0
0
mirror of https://github.com/fralx/LimeReport.git synced 2024-12-24 00:33:02 +03:00
LimeReport/limereport/items/charts/lrlineschart.cpp
Андрей Лухнов 0fca7169d3 Define code style and format all source file using clang-format-14
except those placed in 3rdparty directories.
2024-09-19 21:09:38 +03:00

129 lines
5.3 KiB
C++

#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.type() == AxisData::XAxis || (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 AxisData& xAxisData = this->xAxisData();
const qreal xAxisDiff = std::max(1.0, xAxisData.maxValue() - xAxisData.minValue());
const qreal hStep = barsRect.width() / xAxisDiff;
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
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