1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Charts module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include "grid.h" |
31 | #include "charts.h" |
32 | #include <QtCharts/QChart> |
33 | #include <QtWidgets/QGraphicsGridLayout> |
34 | #include <QtWidgets/QGraphicsSceneMouseEvent> |
35 | #include <QtCore/QDebug> |
36 | |
37 | Grid::Grid(int size, QGraphicsItem *parent) |
38 | : QGraphicsWidget(parent), |
39 | m_listCount(3), |
40 | m_valueMax(10), |
41 | m_valueCount(7), |
42 | m_size(size), |
43 | m_dataTable(Model::generateRandomData(listCount: m_listCount, valueMax: m_valueMax, valueCount: m_valueCount)), |
44 | m_state(NoState), |
45 | m_currentState(NoState), |
46 | m_rubberBand(new QGraphicsRectItem()), |
47 | m_gridLayout(new QGraphicsGridLayout()) |
48 | { |
49 | setLayout(m_gridLayout); |
50 | m_rubberBand->setParentItem(this); |
51 | m_rubberBand->setVisible(false); |
52 | m_rubberBand->setZValue(2); |
53 | } |
54 | |
55 | Grid::~Grid() |
56 | { |
57 | |
58 | } |
59 | |
60 | void Grid::createCharts(const QString &category) |
61 | { |
62 | clear(); |
63 | |
64 | QChart *qchart(0); |
65 | Charts::ChartList list = Charts::chartList(); |
66 | |
67 | if (category.isEmpty()) { |
68 | for (int i = 0; i < m_size * m_size; ++i) { |
69 | QChart *chart = new QChart(); |
70 | chart->setTitle(QObject::tr(s: "Empty" )); |
71 | m_gridLayout->addItem(aitem: chart, arow: i / m_size, acolumn: i % m_size); |
72 | m_chartHash[chart] = i; |
73 | m_chartHashRev[i] = chart; |
74 | } |
75 | } else { |
76 | int j = 0; |
77 | for (int i = 0; i < list.size(); ++i) { |
78 | Chart *chart = list.at(i); |
79 | if (chart->category() == category && j < m_size * m_size) { |
80 | qchart = list.at(i)->createChart(table: m_dataTable); |
81 | m_gridLayout->addItem(aitem: qchart, arow: j / m_size, acolumn: j % m_size); |
82 | m_chartHash[qchart] = j; |
83 | m_chartHashRev[j] = qchart; |
84 | j++; |
85 | } |
86 | } |
87 | for (; j < m_size * m_size; ++j) { |
88 | qchart = new QChart(); |
89 | qchart->setTitle(QObject::tr(s: "Empty" )); |
90 | m_gridLayout->addItem(aitem: qchart, arow: j / m_size, acolumn: j % m_size); |
91 | m_chartHash[qchart] = j; |
92 | m_chartHashRev[j] = qchart; |
93 | } |
94 | } |
95 | m_gridLayout->activate(); |
96 | } |
97 | |
98 | void Grid::createCharts(const QString &category, const QString &subcategory, const QString &name) |
99 | { |
100 | clear(); |
101 | |
102 | QChart *qchart(0); |
103 | Charts::ChartList list = Charts::chartList(); |
104 | Chart *chart; |
105 | |
106 | //find chart |
107 | for (int i = 0; i < list.size(); ++i) { |
108 | |
109 | chart = list.at(i); |
110 | if (chart->category() == category && |
111 | chart->subCategory() == subcategory && |
112 | chart->name() == name) { |
113 | break; |
114 | } |
115 | chart = 0; |
116 | } |
117 | |
118 | //create charts |
119 | for (int j = 0; j < m_size * m_size; ++j) { |
120 | |
121 | if(!chart){ |
122 | qchart = new QChart(); |
123 | }else{ |
124 | qchart = chart->createChart(table: m_dataTable); |
125 | } |
126 | qchart->setTitle(QObject::tr(s: "Empty" )); |
127 | m_gridLayout->addItem(aitem: qchart, arow: j / m_size, acolumn: j % m_size); |
128 | m_chartHash[qchart] = j; |
129 | m_chartHashRev[j] = qchart; |
130 | } |
131 | |
132 | m_gridLayout->activate(); |
133 | } |
134 | |
135 | void Grid::clear() |
136 | { |
137 | int count = m_gridLayout->count(); |
138 | for (int i = 0; i < count; ++i) |
139 | m_gridLayout->removeAt(index: 0); |
140 | |
141 | qDeleteAll(c: m_chartHash.keys()); |
142 | m_chartHash.clear(); |
143 | m_chartHashRev.clear(); |
144 | } |
145 | |
146 | QList<QChart *> Grid::charts() |
147 | { |
148 | return m_chartHash.keys(); |
149 | } |
150 | |
151 | void Grid::setState(State state) |
152 | { |
153 | m_state = state; |
154 | } |
155 | |
156 | void Grid::setSize(int size) |
157 | { |
158 | if (m_size != size) { |
159 | |
160 | //remove old; |
161 | int count = m_gridLayout->count(); |
162 | for (int i = 0; i < count; ++i) { |
163 | m_gridLayout->removeAt(index: 0); |
164 | } |
165 | |
166 | |
167 | QChart* qchart = 0; |
168 | int j = 0; |
169 | |
170 | for (; j < size * size; ++j) { |
171 | |
172 | qchart = m_chartHashRev[j]; |
173 | |
174 | if (!qchart){ |
175 | qchart = new QChart(); |
176 | qchart->setTitle(QObject::tr(s: "Empty" )); |
177 | } |
178 | |
179 | m_chartHash[qchart] = j; |
180 | m_chartHashRev[j] = qchart; |
181 | m_gridLayout->addItem(aitem: qchart, arow: j / size, acolumn: j % size); |
182 | } |
183 | |
184 | //delete rest |
185 | while (j < m_size * m_size) { |
186 | QChart* qchart = m_chartHashRev.take(akey: j); |
187 | delete(qchart); |
188 | m_chartHash.remove(akey: qchart); |
189 | j++; |
190 | } |
191 | |
192 | m_size = size; |
193 | } |
194 | } |
195 | |
196 | void Grid::setRubberPen(const QPen &pen) |
197 | { |
198 | m_rubberBand->setPen(pen); |
199 | } |
200 | |
201 | void Grid::replaceChart(QChart *oldChart, Chart *newChart) |
202 | { |
203 | int index = m_chartHash[oldChart]; |
204 | //not in 4.7.2 m_baseLayout->removeItem(qchart); |
205 | for (int i = 0; i < m_gridLayout->count(); ++i) { |
206 | if (m_gridLayout->itemAt(index: i) == oldChart) { |
207 | m_gridLayout->removeAt(index: i); |
208 | break; |
209 | } |
210 | } |
211 | m_chartHash.remove(akey: oldChart); |
212 | m_chartHashRev.remove(akey: index); |
213 | QChart *chart = newChart->createChart(table: m_dataTable); |
214 | m_gridLayout->addItem(aitem: chart, arow: index / m_size, acolumn: index % m_size); |
215 | m_chartHash[chart] = index; |
216 | m_chartHashRev[index] = chart; |
217 | delete oldChart; |
218 | } |
219 | |
220 | void Grid::mousePressEvent(QGraphicsSceneMouseEvent *event) |
221 | { |
222 | if (event->button() == Qt::LeftButton) { |
223 | |
224 | m_origin = event->pos(); |
225 | m_currentState = NoState; |
226 | |
227 | foreach (QChart *chart, charts()) { |
228 | QRectF geometryRect = chart->geometry(); |
229 | QRectF plotArea = chart->plotArea(); |
230 | plotArea.translate(p: geometryRect.topLeft()); |
231 | if (plotArea.contains(p: m_origin)) { |
232 | m_currentState = m_state; |
233 | if (m_currentState == NoState) emit chartSelected(chart); |
234 | break; |
235 | } |
236 | } |
237 | if (m_currentState == ZoomState) { |
238 | m_rubberBand->setRect(QRectF(m_origin, QSize())); |
239 | m_rubberBand->setVisible(true); |
240 | } |
241 | |
242 | event->accept(); |
243 | } |
244 | |
245 | if (event->button() == Qt::RightButton) { |
246 | m_origin = event->pos(); |
247 | m_currentState = m_state; |
248 | } |
249 | } |
250 | |
251 | void Grid::mouseMoveEvent(QGraphicsSceneMouseEvent *event) |
252 | { |
253 | if (m_currentState != NoState) { |
254 | |
255 | foreach (QChart *chart, charts()) { |
256 | QRectF geometryRect = chart->geometry(); |
257 | QRectF plotArea = chart->plotArea(); |
258 | plotArea.translate(p: geometryRect.topLeft()); |
259 | if (plotArea.contains(p: m_origin)) { |
260 | if (m_currentState == ScrollState) { |
261 | QPointF delta = m_origin - event->pos(); |
262 | chart->scroll(dx: delta.x(), dy: -delta.y()); |
263 | } |
264 | if (m_currentState == ZoomState && plotArea.contains(p: event->pos())) |
265 | m_rubberBand->setRect(QRectF(m_origin, event->pos()).normalized()); |
266 | break; |
267 | } |
268 | } |
269 | if (m_currentState == ScrollState) |
270 | m_origin = event->pos(); |
271 | event->accept(); |
272 | } |
273 | } |
274 | |
275 | void Grid::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) |
276 | { |
277 | if (event->button() == Qt::LeftButton) { |
278 | if (m_currentState == ZoomState) { |
279 | m_rubberBand->setVisible(false); |
280 | |
281 | foreach (QChart *chart, charts()) { |
282 | QRectF geometryRect = chart->geometry(); |
283 | QRectF plotArea = chart->plotArea(); |
284 | plotArea.translate(p: geometryRect.topLeft()); |
285 | if (plotArea.contains(p: m_origin)) { |
286 | QRectF rect = m_rubberBand->rect(); |
287 | rect.translate(p: -geometryRect.topLeft()); |
288 | chart->zoomIn(rect); |
289 | break; |
290 | } |
291 | } |
292 | } |
293 | m_currentState = NoState; |
294 | event->accept(); |
295 | } |
296 | |
297 | if (event->button() == Qt::RightButton) { |
298 | if (m_currentState == ZoomState) { |
299 | foreach (QChart *chart, charts()) { |
300 | QRectF geometryRect = chart->geometry(); |
301 | QRectF plotArea = chart->plotArea(); |
302 | plotArea.translate(p: geometryRect.topLeft()); |
303 | if (plotArea.contains(p: m_origin)) { |
304 | chart->zoomOut(); |
305 | break; |
306 | } |
307 | } |
308 | } |
309 | } |
310 | } |
311 | |