1/*
2 * This file is part of KQuickCharts
3 * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
4 *
5 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8#include "XYChart.h"
9
10#include "RangeGroup.h"
11#include "datasource/ChartDataSource.h"
12
13bool operator==(const ComputedRange &first, const ComputedRange &second)
14{
15 return first.startX == second.startX && first.endX == second.endX && qFuzzyCompare(p1: first.startY, p2: second.startY) && qFuzzyCompare(p1: first.endY, p2: second.endY);
16}
17
18XYChart::XYChart(QQuickItem *parent)
19 : Chart(parent)
20{
21 m_xRange = new RangeGroup{this};
22 connect(sender: m_xRange, signal: &RangeGroup::rangeChanged, context: this, slot: &XYChart::updateComputedRange);
23 m_yRange = new RangeGroup{this};
24 connect(sender: m_yRange, signal: &RangeGroup::rangeChanged, context: this, slot: &XYChart::updateComputedRange);
25}
26
27RangeGroup *XYChart::xRange() const
28{
29 return m_xRange;
30}
31
32RangeGroup *XYChart::yRange() const
33{
34 return m_yRange;
35}
36
37XYChart::Direction XYChart::direction() const
38{
39 return m_direction;
40}
41
42void XYChart::setDirection(XYChart::Direction newDirection)
43{
44 if (newDirection == m_direction) {
45 return;
46 }
47
48 m_direction = newDirection;
49 onDataChanged();
50 Q_EMIT directionChanged();
51}
52
53bool XYChart::stacked() const
54{
55 return m_stacked;
56}
57
58void XYChart::setStacked(bool newStacked)
59{
60 if (newStacked == m_stacked) {
61 return;
62 }
63
64 m_stacked = newStacked;
65 onDataChanged();
66 Q_EMIT stackedChanged();
67}
68
69ComputedRange XYChart::computedRange() const
70{
71 return m_computedRange;
72}
73
74void XYChart::updateComputedRange()
75{
76 if (valueSources().count() == 0) {
77 return;
78 }
79
80 ComputedRange result;
81
82 auto xRange = m_xRange->calculateRange(
83 sources: valueSources(),
84 minimumCallback: [](ChartDataSource *) {
85 return 0;
86 },
87 maximumCallback: [](ChartDataSource *source) {
88 return source->itemCount();
89 });
90 result.startX = xRange.start;
91 result.endX = xRange.end;
92 result.distanceX = xRange.distance;
93
94 auto maximumY = [this, xRange](ChartDataSource *source) {
95 if (!m_stacked) {
96 return source->maximum().toDouble();
97 } else {
98 qreal max = std::numeric_limits<qreal>::min();
99 for (int i = xRange.start; i < xRange.end; ++i) {
100 qreal yDistance = 0.0;
101 for (auto source : valueSources()) {
102 yDistance += source->item(index: i).toDouble();
103 }
104 max = std::max(a: max, b: yDistance);
105 }
106 return max;
107 }
108 };
109
110 auto yRange = m_yRange->calculateRange(
111 sources: valueSources(),
112 minimumCallback: [](ChartDataSource *source) {
113 return std::min(a: 0.0, b: source->minimum().toDouble());
114 },
115 maximumCallback: maximumY);
116 result.startY = yRange.start;
117 result.endY = yRange.end;
118 result.distanceY = yRange.distance;
119
120 setComputedRange(result);
121}
122
123void XYChart::setComputedRange(ComputedRange range)
124{
125 if (range == m_computedRange) {
126 return;
127 }
128
129 m_computedRange = range;
130 Q_EMIT computedRangeChanged();
131}
132
133QDebug operator<<(QDebug debug, const ComputedRange &range)
134{
135 debug << "Range: startX" << range.startX << "endX" << range.endX << "distance" << range.distanceX << "startY" << range.startY << "endY" << range.endY
136 << "distance" << range.distanceY;
137 return debug;
138}
139
140#include "moc_XYChart.cpp"
141

source code of kquickcharts/src/XYChart.cpp