diff options
Diffstat (limited to 'src/charts/ChartAxes.cpp')
-rw-r--r-- | src/charts/ChartAxes.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/charts/ChartAxes.cpp b/src/charts/ChartAxes.cpp new file mode 100644 index 0000000..caf8828 --- /dev/null +++ b/src/charts/ChartAxes.cpp @@ -0,0 +1,138 @@ +#include "ChartAxes.h" +#include "ChartScene.h" + +#include <cmath> + +const QPointF ChartAxes::XLabelOffset(0, 5); +const QPointF ChartAxes::YLabelOffset(-10, -7); +const QFont ChartAxes::TickLabelFont("Sans Serif", 11); + +ChartAxes::ChartAxes(ChartScene* scene, int xTickInterval): + scene(scene), xTickInterval(xTickInterval) +{ +} + +void ChartAxes::paint() +{ + addAxisLines(); + addTicks(); +} + +void ChartAxes::addAxisLines() +{ + QPointF chartOrigin = scene->getChartOrigin(); + QRectF chartRect = scene->getChartRect(); + scene->addLine(QLineF(chartOrigin, chartRect.topLeft())); + scene->addLine(QLineF(chartOrigin, chartRect.bottomRight())); +} + +void ChartAxes::addTicks() +{ + addXTicks(); + addYTicks(); +} + +void ChartAxes::addXTicks() +{ + qreal tickSpacing = scene->getDataDirection() * scene->getXTickSpacing(); + QPointF pos = getTickOrigin(XTick); + for(int i = 0; i < scene->getDataSet().size(); i++) + { + addLabelledXTick(i, pos); + pos.rx() += tickSpacing; + } +} + +void ChartAxes::addLabelledXTick(int index, QPointF& pos) +{ + if(index % xTickInterval == 0) + { + addTick(pos, XTick); + DataPoint point = scene->getDataSet().at(index); + addLabel(point.label, pos, XTick); + } +} + +QPointF ChartAxes::getTickOrigin(TickOrientation orientation) const +{ + QPointF res = scene->getChartOrigin(); + if(orientation == XTick) + { + if(scene->getDataDirection() == 1) + res.rx() += ChartScene::DataSetPadding.width(); + else + res.rx() += scene->getChartRect().width(); + } + else + res.ry() -= ChartScene::DataSetPadding.height(); + return res; +} + +void ChartAxes::addTick(const QPointF& pos, TickOrientation orientation) +{ + QPointF end = pos + getTickVector(orientation); + scene->addLine(QLineF(pos, end)); +} + +QPointF ChartAxes::getTickVector(TickOrientation orientation) +{ + if(orientation == XTick) + return QPointF(0, TickLength); + else + return QPointF(-TickLength, 0); +} + +void ChartAxes::addLabel(const QString& labelText, const QPointF& pos, + TickOrientation orientation) +{ + QPointF labelOffset = getLabelOffset(orientation); + QGraphicsItem* textItem = scene->addSimpleText(labelText, TickLabelFont); + qreal xAlignOffset = getLabelXAlignOffset( + textItem->boundingRect().width(), orientation); + textItem->setPos(pos + labelOffset + QPointF(xAlignOffset, 0)); +} + +QPointF ChartAxes::getLabelOffset(TickOrientation orientation) +{ + if(orientation == XTick) + return XLabelOffset; + else + return YLabelOffset; +} + +qreal ChartAxes::getLabelXAlignOffset(qreal labelWidth, TickOrientation orientation) +{ + if(orientation == XTick) + return -labelWidth / 2; + else + return -labelWidth; +} + +void ChartAxes::addYTicks() +{ + int valueSpacing = scene->getYTickSpacing(); + qreal posSpacing = scene->getYPosFromValue(valueSpacing); + QPointF pos = getTickOrigin(YTick); + for(int value = scene->getMinY(); value <= scene->getMaxY(); + value += valueSpacing) + { + addLabelledYTick(value, pos, posSpacing); + if(valueSpacing == 0) + break; + } +} + +void ChartAxes::addLabelledYTick(int value, QPointF& pos, qreal posSpacing) +{ + addTick(pos, YTick); + addLabel(QString::number(value), pos, YTick); + addHRuler(pos); + pos.ry() -= posSpacing; +} + +void ChartAxes::addHRuler(const QPointF& pos) + { + QPointF end = pos; + end.rx() += scene->getChartRect().width(); + scene->addLine(QLineF(pos, end), QPen(Qt::lightGray)); + } |