##// END OF EJS Templates
Misc fixes...
Miikka Heikkinen -
r2710:e26d82d56bc9
parent child
Show More
@@ -1,1054 +1,1080
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 <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 "qbarcategoryaxis.h"
31 31 #include "qvalueaxis.h"
32 32 #include "qlogvalueaxis.h"
33 33 #include "qcategoryaxis.h"
34 34 #include "qabstractseries_p.h"
35 35 #include "declarativemargins.h"
36 36 #include "chartdataset_p.h"
37 37 #include "declarativeaxes.h"
38 38 #include "qchart_p.h"
39 39 #include "qpolarchart.h"
40 40
41 41 #ifndef QT_ON_ARM
42 42 #include "qdatetimeaxis.h"
43 43 #endif
44 44
45 45 #ifdef CHARTS_FOR_QUICK2
46 46 #include <QGraphicsSceneMouseEvent>
47 47 #include <QGraphicsSceneHoverEvent>
48 48 #include <QApplication>
49 49 #include <QTimer>
50 50 #include <QThread>
51 51 #endif
52 52
53 53 QTCOMMERCIALCHART_BEGIN_NAMESPACE
54 54
55 55 #ifdef QDOC_QT5
56 56 /*!
57 57 \qmltype ChartView
58 58 \instantiates DeclarativeChart
59 59 \inqmlmodule QtCommercial.Chart
60 60
61 61 \include doc/src/chartview.qdocinc
62 62 */
63 63 #else
64 64 /*!
65 65 \qmlclass ChartView DeclarativeChart
66 66
67 67 \include ../doc/src/chartview.qdocinc
68 68 */
69 69 #endif
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 Defaults to \c{true}.
183 Defaults to \c{false}.
184
185 \sa locale
186 */
187
188 /*!
189 \qmlproperty locale ChartView::locale
190 \since QtCharts 2.0
191 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
192 This also determines the locale used to format DateTimeAxis labels regardless of
193 localizeNumbers property.
194 Defaults to application default locale at the time the chart is constructed.
195
196 \sa localizeNumbers
184 197 */
185 198
186 199 /*!
187 200 \qmlmethod AbstractSeries ChartView::series(int index)
188 201 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
189 202 the count property of the chart.
190 203 */
191 204
192 205 /*!
193 206 \qmlmethod AbstractSeries ChartView::series(string name)
194 207 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
195 208 */
196 209
197 210 /*!
198 211 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
199 212 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
200 213 optional axis \a axisY. For example:
201 214 \code
202 215 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
203 216 var myAxisX = chartView.axisX(lineSeries);
204 217 var myAxisY = chartView.axisY(lineSeries);
205 218 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
206 219 \endcode
207 220 */
208 221
209 222 /*!
210 223 \qmlmethod ChartView::removeSeries(AbstractSeries series)
211 224 Removes the \a series from the chart. The series object is also destroyed.
212 225 */
213 226
214 227 /*!
215 228 \qmlmethod ChartView::removeAllSeries()
216 229 Removes all series from the chart. All the series objects are also destroyed.
217 230 */
218 231
219 232 /*!
220 233 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
221 234 The x-axis of the series.
222 235 */
223 236
224 237 /*!
225 238 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
226 239 The y-axis of the series.
227 240 */
228 241
229 242 /*!
230 243 \qmlmethod ChartView::zoomY(real factor)
231 244 Zooms in by \a factor on the center of the chart.
232 245 */
233 246
234 247 /*!
235 248 \qmlmethod ChartView::scrollLeft(real pixels)
236 249 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
237 250 */
238 251
239 252 /*!
240 253 \qmlmethod ChartView::scrollRight(real pixels)
241 254 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
242 255 */
243 256
244 257 /*!
245 258 \qmlmethod ChartView::scrollUp(real pixels)
246 259 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
247 260 */
248 261
249 262 /*!
250 263 \qmlmethod ChartView::scrollDown(real pixels)
251 264 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
252 265 */
253 266
254 267 /*!
255 268 \qmlsignal ChartView::onPlotAreaChanged(rect plotArea)
256 269 The plot area of the chart has changed. This may happen for example, if you modify minimumMargins
257 270 or if you resize the chart, or if you modify font size related properties of the legend or chart
258 271 title.
259 272 */
260 273
261 274 /*!
262 275 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
263 276 The \a series has been added to the chart.
264 277 */
265 278
266 279 /*!
267 280 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
268 281 The \a series has been removed from the chart. Please note that \a series is no longer a valid
269 282 object after the signal handler has completed.
270 283 */
271 284
272 285 DeclarativeChart::DeclarativeChart(QDECLARATIVE_ITEM *parent)
273 286 : QDECLARATIVE_PAINTED_ITEM(parent)
274 287 {
275 288 initChart(QChart::ChartTypeCartesian);
276 289 }
277 290
278 291 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QDECLARATIVE_ITEM *parent)
279 292 : QDECLARATIVE_PAINTED_ITEM(parent)
280 293 {
281 294 initChart(type);
282 295 }
283 296
284 297 void DeclarativeChart::initChart(QChart::ChartType type)
285 298 {
286 299 #ifdef CHARTS_FOR_QUICK2
287 300 m_currentSceneImage = 0;
288 301 m_guiThreadId = QThread::currentThreadId();
289 302 m_paintThreadId = 0;
290 303 m_updatePending = false;
291 304
292 305 if (type == QChart::ChartTypePolar)
293 306 m_chart = new QPolarChart();
294 307 else
295 308 m_chart = new QChart();
296 309
297 310 m_scene = new QGraphicsScene(this);
298 311 m_scene->addItem(m_chart);
299 312
300 313 setAntialiasing(QQuickItem::antialiasing());
301 314 connect(m_scene, SIGNAL(changed(QList<QRectF>)), this, SLOT(sceneChanged(QList<QRectF>)));
302 315 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
303 316
304 317 setAcceptedMouseButtons(Qt::AllButtons);
305 318 setAcceptHoverEvents(true);
306 319 #else
307 320 if (type == QChart::ChartTypePolar)
308 321 m_chart = new QPolarChart(this);
309 322 else
310 323 m_chart = new QChart(this);
311 324
312 325 setFlag(QGraphicsItem::ItemHasNoContents, false);
313 326 #endif
314 327
315 328 m_margins = new DeclarativeMargins(this);
316 329 m_margins->setTop(m_chart->margins().top());
317 330 m_margins->setLeft(m_chart->margins().left());
318 331 m_margins->setRight(m_chart->margins().right());
319 332 m_margins->setBottom(m_chart->margins().bottom());
320 333 connect(m_margins, SIGNAL(topChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
321 334 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
322 335 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
323 336 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)), this, SLOT(changeMinimumMargins(int,int,int,int)));
324 337 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
325 338 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
326 339 }
327 340
328 341 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
329 342 {
330 343 emit seriesAdded(series);
331 344 }
332 345
333 346 void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
334 347 {
335 348 m_chart->setMargins(QMargins(left, top, right, bottom));
336 349 emit minimumMarginsChanged();
337 350 emit plotAreaChanged(m_chart->plotArea());
338 351 }
339 352
340 353 DeclarativeChart::~DeclarativeChart()
341 354 {
342 355 delete m_chart;
343 356 #ifdef CHARTS_FOR_QUICK2
344 357 m_sceneImageLock.lock();
345 358 delete m_currentSceneImage;
346 359 m_currentSceneImage = 0;
347 360 m_sceneImageLock.unlock();
348 361 #endif
349 362 }
350 363
351 364 void DeclarativeChart::childEvent(QChildEvent *event)
352 365 {
353 366 if (event->type() == QEvent::ChildAdded) {
354 367 if (qobject_cast<QAbstractSeries *>(event->child())) {
355 368 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
356 369 }
357 370 }
358 371 }
359 372
360 373 void DeclarativeChart::componentComplete()
361 374 {
362 375 foreach (QObject *child, children()) {
363 376 if (qobject_cast<QAbstractSeries *>(child)) {
364 377 // Add series to the chart
365 378 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
366 379 m_chart->addSeries(series);
367 380
368 381 // Connect to axis changed signals (unless this is a pie series)
369 382 if (!qobject_cast<DeclarativePieSeries *>(series)) {
370 383 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
371 384 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
372 385 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
373 386 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
374 387 }
375 388
376 389 initializeAxes(series);
377 390 }
378 391 }
379 392
380 393 QDECLARATIVE_ITEM::componentComplete();
381 394 }
382 395
383 396 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
384 397 {
385 398 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
386 399 if (axis && s) {
387 400 if (!m_chart->axes(Qt::Horizontal).contains(axis))
388 401 m_chart->setAxisX(axis, s);
389 402 if (!s->attachedAxes().contains(axis))
390 403 s->attachAxis(axis);
391 404 } else {
392 405 qWarning() << "Trying to set axisX to null.";
393 406 }
394 407 }
395 408
396 409 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
397 410 {
398 411 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
399 412 if (axis && s) {
400 413 if (!m_chart->axes(Qt::Horizontal).contains(axis)) {
401 414 QList<QAbstractAxis *> oldAxes = m_chart->axes(Qt::Horizontal, s);
402 415 foreach (QAbstractAxis* a, oldAxes) {
403 416 m_chart->removeAxis(a);
404 417 delete a;
405 418 }
406 419 m_chart->addAxis(axis, Qt::AlignTop);
407 420 }
408 421 if (!s->attachedAxes().contains(axis))
409 422 s->attachAxis(axis);
410 423 } else {
411 424 qWarning() << "Trying to set axisXTop to null.";
412 425 }
413 426 }
414 427
415 428 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
416 429 {
417 430 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
418 431 if (axis && s) {
419 432 if (!m_chart->axes(Qt::Vertical).contains(axis))
420 433 m_chart->setAxisY(axis, s);
421 434 if (!s->attachedAxes().contains(axis))
422 435 s->attachAxis(axis);
423 436 } else {
424 437 qWarning() << "Trying to set axisY to null.";
425 438 }
426 439 }
427 440
428 441 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
429 442 {
430 443 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
431 444 if (axis && s) {
432 445 if (!m_chart->axes(Qt::Vertical).contains(axis)) {
433 446 QList<QAbstractAxis *> oldAxes = m_chart->axes((Qt::Vertical), s);
434 447 foreach (QAbstractAxis* a, oldAxes) {
435 448 m_chart->removeAxis(a);
436 449 delete a;
437 450 }
438 451 m_chart->addAxis(axis, Qt::AlignRight);
439 452 }
440 453 if (!s->attachedAxes().contains(axis))
441 454 s->attachAxis(axis);
442 455 } else {
443 456 qWarning() << "Trying to set axisYRight to null.";
444 457 }
445 458 }
446 459
447 460 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
448 461 {
449 462 if (newGeometry.isValid()) {
450 463 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
451 464 m_chart->resize(newGeometry.width(), newGeometry.height());
452 465 }
453 466 }
454 467 QDECLARATIVE_ITEM::geometryChanged(newGeometry, oldGeometry);
455 468
456 469 // It would be better to trigger the plotAreaChanged signal from QChart::plotAreaChanged or
457 470 // similar. Since that kind of a signal is not clearly needed in the C++ API the work-around is
458 471 // to implement it here for the QML API purposes.
459 472 emit plotAreaChanged(m_chart->plotArea());
460 473 }
461 474
462 475 #ifdef CHARTS_FOR_QUICK2
463 476 void DeclarativeChart::sceneChanged(QList<QRectF> region)
464 477 {
465 478 Q_UNUSED(region);
466 479
467 480 if (m_guiThreadId == m_paintThreadId) {
468 481 // Rendering in gui thread, no need for shenannigans, just update
469 482 update();
470 483 } else {
471 484 // Multi-threaded rendering, need to ensure scene is actually rendered in gui thread
472 485 if (!m_updatePending) {
473 486 m_updatePending = true;
474 487 // Do async render to avoid some unnecessary renders.
475 488 QTimer::singleShot(0, this, SLOT(renderScene()));
476 489 }
477 490 }
478 491 }
479 492
480 493 void DeclarativeChart::renderScene()
481 494 {
482 495 m_updatePending = false;
483 496 m_sceneImageLock.lock();
484 497 delete m_currentSceneImage;
485 498 m_currentSceneImage = new QImage(m_chart->size().toSize(), QImage::Format_ARGB32);
486 499 m_currentSceneImage->fill(Qt::transparent);
487 500 QPainter painter(m_currentSceneImage);
488 501 if (antialiasing())
489 502 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
490 503 QRect renderRect(QPoint(0, 0), m_chart->size().toSize());
491 504 m_scene->render(&painter, renderRect, renderRect);
492 505 m_sceneImageLock.unlock();
493 506
494 507 update();
495 508 }
496 509
497 510 void DeclarativeChart::paint(QPainter *painter)
498 511 {
499 512 if (!m_paintThreadId) {
500 513 m_paintThreadId = QThread::currentThreadId();
501 514 if (m_guiThreadId == m_paintThreadId) {
502 515 // No need for scene image in single threaded rendering, so delete
503 516 // the one that got made by default before the rendering type was
504 517 // detected.
505 518 delete m_currentSceneImage;
506 519 m_currentSceneImage = 0;
507 520 }
508 521 }
509 522
510 523 if (m_guiThreadId == m_paintThreadId) {
511 524 QRectF renderRect(QPointF(0, 0), m_chart->size());
512 525 m_scene->render(painter, renderRect, renderRect);
513 526 } else {
514 527 m_sceneImageLock.lock();
515 528 if (m_currentSceneImage) {
516 529 QRect imageRect(QPoint(0, 0), m_currentSceneImage->size());
517 530 QRect itemRect(QPoint(0, 0), QSize(width(), height()));
518 531 painter->drawImage(itemRect, *m_currentSceneImage, imageRect);
519 532 }
520 533 m_sceneImageLock.unlock();
521 534 }
522 535 }
523 536
524 537 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
525 538 {
526 539 m_mousePressScenePoint = event->pos();
527 540 m_mousePressScreenPoint = event->globalPos();
528 541 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
529 542 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
530 543 m_mousePressButton = event->button();
531 544 m_mousePressButtons = event->buttons();
532 545
533 546 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
534 547 mouseEvent.setWidget(0);
535 548 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
536 549 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
537 550 mouseEvent.setScenePos(m_mousePressScenePoint);
538 551 mouseEvent.setScreenPos(m_mousePressScreenPoint);
539 552 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
540 553 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
541 554 mouseEvent.setButtons(m_mousePressButtons);
542 555 mouseEvent.setButton(m_mousePressButton);
543 556 mouseEvent.setModifiers(event->modifiers());
544 557 mouseEvent.setAccepted(false);
545 558
546 559 QApplication::sendEvent(m_scene, &mouseEvent);
547 560 }
548 561
549 562 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
550 563 {
551 564 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
552 565 mouseEvent.setWidget(0);
553 566 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
554 567 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
555 568 mouseEvent.setScenePos(event->pos());
556 569 mouseEvent.setScreenPos(event->globalPos());
557 570 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
558 571 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
559 572 mouseEvent.setButtons(event->buttons());
560 573 mouseEvent.setButton(event->button());
561 574 mouseEvent.setModifiers(event->modifiers());
562 575 mouseEvent.setAccepted(false);
563 576
564 577 QApplication::sendEvent(m_scene, &mouseEvent);
565 578
566 579 m_mousePressButtons = event->buttons();
567 580 m_mousePressButton = Qt::NoButton;
568 581 }
569 582
570 583 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
571 584 {
572 585 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
573 586 // QGraphicsScene generates hover events from mouse move events, so we don't need
574 587 // to pass hover events there.
575 588 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
576 589 mouseEvent.setWidget(0);
577 590 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
578 591 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
579 592 mouseEvent.setScenePos(event->pos());
580 593 // Hover events do not have global pos in them, and the screen position doesn't seem to
581 594 // matter anyway in this use case, so just pass event pos instead of trying to
582 595 // calculate the real screen position.
583 596 mouseEvent.setScreenPos(event->pos());
584 597 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
585 598 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
586 599 mouseEvent.setButtons(m_mousePressButtons);
587 600 mouseEvent.setButton(m_mousePressButton);
588 601 mouseEvent.setModifiers(event->modifiers());
589 602 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
590 603 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
591 604 mouseEvent.setAccepted(false);
592 605
593 606 QApplication::sendEvent(m_scene, &mouseEvent);
594 607 }
595 608
596 609 void DeclarativeChart::handleAntialiasingChanged(bool enable)
597 610 {
598 611 setAntialiasing(enable);
599 612 }
600 613 #endif
601 614
602 615 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
603 616 {
604 617 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
605 618 if (chartTheme != m_chart->theme())
606 619 m_chart->setTheme(chartTheme);
607 620 }
608 621
609 622 DeclarativeChart::Theme DeclarativeChart::theme()
610 623 {
611 624 return (DeclarativeChart::Theme) m_chart->theme();
612 625 }
613 626
614 627 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
615 628 {
616 629 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
617 630 if (animationOptions != m_chart->animationOptions())
618 631 m_chart->setAnimationOptions(animationOptions);
619 632 }
620 633
621 634 DeclarativeChart::Animation DeclarativeChart::animationOptions()
622 635 {
623 636 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
624 637 return DeclarativeChart::AllAnimations;
625 638 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
626 639 return DeclarativeChart::GridAxisAnimations;
627 640 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
628 641 return DeclarativeChart::SeriesAnimations;
629 642 else
630 643 return DeclarativeChart::NoAnimation;
631 644 }
632 645
633 646 void DeclarativeChart::setTitle(QString title)
634 647 {
635 648 if (title != m_chart->title())
636 649 m_chart->setTitle(title);
637 650 }
638 651 QString DeclarativeChart::title()
639 652 {
640 653 return m_chart->title();
641 654 }
642 655
643 656 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
644 657 {
645 658 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
646 659 if (axes.count())
647 660 return axes[0];
648 661 return 0;
649 662 }
650 663
651 664 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
652 665 {
653 666 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
654 667 if (axes.count())
655 668 return axes[0];
656 669 return 0;
657 670 }
658 671
659 672 QLegend *DeclarativeChart::legend()
660 673 {
661 674 return m_chart->legend();
662 675 }
663 676
664 677 void DeclarativeChart::setTitleColor(QColor color)
665 678 {
666 679 QBrush b = m_chart->titleBrush();
667 680 if (color != b.color()) {
668 681 b.setColor(color);
669 682 m_chart->setTitleBrush(b);
670 683 emit titleColorChanged(color);
671 684 }
672 685 }
673 686
674 687 QFont DeclarativeChart::titleFont() const
675 688 {
676 689 return m_chart->titleFont();
677 690 }
678 691
679 692 void DeclarativeChart::setTitleFont(const QFont &font)
680 693 {
681 694 m_chart->setTitleFont(font);
682 695 }
683 696
684 697 QColor DeclarativeChart::titleColor()
685 698 {
686 699 return m_chart->titleBrush().color();
687 700 }
688 701
689 702 void DeclarativeChart::setBackgroundColor(QColor color)
690 703 {
691 704 QBrush b = m_chart->backgroundBrush();
692 705 if (b.style() != Qt::SolidPattern || color != b.color()) {
693 706 b.setStyle(Qt::SolidPattern);
694 707 b.setColor(color);
695 708 m_chart->setBackgroundBrush(b);
696 709 emit backgroundColorChanged();
697 710 }
698 711 }
699 712
700 713 QColor DeclarativeChart::backgroundColor()
701 714 {
702 715 return m_chart->backgroundBrush().color();
703 716 }
704 717
705 718 void QtCommercialChart::DeclarativeChart::setPlotAreaColor(QColor color)
706 719 {
707 720 QBrush b = m_chart->plotAreaBackgroundBrush();
708 721 if (b.style() != Qt::SolidPattern || color != b.color()) {
709 722 b.setStyle(Qt::SolidPattern);
710 723 b.setColor(color);
711 724 m_chart->setPlotAreaBackgroundBrush(b);
712 725 m_chart->setPlotAreaBackgroundVisible(true);
713 726 emit plotAreaColorChanged();
714 727 }
715 728 }
716 729
717 730 QColor QtCommercialChart::DeclarativeChart::plotAreaColor()
718 731 {
719 732 return m_chart->plotAreaBackgroundBrush().color();
720 733 }
721 734
722 735 void DeclarativeChart::setLocalizeNumbers(bool localize)
723 736 {
724 737 if (m_chart->localizeNumbers() != localize) {
725 738 m_chart->setLocalizeNumbers(localize);
726 739 emit localizeNumbersChanged();
727 740 }
728 741 }
729 742
730 743 bool DeclarativeChart::localizeNumbers() const
731 744 {
732 745 return m_chart->localizeNumbers();
733 746 }
734 747
748 void QtCommercialChart::DeclarativeChart::setLocale(const QLocale &locale)
749 {
750 if (m_chart->locale() != locale) {
751 m_chart->setLocale(locale);
752 emit localeChanged();
753 }
754 }
755
756 QLocale QtCommercialChart::DeclarativeChart::locale() const
757 {
758 return m_chart->locale();
759 }
760
735 761 int DeclarativeChart::count()
736 762 {
737 763 return m_chart->series().count();
738 764 }
739 765
740 766 void DeclarativeChart::setDropShadowEnabled(bool enabled)
741 767 {
742 768 if (enabled != m_chart->isDropShadowEnabled()) {
743 769 m_chart->setDropShadowEnabled(enabled);
744 770 dropShadowEnabledChanged(enabled);
745 771 }
746 772 }
747 773
748 774 bool DeclarativeChart::dropShadowEnabled()
749 775 {
750 776 return m_chart->isDropShadowEnabled();
751 777 }
752 778
753 779 qreal DeclarativeChart::backgroundRoundness() const
754 780 {
755 781 return m_chart->backgroundRoundness();
756 782 }
757 783
758 784 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
759 785 {
760 786 if (m_chart->backgroundRoundness() != diameter) {
761 787 m_chart->setBackgroundRoundness(diameter);
762 788 emit backgroundRoundnessChanged(diameter);
763 789 }
764 790 }
765 791
766 792 qreal DeclarativeChart::topMargin()
767 793 {
768 794 qWarning() << "ChartView.topMargin is deprecated. Use margins instead.";
769 795 return m_chart->margins().top();
770 796 }
771 797
772 798 qreal DeclarativeChart::bottomMargin()
773 799 {
774 800 qWarning() << "ChartView.bottomMargin is deprecated. Use margins instead.";
775 801 return m_chart->margins().bottom();
776 802 }
777 803
778 804 qreal DeclarativeChart::leftMargin()
779 805 {
780 806 qWarning() << "ChartView.leftMargin is deprecated. Use margins instead.";
781 807 return m_chart->margins().left();
782 808 }
783 809
784 810 qreal DeclarativeChart::rightMargin()
785 811 {
786 812 qWarning() << "ChartView.rightMargin is deprecated. Use margins instead.";
787 813 return m_chart->margins().right();
788 814 }
789 815
790 816 void DeclarativeChart::zoom(qreal factor)
791 817 {
792 818 m_chart->zoom(factor);
793 819 }
794 820
795 821 void DeclarativeChart::scrollLeft(qreal pixels)
796 822 {
797 823 m_chart->scroll(-pixels, 0);
798 824 }
799 825
800 826 void DeclarativeChart::scrollRight(qreal pixels)
801 827 {
802 828 m_chart->scroll(pixels, 0);
803 829 }
804 830
805 831 void DeclarativeChart::scrollUp(qreal pixels)
806 832 {
807 833 m_chart->scroll(0, pixels);
808 834 }
809 835
810 836 void DeclarativeChart::scrollDown(qreal pixels)
811 837 {
812 838 m_chart->scroll(0, -pixels);
813 839 }
814 840
815 841 QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> DeclarativeChart::axes()
816 842 {
817 843 return QDECLARATIVE_LIST_PROPERTY<QAbstractAxis>(this, 0,
818 844 &DeclarativeChart::axesAppendFunc,
819 845 &DeclarativeChart::axesCountFunc,
820 846 #ifdef CHARTS_FOR_QUICK2
821 847 &DeclarativeChart::axesAtFunc,
822 848 &DeclarativeChart::axesClearFunc);
823 849 #else
824 850 &DeclarativeChart::axesAtFunc);
825 851 #endif
826 852 }
827 853
828 854 void DeclarativeChart::axesAppendFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, QAbstractAxis *element)
829 855 {
830 856 // Empty implementation
831 857 Q_UNUSED(list);
832 858 Q_UNUSED(element);
833 859 }
834 860
835 861 int DeclarativeChart::axesCountFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list)
836 862 {
837 863 if (qobject_cast<DeclarativeChart *>(list->object)) {
838 864 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
839 865 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
840 866 }
841 867 return 0;
842 868 }
843 869
844 870 QAbstractAxis *DeclarativeChart::axesAtFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, int index)
845 871 {
846 872 if (qobject_cast<DeclarativeChart *>(list->object)) {
847 873 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
848 874 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
849 875 return axes.at(index);
850 876 }
851 877 return 0;
852 878 }
853 879
854 880 void DeclarativeChart::axesClearFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list)
855 881 {
856 882 // Empty implementation
857 883 Q_UNUSED(list);
858 884 }
859 885
860 886
861 887 QAbstractSeries *DeclarativeChart::series(int index)
862 888 {
863 889 if (index < m_chart->series().count()) {
864 890 return m_chart->series().at(index);
865 891 }
866 892 return 0;
867 893 }
868 894
869 895 QAbstractSeries *DeclarativeChart::series(QString seriesName)
870 896 {
871 897 foreach (QAbstractSeries *series, m_chart->series()) {
872 898 if (series->name() == seriesName)
873 899 return series;
874 900 }
875 901 return 0;
876 902 }
877 903
878 904 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
879 905 {
880 906 QAbstractSeries *series = 0;
881 907
882 908 switch (type) {
883 909 case DeclarativeChart::SeriesTypeLine:
884 910 series = new DeclarativeLineSeries();
885 911 break;
886 912 case DeclarativeChart::SeriesTypeArea: {
887 913 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
888 914 area->setUpperSeries(new DeclarativeLineSeries());
889 915 series = area;
890 916 break;
891 917 }
892 918 case DeclarativeChart::SeriesTypeStackedBar:
893 919 series = new DeclarativeStackedBarSeries();
894 920 break;
895 921 case DeclarativeChart::SeriesTypePercentBar:
896 922 series = new DeclarativePercentBarSeries();
897 923 break;
898 924 case DeclarativeChart::SeriesTypeBar:
899 925 series = new DeclarativeBarSeries();
900 926 break;
901 927 case DeclarativeChart::SeriesTypeHorizontalBar:
902 928 series = new DeclarativeHorizontalBarSeries();
903 929 break;
904 930 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
905 931 series = new DeclarativeHorizontalPercentBarSeries();
906 932 break;
907 933 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
908 934 series = new DeclarativeHorizontalStackedBarSeries();
909 935 break;
910 936 case DeclarativeChart::SeriesTypeBoxPlot:
911 937 series = new DeclarativeBoxPlotSeries();
912 938 break;
913 939 case DeclarativeChart::SeriesTypePie:
914 940 series = new DeclarativePieSeries();
915 941 break;
916 942 case DeclarativeChart::SeriesTypeScatter:
917 943 series = new DeclarativeScatterSeries();
918 944 break;
919 945 case DeclarativeChart::SeriesTypeSpline:
920 946 series = new DeclarativeSplineSeries();
921 947 break;
922 948 default:
923 949 qWarning() << "Illegal series type";
924 950 }
925 951
926 952 if (series) {
927 953 // Connect to axis changed signals (unless this is a pie series)
928 954 if (!qobject_cast<DeclarativePieSeries *>(series)) {
929 955 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
930 956 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
931 957 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
932 958 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
933 959 }
934 960
935 961 series->setName(name);
936 962 m_chart->addSeries(series);
937 963
938 964 if (axisX)
939 965 setAxisX(axisX, series);
940 966 if (axisY)
941 967 setAxisY(axisY, series);
942 968
943 969 if (series->attachedAxes().count() < 2)
944 970 initializeAxes(series);
945 971 }
946 972
947 973 return series;
948 974 }
949 975
950 976 void DeclarativeChart::removeSeries(QAbstractSeries *series)
951 977 {
952 978 if (series)
953 979 m_chart->removeSeries(series);
954 980 else
955 981 qWarning("removeSeries: cannot remove null");
956 982 }
957 983
958 984 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
959 985 {
960 986 if (axis)
961 987 m_chart->setAxisX(axis, series);
962 988 }
963 989
964 990 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
965 991 {
966 992 if (axis)
967 993 m_chart->setAxisY(axis, series);
968 994 }
969 995
970 996 void DeclarativeChart::createDefaultAxes()
971 997 {
972 998 qWarning() << "ChartView.createDefaultAxes() is deprecated. Axes are created automatically.";
973 999 }
974 1000
975 1001 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
976 1002 {
977 1003 if (!series) {
978 1004 qWarning() << "No axis type defined for null series";
979 1005 return 0;
980 1006 }
981 1007
982 1008 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
983 1009 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
984 1010 return existingAxis;
985 1011 }
986 1012
987 1013 switch (series->d_ptr->defaultAxisType(orientation)) {
988 1014 case QAbstractAxis::AxisTypeValue:
989 1015 return new QValueAxis(this);
990 1016 case QAbstractAxis::AxisTypeBarCategory:
991 1017 return new QBarCategoryAxis(this);
992 1018 case QAbstractAxis::AxisTypeCategory:
993 1019 return new QCategoryAxis(this);
994 1020 #ifndef QT_ON_ARM
995 1021 case QAbstractAxis::AxisTypeDateTime:
996 1022 return new QDateTimeAxis(this);
997 1023 #endif
998 1024 case QAbstractAxis::AxisTypeLogValue:
999 1025 return new QLogValueAxis(this);
1000 1026 default:
1001 1027 // assume AxisTypeNoAxis
1002 1028 return 0;
1003 1029 }
1004 1030 }
1005 1031
1006 1032 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1007 1033 {
1008 1034 if (qobject_cast<DeclarativeLineSeries *>(series))
1009 1035 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
1010 1036 else if (qobject_cast<DeclarativeScatterSeries *>(series))
1011 1037 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
1012 1038 else if (qobject_cast<DeclarativeSplineSeries *>(series))
1013 1039 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
1014 1040 else if (qobject_cast<DeclarativeAreaSeries *>(series))
1015 1041 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
1016 1042 else if (qobject_cast<DeclarativeBarSeries *>(series))
1017 1043 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
1018 1044 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
1019 1045 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
1020 1046 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
1021 1047 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1022 1048 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1023 1049 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1024 1050 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1025 1051 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1026 1052 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1027 1053 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1028 1054 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1029 1055 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1030 1056 // else: do nothing
1031 1057 }
1032 1058
1033 1059 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1034 1060 {
1035 1061 // Initialize axis X
1036 1062 if (axes->axisX())
1037 1063 axes->emitAxisXChanged();
1038 1064 else if (axes->axisXTop())
1039 1065 axes->emitAxisXTopChanged();
1040 1066 else
1041 1067 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1042 1068
1043 1069 // Initialize axis Y
1044 1070 if (axes->axisY())
1045 1071 axes->emitAxisYChanged();
1046 1072 else if (axes->axisYRight())
1047 1073 axes->emitAxisYRightChanged();
1048 1074 else
1049 1075 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1050 1076 }
1051 1077
1052 1078 #include "moc_declarativechart.cpp"
1053 1079
1054 1080 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,240 +1,245
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 "shared_defines.h"
26 26
27 27 #ifdef CHARTS_FOR_QUICK2
28 28 #include <QtQuick/QQuickItem>
29 29 #include <QtQuick/QQuickPaintedItem>
30 30 #include <QtWidgets/QGraphicsScene>
31 31 #include <QtCore/QMutex>
32 32 #else
33 33 #include <QtDeclarative/QDeclarativeItem>
34 34 #endif
35 35
36 36 #include "qchart.h"
37 #include <QtCore/QLocale>
37 38
38 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 40
40 41 class DeclarativeMargins;
41 42 class Domain;
42 43 class DeclarativeAxes;
43 44
44 45 class DeclarativeChart : public QDECLARATIVE_PAINTED_ITEM
45 46 {
46 47 Q_OBJECT
47 48 Q_PROPERTY(Theme theme READ theme WRITE setTheme)
48 49 Q_PROPERTY(Animation animationOptions READ animationOptions WRITE setAnimationOptions)
49 50 Q_PROPERTY(QString title READ title WRITE setTitle)
50 51 Q_PROPERTY(QFont titleFont READ titleFont WRITE setTitleFont)
51 52 Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor NOTIFY titleColorChanged)
52 53 Q_PROPERTY(QLegend *legend READ legend CONSTANT)
53 54 Q_PROPERTY(int count READ count)
54 55 Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
55 56 Q_PROPERTY(bool dropShadowEnabled READ dropShadowEnabled WRITE setDropShadowEnabled NOTIFY dropShadowEnabledChanged)
56 57 Q_PROPERTY(qreal backgroundRoundness READ backgroundRoundness WRITE setBackgroundRoundness NOTIFY backgroundRoundnessChanged REVISION 3)
57 58 Q_PROPERTY(qreal topMargin READ topMargin)
58 59 Q_PROPERTY(qreal bottomMargin READ bottomMargin)
59 60 Q_PROPERTY(qreal leftMargin READ leftMargin)
60 61 Q_PROPERTY(qreal rightMargin READ rightMargin)
61 62 Q_PROPERTY(DeclarativeMargins *minimumMargins READ minimumMargins NOTIFY minimumMarginsChanged REVISION 1)
62 63 Q_PROPERTY(DeclarativeMargins *margins READ margins NOTIFY marginsChanged REVISION 2)
63 64 Q_PROPERTY(QRectF plotArea READ plotArea NOTIFY plotAreaChanged REVISION 1)
64 65 Q_PROPERTY(QColor plotAreaColor READ plotAreaColor WRITE setPlotAreaColor NOTIFY plotAreaColorChanged REVISION 3)
65 66 #ifdef CHARTS_FOR_QUICK2
66 67 Q_PROPERTY(QQmlListProperty<QAbstractAxis> axes READ axes REVISION 2)
67 68 #else
68 69 Q_PROPERTY(QDeclarativeListProperty<QAbstractAxis> axes READ axes REVISION 2)
69 70 #endif
70 71 Q_PROPERTY(bool localizeNumbers READ localizeNumbers WRITE setLocalizeNumbers NOTIFY localizeNumbersChanged REVISION 4)
72 Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged REVISION 4)
71 73 Q_ENUMS(Animation)
72 74 Q_ENUMS(Theme)
73 75 Q_ENUMS(SeriesType)
74 76
75 77 public:
76 78 // duplicating enums from QChart to make the QML api namings 1-to-1 with the C++ api
77 79 enum Theme {
78 80 ChartThemeLight = 0,
79 81 ChartThemeBlueCerulean,
80 82 ChartThemeDark,
81 83 ChartThemeBrownSand,
82 84 ChartThemeBlueNcs,
83 85 ChartThemeHighContrast,
84 86 ChartThemeBlueIcy,
85 87 ChartThemeQt
86 88 };
87 89
88 90 enum Animation {
89 91 NoAnimation = 0x0,
90 92 GridAxisAnimations = 0x1,
91 93 SeriesAnimations = 0x2,
92 94 AllAnimations = 0x3
93 95 };
94 96
95 97 enum SeriesType {
96 98 SeriesTypeLine,
97 99 SeriesTypeArea,
98 100 SeriesTypeBar,
99 101 SeriesTypeStackedBar,
100 102 SeriesTypePercentBar,
101 103 SeriesTypeBoxPlot,
102 104 SeriesTypePie,
103 105 SeriesTypeScatter,
104 106 SeriesTypeSpline,
105 107 SeriesTypeHorizontalBar,
106 108 SeriesTypeHorizontalStackedBar,
107 109 SeriesTypeHorizontalPercentBar
108 110 };
109 111
110 112 public:
111 113 DeclarativeChart(QDECLARATIVE_ITEM *parent = 0);
112 114 ~DeclarativeChart();
113 115
114 116 public: // From parent classes
115 117 void childEvent(QChildEvent *event);
116 118 void componentComplete();
117 119 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
118 120 #ifdef CHARTS_FOR_QUICK2
119 121 void paint(QPainter *painter);
120 122 protected:
121 123 void mousePressEvent(QMouseEvent *event);
122 124 void mouseReleaseEvent(QMouseEvent *event);
123 125 void hoverMoveEvent(QHoverEvent *event);
124 126 private Q_SLOTS:
125 127 void handleAntialiasingChanged(bool enable);
126 128 void sceneChanged(QList<QRectF> region);
127 129 void renderScene();
128 130 #endif
129 131
130 132 public:
131 133 void setTheme(DeclarativeChart::Theme theme);
132 134 DeclarativeChart::Theme theme();
133 135 void setAnimationOptions(DeclarativeChart::Animation animations);
134 136 DeclarativeChart::Animation animationOptions();
135 137 void setTitle(QString title);
136 138 QString title();
137 139 QLegend *legend();
138 140 QFont titleFont() const;
139 141 void setTitleFont(const QFont &font);
140 142 void setTitleColor(QColor color);
141 143 QColor titleColor();
142 144 void setBackgroundColor(QColor color);
143 145 QColor backgroundColor();
144 146 Q_REVISION(3) void setPlotAreaColor(QColor color);
145 147 Q_REVISION(3) QColor plotAreaColor();
146 148 Q_REVISION(4) void setLocalizeNumbers(bool localize);
147 149 Q_REVISION(4) bool localizeNumbers() const;
150 Q_REVISION(4) void setLocale(const QLocale &locale);
151 Q_REVISION(4) QLocale locale() const;
148 152
149 153 int count();
150 154 void setDropShadowEnabled(bool enabled);
151 155 bool dropShadowEnabled();
152 156 Q_REVISION(3) qreal backgroundRoundness() const;
153 157 Q_REVISION(3) void setBackgroundRoundness(qreal diameter);
154 158
155 159 // Margins & plotArea
156 160 qreal topMargin();
157 161 qreal bottomMargin();
158 162 qreal leftMargin();
159 163 qreal rightMargin();
160 164 DeclarativeMargins *minimumMargins() { return m_margins; }
161 165 Q_REVISION(2) DeclarativeMargins *margins() { return m_margins; }
162 166 QRectF plotArea() { return m_chart->plotArea(); }
163 167
164 168 // Axis handling
165 169 QAbstractAxis *defaultAxis(Qt::Orientation orientation, QAbstractSeries *series);
166 170 void initializeAxes(QAbstractSeries *series);
167 171 void doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes);
168 172 QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> axes();
169 173 static void axesAppendFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, QAbstractAxis *element);
170 174 static int axesCountFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list);
171 175 static QAbstractAxis *axesAtFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list, int index);
172 176 static void axesClearFunc(QDECLARATIVE_LIST_PROPERTY<QAbstractAxis> *list);
173 177
174 178 public:
175 179 Q_INVOKABLE QAbstractSeries *series(int index);
176 180 Q_INVOKABLE QAbstractSeries *series(QString seriesName);
177 181 Q_INVOKABLE QAbstractSeries *createSeries(int type, QString name = "", QAbstractAxis *axisX = 0, QAbstractAxis *axisY = 0);
178 182 Q_INVOKABLE void removeSeries(QAbstractSeries *series);
179 183 Q_INVOKABLE void removeAllSeries() { m_chart->removeAllSeries(); }
180 184 Q_INVOKABLE void setAxisX(QAbstractAxis *axis, QAbstractSeries *series = 0);
181 185 Q_INVOKABLE void setAxisY(QAbstractAxis *axis, QAbstractSeries *series = 0);
182 186 Q_INVOKABLE void createDefaultAxes();
183 187 Q_INVOKABLE QAbstractAxis *axisX(QAbstractSeries *series = 0);
184 188 Q_INVOKABLE QAbstractAxis *axisY(QAbstractSeries *series = 0);
185 189 Q_INVOKABLE void zoom(qreal factor);
186 190 Q_INVOKABLE void scrollLeft(qreal pixels);
187 191 Q_INVOKABLE void scrollRight(qreal pixels);
188 192 Q_INVOKABLE void scrollUp(qreal pixels);
189 193 Q_INVOKABLE void scrollDown(qreal pixels);
190 194
191 195 Q_SIGNALS:
192 196 void axisLabelsChanged();
193 197 void titleColorChanged(QColor color);
194 198 void backgroundColorChanged();
195 199 void dropShadowEnabledChanged(bool enabled);
196 200 void minimumMarginsChanged();
197 201 Q_REVISION(2) void marginsChanged();
198 202 void plotAreaChanged(QRectF plotArea);
199 203 void seriesAdded(QAbstractSeries *series);
200 204 void seriesRemoved(QAbstractSeries *series);
201 205 Q_REVISION(3) void plotAreaColorChanged();
202 206 Q_REVISION(3) void backgroundRoundnessChanged(qreal diameter);
203 207 Q_REVISION(4) void localizeNumbersChanged();
208 Q_REVISION(4) void localeChanged();
204 209
205 210 private Q_SLOTS:
206 211 void changeMinimumMargins(int top, int bottom, int left, int right);
207 212 void handleAxisXSet(QAbstractAxis *axis);
208 213 void handleAxisYSet(QAbstractAxis *axis);
209 214 void handleAxisXTopSet(QAbstractAxis *axis);
210 215 void handleAxisYRightSet(QAbstractAxis *axis);
211 216 void handleSeriesAdded(QAbstractSeries *series);
212 217
213 218 protected:
214 219 explicit DeclarativeChart(QChart::ChartType type, QDECLARATIVE_ITEM *parent);
215 220
216 221 private:
217 222 void initChart(QChart::ChartType type);
218 223 // Extending QChart with DeclarativeChart is not possible because QObject does not support
219 224 // multi inheritance, so we now have a QChart as a member instead
220 225 QChart *m_chart;
221 226 #ifdef CHARTS_FOR_QUICK2
222 227 QGraphicsScene *m_scene;
223 228 QPointF m_mousePressScenePoint;
224 229 QPoint m_mousePressScreenPoint;
225 230 QPointF m_lastMouseMoveScenePoint;
226 231 QPoint m_lastMouseMoveScreenPoint;
227 232 Qt::MouseButton m_mousePressButton;
228 233 Qt::MouseButtons m_mousePressButtons;
229 234 QMutex m_sceneImageLock;
230 235 QImage *m_currentSceneImage;
231 236 bool m_updatePending;
232 237 Qt::HANDLE m_paintThreadId;
233 238 Qt::HANDLE m_guiThreadId;
234 239 #endif
235 240 DeclarativeMargins *m_margins;
236 241 };
237 242
238 243 QTCOMMERCIALCHART_END_NAMESPACE
239 244
240 245 #endif // DECLARATIVECHART_H
@@ -1,273 +1,332
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 "qchart.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qvalueaxis.h"
24 24 #include "qlogvalueaxis.h"
25 25 #include "declarativecategoryaxis.h"
26 26 #include "qbarcategoryaxis.h"
27 27 #include "declarativechart.h"
28 28 #include "declarativepolarchart.h"
29 29 #include "declarativexypoint.h"
30 30 #include "declarativelineseries.h"
31 31 #include "declarativesplineseries.h"
32 32 #include "declarativeareaseries.h"
33 33 #include "declarativescatterseries.h"
34 34 #include "declarativebarseries.h"
35 35 #include "declarativeboxplotseries.h"
36 36 #include "declarativepieseries.h"
37 37 #include "declarativeaxes.h"
38 38 #include "qvxymodelmapper.h"
39 39 #include "qhxymodelmapper.h"
40 40 #include "qhpiemodelmapper.h"
41 41 #include "qvpiemodelmapper.h"
42 42 #include "qhbarmodelmapper.h"
43 43 #include "qvbarmodelmapper.h"
44 44 #include "declarativemargins.h"
45 45 #include "qarealegendmarker.h"
46 46 #include "qbarlegendmarker.h"
47 47 #include "qpielegendmarker.h"
48 48 #include "qxylegendmarker.h"
49 49 #include "qboxplotmodelmapper.h"
50 50 #include "qvboxplotmodelmapper.h"
51 51 #ifndef QT_ON_ARM
52 52 #include "qdatetimeaxis.h"
53 53 #endif
54 54 #include "shared_defines.h"
55 55 #include <QAbstractItemModel>
56 56 #ifdef CHARTS_FOR_QUICK2
57 57 #include <QtQml/QQmlExtensionPlugin>
58 58 #else
59 59 #include <QtDeclarative/qdeclarativeextensionplugin.h>
60 60 #include <QtDeclarative/qdeclarative.h>
61 61 #endif
62 62
63 63 QTCOMMERCIALCHART_USE_NAMESPACE
64 64
65 65 Q_DECLARE_METATYPE(QList<QPieSlice *>)
66 66 Q_DECLARE_METATYPE(QList<QBarSet *>)
67 67 Q_DECLARE_METATYPE(QList<QAbstractAxis *>)
68 68
69 69 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
70 70
71 71 Q_DECLARE_METATYPE(DeclarativeChart *)
72 72 Q_DECLARE_METATYPE(DeclarativePolarChart *)
73 73 Q_DECLARE_METATYPE(DeclarativeMargins *)
74 74 Q_DECLARE_METATYPE(DeclarativeAreaSeries *)
75 75 Q_DECLARE_METATYPE(DeclarativeBarSeries *)
76 76 Q_DECLARE_METATYPE(DeclarativeBarSet *)
77 77 Q_DECLARE_METATYPE(DeclarativeBoxPlotSeries *)
78 78 Q_DECLARE_METATYPE(DeclarativeBoxSet *)
79 79 Q_DECLARE_METATYPE(DeclarativeLineSeries *)
80 80 Q_DECLARE_METATYPE(DeclarativePieSeries *)
81 81 Q_DECLARE_METATYPE(DeclarativePieSlice *)
82 82 Q_DECLARE_METATYPE(DeclarativeScatterSeries *)
83 83 Q_DECLARE_METATYPE(DeclarativeSplineSeries *)
84 84
85 85 Q_DECLARE_METATYPE(QAbstractAxis *)
86 86 Q_DECLARE_METATYPE(QValueAxis *)
87 87 Q_DECLARE_METATYPE(QBarCategoryAxis *)
88 88 Q_DECLARE_METATYPE(QCategoryAxis *)
89 89 Q_DECLARE_METATYPE(QDateTimeAxis *)
90 90 Q_DECLARE_METATYPE(QLogValueAxis *)
91 91
92 92 Q_DECLARE_METATYPE(QLegend *)
93 93 Q_DECLARE_METATYPE(QLegendMarker *)
94 94 Q_DECLARE_METATYPE(QAreaLegendMarker *)
95 95 Q_DECLARE_METATYPE(QBarLegendMarker *)
96 96 Q_DECLARE_METATYPE(QPieLegendMarker *)
97 97
98 98 Q_DECLARE_METATYPE(QHPieModelMapper *)
99 99 Q_DECLARE_METATYPE(QHXYModelMapper *)
100 100 Q_DECLARE_METATYPE(QPieModelMapper *)
101 101 Q_DECLARE_METATYPE(QHBarModelMapper *)
102 102 Q_DECLARE_METATYPE(QBarModelMapper *)
103 103 Q_DECLARE_METATYPE(QVBarModelMapper *)
104 104 Q_DECLARE_METATYPE(QVPieModelMapper *)
105 105 Q_DECLARE_METATYPE(QVXYModelMapper *)
106 106 Q_DECLARE_METATYPE(QXYLegendMarker *)
107 107 Q_DECLARE_METATYPE(QXYModelMapper *)
108 108 Q_DECLARE_METATYPE(QBoxPlotModelMapper *)
109 109 Q_DECLARE_METATYPE(QVBoxPlotModelMapper *)
110 110
111 111
112 112 Q_DECLARE_METATYPE(QAbstractSeries *)
113 113 Q_DECLARE_METATYPE(QXYSeries *)
114 114 Q_DECLARE_METATYPE(QAbstractBarSeries *)
115 115 Q_DECLARE_METATYPE(QBarSeries *)
116 116 Q_DECLARE_METATYPE(QBarSet *)
117 117 Q_DECLARE_METATYPE(QAreaSeries *)
118 118 Q_DECLARE_METATYPE(QHorizontalBarSeries *)
119 119 Q_DECLARE_METATYPE(QHorizontalPercentBarSeries *)
120 120 Q_DECLARE_METATYPE(QHorizontalStackedBarSeries *)
121 121 Q_DECLARE_METATYPE(QLineSeries *)
122 122 Q_DECLARE_METATYPE(QPercentBarSeries *)
123 123 Q_DECLARE_METATYPE(QPieSeries *)
124 124 Q_DECLARE_METATYPE(QPieSlice *)
125 125 Q_DECLARE_METATYPE(QScatterSeries *)
126 126 Q_DECLARE_METATYPE(QSplineSeries *)
127 127 Q_DECLARE_METATYPE(QStackedBarSeries *)
128 128
129 129 #endif
130 130
131 131 QTCOMMERCIALCHART_BEGIN_NAMESPACE
132 132
133 133 class ChartQmlPlugin : public QDECLARATIVE_EXTENSION_PLUGIN
134 134 {
135 135 Q_OBJECT
136 136
137 137 #ifdef CHARTS_FOR_QUICK2
138 138 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
139 139 #else
140 140 # if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
141 141 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDeclarativeExtensionInterface")
142 142 # endif
143 143 #endif
144 144
145 145 public:
146 146 virtual void registerTypes(const char *uri)
147 147 {
148 148 Q_ASSERT(QLatin1String(uri) == QLatin1String("QtCommercial.Chart"));
149 149
150 150 qRegisterMetaType<QList<QPieSlice *> >();
151 151 qRegisterMetaType<QList<QBarSet *> >();
152 152 qRegisterMetaType<QList<QAbstractAxis *> >();
153 153
154 154 // QtCommercial.Chart 1.0
155 155 qmlRegisterType<DeclarativeChart>(uri, 1, 0, "ChartView");
156 156 qmlRegisterType<DeclarativeXYPoint>(uri, 1, 0, "XYPoint");
157 157 qmlRegisterType<DeclarativeScatterSeries>(uri, 1, 0, "ScatterSeries");
158 158 qmlRegisterType<DeclarativeLineSeries>(uri, 1, 0, "LineSeries");
159 159 qmlRegisterType<DeclarativeSplineSeries>(uri, 1, 0, "SplineSeries");
160 160 qmlRegisterType<DeclarativeAreaSeries>(uri, 1, 0, "AreaSeries");
161 161 qmlRegisterType<DeclarativeBarSeries>(uri, 1, 0, "BarSeries");
162 162 qmlRegisterType<DeclarativeStackedBarSeries>(uri, 1, 0, "StackedBarSeries");
163 163 qmlRegisterType<DeclarativePercentBarSeries>(uri, 1, 0, "PercentBarSeries");
164 164 qmlRegisterType<DeclarativePieSeries>(uri, 1, 0, "PieSeries");
165 165 qmlRegisterType<QPieSlice>(uri, 1, 0, "PieSlice");
166 166 qmlRegisterType<DeclarativeBarSet>(uri, 1, 0, "BarSet");
167 167 qmlRegisterType<QHXYModelMapper>(uri, 1, 0, "HXYModelMapper");
168 168 qmlRegisterType<QVXYModelMapper>(uri, 1, 0, "VXYModelMapper");
169 169 qmlRegisterType<QHPieModelMapper>(uri, 1, 0, "HPieModelMapper");
170 170 qmlRegisterType<QVPieModelMapper>(uri, 1, 0, "VPieModelMapper");
171 171 qmlRegisterType<QHBarModelMapper>(uri, 1, 0, "HBarModelMapper");
172 172 qmlRegisterType<QVBarModelMapper>(uri, 1, 0, "VBarModelMapper");
173 173
174 174 qmlRegisterType<QValueAxis>(uri, 1, 0, "ValuesAxis");
175 175 qmlRegisterType<QBarCategoryAxis>(uri, 1, 0, "BarCategoriesAxis");
176 176 qmlRegisterUncreatableType<QLegend>(uri, 1, 0, "Legend",
177 177 QLatin1String("Trying to create uncreatable: Legend."));
178 178 qmlRegisterUncreatableType<QXYSeries>(uri, 1, 0, "XYSeries",
179 179 QLatin1String("Trying to create uncreatable: XYSeries."));
180 180 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
181 181 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
182 182 qmlRegisterUncreatableType<QXYModelMapper>(uri, 1, 0, "XYModelMapper",
183 183 QLatin1String("Trying to create uncreatable: XYModelMapper."));
184 184 qmlRegisterUncreatableType<QPieModelMapper>(uri, 1, 0, "PieModelMapper",
185 185 QLatin1String("Trying to create uncreatable: PieModelMapper."));
186 186 qmlRegisterUncreatableType<QBarModelMapper>(uri, 1, 0, "BarModelMapper",
187 187 QLatin1String("Trying to create uncreatable: BarModelMapper."));
188 188 qmlRegisterUncreatableType<QAbstractSeries>(uri, 1, 0, "AbstractSeries",
189 189 QLatin1String("Trying to create uncreatable: AbstractSeries."));
190 190 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 1, 0, "AbstractBarSeries",
191 191 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
192 192 qmlRegisterUncreatableType<QAbstractAxis>(uri, 1, 0, "AbstractAxis",
193 193 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
194 194 qmlRegisterUncreatableType<QBarSet>(uri, 1, 0, "BarSetBase",
195 195 QLatin1String("Trying to create uncreatable: BarsetBase."));
196 196 qmlRegisterUncreatableType<QPieSeries>(uri, 1, 0, "QPieSeries",
197 197 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
198 198 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 1, 0, "DeclarativeAxes",
199 199 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
200 200
201 201 // QtCommercial.Chart 1.1
202 202 qmlRegisterType<DeclarativeChart, 1>(uri, 1, 1, "ChartView");
203 203 qmlRegisterType<DeclarativeScatterSeries, 1>(uri, 1, 1, "ScatterSeries");
204 204 qmlRegisterType<DeclarativeLineSeries, 1>(uri, 1, 1, "LineSeries");
205 205 qmlRegisterType<DeclarativeSplineSeries, 1>(uri, 1, 1, "SplineSeries");
206 206 qmlRegisterType<DeclarativeAreaSeries, 1>(uri, 1, 1, "AreaSeries");
207 207 qmlRegisterType<DeclarativeBarSeries, 1>(uri, 1, 1, "BarSeries");
208 208 qmlRegisterType<DeclarativeStackedBarSeries, 1>(uri, 1, 1, "StackedBarSeries");
209 209 qmlRegisterType<DeclarativePercentBarSeries, 1>(uri, 1, 1, "PercentBarSeries");
210 210 qmlRegisterType<DeclarativeHorizontalBarSeries, 1>(uri, 1, 1, "HorizontalBarSeries");
211 211 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 1>(uri, 1, 1, "HorizontalStackedBarSeries");
212 212 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 1>(uri, 1, 1, "HorizontalPercentBarSeries");
213 213 qmlRegisterType<DeclarativePieSeries>(uri, 1, 1, "PieSeries");
214 214 qmlRegisterType<DeclarativeBarSet>(uri, 1, 1, "BarSet");
215 215 qmlRegisterType<QValueAxis>(uri, 1, 1, "ValueAxis");
216 216 #ifndef QT_ON_ARM
217 217 qmlRegisterType<QDateTimeAxis>(uri, 1, 1, "DateTimeAxis");
218 218 #endif
219 219 qmlRegisterType<DeclarativeCategoryAxis>(uri, 1, 1, "CategoryAxis");
220 220 qmlRegisterType<DeclarativeCategoryRange>(uri, 1, 1, "CategoryRange");
221 221 qmlRegisterType<QBarCategoryAxis>(uri, 1, 1, "BarCategoryAxis");
222 222 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 1, 1, "Margins",
223 223 QLatin1String("Trying to create uncreatable: Margins."));
224 224
225 225 // QtCommercial.Chart 1.2
226 226 qmlRegisterType<DeclarativeChart, 2>(uri, 1, 2, "ChartView");
227 227 qmlRegisterType<DeclarativeScatterSeries, 2>(uri, 1, 2, "ScatterSeries");
228 228 qmlRegisterType<DeclarativeLineSeries, 2>(uri, 1, 2, "LineSeries");
229 229 qmlRegisterType<DeclarativeSplineSeries, 2>(uri, 1, 2, "SplineSeries");
230 230 qmlRegisterType<DeclarativeAreaSeries, 2>(uri, 1, 2, "AreaSeries");
231 231 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 1, 2, "BarSeries");
232 232 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 1, 2, "StackedBarSeries");
233 233 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 1, 2, "PercentBarSeries");
234 234 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 1, 2, "HorizontalBarSeries");
235 235 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 1, 2, "HorizontalStackedBarSeries");
236 236 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 1, 2, "HorizontalPercentBarSeries");
237 237
238 238 // QtCommercial.Chart 1.3
239 239 qmlRegisterType<DeclarativeChart, 3>(uri, 1, 3, "ChartView");
240 240 qmlRegisterType<DeclarativePolarChart, 1>(uri, 1, 3, "PolarChartView");
241 241 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 1, 3, "SplineSeries");
242 242 qmlRegisterType<DeclarativeScatterSeries, 3>(uri, 1, 3, "ScatterSeries");
243 243 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 1, 3, "LineSeries");
244 244 qmlRegisterType<DeclarativeAreaSeries, 3>(uri, 1, 3, "AreaSeries");
245 245 qmlRegisterType<QLogValueAxis>(uri, 1, 3, "LogValueAxis");
246 246 qmlRegisterType<DeclarativeBoxPlotSeries>(uri, 1, 3, "BoxPlotSeries");
247 247 qmlRegisterType<DeclarativeBoxSet>(uri, 1, 3, "BoxSet");
248 248
249 249 // QtCommercial.Chart 1.4
250 250 qmlRegisterType<DeclarativeAreaSeries, 4>(uri, 1, 4, "AreaSeries");
251 251 qmlRegisterType<DeclarativeBarSet, 2>(uri, 1, 4, "BarSet");
252 252 qmlRegisterType<DeclarativeBoxPlotSeries, 1>(uri, 1, 4, "BoxPlotSeries");
253 253 qmlRegisterType<DeclarativeBoxSet, 1>(uri, 1, 4, "BoxSet");
254 254 qmlRegisterType<DeclarativePieSlice>(uri, 1, 4, "PieSlice");
255 255 qmlRegisterType<DeclarativeScatterSeries, 4>(uri, 1, 4, "ScatterSeries");
256 256
257 257 // QtCommercial.Chart 2.0
258 258 qmlRegisterType<QVBoxPlotModelMapper>(uri, 2, 0, "VBoxPlotModelMapper");
259 259 qmlRegisterUncreatableType<QBoxPlotModelMapper>(uri, 2, 0, "BoxPlotModelMapper",
260 260 QLatin1String("Trying to create uncreatable: BoxPlotModelMapper."));
261
262 // Re-register latest revisions for 2.0
261 263 qmlRegisterType<DeclarativeChart, 4>(uri, 2, 0, "ChartView");
264 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 2, 0, "LineSeries");
265 qmlRegisterType<DeclarativeScatterSeries, 4>(uri, 2, 0, "ScatterSeries");
266 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 2, 0, "SplineSeries");
267 qmlRegisterType<DeclarativeAreaSeries, 4>(uri, 2, 0, "AreaSeries");
268 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 2, 0, "BarSeries");
269 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 2, 0, "StackedBarSeries");
270 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 2, 0, "PercentBarSeries");
271 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 2, 0, "HorizontalBarSeries");
272 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 2, 0, "HorizontalStackedBarSeries");
273 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 2, 0, "HorizontalPercentBarSeries");
274 qmlRegisterType<DeclarativeBarSet, 2>(uri, 2, 0, "BarSet");
275 qmlRegisterType<DeclarativeBoxPlotSeries, 1>(uri, 2, 0, "BoxPlotSeries");
276 qmlRegisterType<DeclarativeBoxSet, 1>(uri, 2, 0, "BoxSet");
277 qmlRegisterType<DeclarativePieSlice>(uri, 2, 0, "PieSlice");
278 qmlRegisterType<DeclarativePieSeries>(uri, 2, 0, "PieSeries");
279 qmlRegisterType<DeclarativeXYPoint>(uri, 2, 0, "XYPoint");
280 qmlRegisterType<QHXYModelMapper>(uri, 2, 0, "HXYModelMapper");
281 qmlRegisterType<QVXYModelMapper>(uri, 2, 0, "VXYModelMapper");
282 qmlRegisterType<QHPieModelMapper>(uri, 2, 0, "HPieModelMapper");
283 qmlRegisterType<QVPieModelMapper>(uri, 2, 0, "VPieModelMapper");
284 qmlRegisterType<QHBarModelMapper>(uri, 2, 0, "HBarModelMapper");
285 qmlRegisterType<QVBarModelMapper>(uri, 2, 0, "VBarModelMapper");
286 qmlRegisterType<QValueAxis>(uri, 2, 0, "ValueAxis");
287 #ifndef QT_ON_ARM
288 qmlRegisterType<QDateTimeAxis>(uri, 2, 0, "DateTimeAxis");
289 #endif
290 qmlRegisterType<DeclarativeCategoryAxis>(uri, 2, 0, "CategoryAxis");
291 qmlRegisterType<DeclarativeCategoryRange>(uri, 2, 0, "CategoryRange");
292 qmlRegisterType<QBarCategoryAxis>(uri, 2, 0, "BarCategoryAxis");
293 qmlRegisterUncreatableType<QLegend>(uri, 2, 0, "Legend",
294 QLatin1String("Trying to create uncreatable: Legend."));
295 qmlRegisterUncreatableType<QXYSeries>(uri, 2, 0, "XYSeries",
296 QLatin1String("Trying to create uncreatable: XYSeries."));
297 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 2, 0, "AbstractItemModel",
298 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
299 qmlRegisterUncreatableType<QXYModelMapper>(uri, 2, 0, "XYModelMapper",
300 QLatin1String("Trying to create uncreatable: XYModelMapper."));
301 qmlRegisterUncreatableType<QPieModelMapper>(uri, 2, 0, "PieModelMapper",
302 QLatin1String("Trying to create uncreatable: PieModelMapper."));
303 qmlRegisterUncreatableType<QBarModelMapper>(uri, 2, 0, "BarModelMapper",
304 QLatin1String("Trying to create uncreatable: BarModelMapper."));
305 qmlRegisterUncreatableType<QAbstractSeries>(uri, 2, 0, "AbstractSeries",
306 QLatin1String("Trying to create uncreatable: AbstractSeries."));
307 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 2, 0, "AbstractBarSeries",
308 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
309 qmlRegisterUncreatableType<QAbstractAxis>(uri, 2, 0, "AbstractAxis",
310 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
311 qmlRegisterUncreatableType<QBarSet>(uri, 2, 0, "BarSetBase",
312 QLatin1String("Trying to create uncreatable: BarsetBase."));
313 qmlRegisterUncreatableType<QPieSeries>(uri, 2, 0, "QPieSeries",
314 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
315 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 2, 0, "DeclarativeAxes",
316 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
317 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 2, 0, "Margins",
318 QLatin1String("Trying to create uncreatable: Margins."));
319 qmlRegisterType<DeclarativePolarChart>(uri, 2, 0, "PolarChartView");
320 qmlRegisterType<QLogValueAxis>(uri, 2, 0, "LogValueAxis");
262 321 }
263 322 };
264 323
265 324 QTCOMMERCIALCHART_END_NAMESPACE
266 325
267 326 #include "plugin.moc"
268 327
269 328 QTCOMMERCIALCHART_USE_NAMESPACE
270 329
271 330 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
272 331 Q_EXPORT_PLUGIN2(qtcommercialchartqml, QT_PREPEND_NAMESPACE(ChartQmlPlugin))
273 332 #endif
@@ -1,402 +1,402
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 "chartaxiselement_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "abstractchartlayout_p.h"
25 25 #include <qmath.h>
26 26 #include <QDateTime>
27 27 #include <QTextDocument>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.lhjztL]*([dicuoxfegXFEG])";
32 static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.?(\\d)*([defgiEG])(.*)$";
32 static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.(\\d+)([defgiEG])(.*)$";
33 33 static QRegExp *labelFormatMatcher = 0;
34 34 static QRegExp *labelFormatMatcherLocalized = 0;
35 35 class StaticLabelFormatMatcherDeleter
36 36 {
37 37 public:
38 38 StaticLabelFormatMatcherDeleter() {}
39 39 ~StaticLabelFormatMatcherDeleter() {
40 40 delete labelFormatMatcher;
41 41 delete labelFormatMatcherLocalized;
42 42 }
43 43 };
44 44 static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;
45 45
46 46 ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
47 47 : ChartElement(item),
48 48 m_axis(axis),
49 49 m_animation(0),
50 50 m_grid(new QGraphicsItemGroup(item)),
51 51 m_arrow(new QGraphicsItemGroup(item)),
52 52 m_shades(new QGraphicsItemGroup(item)),
53 53 m_labels(new QGraphicsItemGroup(item)),
54 54 m_title(new QGraphicsTextItem(item)),
55 55 m_intervalAxis(intervalAxis)
56 56
57 57 {
58 58 //initial initialization
59 59 m_arrow->setHandlesChildEvents(false);
60 60 m_arrow->setZValue(ChartPresenter::AxisZValue);
61 61 m_labels->setZValue(ChartPresenter::AxisZValue);
62 62 m_shades->setZValue(ChartPresenter::ShadesZValue);
63 63 m_grid->setZValue(ChartPresenter::GridZValue);
64 64 m_title->setZValue(ChartPresenter::GridZValue);
65 65 m_title->document()->setDocumentMargin(ChartPresenter::textMargin());
66 66 handleVisibleChanged(axis->isVisible());
67 67 connectSlots();
68 68
69 69 setFlag(QGraphicsItem::ItemHasNoContents, true);
70 70 }
71 71
72 72 ChartAxisElement::~ChartAxisElement()
73 73 {
74 74 }
75 75
76 76 void ChartAxisElement::connectSlots()
77 77 {
78 78 QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
79 79 QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
80 80 QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
81 81 QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
82 82 QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
83 83 QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
84 84 QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
85 85 QObject::connect(axis(), SIGNAL(labelsPenChanged(const QPen&)), this, SLOT(handleLabelsPenChanged(const QPen&)));
86 86 QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
87 87 QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
88 88 QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
89 89 QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
90 90 QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
91 91 QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
92 92 QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
93 93 QObject::connect(axis(), SIGNAL(titlePenChanged(const QPen&)), this, SLOT(handleTitlePenChanged(const QPen&)));
94 94 QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
95 95 QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
96 96 QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
97 97 }
98 98
99 99 void ChartAxisElement::handleArrowVisibleChanged(bool visible)
100 100 {
101 101 m_arrow->setVisible(visible);
102 102 }
103 103
104 104 void ChartAxisElement::handleGridVisibleChanged(bool visible)
105 105 {
106 106 m_grid->setVisible(visible);
107 107 }
108 108
109 109 void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
110 110 {
111 111 QGraphicsLayoutItem::updateGeometry();
112 112 presenter()->layout()->invalidate();
113 113 m_labels->setVisible(visible);
114 114 }
115 115
116 116 void ChartAxisElement::handleShadesVisibleChanged(bool visible)
117 117 {
118 118 m_shades->setVisible(visible);
119 119 }
120 120
121 121 void ChartAxisElement::handleTitleVisibleChanged(bool visible)
122 122 {
123 123 QGraphicsLayoutItem::updateGeometry();
124 124 presenter()->layout()->invalidate();
125 125 m_title->setVisible(visible);
126 126 }
127 127
128 128 void ChartAxisElement::handleLabelsAngleChanged(int angle)
129 129 {
130 130 foreach (QGraphicsItem *item, m_labels->childItems())
131 131 item->setRotation(angle);
132 132
133 133 QGraphicsLayoutItem::updateGeometry();
134 134 presenter()->layout()->invalidate();
135 135 }
136 136
137 137 void ChartAxisElement::handleLabelsPenChanged(const QPen &pen)
138 138 {
139 139 Q_UNUSED(pen)
140 140 }
141 141
142 142 void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
143 143 {
144 144 foreach (QGraphicsItem *item, m_labels->childItems())
145 145 static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
146 146 }
147 147
148 148 void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
149 149 {
150 150 foreach (QGraphicsItem *item, m_labels->childItems())
151 151 static_cast<QGraphicsTextItem *>(item)->setFont(font);
152 152 QGraphicsLayoutItem::updateGeometry();
153 153 presenter()->layout()->invalidate();
154 154 }
155 155
156 156 void ChartAxisElement::handleTitleTextChanged(const QString &title)
157 157 {
158 158 QGraphicsLayoutItem::updateGeometry();
159 159 presenter()->layout()->invalidate();
160 160 if (title.isEmpty() || !m_title->isVisible())
161 161 m_title->setHtml(title);
162 162 }
163 163
164 164 void ChartAxisElement::handleTitlePenChanged(const QPen &pen)
165 165 {
166 166 Q_UNUSED(pen)
167 167 }
168 168
169 169 void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
170 170 {
171 171 m_title->setDefaultTextColor(brush.color());
172 172 }
173 173
174 174 void ChartAxisElement::handleTitleFontChanged(const QFont &font)
175 175 {
176 176 if (m_title->font() != font) {
177 177 m_title->setFont(font);
178 178 QGraphicsLayoutItem::updateGeometry();
179 179 presenter()->layout()->invalidate();
180 180 }
181 181 }
182 182
183 183 void ChartAxisElement::handleVisibleChanged(bool visible)
184 184 {
185 185 setVisible(visible);
186 186 if (!visible) {
187 187 m_grid->setVisible(visible);
188 188 m_arrow->setVisible(visible);
189 189 m_shades->setVisible(visible);
190 190 m_labels->setVisible(visible);
191 191 m_title->setVisible(visible);
192 192 } else {
193 193 m_grid->setVisible(axis()->isGridLineVisible());
194 194 m_arrow->setVisible(axis()->isLineVisible());
195 195 m_shades->setVisible(axis()->shadesVisible());
196 196 m_labels->setVisible(axis()->labelsVisible());
197 197 m_title->setVisible(axis()->isTitleVisible());
198 198 }
199 199
200 200 if (presenter()) presenter()->layout()->invalidate();
201 201 }
202 202
203 203 void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
204 204 {
205 205 Q_UNUSED(min);
206 206 Q_UNUSED(max);
207 207
208 208 if (!isEmpty()) {
209 209 QVector<qreal> layout = calculateLayout();
210 210 updateLayout(layout);
211 211 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
212 212 QSizeF after = sizeHint(Qt::PreferredSize);
213 213
214 214 if (before != after) {
215 215 QGraphicsLayoutItem::updateGeometry();
216 216 // We don't want to call invalidate on layout, since it will change minimum size of
217 217 // component, which we would like to avoid since it causes nasty flips when scrolling
218 218 // or zooming, instead recalculate layout and use plotArea for extra space.
219 219 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
220 220 }
221 221 }
222 222 }
223 223
224 224 bool ChartAxisElement::isEmpty()
225 225 {
226 226 return axisGeometry().isEmpty()
227 227 || gridGeometry().isEmpty()
228 228 || qFuzzyCompare(min(), max());
229 229 }
230 230
231 231 qreal ChartAxisElement::min() const
232 232 {
233 233 return m_axis->d_ptr->min();
234 234 }
235 235
236 236 qreal ChartAxisElement::max() const
237 237 {
238 238 return m_axis->d_ptr->max();
239 239 }
240 240
241 241 QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array,
242 242 qreal value, int precision, const QString &preStr,
243 243 const QString &postStr) const
244 244 {
245 245 QString retVal;
246 246 if (!formatSpec.isEmpty()) {
247 247 if (formatSpec.at(0) == QLatin1Char('d')
248 248 || formatSpec.at(0) == QLatin1Char('i')
249 249 || formatSpec.at(0) == QLatin1Char('c')) {
250 250 if (presenter()->localizeNumbers())
251 251 retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr;
252 252 else
253 253 retVal = QString().sprintf(array, qint64(value));
254 254 } else if (formatSpec.at(0) == QLatin1Char('u')
255 255 || formatSpec.at(0) == QLatin1Char('o')
256 256 || formatSpec.at(0) == QLatin1Char('x')
257 257 || formatSpec.at(0) == QLatin1Char('X')) {
258 258 // These formats are not supported by localized numbers
259 259 retVal = QString().sprintf(array, quint64(value));
260 260 } else if (formatSpec.at(0) == QLatin1Char('f')
261 261 || formatSpec.at(0) == QLatin1Char('F')
262 262 || formatSpec.at(0) == QLatin1Char('e')
263 263 || formatSpec.at(0) == QLatin1Char('E')
264 264 || formatSpec.at(0) == QLatin1Char('g')
265 265 || formatSpec.at(0) == QLatin1Char('G')) {
266 266 if (presenter()->localizeNumbers()) {
267 267 retVal = preStr
268 268 + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(),
269 269 precision)
270 270 + postStr;
271 271 } else {
272 272 retVal = QString().sprintf(array, value);
273 273 }
274 274 }
275 275 }
276 276 return retVal;
277 277 }
278 278
279 279 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks,
280 280 const QString &format) const
281 281 {
282 282 QStringList labels;
283 283
284 284 if (max <= min || ticks < 1)
285 285 return labels;
286 286
287 287 if (format.isNull()) {
288 288 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0) + 1;
289 289 for (int i = 0; i < ticks; i++) {
290 290 qreal value = min + (i * (max - min) / (ticks - 1));
291 291 labels << presenter()->numberToString(value, 'f', n);
292 292 }
293 293 } else {
294 294 QByteArray array = format.toLatin1();
295 295 QString formatSpec;
296 296 QString preStr;
297 297 QString postStr;
298 298 int precision = 6; // Six is the default precision in Qt API
299 299 if (presenter()->localizeNumbers()) {
300 300 if (!labelFormatMatcherLocalized)
301 301 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
302 302 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
303 303 preStr = labelFormatMatcherLocalized->cap(1);
304 304 if (!labelFormatMatcherLocalized->cap(2).isEmpty())
305 305 precision = labelFormatMatcherLocalized->cap(2).toInt();
306 306 formatSpec = labelFormatMatcherLocalized->cap(3);
307 307 postStr = labelFormatMatcherLocalized->cap(4);
308 308 }
309 309 } else {
310 310 if (!labelFormatMatcher)
311 311 labelFormatMatcher = new QRegExp(labelFormatMatchString);
312 312 if (labelFormatMatcher->indexIn(format, 0) != -1)
313 313 formatSpec = labelFormatMatcher->cap(1);
314 314 }
315 315 for (int i = 0; i < ticks; i++) {
316 316 qreal value = min + (i * (max - min) / (ticks - 1));
317 317 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
318 318 }
319 319 }
320 320
321 321 return labels;
322 322 }
323 323
324 324 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks,
325 325 const QString &format) const
326 326 {
327 327 QStringList labels;
328 328
329 329 if (max <= min || ticks < 1)
330 330 return labels;
331 331
332 332 int firstTick;
333 333 if (base > 1)
334 334 firstTick = ceil(log10(min) / log10(base));
335 335 else
336 336 firstTick = ceil(log10(max) / log10(base));
337 337
338 338 if (format.isNull()) {
339 339 int n = 0;
340 340 if (ticks > 1)
341 341 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
342 342 n++;
343 343 for (int i = firstTick; i < ticks + firstTick; i++) {
344 344 qreal value = qPow(base, i);
345 345 labels << presenter()->numberToString(value, 'f', n);
346 346 }
347 347 } else {
348 348 QByteArray array = format.toLatin1();
349 349 QString formatSpec;
350 350 QString preStr;
351 351 QString postStr;
352 352 int precision = 6; // Six is the default precision in Qt API
353 353 if (presenter()->localizeNumbers()) {
354 354 if (!labelFormatMatcherLocalized)
355 355 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
356 356 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
357 357 preStr = labelFormatMatcherLocalized->cap(1);
358 358 if (!labelFormatMatcherLocalized->cap(2).isEmpty())
359 359 precision = labelFormatMatcherLocalized->cap(2).toInt();
360 360 formatSpec = labelFormatMatcherLocalized->cap(3);
361 361 postStr = labelFormatMatcherLocalized->cap(4);
362 362 }
363 363 } else {
364 364 if (!labelFormatMatcher)
365 365 labelFormatMatcher = new QRegExp(labelFormatMatchString);
366 366 if (labelFormatMatcher->indexIn(format, 0) != -1)
367 367 formatSpec = labelFormatMatcher->cap(1);
368 368 }
369 369 for (int i = firstTick; i < ticks + firstTick; i++) {
370 370 qreal value = qPow(base, i);
371 371 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
372 372 }
373 373 }
374 374
375 375 return labels;
376 376 }
377 377
378 378 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,
379 379 const QString &format) const
380 380 {
381 381 QStringList labels;
382 382
383 383 if (max <= min || ticks < 1)
384 384 return labels;
385 385
386 386 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
387 387 n++;
388 388 for (int i = 0; i < ticks; i++) {
389 389 qreal value = min + (i * (max - min) / (ticks - 1));
390 390 labels << presenter()->locale().toString(QDateTime::fromMSecsSinceEpoch(value), format);
391 391 }
392 392 return labels;
393 393 }
394 394
395 395 void ChartAxisElement::axisSelected()
396 396 {
397 397 emit clicked();
398 398 }
399 399
400 400 #include "moc_chartaxiselement_p.cpp"
401 401
402 402 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,509 +1,509
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 #include "chartpresenter_p.h"
21 21 #include "qchart.h"
22 22 #include "chartitem_p.h"
23 23 #include "qchart_p.h"
24 24 #include "qabstractaxis.h"
25 25 #include "qabstractaxis_p.h"
26 26 #include "chartdataset_p.h"
27 27 #include "chartanimation_p.h"
28 28 #include "qabstractseries_p.h"
29 29 #include "qareaseries.h"
30 30 #include "chartaxiselement_p.h"
31 31 #include "chartbackground_p.h"
32 32 #include "cartesianchartlayout_p.h"
33 33 #include "polarchartlayout_p.h"
34 34 #include "charttitle_p.h"
35 35 #include <QTimer>
36 36 #include <QTextDocument>
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
41 41 : QObject(chart),
42 42 m_chart(chart),
43 43 m_options(QChart::NoAnimation),
44 44 m_state(ShowState),
45 45 m_background(0),
46 46 m_plotAreaBackground(0),
47 47 m_title(0),
48 m_localizeNumbers(true)
48 m_localizeNumbers(false)
49 49 {
50 50 if (type == QChart::ChartTypeCartesian)
51 51 m_layout = new CartesianChartLayout(this);
52 52 else if (type == QChart::ChartTypePolar)
53 53 m_layout = new PolarChartLayout(this);
54 54 Q_ASSERT(m_layout);
55 55 }
56 56
57 57 ChartPresenter::~ChartPresenter()
58 58 {
59 59
60 60 }
61 61
62 62 void ChartPresenter::setGeometry(const QRectF rect)
63 63 {
64 64 if (m_rect != rect) {
65 65 m_rect = rect;
66 66 foreach (ChartItem *chart, m_chartItems) {
67 67 chart->domain()->setSize(rect.size());
68 68 chart->setPos(rect.topLeft());
69 69 }
70 70 }
71 71 }
72 72
73 73 QRectF ChartPresenter::geometry() const
74 74 {
75 75 return m_rect;
76 76 }
77 77
78 78 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
79 79 {
80 80 axis->d_ptr->initializeGraphics(rootItem());
81 81 axis->d_ptr->initializeAnimations(m_options);
82 82 ChartAxisElement *item = axis->d_ptr->axisItem();
83 83 item->setPresenter(this);
84 84 item->setThemeManager(m_chart->d_ptr->m_themeManager);
85 85 m_axisItems<<item;
86 86 m_axes<<axis;
87 87 m_layout->invalidate();
88 88 }
89 89
90 90 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
91 91 {
92 92 ChartAxisElement *item = axis->d_ptr->m_item.take();
93 93 item->hide();
94 94 item->disconnect();
95 95 item->deleteLater();
96 96 m_axisItems.removeAll(item);
97 97 m_axes.removeAll(axis);
98 98 m_layout->invalidate();
99 99 }
100 100
101 101
102 102 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
103 103 {
104 104 series->d_ptr->initializeGraphics(rootItem());
105 105 series->d_ptr->initializeAnimations(m_options);
106 106 series->d_ptr->setPresenter(this);
107 107 ChartItem *chart = series->d_ptr->chartItem();
108 108 chart->setPresenter(this);
109 109 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
110 110 chart->domain()->setSize(m_rect.size());
111 111 chart->setPos(m_rect.topLeft());
112 112 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
113 113 m_chartItems<<chart;
114 114 m_series<<series;
115 115 m_layout->invalidate();
116 116 }
117 117
118 118 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
119 119 {
120 120 ChartItem *chart = series->d_ptr->m_item.take();
121 121 chart->hide();
122 122 chart->disconnect();
123 123 chart->deleteLater();
124 124 m_chartItems.removeAll(chart);
125 125 m_series.removeAll(series);
126 126 m_layout->invalidate();
127 127 }
128 128
129 129 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
130 130 {
131 131 if (m_options != options) {
132 132 QChart::AnimationOptions oldOptions = m_options;
133 133 m_options = options;
134 134 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
135 135 foreach (QAbstractSeries *series, m_series)
136 136 series->d_ptr->initializeAnimations(m_options);
137 137 }
138 138 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
139 139 foreach (QAbstractAxis *axis, m_axes)
140 140 axis->d_ptr->initializeAnimations(m_options);
141 141 }
142 142 m_layout->invalidate(); // So that existing animations don't just stop halfway
143 143 }
144 144 }
145 145
146 146 void ChartPresenter::setState(State state,QPointF point)
147 147 {
148 148 m_state=state;
149 149 m_statePoint=point;
150 150 }
151 151
152 152 QChart::AnimationOptions ChartPresenter::animationOptions() const
153 153 {
154 154 return m_options;
155 155 }
156 156
157 157 void ChartPresenter::createBackgroundItem()
158 158 {
159 159 if (!m_background) {
160 160 m_background = new ChartBackground(rootItem());
161 161 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
162 162 m_background->setBrush(QChartPrivate::defaultBrush());
163 163 m_background->setZValue(ChartPresenter::BackgroundZValue);
164 164 }
165 165 }
166 166
167 167 void ChartPresenter::createPlotAreaBackgroundItem()
168 168 {
169 169 if (!m_plotAreaBackground) {
170 170 if (m_chart->chartType() == QChart::ChartTypeCartesian)
171 171 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
172 172 else
173 173 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
174 174 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
175 175 // antialising artifacts with axis lines for some reason.
176 176 m_plotAreaBackground->setPen(QPen(Qt::transparent));
177 177 m_plotAreaBackground->setBrush(Qt::NoBrush);
178 178 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
179 179 m_plotAreaBackground->setVisible(false);
180 180 }
181 181 }
182 182
183 183 void ChartPresenter::createTitleItem()
184 184 {
185 185 if (!m_title) {
186 186 m_title = new ChartTitle(rootItem());
187 187 m_title->setZValue(ChartPresenter::BackgroundZValue);
188 188 }
189 189 }
190 190
191 191 void ChartPresenter::startAnimation(ChartAnimation *animation)
192 192 {
193 193 animation->stop();
194 194 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
195 195 }
196 196
197 197 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
198 198 {
199 199 createBackgroundItem();
200 200 m_background->setBrush(brush);
201 201 m_layout->invalidate();
202 202 }
203 203
204 204 QBrush ChartPresenter::backgroundBrush() const
205 205 {
206 206 if (!m_background)
207 207 return QBrush();
208 208 return m_background->brush();
209 209 }
210 210
211 211 void ChartPresenter::setBackgroundPen(const QPen &pen)
212 212 {
213 213 createBackgroundItem();
214 214 m_background->setPen(pen);
215 215 m_layout->invalidate();
216 216 }
217 217
218 218 QPen ChartPresenter::backgroundPen() const
219 219 {
220 220 if (!m_background)
221 221 return QPen();
222 222 return m_background->pen();
223 223 }
224 224
225 225 void ChartPresenter::setBackgroundRoundness(qreal diameter)
226 226 {
227 227 createBackgroundItem();
228 228 m_background->setDiameter(diameter);
229 229 m_layout->invalidate();
230 230 }
231 231
232 232 qreal ChartPresenter::backgroundRoundness() const
233 233 {
234 234 if (!m_background)
235 235 return 0;
236 236 return m_background->diameter();
237 237 }
238 238
239 239 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
240 240 {
241 241 createPlotAreaBackgroundItem();
242 242 m_plotAreaBackground->setBrush(brush);
243 243 m_layout->invalidate();
244 244 }
245 245
246 246 QBrush ChartPresenter::plotAreaBackgroundBrush() const
247 247 {
248 248 if (!m_plotAreaBackground)
249 249 return QBrush();
250 250 return m_plotAreaBackground->brush();
251 251 }
252 252
253 253 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
254 254 {
255 255 createPlotAreaBackgroundItem();
256 256 m_plotAreaBackground->setPen(pen);
257 257 m_layout->invalidate();
258 258 }
259 259
260 260 QPen ChartPresenter::plotAreaBackgroundPen() const
261 261 {
262 262 if (!m_plotAreaBackground)
263 263 return QPen();
264 264 return m_plotAreaBackground->pen();
265 265 }
266 266
267 267 void ChartPresenter::setTitle(const QString &title)
268 268 {
269 269 createTitleItem();
270 270 m_title->setText(title);
271 271 m_layout->invalidate();
272 272 }
273 273
274 274 QString ChartPresenter::title() const
275 275 {
276 276 if (!m_title)
277 277 return QString();
278 278 return m_title->text();
279 279 }
280 280
281 281 void ChartPresenter::setTitleFont(const QFont &font)
282 282 {
283 283 createTitleItem();
284 284 m_title->setFont(font);
285 285 m_layout->invalidate();
286 286 }
287 287
288 288 QFont ChartPresenter::titleFont() const
289 289 {
290 290 if (!m_title)
291 291 return QFont();
292 292 return m_title->font();
293 293 }
294 294
295 295 void ChartPresenter::setTitleBrush(const QBrush &brush)
296 296 {
297 297 createTitleItem();
298 298 m_title->setDefaultTextColor(brush.color());
299 299 m_layout->invalidate();
300 300 }
301 301
302 302 QBrush ChartPresenter::titleBrush() const
303 303 {
304 304 if (!m_title)
305 305 return QBrush();
306 306 return QBrush(m_title->defaultTextColor());
307 307 }
308 308
309 309 void ChartPresenter::setBackgroundVisible(bool visible)
310 310 {
311 311 createBackgroundItem();
312 312 m_background->setVisible(visible);
313 313 }
314 314
315 315
316 316 bool ChartPresenter::isBackgroundVisible() const
317 317 {
318 318 if (!m_background)
319 319 return false;
320 320 return m_background->isVisible();
321 321 }
322 322
323 323 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
324 324 {
325 325 createPlotAreaBackgroundItem();
326 326 m_plotAreaBackground->setVisible(visible);
327 327 }
328 328
329 329 bool ChartPresenter::isPlotAreaBackgroundVisible() const
330 330 {
331 331 if (!m_plotAreaBackground)
332 332 return false;
333 333 return m_plotAreaBackground->isVisible();
334 334 }
335 335
336 336 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
337 337 {
338 338 createBackgroundItem();
339 339 m_background->setDropShadowEnabled(enabled);
340 340 }
341 341
342 342 bool ChartPresenter::isBackgroundDropShadowEnabled() const
343 343 {
344 344 if (!m_background)
345 345 return false;
346 346 return m_background->isDropShadowEnabled();
347 347 }
348 348
349 349 void ChartPresenter::setLocalizeNumbers(bool localize)
350 350 {
351 351 m_localizeNumbers = localize;
352 352 m_layout->invalidate();
353 353 }
354 354
355 355 void ChartPresenter::setLocale(const QLocale &locale)
356 356 {
357 357 m_locale = locale;
358 358 m_layout->invalidate();
359 359 }
360 360
361 361 AbstractChartLayout *ChartPresenter::layout()
362 362 {
363 363 return m_layout;
364 364 }
365 365
366 366 QLegend *ChartPresenter::legend()
367 367 {
368 368 return m_chart->legend();
369 369 }
370 370
371 371 void ChartPresenter::setVisible(bool visible)
372 372 {
373 373 m_chart->setVisible(visible);
374 374 }
375 375
376 376 ChartBackground *ChartPresenter::backgroundElement()
377 377 {
378 378 return m_background;
379 379 }
380 380
381 381 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
382 382 {
383 383 return m_plotAreaBackground;
384 384 }
385 385
386 386 QList<ChartAxisElement *> ChartPresenter::axisItems() const
387 387 {
388 388 return m_axisItems;
389 389 }
390 390
391 391 QList<ChartItem *> ChartPresenter::chartItems() const
392 392 {
393 393 return m_chartItems;
394 394 }
395 395
396 396 ChartTitle *ChartPresenter::titleElement()
397 397 {
398 398 return m_title;
399 399 }
400 400
401 401 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
402 402 {
403 403 static QGraphicsTextItem dummyTextItem;
404 404 static bool initMargin = true;
405 405 if (initMargin) {
406 406 dummyTextItem.document()->setDocumentMargin(textMargin());
407 407 initMargin = false;
408 408 }
409 409
410 410 dummyTextItem.setFont(font);
411 411 dummyTextItem.setHtml(text);
412 412 QRectF boundingRect = dummyTextItem.boundingRect();
413 413
414 414 // Take rotation into account
415 415 if (angle) {
416 416 QTransform transform;
417 417 transform.rotate(angle);
418 418 boundingRect = transform.mapRect(boundingRect);
419 419 }
420 420
421 421 return boundingRect;
422 422 }
423 423
424 424 // boundingRect parameter returns the rotated bounding rect of the text
425 425 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
426 426 qreal maxWidth, qreal maxHeight, QRectF &boundingRect)
427 427 {
428 428 QString truncatedString(text);
429 429 boundingRect = textBoundingRect(font, truncatedString, angle);
430 430 if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) {
431 431 // It can be assumed that almost any amount of string manipulation is faster
432 432 // than calculating one bounding rectangle, so first prepare a list of truncated strings
433 433 // to try.
434 434 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
435 435 static QRegExp truncateMatcher(truncateMatchString);
436 436
437 437 QVector<QString> testStrings(text.length());
438 438 int count(0);
439 439 static QLatin1Char closeTag('>');
440 440 static QLatin1Char openTag('<');
441 441 static QLatin1Char semiColon(';');
442 442 static QLatin1String ellipsis("...");
443 443 while (truncatedString.length() > 1) {
444 444 int chopIndex(-1);
445 445 int chopCount(1);
446 446 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
447 447
448 448 if (lastChar == closeTag)
449 449 chopIndex = truncatedString.lastIndexOf(openTag);
450 450 else if (lastChar == semiColon)
451 451 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
452 452
453 453 if (chopIndex != -1)
454 454 chopCount = truncatedString.length() - chopIndex;
455 455 truncatedString.chop(chopCount);
456 456 testStrings[count] = truncatedString + ellipsis;
457 457 count++;
458 458 }
459 459
460 460 // Binary search for best fit
461 461 int minIndex(0);
462 462 int maxIndex(count - 1);
463 463 int bestIndex(count);
464 464 QRectF checkRect;
465 465
466 466 while (maxIndex >= minIndex) {
467 467 int mid = (maxIndex + minIndex) / 2;
468 468 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
469 469 if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) {
470 470 // Checked index too large, all under this are also too large
471 471 minIndex = mid + 1;
472 472 } else {
473 473 // Checked index fits, all over this also fit
474 474 maxIndex = mid - 1;
475 475 bestIndex = mid;
476 476 boundingRect = checkRect;
477 477 }
478 478 }
479 479 // Default to "..." if nothing fits
480 480 if (bestIndex == count) {
481 481 boundingRect = textBoundingRect(font, ellipsis, angle);
482 482 truncatedString = ellipsis;
483 483 } else {
484 484 truncatedString = testStrings.at(bestIndex);
485 485 }
486 486 }
487 487
488 488 return truncatedString;
489 489 }
490 490
491 491 QString ChartPresenter::numberToString(double value, char f, int prec)
492 492 {
493 493 if (m_localizeNumbers)
494 494 return m_locale.toString(value, f, prec);
495 495 else
496 496 return QString::number(value, f, prec);
497 497 }
498 498
499 499 QString ChartPresenter::numberToString(int value)
500 500 {
501 501 if (m_localizeNumbers)
502 502 return m_locale.toString(value);
503 503 else
504 504 return QString::number(value);
505 505 }
506 506
507 507 #include "moc_chartpresenter_p.cpp"
508 508
509 509 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,872 +1,872
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 "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "legendscroller_p.h"
24 24 #include "qlegend_p.h"
25 25 #include "chartbackground_p.h"
26 26 #include "qabstractaxis.h"
27 27 #include "abstractchartlayout_p.h"
28 28 #include "charttheme_p.h"
29 29 #include "chartpresenter_p.h"
30 30 #include "chartdataset_p.h"
31 31 #include <QGraphicsScene>
32 32 #include <QGraphicsSceneResizeEvent>
33 33
34 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 35
36 36 /*!
37 37 \enum QChart::ChartTheme
38 38
39 39 This enum describes the theme used by the chart.
40 40
41 41 \value ChartThemeLight The default theme
42 42 \value ChartThemeBlueCerulean
43 43 \value ChartThemeDark
44 44 \value ChartThemeBrownSand
45 45 \value ChartThemeBlueNcs
46 46 \value ChartThemeHighContrast
47 47 \value ChartThemeBlueIcy
48 48 \value ChartThemeQt
49 49 */
50 50
51 51 /*!
52 52 \enum QChart::AnimationOption
53 53
54 54 For enabling/disabling animations. Defaults to NoAnimation.
55 55
56 56 \value NoAnimation
57 57 \value GridAxisAnimations
58 58 \value SeriesAnimations
59 59 \value AllAnimations
60 60 */
61 61
62 62 /*!
63 63 \enum QChart::ChartType
64 64
65 65 This enum describes the chart type.
66 66
67 67 \value ChartTypeUndefined
68 68 \value ChartTypeCartesian
69 69 \value ChartTypePolar
70 70 */
71 71
72 72 /*!
73 73 \class QChart
74 74 \inmodule Qt Charts
75 75 \brief Main chart API for Qt Charts.
76 76
77 77 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
78 78 representation of different types of series and other chart related objects like legend and
79 79 axes. If you simply want to show a chart in a layout, you can use the
80 80 convenience class QChartView instead of QChart.
81 81 \sa QChartView, QPolarChart
82 82 */
83 83
84 84 /*!
85 85 \property QChart::animationOptions
86 86 The animation \a options for the chart. Animations are enabled/disabled based on this setting.
87 87 */
88 88
89 89 /*!
90 90 \property QChart::backgroundVisible
91 91 Specifies whether the chart background is visible or not.
92 92 \sa setBackgroundBrush(), setBackgroundPen(), plotAreaBackgroundVisible
93 93 */
94 94
95 95 /*!
96 96 \property QChart::dropShadowEnabled
97 97 If set to true, the background drop shadow effect is enabled. If set to false, it is disabled. Note that the drop
98 98 shadow effect depends on theme, which means the setting may be changed if you switch to another theme.
99 99 */
100 100
101 101 /*!
102 102 \property QChart::backgroundRoundness
103 103 The diameter of the rounding cirle at the corners of the chart background.
104 104 */
105 105
106 106 /*!
107 107 \property QChart::minimumMargins
108 108 Minimum margins between the plot area (axes) and the edge of the chart widget.
109 109 This property is deprecated; use margins property instead.
110 110
111 111 \sa margins
112 112 */
113 113
114 114 /*!
115 115 \property QChart::margins
116 116 Margins between the plot area (axes) and the edge of the chart widget.
117 117 */
118 118
119 119 /*!
120 120 \property QChart::theme
121 121 Theme is a built-in collection of UI style related settings applied for all visual elements of a chart, like colors,
122 122 pens, brushes, and fonts of series, axes, title, and legend. \l {Chart themes demo} shows an example with a few
123 123 different themes.
124 124 \note Changing the theme will overwrite all customizations previously applied to the series.
125 125 */
126 126
127 127 /*!
128 128 \property QChart::title
129 129 Title is the name (label) of a chart. It is shown as a headline on top of the chart. Chart title supports html formatting.
130 130 */
131 131
132 132 /*!
133 133 \property QChart::chartType
134 134 Chart type indicates if the chart is a cartesian chart or a polar chart.
135 135 This property is set internally and it is read only.
136 136 \sa QPolarChart
137 137 */
138 138
139 139 /*!
140 140 \property QChart::plotAreaBackgroundVisible
141 141 Specifies whether the chart plot area background is visible or not.
142 142 \note By default the plot area background is not visible and the plot area uses
143 143 the general chart background.
144 144 \sa setPlotAreaBackgroundBrush(), setPlotAreaBackgroundPen(), backgroundVisible
145 145 */
146 146
147 147 /*!
148 148 \property QChart::localizeNumbers
149 149 \since QtCharts 2.0
150 150 When \c{true}, all generated numbers appearing in various series and axis labels will be
151 151 localized using the QLocale set with the locale property.
152 152 When \c{false}, the "C" locale is always used.
153 Defaults to \c{true}.
153 Defaults to \c{false}.
154 154 \note This property doesn't affect QDateTimeAxis labels, which always use the QLocale set with
155 155 the locale property.
156 156
157 157 \sa locale
158 158 */
159 159
160 160 /*!
161 161 \property QChart::locale
162 162 \since QtCharts 2.0
163 163 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
164 164 This also determines the locale used to format QDateTimeAxis labels regardless of
165 165 localizeNumbers property.
166 166 Defaults to application default locale at the time the chart is constructed.
167 167
168 168 \sa localizeNumbers
169 169 */
170 170
171 171 /*!
172 172 \internal
173 173 Constructs a chart object of \a type which is a child of a \a parent.
174 174 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
175 175 This constructor is called only by subclasses.
176 176 */
177 177 QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags)
178 178 : QGraphicsWidget(parent, wFlags),
179 179 d_ptr(new QChartPrivate(this, type))
180 180 {
181 181 d_ptr->init();
182 182 }
183 183
184 184 /*!
185 185 Constructs a chart object which is a child of a \a parent.
186 186 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
187 187 */
188 188 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
189 189 : QGraphicsWidget(parent, wFlags),
190 190 d_ptr(new QChartPrivate(this, ChartTypeCartesian))
191 191 {
192 192 d_ptr->init();
193 193 }
194 194
195 195 /*!
196 196 Destroys the chart object and its children, like series and axis objects added to it.
197 197 */
198 198 QChart::~QChart()
199 199 {
200 200 //start by deleting dataset, it will remove all series and axes
201 201 delete d_ptr->m_dataset;
202 202 d_ptr->m_dataset = 0;
203 203 }
204 204
205 205 /*!
206 206 Adds the \a series onto the chart and takes the ownership of it.
207 207
208 208 \note A newly added series is attached to no axes by default, including any axes that were created for the chart
209 209 using createDefaultAxes() before the series was added to the chart. If no axes are attached to
210 210 the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges
211 211 that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other
212 212 series that have properly attached axes, so always make sure you either call createDefaultAxes() after
213 213 a series has been added or explicitly attach axes for the series.
214 214
215 215 \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis()
216 216 */
217 217 void QChart::addSeries(QAbstractSeries *series)
218 218 {
219 219 Q_ASSERT(series);
220 220 d_ptr->m_dataset->addSeries(series);
221 221 }
222 222
223 223 /*!
224 224 Removes the \a series from the chart.
225 225 The chart releases its ownership of the specified \a series object.
226 226
227 227 \sa addSeries(), removeAllSeries()
228 228 */
229 229 void QChart::removeSeries(QAbstractSeries *series)
230 230 {
231 231 Q_ASSERT(series);
232 232 d_ptr->m_dataset->removeSeries(series);
233 233 }
234 234
235 235 /*!
236 236 Removes and deletes all series objects that have been added to the chart.
237 237
238 238 \sa addSeries(), removeSeries()
239 239 */
240 240 void QChart::removeAllSeries()
241 241 {
242 242 foreach (QAbstractSeries *s , d_ptr->m_dataset->series()){
243 243 removeSeries(s);
244 244 delete s;
245 245 }
246 246 }
247 247
248 248 /*!
249 249 Sets the \a brush that is used for painting the background of the chart area.
250 250 */
251 251 void QChart::setBackgroundBrush(const QBrush &brush)
252 252 {
253 253 d_ptr->m_presenter->setBackgroundBrush(brush);
254 254 }
255 255
256 256 /*!
257 257 Gets the brush that is used for painting the background of the chart area.
258 258 */
259 259 QBrush QChart::backgroundBrush() const
260 260 {
261 261 return d_ptr->m_presenter->backgroundBrush();
262 262 }
263 263
264 264 /*!
265 265 Sets the \a pen that is used for painting the background of the chart area.
266 266 */
267 267 void QChart::setBackgroundPen(const QPen &pen)
268 268 {
269 269 d_ptr->m_presenter->setBackgroundPen(pen);
270 270 }
271 271
272 272 /*!
273 273 Gets the pen that is used for painting the background of the chart area.
274 274 */
275 275 QPen QChart::backgroundPen() const
276 276 {
277 277 return d_ptr->m_presenter->backgroundPen();
278 278 }
279 279
280 280 void QChart::setTitle(const QString &title)
281 281 {
282 282 d_ptr->m_presenter->setTitle(title);
283 283 }
284 284
285 285 QString QChart::title() const
286 286 {
287 287 return d_ptr->m_presenter->title();
288 288 }
289 289
290 290 /*!
291 291 Sets the \a font that is used for drawing the chart title.
292 292 */
293 293 void QChart::setTitleFont(const QFont &font)
294 294 {
295 295 d_ptr->m_presenter->setTitleFont(font);
296 296 }
297 297
298 298 /*!
299 299 Gets the font that is used for drawing the chart title.
300 300 */
301 301 QFont QChart::titleFont() const
302 302 {
303 303 return d_ptr->m_presenter->titleFont();
304 304 }
305 305
306 306 /*!
307 307 Sets the \a brush used for drawing the title text.
308 308 */
309 309 void QChart::setTitleBrush(const QBrush &brush)
310 310 {
311 311 d_ptr->m_presenter->setTitleBrush(brush);
312 312 }
313 313
314 314 /*!
315 315 Returns the brush used for drawing the title text.
316 316 */
317 317 QBrush QChart::titleBrush() const
318 318 {
319 319 return d_ptr->m_presenter->titleBrush();
320 320 }
321 321
322 322 void QChart::setTheme(QChart::ChartTheme theme)
323 323 {
324 324 d_ptr->m_themeManager->setTheme(theme);
325 325 }
326 326
327 327 QChart::ChartTheme QChart::theme() const
328 328 {
329 329 return d_ptr->m_themeManager->theme()->id();
330 330 }
331 331
332 332 /*!
333 333 Zooms in the view by a factor of two.
334 334 */
335 335 void QChart::zoomIn()
336 336 {
337 337 d_ptr->zoomIn(2.0);
338 338 }
339 339
340 340 /*!
341 341 Zooms in the view to a maximum level at which \a rect is still fully visible.
342 342 \note This is not supported for polar charts.
343 343 */
344 344 void QChart::zoomIn(const QRectF &rect)
345 345 {
346 346 if (d_ptr->m_type == QChart::ChartTypePolar)
347 347 return;
348 348 d_ptr->zoomIn(rect);
349 349 }
350 350
351 351 /*!
352 352 Zooms out the view by a factor of two.
353 353 */
354 354 void QChart::zoomOut()
355 355 {
356 356 d_ptr->zoomOut(2.0);
357 357 }
358 358
359 359 /*!
360 360 Zooms in the view by a custom \a factor.
361 361
362 362 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
363 363 */
364 364 void QChart::zoom(qreal factor)
365 365 {
366 366 if (qFuzzyCompare(factor, 0))
367 367 return;
368 368
369 369 if (qFuzzyCompare(factor, (qreal)1.0))
370 370 return;
371 371
372 372 if (factor < 0)
373 373 return;
374 374
375 375 if (factor > 1.0)
376 376 d_ptr->zoomIn(factor);
377 377 else
378 378 d_ptr->zoomOut(1.0 / factor);
379 379 }
380 380
381 381
382 382 /*!
383 383 Resets the series domains to what they were before any zoom method was called.
384 384 Note that this will also reset any scrolls and explicit axis range settings done between
385 385 the first zoom operation and calling this method. If no zoom operation has been
386 386 done, this method does nothing.
387 387 */
388 388 void QChart::zoomReset()
389 389 {
390 390 d_ptr->zoomReset();
391 391 }
392 392
393 393 /*!
394 394 Returns true if any series has a zoomed domain.
395 395 */
396 396 bool QChart::isZoomed()
397 397 {
398 398 return d_ptr->isZoomed();
399 399 }
400 400
401 401 /*!
402 402 Returns a pointer to the horizontal axis attached to the specified \a series.
403 403 If no \a series is specified, the first horizontal axis added to the chart is returned.
404 404
405 405 \sa addAxis(), QAbstractSeries::attachAxis()
406 406 */
407 407 QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
408 408 {
409 409 QList<QAbstractAxis *> axisList = axes(Qt::Horizontal, series);
410 410 if (axisList.count())
411 411 return axisList[0];
412 412 return 0;
413 413 }
414 414
415 415 /*!
416 416 Returns a pointer to the vertical axis attached to the specified \a series.
417 417 If no \a series is specified, the first vertical axis added to the chart is returned.
418 418
419 419 \sa addAxis(), QAbstractSeries::attachAxis()
420 420 */
421 421 QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
422 422 {
423 423 QList<QAbstractAxis *> axisList = axes(Qt::Vertical, series);
424 424 if (axisList.count())
425 425 return axisList[0];
426 426 return 0;
427 427 }
428 428
429 429 /*!
430 430 Returns the axes attached to the \a series with \a orientation. If no \a series is provided,
431 431 then all axes added to the chart with the specified orientation are returned.
432 432 \sa addAxis(), createDefaultAxes()
433 433 */
434 434 QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
435 435 {
436 436 QList<QAbstractAxis *> result ;
437 437
438 438 if (series) {
439 439 foreach (QAbstractAxis *axis, series->attachedAxes()){
440 440 if (orientation.testFlag(axis->orientation()))
441 441 result << axis;
442 442 }
443 443 } else {
444 444 foreach (QAbstractAxis *axis, d_ptr->m_dataset->axes()){
445 445 if (orientation.testFlag(axis->orientation()) && !result.contains(axis))
446 446 result << axis;
447 447 }
448 448 }
449 449
450 450 return result;
451 451 }
452 452
453 453 /*!
454 454 Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
455 455 the chart will be deleted.
456 456
457 457 \note This function has to be called after all series have been added to the chart. The axes created by this function
458 458 will NOT get automatically attached to any series added to the chart after this function has been called.
459 459 A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
460 460 if there are other series with properly attached axes also present.
461 461
462 462 \table
463 463 \header
464 464 \li Series type
465 465 \li X-axis
466 466 \li Y-axis
467 467 \row
468 468 \li QXYSeries
469 469 \li QValueAxis
470 470 \li QValueAxis
471 471 \row
472 472 \li QBarSeries
473 473 \li QBarCategoryAxis
474 474 \li QValueAxis
475 475 \row
476 476 \li QPieSeries
477 477 \li None
478 478 \li None
479 479 \endtable
480 480
481 481 If there are several QXYSeries derived series added to the chart and no series of other types have been added, then only one pair of axes is created.
482 482 If there are several series of different types added to the chart, then each series gets its own axes pair.
483 483
484 484 The axes specific to the series can be later obtained from the chart by providing the series as the parameter for axes() function call.
485 485 QPieSeries does not create any axes.
486 486
487 487 \sa axisX(), axisY(), axes(), setAxisX(), setAxisY(), QAbstractSeries::attachAxis()
488 488 */
489 489 void QChart::createDefaultAxes()
490 490 {
491 491 d_ptr->m_dataset->createDefaultAxes();
492 492 }
493 493
494 494 /*!
495 495 Returns the legend object of the chart. Ownership stays with the chart.
496 496 */
497 497 QLegend *QChart::legend() const
498 498 {
499 499 return d_ptr->m_legend;
500 500 }
501 501
502 502 void QChart::setMinimumMargins(const QMargins &margins)
503 503 {
504 504 qWarning() << "QChart::setMinimumMargins is deprecated. Use QChart::setMargins instead.";
505 505 d_ptr->m_presenter->layout()->setMargins(margins);
506 506 }
507 507
508 508 QMargins QChart::minimumMargins() const
509 509 {
510 510 qWarning() << "QChart::minimumMargins is deprecated. Use QChart::margins instead.";
511 511 return d_ptr->m_presenter->layout()->margins();
512 512 }
513 513
514 514 void QChart::setMargins(const QMargins &margins)
515 515 {
516 516 d_ptr->m_presenter->layout()->setMargins(margins);
517 517 }
518 518
519 519 QMargins QChart::margins() const
520 520 {
521 521 return d_ptr->m_presenter->layout()->margins();
522 522 }
523 523
524 524 QChart::ChartType QChart::chartType() const
525 525 {
526 526 return d_ptr->m_type;
527 527 }
528 528
529 529 /*!
530 530 Returns the the rectangle within which the drawing of the chart is done.
531 531 It does not include the area defined by margins.
532 532 */
533 533 QRectF QChart::plotArea() const
534 534 {
535 535 return d_ptr->m_presenter->geometry();
536 536 }
537 537
538 538 /*!
539 539 Sets the \a brush for the background of the plot area of the chart.
540 540
541 541 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
542 542 */
543 543 void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
544 544 {
545 545 d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
546 546 }
547 547
548 548 /*!
549 549 Returns the brush for the background of the plot area of the chart.
550 550
551 551 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
552 552 */
553 553 QBrush QChart::plotAreaBackgroundBrush() const
554 554 {
555 555 return d_ptr->m_presenter->plotAreaBackgroundBrush();
556 556 }
557 557
558 558 /*!
559 559 Sets the \a pen for the background of the plot area of the chart.
560 560
561 561 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
562 562 */
563 563 void QChart::setPlotAreaBackgroundPen(const QPen &pen)
564 564 {
565 565 d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
566 566 }
567 567
568 568 /*!
569 569 Returns the pen for the background of the plot area of the chart.
570 570
571 571 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
572 572 */
573 573 QPen QChart::plotAreaBackgroundPen() const
574 574 {
575 575 return d_ptr->m_presenter->plotAreaBackgroundPen();
576 576 }
577 577
578 578 void QChart::setPlotAreaBackgroundVisible(bool visible)
579 579 {
580 580 d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
581 581 }
582 582
583 583 bool QChart::isPlotAreaBackgroundVisible() const
584 584 {
585 585 return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
586 586 }
587 587
588 588 void QChart::setLocalizeNumbers(bool localize)
589 589 {
590 590 d_ptr->m_presenter->setLocalizeNumbers(localize);
591 591 }
592 592
593 593 bool QChart::localizeNumbers() const
594 594 {
595 595 return d_ptr->m_presenter->localizeNumbers();
596 596 }
597 597
598 598 void QChart::setLocale(const QLocale &locale)
599 599 {
600 600 d_ptr->m_presenter->setLocale(locale);
601 601 }
602 602
603 603 QLocale QChart::locale() const
604 604 {
605 605 return d_ptr->m_presenter->locale();
606 606 }
607 607
608 608 void QChart::setAnimationOptions(AnimationOptions options)
609 609 {
610 610 d_ptr->m_presenter->setAnimationOptions(options);
611 611 }
612 612
613 613 QChart::AnimationOptions QChart::animationOptions() const
614 614 {
615 615 return d_ptr->m_presenter->animationOptions();
616 616 }
617 617
618 618 /*!
619 619 Scrolls the visible area of the chart by the distance defined in the \a dx and \a dy.
620 620
621 621 For polar charts, \a dx indicates the angle along angular axis instead of distance.
622 622 */
623 623 void QChart::scroll(qreal dx, qreal dy)
624 624 {
625 625 d_ptr->scroll(dx,dy);
626 626 }
627 627
628 628 void QChart::setBackgroundVisible(bool visible)
629 629 {
630 630 d_ptr->m_presenter->setBackgroundVisible(visible);
631 631 }
632 632
633 633 bool QChart::isBackgroundVisible() const
634 634 {
635 635 return d_ptr->m_presenter->isBackgroundVisible();
636 636 }
637 637
638 638 void QChart::setDropShadowEnabled(bool enabled)
639 639 {
640 640 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
641 641 }
642 642
643 643 bool QChart::isDropShadowEnabled() const
644 644 {
645 645 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
646 646 }
647 647
648 648 void QChart::setBackgroundRoundness(qreal diameter)
649 649 {
650 650 d_ptr->m_presenter->setBackgroundRoundness(diameter);
651 651 }
652 652
653 653 qreal QChart::backgroundRoundness() const
654 654 {
655 655 return d_ptr->m_presenter->backgroundRoundness();
656 656 }
657 657
658 658 /*!
659 659 Returns all series that are added to the chart.
660 660
661 661 \sa addSeries(), removeSeries(), removeAllSeries()
662 662 */
663 663 QList<QAbstractSeries *> QChart::series() const
664 664 {
665 665 return d_ptr->m_dataset->series();
666 666 }
667 667
668 668 /*!
669 669 Adds the \a axis to the chart and attaches it to the \a series as a bottom-aligned horizontal axis.
670 670 The chart takes ownership of both the \a axis and the \a series.
671 671 Any horizontal axes previously attached to the \a series are deleted.
672 672
673 673 \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
674 674 */
675 675 void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
676 676 {
677 677 QList<QAbstractAxis*> list = axes(Qt::Horizontal, series);
678 678
679 679 foreach (QAbstractAxis* a, list) {
680 680 d_ptr->m_dataset->removeAxis(a);
681 681 delete a;
682 682 }
683 683
684 684 if (!d_ptr->m_dataset->axes().contains(axis))
685 685 d_ptr->m_dataset->addAxis(axis, Qt::AlignBottom);
686 686 d_ptr->m_dataset->attachAxis(series, axis);
687 687 }
688 688
689 689 /*!
690 690 Adds the \a axis to the chart and attaches it to the \a series as a left-aligned vertical axis.
691 691 The chart takes ownership of both the \a axis and the \a series.
692 692 Any vertical axes previously attached to the \a series are deleted.
693 693
694 694 \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
695 695 */
696 696 void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
697 697 {
698 698 QList<QAbstractAxis*> list = axes(Qt::Vertical, series);
699 699
700 700 foreach (QAbstractAxis* a, list) {
701 701 d_ptr->m_dataset->removeAxis(a);
702 702 delete a;
703 703 }
704 704
705 705 if (!d_ptr->m_dataset->axes().contains(axis))
706 706 d_ptr->m_dataset->addAxis(axis, Qt::AlignLeft);
707 707 d_ptr->m_dataset->attachAxis(series, axis);
708 708 }
709 709
710 710 /*!
711 711 Adds the \a axis to the chart with \a alignment. The chart takes the ownership of the axis.
712 712
713 713 \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
714 714 */
715 715 void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
716 716 {
717 717 d_ptr->m_dataset->addAxis(axis, alignment);
718 718 }
719 719
720 720 /*!
721 721 Removes the \a axis from the chart.
722 722 The chart releases its ownership of the specified \a axis object.
723 723
724 724 \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
725 725 */
726 726 void QChart::removeAxis(QAbstractAxis *axis)
727 727 {
728 728 d_ptr->m_dataset->removeAxis(axis);
729 729 }
730 730
731 731 /*!
732 732 Returns the value in the \a series domain that corresponds to the \a position relative to chart widget.
733 733 */
734 734 QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
735 735 {
736 736 return d_ptr->m_dataset->mapToValue(position, series);
737 737 }
738 738
739 739 /*!
740 740 Returns the position on the chart widget that corresponds to the \a value in the \a series domain.
741 741 */
742 742 QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
743 743 {
744 744 return d_ptr->m_dataset->mapToPosition(value, series);
745 745 }
746 746
747 747 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
748 748
749 749 QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
750 750 q_ptr(q),
751 751 m_legend(0),
752 752 m_dataset(new ChartDataSet(q)),
753 753 m_presenter(new ChartPresenter(q, type)),
754 754 m_themeManager(new ChartThemeManager(q)),
755 755 m_type(type)
756 756 {
757 757 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
758 758 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
759 759 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
760 760 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
761 761 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
762 762 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
763 763 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
764 764 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
765 765 }
766 766
767 767 QChartPrivate::~QChartPrivate()
768 768 {
769 769 }
770 770
771 771 // Hackish solution to the problem of explicitly assigning the default pen/brush/font
772 772 // to a series or axis and having theme override it:
773 773 // Initialize pens, brushes, and fonts to something nobody is likely to ever use,
774 774 // so that default theme initialization will always set these properly.
775 775 QPen &QChartPrivate::defaultPen()
776 776 {
777 777 static QPen defaultPen(QColor(1, 2, 0), 0.93247536);
778 778 return defaultPen;
779 779 }
780 780
781 781 QBrush &QChartPrivate::defaultBrush()
782 782 {
783 783 static QBrush defaultBrush(QColor(1, 2, 0), Qt::Dense7Pattern);
784 784 return defaultBrush;
785 785 }
786 786
787 787 QFont &QChartPrivate::defaultFont()
788 788 {
789 789 static bool defaultFontInitialized(false);
790 790 static QFont defaultFont;
791 791 if (!defaultFontInitialized) {
792 792 defaultFont.setPointSizeF(8.34563465);
793 793 defaultFontInitialized = true;
794 794 }
795 795 return defaultFont;
796 796 }
797 797
798 798 void QChartPrivate::init()
799 799 {
800 800 m_legend = new LegendScroller(q_ptr);
801 801 q_ptr->setTheme(QChart::ChartThemeLight);
802 802 q_ptr->setLayout(m_presenter->layout());
803 803 }
804 804
805 805 void QChartPrivate::zoomIn(qreal factor)
806 806 {
807 807 QRectF rect = m_presenter->geometry();
808 808 rect.setWidth(rect.width() / factor);
809 809 rect.setHeight(rect.height() / factor);
810 810 rect.moveCenter(m_presenter->geometry().center());
811 811 zoomIn(rect);
812 812 }
813 813
814 814 void QChartPrivate::zoomIn(const QRectF &rect)
815 815 {
816 816 if (!rect.isValid())
817 817 return;
818 818
819 819 QRectF r = rect.normalized();
820 820 const QRectF geometry = m_presenter->geometry();
821 821 r.translate(-geometry.topLeft());
822 822
823 823 if (!r.isValid())
824 824 return;
825 825
826 826 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
827 827 m_presenter->setState(ChartPresenter::ZoomInState,zoomPoint);
828 828 m_dataset->zoomInDomain(r);
829 829 m_presenter->setState(ChartPresenter::ShowState,QPointF());
830 830
831 831 }
832 832
833 833 void QChartPrivate::zoomReset()
834 834 {
835 835 m_dataset->zoomResetDomain();
836 836 }
837 837
838 838 bool QChartPrivate::isZoomed()
839 839 {
840 840 return m_dataset->isZoomedDomain();
841 841 }
842 842
843 843 void QChartPrivate::zoomOut(qreal factor)
844 844 {
845 845 const QRectF geometry = m_presenter->geometry();
846 846
847 847 QRectF r;
848 848 r.setSize(geometry.size() / factor);
849 849 r.moveCenter(QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
850 850 if (!r.isValid())
851 851 return;
852 852
853 853 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
854 854 m_presenter->setState(ChartPresenter::ZoomOutState,zoomPoint);
855 855 m_dataset->zoomOutDomain(r);
856 856 m_presenter->setState(ChartPresenter::ShowState,QPointF());
857 857 }
858 858
859 859 void QChartPrivate::scroll(qreal dx, qreal dy)
860 860 {
861 861 if (dx < 0) m_presenter->setState(ChartPresenter::ScrollLeftState,QPointF());
862 862 if (dx > 0) m_presenter->setState(ChartPresenter::ScrollRightState,QPointF());
863 863 if (dy < 0) m_presenter->setState(ChartPresenter::ScrollUpState,QPointF());
864 864 if (dy > 0) m_presenter->setState(ChartPresenter::ScrollDownState,QPointF());
865 865
866 866 m_dataset->scrollDomain(dx, dy);
867 867 m_presenter->setState(ChartPresenter::ShowState,QPointF());
868 868 }
869 869
870 870 #include "moc_qchart.cpp"
871 871
872 872 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now