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 "GridLines.h"
9
10 #include "XYChart.h"
11 #include "scenegraph/LineGridNode.h"
12
LinePropertiesGroup(GridLines * parent)13 LinePropertiesGroup::LinePropertiesGroup(GridLines *parent)
14 : QObject(parent)
15 {
16 m_parent = parent;
17 }
18
visible() const19 bool LinePropertiesGroup::visible() const
20 {
21 return m_visible;
22 }
23
setVisible(bool newVisible)24 void LinePropertiesGroup::setVisible(bool newVisible)
25 {
26 if (newVisible == m_visible) {
27 return;
28 }
29
30 m_visible = newVisible;
31 Q_EMIT propertiesChanged();
32 }
33
color() const34 QColor LinePropertiesGroup::color() const
35 {
36 return m_color;
37 }
38
setColor(const QColor & newColor)39 void LinePropertiesGroup::setColor(const QColor &newColor)
40 {
41 if (newColor == m_color) {
42 return;
43 }
44
45 m_color = newColor;
46 Q_EMIT propertiesChanged();
47 }
48
lineWidth() const49 float LinePropertiesGroup::lineWidth() const
50 {
51 return m_lineWidth;
52 }
53
setLineWidth(float newLineWidth)54 void LinePropertiesGroup::setLineWidth(float newLineWidth)
55 {
56 if (newLineWidth == m_lineWidth) {
57 return;
58 }
59
60 m_lineWidth = newLineWidth;
61 Q_EMIT propertiesChanged();
62 }
63
frequency() const64 int LinePropertiesGroup::frequency() const
65 {
66 return m_frequency;
67 }
68
setFrequency(int newFrequency)69 void LinePropertiesGroup::setFrequency(int newFrequency)
70 {
71 if (newFrequency == m_frequency) {
72 return;
73 }
74
75 m_frequency = newFrequency;
76 Q_EMIT propertiesChanged();
77 }
78
count() const79 int LinePropertiesGroup::count() const
80 {
81 return m_count;
82 }
83
setCount(int newCount)84 void LinePropertiesGroup::setCount(int newCount)
85 {
86 if (newCount == m_count) {
87 return;
88 }
89
90 m_count = newCount;
91 Q_EMIT propertiesChanged();
92 }
93
GridLines(QQuickItem * parent)94 GridLines::GridLines(QQuickItem *parent)
95 : QQuickItem(parent)
96 {
97 setFlag(QQuickItem::ItemHasContents);
98
99 m_major = std::make_unique<LinePropertiesGroup>(this);
100 connect(m_major.get(), &LinePropertiesGroup::propertiesChanged, this, &GridLines::update);
101 m_minor = std::make_unique<LinePropertiesGroup>(this);
102 connect(m_minor.get(), &LinePropertiesGroup::propertiesChanged, this, &GridLines::update);
103 }
104
direction() const105 GridLines::Direction GridLines::direction() const
106 {
107 return m_direction;
108 }
109
setDirection(GridLines::Direction newDirection)110 void GridLines::setDirection(GridLines::Direction newDirection)
111 {
112 if (newDirection == m_direction) {
113 return;
114 }
115
116 m_direction = newDirection;
117 update();
118 Q_EMIT directionChanged();
119 }
120
chart() const121 XYChart *GridLines::chart() const
122 {
123 return m_chart;
124 }
125
setChart(XYChart * newChart)126 void GridLines::setChart(XYChart *newChart)
127 {
128 if (newChart == m_chart) {
129 return;
130 }
131
132 if (m_chart) {
133 disconnect(m_chart, &XYChart::computedRangeChanged, this, &GridLines::update);
134 }
135
136 m_chart = newChart;
137
138 if (m_chart) {
139 connect(m_chart, &XYChart::computedRangeChanged, this, &GridLines::update);
140 }
141
142 update();
143 Q_EMIT chartChanged();
144 }
145
spacing() const146 float GridLines::spacing() const
147 {
148 return m_spacing;
149 }
150
setSpacing(float newSpacing)151 void GridLines::setSpacing(float newSpacing)
152 {
153 if (newSpacing == m_spacing || m_chart != nullptr) {
154 return;
155 }
156
157 m_spacing = newSpacing;
158 update();
159 Q_EMIT spacingChanged();
160 }
161
majorGroup() const162 LinePropertiesGroup *GridLines::majorGroup() const
163 {
164 return m_major.get();
165 }
166
minorGroup() const167 LinePropertiesGroup *GridLines::minorGroup() const
168 {
169 return m_minor.get();
170 }
171
updatePaintNode(QSGNode * node,QQuickItem::UpdatePaintNodeData *)172 QSGNode *GridLines::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *)
173 {
174 if (!node) {
175 node = new QSGNode{};
176 node->appendChildNode(new LineGridNode{});
177 node->appendChildNode(new LineGridNode{});
178 }
179
180 if (m_chart) {
181 if (m_direction == Direction::Horizontal) {
182 m_spacing = width() / (m_chart->computedRange().distanceX - 1);
183 } else {
184 m_spacing = height() / (m_chart->computedRange().distanceY);
185 }
186 }
187
188 updateLines(static_cast<LineGridNode *>(node->childAtIndex(0)), m_minor.get());
189 updateLines(static_cast<LineGridNode *>(node->childAtIndex(1)), m_major.get());
190
191 return node;
192 }
193
updateLines(LineGridNode * node,LinePropertiesGroup * properties)194 void GridLines::updateLines(LineGridNode *node, LinePropertiesGroup *properties)
195 {
196 node->setVisible(properties->visible());
197 node->setRect(boundingRect());
198 node->setVertical(m_direction == Direction::Vertical);
199 node->setColor(properties->color());
200 node->setLineWidth(properties->lineWidth());
201 if (properties->count() > 0) {
202 node->setSpacing(m_direction == Direction::Horizontal ? width() / (properties->count() + 1) : height() / (properties->count() + 1));
203 } else {
204 node->setSpacing(m_spacing * properties->frequency());
205 }
206 node->update();
207 }
208