##// END OF EJS Templates
Fix axis attachments in QML....
Miikka Heikkinen -
r2718:ec8b39fe3792
parent child
Show More
@@ -1,1051 +1,1055
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "declarativechart.h"
22 22 #include <QtGui/QPainter>
23 23 #include "declarativelineseries.h"
24 24 #include "declarativeareaseries.h"
25 25 #include "declarativebarseries.h"
26 26 #include "declarativepieseries.h"
27 27 #include "declarativesplineseries.h"
28 28 #include "declarativeboxplotseries.h"
29 29 #include "declarativescatterseries.h"
30 30 #include <QtCharts/QBarCategoryAxis>
31 31 #include <QtCharts/QValueAxis>
32 32 #include <QtCharts/QLogValueAxis>
33 33 #include <QtCharts/QCategoryAxis>
34 34 #include <private/qabstractseries_p.h>
35 35 #include "declarativemargins.h"
36 36 #include <private/chartdataset_p.h>
37 37 #include "declarativeaxes.h"
38 38 #include <private/qchart_p.h>
39 39 #include <QtCharts/QPolarChart>
40 40
41 41 #ifndef QT_ON_ARM
42 42 #include <QtCharts/QDateTimeAxis>
43 43 #endif
44 44
45 45 #include <QtWidgets/QGraphicsSceneMouseEvent>
46 46 #include <QtWidgets/QGraphicsSceneHoverEvent>
47 47 #include <QtWidgets/QApplication>
48 48 #include <QtCore/QTimer>
49 49 #include <QtCore/QThread>
50 50
51 51 QT_CHARTS_BEGIN_NAMESPACE
52 52
53 53 /*!
54 54 \qmltype ChartView
55 55 \instantiates DeclarativeChart
56 56 \inqmlmodule QtCharts
57 57
58 58 ChartView element is the parent that is responsible for showing different chart series types.
59 59
60 60 The following QML shows how to create a simple chart with one pie series:
61 61 \snippet qmlpiechart/qml/qmlpiechart/main.qml 1
62 62 \snippet qmlpiechart/qml/qmlpiechart/main.qml 2
63 63 \snippet qmlpiechart/qml/qmlpiechart/main.qml 3
64 64
65 65 \beginfloatleft
66 66 \image examples_qmlpiechart.png
67 67 \endfloat
68 68 \clearfloat
69 69 */
70 70
71 71 /*!
72 72 \qmlproperty Theme ChartView::theme
73 73 Theme defines the visual appearance of the chart, including for example colors, fonts, line
74 74 widths and chart background.
75 75 */
76 76
77 77 /*!
78 78 \qmlproperty Animation ChartView::animationOptions
79 79 Animation configuration of the chart. One of ChartView.NoAnimation, ChartView.GridAxisAnimations,
80 80 ChartView.SeriesAnimations or ChartView.AllAnimations.
81 81 */
82 82
83 83 /*!
84 84 \qmlproperty Font ChartView::titleFont
85 85 The title font of the chart.
86 86
87 87 See the Qt documentation for more details of Font.
88 88 */
89 89
90 90 /*!
91 91 \qmlproperty string ChartView::title
92 92 The title of the chart, shown on top of the chart.
93 93 \sa ChartView::titleColor
94 94 */
95 95
96 96 /*!
97 97 \qmlproperty color ChartView::titleColor
98 98 The color of the title text.
99 99 */
100 100
101 101 /*!
102 102 \qmlproperty Legend ChartView::legend
103 103 The legend of the chart. Legend lists all the series, pie slices and bar sets added on the chart.
104 104 */
105 105
106 106 /*!
107 107 \qmlproperty int ChartView::count
108 108 The count of series added to the chart.
109 109 */
110 110
111 111 /*!
112 112 \qmlproperty color ChartView::backgroundColor
113 113 The color of the chart's background. By default background color is defined by chart theme.
114 114 \sa ChartView::theme
115 115 */
116 116
117 117 /*!
118 118 \qmlproperty real ChartView::backgroundRoundness
119 119 The diameter of the rounding cirle at the corners of the chart background.
120 120 */
121 121
122 122 /*!
123 123 \qmlproperty color ChartView::plotAreaColor
124 124 The color of the background of the chart's plot area. By default plot area background uses chart's
125 125 background color.
126 126 \sa ChartView::backgroundColor
127 127 */
128 128
129 129 /*!
130 130 \qmlproperty bool ChartView::dropShadowEnabled
131 131 The chart's border drop shadow. Set to true to enable drop shadow.
132 132 */
133 133
134 134 /*!
135 135 \qmlproperty real ChartView::topMargin
136 136 Deprecated; use margins instead.
137 137 */
138 138
139 139 /*!
140 140 \qmlproperty real ChartView::bottomMargin
141 141 Deprecated; use margins instead.
142 142 */
143 143
144 144 /*!
145 145 \qmlproperty real ChartView::leftMargin
146 146 Deprecated; use margins instead.
147 147 */
148 148
149 149 /*!
150 150 \qmlproperty real ChartView::rightMargin
151 151 Deprecated; use margins instead.
152 152 */
153 153
154 154 /*!
155 155 \qmlproperty Margins ChartView::minimumMargins
156 156 Deprecated; use margins instead.
157 157 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
158 158 area of ChartView is used for drawing title, axes and legend. Please note that setting the
159 159 properties of minimumMargins may be bigger than the defined value, depending on other ChartView
160 160 properties that affect it's layout. If you need to know the actual plotting area used at any
161 161 given time, you can check ChartView::plotArea instead.
162 162 */
163 163
164 164 /*!
165 165 \qmlproperty rect ChartView::plotArea
166 166 The area on the ChartView that is used for drawing series. This is the ChartView rect without the
167 167 margins.
168 168 \sa ChartView::minimumMargins
169 169 */
170 170
171 171 /*!
172 172 \qmlproperty Margins ChartView::margins
173 173 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
174 174 area of ChartView is used for drawing title, axes and legend.
175 175 */
176 176
177 177 /*!
178 178 \qmlproperty bool ChartView::localizeNumbers
179 179 \since QtCharts 2.0
180 180 When \c{true}, all generated numbers appearing in various series and axis labels will be
181 181 localized using the default QLocale of the application, which defaults to the system locale.
182 182 When \c{false}, the "C" locale is always used.
183 183 Defaults to \c{false}.
184 184
185 185 \sa locale
186 186 */
187 187
188 188 /*!
189 189 \qmlproperty locale ChartView::locale
190 190 \since QtCharts 2.0
191 191 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
192 192 This also determines the locale used to format DateTimeAxis labels regardless of
193 193 localizeNumbers property.
194 194 Defaults to application default locale at the time the chart is constructed.
195 195
196 196 \sa localizeNumbers
197 197 */
198 198
199 199 /*!
200 200 \qmlmethod AbstractSeries ChartView::series(int index)
201 201 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
202 202 the count property of the chart.
203 203 */
204 204
205 205 /*!
206 206 \qmlmethod AbstractSeries ChartView::series(string name)
207 207 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
208 208 */
209 209
210 210 /*!
211 211 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
212 212 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
213 213 optional axis \a axisY. For example:
214 214 \code
215 215 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
216 216 var myAxisX = chartView.axisX(lineSeries);
217 217 var myAxisY = chartView.axisY(lineSeries);
218 218 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
219 219 \endcode
220 220 */
221 221
222 222 /*!
223 223 \qmlmethod ChartView::removeSeries(AbstractSeries series)
224 224 Removes the \a series from the chart. The series object is also destroyed.
225 225 */
226 226
227 227 /*!
228 228 \qmlmethod ChartView::removeAllSeries()
229 229 Removes all series from the chart. All the series objects are also destroyed.
230 230 */
231 231
232 232 /*!
233 233 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
234 234 The x-axis of the series.
235 235 */
236 236
237 237 /*!
238 238 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
239 239 The y-axis of the series.
240 240 */
241 241
242 242 /*!
243 243 \qmlmethod ChartView::zoomY(real factor)
244 244 Zooms in by \a factor on the center of the chart.
245 245 */
246 246
247 247 /*!
248 248 \qmlmethod ChartView::scrollLeft(real pixels)
249 249 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
250 250 */
251 251
252 252 /*!
253 253 \qmlmethod ChartView::scrollRight(real pixels)
254 254 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
255 255 */
256 256
257 257 /*!
258 258 \qmlmethod ChartView::scrollUp(real pixels)
259 259 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
260 260 */
261 261
262 262 /*!
263 263 \qmlmethod ChartView::scrollDown(real pixels)
264 264 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
265 265 */
266 266
267 267 /*!
268 268 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
269 269 The \a series has been added to the chart.
270 270 */
271 271
272 272 /*!
273 273 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
274 274 The \a series has been removed from the chart. Please note that \a series is no longer a valid
275 275 object after the signal handler has completed.
276 276 */
277 277
278 278 DeclarativeChart::DeclarativeChart(QQuickItem *parent)
279 279 : QQuickPaintedItem(parent)
280 280 {
281 281 initChart(QChart::ChartTypeCartesian);
282 282 }
283 283
284 284 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QQuickItem *parent)
285 285 : QQuickPaintedItem(parent)
286 286 {
287 287 initChart(type);
288 288 }
289 289
290 290 void DeclarativeChart::initChart(QChart::ChartType type)
291 291 {
292 292 m_currentSceneImage = 0;
293 293 m_guiThreadId = QThread::currentThreadId();
294 294 m_paintThreadId = 0;
295 295 m_updatePending = false;
296 296
297 297 if (type == QChart::ChartTypePolar)
298 298 m_chart = new QPolarChart();
299 299 else
300 300 m_chart = new QChart();
301 301
302 302 m_scene = new QGraphicsScene(this);
303 303 m_scene->addItem(m_chart);
304 304
305 305 setAntialiasing(QQuickItem::antialiasing());
306 306 connect(m_scene, SIGNAL(changed(QList<QRectF>)), this, SLOT(sceneChanged(QList<QRectF>)));
307 307 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
308 308
309 309 setAcceptedMouseButtons(Qt::AllButtons);
310 310 setAcceptHoverEvents(true);
311 311
312 312 m_margins = new DeclarativeMargins(this);
313 313 m_margins->setTop(m_chart->margins().top());
314 314 m_margins->setLeft(m_chart->margins().left());
315 315 m_margins->setRight(m_chart->margins().right());
316 316 m_margins->setBottom(m_chart->margins().bottom());
317 317 connect(m_margins, SIGNAL(topChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
318 318 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
319 319 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
320 320 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
321 321 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
322 322 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
323 323 connect(m_chart, &QChart::plotAreaChanged, this, &DeclarativeChart::plotAreaChanged);
324 324 }
325 325
326 326 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
327 327 {
328 328 emit seriesAdded(series);
329 329 }
330 330
331 331 void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
332 332 {
333 333 m_chart->setMargins(QMargins(left, top, right, bottom));
334 334 emit minimumMarginsChanged();
335 335 }
336 336
337 337 DeclarativeChart::~DeclarativeChart()
338 338 {
339 339 delete m_chart;
340 340 m_sceneImageLock.lock();
341 341 delete m_currentSceneImage;
342 342 m_currentSceneImage = 0;
343 343 m_sceneImageLock.unlock();
344 344 }
345 345
346 346 void DeclarativeChart::childEvent(QChildEvent *event)
347 347 {
348 348 if (event->type() == QEvent::ChildAdded) {
349 349 if (qobject_cast<QAbstractSeries *>(event->child())) {
350 350 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
351 351 }
352 352 }
353 353 }
354 354
355 355 void DeclarativeChart::componentComplete()
356 356 {
357 357 foreach (QObject *child, children()) {
358 358 if (qobject_cast<QAbstractSeries *>(child)) {
359 359 // Add series to the chart
360 360 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
361 361 m_chart->addSeries(series);
362 362
363 363 // Connect to axis changed signals (unless this is a pie series)
364 364 if (!qobject_cast<DeclarativePieSeries *>(series)) {
365 365 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
366 366 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
367 367 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
368 368 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
369 369 }
370 370
371 371 initializeAxes(series);
372 372 }
373 373 }
374 374
375 375 QQuickItem::componentComplete();
376 376 }
377 377
378 void DeclarativeChart::seriesAxisAttachHelper(QAbstractSeries *series, QAbstractAxis *axis,
379 Qt::Orientations orientation,
380 Qt::Alignment alignment)
381 {
382 if (!series->attachedAxes().contains(axis)) {
383 // Remove & delete old axes that are not attached to any other series
384 foreach (QAbstractAxis* oldAxis, m_chart->axes(orientation, series)) {
385 bool otherAttachments = false;
386 if (oldAxis != axis) {
387 foreach (QAbstractSeries *oldSeries, m_chart->series()) {
388 if (oldSeries != series && oldSeries->attachedAxes().contains(oldAxis)) {
389 otherAttachments = true;
390 break;
391 }
392 }
393 if (!otherAttachments) {
394 m_chart->removeAxis(oldAxis);
395 delete oldAxis;
396 }
397 }
398 }
399 if (!m_chart->axes(orientation).contains(axis))
400 m_chart->addAxis(axis, alignment);
401
402 series->attachAxis(axis);
403 }
404 }
405
378 406 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
379 407 {
380 408 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
381 409 if (axis && s) {
382 if (!m_chart->axes(Qt::Horizontal).contains(axis))
383 m_chart->setAxisX(axis, s);
384 if (!s->attachedAxes().contains(axis))
385 s->attachAxis(axis);
410 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignBottom);
386 411 } else {
387 412 qWarning() << "Trying to set axisX to null.";
388 413 }
389 414 }
390 415
391 416 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
392 417 {
393 418 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
394 419 if (axis && s) {
395 if (!m_chart->axes(Qt::Horizontal).contains(axis)) {
396 QList<QAbstractAxis *> oldAxes = m_chart->axes(Qt::Horizontal, s);
397 foreach (QAbstractAxis* a, oldAxes) {
398 m_chart->removeAxis(a);
399 delete a;
400 }
401 m_chart->addAxis(axis, Qt::AlignTop);
402 }
403 if (!s->attachedAxes().contains(axis))
404 s->attachAxis(axis);
420 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignTop);
405 421 } else {
406 422 qWarning() << "Trying to set axisXTop to null.";
407 423 }
408 424 }
409 425
410 426 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
411 427 {
412 428 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
413 429 if (axis && s) {
414 if (!m_chart->axes(Qt::Vertical).contains(axis))
415 m_chart->setAxisY(axis, s);
416 if (!s->attachedAxes().contains(axis))
417 s->attachAxis(axis);
430 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignLeft);
418 431 } else {
419 432 qWarning() << "Trying to set axisY to null.";
420 433 }
421 434 }
422 435
423 436 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
424 437 {
425 438 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
426 439 if (axis && s) {
427 if (!m_chart->axes(Qt::Vertical).contains(axis)) {
428 QList<QAbstractAxis *> oldAxes = m_chart->axes((Qt::Vertical), s);
429 foreach (QAbstractAxis* a, oldAxes) {
430 m_chart->removeAxis(a);
431 delete a;
432 }
433 m_chart->addAxis(axis, Qt::AlignRight);
434 }
435 if (!s->attachedAxes().contains(axis))
436 s->attachAxis(axis);
440 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignRight);
437 441 } else {
438 442 qWarning() << "Trying to set axisYRight to null.";
439 443 }
440 444 }
441 445
442 446 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
443 447 {
444 448 if (newGeometry.isValid()) {
445 449 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
446 450 m_chart->resize(newGeometry.width(), newGeometry.height());
447 451 }
448 452 }
449 453 QQuickItem::geometryChanged(newGeometry, oldGeometry);
450 454 }
451 455
452 456 void DeclarativeChart::sceneChanged(QList<QRectF> region)
453 457 {
454 458 Q_UNUSED(region);
455 459
456 460 if (m_guiThreadId == m_paintThreadId) {
457 461 // Rendering in gui thread, no need for shenannigans, just update
458 462 update();
459 463 } else {
460 464 // Multi-threaded rendering, need to ensure scene is actually rendered in gui thread
461 465 if (!m_updatePending) {
462 466 m_updatePending = true;
463 467 // Do async render to avoid some unnecessary renders.
464 468 QTimer::singleShot(0, this, SLOT(renderScene()));
465 469 }
466 470 }
467 471 }
468 472
469 473 void DeclarativeChart::renderScene()
470 474 {
471 475 m_updatePending = false;
472 476 m_sceneImageLock.lock();
473 477 delete m_currentSceneImage;
474 478 m_currentSceneImage = new QImage(m_chart->size().toSize(), QImage::Format_ARGB32);
475 479 m_currentSceneImage->fill(Qt::transparent);
476 480 QPainter painter(m_currentSceneImage);
477 481 if (antialiasing())
478 482 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
479 483 QRect renderRect(QPoint(0, 0), m_chart->size().toSize());
480 484 m_scene->render(&painter, renderRect, renderRect);
481 485 m_sceneImageLock.unlock();
482 486
483 487 update();
484 488 }
485 489
486 490 void DeclarativeChart::paint(QPainter *painter)
487 491 {
488 492 if (!m_paintThreadId) {
489 493 m_paintThreadId = QThread::currentThreadId();
490 494 if (m_guiThreadId == m_paintThreadId) {
491 495 // No need for scene image in single threaded rendering, so delete
492 496 // the one that got made by default before the rendering type was
493 497 // detected.
494 498 delete m_currentSceneImage;
495 499 m_currentSceneImage = 0;
496 500 }
497 501 }
498 502
499 503 if (m_guiThreadId == m_paintThreadId) {
500 504 QRectF renderRect(QPointF(0, 0), m_chart->size());
501 505 m_scene->render(painter, renderRect, renderRect);
502 506 } else {
503 507 m_sceneImageLock.lock();
504 508 if (m_currentSceneImage) {
505 509 QRect imageRect(QPoint(0, 0), m_currentSceneImage->size());
506 510 QRect itemRect(QPoint(0, 0), QSize(width(), height()));
507 511 painter->drawImage(itemRect, *m_currentSceneImage, imageRect);
508 512 }
509 513 m_sceneImageLock.unlock();
510 514 }
511 515 }
512 516
513 517 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
514 518 {
515 519 m_mousePressScenePoint = event->pos();
516 520 m_mousePressScreenPoint = event->globalPos();
517 521 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
518 522 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
519 523 m_mousePressButton = event->button();
520 524 m_mousePressButtons = event->buttons();
521 525
522 526 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
523 527 mouseEvent.setWidget(0);
524 528 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
525 529 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
526 530 mouseEvent.setScenePos(m_mousePressScenePoint);
527 531 mouseEvent.setScreenPos(m_mousePressScreenPoint);
528 532 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
529 533 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
530 534 mouseEvent.setButtons(m_mousePressButtons);
531 535 mouseEvent.setButton(m_mousePressButton);
532 536 mouseEvent.setModifiers(event->modifiers());
533 537 mouseEvent.setAccepted(false);
534 538
535 539 QApplication::sendEvent(m_scene, &mouseEvent);
536 540 }
537 541
538 542 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
539 543 {
540 544 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
541 545 mouseEvent.setWidget(0);
542 546 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
543 547 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
544 548 mouseEvent.setScenePos(event->pos());
545 549 mouseEvent.setScreenPos(event->globalPos());
546 550 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
547 551 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
548 552 mouseEvent.setButtons(event->buttons());
549 553 mouseEvent.setButton(event->button());
550 554 mouseEvent.setModifiers(event->modifiers());
551 555 mouseEvent.setAccepted(false);
552 556
553 557 QApplication::sendEvent(m_scene, &mouseEvent);
554 558
555 559 m_mousePressButtons = event->buttons();
556 560 m_mousePressButton = Qt::NoButton;
557 561 }
558 562
559 563 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
560 564 {
561 565 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
562 566 // QGraphicsScene generates hover events from mouse move events, so we don't need
563 567 // to pass hover events there.
564 568 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
565 569 mouseEvent.setWidget(0);
566 570 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
567 571 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
568 572 mouseEvent.setScenePos(event->pos());
569 573 // Hover events do not have global pos in them, and the screen position doesn't seem to
570 574 // matter anyway in this use case, so just pass event pos instead of trying to
571 575 // calculate the real screen position.
572 576 mouseEvent.setScreenPos(event->pos());
573 577 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
574 578 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
575 579 mouseEvent.setButtons(m_mousePressButtons);
576 580 mouseEvent.setButton(m_mousePressButton);
577 581 mouseEvent.setModifiers(event->modifiers());
578 582 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
579 583 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
580 584 mouseEvent.setAccepted(false);
581 585
582 586 QApplication::sendEvent(m_scene, &mouseEvent);
583 587 }
584 588
585 589 void DeclarativeChart::handleAntialiasingChanged(bool enable)
586 590 {
587 591 setAntialiasing(enable);
588 592 }
589 593
590 594 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
591 595 {
592 596 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
593 597 if (chartTheme != m_chart->theme())
594 598 m_chart->setTheme(chartTheme);
595 599 }
596 600
597 601 DeclarativeChart::Theme DeclarativeChart::theme()
598 602 {
599 603 return (DeclarativeChart::Theme) m_chart->theme();
600 604 }
601 605
602 606 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
603 607 {
604 608 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
605 609 if (animationOptions != m_chart->animationOptions())
606 610 m_chart->setAnimationOptions(animationOptions);
607 611 }
608 612
609 613 DeclarativeChart::Animation DeclarativeChart::animationOptions()
610 614 {
611 615 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
612 616 return DeclarativeChart::AllAnimations;
613 617 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
614 618 return DeclarativeChart::GridAxisAnimations;
615 619 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
616 620 return DeclarativeChart::SeriesAnimations;
617 621 else
618 622 return DeclarativeChart::NoAnimation;
619 623 }
620 624
621 625 void DeclarativeChart::setTitle(QString title)
622 626 {
623 627 if (title != m_chart->title())
624 628 m_chart->setTitle(title);
625 629 }
626 630 QString DeclarativeChart::title()
627 631 {
628 632 return m_chart->title();
629 633 }
630 634
631 635 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
632 636 {
633 637 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
634 638 if (axes.count())
635 639 return axes[0];
636 640 return 0;
637 641 }
638 642
639 643 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
640 644 {
641 645 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
642 646 if (axes.count())
643 647 return axes[0];
644 648 return 0;
645 649 }
646 650
647 651 QLegend *DeclarativeChart::legend()
648 652 {
649 653 return m_chart->legend();
650 654 }
651 655
652 656 void DeclarativeChart::setTitleColor(QColor color)
653 657 {
654 658 QBrush b = m_chart->titleBrush();
655 659 if (color != b.color()) {
656 660 b.setColor(color);
657 661 m_chart->setTitleBrush(b);
658 662 emit titleColorChanged(color);
659 663 }
660 664 }
661 665
662 666 QFont DeclarativeChart::titleFont() const
663 667 {
664 668 return m_chart->titleFont();
665 669 }
666 670
667 671 void DeclarativeChart::setTitleFont(const QFont &font)
668 672 {
669 673 m_chart->setTitleFont(font);
670 674 }
671 675
672 676 QColor DeclarativeChart::titleColor()
673 677 {
674 678 return m_chart->titleBrush().color();
675 679 }
676 680
677 681 void DeclarativeChart::setBackgroundColor(QColor color)
678 682 {
679 683 QBrush b = m_chart->backgroundBrush();
680 684 if (b.style() != Qt::SolidPattern || color != b.color()) {
681 685 b.setStyle(Qt::SolidPattern);
682 686 b.setColor(color);
683 687 m_chart->setBackgroundBrush(b);
684 688 emit backgroundColorChanged();
685 689 }
686 690 }
687 691
688 692 QColor DeclarativeChart::backgroundColor()
689 693 {
690 694 return m_chart->backgroundBrush().color();
691 695 }
692 696
693 697 void QtCharts::DeclarativeChart::setPlotAreaColor(QColor color)
694 698 {
695 699 QBrush b = m_chart->plotAreaBackgroundBrush();
696 700 if (b.style() != Qt::SolidPattern || color != b.color()) {
697 701 b.setStyle(Qt::SolidPattern);
698 702 b.setColor(color);
699 703 m_chart->setPlotAreaBackgroundBrush(b);
700 704 m_chart->setPlotAreaBackgroundVisible(true);
701 705 emit plotAreaColorChanged();
702 706 }
703 707 }
704 708
705 709 QColor QtCharts::DeclarativeChart::plotAreaColor()
706 710 {
707 711 return m_chart->plotAreaBackgroundBrush().color();
708 712 }
709 713
710 714 void DeclarativeChart::setLocalizeNumbers(bool localize)
711 715 {
712 716 if (m_chart->localizeNumbers() != localize) {
713 717 m_chart->setLocalizeNumbers(localize);
714 718 emit localizeNumbersChanged();
715 719 }
716 720 }
717 721
718 722 bool DeclarativeChart::localizeNumbers() const
719 723 {
720 724 return m_chart->localizeNumbers();
721 725 }
722 726
723 727 void QtCharts::DeclarativeChart::setLocale(const QLocale &locale)
724 728 {
725 729 if (m_chart->locale() != locale) {
726 730 m_chart->setLocale(locale);
727 731 emit localeChanged();
728 732 }
729 733 }
730 734
731 735 QLocale QtCharts::DeclarativeChart::locale() const
732 736 {
733 737 return m_chart->locale();
734 738 }
735 739
736 740 int DeclarativeChart::count()
737 741 {
738 742 return m_chart->series().count();
739 743 }
740 744
741 745 void DeclarativeChart::setDropShadowEnabled(bool enabled)
742 746 {
743 747 if (enabled != m_chart->isDropShadowEnabled()) {
744 748 m_chart->setDropShadowEnabled(enabled);
745 749 dropShadowEnabledChanged(enabled);
746 750 }
747 751 }
748 752
749 753 bool DeclarativeChart::dropShadowEnabled()
750 754 {
751 755 return m_chart->isDropShadowEnabled();
752 756 }
753 757
754 758 qreal DeclarativeChart::backgroundRoundness() const
755 759 {
756 760 return m_chart->backgroundRoundness();
757 761 }
758 762
759 763 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
760 764 {
761 765 if (m_chart->backgroundRoundness() != diameter) {
762 766 m_chart->setBackgroundRoundness(diameter);
763 767 emit backgroundRoundnessChanged(diameter);
764 768 }
765 769 }
766 770
767 771 qreal DeclarativeChart::topMargin()
768 772 {
769 773 qWarning() << "ChartView.topMargin is deprecated. Use margins instead.";
770 774 return m_chart->margins().top();
771 775 }
772 776
773 777 qreal DeclarativeChart::bottomMargin()
774 778 {
775 779 qWarning() << "ChartView.bottomMargin is deprecated. Use margins instead.";
776 780 return m_chart->margins().bottom();
777 781 }
778 782
779 783 qreal DeclarativeChart::leftMargin()
780 784 {
781 785 qWarning() << "ChartView.leftMargin is deprecated. Use margins instead.";
782 786 return m_chart->margins().left();
783 787 }
784 788
785 789 qreal DeclarativeChart::rightMargin()
786 790 {
787 791 qWarning() << "ChartView.rightMargin is deprecated. Use margins instead.";
788 792 return m_chart->margins().right();
789 793 }
790 794
791 795 void DeclarativeChart::zoom(qreal factor)
792 796 {
793 797 m_chart->zoom(factor);
794 798 }
795 799
796 800 void DeclarativeChart::scrollLeft(qreal pixels)
797 801 {
798 802 m_chart->scroll(-pixels, 0);
799 803 }
800 804
801 805 void DeclarativeChart::scrollRight(qreal pixels)
802 806 {
803 807 m_chart->scroll(pixels, 0);
804 808 }
805 809
806 810 void DeclarativeChart::scrollUp(qreal pixels)
807 811 {
808 812 m_chart->scroll(0, pixels);
809 813 }
810 814
811 815 void DeclarativeChart::scrollDown(qreal pixels)
812 816 {
813 817 m_chart->scroll(0, -pixels);
814 818 }
815 819
816 820 QQmlListProperty<QAbstractAxis> DeclarativeChart::axes()
817 821 {
818 822 return QQmlListProperty<QAbstractAxis>(this, 0,
819 823 &DeclarativeChart::axesAppendFunc,
820 824 &DeclarativeChart::axesCountFunc,
821 825 &DeclarativeChart::axesAtFunc,
822 826 &DeclarativeChart::axesClearFunc);
823 827 }
824 828
825 829 void DeclarativeChart::axesAppendFunc(QQmlListProperty<QAbstractAxis> *list, QAbstractAxis *element)
826 830 {
827 831 // Empty implementation
828 832 Q_UNUSED(list);
829 833 Q_UNUSED(element);
830 834 }
831 835
832 836 int DeclarativeChart::axesCountFunc(QQmlListProperty<QAbstractAxis> *list)
833 837 {
834 838 if (qobject_cast<DeclarativeChart *>(list->object)) {
835 839 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
836 840 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
837 841 }
838 842 return 0;
839 843 }
840 844
841 845 QAbstractAxis *DeclarativeChart::axesAtFunc(QQmlListProperty<QAbstractAxis> *list, int index)
842 846 {
843 847 if (qobject_cast<DeclarativeChart *>(list->object)) {
844 848 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
845 849 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
846 850 return axes.at(index);
847 851 }
848 852 return 0;
849 853 }
850 854
851 855 void DeclarativeChart::axesClearFunc(QQmlListProperty<QAbstractAxis> *list)
852 856 {
853 857 // Empty implementation
854 858 Q_UNUSED(list);
855 859 }
856 860
857 861
858 862 QAbstractSeries *DeclarativeChart::series(int index)
859 863 {
860 864 if (index < m_chart->series().count()) {
861 865 return m_chart->series().at(index);
862 866 }
863 867 return 0;
864 868 }
865 869
866 870 QAbstractSeries *DeclarativeChart::series(QString seriesName)
867 871 {
868 872 foreach (QAbstractSeries *series, m_chart->series()) {
869 873 if (series->name() == seriesName)
870 874 return series;
871 875 }
872 876 return 0;
873 877 }
874 878
875 879 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
876 880 {
877 881 QAbstractSeries *series = 0;
878 882
879 883 switch (type) {
880 884 case DeclarativeChart::SeriesTypeLine:
881 885 series = new DeclarativeLineSeries();
882 886 break;
883 887 case DeclarativeChart::SeriesTypeArea: {
884 888 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
885 889 area->setUpperSeries(new DeclarativeLineSeries());
886 890 series = area;
887 891 break;
888 892 }
889 893 case DeclarativeChart::SeriesTypeStackedBar:
890 894 series = new DeclarativeStackedBarSeries();
891 895 break;
892 896 case DeclarativeChart::SeriesTypePercentBar:
893 897 series = new DeclarativePercentBarSeries();
894 898 break;
895 899 case DeclarativeChart::SeriesTypeBar:
896 900 series = new DeclarativeBarSeries();
897 901 break;
898 902 case DeclarativeChart::SeriesTypeHorizontalBar:
899 903 series = new DeclarativeHorizontalBarSeries();
900 904 break;
901 905 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
902 906 series = new DeclarativeHorizontalPercentBarSeries();
903 907 break;
904 908 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
905 909 series = new DeclarativeHorizontalStackedBarSeries();
906 910 break;
907 911 case DeclarativeChart::SeriesTypeBoxPlot:
908 912 series = new DeclarativeBoxPlotSeries();
909 913 break;
910 914 case DeclarativeChart::SeriesTypePie:
911 915 series = new DeclarativePieSeries();
912 916 break;
913 917 case DeclarativeChart::SeriesTypeScatter:
914 918 series = new DeclarativeScatterSeries();
915 919 break;
916 920 case DeclarativeChart::SeriesTypeSpline:
917 921 series = new DeclarativeSplineSeries();
918 922 break;
919 923 default:
920 924 qWarning() << "Illegal series type";
921 925 }
922 926
923 927 if (series) {
924 928 // Connect to axis changed signals (unless this is a pie series)
925 929 if (!qobject_cast<DeclarativePieSeries *>(series)) {
926 930 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
927 931 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
928 932 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
929 933 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
930 934 }
931 935
932 936 series->setName(name);
933 937 m_chart->addSeries(series);
934 938
939 if (!axisX || !axisY)
940 initializeAxes(series);
941
935 942 if (axisX)
936 943 setAxisX(axisX, series);
937 944 if (axisY)
938 945 setAxisY(axisY, series);
939
940 if (series->attachedAxes().count() < 2)
941 initializeAxes(series);
942 946 }
943 947
944 948 return series;
945 949 }
946 950
947 951 void DeclarativeChart::removeSeries(QAbstractSeries *series)
948 952 {
949 953 if (series)
950 954 m_chart->removeSeries(series);
951 955 else
952 956 qWarning("removeSeries: cannot remove null");
953 957 }
954 958
955 959 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
956 960 {
957 if (axis)
958 m_chart->setAxisX(axis, series);
961 if (axis && series)
962 seriesAxisAttachHelper(series, axis, Qt::Horizontal, Qt::AlignBottom);
959 963 }
960 964
961 965 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
962 966 {
963 if (axis)
964 m_chart->setAxisY(axis, series);
967 if (axis && series)
968 seriesAxisAttachHelper(series, axis, Qt::Vertical, Qt::AlignLeft);
965 969 }
966 970
967 971 void DeclarativeChart::createDefaultAxes()
968 972 {
969 973 qWarning() << "ChartView.createDefaultAxes() is deprecated. Axes are created automatically.";
970 974 }
971 975
972 976 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
973 977 {
974 978 if (!series) {
975 979 qWarning() << "No axis type defined for null series";
976 980 return 0;
977 981 }
978 982
979 983 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
980 984 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
981 985 return existingAxis;
982 986 }
983 987
984 988 switch (series->d_ptr->defaultAxisType(orientation)) {
985 989 case QAbstractAxis::AxisTypeValue:
986 990 return new QValueAxis(this);
987 991 case QAbstractAxis::AxisTypeBarCategory:
988 992 return new QBarCategoryAxis(this);
989 993 case QAbstractAxis::AxisTypeCategory:
990 994 return new QCategoryAxis(this);
991 995 #ifndef QT_ON_ARM
992 996 case QAbstractAxis::AxisTypeDateTime:
993 997 return new QDateTimeAxis(this);
994 998 #endif
995 999 case QAbstractAxis::AxisTypeLogValue:
996 1000 return new QLogValueAxis(this);
997 1001 default:
998 1002 // assume AxisTypeNoAxis
999 1003 return 0;
1000 1004 }
1001 1005 }
1002 1006
1003 1007 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1004 1008 {
1005 1009 if (qobject_cast<DeclarativeLineSeries *>(series))
1006 1010 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
1007 1011 else if (qobject_cast<DeclarativeScatterSeries *>(series))
1008 1012 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
1009 1013 else if (qobject_cast<DeclarativeSplineSeries *>(series))
1010 1014 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
1011 1015 else if (qobject_cast<DeclarativeAreaSeries *>(series))
1012 1016 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
1013 1017 else if (qobject_cast<DeclarativeBarSeries *>(series))
1014 1018 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
1015 1019 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
1016 1020 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
1017 1021 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
1018 1022 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1019 1023 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1020 1024 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1021 1025 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1022 1026 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1023 1027 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1024 1028 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1025 1029 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1026 1030 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1027 1031 // else: do nothing
1028 1032 }
1029 1033
1030 1034 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1031 1035 {
1032 1036 // Initialize axis X
1033 1037 if (axes->axisX())
1034 1038 axes->emitAxisXChanged();
1035 1039 else if (axes->axisXTop())
1036 1040 axes->emitAxisXTopChanged();
1037 1041 else
1038 1042 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1039 1043
1040 1044 // Initialize axis Y
1041 1045 if (axes->axisY())
1042 1046 axes->emitAxisYChanged();
1043 1047 else if (axes->axisYRight())
1044 1048 axes->emitAxisYRightChanged();
1045 1049 else
1046 1050 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1047 1051 }
1048 1052
1049 1053 #include "moc_declarativechart.cpp"
1050 1054
1051 1055 QT_CHARTS_END_NAMESPACE
@@ -1,231 +1,233
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2014 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef DECLARATIVECHART_H
22 22 #define DECLARATIVECHART_H
23 23
24 24 #include <QtCore/QtGlobal>
25 25 #include <QtQuick/QQuickItem>
26 26 #include <QtQuick/QQuickPaintedItem>
27 27 #include <QtWidgets/QGraphicsScene>
28 28 #include <QtCore/QMutex>
29 29
30 30 #include <QtCharts/QChart>
31 31 #include <QtCore/QLocale>
32 32
33 33 QT_CHARTS_BEGIN_NAMESPACE
34 34
35 35 class DeclarativeMargins;
36 36 class Domain;
37 37 class DeclarativeAxes;
38 38
39 39 class DeclarativeChart : public QQuickPaintedItem
40 40 {
41 41 Q_OBJECT
42 42 Q_PROPERTY(Theme theme READ theme WRITE setTheme)
43 43 Q_PROPERTY(Animation animationOptions READ animationOptions WRITE setAnimationOptions)
44 44 Q_PROPERTY(QString title READ title WRITE setTitle)
45 45 Q_PROPERTY(QFont titleFont READ titleFont WRITE setTitleFont)
46 46 Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor NOTIFY titleColorChanged)
47 47 Q_PROPERTY(QLegend *legend READ legend CONSTANT)
48 48 Q_PROPERTY(int count READ count)
49 49 Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
50 50 Q_PROPERTY(bool dropShadowEnabled READ dropShadowEnabled WRITE setDropShadowEnabled NOTIFY dropShadowEnabledChanged)
51 51 Q_PROPERTY(qreal backgroundRoundness READ backgroundRoundness WRITE setBackgroundRoundness NOTIFY backgroundRoundnessChanged REVISION 3)
52 52 Q_PROPERTY(qreal topMargin READ topMargin)
53 53 Q_PROPERTY(qreal bottomMargin READ bottomMargin)
54 54 Q_PROPERTY(qreal leftMargin READ leftMargin)
55 55 Q_PROPERTY(qreal rightMargin READ rightMargin)
56 56 Q_PROPERTY(DeclarativeMargins *minimumMargins READ minimumMargins NOTIFY minimumMarginsChanged REVISION 1)
57 57 Q_PROPERTY(DeclarativeMargins *margins READ margins NOTIFY marginsChanged REVISION 2)
58 58 Q_PROPERTY(QRectF plotArea READ plotArea NOTIFY plotAreaChanged REVISION 1)
59 59 Q_PROPERTY(QColor plotAreaColor READ plotAreaColor WRITE setPlotAreaColor NOTIFY plotAreaColorChanged REVISION 3)
60 60 Q_PROPERTY(QQmlListProperty<QAbstractAxis> axes READ axes REVISION 2)
61 61 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers NOTIFY localizeNumbersChanged REVISION 4)
62 62 Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged REVISION 4)
63 63 Q_ENUMS(Animation)
64 64 Q_ENUMS(Theme)
65 65 Q_ENUMS(SeriesType)
66 66
67 67 public:
68 68 // duplicating enums from QChart to make the QML api namings 1-to-1 with the C++ api
69 69 enum Theme {
70 70 ChartThemeLight = 0,
71 71 ChartThemeBlueCerulean,
72 72 ChartThemeDark,
73 73 ChartThemeBrownSand,
74 74 ChartThemeBlueNcs,
75 75 ChartThemeHighContrast,
76 76 ChartThemeBlueIcy,
77 77 ChartThemeQt
78 78 };
79 79
80 80 enum Animation {
81 81 NoAnimation = 0x0,
82 82 GridAxisAnimations = 0x1,
83 83 SeriesAnimations = 0x2,
84 84 AllAnimations = 0x3
85 85 };
86 86
87 87 enum SeriesType {
88 88 SeriesTypeLine,
89 89 SeriesTypeArea,
90 90 SeriesTypeBar,
91 91 SeriesTypeStackedBar,
92 92 SeriesTypePercentBar,
93 93 SeriesTypeBoxPlot,
94 94 SeriesTypePie,
95 95 SeriesTypeScatter,
96 96 SeriesTypeSpline,
97 97 SeriesTypeHorizontalBar,
98 98 SeriesTypeHorizontalStackedBar,
99 99 SeriesTypeHorizontalPercentBar
100 100 };
101 101
102 102 public:
103 103 DeclarativeChart(QQuickItem *parent = 0);
104 104 ~DeclarativeChart();
105 105
106 106 public: // From parent classes
107 107 void childEvent(QChildEvent *event);
108 108 void componentComplete();
109 109 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
110 110 void paint(QPainter *painter);
111 111 protected:
112 112 void mousePressEvent(QMouseEvent *event);
113 113 void mouseReleaseEvent(QMouseEvent *event);
114 114 void hoverMoveEvent(QHoverEvent *event);
115 115 private Q_SLOTS:
116 116 void handleAntialiasingChanged(bool enable);
117 117 void sceneChanged(QList<QRectF> region);
118 118 void renderScene();
119 119
120 120 public:
121 121 void setTheme(DeclarativeChart::Theme theme);
122 122 DeclarativeChart::Theme theme();
123 123 void setAnimationOptions(DeclarativeChart::Animation animations);
124 124 DeclarativeChart::Animation animationOptions();
125 125 void setTitle(QString title);
126 126 QString title();
127 127 QLegend *legend();
128 128 QFont titleFont() const;
129 129 void setTitleFont(const QFont &font);
130 130 void setTitleColor(QColor color);
131 131 QColor titleColor();
132 132 void setBackgroundColor(QColor color);
133 133 QColor backgroundColor();
134 134 void setPlotAreaColor(QColor color);
135 135 QColor plotAreaColor();
136 136 void setLocalizeNumbers(bool localize);
137 137 bool localizeNumbers() const;
138 138 void setLocale(const QLocale &locale);
139 139 QLocale locale() const;
140 140
141 141 int count();
142 142 void setDropShadowEnabled(bool enabled);
143 143 bool dropShadowEnabled();
144 144 qreal backgroundRoundness() const;
145 145 void setBackgroundRoundness(qreal diameter);
146 146
147 147 // Margins & plotArea
148 148 qreal topMargin();
149 149 qreal bottomMargin();
150 150 qreal leftMargin();
151 151 qreal rightMargin();
152 152 DeclarativeMargins *minimumMargins() { return m_margins; }
153 153 DeclarativeMargins *margins() { return m_margins; }
154 154 QRectF plotArea() { return m_chart->plotArea(); }
155 155
156 156 // Axis handling
157 157 QAbstractAxis *defaultAxis(Qt::Orientation orientation, QAbstractSeries *series);
158 158 void initializeAxes(QAbstractSeries *series);
159 159 void doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes);
160 160 QQmlListProperty<QAbstractAxis> axes();
161 161 static void axesAppendFunc(QQmlListProperty<QAbstractAxis> *list, QAbstractAxis *element);
162 162 static int axesCountFunc(QQmlListProperty<QAbstractAxis> *list);
163 163 static QAbstractAxis *axesAtFunc(QQmlListProperty<QAbstractAxis> *list, int index);
164 164 static void axesClearFunc(QQmlListProperty<QAbstractAxis> *list);
165 165
166 166 public:
167 167 Q_INVOKABLE QAbstractSeries *series(int index);
168 168 Q_INVOKABLE QAbstractSeries *series(QString seriesName);
169 169 Q_INVOKABLE QAbstractSeries *createSeries(int type, QString name = "", QAbstractAxis *axisX = 0, QAbstractAxis *axisY = 0);
170 170 Q_INVOKABLE void removeSeries(QAbstractSeries *series);
171 171 Q_INVOKABLE void removeAllSeries() { m_chart->removeAllSeries(); }
172 172 Q_INVOKABLE void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = 0);
173 173 Q_INVOKABLE void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = 0);
174 174 Q_INVOKABLE void createDefaultAxes();
175 175 Q_INVOKABLE QAbstractAxis *axisX(QAbstractSeries *series = 0);
176 176 Q_INVOKABLE QAbstractAxis *axisY(QAbstractSeries *series = 0);
177 177 Q_INVOKABLE void zoom(qreal factor);
178 178 Q_INVOKABLE void scrollLeft(qreal pixels);
179 179 Q_INVOKABLE void scrollRight(qreal pixels);
180 180 Q_INVOKABLE void scrollUp(qreal pixels);
181 181 Q_INVOKABLE void scrollDown(qreal pixels);
182 182
183 183 Q_SIGNALS:
184 184 void axisLabelsChanged();
185 185 void titleColorChanged(QColor color);
186 186 void backgroundColorChanged();
187 187 void dropShadowEnabledChanged(bool enabled);
188 188 void minimumMarginsChanged();
189 189 Q_REVISION(2) void marginsChanged();
190 190 void plotAreaChanged(QRectF plotArea);
191 191 void seriesAdded(QAbstractSeries *series);
192 192 void seriesRemoved(QAbstractSeries *series);
193 193 Q_REVISION(3) void plotAreaColorChanged();
194 194 Q_REVISION(3) void backgroundRoundnessChanged(qreal diameter);
195 195 Q_REVISION(4) void localizeNumbersChanged();
196 196 Q_REVISION(4) void localeChanged();
197 197
198 198 private Q_SLOTS:
199 199 void changeMinimumMargins(int top, int bottom, int left, int right);
200 200 void handleAxisXSet(QAbstractAxis *axis);
201 201 void handleAxisYSet(QAbstractAxis *axis);
202 202 void handleAxisXTopSet(QAbstractAxis *axis);
203 203 void handleAxisYRightSet(QAbstractAxis *axis);
204 204 void handleSeriesAdded(QAbstractSeries *series);
205 205
206 206 protected:
207 207 explicit DeclarativeChart(QChart::ChartType type, QQuickItem *parent);
208 208
209 209 private:
210 210 void initChart(QChart::ChartType type);
211 void seriesAxisAttachHelper(QAbstractSeries *series, QAbstractAxis *axis,
212 Qt::Orientations orientation, Qt::Alignment alignment);
211 213 // Extending QChart with DeclarativeChart is not possible because QObject does not support
212 214 // multi inheritance, so we now have a QChart as a member instead
213 215 QChart *m_chart;
214 216 QGraphicsScene *m_scene;
215 217 QPointF m_mousePressScenePoint;
216 218 QPoint m_mousePressScreenPoint;
217 219 QPointF m_lastMouseMoveScenePoint;
218 220 QPoint m_lastMouseMoveScreenPoint;
219 221 Qt::MouseButton m_mousePressButton;
220 222 Qt::MouseButtons m_mousePressButtons;
221 223 QMutex m_sceneImageLock;
222 224 QImage *m_currentSceneImage;
223 225 bool m_updatePending;
224 226 Qt::HANDLE m_paintThreadId;
225 227 Qt::HANDLE m_guiThreadId;
226 228 DeclarativeMargins *m_margins;
227 229 };
228 230
229 231 QT_CHARTS_END_NAMESPACE
230 232
231 233 #endif // DECLARATIVECHART_H
General Comments 0
You need to be logged in to leave comments. Login now