#include "lrlineschart.h" namespace LimeReport { void LinesChart::paintChart(QPainter *painter, QRectF chartRect) { updateMinAndMaxValues(); const qreal valuesHMargin = this->valuesHMargin(painter); const qreal valuesVMargin = this->valuesVMargin(painter); QRectF calcRect = horizontalLabelsRect( painter, chartRect.adjusted( hPadding(chartRect) * 2 + valuesHMargin, chartRect.height() - (painter->fontMetrics().height() + vPadding(chartRect)*2), -(hPadding(chartRect) * 2), -vPadding(chartRect) ) ); qreal barsShift = calcRect.height(); paintVerticalGrid( painter, chartRect.adjusted( hPadding(chartRect), vPadding(chartRect) + valuesVMargin, -hPadding(chartRect), -(vPadding(chartRect) + barsShift) ) ); paintSerialLines( painter, chartRect.adjusted( hPadding(chartRect) * 2 + valuesHMargin, vPadding(chartRect) + valuesVMargin, -(hPadding(chartRect) * 2), -(vPadding(chartRect)+barsShift) ) ); paintHorizontalLabels(painter, calcRect); } void LinesChart::drawDesignMode(QPainter* painter, qreal hStep, qreal vStep, qreal topShift, QRectF barsRect){ for (int i = 0; i < valuesCount()-1; ++i){ QPoint startPoint = QPoint((i+1) * hStep + barsRect.left() - hStep/2, (maxValue() * vStep+topShift) - designValues()[i] * vStep ); QPoint endPoint = QPoint((i+2) * hStep + barsRect.left() - hStep/2, (maxValue() * vStep+topShift) - designValues()[i+1] * vStep ); drawSegment(painter, startPoint, endPoint, color_map[0]); startPoint = QPoint((i+1) * hStep + barsRect.left() - hStep/2, (maxValue() * vStep+topShift) - designValues()[i+3] * vStep ); endPoint = QPoint((i+2) * hStep + barsRect.left() - hStep/2, (maxValue() * vStep+topShift) - designValues()[i+3+1] * vStep ); drawSegment(painter, startPoint, endPoint, color_map[1]); startPoint = QPoint((i+1) * hStep + barsRect.left() - hStep/2, (maxValue() * vStep+topShift) - designValues()[i+6] * vStep ); endPoint = QPoint((i+2) * hStep + barsRect.left() - hStep/2, (maxValue() * vStep+topShift) - designValues()[i+6+1] * vStep ); drawSegment(painter, startPoint, endPoint, color_map[2]); } } qreal LinesChart::calculatePos(const AxisData &data, qreal value, qreal rectSize) const { if (data.reverseDirection() && data.rangeMin() >= 0) { // Not flipping for minimum less than 0 because lower number is at the bottom. return (1 - (data.rangeMax() - value) / data.delta()) * rectSize; } else { return (data.rangeMax() - value) / data.delta() * rectSize; } } void LinesChart::paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect) { const AxisData &yAxisData = this->yAxisData(); const qreal xAxisDiff = std::max(1.0, maxXValue() - minXValue()); const qreal hStep = barsRect.width() / xAxisDiff; const qreal topMargin = barsRect.top(); QPen pen(series->color()); pen.setWidth(4); painter->setPen(pen); const QList &values = series->data()->values(); qreal lastYValue = 0; qreal lastXValue = barsRect.left() + hStep/2; if (!values.isEmpty()) { // Calculate first point position on plot before loop lastYValue = calculatePos(yAxisData, values.first(), barsRect.height()); } for (int i = 0; i < values.count()-1; ++i ){ const qreal startY = lastYValue; const qreal endY = calculatePos(yAxisData, values.at(i+1), barsRect.height()); // Record last used Y position to only calculate new one lastYValue = endY; const qreal startX = lastXValue; const qreal endX = startX + hStep; // Record last used X position to only calculate new one lastXValue = endX; QPoint startPoint = QPoint(startX, startY + topMargin); QPoint endPoint = QPoint(endX, endY + topMargin); drawSegment(painter, startPoint, endPoint, series->color()); } } void LinesChart::paintSerialLines(QPainter* painter, QRectF barsRect) { if (valuesCount() == 0) return; painter->save(); painter->setRenderHint(QPainter::Antialiasing,true); if (m_chartItem->itemMode() == DesignMode){ const AxisData &yAxisData = this->yAxisData(); const qreal delta = yAxisData.delta(); const qreal hStep = barsRect.width() / valuesCount(); const qreal vStep = barsRect.height() / delta; const qreal topShift = (delta - (maxValue() - minValue())) * vStep + barsRect.top(); drawDesignMode(painter, hStep, vStep, topShift, barsRect); painter->restore(); return; } for (SeriesItem *series : m_chartItem->series()) { paintSeries(painter, series, barsRect); } painter->restore(); } } //namespace LimeReport