2020-01-11 02:11:55 +03:00
|
|
|
#include "lrlineschart.h"
|
|
|
|
|
|
|
|
namespace LimeReport {
|
|
|
|
|
|
|
|
void LinesChart::paintChart(QPainter *painter, QRectF chartRect)
|
|
|
|
{
|
2022-01-05 14:13:05 +03:00
|
|
|
updateMinAndMaxValues();
|
|
|
|
|
|
|
|
const qreal valuesHMargin = this->valuesHMargin(painter);
|
|
|
|
const qreal valuesVMargin = this->valuesVMargin(painter);
|
|
|
|
|
2020-01-11 02:11:55 +03:00
|
|
|
QRectF calcRect = horizontalLabelsRect(
|
|
|
|
painter,
|
|
|
|
chartRect.adjusted(
|
2022-01-05 14:13:05 +03:00
|
|
|
hPadding(chartRect) * 2 + valuesHMargin,
|
2020-01-11 02:11:55 +03:00
|
|
|
chartRect.height() - (painter->fontMetrics().height() + vPadding(chartRect)*2),
|
|
|
|
-(hPadding(chartRect) * 2),
|
|
|
|
-vPadding(chartRect)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
qreal barsShift = calcRect.height();
|
|
|
|
paintVerticalGrid(
|
|
|
|
painter,
|
|
|
|
chartRect.adjusted(
|
|
|
|
hPadding(chartRect),
|
2022-01-05 14:13:05 +03:00
|
|
|
vPadding(chartRect) + valuesVMargin,
|
2020-01-11 02:11:55 +03:00
|
|
|
-hPadding(chartRect),
|
|
|
|
-(vPadding(chartRect) + barsShift)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
paintSerialLines(
|
|
|
|
painter,
|
|
|
|
chartRect.adjusted(
|
2022-01-05 14:13:05 +03:00
|
|
|
hPadding(chartRect) * 2 + valuesHMargin,
|
|
|
|
vPadding(chartRect) + valuesVMargin,
|
2020-01-11 02:11:55 +03:00
|
|
|
-(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]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-25 21:13:00 +03:00
|
|
|
qreal LinesChart::calculatePos(const AxisData &data, qreal value, qreal rectSize) const
|
2022-01-18 12:56:05 +03:00
|
|
|
{
|
2022-01-25 21:13:00 +03:00
|
|
|
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;
|
|
|
|
}
|
2022-01-18 12:56:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void LinesChart::paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect)
|
|
|
|
{
|
|
|
|
const AxisData &yAxisData = this->yAxisData();
|
2022-01-25 21:28:32 +03:00
|
|
|
const AxisData &xAxisData = this->xAxisData();
|
2022-01-18 12:56:05 +03:00
|
|
|
|
2022-01-25 21:28:32 +03:00
|
|
|
const qreal xAxisDiff = std::max(1.0, xAxisData.maxValue() - xAxisData.minValue());
|
2022-01-25 21:13:00 +03:00
|
|
|
const qreal hStep = barsRect.width() / xAxisDiff;
|
2022-01-18 12:56:05 +03:00
|
|
|
const qreal topMargin = barsRect.top();
|
|
|
|
|
|
|
|
QPen pen(series->color());
|
|
|
|
pen.setWidth(4);
|
|
|
|
painter->setPen(pen);
|
|
|
|
|
|
|
|
const QList<qreal> &values = series->data()->values();
|
|
|
|
|
|
|
|
qreal lastYValue = 0;
|
|
|
|
qreal lastXValue = barsRect.left() + hStep/2;
|
|
|
|
if (!values.isEmpty()) {
|
|
|
|
// Calculate first point position on plot before loop
|
2022-01-25 21:13:00 +03:00
|
|
|
lastYValue = calculatePos(yAxisData, values.first(), barsRect.height());
|
2022-01-18 12:56:05 +03:00
|
|
|
}
|
|
|
|
for (int i = 0; i < values.count()-1; ++i ){
|
|
|
|
const qreal startY = lastYValue;
|
2022-01-25 21:13:00 +03:00
|
|
|
const qreal endY = calculatePos(yAxisData, values.at(i+1), barsRect.height());
|
2022-01-18 12:56:05 +03:00
|
|
|
// 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());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-11 02:11:55 +03:00
|
|
|
void LinesChart::paintSerialLines(QPainter* painter, QRectF barsRect)
|
|
|
|
{
|
2020-05-18 22:12:05 +03:00
|
|
|
if (valuesCount() == 0) return;
|
|
|
|
|
2020-01-11 02:11:55 +03:00
|
|
|
painter->save();
|
|
|
|
painter->setRenderHint(QPainter::Antialiasing,true);
|
2022-01-18 12:56:05 +03:00
|
|
|
|
|
|
|
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();
|
2020-01-11 02:11:55 +03:00
|
|
|
drawDesignMode(painter, hStep, vStep, topShift, barsRect);
|
2022-01-18 12:56:05 +03:00
|
|
|
painter->restore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (SeriesItem *series : m_chartItem->series()) {
|
|
|
|
paintSeries(painter, series, barsRect);
|
2020-01-11 02:11:55 +03:00
|
|
|
}
|
2022-01-18 12:56:05 +03:00
|
|
|
|
2020-01-11 02:11:55 +03:00
|
|
|
painter->restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
} //namespace LimeReport
|
|
|
|
|