##// END OF EJS Templates
No longer automatically disable QDateTimeAxis on ARM platforms...
Miikka Heikkinen -
r2861:21c113d296ef
parent child
Show More
@@ -1,66 +1,66
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += areachart \
3 3 customchart \
4 4 linechart \
5 5 percentbarchart \
6 6 piechart \
7 7 piechartdrilldown \
8 8 scatterchart \
9 9 scatterinteractions \
10 10 splinechart \
11 11 stackedbarchart \
12 12 stackedbarchartdrilldown \
13 13 zoomlinechart \
14 14 modeldata \
15 15 barchart \
16 16 boxplotchart \
17 17 legend \
18 18 barmodelmapper \
19 19 lineandbar \
20 20 horizontalbarchart \
21 21 horizontalstackedbarchart \
22 22 horizontalpercentbarchart \
23 23 donutbreakdown \
24 24 temperaturerecords \
25 25 donutchart \
26 26 multiaxis \
27 27 legendmarkers \
28 28 logvalueaxis \
29 29 polarchart \
30 30 piechartcustomization \
31 31 dynamicspline \
32 32 nesteddonuts \
33 33 chartinteractions \
34 34 callout \
35 35 chartthemes
36 36
37 37 qtHaveModule(quick) {
38 38 SUBDIRS += qmlboxplot \
39 39 qmlpiechart \
40 40 qmlweather \
41 41 qmlf1legends \
42 42 qmlcustomizations \
43 43 qmlaxes \
44 44 qmlcustomlegend \
45 45 qmlpolarchart \
46 46 qmlchart \
47 47 qmloscilloscope
48 48 }
49 49
50 50 qtHaveModule(multimedia) {
51 51 SUBDIRS += audio
52 52 } else {
53 53 message("QtMultimedia library not available. Some examples are disabled.")
54 54 }
55 55
56 56 contains(QT_CONFIG, opengl) {
57 57 SUBDIRS += openglseries
58 58 } else {
59 59 message("OpenGL not available. Some examples are disabled.")
60 60 }
61 61
62 !linux-arm*: {
62 !contains(QT_COORD_TYPE, float): {
63 63 SUBDIRS += \
64 64 datetimeaxis
65 65 }
66 66
@@ -1,108 +1,108
1 1 #Subdirectiores are defined here, because qt creator doesn't handle nested include(foo.pri) chains very well.
2 2
3 3 INCLUDEPATH += $$PWD \
4 4 $$PWD/valueaxis \
5 5 $$PWD/barcategoryaxis \
6 6 $$PWD/categoryaxis \
7 7 $$PWD/logvalueaxis
8 8
9 9 DEPENDPATH += $$PWD \
10 10 $$PWD/valueaxis \
11 11 $$PWD/barcategoryaxis \
12 12 $$PWD/categoryaxis \
13 13 $$PWD/logvalueaxis
14 14
15 15 SOURCES += \
16 16 $$PWD/chartaxiselement.cpp \
17 17 $$PWD/cartesianchartaxis.cpp \
18 18 $$PWD/qabstractaxis.cpp \
19 19 $$PWD/verticalaxis.cpp \
20 20 $$PWD/horizontalaxis.cpp \
21 21 $$PWD/valueaxis/chartvalueaxisx.cpp \
22 22 $$PWD/valueaxis/chartvalueaxisy.cpp \
23 23 $$PWD/valueaxis/qvalueaxis.cpp \
24 24 $$PWD/barcategoryaxis/chartbarcategoryaxisx.cpp \
25 25 $$PWD/barcategoryaxis/chartbarcategoryaxisy.cpp \
26 26 $$PWD/barcategoryaxis/qbarcategoryaxis.cpp \
27 27 $$PWD/categoryaxis/chartcategoryaxisx.cpp \
28 28 $$PWD/categoryaxis/chartcategoryaxisy.cpp \
29 29 $$PWD/categoryaxis/qcategoryaxis.cpp \
30 30 $$PWD/logvalueaxis/chartlogvalueaxisx.cpp \
31 31 $$PWD/logvalueaxis/chartlogvalueaxisy.cpp \
32 32 $$PWD/logvalueaxis/qlogvalueaxis.cpp
33 33
34 34 PRIVATE_HEADERS += \
35 35 $$PWD/chartaxiselement_p.h \
36 36 $$PWD/cartesianchartaxis_p.h \
37 37 $$PWD/qabstractaxis_p.h \
38 38 $$PWD/verticalaxis_p.h \
39 39 $$PWD/horizontalaxis_p.h \
40 40 $$PWD/linearrowitem_p.h \
41 41 $$PWD/valueaxis/chartvalueaxisx_p.h \
42 42 $$PWD/valueaxis/chartvalueaxisy_p.h \
43 43 $$PWD/valueaxis/qvalueaxis_p.h \
44 44 $$PWD/barcategoryaxis/chartbarcategoryaxisx_p.h \
45 45 $$PWD/barcategoryaxis/chartbarcategoryaxisy_p.h \
46 46 $$PWD/barcategoryaxis/qbarcategoryaxis_p.h \
47 47 $$PWD/categoryaxis/chartcategoryaxisx_p.h \
48 48 $$PWD/categoryaxis/chartcategoryaxisy_p.h \
49 49 $$PWD/categoryaxis/qcategoryaxis_p.h \
50 50 $$PWD/logvalueaxis/chartlogvalueaxisx_p.h \
51 51 $$PWD/logvalueaxis/chartlogvalueaxisy_p.h \
52 52 $$PWD/logvalueaxis/qlogvalueaxis_p.h
53 53
54 54 PUBLIC_HEADERS += \
55 55 $$PWD/qabstractaxis.h \
56 56 $$PWD/valueaxis/qvalueaxis.h \
57 57 $$PWD/barcategoryaxis/qbarcategoryaxis.h \
58 58 $$PWD/categoryaxis/qcategoryaxis.h \
59 59 $$PWD/logvalueaxis/qlogvalueaxis.h \
60 60
61 61 # polar
62 62 SOURCES += \
63 63 $$PWD/polarchartaxis.cpp \
64 64 $$PWD/polarchartaxisangular.cpp \
65 65 $$PWD/polarchartaxisradial.cpp \
66 66 $$PWD/valueaxis/polarchartvalueaxisangular.cpp \
67 67 $$PWD/valueaxis/polarchartvalueaxisradial.cpp \
68 68 $$PWD/logvalueaxis/polarchartlogvalueaxisangular.cpp \
69 69 $$PWD/logvalueaxis/polarchartlogvalueaxisradial.cpp \
70 70 $$PWD/categoryaxis/polarchartcategoryaxisangular.cpp \
71 71 $$PWD/categoryaxis/polarchartcategoryaxisradial.cpp
72 72
73 73 PRIVATE_HEADERS += \
74 74 $$PWD/polarchartaxis_p.h \
75 75 $$PWD/polarchartaxisangular_p.h \
76 76 $$PWD/polarchartaxisradial_p.h \
77 77 $$PWD/valueaxis/polarchartvalueaxisangular_p.h \
78 78 $$PWD/valueaxis/polarchartvalueaxisradial_p.h \
79 79 $$PWD/logvalueaxis/polarchartlogvalueaxisangular_p.h \
80 80 $$PWD/logvalueaxis/polarchartlogvalueaxisradial_p.h \
81 81 $$PWD/categoryaxis/polarchartcategoryaxisangular_p.h \
82 82 $$PWD/categoryaxis/polarchartcategoryaxisradial_p.h
83 83
84 !linux-arm*: {
84 !contains(QT_COORD_TYPE, float): {
85 85 INCLUDEPATH += \
86 86 $$PWD/datetimeaxis
87 87
88 88 DEPENDPATH += \
89 89 $$PWD/datetimeaxis
90 90
91 91 SOURCES += \
92 92 $$PWD/datetimeaxis/chartdatetimeaxisx.cpp \
93 93 $$PWD/datetimeaxis/chartdatetimeaxisy.cpp \
94 94 $$PWD/datetimeaxis/qdatetimeaxis.cpp \
95 95 $$PWD/datetimeaxis/polarchartdatetimeaxisangular.cpp \
96 96 $$PWD/datetimeaxis/polarchartdatetimeaxisradial.cpp
97 97
98 98 PRIVATE_HEADERS += \
99 99 $$PWD/datetimeaxis/chartdatetimeaxisx_p.h \
100 100 $$PWD/datetimeaxis/chartdatetimeaxisy_p.h \
101 101 $$PWD/datetimeaxis/qdatetimeaxis_p.h \
102 102 $$PWD/datetimeaxis/polarchartdatetimeaxisangular_p.h \
103 103 $$PWD/datetimeaxis/polarchartdatetimeaxisradial_p.h
104 104
105 105 PUBLIC_HEADERS += \
106 106 $$PWD/datetimeaxis/qdatetimeaxis.h
107 107 }
108 108
@@ -1,398 +1,398
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QDateTimeAxis>
31 31 #include <private/qdatetimeaxis_p.h>
32 32 #include <private/chartdatetimeaxisx_p.h>
33 33 #include <private/chartdatetimeaxisy_p.h>
34 34 #include <private/polarchartdatetimeaxisangular_p.h>
35 35 #include <private/polarchartdatetimeaxisradial_p.h>
36 36 #include <private/abstractdomain_p.h>
37 37 #include <QtCharts/QChart>
38 38 #include <float.h>
39 39 #include <cmath>
40 40
41 41 QT_CHARTS_BEGIN_NAMESPACE
42 42 /*!
43 43 \class QDateTimeAxis
44 44 \inmodule Qt Charts
45 45 \brief The QDateTimeAxis class is used for manipulating chart's axis.
46 46
47 47 The labels can be configured by setting an appropriate DateTime format.
48 48 QDateTimeAxis works correctly with dates from 4714 BCE to 287396 CE.
49 49 There are also other limitiation related to QDateTime. Please refer to QDateTime documentation.
50 50 QDateTimeAxis can be setup to show axis line with tick marks, grid lines and shades.
51 51
52 Note: QDateTimeAxis is disabled on ARM architecture.
52 Note: QDateTimeAxis is disabled on platforms that define qreal as float.
53 53
54 54 \image api_datatime_axis.png
55 55
56 56 QDateTimeAxis can be used with any QXYSeries.
57 57 To add a data point to the series QDateTime::toMSecsSinceEpoch() is used.
58 58 \code
59 59 QLineSeries *series = new QLineSeries;
60 60
61 61 QDateTime xValue;
62 62 xValue.setDate(QDate(2012, 1 , 18));
63 63 xValue.setTime(QTime(9, 34));
64 64 qreal yValue = 12;
65 65 series->append(xValue.toMSecsSinceEpoch(), yValue);
66 66
67 67 xValue.setDate(QDate(2013, 5 , 11));
68 68 xValue.setTime(QTime(11, 14));
69 69 qreal yValue = 22;
70 70 series->append(xValue.toMSecsSinceEpoch(), yValue);
71 71 \endcode
72 72
73 73 Adding the series to the chart and setting up the QDateTimeAxis.
74 74 \code
75 75 QChartView *chartView = new QChartView;
76 76 chartView->chart()->addSeries(series);
77 77
78 78 // ...
79 79 QDateTimeAxis *axisX = new QDateTimeAxis;
80 80 axisX->setFormat("dd-MM-yyyy h:mm");
81 81 chartView->chart()->setAxisX(axisX, series);
82 82 \endcode
83 83 */
84 84
85 85 /*!
86 86 \qmltype DateTimeAxis
87 87 \instantiates QDateTimeAxis
88 88 \inqmlmodule QtCharts
89 89
90 90 \brief The DateTimeAxis element is used for manipulating chart's axes.
91 91 \inherits AbstractAxis
92 92
93 93 The labels can be configured by setting an appropriate DateTime format.
94 94 Note that any date before 4714 BCE or after about 1.4 million CE may not be accurately stored.
95 95 DateTimeAxis can be setup to show axis line with tick marks, grid lines and shades.
96 96 */
97 97
98 98 /*!
99 99 \property QDateTimeAxis::min
100 100 Defines the minimum value on the axis.
101 101 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
102 102 */
103 103 /*!
104 104 \qmlproperty datetime DateTimeAxis::min
105 105 Defines the minimum value on the axis.
106 106 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
107 107 */
108 108
109 109 /*!
110 110 \property QDateTimeAxis::max
111 111 Defines the maximum value on the axis.
112 112 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
113 113 */
114 114 /*!
115 115 \qmlproperty datetime DateTimeAxis::max
116 116 Defines the maximum value on the axis.
117 117 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
118 118 */
119 119
120 120 /*!
121 121 \fn void QDateTimeAxis::minChanged(QDateTime min)
122 122 Axis emits signal when \a min of axis has changed.
123 123 */
124 124 /*!
125 125 \qmlsignal DateTimeAxis::onMinChanged(datetime min)
126 126 Axis emits signal when \a min of axis has changed.
127 127 */
128 128
129 129 /*!
130 130 \fn void QDateTimeAxis::maxChanged(QDateTime max)
131 131 Axis emits signal when \a max of axis has changed.
132 132 */
133 133 /*!
134 134 \qmlsignal DateTimeAxis::onMaxChanged(datetime max)
135 135 Axis emits signal when \a max of axis has changed.
136 136 */
137 137
138 138 /*!
139 139 \fn void QDateTimeAxis::rangeChanged(QDateTime min, QDateTime max)
140 140 Axis emits signal when \a min or \a max of axis has changed.
141 141 */
142 142
143 143 /*!
144 144 \property QDateTimeAxis::tickCount
145 145 The number of tick marks for the axis.
146 146 */
147 147
148 148 /*!
149 149 \qmlproperty int DateTimeAxis::tickCount
150 150 The number of tick marks for the axis.
151 151 */
152 152
153 153 /*!
154 154 \property QDateTimeAxis::format
155 155 The format string that is used when creating label for the axis out of a QDateTime object.
156 156 Check QDateTime documentation for information on how the string should be defined.
157 157
158 158 \sa QChart::locale
159 159 */
160 160 /*!
161 161 \qmlproperty string DateTimeAxis::format
162 162 The format string that is used when creating label for the axis out of a QDateTime object.
163 163 Check QDateTime documentation for information on how the string should be defined.
164 164 */
165 165
166 166 /*!
167 167 \fn void QDateTimeAxis::tickCountChanged(int tickCount)
168 168 Axis emits signal when \a tickCount number on axis have changed.
169 169 */
170 170 /*!
171 171 \qmlsignal DateTimeAxis::tickCountChanged(int tickCount)
172 172 Axis emits signal when \a tickCount number on axis have changed.
173 173 */
174 174
175 175 /*!
176 176 \fn void QDateTimeAxis::formatChanged(QString format)
177 177 Axis emits signal when \a format of the axis has changed.
178 178 */
179 179 /*!
180 180 \qmlsignal DateTimeAxis::onFormatChanged(string format)
181 181 Axis emits signal when \a format of the axis has changed.
182 182 */
183 183
184 184 /*!
185 185 Constructs an axis object which is a child of \a parent.
186 186 */
187 187 QDateTimeAxis::QDateTimeAxis(QObject *parent) :
188 188 QAbstractAxis(*new QDateTimeAxisPrivate(this), parent)
189 189 {
190 190
191 191 }
192 192
193 193 /*!
194 194 \internal
195 195 */
196 196 QDateTimeAxis::QDateTimeAxis(QDateTimeAxisPrivate &d, QObject *parent) : QAbstractAxis(d, parent)
197 197 {
198 198
199 199 }
200 200
201 201 /*!
202 202 Destroys the object.
203 203 */
204 204 QDateTimeAxis::~QDateTimeAxis()
205 205 {
206 206 Q_D(QDateTimeAxis);
207 207 if (d->m_chart)
208 208 d->m_chart->removeAxis(this);
209 209 }
210 210
211 211 void QDateTimeAxis::setMin(QDateTime min)
212 212 {
213 213 Q_D(QDateTimeAxis);
214 214 if (min.isValid())
215 215 d->setRange(min.toMSecsSinceEpoch(), qMax(d->m_max, qreal(min.toMSecsSinceEpoch())));
216 216 }
217 217
218 218 QDateTime QDateTimeAxis::min() const
219 219 {
220 220 Q_D(const QDateTimeAxis);
221 221 return QDateTime::fromMSecsSinceEpoch(d->m_min);
222 222 }
223 223
224 224 void QDateTimeAxis::setMax(QDateTime max)
225 225 {
226 226 Q_D(QDateTimeAxis);
227 227 if (max.isValid())
228 228 d->setRange(qMin(d->m_min, qreal(max.toMSecsSinceEpoch())), max.toMSecsSinceEpoch());
229 229 }
230 230
231 231 QDateTime QDateTimeAxis::max() const
232 232 {
233 233 Q_D(const QDateTimeAxis);
234 234 return QDateTime::fromMSecsSinceEpoch(d->m_max);
235 235 }
236 236
237 237 /*!
238 238 Sets range from \a min to \a max on the axis.
239 239 If min is greater than max then this function returns without making any changes.
240 240 */
241 241 void QDateTimeAxis::setRange(QDateTime min, QDateTime max)
242 242 {
243 243 Q_D(QDateTimeAxis);
244 244 if (!min.isValid() || !max.isValid() || min > max)
245 245 return;
246 246
247 247 d->setRange(min.toMSecsSinceEpoch(),max.toMSecsSinceEpoch());
248 248 }
249 249
250 250 void QDateTimeAxis::setFormat(QString format)
251 251 {
252 252 Q_D(QDateTimeAxis);
253 253 if (d->m_format != format) {
254 254 d->m_format = format;
255 255 emit formatChanged(format);
256 256 }
257 257 }
258 258
259 259 QString QDateTimeAxis::format() const
260 260 {
261 261 Q_D(const QDateTimeAxis);
262 262 return d->m_format;
263 263 }
264 264
265 265 /*!
266 266 Sets \a count for ticks on the axis.
267 267 */
268 268 void QDateTimeAxis::setTickCount(int count)
269 269 {
270 270 Q_D(QDateTimeAxis);
271 271 if (d->m_tickCount != count && count >= 2) {
272 272 d->m_tickCount = count;
273 273 emit tickCountChanged(count);
274 274 }
275 275 }
276 276
277 277 /*!
278 278 \fn int QDateTimeAxis::tickCount() const
279 279 Return number of ticks on the axis.
280 280 */
281 281 int QDateTimeAxis::tickCount() const
282 282 {
283 283 Q_D(const QDateTimeAxis);
284 284 return d->m_tickCount;
285 285 }
286 286
287 287 /*!
288 288 Returns the type of the axis.
289 289 */
290 290 QAbstractAxis::AxisType QDateTimeAxis::type() const
291 291 {
292 292 return AxisTypeDateTime;
293 293 }
294 294
295 295 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
296 296
297 297 QDateTimeAxisPrivate::QDateTimeAxisPrivate(QDateTimeAxis *q)
298 298 : QAbstractAxisPrivate(q),
299 299 m_min(0),
300 300 m_max(0),
301 301 m_tickCount(5)
302 302 {
303 303 m_format = QStringLiteral("dd-MM-yyyy\nh:mm");
304 304 }
305 305
306 306 QDateTimeAxisPrivate::~QDateTimeAxisPrivate()
307 307 {
308 308
309 309 }
310 310
311 311 void QDateTimeAxisPrivate::setRange(qreal min,qreal max)
312 312 {
313 313 Q_Q(QDateTimeAxis);
314 314
315 315 bool changed = false;
316 316
317 317 if (m_min != min) {
318 318 m_min = min;
319 319 changed = true;
320 320 emit q->minChanged(QDateTime::fromMSecsSinceEpoch(min));
321 321 }
322 322
323 323 if (m_max != max) {
324 324 m_max = max;
325 325 changed = true;
326 326 emit q->maxChanged(QDateTime::fromMSecsSinceEpoch(max));
327 327 }
328 328
329 329 if (changed) {
330 330 emit q->rangeChanged(QDateTime::fromMSecsSinceEpoch(min), QDateTime::fromMSecsSinceEpoch(max));
331 331 emit rangeChanged(m_min,m_max);
332 332 }
333 333 }
334 334
335 335
336 336 void QDateTimeAxisPrivate::setMin(const QVariant &min)
337 337 {
338 338 Q_Q(QDateTimeAxis);
339 339 if (min.canConvert(QVariant::DateTime))
340 340 q->setMin(min.toDateTime());
341 341 }
342 342
343 343 void QDateTimeAxisPrivate::setMax(const QVariant &max)
344 344 {
345 345
346 346 Q_Q(QDateTimeAxis);
347 347 if (max.canConvert(QVariant::DateTime))
348 348 q->setMax(max.toDateTime());
349 349 }
350 350
351 351 void QDateTimeAxisPrivate::setRange(const QVariant &min, const QVariant &max)
352 352 {
353 353 Q_Q(QDateTimeAxis);
354 354 if (min.canConvert(QVariant::DateTime) && max.canConvert(QVariant::DateTime))
355 355 q->setRange(min.toDateTime(), max.toDateTime());
356 356 }
357 357
358 358 void QDateTimeAxisPrivate::initializeGraphics(QGraphicsItem* parent)
359 359 {
360 360 Q_Q(QDateTimeAxis);
361 361 ChartAxisElement *axis(0);
362 362 if (m_chart->chartType() == QChart::ChartTypeCartesian) {
363 363 if (orientation() == Qt::Vertical)
364 364 axis = new ChartDateTimeAxisY(q,parent);
365 365 if (orientation() == Qt::Horizontal)
366 366 axis = new ChartDateTimeAxisX(q,parent);
367 367 }
368 368
369 369 if (m_chart->chartType() == QChart::ChartTypePolar) {
370 370 if (orientation() == Qt::Vertical)
371 371 axis = new PolarChartDateTimeAxisRadial(q, parent);
372 372 if (orientation() == Qt::Horizontal)
373 373 axis = new PolarChartDateTimeAxisAngular(q, parent);
374 374 }
375 375
376 376 m_item.reset(axis);
377 377 QAbstractAxisPrivate::initializeGraphics(parent);
378 378 }
379 379
380 380 void QDateTimeAxisPrivate::initializeDomain(AbstractDomain *domain)
381 381 {
382 382 if (m_max == m_min) {
383 383 if (orientation() == Qt::Vertical)
384 384 setRange(domain->minY(), domain->maxY());
385 385 else
386 386 setRange(domain->minX(), domain->maxX());
387 387 } else {
388 388 if (orientation() == Qt::Vertical)
389 389 domain->setRangeY(m_min, m_max);
390 390 else
391 391 domain->setRangeX(m_min, m_max);
392 392 }
393 393 }
394 394
395 395 #include "moc_qdatetimeaxis.cpp"
396 396 #include "moc_qdatetimeaxis_p.cpp"
397 397
398 398 QT_CHARTS_END_NAMESPACE
@@ -1,650 +1,650
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <private/chartdataset_p.h>
31 31 #include <private/chartpresenter_p.h>
32 32 #include <QtCharts/QChart>
33 33 #include <private/qchart_p.h>
34 34 #include <QtCharts/QValueAxis>
35 35 #include <QtCharts/QBarCategoryAxis>
36 36 #include <private/qvalueaxis_p.h>
37 37 #include <QtCharts/QCategoryAxis>
38 38 #include <private/qabstractseries_p.h>
39 39 #include <QtCharts/QAbstractBarSeries>
40 40 #include <QtCharts/QStackedBarSeries>
41 41 #include <QtCharts/QPercentBarSeries>
42 42 #include <QtCharts/QPieSeries>
43 43 #include <private/chartitem_p.h>
44 44 #include <private/xydomain_p.h>
45 45 #include <private/xypolardomain_p.h>
46 46 #include <private/xlogydomain_p.h>
47 47 #include <private/logxydomain_p.h>
48 48 #include <private/logxlogydomain_p.h>
49 49 #include <private/xlogypolardomain_p.h>
50 50 #include <private/logxypolardomain_p.h>
51 51 #include <private/logxlogypolardomain_p.h>
52 52 #include <private/glxyseriesdata_p.h>
53 53
54 #ifndef QT_ON_ARM
54 #ifndef QT_QREAL_IS_FLOAT
55 55 #include <QtCharts/QDateTimeAxis>
56 56 #endif
57 57
58 58 QT_CHARTS_BEGIN_NAMESPACE
59 59
60 60 ChartDataSet::ChartDataSet(QChart *chart)
61 61 : QObject(chart),
62 62 m_chart(chart),
63 63 m_glXYSeriesDataManager(new GLXYSeriesDataManager(this))
64 64 {
65 65
66 66 }
67 67
68 68 ChartDataSet::~ChartDataSet()
69 69 {
70 70 deleteAllSeries();
71 71 deleteAllAxes();
72 72 }
73 73
74 74 /*
75 75 * This method adds series to chartdataset, series ownership is taken from caller.
76 76 */
77 77 void ChartDataSet::addSeries(QAbstractSeries *series)
78 78 {
79 79 if (m_seriesList.contains(series)) {
80 80 qWarning() << QObject::tr("Can not add series. Series already on the chart.");
81 81 return;
82 82 }
83 83
84 84 // Ignore unsupported series added to polar chart
85 85 if (m_chart && m_chart->chartType() == QChart::ChartTypePolar) {
86 86 if (!(series->type() == QAbstractSeries::SeriesTypeArea
87 87 || series->type() == QAbstractSeries::SeriesTypeLine
88 88 || series->type() == QAbstractSeries::SeriesTypeScatter
89 89 || series->type() == QAbstractSeries::SeriesTypeSpline)) {
90 90 qWarning() << QObject::tr("Can not add series. Series type is not supported by a polar chart.");
91 91 return;
92 92 }
93 93 // Disable OpenGL for series in polar charts
94 94 series->setUseOpenGL(false);
95 95 series->d_ptr->setDomain(new XYPolarDomain());
96 96 // Set the correct domain for upper and lower series too
97 97 if (series->type() == QAbstractSeries::SeriesTypeArea) {
98 98 foreach (QObject *child, series->children()) {
99 99 if (qobject_cast<QAbstractSeries *>(child)) {
100 100 QAbstractSeries *childSeries = qobject_cast<QAbstractSeries *>(child);
101 101 childSeries->d_ptr->setDomain(new XYPolarDomain());
102 102 }
103 103 }
104 104 }
105 105 } else {
106 106 series->d_ptr->setDomain(new XYDomain());
107 107 }
108 108
109 109 series->d_ptr->initializeDomain();
110 110 m_seriesList.append(series);
111 111
112 112 series->setParent(this); // take ownership
113 113 series->d_ptr->m_chart = m_chart;
114 114
115 115 emit seriesAdded(series);
116 116 }
117 117
118 118 /*
119 119 * This method adds axis to chartdataset, axis ownership is taken from caller.
120 120 */
121 121 void ChartDataSet::addAxis(QAbstractAxis *axis, Qt::Alignment aligment)
122 122 {
123 123 if (m_axisList.contains(axis)) {
124 124 qWarning() << QObject::tr("Can not add axis. Axis already on the chart.");
125 125 return;
126 126 }
127 127
128 128 axis->d_ptr->setAlignment(aligment);
129 129
130 130 if (!axis->alignment()) {
131 131 qWarning() << QObject::tr("No alignment specified !");
132 132 return;
133 133 };
134 134
135 135 AbstractDomain *newDomain;
136 136 if (m_chart && m_chart->chartType() == QChart::ChartTypePolar)
137 137 newDomain = new XYPolarDomain();
138 138 else
139 139 newDomain = new XYDomain();
140 140
141 141 QSharedPointer<AbstractDomain> domain(newDomain);
142 142 axis->d_ptr->initializeDomain(domain.data());
143 143
144 144 axis->setParent(this);
145 145 axis->d_ptr->m_chart = m_chart;
146 146 m_axisList.append(axis);
147 147
148 148 emit axisAdded(axis);
149 149 }
150 150
151 151 /*
152 152 * This method removes series form chartdataset, series ownership is passed back to caller.
153 153 */
154 154 void ChartDataSet::removeSeries(QAbstractSeries *series)
155 155 {
156 156
157 157 if (! m_seriesList.contains(series)) {
158 158 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
159 159 return;
160 160 }
161 161
162 162 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
163 163
164 164 foreach(QAbstractAxis* axis, axes) {
165 165 detachAxis(series,axis);
166 166 }
167 167
168 168 emit seriesRemoved(series);
169 169 m_seriesList.removeAll(series);
170 170
171 171 // Reset domain to default
172 172 series->d_ptr->setDomain(new XYDomain());
173 173 series->setParent(0);
174 174 series->d_ptr->m_chart = 0;
175 175
176 176 QXYSeries *xySeries = qobject_cast<QXYSeries *>(series);
177 177 if (xySeries)
178 178 m_glXYSeriesDataManager->removeSeries(xySeries);
179 179 }
180 180
181 181 /*
182 182 * This method removes axis form chartdataset, series ownership is passed back to caller.
183 183 */
184 184 void ChartDataSet::removeAxis(QAbstractAxis *axis)
185 185 {
186 186 if (! m_axisList.contains(axis)) {
187 187 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
188 188 return;
189 189 }
190 190
191 191 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
192 192
193 193 foreach(QAbstractSeries* s, series) {
194 194 detachAxis(s,axis);
195 195 }
196 196
197 197 emit axisRemoved(axis);
198 198 m_axisList.removeAll(axis);
199 199
200 200 axis->setParent(0);
201 201 axis->d_ptr->m_chart = 0;
202 202 }
203 203
204 204 /*
205 205 * This method attaches axis to series, return true if success.
206 206 */
207 207 bool ChartDataSet::attachAxis(QAbstractSeries *series,QAbstractAxis *axis)
208 208 {
209 209 Q_ASSERT(axis);
210 210
211 211 if (!series)
212 212 return false;
213 213
214 214 QList<QAbstractSeries *> attachedSeriesList = axis->d_ptr->m_series;
215 215 QList<QAbstractAxis *> attachedAxisList = series->d_ptr->m_axes;
216 216
217 217 if (!m_seriesList.contains(series)) {
218 218 qWarning() << QObject::tr("Can not find series on the chart.");
219 219 return false;
220 220 }
221 221
222 222 if (axis && !m_axisList.contains(axis)) {
223 223 qWarning() << QObject::tr("Can not find axis on the chart.");
224 224 return false;
225 225 }
226 226
227 227 if (attachedAxisList.contains(axis)) {
228 228 qWarning() << QObject::tr("Axis already attached to series.");
229 229 return false;
230 230 }
231 231
232 232 if (attachedSeriesList.contains(series)) {
233 233 qWarning() << QObject::tr("Axis already attached to series.");
234 234 return false;
235 235 }
236 236
237 237 AbstractDomain *domain = series->d_ptr->domain();
238 238 AbstractDomain::DomainType type = selectDomain(attachedAxisList<<axis);
239 239
240 240 if (type == AbstractDomain::UndefinedDomain) return false;
241 241
242 242 if (domain->type() != type) {
243 243 AbstractDomain *old = domain;
244 244 domain = createDomain(type);
245 245 domain->setRange(old->minX(), old->maxX(), old->minY(), old->maxY());
246 246 // Initialize domain size to old domain size, as it won't get updated
247 247 // unless geometry changes.
248 248 domain->setSize(old->size());
249 249 }
250 250
251 251 if (!domain)
252 252 return false;
253 253
254 254 if (!domain->attachAxis(axis))
255 255 return false;
256 256
257 257 QList<AbstractDomain *> blockedDomains;
258 258 domain->blockRangeSignals(true);
259 259 blockedDomains << domain;
260 260
261 261 if (domain != series->d_ptr->domain()) {
262 262 foreach (QAbstractAxis *axis, series->d_ptr->m_axes) {
263 263 series->d_ptr->domain()->detachAxis(axis);
264 264 domain->attachAxis(axis);
265 265 foreach (QAbstractSeries *otherSeries, axis->d_ptr->m_series) {
266 266 if (otherSeries != series && otherSeries->d_ptr->domain()) {
267 267 if (!otherSeries->d_ptr->domain()->rangeSignalsBlocked()) {
268 268 otherSeries->d_ptr->domain()->blockRangeSignals(true);
269 269 blockedDomains << otherSeries->d_ptr->domain();
270 270 }
271 271 }
272 272 }
273 273 }
274 274 series->d_ptr->setDomain(domain);
275 275 series->d_ptr->initializeDomain();
276 276 }
277 277
278 278 series->d_ptr->m_axes<<axis;
279 279 axis->d_ptr->m_series<<series;
280 280
281 281 series->d_ptr->initializeAxes();
282 282 axis->d_ptr->initializeDomain(domain);
283 283
284 284 foreach (AbstractDomain *blockedDomain, blockedDomains)
285 285 blockedDomain->blockRangeSignals(false);
286 286
287 287 return true;
288 288 }
289 289
290 290 /*
291 291 * This method detaches axis to series, return true if success.
292 292 */
293 293 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
294 294 {
295 295 Q_ASSERT(series);
296 296 Q_ASSERT(axis);
297 297
298 298 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
299 299 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
300 300 AbstractDomain* domain = series->d_ptr->domain();
301 301
302 302 if (!m_seriesList.contains(series)) {
303 303 qWarning() << QObject::tr("Can not find series on the chart.");
304 304 return false;
305 305 }
306 306
307 307 if (axis && !m_axisList.contains(axis)) {
308 308 qWarning() << QObject::tr("Can not find axis on the chart.");
309 309 return false;
310 310 }
311 311
312 312 if (!attachedAxisList.contains(axis)) {
313 313 qWarning() << QObject::tr("Axis not attached to series.");
314 314 return false;
315 315 }
316 316
317 317 Q_ASSERT(axis->d_ptr->m_series.contains(series));
318 318
319 319 domain->detachAxis(axis);
320 320 series->d_ptr->m_axes.removeAll(axis);
321 321 axis->d_ptr->m_series.removeAll(series);
322 322
323 323 return true;
324 324 }
325 325
326 326 void ChartDataSet::createDefaultAxes()
327 327 {
328 328 if (m_seriesList.isEmpty())
329 329 return;
330 330
331 331 QAbstractAxis::AxisTypes typeX(0);
332 332 QAbstractAxis::AxisTypes typeY(0);
333 333
334 334 // Remove possibly existing axes
335 335 deleteAllAxes();
336 336
337 337 Q_ASSERT(m_axisList.isEmpty());
338 338
339 339 // Select the required axis x and axis y types based on the types of the current series
340 340 foreach(QAbstractSeries* s, m_seriesList) {
341 341 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
342 342 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
343 343 }
344 344
345 345 createAxes(typeX, Qt::Horizontal);
346 346 createAxes(typeY, Qt::Vertical);
347 347 }
348 348
349 349 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
350 350 {
351 351 QAbstractAxis *axis = 0;
352 352 //decide what axis should be created
353 353
354 354 switch (type) {
355 355 case QAbstractAxis::AxisTypeValue:
356 356 axis = new QValueAxis(this);
357 357 break;
358 358 case QAbstractAxis::AxisTypeBarCategory:
359 359 axis = new QBarCategoryAxis(this);
360 360 break;
361 361 case QAbstractAxis::AxisTypeCategory:
362 362 axis = new QCategoryAxis(this);
363 363 break;
364 #ifndef Q_WS_QWS
364 #ifndef QT_QREAL_IS_FLOAT
365 365 case QAbstractAxis::AxisTypeDateTime:
366 366 axis = new QDateTimeAxis(this);
367 367 break;
368 368 #endif
369 369 default:
370 370 axis = 0;
371 371 break;
372 372 }
373 373
374 374 if (axis) {
375 375 //create one axis for all
376 376
377 377 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
378 378 qreal min = 0;
379 379 qreal max = 0;
380 380 findMinMaxForSeries(m_seriesList,orientation,min,max);
381 381 foreach(QAbstractSeries *s, m_seriesList) {
382 382 attachAxis(s,axis);
383 383 }
384 384 axis->setRange(min,max);
385 385 } else {
386 386 // Create separate axis for each series
387 387 foreach(QAbstractSeries *s, m_seriesList) {
388 388 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
389 389 if(axis) {
390 390 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
391 391 attachAxis(s,axis);
392 392 }
393 393 }
394 394 }
395 395 }
396 396
397 397 void ChartDataSet::findMinMaxForSeries(QList<QAbstractSeries *> series,Qt::Orientations orientation, qreal &min, qreal &max)
398 398 {
399 399 Q_ASSERT(!series.isEmpty());
400 400
401 401 AbstractDomain *domain = series.first()->d_ptr->domain();
402 402 min = (orientation == Qt::Vertical) ? domain->minY() : domain->minX();
403 403 max = (orientation == Qt::Vertical) ? domain->maxY() : domain->maxX();
404 404
405 405 for (int i = 1; i< series.size(); i++) {
406 406 AbstractDomain *domain = series[i]->d_ptr->domain();
407 407 min = qMin((orientation == Qt::Vertical) ? domain->minY() : domain->minX(), min);
408 408 max = qMax((orientation == Qt::Vertical) ? domain->maxY() : domain->maxX(), max);
409 409 }
410 410 if (min == max) {
411 411 min -= 0.5;
412 412 max += 0.5;
413 413 }
414 414 }
415 415
416 416 void ChartDataSet::deleteAllSeries()
417 417 {
418 418 foreach (QAbstractSeries *s , m_seriesList){
419 419 removeSeries(s);
420 420 s->deleteLater();
421 421 }
422 422 Q_ASSERT(m_seriesList.count() == 0);
423 423 }
424 424
425 425 void ChartDataSet::deleteAllAxes()
426 426 {
427 427 foreach (QAbstractAxis *a , m_axisList){
428 428 removeAxis(a);
429 429 a->deleteLater();
430 430 }
431 431 Q_ASSERT(m_axisList.count() == 0);
432 432 }
433 433
434 434 void ChartDataSet::zoomInDomain(const QRectF &rect)
435 435 {
436 436 QList<AbstractDomain*> domains;
437 437 foreach(QAbstractSeries *s, m_seriesList) {
438 438 AbstractDomain* domain = s->d_ptr->domain();
439 439 s->d_ptr->m_domain->blockRangeSignals(true);
440 440 domains<<domain;
441 441 }
442 442
443 443 foreach(AbstractDomain *domain, domains)
444 444 domain->zoomIn(rect);
445 445
446 446 foreach(AbstractDomain *domain, domains)
447 447 domain->blockRangeSignals(false);
448 448 }
449 449
450 450 void ChartDataSet::zoomOutDomain(const QRectF &rect)
451 451 {
452 452 QList<AbstractDomain*> domains;
453 453 foreach(QAbstractSeries *s, m_seriesList) {
454 454 AbstractDomain* domain = s->d_ptr->domain();
455 455 s->d_ptr->m_domain->blockRangeSignals(true);
456 456 domains<<domain;
457 457 }
458 458
459 459 foreach(AbstractDomain *domain, domains)
460 460 domain->zoomOut(rect);
461 461
462 462 foreach(AbstractDomain *domain, domains)
463 463 domain->blockRangeSignals(false);
464 464 }
465 465
466 466 void ChartDataSet::zoomResetDomain()
467 467 {
468 468 QList<AbstractDomain*> domains;
469 469 foreach (QAbstractSeries *s, m_seriesList) {
470 470 AbstractDomain *domain = s->d_ptr->domain();
471 471 s->d_ptr->m_domain->blockRangeSignals(true);
472 472 domains << domain;
473 473 }
474 474
475 475 foreach (AbstractDomain *domain, domains)
476 476 domain->zoomReset();
477 477
478 478 foreach (AbstractDomain *domain, domains)
479 479 domain->blockRangeSignals(false);
480 480 }
481 481
482 482 bool ChartDataSet::isZoomedDomain()
483 483 {
484 484 foreach (QAbstractSeries *s, m_seriesList) {
485 485 if (s->d_ptr->domain()->isZoomed())
486 486 return true;
487 487 }
488 488 return false;
489 489 }
490 490
491 491 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
492 492 {
493 493 QList<AbstractDomain*> domains;
494 494 foreach(QAbstractSeries *s, m_seriesList) {
495 495 AbstractDomain* domain = s->d_ptr->domain();
496 496 s->d_ptr->m_domain->blockRangeSignals(true);
497 497 domains<<domain;
498 498 }
499 499
500 500 foreach(AbstractDomain *domain, domains)
501 501 domain->move(dx, dy);
502 502
503 503 foreach(AbstractDomain *domain, domains)
504 504 domain->blockRangeSignals(false);
505 505 }
506 506
507 507 QPointF ChartDataSet::mapToValue(const QPointF &position, QAbstractSeries *series)
508 508 {
509 509 QPointF point;
510 510 if (series == 0 && !m_seriesList.isEmpty())
511 511 series = m_seriesList.first();
512 512
513 513 if (series && series->type() == QAbstractSeries::SeriesTypePie)
514 514 return point;
515 515
516 516 if (series && m_seriesList.contains(series))
517 517 point = series->d_ptr->m_domain->calculateDomainPoint(position - m_chart->plotArea().topLeft());
518 518 return point;
519 519 }
520 520
521 521 QPointF ChartDataSet::mapToPosition(const QPointF &value, QAbstractSeries *series)
522 522 {
523 523 QPointF point = m_chart->plotArea().topLeft();
524 524 if (series == 0 && !m_seriesList.isEmpty())
525 525 series = m_seriesList.first();
526 526
527 527 if (series && series->type() == QAbstractSeries::SeriesTypePie)
528 528 return QPoint(0, 0);
529 529
530 530 bool ok;
531 531 if (series && m_seriesList.contains(series))
532 532 point += series->d_ptr->m_domain->calculateGeometryPoint(value, ok);
533 533 return point;
534 534 }
535 535
536 536 QList<QAbstractAxis *> ChartDataSet::axes() const
537 537 {
538 538 return m_axisList;
539 539 }
540 540
541 541 QList<QAbstractSeries *> ChartDataSet::series() const
542 542 {
543 543 return m_seriesList;
544 544 }
545 545
546 546 AbstractDomain::DomainType ChartDataSet::selectDomain(QList<QAbstractAxis *> axes)
547 547 {
548 548 enum Type {
549 549 Undefined = 0,
550 550 LogType = 0x1,
551 551 ValueType = 0x2
552 552 };
553 553
554 554 int horizontal(Undefined);
555 555 int vertical(Undefined);
556 556
557 557 // Assume cartesian chart type, unless chart is set
558 558 QChart::ChartType chartType(QChart::ChartTypeCartesian);
559 559 if (m_chart)
560 560 chartType = m_chart->chartType();
561 561
562 562 foreach (QAbstractAxis *axis, axes)
563 563 {
564 564 switch (axis->type()) {
565 565 case QAbstractAxis::AxisTypeLogValue:
566 566 if (axis->orientation() == Qt::Horizontal)
567 567 horizontal |= LogType;
568 568 if (axis->orientation() == Qt::Vertical)
569 569 vertical |= LogType;
570 570 break;
571 571 case QAbstractAxis::AxisTypeValue:
572 572 case QAbstractAxis::AxisTypeBarCategory:
573 573 case QAbstractAxis::AxisTypeCategory:
574 574 case QAbstractAxis::AxisTypeDateTime:
575 575 if (axis->orientation() == Qt::Horizontal)
576 576 horizontal |= ValueType;
577 577 if (axis->orientation() == Qt::Vertical)
578 578 vertical |= ValueType;
579 579 break;
580 580 default:
581 581 qWarning() << "Undefined type";
582 582 break;
583 583 }
584 584 }
585 585
586 586 if (vertical == Undefined)
587 587 vertical = ValueType;
588 588 if (horizontal == Undefined)
589 589 horizontal = ValueType;
590 590
591 591 if (vertical == ValueType && horizontal == ValueType) {
592 592 if (chartType == QChart::ChartTypeCartesian)
593 593 return AbstractDomain::XYDomain;
594 594 else if (chartType == QChart::ChartTypePolar)
595 595 return AbstractDomain::XYPolarDomain;
596 596 }
597 597
598 598 if (vertical == LogType && horizontal == ValueType) {
599 599 if (chartType == QChart::ChartTypeCartesian)
600 600 return AbstractDomain::XLogYDomain;
601 601 if (chartType == QChart::ChartTypePolar)
602 602 return AbstractDomain::XLogYPolarDomain;
603 603 }
604 604
605 605 if (vertical == ValueType && horizontal == LogType) {
606 606 if (chartType == QChart::ChartTypeCartesian)
607 607 return AbstractDomain::LogXYDomain;
608 608 else if (chartType == QChart::ChartTypePolar)
609 609 return AbstractDomain::LogXYPolarDomain;
610 610 }
611 611
612 612 if (vertical == LogType && horizontal == LogType) {
613 613 if (chartType == QChart::ChartTypeCartesian)
614 614 return AbstractDomain::LogXLogYDomain;
615 615 else if (chartType == QChart::ChartTypePolar)
616 616 return AbstractDomain::LogXLogYPolarDomain;
617 617 }
618 618
619 619 return AbstractDomain::UndefinedDomain;
620 620 }
621 621
622 622 //refactor create factory
623 623 AbstractDomain* ChartDataSet::createDomain(AbstractDomain::DomainType type)
624 624 {
625 625 switch (type)
626 626 {
627 627 case AbstractDomain::LogXLogYDomain:
628 628 return new LogXLogYDomain();
629 629 case AbstractDomain::XYDomain:
630 630 return new XYDomain();
631 631 case AbstractDomain::XLogYDomain:
632 632 return new XLogYDomain();
633 633 case AbstractDomain::LogXYDomain:
634 634 return new LogXYDomain();
635 635 case AbstractDomain::XYPolarDomain:
636 636 return new XYPolarDomain();
637 637 case AbstractDomain::XLogYPolarDomain:
638 638 return new XLogYPolarDomain();
639 639 case AbstractDomain::LogXYPolarDomain:
640 640 return new LogXYPolarDomain();
641 641 case AbstractDomain::LogXLogYPolarDomain:
642 642 return new LogXLogYPolarDomain();
643 643 default:
644 644 return 0;
645 645 }
646 646 }
647 647
648 648 #include "moc_chartdataset_p.cpp"
649 649
650 650 QT_CHARTS_END_NAMESPACE
@@ -1,96 +1,98
1 1 ############################# BUILD CONFIG ######################################
2 2
3 3 TARGET = QtCharts
4 4
5 5 message($$QT_CONFIG)
6 6 QT = core gui widgets
7 7 DEFINES += QT_CHARTS_LIBRARY
8 contains(QT_COORD_TYPE, float): DEFINES += QT_QREAL_IS_FLOAT
9
8 10 # Fix exports in static builds for applications linking charts module
9 11 static: MODULE_DEFINES += QT_CHARTS_STATICLIB
10 12
11 13 MODULE_INCNAME = QtCharts
12 14
13 15 QMAKE_DOCS = $$PWD/doc/qtcharts.qdocconf
14 16
15 17 load(qt_module)
16 18
17 19 QMAKE_TARGET_PRODUCT = "Qt Charts (Qt $$QT_VERSION)"
18 20 QMAKE_TARGET_DESCRIPTION = "Charts component for Qt."
19 21
20 22 ############################# SOURCES ##########################################
21 23
22 24 SOURCES += \
23 25 $$PWD/chartdataset.cpp \
24 26 $$PWD/chartpresenter.cpp \
25 27 $$PWD/chartthememanager.cpp \
26 28 $$PWD/qchart.cpp \
27 29 $$PWD/qchartview.cpp \
28 30 $$PWD/qabstractseries.cpp \
29 31 $$PWD/chartbackground.cpp \
30 32 $$PWD/chartelement.cpp \
31 33 $$PWD/chartitem.cpp \
32 34 $$PWD/scroller.cpp \
33 35 $$PWD/charttitle.cpp \
34 36 $$PWD/qpolarchart.cpp
35 37
36 38 contains(QT_CONFIG, opengl): SOURCES += $$PWD/glwidget.cpp
37 39
38 40 PRIVATE_HEADERS += \
39 41 $$PWD/chartdataset_p.h \
40 42 $$PWD/chartitem_p.h \
41 43 $$PWD/chartpresenter_p.h \
42 44 $$PWD/chartthememanager_p.h \
43 45 $$PWD/chartbackground_p.h \
44 46 $$PWD/chartelement_p.h \
45 47 $$PWD/chartconfig_p.h \
46 48 $$PWD/qchart_p.h \
47 49 $$PWD/qchartview_p.h \
48 50 $$PWD/scroller_p.h \
49 51 $$PWD/qabstractseries_p.h \
50 52 $$PWD/charttitle_p.h \
51 53 $$PWD/charthelpers_p.h
52 54
53 55 contains(QT_CONFIG, opengl): PRIVATE_HEADERS += $$PWD/glwidget_p.h
54 56
55 57 PUBLIC_HEADERS += \
56 58 $$PWD/qchart.h \
57 59 $$PWD/qchartglobal.h \
58 60 $$PWD/qabstractseries.h \
59 61 $$PWD/qchartview.h \
60 62 $$PWD/chartsnamespace.h \
61 63 $$PWD/qpolarchart.h
62 64
63 65 include($$PWD/common.pri)
64 66 include($$PWD/animations/animations.pri)
65 67 include($$PWD/areachart/areachart.pri)
66 68 include($$PWD/axis/axis.pri)
67 69 include($$PWD/domain/domain.pri)
68 70 include($$PWD/barchart/barchart.pri)
69 71 include($$PWD/legend/legend.pri)
70 72 include($$PWD/linechart/linechart.pri)
71 73 include($$PWD/piechart/piechart.pri)
72 74 include($$PWD/scatterchart/scatter.pri)
73 75 include($$PWD/splinechart/splinechart.pri)
74 76 include($$PWD/themes/themes.pri)
75 77 include($$PWD/xychart/xychart.pri)
76 78 include($$PWD/layout/layout.pri)
77 79 include($$PWD/boxplotchart/boxplotchart.pri)
78 80
79 81 HEADERS += $$PUBLIC_HEADERS
80 82 HEADERS += $$PRIVATE_HEADERS
81 83 HEADERS += $$THEMES
82 84
83 85 OTHER_FILES += doc/qtcharts.qdocconf \
84 86 doc/src/* \
85 87 doc/images/*
86 88
87 89 msvc {
88 90 # Suppress "conversion from 'size_t' to 'int', possible loss of data" warnings in 64bit
89 91 # builds resulting from usage of str::sort
90 92 QMAKE_CXXFLAGS_WARN_ON += -wd4267
91 93 }
92 94
93 95 win32:!winrt:!wince {
94 96 # ChartThemeSystem uses Windows native API
95 97 LIBS += -luser32
96 98 }
@@ -1,72 +1,73
1 1
2 2 TARGET = qtchartsqml2
3 3 QT += qml quick
4 4 QT += charts charts-private
5 5 TARGETPATH = QtCharts
6 contains(QT_COORD_TYPE, float): DEFINES += QT_QREAL_IS_FLOAT
6 7
7 8 IMPORT_VERSION = $$MODULE_VERSION
8 9
9 10 # Only build qml plugin static if Qt itself is also built static
10 11 !contains(QT_CONFIG, static): CONFIG -= static staticlib
11 12
12 13 include($$PWD/designer/designer.pri)
13 14
14 15 INCLUDEPATH += ../../include \
15 16 ../../include/QtCharts \
16 17 ../charts \
17 18 ../charts/animations \
18 19 ../charts/axis \
19 20 ../charts/domain
20 21
21 22 SOURCES += \
22 23 chartsqml2_plugin.cpp \
23 24 declarativechart.cpp \
24 25 declarativexypoint.cpp \
25 26 declarativexyseries.cpp \
26 27 declarativelineseries.cpp \
27 28 declarativesplineseries.cpp \
28 29 declarativeareaseries.cpp \
29 30 declarativescatterseries.cpp \
30 31 declarativepieseries.cpp \
31 32 declarativebarseries.cpp \
32 33 declarativecategoryaxis.cpp \
33 34 declarativemargins.cpp \
34 35 declarativeaxes.cpp \
35 36 declarativepolarchart.cpp \
36 37 declarativeboxplotseries.cpp \
37 38 declarativechartnode.cpp \
38 39 declarativerendernode.cpp
39 40
40 41 HEADERS += \
41 42 declarativechart.h \
42 43 declarativexypoint.h \
43 44 declarativexyseries.h \
44 45 declarativelineseries.h \
45 46 declarativesplineseries.h \
46 47 declarativeareaseries.h \
47 48 declarativescatterseries.h \
48 49 declarativepieseries.h \
49 50 declarativebarseries.h \
50 51 declarativecategoryaxis.h \
51 52 declarativemargins.h \
52 53 declarativeaxes.h \
53 54 declarativepolarchart.h \
54 55 declarativeboxplotseries.h \
55 56 declarativechartnode.h \
56 57 declarativerendernode.h
57 58
58 59 OTHER_FILES = qmldir
59 60
60 61 CONFIG += no_cxx_module
61 62
62 63 load(qml_plugin)
63 64
64 65 win32 {
65 66 CONFIG += skip_target_version_ext
66 67 VERSION = $$MODULE_VERSION
67 68 QMAKE_TARGET_PRODUCT = "Qt Charts (Qt $$QT_VERSION)"
68 69 QMAKE_TARGET_DESCRIPTION = "Charts QML plugin for Qt."
69 70 }
70 71
71 72 QML_FILES += \
72 73 $$PWD/plugins.qmltypes
@@ -1,331 +1,333
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtCharts/QChart>
31 31 #include <QtCharts/QAbstractAxis>
32 32 #include <QtCharts/QValueAxis>
33 33 #include <QtCharts/QLogValueAxis>
34 34 #include "declarativecategoryaxis.h"
35 35 #include <QtCharts/QBarCategoryAxis>
36 36 #include "declarativechart.h"
37 37 #include "declarativepolarchart.h"
38 38 #include "declarativexypoint.h"
39 39 #include "declarativelineseries.h"
40 40 #include "declarativesplineseries.h"
41 41 #include "declarativeareaseries.h"
42 42 #include "declarativescatterseries.h"
43 43 #include "declarativebarseries.h"
44 44 #include "declarativeboxplotseries.h"
45 45 #include "declarativepieseries.h"
46 46 #include "declarativeaxes.h"
47 47 #include <QtCharts/QVXYModelMapper>
48 48 #include <QtCharts/QHXYModelMapper>
49 49 #include <QtCharts/QHPieModelMapper>
50 50 #include <QtCharts/QVPieModelMapper>
51 51 #include <QtCharts/QHBarModelMapper>
52 52 #include <QtCharts/QVBarModelMapper>
53 53 #include "declarativemargins.h"
54 54 #include <QtCharts/QAreaLegendMarker>
55 55 #include <QtCharts/QBarLegendMarker>
56 56 #include <QtCharts/QPieLegendMarker>
57 57 #include <QtCharts/QXYLegendMarker>
58 58 #include <QtCharts/QBoxPlotModelMapper>
59 59 #include <QtCharts/QVBoxPlotModelMapper>
60 #ifndef QT_ON_ARM
60 #ifndef QT_QREAL_IS_FLOAT
61 61 #include <QtCharts/QDateTimeAxis>
62 62 #endif
63 63 #include <QtCore/QAbstractItemModel>
64 64 #include <QtQml>
65 65
66 66 QT_CHARTS_USE_NAMESPACE
67 67
68 68 QML_DECLARE_TYPE(QList<QPieSlice *>)
69 69 QML_DECLARE_TYPE(QList<QBarSet *>)
70 70 QML_DECLARE_TYPE(QList<QAbstractAxis *>)
71 71
72 72 QML_DECLARE_TYPE(DeclarativeChart)
73 73 QML_DECLARE_TYPE(DeclarativePolarChart)
74 74 QML_DECLARE_TYPE(DeclarativeMargins)
75 75 QML_DECLARE_TYPE(DeclarativeAreaSeries)
76 76 QML_DECLARE_TYPE(DeclarativeBarSeries)
77 77 QML_DECLARE_TYPE(DeclarativeBarSet)
78 78 QML_DECLARE_TYPE(DeclarativeBoxPlotSeries)
79 79 QML_DECLARE_TYPE(DeclarativeBoxSet)
80 80 QML_DECLARE_TYPE(DeclarativeLineSeries)
81 81 QML_DECLARE_TYPE(DeclarativePieSeries)
82 82 QML_DECLARE_TYPE(DeclarativePieSlice)
83 83 QML_DECLARE_TYPE(DeclarativeScatterSeries)
84 84 QML_DECLARE_TYPE(DeclarativeSplineSeries)
85 85
86 86 QML_DECLARE_TYPE(QAbstractAxis)
87 87 QML_DECLARE_TYPE(QValueAxis)
88 88 QML_DECLARE_TYPE(QBarCategoryAxis)
89 89 QML_DECLARE_TYPE(QCategoryAxis)
90 QML_DECLARE_TYPE(QDateTimeAxis)
90 #ifndef QT_QREAL_IS_FLOAT
91 QML_DECLARE_TYPE(QDateTimeAxis)
92 #endif
91 93 QML_DECLARE_TYPE(QLogValueAxis)
92 94
93 95 QML_DECLARE_TYPE(QLegend)
94 96 QML_DECLARE_TYPE(QLegendMarker)
95 97 QML_DECLARE_TYPE(QAreaLegendMarker)
96 98 QML_DECLARE_TYPE(QBarLegendMarker)
97 99 QML_DECLARE_TYPE(QPieLegendMarker)
98 100
99 101 QML_DECLARE_TYPE(QHPieModelMapper)
100 102 QML_DECLARE_TYPE(QHXYModelMapper)
101 103 QML_DECLARE_TYPE(QPieModelMapper)
102 104 QML_DECLARE_TYPE(QHBarModelMapper)
103 105 QML_DECLARE_TYPE(QBarModelMapper)
104 106 QML_DECLARE_TYPE(QVBarModelMapper)
105 107 QML_DECLARE_TYPE(QVPieModelMapper)
106 108 QML_DECLARE_TYPE(QVXYModelMapper)
107 109 QML_DECLARE_TYPE(QXYLegendMarker)
108 110 QML_DECLARE_TYPE(QXYModelMapper)
109 111 QML_DECLARE_TYPE(QBoxPlotModelMapper)
110 112 QML_DECLARE_TYPE(QVBoxPlotModelMapper)
111 113
112 114 QML_DECLARE_TYPE(QAbstractSeries)
113 115 QML_DECLARE_TYPE(QXYSeries)
114 116 QML_DECLARE_TYPE(QAbstractBarSeries)
115 117 QML_DECLARE_TYPE(QBarSeries)
116 118 QML_DECLARE_TYPE(QBarSet)
117 119 QML_DECLARE_TYPE(QAreaSeries)
118 120 QML_DECLARE_TYPE(QHorizontalBarSeries)
119 121 QML_DECLARE_TYPE(QHorizontalPercentBarSeries)
120 122 QML_DECLARE_TYPE(QHorizontalStackedBarSeries)
121 123 QML_DECLARE_TYPE(QLineSeries)
122 124 QML_DECLARE_TYPE(QPercentBarSeries)
123 125 QML_DECLARE_TYPE(QPieSeries)
124 126 QML_DECLARE_TYPE(QPieSlice)
125 127 QML_DECLARE_TYPE(QScatterSeries)
126 128 QML_DECLARE_TYPE(QSplineSeries)
127 129 QML_DECLARE_TYPE(QStackedBarSeries)
128 130
129 131 QT_CHARTS_BEGIN_NAMESPACE
130 132
131 133 class QtChartsQml2Plugin : public QQmlExtensionPlugin
132 134 {
133 135 Q_OBJECT
134 136
135 137 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
136 138
137 139 public:
138 140 virtual void registerTypes(const char *uri)
139 141 {
140 142 Q_ASSERT(QLatin1String(uri) == QLatin1String("QtCharts"));
141 143
142 144 // @uri QtCharts
143 145
144 146 qRegisterMetaType<QList<QPieSlice *> >();
145 147 qRegisterMetaType<QList<QBarSet *> >();
146 148 qRegisterMetaType<QList<QAbstractAxis *> >();
147 149
148 150 // QtCharts 1.0
149 151 qmlRegisterType<DeclarativeChart>(uri, 1, 0, "ChartView");
150 152 qmlRegisterType<DeclarativeXYPoint>(uri, 1, 0, "XYPoint");
151 153 qmlRegisterType<DeclarativeScatterSeries>(uri, 1, 0, "ScatterSeries");
152 154 qmlRegisterType<DeclarativeLineSeries>(uri, 1, 0, "LineSeries");
153 155 qmlRegisterType<DeclarativeSplineSeries>(uri, 1, 0, "SplineSeries");
154 156 qmlRegisterType<DeclarativeAreaSeries>(uri, 1, 0, "AreaSeries");
155 157 qmlRegisterType<DeclarativeBarSeries>(uri, 1, 0, "BarSeries");
156 158 qmlRegisterType<DeclarativeStackedBarSeries>(uri, 1, 0, "StackedBarSeries");
157 159 qmlRegisterType<DeclarativePercentBarSeries>(uri, 1, 0, "PercentBarSeries");
158 160 qmlRegisterType<DeclarativePieSeries>(uri, 1, 0, "PieSeries");
159 161 qmlRegisterType<QPieSlice>(uri, 1, 0, "PieSlice");
160 162 qmlRegisterType<DeclarativeBarSet>(uri, 1, 0, "BarSet");
161 163 qmlRegisterType<QHXYModelMapper>(uri, 1, 0, "HXYModelMapper");
162 164 qmlRegisterType<QVXYModelMapper>(uri, 1, 0, "VXYModelMapper");
163 165 qmlRegisterType<QHPieModelMapper>(uri, 1, 0, "HPieModelMapper");
164 166 qmlRegisterType<QVPieModelMapper>(uri, 1, 0, "VPieModelMapper");
165 167 qmlRegisterType<QHBarModelMapper>(uri, 1, 0, "HBarModelMapper");
166 168 qmlRegisterType<QVBarModelMapper>(uri, 1, 0, "VBarModelMapper");
167 169
168 170 qmlRegisterType<QValueAxis>(uri, 1, 0, "ValuesAxis");
169 171 qmlRegisterType<QBarCategoryAxis>(uri, 1, 0, "BarCategoriesAxis");
170 172 qmlRegisterUncreatableType<QLegend>(uri, 1, 0, "Legend",
171 173 QLatin1String("Trying to create uncreatable: Legend."));
172 174 qmlRegisterUncreatableType<QXYSeries>(uri, 1, 0, "XYSeries",
173 175 QLatin1String("Trying to create uncreatable: XYSeries."));
174 176 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
175 177 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
176 178 qmlRegisterUncreatableType<QXYModelMapper>(uri, 1, 0, "XYModelMapper",
177 179 QLatin1String("Trying to create uncreatable: XYModelMapper."));
178 180 qmlRegisterUncreatableType<QPieModelMapper>(uri, 1, 0, "PieModelMapper",
179 181 QLatin1String("Trying to create uncreatable: PieModelMapper."));
180 182 qmlRegisterUncreatableType<QBarModelMapper>(uri, 1, 0, "BarModelMapper",
181 183 QLatin1String("Trying to create uncreatable: BarModelMapper."));
182 184 qmlRegisterUncreatableType<QAbstractSeries>(uri, 1, 0, "AbstractSeries",
183 185 QLatin1String("Trying to create uncreatable: AbstractSeries."));
184 186 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 1, 0, "AbstractBarSeries",
185 187 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
186 188 qmlRegisterUncreatableType<QAbstractAxis>(uri, 1, 0, "AbstractAxis",
187 189 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
188 190 qmlRegisterUncreatableType<QBarSet>(uri, 1, 0, "BarSetBase",
189 191 QLatin1String("Trying to create uncreatable: BarsetBase."));
190 192 qmlRegisterUncreatableType<QPieSeries>(uri, 1, 0, "QPieSeries",
191 193 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
192 194 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 1, 0, "DeclarativeAxes",
193 195 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
194 196
195 197 // QtCharts 1.1
196 198 qmlRegisterType<DeclarativeChart, 1>(uri, 1, 1, "ChartView");
197 199 qmlRegisterType<DeclarativeScatterSeries, 1>(uri, 1, 1, "ScatterSeries");
198 200 qmlRegisterType<DeclarativeLineSeries, 1>(uri, 1, 1, "LineSeries");
199 201 qmlRegisterType<DeclarativeSplineSeries, 1>(uri, 1, 1, "SplineSeries");
200 202 qmlRegisterType<DeclarativeAreaSeries, 1>(uri, 1, 1, "AreaSeries");
201 203 qmlRegisterType<DeclarativeBarSeries, 1>(uri, 1, 1, "BarSeries");
202 204 qmlRegisterType<DeclarativeStackedBarSeries, 1>(uri, 1, 1, "StackedBarSeries");
203 205 qmlRegisterType<DeclarativePercentBarSeries, 1>(uri, 1, 1, "PercentBarSeries");
204 206 qmlRegisterType<DeclarativeHorizontalBarSeries, 1>(uri, 1, 1, "HorizontalBarSeries");
205 207 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 1>(uri, 1, 1, "HorizontalStackedBarSeries");
206 208 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 1>(uri, 1, 1, "HorizontalPercentBarSeries");
207 209 qmlRegisterType<DeclarativePieSeries>(uri, 1, 1, "PieSeries");
208 210 qmlRegisterType<DeclarativeBarSet>(uri, 1, 1, "BarSet");
209 211 qmlRegisterType<QValueAxis>(uri, 1, 1, "ValueAxis");
210 #ifndef QT_ON_ARM
212 #ifndef QT_QREAL_IS_FLOAT
211 213 qmlRegisterType<QDateTimeAxis>(uri, 1, 1, "DateTimeAxis");
212 214 #endif
213 215 qmlRegisterType<DeclarativeCategoryAxis>(uri, 1, 1, "CategoryAxis");
214 216 qmlRegisterType<DeclarativeCategoryRange>(uri, 1, 1, "CategoryRange");
215 217 qmlRegisterType<QBarCategoryAxis>(uri, 1, 1, "BarCategoryAxis");
216 218 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 1, 1, "Margins",
217 219 QLatin1String("Trying to create uncreatable: Margins."));
218 220
219 221 // QtCharts 1.2
220 222 qmlRegisterType<DeclarativeChart, 2>(uri, 1, 2, "ChartView");
221 223 qmlRegisterType<DeclarativeScatterSeries, 2>(uri, 1, 2, "ScatterSeries");
222 224 qmlRegisterType<DeclarativeLineSeries, 2>(uri, 1, 2, "LineSeries");
223 225 qmlRegisterType<DeclarativeSplineSeries, 2>(uri, 1, 2, "SplineSeries");
224 226 qmlRegisterType<DeclarativeAreaSeries, 2>(uri, 1, 2, "AreaSeries");
225 227 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 1, 2, "BarSeries");
226 228 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 1, 2, "StackedBarSeries");
227 229 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 1, 2, "PercentBarSeries");
228 230 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 1, 2, "HorizontalBarSeries");
229 231 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 1, 2, "HorizontalStackedBarSeries");
230 232 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 1, 2, "HorizontalPercentBarSeries");
231 233
232 234 // QtCharts 1.3
233 235 qmlRegisterType<DeclarativeChart, 3>(uri, 1, 3, "ChartView");
234 236 qmlRegisterType<DeclarativePolarChart, 1>(uri, 1, 3, "PolarChartView");
235 237 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 1, 3, "SplineSeries");
236 238 qmlRegisterType<DeclarativeScatterSeries, 3>(uri, 1, 3, "ScatterSeries");
237 239 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 1, 3, "LineSeries");
238 240 qmlRegisterType<DeclarativeAreaSeries, 3>(uri, 1, 3, "AreaSeries");
239 241 qmlRegisterType<QLogValueAxis>(uri, 1, 3, "LogValueAxis");
240 242 qmlRegisterType<DeclarativeBoxPlotSeries>(uri, 1, 3, "BoxPlotSeries");
241 243 qmlRegisterType<DeclarativeBoxSet>(uri, 1, 3, "BoxSet");
242 244
243 245 // QtCharts 1.4
244 246 qmlRegisterType<DeclarativeAreaSeries, 4>(uri, 1, 4, "AreaSeries");
245 247 qmlRegisterType<DeclarativeBarSet, 2>(uri, 1, 4, "BarSet");
246 248 qmlRegisterType<DeclarativeBoxPlotSeries, 1>(uri, 1, 4, "BoxPlotSeries");
247 249 qmlRegisterType<DeclarativeBoxSet, 1>(uri, 1, 4, "BoxSet");
248 250 qmlRegisterType<DeclarativePieSlice>(uri, 1, 4, "PieSlice");
249 251 qmlRegisterType<DeclarativeScatterSeries, 4>(uri, 1, 4, "ScatterSeries");
250 252
251 253 // QtCharts 2.0
252 254 qmlRegisterType<QVBoxPlotModelMapper>(uri, 2, 0, "VBoxPlotModelMapper");
253 255 qmlRegisterUncreatableType<QBoxPlotModelMapper>(uri, 2, 0, "BoxPlotModelMapper",
254 256 QLatin1String("Trying to create uncreatable: BoxPlotModelMapper."));
255 257 qmlRegisterType<DeclarativeChart, 4>(uri, 2, 0, "ChartView");
256 258 qmlRegisterType<DeclarativeXYPoint>(uri, 2, 0, "XYPoint");
257 259 qmlRegisterType<DeclarativeScatterSeries, 4>(uri, 2, 0, "ScatterSeries");
258 260 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 2, 0, "LineSeries");
259 261 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 2, 0, "SplineSeries");
260 262 qmlRegisterType<DeclarativeAreaSeries, 4>(uri, 2, 0, "AreaSeries");
261 263 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 2, 0, "BarSeries");
262 264 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 2, 0, "StackedBarSeries");
263 265 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 2, 0, "PercentBarSeries");
264 266 qmlRegisterType<DeclarativePieSeries>(uri, 2, 0, "PieSeries");
265 267 qmlRegisterType<QPieSlice>(uri, 2, 0, "PieSlice");
266 268 qmlRegisterType<DeclarativeBarSet, 2>(uri, 2, 0, "BarSet");
267 269 qmlRegisterType<QHXYModelMapper>(uri, 2, 0, "HXYModelMapper");
268 270 qmlRegisterType<QVXYModelMapper>(uri, 2, 0, "VXYModelMapper");
269 271 qmlRegisterType<QHPieModelMapper>(uri, 2, 0, "HPieModelMapper");
270 272 qmlRegisterType<QVPieModelMapper>(uri, 2, 0, "VPieModelMapper");
271 273 qmlRegisterType<QHBarModelMapper>(uri, 2, 0, "HBarModelMapper");
272 274 qmlRegisterType<QVBarModelMapper>(uri, 2, 0, "VBarModelMapper");
273 275 qmlRegisterType<QValueAxis>(uri, 2, 0, "ValueAxis");
274 #ifndef QT_ON_ARM
276 #ifndef QT_QREAL_IS_FLOAT
275 277 qmlRegisterType<QDateTimeAxis>(uri, 2, 0, "DateTimeAxis");
276 278 #endif
277 279 qmlRegisterType<DeclarativeCategoryAxis>(uri, 2, 0, "CategoryAxis");
278 280 qmlRegisterType<DeclarativeCategoryRange>(uri, 2, 0, "CategoryRange");
279 281 qmlRegisterType<QBarCategoryAxis>(uri, 2, 0, "BarCategoryAxis");
280 282 qmlRegisterType<DeclarativePolarChart, 1>(uri, 2, 0, "PolarChartView");
281 283 qmlRegisterType<QLogValueAxis, 1>(uri, 2, 0, "LogValueAxis");
282 284 qmlRegisterType<DeclarativeBoxPlotSeries, 1>(uri, 2, 0, "BoxPlotSeries");
283 285 qmlRegisterType<DeclarativeBoxSet, 1>(uri, 2, 0, "BoxSet");
284 286 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 2, 0, "HorizontalBarSeries");
285 287 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 2, 0, "HorizontalStackedBarSeries");
286 288 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 2, 0, "HorizontalPercentBarSeries");
287 289 qmlRegisterType<DeclarativePieSlice>(uri, 2, 0, "PieSlice");
288 290 qmlRegisterUncreatableType<QLegend>(uri, 2, 0, "Legend",
289 291 QLatin1String("Trying to create uncreatable: Legend."));
290 292 qmlRegisterUncreatableType<QXYSeries>(uri, 2, 0, "XYSeries",
291 293 QLatin1String("Trying to create uncreatable: XYSeries."));
292 294 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 2, 0, "AbstractItemModel",
293 295 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
294 296 qmlRegisterUncreatableType<QXYModelMapper>(uri, 2, 0, "XYModelMapper",
295 297 QLatin1String("Trying to create uncreatable: XYModelMapper."));
296 298 qmlRegisterUncreatableType<QPieModelMapper>(uri, 2, 0, "PieModelMapper",
297 299 QLatin1String("Trying to create uncreatable: PieModelMapper."));
298 300 qmlRegisterUncreatableType<QBarModelMapper>(uri, 2, 0, "BarModelMapper",
299 301 QLatin1String("Trying to create uncreatable: BarModelMapper."));
300 302 qmlRegisterUncreatableType<QAbstractSeries>(uri, 2, 0, "AbstractSeries",
301 303 QLatin1String("Trying to create uncreatable: AbstractSeries."));
302 304 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 2, 0, "AbstractBarSeries",
303 305 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
304 306 qmlRegisterUncreatableType<QAbstractAxis>(uri, 2, 0, "AbstractAxis",
305 307 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
306 308 qmlRegisterUncreatableType<QBarSet>(uri, 2, 0, "BarSetBase",
307 309 QLatin1String("Trying to create uncreatable: BarsetBase."));
308 310 qmlRegisterUncreatableType<QPieSeries>(uri, 2, 0, "QPieSeries",
309 311 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
310 312 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 2, 0, "DeclarativeAxes",
311 313 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
312 314 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 2, 0, "Margins",
313 315 QLatin1String("Trying to create uncreatable: Margins."));
314 316
315 317 // QtCharts 2.1
316 318 qmlRegisterType<DeclarativeCategoryAxis, 1>(uri, 2, 1, "CategoryAxis");
317 319 qmlRegisterUncreatableType<QAbstractAxis>(uri, 2, 1, "AbstractAxis",
318 320 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
319 321 qmlRegisterType<DeclarativeChart, 5>(uri, 2, 1, "ChartView");
320 322 qmlRegisterType<DeclarativeScatterSeries, 5>(uri, 2, 1, "ScatterSeries");
321 323 qmlRegisterType<DeclarativeLineSeries, 4>(uri, 2, 1, "LineSeries");
322 324 qmlRegisterType<DeclarativeSplineSeries, 4>(uri, 2, 1, "SplineSeries");
323 325 }
324 326
325 327 };
326 328
327 329 QT_CHARTS_END_NAMESPACE
328 330
329 331 #include "chartsqml2_plugin.moc"
330 332
331 333 QT_CHARTS_USE_NAMESPACE
@@ -1,1248 +1,1248
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include "declarativechart.h"
31 31 #include <QtGui/QPainter>
32 32 #include "declarativelineseries.h"
33 33 #include "declarativeareaseries.h"
34 34 #include "declarativebarseries.h"
35 35 #include "declarativepieseries.h"
36 36 #include "declarativesplineseries.h"
37 37 #include "declarativeboxplotseries.h"
38 38 #include "declarativescatterseries.h"
39 39 #include "declarativechartnode.h"
40 40 #include "declarativerendernode.h"
41 41 #include <QtCharts/QBarCategoryAxis>
42 42 #include <QtCharts/QValueAxis>
43 43 #include <QtCharts/QLogValueAxis>
44 44 #include <QtCharts/QCategoryAxis>
45 45 #include <private/qabstractseries_p.h>
46 46 #include "declarativemargins.h"
47 47 #include <private/chartdataset_p.h>
48 48 #include "declarativeaxes.h"
49 49 #include <private/qchart_p.h>
50 50 #include <private/chartpresenter_p.h>
51 51 #include <QtCharts/QPolarChart>
52 52
53 #ifndef QT_ON_ARM
53 #ifndef QT_QREAL_IS_FLOAT
54 54 #include <QtCharts/QDateTimeAxis>
55 55 #endif
56 56
57 57 #include <QtWidgets/QGraphicsSceneMouseEvent>
58 58 #include <QtWidgets/QGraphicsSceneHoverEvent>
59 59 #include <QtWidgets/QApplication>
60 60 #include <QtCore/QTimer>
61 61 #include <QtCore/QThread>
62 62
63 63 QT_CHARTS_BEGIN_NAMESPACE
64 64
65 65 /*!
66 66 \qmltype ChartView
67 67 \instantiates DeclarativeChart
68 68 \inqmlmodule QtCharts
69 69
70 70 \brief Chart element.
71 71
72 72 ChartView element is the parent that is responsible for showing different chart series types.
73 73
74 74 The following QML shows how to create a simple chart with one pie series:
75 75 \snippet qmlpiechart/qml/qmlpiechart/main.qml 1
76 76 \snippet qmlpiechart/qml/qmlpiechart/main.qml 2
77 77 \snippet qmlpiechart/qml/qmlpiechart/main.qml 3
78 78
79 79 \beginfloatleft
80 80 \image examples_qmlpiechart.png
81 81 \endfloat
82 82 \clearfloat
83 83 */
84 84
85 85 /*!
86 86 \qmlproperty Theme ChartView::theme
87 87 Theme defines the visual appearance of the chart, including for example colors, fonts, line
88 88 widths and chart background.
89 89 */
90 90
91 91 /*!
92 92 \qmlproperty Animation ChartView::animationOptions
93 93 Animation configuration of the chart. One of ChartView.NoAnimation, ChartView.GridAxisAnimations,
94 94 ChartView.SeriesAnimations or ChartView.AllAnimations.
95 95 */
96 96
97 97 /*!
98 98 \qmlproperty int ChartView::animationDuration
99 99 The duration of the animation for the chart.
100 100 */
101 101
102 102 /*!
103 103 \qmlproperty easing ChartView::animationEasingCurve
104 104 The easing curve of the animation for the chart.
105 105 */
106 106
107 107 /*!
108 108 \qmlproperty Font ChartView::titleFont
109 109 The title font of the chart.
110 110
111 111 See the Qt documentation for more details of Font.
112 112 */
113 113
114 114 /*!
115 115 \qmlproperty string ChartView::title
116 116 The title of the chart, shown on top of the chart.
117 117 \sa ChartView::titleColor
118 118 */
119 119
120 120 /*!
121 121 \qmlproperty color ChartView::titleColor
122 122 The color of the title text.
123 123 */
124 124
125 125 /*!
126 126 \qmlproperty Legend ChartView::legend
127 127 The legend of the chart. Legend lists all the series, pie slices and bar sets added on the chart.
128 128 */
129 129
130 130 /*!
131 131 \qmlproperty int ChartView::count
132 132 The count of series added to the chart.
133 133 */
134 134
135 135 /*!
136 136 \qmlproperty color ChartView::backgroundColor
137 137 The color of the chart's background. By default background color is defined by chart theme.
138 138 \sa ChartView::theme
139 139 */
140 140
141 141 /*!
142 142 \qmlproperty real ChartView::backgroundRoundness
143 143 The diameter of the rounding circle at the corners of the chart background.
144 144 */
145 145
146 146 /*!
147 147 \qmlproperty color ChartView::plotAreaColor
148 148 The color of the background of the chart's plot area. By default plot area background uses chart's
149 149 background color.
150 150 \sa ChartView::backgroundColor
151 151 */
152 152
153 153 /*!
154 154 \qmlproperty list<AbstractAxis> ChartView::axes
155 155 The axes of the ChartView.
156 156 */
157 157
158 158 /*!
159 159 \qmlproperty bool ChartView::dropShadowEnabled
160 160 The chart's border drop shadow. Set to true to enable drop shadow.
161 161 */
162 162
163 163 /*!
164 164 \qmlproperty rect ChartView::plotArea
165 165 The area on the ChartView that is used for drawing series. This is the ChartView rect without the
166 166 margins.
167 167 \sa ChartView::margins
168 168 */
169 169
170 170 /*!
171 171 \qmlproperty Margins ChartView::margins
172 172 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
173 173 area of ChartView is used for drawing title, axes and legend.
174 174 */
175 175
176 176 /*!
177 177 \qmlproperty bool ChartView::localizeNumbers
178 178 \since QtCharts 2.0
179 179 When \c{true}, all generated numbers appearing in various series and axis labels will be
180 180 localized using the default QLocale of the application, which defaults to the system locale.
181 181 When \c{false}, the "C" locale is always used.
182 182 Defaults to \c{false}.
183 183
184 184 \sa locale
185 185 */
186 186
187 187 /*!
188 188 \qmlproperty locale ChartView::locale
189 189 \since QtCharts 2.0
190 190 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
191 191 This also determines the locale used to format DateTimeAxis labels regardless of
192 192 localizeNumbers property.
193 193 Defaults to application default locale at the time the chart is constructed.
194 194
195 195 \sa localizeNumbers
196 196 */
197 197
198 198 /*!
199 199 \qmlmethod AbstractSeries ChartView::series(int index)
200 200 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
201 201 the count property of the chart.
202 202 */
203 203
204 204 /*!
205 205 \qmlmethod AbstractSeries ChartView::series(string name)
206 206 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
207 207 */
208 208
209 209 /*!
210 210 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
211 211 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
212 212 optional axis \a axisY. For example:
213 213 \code
214 214 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
215 215 var myAxisX = chartView.axisX(lineSeries);
216 216 var myAxisY = chartView.axisY(lineSeries);
217 217 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
218 218 \endcode
219 219 */
220 220
221 221 /*!
222 222 \qmlmethod ChartView::removeSeries(AbstractSeries series)
223 223 Removes the \a series from the chart. The series object is also destroyed.
224 224 */
225 225
226 226 /*!
227 227 \qmlmethod ChartView::removeAllSeries()
228 228 Removes all series from the chart. All the series objects are also destroyed.
229 229 */
230 230
231 231 /*!
232 232 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
233 233 The x-axis of the series.
234 234 */
235 235
236 236 /*!
237 237 \qmlmethod ChartView::setAxisX(AbstractAxis axis, AbstractSeries series)
238 238 Set the x-axis of the series.
239 239 */
240 240
241 241 /*!
242 242 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
243 243 The y-axis of the series.
244 244 */
245 245
246 246 /*!
247 247 \qmlmethod ChartView::setAxisY(AbstractAxis axis, AbstractSeries series)
248 248 Set the y-axis of the series.
249 249 */
250 250
251 251 /*!
252 252 \qmlmethod ChartView::zoom(real factor)
253 253 Zooms in by \a factor on the center of the chart.
254 254
255 255 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
256 256 */
257 257
258 258 /*!
259 259 \qmlmethod ChartView::zoomIn()
260 260 Zooms in the view by a factor of two.
261 261 */
262 262
263 263 /*!
264 264 \qmlmethod ChartView::zoomIn(rect rectangle)
265 265 Zooms in the view to a maximum level at which \a rectangle is still fully visible.
266 266 \note This is not supported for polar charts.
267 267 */
268 268
269 269 /*!
270 270 \qmlmethod ChartView::zoomOut()
271 271 Zooms out the view by a factor of two.
272 272 */
273 273
274 274 /*!
275 275 \qmlmethod ChartView::zoomReset()
276 276 Resets the series domains to what they were before any zoom method was called.
277 277 Note that this will also reset any scrolls and explicit axis range settings done between
278 278 the first zoom operation and calling this method. If no zoom operation has been
279 279 done, this method does nothing.
280 280 */
281 281
282 282 /*!
283 283 \qmlmethod ChartView::isZoomed()
284 284 Returns true if any series has a zoomed domain.
285 285 */
286 286
287 287 /*!
288 288 \qmlmethod ChartView::scrollLeft(real pixels)
289 289 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
290 290 */
291 291
292 292 /*!
293 293 \qmlmethod ChartView::scrollRight(real pixels)
294 294 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
295 295 */
296 296
297 297 /*!
298 298 \qmlmethod ChartView::scrollUp(real pixels)
299 299 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
300 300 */
301 301
302 302 /*!
303 303 \qmlmethod ChartView::scrollDown(real pixels)
304 304 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
305 305 */
306 306
307 307 /*!
308 308 \qmlmethod point ChartView::mapToValue(point position, AbstractSeries series)
309 309 Returns the value in the \a series domain that corresponds to the \a position relative to the
310 310 chart.
311 311 */
312 312
313 313 /*!
314 314 \qmlmethod point ChartView::mapToPosition(point value, AbstractSeries series)
315 315 Returns the position on the chart that corresponds to the \a value in the \a series domain.
316 316 */
317 317
318 318 /*!
319 319 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
320 320 The \a series has been added to the chart.
321 321 */
322 322
323 323 /*!
324 324 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
325 325 The \a series has been removed from the chart. Please note that \a series is no longer a valid
326 326 object after the signal handler has completed.
327 327 */
328 328
329 329 DeclarativeChart::DeclarativeChart(QQuickItem *parent)
330 330 : QQuickItem(parent)
331 331 {
332 332 initChart(QChart::ChartTypeCartesian);
333 333 }
334 334
335 335 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QQuickItem *parent)
336 336 : QQuickItem(parent)
337 337 {
338 338 initChart(type);
339 339 }
340 340
341 341 void DeclarativeChart::initChart(QChart::ChartType type)
342 342 {
343 343 m_sceneImage = 0;
344 344 m_sceneImageDirty = false;
345 345 m_sceneImageNeedsClear = false;
346 346 m_guiThreadId = QThread::currentThreadId();
347 347 m_paintThreadId = 0;
348 348 m_updatePending = false;
349 349
350 350 setFlag(ItemHasContents, true);
351 351
352 352 if (type == QChart::ChartTypePolar)
353 353 m_chart = new QPolarChart();
354 354 else
355 355 m_chart = new QChart();
356 356
357 357 m_chart->d_ptr->m_presenter->glSetUseWidget(false);
358 358 m_glXYDataManager = m_chart->d_ptr->m_dataset->glXYSeriesDataManager();
359 359
360 360 m_scene = new QGraphicsScene(this);
361 361 m_scene->addItem(m_chart);
362 362
363 363 setAntialiasing(QQuickItem::antialiasing());
364 364 connect(m_scene, &QGraphicsScene::changed, this, &DeclarativeChart::sceneChanged);
365 365 connect(this, &DeclarativeChart::needRender, this, &DeclarativeChart::renderScene,
366 366 Qt::QueuedConnection);
367 367 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
368 368
369 369 setAcceptedMouseButtons(Qt::AllButtons);
370 370 setAcceptHoverEvents(true);
371 371
372 372 m_margins = new DeclarativeMargins(this);
373 373 m_margins->setTop(m_chart->margins().top());
374 374 m_margins->setLeft(m_chart->margins().left());
375 375 m_margins->setRight(m_chart->margins().right());
376 376 m_margins->setBottom(m_chart->margins().bottom());
377 377 connect(m_margins, SIGNAL(topChanged(int,int,int,int)),
378 378 this, SLOT(changeMargins(int,int,int,int)));
379 379 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)),
380 380 this, SLOT(changeMargins(int,int,int,int)));
381 381 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)),
382 382 this, SLOT(changeMargins(int,int,int,int)));
383 383 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)),
384 384 this, SLOT(changeMargins(int,int,int,int)));
385 385 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
386 386 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
387 387 connect(m_chart, &QChart::plotAreaChanged, this, &DeclarativeChart::plotAreaChanged);
388 388 }
389 389
390 390 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
391 391 {
392 392 emit seriesAdded(series);
393 393 }
394 394
395 395 void DeclarativeChart::changeMargins(int top, int bottom, int left, int right)
396 396 {
397 397 m_chart->setMargins(QMargins(left, top, right, bottom));
398 398 emit marginsChanged();
399 399 }
400 400
401 401 DeclarativeChart::~DeclarativeChart()
402 402 {
403 403 delete m_chart;
404 404 delete m_sceneImage;
405 405 }
406 406
407 407 void DeclarativeChart::childEvent(QChildEvent *event)
408 408 {
409 409 if (event->type() == QEvent::ChildAdded) {
410 410 if (qobject_cast<QAbstractSeries *>(event->child())) {
411 411 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
412 412 }
413 413 }
414 414 }
415 415
416 416 void DeclarativeChart::componentComplete()
417 417 {
418 418 foreach (QObject *child, children()) {
419 419 if (qobject_cast<QAbstractSeries *>(child)) {
420 420 // Add series to the chart
421 421 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
422 422 m_chart->addSeries(series);
423 423
424 424 // Connect to axis changed signals (unless this is a pie series)
425 425 if (!qobject_cast<DeclarativePieSeries *>(series)) {
426 426 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
427 427 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
428 428 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
429 429 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
430 430 }
431 431
432 432 initializeAxes(series);
433 433 }
434 434 }
435 435
436 436 QQuickItem::componentComplete();
437 437 }
438 438
439 439 void DeclarativeChart::seriesAxisAttachHelper(QAbstractSeries *series, QAbstractAxis *axis,
440 440 Qt::Orientations orientation,
441 441 Qt::Alignment alignment)
442 442 {
443 443 if (!series->attachedAxes().contains(axis)) {
444 444 // Remove & delete old axes that are not attached to any other series
445 445 foreach (QAbstractAxis* oldAxis, m_chart->axes(orientation, series)) {
446 446 bool otherAttachments = false;
447 447 if (oldAxis != axis) {
448 448 foreach (QAbstractSeries *oldSeries, m_chart->series()) {
449 449 if (oldSeries != series && oldSeries->attachedAxes().contains(oldAxis)) {
450 450 otherAttachments = true;
451 451 break;
452 452 }
453 453 }
454 454 if (!otherAttachments) {
455 455 m_chart->removeAxis(oldAxis);
456 456 delete oldAxis;
457 457 }
458 458 }
459 459 }
460 460 if (!m_chart->axes(orientation).contains(axis))
461 461 m_chart->addAxis(axis, alignment);
462 462
463 463 series->attachAxis(axis);
464 464 }
465 465 }
466 466
467 467 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
468 468 {
469 469 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
470 470 if (axis && s) {
471 471 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignBottom);
472 472 } else {
473 473 qWarning() << "Trying to set axisX to null.";
474 474 }
475 475 }
476 476
477 477 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
478 478 {
479 479 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
480 480 if (axis && s) {
481 481 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignTop);
482 482 } else {
483 483 qWarning() << "Trying to set axisXTop to null.";
484 484 }
485 485 }
486 486
487 487 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
488 488 {
489 489 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
490 490 if (axis && s) {
491 491 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignLeft);
492 492 } else {
493 493 qWarning() << "Trying to set axisY to null.";
494 494 }
495 495 }
496 496
497 497 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
498 498 {
499 499 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
500 500 if (axis && s) {
501 501 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignRight);
502 502 } else {
503 503 qWarning() << "Trying to set axisYRight to null.";
504 504 }
505 505 }
506 506
507 507 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
508 508 {
509 509 if (newGeometry.isValid()) {
510 510 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
511 511 m_chart->resize(newGeometry.width(), newGeometry.height());
512 512 }
513 513 }
514 514 QQuickItem::geometryChanged(newGeometry, oldGeometry);
515 515 }
516 516
517 517 QSGNode *DeclarativeChart::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
518 518 {
519 519 DeclarativeChartNode *node = static_cast<DeclarativeChartNode *>(oldNode);
520 520
521 521 if (!node) {
522 522 node = new DeclarativeChartNode(window());
523 523 connect(window(), &QQuickWindow::beforeRendering,
524 524 node->glRenderNode(), &DeclarativeRenderNode::render);
525 525 }
526 526
527 527 const QRectF &bRect = boundingRect();
528 528
529 529 // Update GL data
530 530 if (m_glXYDataManager->dataMap().size() || m_glXYDataManager->mapDirty()) {
531 531 const QRectF &plotArea = m_chart->plotArea();
532 532 const QSizeF &chartAreaSize = m_chart->size();
533 533
534 534 // We can't use chart's plot area directly, as graphicscene has some internal minimum size
535 535 const qreal normalizedX = plotArea.x() / chartAreaSize.width();
536 536 const qreal normalizedY = plotArea.y() / chartAreaSize.height();
537 537 const qreal normalizedWidth = plotArea.width() / chartAreaSize.width();
538 538 const qreal normalizedHeight = plotArea.height() / chartAreaSize.height();
539 539
540 540 QRectF adjustedPlotArea(normalizedX * bRect.width(),
541 541 normalizedY * bRect.height(),
542 542 normalizedWidth * bRect.width(),
543 543 normalizedHeight * bRect.height());
544 544
545 545 const QSize &adjustedPlotSize = adjustedPlotArea.size().toSize();
546 546 if (adjustedPlotSize != node->glRenderNode()->textureSize())
547 547 node->glRenderNode()->setTextureSize(adjustedPlotSize);
548 548
549 549 node->glRenderNode()->setRect(adjustedPlotArea);
550 550 node->glRenderNode()->setSeriesData(m_glXYDataManager->mapDirty(),
551 551 m_glXYDataManager->dataMap());
552 552
553 553 // Clear dirty flags from original xy data
554 554 m_glXYDataManager->clearAllDirty();
555 555 }
556 556
557 557 // Copy chart (if dirty) to chart node
558 558 if (m_sceneImageDirty) {
559 559 node->createTextureFromImage(*m_sceneImage);
560 560 m_sceneImageDirty = false;
561 561 }
562 562
563 563 node->setRect(bRect);
564 564
565 565 return node;
566 566 }
567 567
568 568 void DeclarativeChart::sceneChanged(QList<QRectF> region)
569 569 {
570 570 const int count = region.size();
571 571 const qreal limitSize = 0.01;
572 572 if (count && !m_updatePending) {
573 573 qreal totalSize = 0.0;
574 574 for (int i = 0; i < count; i++) {
575 575 const QRectF &reg = region.at(i);
576 576 totalSize += (reg.height() * reg.width());
577 577 if (totalSize >= limitSize)
578 578 break;
579 579 }
580 580 // Ignore region updates that change less than small fraction of a pixel, as there is
581 581 // little point regenerating the image in these cases. These are typically cases
582 582 // where OpenGL series are drawn to otherwise static chart.
583 583 if (totalSize >= limitSize) {
584 584 m_updatePending = true;
585 585 // Do async render to avoid some unnecessary renders.
586 586 emit needRender();
587 587 } else {
588 588 // We do want to call update to trigger possible gl series updates.
589 589 update();
590 590 }
591 591 }
592 592 }
593 593
594 594 void DeclarativeChart::renderScene()
595 595 {
596 596 m_updatePending = false;
597 597 m_sceneImageDirty = true;
598 598 QSize chartSize = m_chart->size().toSize();
599 599 if (!m_sceneImage || chartSize != m_sceneImage->size()) {
600 600 delete m_sceneImage;
601 601 m_sceneImage = new QImage(chartSize, QImage::Format_ARGB32);
602 602 m_sceneImageNeedsClear = true;
603 603 }
604 604
605 605 if (m_sceneImageNeedsClear) {
606 606 m_sceneImage->fill(Qt::transparent);
607 607 // Don't clear the flag if chart background has any transparent element to it
608 608 if (m_chart->backgroundBrush().color().alpha() == 0xff && !m_chart->isDropShadowEnabled())
609 609 m_sceneImageNeedsClear = false;
610 610 }
611 611 QPainter painter(m_sceneImage);
612 612 if (antialiasing()) {
613 613 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing
614 614 | QPainter::SmoothPixmapTransform);
615 615 }
616 616 QRect renderRect(QPoint(0, 0), chartSize);
617 617 m_scene->render(&painter, renderRect, renderRect);
618 618 update();
619 619 }
620 620
621 621 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
622 622 {
623 623 m_mousePressScenePoint = event->pos();
624 624 m_mousePressScreenPoint = event->globalPos();
625 625 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
626 626 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
627 627 m_mousePressButton = event->button();
628 628 m_mousePressButtons = event->buttons();
629 629
630 630 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
631 631 mouseEvent.setWidget(0);
632 632 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
633 633 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
634 634 mouseEvent.setScenePos(m_mousePressScenePoint);
635 635 mouseEvent.setScreenPos(m_mousePressScreenPoint);
636 636 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
637 637 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
638 638 mouseEvent.setButtons(m_mousePressButtons);
639 639 mouseEvent.setButton(m_mousePressButton);
640 640 mouseEvent.setModifiers(event->modifiers());
641 641 mouseEvent.setAccepted(false);
642 642
643 643 QApplication::sendEvent(m_scene, &mouseEvent);
644 644 }
645 645
646 646 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
647 647 {
648 648 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
649 649 mouseEvent.setWidget(0);
650 650 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
651 651 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
652 652 mouseEvent.setScenePos(event->pos());
653 653 mouseEvent.setScreenPos(event->globalPos());
654 654 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
655 655 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
656 656 mouseEvent.setButtons(event->buttons());
657 657 mouseEvent.setButton(event->button());
658 658 mouseEvent.setModifiers(event->modifiers());
659 659 mouseEvent.setAccepted(false);
660 660
661 661 QApplication::sendEvent(m_scene, &mouseEvent);
662 662
663 663 m_mousePressButtons = event->buttons();
664 664 m_mousePressButton = Qt::NoButton;
665 665 }
666 666
667 667 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
668 668 {
669 669 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
670 670 // QGraphicsScene generates hover events from mouse move events, so we don't need
671 671 // to pass hover events there.
672 672 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
673 673 mouseEvent.setWidget(0);
674 674 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
675 675 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
676 676 mouseEvent.setScenePos(event->pos());
677 677 // Hover events do not have global pos in them, and the screen position doesn't seem to
678 678 // matter anyway in this use case, so just pass event pos instead of trying to
679 679 // calculate the real screen position.
680 680 mouseEvent.setScreenPos(event->pos());
681 681 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
682 682 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
683 683 mouseEvent.setButtons(m_mousePressButtons);
684 684 mouseEvent.setButton(m_mousePressButton);
685 685 mouseEvent.setModifiers(event->modifiers());
686 686 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
687 687 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
688 688 mouseEvent.setAccepted(false);
689 689
690 690 QApplication::sendEvent(m_scene, &mouseEvent);
691 691 }
692 692
693 693 void DeclarativeChart::mouseDoubleClickEvent(QMouseEvent *event)
694 694 {
695 695 m_mousePressScenePoint = event->pos();
696 696 m_mousePressScreenPoint = event->globalPos();
697 697 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
698 698 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
699 699 m_mousePressButton = event->button();
700 700 m_mousePressButtons = event->buttons();
701 701
702 702 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
703 703 mouseEvent.setWidget(0);
704 704 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
705 705 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
706 706 mouseEvent.setScenePos(m_mousePressScenePoint);
707 707 mouseEvent.setScreenPos(m_mousePressScreenPoint);
708 708 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
709 709 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
710 710 mouseEvent.setButtons(m_mousePressButtons);
711 711 mouseEvent.setButton(m_mousePressButton);
712 712 mouseEvent.setModifiers(event->modifiers());
713 713 mouseEvent.setAccepted(false);
714 714
715 715 QApplication::sendEvent(m_scene, &mouseEvent);
716 716 }
717 717
718 718 void DeclarativeChart::handleAntialiasingChanged(bool enable)
719 719 {
720 720 setAntialiasing(enable);
721 721 }
722 722
723 723 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
724 724 {
725 725 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
726 726 if (chartTheme != m_chart->theme())
727 727 m_chart->setTheme(chartTheme);
728 728 }
729 729
730 730 DeclarativeChart::Theme DeclarativeChart::theme()
731 731 {
732 732 return (DeclarativeChart::Theme) m_chart->theme();
733 733 }
734 734
735 735 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
736 736 {
737 737 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
738 738 if (animationOptions != m_chart->animationOptions())
739 739 m_chart->setAnimationOptions(animationOptions);
740 740 }
741 741
742 742 DeclarativeChart::Animation DeclarativeChart::animationOptions()
743 743 {
744 744 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
745 745 return DeclarativeChart::AllAnimations;
746 746 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
747 747 return DeclarativeChart::GridAxisAnimations;
748 748 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
749 749 return DeclarativeChart::SeriesAnimations;
750 750 else
751 751 return DeclarativeChart::NoAnimation;
752 752 }
753 753
754 754 void DeclarativeChart::setAnimationDuration(int msecs)
755 755 {
756 756 if (msecs != m_chart->animationDuration()) {
757 757 m_chart->setAnimationDuration(msecs);
758 758 emit animationDurationChanged(msecs);
759 759 }
760 760 }
761 761
762 762 int DeclarativeChart::animationDuration() const
763 763 {
764 764 return m_chart->animationDuration();
765 765 }
766 766
767 767 void DeclarativeChart::setAnimationEasingCurve(const QEasingCurve &curve)
768 768 {
769 769 if (curve != m_chart->animationEasingCurve()) {
770 770 m_chart->setAnimationEasingCurve(curve);
771 771 emit animationEasingCurveChanged(curve);
772 772 }
773 773 }
774 774
775 775 QEasingCurve DeclarativeChart::animationEasingCurve() const
776 776 {
777 777 return m_chart->animationEasingCurve();
778 778 }
779 779
780 780 void DeclarativeChart::setTitle(QString title)
781 781 {
782 782 if (title != m_chart->title())
783 783 m_chart->setTitle(title);
784 784 }
785 785 QString DeclarativeChart::title()
786 786 {
787 787 return m_chart->title();
788 788 }
789 789
790 790 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
791 791 {
792 792 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
793 793 if (axes.count())
794 794 return axes[0];
795 795 return 0;
796 796 }
797 797
798 798 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
799 799 {
800 800 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
801 801 if (axes.count())
802 802 return axes[0];
803 803 return 0;
804 804 }
805 805
806 806 QLegend *DeclarativeChart::legend()
807 807 {
808 808 return m_chart->legend();
809 809 }
810 810
811 811 void DeclarativeChart::setTitleColor(QColor color)
812 812 {
813 813 QBrush b = m_chart->titleBrush();
814 814 if (color != b.color()) {
815 815 b.setColor(color);
816 816 m_chart->setTitleBrush(b);
817 817 emit titleColorChanged(color);
818 818 }
819 819 }
820 820
821 821 QFont DeclarativeChart::titleFont() const
822 822 {
823 823 return m_chart->titleFont();
824 824 }
825 825
826 826 void DeclarativeChart::setTitleFont(const QFont &font)
827 827 {
828 828 m_chart->setTitleFont(font);
829 829 }
830 830
831 831 QColor DeclarativeChart::titleColor()
832 832 {
833 833 return m_chart->titleBrush().color();
834 834 }
835 835
836 836 void DeclarativeChart::setBackgroundColor(QColor color)
837 837 {
838 838 QBrush b = m_chart->backgroundBrush();
839 839 if (b.style() != Qt::SolidPattern || color != b.color()) {
840 840 if (color.alpha() < 0xff)
841 841 m_sceneImageNeedsClear = true;
842 842 b.setStyle(Qt::SolidPattern);
843 843 b.setColor(color);
844 844 m_chart->setBackgroundBrush(b);
845 845 emit backgroundColorChanged();
846 846 }
847 847 }
848 848
849 849 QColor DeclarativeChart::backgroundColor()
850 850 {
851 851 return m_chart->backgroundBrush().color();
852 852 }
853 853
854 854 void QtCharts::DeclarativeChart::setPlotAreaColor(QColor color)
855 855 {
856 856 QBrush b = m_chart->plotAreaBackgroundBrush();
857 857 if (b.style() != Qt::SolidPattern || color != b.color()) {
858 858 b.setStyle(Qt::SolidPattern);
859 859 b.setColor(color);
860 860 m_chart->setPlotAreaBackgroundBrush(b);
861 861 m_chart->setPlotAreaBackgroundVisible(true);
862 862 emit plotAreaColorChanged();
863 863 }
864 864 }
865 865
866 866 QColor QtCharts::DeclarativeChart::plotAreaColor()
867 867 {
868 868 return m_chart->plotAreaBackgroundBrush().color();
869 869 }
870 870
871 871 void DeclarativeChart::setLocalizeNumbers(bool localize)
872 872 {
873 873 if (m_chart->localizeNumbers() != localize) {
874 874 m_chart->setLocalizeNumbers(localize);
875 875 emit localizeNumbersChanged();
876 876 }
877 877 }
878 878
879 879 bool DeclarativeChart::localizeNumbers() const
880 880 {
881 881 return m_chart->localizeNumbers();
882 882 }
883 883
884 884 void QtCharts::DeclarativeChart::setLocale(const QLocale &locale)
885 885 {
886 886 if (m_chart->locale() != locale) {
887 887 m_chart->setLocale(locale);
888 888 emit localeChanged();
889 889 }
890 890 }
891 891
892 892 QLocale QtCharts::DeclarativeChart::locale() const
893 893 {
894 894 return m_chart->locale();
895 895 }
896 896
897 897 int DeclarativeChart::count()
898 898 {
899 899 return m_chart->series().count();
900 900 }
901 901
902 902 void DeclarativeChart::setDropShadowEnabled(bool enabled)
903 903 {
904 904 if (enabled != m_chart->isDropShadowEnabled()) {
905 905 m_sceneImageNeedsClear = true;
906 906 m_chart->setDropShadowEnabled(enabled);
907 907 dropShadowEnabledChanged(enabled);
908 908 }
909 909 }
910 910
911 911 bool DeclarativeChart::dropShadowEnabled()
912 912 {
913 913 return m_chart->isDropShadowEnabled();
914 914 }
915 915
916 916 qreal DeclarativeChart::backgroundRoundness() const
917 917 {
918 918 return m_chart->backgroundRoundness();
919 919 }
920 920
921 921 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
922 922 {
923 923 if (m_chart->backgroundRoundness() != diameter) {
924 924 m_sceneImageNeedsClear = true;
925 925 m_chart->setBackgroundRoundness(diameter);
926 926 emit backgroundRoundnessChanged(diameter);
927 927 }
928 928 }
929 929
930 930 void DeclarativeChart::zoom(qreal factor)
931 931 {
932 932 m_chart->zoom(factor);
933 933 }
934 934
935 935 void DeclarativeChart::zoomIn()
936 936 {
937 937 m_chart->zoomIn();
938 938 }
939 939
940 940 void DeclarativeChart::zoomIn(const QRectF &rectangle)
941 941 {
942 942 m_chart->zoomIn(rectangle);
943 943 }
944 944
945 945 void DeclarativeChart::zoomOut()
946 946 {
947 947 m_chart->zoomOut();
948 948 }
949 949
950 950 void DeclarativeChart::zoomReset()
951 951 {
952 952 m_chart->zoomReset();
953 953 }
954 954
955 955 bool DeclarativeChart::isZoomed()
956 956 {
957 957 return m_chart->isZoomed();
958 958 }
959 959
960 960 void DeclarativeChart::scrollLeft(qreal pixels)
961 961 {
962 962 m_chart->scroll(-pixels, 0);
963 963 }
964 964
965 965 void DeclarativeChart::scrollRight(qreal pixels)
966 966 {
967 967 m_chart->scroll(pixels, 0);
968 968 }
969 969
970 970 void DeclarativeChart::scrollUp(qreal pixels)
971 971 {
972 972 m_chart->scroll(0, pixels);
973 973 }
974 974
975 975 void DeclarativeChart::scrollDown(qreal pixels)
976 976 {
977 977 m_chart->scroll(0, -pixels);
978 978 }
979 979
980 980 QQmlListProperty<QAbstractAxis> DeclarativeChart::axes()
981 981 {
982 982 return QQmlListProperty<QAbstractAxis>(this, 0,
983 983 &DeclarativeChart::axesAppendFunc,
984 984 &DeclarativeChart::axesCountFunc,
985 985 &DeclarativeChart::axesAtFunc,
986 986 &DeclarativeChart::axesClearFunc);
987 987 }
988 988
989 989 void DeclarativeChart::axesAppendFunc(QQmlListProperty<QAbstractAxis> *list, QAbstractAxis *element)
990 990 {
991 991 // Empty implementation
992 992 Q_UNUSED(list);
993 993 Q_UNUSED(element);
994 994 }
995 995
996 996 int DeclarativeChart::axesCountFunc(QQmlListProperty<QAbstractAxis> *list)
997 997 {
998 998 if (qobject_cast<DeclarativeChart *>(list->object)) {
999 999 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
1000 1000 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
1001 1001 }
1002 1002 return 0;
1003 1003 }
1004 1004
1005 1005 QAbstractAxis *DeclarativeChart::axesAtFunc(QQmlListProperty<QAbstractAxis> *list, int index)
1006 1006 {
1007 1007 if (qobject_cast<DeclarativeChart *>(list->object)) {
1008 1008 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
1009 1009 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
1010 1010 return axes.at(index);
1011 1011 }
1012 1012 return 0;
1013 1013 }
1014 1014
1015 1015 void DeclarativeChart::axesClearFunc(QQmlListProperty<QAbstractAxis> *list)
1016 1016 {
1017 1017 // Empty implementation
1018 1018 Q_UNUSED(list);
1019 1019 }
1020 1020
1021 1021
1022 1022 QAbstractSeries *DeclarativeChart::series(int index)
1023 1023 {
1024 1024 if (index < m_chart->series().count()) {
1025 1025 return m_chart->series().at(index);
1026 1026 }
1027 1027 return 0;
1028 1028 }
1029 1029
1030 1030 QAbstractSeries *DeclarativeChart::series(QString seriesName)
1031 1031 {
1032 1032 foreach (QAbstractSeries *series, m_chart->series()) {
1033 1033 if (series->name() == seriesName)
1034 1034 return series;
1035 1035 }
1036 1036 return 0;
1037 1037 }
1038 1038
1039 1039 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
1040 1040 {
1041 1041 QAbstractSeries *series = 0;
1042 1042
1043 1043 switch (type) {
1044 1044 case DeclarativeChart::SeriesTypeLine:
1045 1045 series = new DeclarativeLineSeries();
1046 1046 break;
1047 1047 case DeclarativeChart::SeriesTypeArea: {
1048 1048 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
1049 1049 DeclarativeLineSeries *line = new DeclarativeLineSeries();
1050 1050 line->setParent(area);
1051 1051 area->setUpperSeries(line);
1052 1052 series = area;
1053 1053 break;
1054 1054 }
1055 1055 case DeclarativeChart::SeriesTypeStackedBar:
1056 1056 series = new DeclarativeStackedBarSeries();
1057 1057 break;
1058 1058 case DeclarativeChart::SeriesTypePercentBar:
1059 1059 series = new DeclarativePercentBarSeries();
1060 1060 break;
1061 1061 case DeclarativeChart::SeriesTypeBar:
1062 1062 series = new DeclarativeBarSeries();
1063 1063 break;
1064 1064 case DeclarativeChart::SeriesTypeHorizontalBar:
1065 1065 series = new DeclarativeHorizontalBarSeries();
1066 1066 break;
1067 1067 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
1068 1068 series = new DeclarativeHorizontalPercentBarSeries();
1069 1069 break;
1070 1070 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
1071 1071 series = new DeclarativeHorizontalStackedBarSeries();
1072 1072 break;
1073 1073 case DeclarativeChart::SeriesTypeBoxPlot:
1074 1074 series = new DeclarativeBoxPlotSeries();
1075 1075 break;
1076 1076 case DeclarativeChart::SeriesTypePie:
1077 1077 series = new DeclarativePieSeries();
1078 1078 break;
1079 1079 case DeclarativeChart::SeriesTypeScatter:
1080 1080 series = new DeclarativeScatterSeries();
1081 1081 break;
1082 1082 case DeclarativeChart::SeriesTypeSpline:
1083 1083 series = new DeclarativeSplineSeries();
1084 1084 break;
1085 1085 default:
1086 1086 qWarning() << "Illegal series type";
1087 1087 }
1088 1088
1089 1089 if (series) {
1090 1090 // Connect to axis changed signals (unless this is a pie series)
1091 1091 if (!qobject_cast<DeclarativePieSeries *>(series)) {
1092 1092 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1093 1093 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1094 1094 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
1095 1095 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
1096 1096 }
1097 1097
1098 1098 series->setName(name);
1099 1099 m_chart->addSeries(series);
1100 1100
1101 1101 if (!axisX || !axisY)
1102 1102 initializeAxes(series);
1103 1103
1104 1104 if (axisX)
1105 1105 setAxisX(axisX, series);
1106 1106 if (axisY)
1107 1107 setAxisY(axisY, series);
1108 1108 }
1109 1109
1110 1110 return series;
1111 1111 }
1112 1112
1113 1113 void DeclarativeChart::removeSeries(QAbstractSeries *series)
1114 1114 {
1115 1115 if (series)
1116 1116 m_chart->removeSeries(series);
1117 1117 else
1118 1118 qWarning("removeSeries: cannot remove null");
1119 1119 }
1120 1120
1121 1121 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
1122 1122 {
1123 1123 if (axis && series)
1124 1124 seriesAxisAttachHelper(series, axis, Qt::Horizontal, Qt::AlignBottom);
1125 1125 }
1126 1126
1127 1127 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
1128 1128 {
1129 1129 if (axis && series)
1130 1130 seriesAxisAttachHelper(series, axis, Qt::Vertical, Qt::AlignLeft);
1131 1131 }
1132 1132
1133 1133 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
1134 1134 {
1135 1135 if (!series) {
1136 1136 qWarning() << "No axis type defined for null series";
1137 1137 return 0;
1138 1138 }
1139 1139
1140 1140 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
1141 1141 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
1142 1142 return existingAxis;
1143 1143 }
1144 1144
1145 1145 switch (series->d_ptr->defaultAxisType(orientation)) {
1146 1146 case QAbstractAxis::AxisTypeValue:
1147 1147 return new QValueAxis(this);
1148 1148 case QAbstractAxis::AxisTypeBarCategory:
1149 1149 return new QBarCategoryAxis(this);
1150 1150 case QAbstractAxis::AxisTypeCategory:
1151 1151 return new QCategoryAxis(this);
1152 #ifndef QT_ON_ARM
1152 #ifndef QT_QREAL_IS_FLOAT
1153 1153 case QAbstractAxis::AxisTypeDateTime:
1154 1154 return new QDateTimeAxis(this);
1155 1155 #endif
1156 1156 case QAbstractAxis::AxisTypeLogValue:
1157 1157 return new QLogValueAxis(this);
1158 1158 default:
1159 1159 // assume AxisTypeNoAxis
1160 1160 return 0;
1161 1161 }
1162 1162 }
1163 1163
1164 1164 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1165 1165 {
1166 1166 if (qobject_cast<DeclarativeLineSeries *>(series))
1167 1167 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
1168 1168 else if (qobject_cast<DeclarativeScatterSeries *>(series))
1169 1169 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
1170 1170 else if (qobject_cast<DeclarativeSplineSeries *>(series))
1171 1171 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
1172 1172 else if (qobject_cast<DeclarativeAreaSeries *>(series))
1173 1173 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
1174 1174 else if (qobject_cast<DeclarativeBarSeries *>(series))
1175 1175 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
1176 1176 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
1177 1177 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
1178 1178 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
1179 1179 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1180 1180 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1181 1181 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1182 1182 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1183 1183 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1184 1184 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1185 1185 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1186 1186 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1187 1187 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1188 1188 // else: do nothing
1189 1189 }
1190 1190
1191 1191 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1192 1192 {
1193 1193 qreal min;
1194 1194 qreal max;
1195 1195 // Initialize axis X
1196 1196 if (axes->axisX()) {
1197 1197 axes->emitAxisXChanged();
1198 1198 } else if (axes->axisXTop()) {
1199 1199 axes->emitAxisXTopChanged();
1200 1200 } else {
1201 1201 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1202 1202 findMinMaxForSeries(series, Qt::Horizontal, min, max);
1203 1203 axes->axisX()->setRange(min, max);
1204 1204 }
1205 1205
1206 1206 // Initialize axis Y
1207 1207 if (axes->axisY()) {
1208 1208 axes->emitAxisYChanged();
1209 1209 } else if (axes->axisYRight()) {
1210 1210 axes->emitAxisYRightChanged();
1211 1211 } else {
1212 1212 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1213 1213 findMinMaxForSeries(series, Qt::Vertical, min, max);
1214 1214 axes->axisY()->setRange(min, max);
1215 1215 }
1216 1216 }
1217 1217
1218 1218 void DeclarativeChart::findMinMaxForSeries(QAbstractSeries *series, Qt::Orientations orientation,
1219 1219 qreal &min, qreal &max)
1220 1220 {
1221 1221 if (!series) {
1222 1222 min = 0.5;
1223 1223 max = 0.5;
1224 1224 } else {
1225 1225 AbstractDomain *domain = series->d_ptr->domain();
1226 1226 min = (orientation == Qt::Vertical) ? domain->minY() : domain->minX();
1227 1227 max = (orientation == Qt::Vertical) ? domain->maxY() : domain->maxX();
1228 1228
1229 1229 if (min == max) {
1230 1230 min -= 0.5;
1231 1231 max += 0.5;
1232 1232 }
1233 1233 }
1234 1234 }
1235 1235
1236 1236 QPointF DeclarativeChart::mapToValue(const QPointF &position, QAbstractSeries *series)
1237 1237 {
1238 1238 return m_chart->mapToValue(position, series);
1239 1239 }
1240 1240
1241 1241 QPointF DeclarativeChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
1242 1242 {
1243 1243 return m_chart->mapToPosition(value, series);
1244 1244 }
1245 1245
1246 1246 #include "moc_declarativechart.cpp"
1247 1247
1248 1248 QT_CHARTS_END_NAMESPACE
@@ -1,41 +1,41
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += \
3 3 qchartview \
4 4 qchart \
5 5 qlineseries \
6 6 qbarset \
7 7 qbarseries \
8 8 qstackedbarseries \
9 9 qpercentbarseries \
10 10 qpieslice qpieseries \
11 11 qpiemodelmapper \
12 12 qsplineseries \
13 13 qscatterseries \
14 14 qxymodelmapper \
15 15 qbarmodelmapper \
16 16 qhorizontalbarseries \
17 17 qhorizontalstackedbarseries \
18 18 qhorizontalpercentbarseries \
19 19 qvalueaxis \
20 20 qlogvalueaxis \
21 21 qcategoryaxis \
22 22 qbarcategoryaxis \
23 23 domain \
24 24 chartdataset \
25 25 qlegend \
26 26 cmake
27 27
28 !linux-arm*: {
28 !contains(QT_COORD_TYPE, float): {
29 29 SUBDIRS += \
30 30 qdatetimeaxis
31 31 }
32 32
33 33 qtHaveModule(quick) {
34 34 SUBDIRS += qml \
35 35 qml-qtquicktest
36 36 }
37 37
38 38 !contains(QT_CONFIG, private_tests): SUBDIRS -= \
39 39 domain \
40 40 chartdataset
41 41
@@ -1,7 +1,8
1 1 !include( ../auto.pri ) {
2 2 error( "Couldn't find the auto.pri file!" )
3 3 }
4 4
5 5 QT += charts-private
6 contains(QT_COORD_TYPE, float): DEFINES += QT_QREAL_IS_FLOAT
6 7
7 8 SOURCES += tst_chartdataset.cpp
@@ -1,385 +1,385
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29
30 30 #include <QtTest/QtTest>
31 31 #include <QtCharts/QAbstractAxis>
32 32 #include <QtCharts/QValueAxis>
33 33 #include <QtCharts/QBarCategoryAxis>
34 34 #include <QtCharts/QCategoryAxis>
35 #ifndef QT_ON_ARM
35 #ifndef QT_QREAL_IS_FLOAT
36 36 #include <QtCharts/QDateTimeAxis>
37 37 #endif
38 38 #include <QtCharts/QLineSeries>
39 39 #include <QtCharts/QAreaSeries>
40 40 #include <QtCharts/QScatterSeries>
41 41 #include <QtCharts/QSplineSeries>
42 42 #include <QtCharts/QPieSeries>
43 43 #include <QtCharts/QBarSeries>
44 44 #include <QtCharts/QPercentBarSeries>
45 45 #include <QtCharts/QStackedBarSeries>
46 46 #include <private/chartdataset_p.h>
47 47 #include <private/abstractdomain_p.h>
48 48 #include <tst_definitions.h>
49 49
50 50 QT_CHARTS_USE_NAMESPACE
51 51
52 52 Q_DECLARE_METATYPE(AbstractDomain *)
53 53 Q_DECLARE_METATYPE(QAbstractAxis *)
54 54 Q_DECLARE_METATYPE(QAbstractSeries *)
55 55 Q_DECLARE_METATYPE(QList<QAbstractSeries *>)
56 56 Q_DECLARE_METATYPE(QList<QAbstractAxis *>)
57 57 Q_DECLARE_METATYPE(Qt::Alignment)
58 58 Q_DECLARE_METATYPE(QList<Qt::Alignment>)
59 59 Q_DECLARE_METATYPE(QLineSeries *)
60 60
61 61 class tst_ChartDataSet: public QObject {
62 62
63 63 Q_OBJECT
64 64 public:
65 65 tst_ChartDataSet():m_dataset(0){};
66 66
67 67 public Q_SLOTS:
68 68 void initTestCase();
69 69 void cleanupTestCase();
70 70 void init();
71 71 void cleanup();
72 72
73 73 private Q_SLOTS:
74 74 void chartdataset_data();
75 75 void chartdataset();
76 76 void addSeries_data();
77 77 void addSeries();
78 78 void removeSeries_data();
79 79 void removeSeries();
80 80 void addAxis_data();
81 81 void addAxis();
82 82 void removeAxis_data();
83 83 void removeAxis();
84 84 void attachAxis_data();
85 85 void attachAxis();
86 86 void detachAxis_data();
87 87 void detachAxis();
88 88
89 89 private:
90 90 ChartDataSet* m_dataset;
91 91 };
92 92
93 93 void tst_ChartDataSet::initTestCase()
94 94 {
95 95 qRegisterMetaType<AbstractDomain*>();
96 96 qRegisterMetaType<QAbstractAxis*>();
97 97 qRegisterMetaType<QAbstractSeries*>();
98 98 }
99 99
100 100 void tst_ChartDataSet::cleanupTestCase()
101 101 {
102 102 QTest::qWait(1); // Allow final deleteLaters to run
103 103 }
104 104
105 105 void tst_ChartDataSet::init()
106 106 {
107 107 Q_ASSERT(!m_dataset);
108 108 m_dataset = new ChartDataSet(0);
109 109 }
110 110
111 111
112 112 void tst_ChartDataSet::cleanup()
113 113 {
114 114 delete m_dataset;
115 115 m_dataset = 0;
116 116 }
117 117
118 118 void tst_ChartDataSet::chartdataset_data()
119 119 {
120 120 }
121 121
122 122 void tst_ChartDataSet::chartdataset()
123 123 {
124 124 QVERIFY(m_dataset->axes().isEmpty());
125 125 QVERIFY(m_dataset->series().isEmpty());
126 126 m_dataset->createDefaultAxes();
127 127 }
128 128
129 129
130 130 void tst_ChartDataSet::addSeries_data()
131 131 {
132 132 QTest::addColumn<QAbstractSeries*>("series");
133 133
134 134 QAbstractSeries* line = new QLineSeries(this);
135 135 QTest::newRow("line") << line;
136 136
137 137 QAbstractSeries* area = new QAreaSeries(static_cast<QLineSeries*>(new QLineSeries(this)));
138 138 QTest::newRow("area") << area;
139 139
140 140 QAbstractSeries* scatter = new QScatterSeries(this);
141 141 QTest::newRow("scatter") << scatter;
142 142
143 143 QAbstractSeries* spline = new QSplineSeries(this);
144 144 QTest::newRow("spline") << spline;
145 145
146 146 QAbstractSeries* pie = new QPieSeries(this);
147 147 QTest::newRow("pie") << pie;
148 148
149 149 QAbstractSeries* bar = new QBarSeries(this);
150 150 QTest::newRow("bar") << bar;
151 151
152 152 QAbstractSeries* percent = new QPercentBarSeries(this);
153 153 QTest::newRow("percent") << percent;
154 154
155 155 QAbstractSeries* stacked = new QStackedBarSeries(this);
156 156 QTest::newRow("stacked") << stacked;
157 157 }
158 158
159 159 void tst_ChartDataSet::addSeries()
160 160 {
161 161 QFETCH(QAbstractSeries*, series);
162 162 QVERIFY(m_dataset->series().isEmpty());
163 163
164 164 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
165 165 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
166 166 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
167 167 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
168 168
169 169 m_dataset->addSeries(series);
170 170
171 171 QCOMPARE(m_dataset->series().count(),1);
172 172 TRY_COMPARE(spy0.count(), 0);
173 173 TRY_COMPARE(spy1.count(), 0);
174 174 TRY_COMPARE(spy2.count(), 1);
175 175 TRY_COMPARE(spy3.count(), 0);
176 176 }
177 177
178 178 void tst_ChartDataSet::removeSeries_data()
179 179 {
180 180 addSeries_data();
181 181 }
182 182
183 183 void tst_ChartDataSet::removeSeries()
184 184 {
185 185 QFETCH(QAbstractSeries*, series);
186 186 QVERIFY(m_dataset->series().isEmpty());
187 187 m_dataset->addSeries(series);
188 188
189 189 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
190 190 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
191 191 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
192 192 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
193 193
194 194 m_dataset->removeSeries(series);
195 195
196 196 QCOMPARE(m_dataset->series().count(),0);
197 197 TRY_COMPARE(spy0.count(), 0);
198 198 TRY_COMPARE(spy1.count(), 0);
199 199 TRY_COMPARE(spy2.count(), 0);
200 200 TRY_COMPARE(spy3.count(), 1);
201 201
202 202 delete series;
203 203 }
204 204
205 205 void tst_ChartDataSet::addAxis_data()
206 206 {
207 207 QTest::addColumn<QAbstractAxis*>("axis");
208 208 QAbstractAxis* value = new QValueAxis(this);
209 209 QAbstractAxis* category = new QCategoryAxis(this);
210 210 QAbstractAxis* barcategory = new QBarCategoryAxis(this);
211 #ifndef Q_WS_QWS
211 #ifndef QT_QREAL_IS_FLOAT
212 212 QAbstractAxis* datetime = new QDateTimeAxis(this);
213 213 #endif
214 214
215 215 QTest::newRow("value") << value;
216 216 QTest::newRow("category") << category;
217 217 QTest::newRow("barcategory") << barcategory;
218 #ifndef Q_WS_QWS
218 #ifndef QT_QREAL_IS_FLOAT
219 219 QTest::newRow("datetime") << datetime;
220 220 #endif
221 221 }
222 222
223 223 void tst_ChartDataSet::addAxis()
224 224 {
225 225 QFETCH(QAbstractAxis*, axis);
226 226 QVERIFY(m_dataset->axes().isEmpty());
227 227
228 228 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
229 229 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
230 230 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
231 231 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
232 232
233 233 m_dataset->addAxis(axis,Qt::AlignBottom);
234 234
235 235 QCOMPARE(m_dataset->axes().count(),1);
236 236 TRY_COMPARE(spy0.count(), 1);
237 237 TRY_COMPARE(spy1.count(), 0);
238 238 TRY_COMPARE(spy2.count(), 0);
239 239 TRY_COMPARE(spy3.count(), 0);
240 240 }
241 241
242 242 void tst_ChartDataSet::removeAxis_data()
243 243 {
244 244 addAxis_data();
245 245 }
246 246
247 247 void tst_ChartDataSet::removeAxis()
248 248 {
249 249 QFETCH(QAbstractAxis*, axis);
250 250 QVERIFY(m_dataset->series().isEmpty());
251 251 m_dataset->addAxis(axis,Qt::AlignBottom);
252 252
253 253 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
254 254 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
255 255 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
256 256 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
257 257
258 258 m_dataset->removeAxis(axis);
259 259
260 260 QCOMPARE(m_dataset->axes().count(),0);
261 261 QCOMPARE(m_dataset->series().count(),0);
262 262 TRY_COMPARE(spy0.count(), 0);
263 263 TRY_COMPARE(spy1.count(), 1);
264 264 TRY_COMPARE(spy2.count(), 0);
265 265 TRY_COMPARE(spy3.count(), 0);
266 266
267 267 delete axis;
268 268 }
269 269
270 270 void tst_ChartDataSet::attachAxis_data()
271 271 {
272 272
273 273 QTest::addColumn<QList<QAbstractSeries*> >("series");
274 274 QTest::addColumn<QList<QAbstractAxis*> >("axis");
275 275 QTest::addColumn<QList<Qt::Alignment> >("alignment");
276 276 QTest::addColumn<QAbstractSeries*>("attachSeries");
277 277 QTest::addColumn<QAbstractAxis*>("attachAxis");
278 278 QTest::addColumn<bool>("success");
279 279
280 280 {
281 281 QList<QAbstractSeries*> series;
282 282 QList<QAbstractAxis*> axes;
283 283 QList<Qt::Alignment> alignment;
284 284 QAbstractSeries* line = new QLineSeries(this);
285 285 QAbstractAxis* value1 = new QValueAxis(this);
286 286 QAbstractAxis* value2 = new QValueAxis(this);
287 287 series << line << 0;
288 288 axes << value1 << value2;
289 289 alignment << Qt::AlignBottom << Qt::AlignLeft;
290 290 QTest::newRow("first") << series << axes << alignment << line << value2 << true ;
291 291 }
292 292
293 293 {
294 294 QList<QAbstractSeries*> series;
295 295 QList<QAbstractAxis*> axes;
296 296 QList<Qt::Alignment> alignment;
297 297 QAbstractSeries* line = new QLineSeries(this);
298 298 QAbstractAxis* value1 = new QValueAxis(this);
299 299 QAbstractAxis* value2 = new QValueAxis(this);
300 300 series << 0 << line;
301 301 axes << value1 << value2;
302 302 alignment << Qt::AlignBottom << Qt::AlignLeft;
303 303 QTest::newRow("second") << series << axes << alignment << line << value1 << true;
304 304 }
305 305
306 306 }
307 307
308 308 void tst_ChartDataSet::attachAxis()
309 309 {
310 310 QFETCH(QList<QAbstractSeries*>, series);
311 311 QFETCH(QList<QAbstractAxis*>, axis);
312 312 QFETCH(QList<Qt::Alignment>, alignment);
313 313 QFETCH(QAbstractSeries*, attachSeries);
314 314 QFETCH(QAbstractAxis*, attachAxis);
315 315 QFETCH(bool, success);
316 316
317 317 Q_ASSERT(series.count() == axis.count());
318 318 Q_ASSERT(series.count() == alignment.count());
319 319
320 320 QVERIFY(m_dataset->series().isEmpty());
321 321 QVERIFY(m_dataset->axes().isEmpty());
322 322
323 323 for(int i = 0 ; i < series.count() ; i++){
324 324 if(series[i]) m_dataset->addSeries(series[i]);
325 325 if(axis[i]) m_dataset->addAxis(axis[i],alignment[i]);
326 326 if(series[i] && axis[i]) m_dataset->attachAxis(series[i],axis[i]);
327 327 }
328 328
329 329 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
330 330 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
331 331 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
332 332 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
333 333
334 334 QCOMPARE(m_dataset->attachAxis(attachSeries,attachAxis),success);
335 335
336 336 }
337 337
338 338 void tst_ChartDataSet::detachAxis_data()
339 339 {
340 340 QTest::addColumn<QList<QAbstractSeries*> >("series");
341 341 QTest::addColumn<QList<QAbstractAxis*> >("axis");
342 342 QTest::addColumn<QAbstractSeries*>("detachSeries");
343 343 QTest::addColumn<QAbstractAxis*>("detachAxis");
344 344 QTest::addColumn<bool>("success");
345 345
346 346 {
347 347 QList<QAbstractSeries*> series;
348 348 QList<QAbstractAxis*> axes;
349 349 QAbstractSeries* line = new QLineSeries(this);
350 350 QAbstractAxis* value = new QValueAxis(this);
351 351 series << line;
352 352 axes << value;
353 353 QTest::newRow("first") << series << axes << line << value << true;
354 354 }
355 355 }
356 356
357 357 void tst_ChartDataSet::detachAxis()
358 358 {
359 359 QFETCH(QList<QAbstractSeries*>, series);
360 360 QFETCH(QList<QAbstractAxis*>, axis);
361 361 QFETCH(QAbstractSeries*, detachSeries);
362 362 QFETCH(QAbstractAxis*, detachAxis);
363 363 QFETCH(bool, success);
364 364
365 365 Q_ASSERT(series.count() == axis.count());
366 366
367 367 QVERIFY(m_dataset->series().isEmpty());
368 368 QVERIFY(m_dataset->axes().isEmpty());
369 369
370 370 for(int i = 0; i < series.count(); i++) {
371 371 if(series[i]) m_dataset->addSeries(series[i]);
372 372 if(axis[i]) m_dataset->addAxis(axis[i],Qt::AlignBottom);
373 373 if(series[i] && axis[i]) m_dataset->attachAxis(series[i],axis[i]);
374 374 }
375 375
376 376 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)));
377 377 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
378 378 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)));
379 379 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
380 380
381 381 QCOMPARE(m_dataset->detachAxis(detachSeries,detachAxis),success);
382 382 }
383 383
384 384 QTEST_MAIN(tst_ChartDataSet)
385 385 #include "tst_chartdataset.moc"
@@ -1,5 +1,6
1 1 !include( ../auto.pri ) {
2 2 error( "Couldn't find the auto.pri file!" )
3 3 }
4 4 SOURCES += tst_qml.cpp
5 5 QT += qml quick
6 contains(QT_COORD_TYPE, float): DEFINES += QT_QREAL_IS_FLOAT
@@ -1,213 +1,213
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2016 The Qt Company Ltd.
4 4 ** Contact: https://www.qt.io/licensing/
5 5 **
6 6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 7 **
8 8 ** $QT_BEGIN_LICENSE:GPL$
9 9 ** Commercial License Usage
10 10 ** Licensees holding valid commercial Qt licenses may use this file in
11 11 ** accordance with the commercial license agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and The Qt Company. For licensing terms
14 14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 15 ** information use the contact form at https://www.qt.io/contact-us.
16 16 **
17 17 ** GNU General Public License Usage
18 18 ** Alternatively, this file may be used under the terms of the GNU
19 19 ** General Public License version 3 or (at your option) any later version
20 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 22 ** included in the packaging of this file. Please review the following
23 23 ** information to ensure the GNU General Public License requirements will
24 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 25 **
26 26 ** $QT_END_LICENSE$
27 27 **
28 28 ****************************************************************************/
29 29 #include <QtTest/QtTest>
30 30 #include <QtQml/QQmlEngine>
31 31 #include <QtQml/QQmlComponent>
32 32 #include "tst_definitions.h"
33 33
34 34 class tst_qml : public QObject
35 35 {
36 36 Q_OBJECT
37 37
38 38 public slots:
39 39 void initTestCase();
40 40 void cleanupTestCase();
41 41 void init();
42 42 void cleanup();
43 43 private slots:
44 44 void checkPlugin_data();
45 45 void checkPlugin();
46 46 private:
47 47 QString componentErrors(const QQmlComponent* component) const;
48 48 QString imports_1_1();
49 49 QString imports_1_3();
50 50 QString imports_1_4();
51 51 QString imports_2_0();
52 52 QString imports_2_1();
53 53
54 54 };
55 55
56 56 QString tst_qml::componentErrors(const QQmlComponent* component) const
57 57 {
58 58 Q_ASSERT(component);
59 59
60 60 QStringList errors;
61 61
62 62 foreach (QQmlError const& error, component->errors()) {
63 63 errors << error.toString();
64 64 }
65 65
66 66 return errors.join("\n");
67 67 }
68 68
69 69 QString tst_qml::imports_1_1()
70 70 {
71 71 return "import QtQuick 2.0 \n"
72 72 "import QtCharts 1.1 \n";
73 73 }
74 74
75 75 QString tst_qml::imports_1_3()
76 76 {
77 77 return "import QtQuick 2.0 \n"
78 78 "import QtCharts 1.3 \n";
79 79 }
80 80
81 81 QString tst_qml::imports_1_4()
82 82 {
83 83 return "import QtQuick 2.0 \n"
84 84 "import QtCharts 1.4 \n";
85 85 }
86 86
87 87 QString tst_qml::imports_2_0()
88 88 {
89 89 return "import QtQuick 2.0 \n"
90 90 "import QtCharts 2.0 \n";
91 91 }
92 92
93 93 QString tst_qml::imports_2_1()
94 94 {
95 95 return "import QtQuick 2.1 \n"
96 96 "import QtCharts 2.1 \n";
97 97 }
98 98
99 99 void tst_qml::initTestCase()
100 100 {
101 101 }
102 102
103 103 void tst_qml::cleanupTestCase()
104 104 {
105 105 }
106 106
107 107 void tst_qml::init()
108 108 {
109 109
110 110 }
111 111
112 112 void tst_qml::cleanup()
113 113 {
114 114
115 115 }
116 116
117 117 void tst_qml::checkPlugin_data()
118 118 {
119 119 QTest::addColumn<QString>("source");
120 120
121 121 QTest::newRow("createChartView") << imports_1_1() + "ChartView{}";
122 122 QTest::newRow("XYPoint") << imports_1_1() + "XYPoint{}";
123 123 QTest::newRow("scatterSeries") << imports_1_1() + "ScatterSeries{}";
124 124 QTest::newRow("lineSeries") << imports_1_1() + "LineSeries{}";
125 125 QTest::newRow("splineSeries") << imports_1_1() + "SplineSeries{}";
126 126 QTest::newRow("areaSeries") << imports_1_1() + "AreaSeries{}";
127 127 QTest::newRow("barSeries") << imports_1_1() + "BarSeries{}";
128 128 QTest::newRow("stackedBarSeries") << imports_1_1() + "StackedBarSeries{}";
129 129 QTest::newRow("precentBarSeries") << imports_1_1() + "PercentBarSeries{}";
130 130 QTest::newRow("horizonatlBarSeries") << imports_1_1() + "HorizontalBarSeries{}";
131 131 QTest::newRow("horizonatlStackedBarSeries") << imports_1_1() + "HorizontalStackedBarSeries{}";
132 132 QTest::newRow("horizonatlstackedBarSeries") << imports_1_1() + "HorizontalPercentBarSeries{}";
133 133 QTest::newRow("pieSeries") << imports_1_1() + "PieSeries{}";
134 134 QTest::newRow("PieSlice") << imports_1_1() + "PieSlice{}";
135 135 QTest::newRow("BarSet") << imports_1_1() + "BarSet{}";
136 136 QTest::newRow("HXYModelMapper") << imports_1_1() + "HXYModelMapper{}";
137 137 QTest::newRow("VXYModelMapper") << imports_1_1() + "VXYModelMapper{}";
138 138 QTest::newRow("HPieModelMapper") << imports_1_1() + "HPieModelMapper{}";
139 139 QTest::newRow("HPieModelMapper") << imports_1_1() + "HPieModelMapper{}";
140 140 QTest::newRow("HBarModelMapper") << imports_1_1() + "HBarModelMapper{}";
141 141 QTest::newRow("VBarModelMapper") << imports_1_1() + "VBarModelMapper{}";
142 142 QTest::newRow("ValueAxis") << imports_1_1() + "ValueAxis{}";
143 #ifndef QT_ON_ARM
143 #ifndef QT_QREAL_IS_FLOAT
144 144 QTest::newRow("DateTimeAxis") << imports_1_1() + "DateTimeAxis{}";
145 145 #endif
146 146 QTest::newRow("CategoryAxis") << imports_1_1() + "CategoryAxis{}";
147 147 QTest::newRow("CategoryRange") << imports_1_1() + "CategoryRange{}";
148 148 QTest::newRow("BarCategoryAxis") << imports_1_1() + "BarCategoryAxis{}";
149 149
150 150 QTest::newRow("createPolarChartView") << imports_1_3() + "PolarChartView{}";
151 151 QTest::newRow("LogValueAxis") << imports_1_3() + "LogValueAxis{}";
152 152 QTest::newRow("BoxPlotSeries") << imports_1_3() + "BoxPlotSeries{}";
153 153 QTest::newRow("BoxSet") << imports_1_3() + "BoxSet{}";
154 154
155 155 QTest::newRow("createChartView_2_0") << imports_2_0() + "ChartView{}";
156 156 QTest::newRow("XYPoint_2_0") << imports_2_0() + "XYPoint{}";
157 157 QTest::newRow("scatterSeries_2_0") << imports_2_0() + "ScatterSeries{}";
158 158 QTest::newRow("lineSeries_2_0") << imports_2_0() + "LineSeries{}";
159 159 QTest::newRow("splineSeries_2_0") << imports_2_0() + "SplineSeries{}";
160 160 QTest::newRow("areaSeries_2_0") << imports_2_0() + "AreaSeries{}";
161 161 QTest::newRow("barSeries_2_0") << imports_2_0() + "BarSeries{}";
162 162 QTest::newRow("stackedBarSeries_2_0") << imports_2_0() + "StackedBarSeries{}";
163 163 QTest::newRow("precentBarSeries_2_0") << imports_2_0() + "PercentBarSeries{}";
164 164 QTest::newRow("horizonatlBarSeries_2_0") << imports_2_0() + "HorizontalBarSeries{}";
165 165 QTest::newRow("horizonatlStackedBarSeries_2_0")
166 166 << imports_2_0() + "HorizontalStackedBarSeries{}";
167 167 QTest::newRow("horizonatlstackedBarSeries_2_0")
168 168 << imports_2_0() + "HorizontalPercentBarSeries{}";
169 169 QTest::newRow("pieSeries_2_0") << imports_2_0() + "PieSeries{}";
170 170 QTest::newRow("PieSlice_2_0") << imports_2_0() + "PieSlice{}";
171 171 QTest::newRow("BarSet_2_0") << imports_2_0() + "BarSet{}";
172 172 QTest::newRow("HXYModelMapper_2_0") << imports_2_0() + "HXYModelMapper{}";
173 173 QTest::newRow("VXYModelMapper_2_0") << imports_2_0() + "VXYModelMapper{}";
174 174 QTest::newRow("HPieModelMapper_2_0") << imports_2_0() + "HPieModelMapper{}";
175 175 QTest::newRow("HPieModelMapper_2_0") << imports_2_0() + "HPieModelMapper{}";
176 176 QTest::newRow("HBarModelMapper_2_0") << imports_2_0() + "HBarModelMapper{}";
177 177 QTest::newRow("VBarModelMapper_2_0") << imports_2_0() + "VBarModelMapper{}";
178 178 QTest::newRow("ValueAxis_2_0") << imports_2_0() + "ValueAxis{}";
179 #ifndef QT_ON_ARM
179 #ifndef QT_QREAL_IS_FLOAT
180 180 QTest::newRow("DateTimeAxis_2_0") << imports_2_0() + "DateTimeAxis{}";
181 181 #endif
182 182 QTest::newRow("CategoryAxis_2_0") << imports_2_0() + "CategoryAxis{}";
183 183 QTest::newRow("CategoryRange_2_0") << imports_2_0() + "CategoryRange{}";
184 184 QTest::newRow("BarCategoryAxis_2_0") << imports_2_0() + "BarCategoryAxis{}";
185 185 QTest::newRow("createPolarChartView_2_0") << imports_2_0() + "PolarChartView{}";
186 186 QTest::newRow("LogValueAxis_2_0") << imports_2_0() + "LogValueAxis{}";
187 187 QTest::newRow("BoxPlotSeries_2_0") << imports_2_0() + "BoxPlotSeries{}";
188 188 QTest::newRow("BoxSet_2_0") << imports_2_0() + "BoxSet{}";
189 189
190 190 QTest::newRow("CategoryAxis_2_1") << imports_2_1() + "CategoryAxis{}";
191 191 QTest::newRow("ScatterSeries_2_1") << imports_2_1() + "ScatterSeries{}";
192 192 QTest::newRow("LineSeries_2_1") << imports_2_1() + "LineSeries{}";
193 193 QTest::newRow("SplineSeries_2_1") << imports_2_1() + "SplineSeries{}";
194 194 }
195 195
196 196 void tst_qml::checkPlugin()
197 197 {
198 198 QFETCH(QString, source);
199 199 QQmlEngine engine;
200 200 engine.addImportPath(QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), QLatin1String("qml")));
201 201 QQmlComponent component(&engine);
202 202 component.setData(source.toLatin1(), QUrl());
203 203 QVERIFY2(!component.isError(), qPrintable(componentErrors(&component)));
204 204 TRY_COMPARE(component.status(), QQmlComponent::Ready);
205 205 QObject *obj = component.create();
206 206 QVERIFY(obj != 0);
207 207 delete obj;
208 208 }
209 209
210 210 QTEST_MAIN(tst_qml)
211 211
212 212 #include "tst_qml.moc"
213 213
@@ -1,51 +1,51
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3 SOURCES += \
4 4 $$PWD/font/font.cpp \
5 5 $$PWD/xyseries/linechart.cpp \
6 6 $$PWD/xyseries/scatterchart.cpp \
7 7 $$PWD/xyseries/splinechart.cpp \
8 8 $$PWD/xyseries/areachart.cpp \
9 9 $$PWD/barseries/verticalstackedbarchart.cpp \
10 10 $$PWD/barseries/horizontalstackedbarchart.cpp \
11 11 $$PWD/barseries/verticalbarchart.cpp \
12 12 $$PWD/barseries/horizontalbarchart.cpp \
13 13 $$PWD/barseries/horizontalpercentbarchart.cpp \
14 14 $$PWD/barseries/verticalpercentbarchart.cpp \
15 15 $$PWD/pieseries/piechart.cpp \
16 16 $$PWD/pieseries/donutchart.cpp \
17 17 $$PWD/axis/valueaxis.cpp \
18 18 $$PWD/axis/logvalueaxisx.cpp \
19 19 $$PWD/axis/logvalueaxisy.cpp \
20 20 $$PWD/axis/categoryaxis.cpp \
21 21 $$PWD/axis/barcategoryaxisx.cpp \
22 22 $$PWD/axis/barcategoryaxisy.cpp \
23 23 $$PWD/axis/barcategoryaxisxlogy.cpp \
24 24 $$PWD/axis/barcategoryaxisylogx.cpp \
25 25 $$PWD/multiaxis/multivalueaxis.cpp \
26 26 $$PWD/multiaxis/multivalueaxis2.cpp \
27 27 $$PWD/multiaxis/multivalueaxis3.cpp \
28 28 $$PWD/multiaxis/multivalueaxis4.cpp \
29 29 $$PWD/multiaxis/multivaluebaraxis.cpp \
30 30 $$PWD/size/sizecharts.cpp \
31 31 $$PWD/domain/barlogy.cpp \
32 32 $$PWD/domain/barlogx.cpp \
33 33 $$PWD/domain/barstackedlogy.cpp \
34 34 $$PWD/domain/barstackedlogx.cpp \
35 35 $$PWD/domain/barpercentlogy.cpp \
36 36 $$PWD/domain/barpercentlogx.cpp \
37 37 $$PWD/domain/linelogxlogy.cpp \
38 38 $$PWD/domain/linelogxy.cpp \
39 39 $$PWD/domain/linexlogy.cpp \
40 40 $$PWD/domain/splinelogxlogy.cpp \
41 41 $$PWD/domain/splinelogxy.cpp \
42 42 $$PWD/domain/splinexlogy.cpp \
43 43 $$PWD/domain/scatterlogxlogy.cpp \
44 44 $$PWD/domain/scatterlogxy.cpp \
45 45 $$PWD/domain/scatterxlogy.cpp
46 46
47 !linux-arm*: {
47 !contains(QT_COORD_TYPE, float): {
48 48 SOURCES += \
49 49 $$PWD/axis/datetimeaxisx.cpp \
50 50 $$PWD/axis/datetimeaxisy.cpp
51 51 }
General Comments 0
You need to be logged in to leave comments. Login now