1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtCharts/QChart>
5#include <private/qchart_p.h>
6#include <private/legendscroller_p.h>
7#include <private/qlegend_p.h>
8#include <private/chartbackground_p.h>
9#include <QtCharts/QAbstractAxis>
10#include <private/abstractchartlayout_p.h>
11#include <private/charttheme_p.h>
12#include <private/chartpresenter_p.h>
13#include <private/chartdataset_p.h>
14#include <QtWidgets/QGraphicsScene>
15#include <QGraphicsSceneResizeEvent>
16
17QT_BEGIN_NAMESPACE
18
19/*!
20 \enum QChart::ChartTheme
21
22 This enum describes the theme used by the chart.
23
24 A theme is a built-in collection of UI style related settings applied to all
25 the visual elements of a chart, such as colors, pens, brushes, and fonts of
26 series, as well as axes, title, and legend. The \l {Charts with Widgets Gallery}
27 illustrates how to use themes.
28
29 \note Changing the theme will overwrite all customizations previously applied
30 to the series.
31
32 \value ChartThemeLight
33 The light theme, which is the default theme.
34 \value ChartThemeBlueCerulean
35 The cerulean blue theme.
36 \value ChartThemeDark
37 The dark theme.
38 \value ChartThemeBrownSand
39 The sand brown theme.
40 \value ChartThemeBlueNcs
41 The natural color system (NCS) blue theme.
42 \value ChartThemeHighContrast
43 The high contrast theme.
44 \value ChartThemeBlueIcy
45 The icy blue theme.
46 \value ChartThemeQt
47 The Qt theme.
48 */
49
50/*!
51 \enum QChart::AnimationOption
52
53 This enum describes the animations enabled in the chart.
54
55 \value NoAnimation
56 Animation is disabled in the chart. This is the default value.
57 \value GridAxisAnimations
58 Grid axis animation is enabled in the chart.
59 \value SeriesAnimations
60 Series animation is enabled in the chart.
61 \value AllAnimations
62 All animation types are enabled in the chart.
63 */
64
65/*!
66 \enum QChart::ChartType
67
68 This enum describes the chart type.
69
70 \value ChartTypeUndefined
71 The chart type is not defined.
72 \value ChartTypeCartesian
73 A cartesian chart.
74 \value ChartTypePolar
75 A polar chart.
76 */
77
78/*!
79 \class QChart
80 \inmodule QtCharts
81 \brief The QChart class manages the graphical representation of the chart's
82 series, legends, and axes.
83
84 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
85 representation of different types of series and other chart related objects like legend and
86 axes. To simply show a chart in a layout, the convenience class QChartView can be used
87 instead of QChart. In addition, line, spline, area, and scatter series can be presented as
88 polar charts by using the QPolarChart class.
89
90 \sa QChartView, QPolarChart
91 */
92
93/*!
94 \property QChart::animationOptions
95 \brief The animation options for the chart.
96
97 Animations are enabled or disabled based on this setting.
98 */
99
100/*!
101 \property QChart::animationDuration
102 \brief The duration of the animation for the chart.
103 */
104
105/*!
106 \property QChart::animationEasingCurve
107 \brief The easing curve of the animation for the chart.
108 */
109
110/*!
111 \property QChart::backgroundVisible
112 \brief Whether the chart background is visible.
113 \sa setBackgroundBrush(), setBackgroundPen(), plotAreaBackgroundVisible
114 */
115
116/*!
117 \property QChart::dropShadowEnabled
118 \brief Whether the background drop shadow effect is enabled.
119
120 If set to \c true, the background drop shadow effect is enabled. If set to \c false, it
121 is disabled.
122
123 \note The drop shadow effect depends on the theme, and therefore the setting may
124 change if the theme is changed.
125 */
126
127/*!
128 \property QChart::backgroundRoundness
129 \brief The diameter of the rounding circle at the corners of the chart background.
130 */
131
132/*!
133 \property QChart::margins
134 \brief The minimum margins allowed between the edge of the chart rectangle and
135 the plot area.
136
137 The margins are used for drawing the title, axes, and legend.
138 */
139
140/*!
141 \property QChart::theme
142 \brief The theme used for the chart.
143 */
144
145/*!
146 \property QChart::title
147 \brief The title of the chart.
148
149 The title is shown as a headline on top of the chart. Chart titles support HTML formatting.
150 */
151
152/*!
153 \property QChart::chartType
154 \brief Whether the chart is a cartesian chart or a polar chart.
155
156 This property is set internally and it is read only.
157 \sa QPolarChart
158 */
159
160/*!
161 \property QChart::plotAreaBackgroundVisible
162 \brief Whether the chart plot area background is visible.
163
164 \note By default, the plot area background is invisible and the plot area uses
165 the general chart background.
166 \sa setPlotAreaBackgroundBrush(), setPlotAreaBackgroundPen(), backgroundVisible
167 */
168
169/*!
170 \property QChart::localizeNumbers
171 \brief Whether numbers are localized.
172
173 When \c{true}, all generated numbers appearing in various series and axis labels will be
174 localized using the QLocale set with the \l locale property.
175 When \c{false}, the \e C locale is always used.
176 Defaults to \c{false}.
177
178 \note This property does not affect QDateTimeAxis labels, which always use the QLocale set with
179 the locale property.
180
181 \sa locale
182*/
183
184/*!
185 \property QChart::locale
186 \brief The locale used to format various chart labels.
187
188 Labels are localized only when \l localizeNumbers is \c true, except for QDateTimeAxis
189 labels, which always use the QLocale set with this property.
190
191 Defaults to the application default locale at the time when the chart is constructed.
192
193 \sa localizeNumbers
194*/
195
196/*!
197 \property QChart::plotArea
198 \brief The rectangle within which the chart is drawn.
199
200 The plot area does not include the area defined by margins. By default this will resize if inside
201 a QChartView. If an explicit size is set for the plot area then it will respect this, to revert
202 back to the default behavior, then calling \c{setPlotArea(QRectF());} will achieve this.
203*/
204
205/*!
206 \internal
207 Constructs a chart object of \a type that is a child of \a parent.
208 The properties specified by \a wFlags are passed to the QGraphicsWidget constructor.
209 This constructor is called only by subclasses.
210*/
211QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags)
212 : QGraphicsWidget(parent, wFlags),
213 d_ptr(new QChartPrivate(this, type))
214{
215 d_ptr->init();
216}
217
218/*!
219 Constructs a chart object that is a child of \a parent.
220 The properties specified by \a wFlags are passed to the QGraphicsWidget constructor.
221 */
222QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
223 : QGraphicsWidget(parent, wFlags),
224 d_ptr(new QChartPrivate(this, ChartTypeCartesian))
225{
226 d_ptr->init();
227}
228
229/*!
230 Deletes the chart object and its children, such as the series and axis objects added to it.
231 */
232QChart::~QChart()
233{
234 //start by deleting dataset, it will remove all series and axes
235 delete d_ptr->m_dataset;
236 d_ptr->m_dataset = 0;
237}
238
239/*!
240 Adds the series \a series to the chart and takes ownership of it.
241
242 \note A newly added series is not attached to any axes by default, not even those that
243 might have been created for the chart
244 using createDefaultAxes() before the series was added to the chart. If no axes are attached to
245 the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges
246 that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other
247 series that have properly attached axes, so always make sure you either call createDefaultAxes() after
248 a series has been added or explicitly attach axes for the series.
249
250 \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis()
251 */
252void QChart::addSeries(QAbstractSeries *series)
253{
254 Q_ASSERT(series);
255 d_ptr->m_dataset->addSeries(series);
256}
257
258/*!
259 Removes the series \a series from the chart.
260 The chart releases the ownership of the specified \a series object.
261
262 \sa addSeries(), removeAllSeries()
263 */
264void QChart::removeSeries(QAbstractSeries *series)
265{
266 Q_ASSERT(series);
267 d_ptr->m_dataset->removeSeries(series);
268}
269
270/*!
271 Removes and deletes all series objects that have been added to the chart.
272
273 \sa addSeries(), removeSeries()
274 */
275void QChart::removeAllSeries()
276{
277 foreach (QAbstractSeries *s , d_ptr->m_dataset->series()){
278 removeSeries(series: s);
279 delete s;
280 }
281}
282
283/*!
284 Sets the brush that is used for painting the background of the chart area to \a brush.
285 */
286void QChart::setBackgroundBrush(const QBrush &brush)
287{
288 d_ptr->m_presenter->setBackgroundBrush(brush);
289}
290
291/*!
292 Gets the brush that is used for painting the background of the chart area.
293 */
294QBrush QChart::backgroundBrush() const
295{
296 return d_ptr->m_presenter->backgroundBrush();
297}
298
299/*!
300 Sets the pen that is used for painting the background of the chart area to \a pen.
301 */
302void QChart::setBackgroundPen(const QPen &pen)
303{
304 d_ptr->m_presenter->setBackgroundPen(pen);
305}
306
307/*!
308 Gets the pen that is used for painting the background of the chart area.
309 */
310QPen QChart::backgroundPen() const
311{
312 return d_ptr->m_presenter->backgroundPen();
313}
314
315void QChart::setTitle(const QString &title)
316{
317 d_ptr->m_presenter->setTitle(title);
318}
319
320QString QChart::title() const
321{
322 return d_ptr->m_presenter->title();
323}
324
325/*!
326 Sets the font that is used for drawing the chart title to \a font.
327 */
328void QChart::setTitleFont(const QFont &font)
329{
330 d_ptr->m_presenter->setTitleFont(font);
331}
332
333/*!
334 Gets the font that is used for drawing the chart title.
335 */
336QFont QChart::titleFont() const
337{
338 return d_ptr->m_presenter->titleFont();
339}
340
341/*!
342 Sets the brush used for drawing the title text to \a brush.
343 */
344void QChart::setTitleBrush(const QBrush &brush)
345{
346 d_ptr->m_presenter->setTitleBrush(brush);
347}
348
349/*!
350 Returns the brush used for drawing the title text.
351 */
352QBrush QChart::titleBrush() const
353{
354 return d_ptr->m_presenter->titleBrush();
355}
356
357void QChart::setTheme(QChart::ChartTheme theme)
358{
359 d_ptr->m_themeManager->setTheme(theme);
360}
361
362QChart::ChartTheme QChart::theme() const
363{
364 return d_ptr->m_themeManager->theme()->id();
365}
366
367/*!
368 Zooms into the view by a factor of two.
369 */
370void QChart::zoomIn()
371{
372 d_ptr->zoomIn(factor: 2.0);
373}
374
375/*!
376 Zooms into the view to a maximum level at which the rectangle \a rect is still
377 fully visible.
378 \note Applying a zoom may modify properties of attached axes, for instance QAbstractAxis::min
379 and QAbstractAxis::max.
380 \note This is not supported for polar charts.
381 */
382void QChart::zoomIn(const QRectF &rect)
383{
384 if (d_ptr->m_type == QChart::ChartTypePolar)
385 return;
386 d_ptr->zoomIn(rect);
387}
388
389/*!
390 Zooms out of the view by a factor of two.
391 \note This will do nothing if the result would contain an invalid logarithmic axis range.
392 */
393void QChart::zoomOut()
394{
395 d_ptr->zoomOut(factor: 2.0);
396}
397
398/*!
399 Zooms into the view by the custom factor \a factor.
400
401 A factor over 1.0 zooms into the view and a factor between 0.0 and 1.0 zooms
402 out of it.
403 */
404void QChart::zoom(qreal factor)
405{
406 if (qFuzzyCompare(p1: factor, p2: 0))
407 return;
408
409 if (qFuzzyCompare(p1: factor, p2: (qreal)1.0))
410 return;
411
412 if (factor < 0)
413 return;
414
415 if (factor > 1.0)
416 d_ptr->zoomIn(factor);
417 else
418 d_ptr->zoomOut(factor: 1.0 / factor);
419}
420
421
422/*!
423 Resets the series domains to what they were before any zoom method was called.
424
425 \note This will also reset scrolling and explicit axis range settings specified between
426 the first zoom operation and calling this method. If no zoom operation has been
427 performed, this method does nothing.
428 */
429void QChart::zoomReset()
430{
431 d_ptr->zoomReset();
432}
433
434/*!
435 Returns \c true if any series has a zoomed domain.
436 */
437bool QChart::isZoomed()
438{
439 return d_ptr->isZoomed();
440}
441
442/*!
443 \deprecated
444 Use axes() instead.
445
446 Returns a pointer to the horizontal axis attached to the specified \a series.
447 If no series is specified, the first horizontal axis added to the chart is returned.
448
449 \sa addAxis(), QAbstractSeries::attachAxis()
450 */
451QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
452{
453 QList<QAbstractAxis *> axisList = axes(orientation: Qt::Horizontal, series);
454 if (axisList.size())
455 return axisList[0];
456 return 0;
457}
458
459/*!
460 \deprecated
461 Use axes() instead.
462
463 Returns a pointer to the vertical axis attached to the specified \a series.
464 If no series is specified, the first vertical axis added to the chart is returned.
465
466 \sa addAxis(), QAbstractSeries::attachAxis()
467 */
468QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
469{
470 QList<QAbstractAxis *> axisList = axes(orientation: Qt::Vertical, series);
471 if (axisList.size())
472 return axisList[0];
473 return 0;
474}
475
476/*!
477 Returns the axes attached to the series \a series with the orientation specified
478 by \a orientation. If no series is specified, all axes added to the chart with
479 the specified orientation are returned.
480
481 \sa addAxis(), createDefaultAxes()
482 */
483QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
484{
485 QList<QAbstractAxis *> result ;
486
487 if (series) {
488 foreach (QAbstractAxis *axis, series->attachedAxes()){
489 if (orientation.testFlag(flag: axis->orientation()))
490 result << axis;
491 }
492 } else {
493 foreach (QAbstractAxis *axis, d_ptr->m_dataset->axes()){
494 if (orientation.testFlag(flag: axis->orientation()) && !result.contains(t: axis))
495 result << axis;
496 }
497 }
498
499 return result;
500}
501
502/*!
503 Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
504 the chart will be deleted.
505
506 \note This function has to be called after all series have been added to the chart. The axes created by this function
507 will NOT get automatically attached to any series added to the chart after this function has been called.
508 A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
509 if there are other series with properly attached axes also present.
510
511 \table
512 \header
513 \li Series type
514 \li Horizontal axis (X)
515 \li Vertical axis (Y)
516 \row
517 \li QXYSeries
518 \li QValueAxis
519 \li QValueAxis
520 \row
521 \li QBarSeries
522 \li QBarCategoryAxis
523 \li QValueAxis
524 \row
525 \li QPieSeries
526 \li None
527 \li None
528 \endtable
529
530 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.
531 If there are several series of different types added to the chart, then each series gets its own axes pair.
532
533 The axes specific to the series can be later obtained from the chart by providing the series
534 as the parameter for the axes() function call.
535 QPieSeries does not create any axes.
536
537 \sa axes(), QAbstractSeries::attachAxis()
538 */
539void QChart::createDefaultAxes()
540{
541 d_ptr->m_dataset->createDefaultAxes();
542}
543
544/*!
545 Returns the legend object of the chart. Ownership stays with the chart.
546 */
547QLegend *QChart::legend() const
548{
549 return d_ptr->m_legend;
550}
551
552void QChart::setMargins(const QMargins &margins)
553{
554 d_ptr->m_presenter->layout()->setMargins(margins);
555}
556
557QMargins QChart::margins() const
558{
559 return d_ptr->m_presenter->layout()->margins();
560}
561
562QChart::ChartType QChart::chartType() const
563{
564 return d_ptr->m_type;
565}
566
567QRectF QChart::plotArea() const
568{
569 return d_ptr->m_presenter->geometry();
570}
571
572void QChart::setPlotArea(const QRectF &rect)
573{
574 d_ptr->m_presenter->setFixedGeometry(rect);
575}
576
577/*!
578 Sets the brush used to fill the background of the plot area of the chart to \a brush.
579
580 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
581 */
582void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
583{
584 d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
585}
586
587/*!
588 Returns the brush used to fill the background of the plot area of the chart.
589
590 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
591 */
592QBrush QChart::plotAreaBackgroundBrush() const
593{
594 return d_ptr->m_presenter->plotAreaBackgroundBrush();
595}
596
597/*!
598 Sets the pen used to draw the background of the plot area of the chart to \a pen.
599
600 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
601 */
602void QChart::setPlotAreaBackgroundPen(const QPen &pen)
603{
604 d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
605}
606
607/*!
608 Returns the pen used to draw the background of the plot area of the chart.
609
610 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
611 */
612QPen QChart::plotAreaBackgroundPen() const
613{
614 return d_ptr->m_presenter->plotAreaBackgroundPen();
615}
616
617void QChart::setPlotAreaBackgroundVisible(bool visible)
618{
619 d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
620}
621
622bool QChart::isPlotAreaBackgroundVisible() const
623{
624 return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
625}
626
627void QChart::setLocalizeNumbers(bool localize)
628{
629 d_ptr->m_presenter->setLocalizeNumbers(localize);
630}
631
632bool QChart::localizeNumbers() const
633{
634 return d_ptr->m_presenter->localizeNumbers();
635}
636
637void QChart::setLocale(const QLocale &locale)
638{
639 d_ptr->m_presenter->setLocale(locale);
640}
641
642QLocale QChart::locale() const
643{
644 return d_ptr->m_presenter->locale();
645}
646
647void QChart::setAnimationOptions(AnimationOptions options)
648{
649 d_ptr->m_presenter->setAnimationOptions(options);
650}
651
652QChart::AnimationOptions QChart::animationOptions() const
653{
654 return d_ptr->m_presenter->animationOptions();
655}
656
657void QChart::setAnimationDuration(int msecs)
658{
659 d_ptr->m_presenter->setAnimationDuration(msecs);
660}
661
662int QChart::animationDuration() const
663{
664 return d_ptr->m_presenter->animationDuration();
665}
666
667void QChart::setAnimationEasingCurve(const QEasingCurve &curve)
668{
669 d_ptr->m_presenter->setAnimationEasingCurve(curve);
670}
671
672QEasingCurve QChart::animationEasingCurve() const
673{
674 return d_ptr->m_presenter->animationEasingCurve();
675}
676
677/*!
678 Scrolls the visible area of the chart by the distance specified by \a dx and \a dy.
679
680 For polar charts, \a dx indicates the angle along the angular axis instead of distance.
681 */
682void QChart::scroll(qreal dx, qreal dy)
683{
684 d_ptr->scroll(dx,dy);
685}
686
687void QChart::setBackgroundVisible(bool visible)
688{
689 d_ptr->m_presenter->setBackgroundVisible(visible);
690}
691
692bool QChart::isBackgroundVisible() const
693{
694 return d_ptr->m_presenter->isBackgroundVisible();
695}
696
697void QChart::setDropShadowEnabled(bool enabled)
698{
699 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
700}
701
702bool QChart::isDropShadowEnabled() const
703{
704 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
705}
706
707void QChart::setBackgroundRoundness(qreal diameter)
708{
709 d_ptr->m_presenter->setBackgroundRoundness(diameter);
710}
711
712qreal QChart::backgroundRoundness() const
713{
714 return d_ptr->m_presenter->backgroundRoundness();
715}
716
717/*!
718 Returns all series that are added to the chart.
719
720 \sa addSeries(), removeSeries(), removeAllSeries()
721*/
722QList<QAbstractSeries *> QChart::series() const
723{
724 return d_ptr->m_dataset->series();
725}
726
727/*!
728 \deprecated
729 Use addAxis() instead.
730
731 Adds the axis \a axis to the chart and attaches it to the series \a series as a
732 bottom-aligned horizontal axis.
733 The chart takes ownership of both the axis and the series.
734 Any horizontal axes previously attached to the series are deleted.
735
736 \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
737*/
738void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
739{
740 QList<QAbstractAxis*> list = axes(orientation: Qt::Horizontal, series);
741
742 foreach (QAbstractAxis* a, list) {
743 d_ptr->m_dataset->removeAxis(axis: a);
744 delete a;
745 }
746
747 if (!d_ptr->m_dataset->axes().contains(t: axis))
748 d_ptr->m_dataset->addAxis(axis, alignment: Qt::AlignBottom);
749 d_ptr->m_dataset->attachAxis(series, axis);
750}
751
752/*!
753 \deprecated
754 Use addAxis() instead.
755
756 Adds the axis \a axis to the chart and attaches it to the series \a series as a
757 left-aligned vertical axis.
758 The chart takes ownership of both the axis and the series.
759 Any vertical axes previously attached to the series are deleted.
760
761 \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
762*/
763void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
764{
765 QList<QAbstractAxis*> list = axes(orientation: Qt::Vertical, series);
766
767 foreach (QAbstractAxis* a, list) {
768 d_ptr->m_dataset->removeAxis(axis: a);
769 delete a;
770 }
771
772 if (!d_ptr->m_dataset->axes().contains(t: axis))
773 d_ptr->m_dataset->addAxis(axis, alignment: Qt::AlignLeft);
774 d_ptr->m_dataset->attachAxis(series, axis);
775}
776
777/*!
778 Adds the axis \a axis to the chart aligned as specified by \a alignment.
779 The chart takes the ownership of the axis.
780
781 \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
782*/
783void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
784{
785 d_ptr->m_dataset->addAxis(axis, alignment);
786}
787
788/*!
789 Removes the axis \a axis from the chart.
790 The chart releases the ownership of the specified \a axis object.
791
792 \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
793*/
794void QChart::removeAxis(QAbstractAxis *axis)
795{
796 d_ptr->m_dataset->removeAxis(axis);
797}
798
799/*!
800 Returns the value in the series specified by \a series at the position
801 specified by \a position in a chart.
802*/
803QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
804{
805 return d_ptr->m_dataset->mapToValue(position, series);
806}
807
808/*!
809 Returns the position on the chart that corresponds to the value \a value in the
810 series specified by \a series.
811*/
812QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
813{
814 return d_ptr->m_dataset->mapToPosition(value, series);
815}
816
817//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
818
819QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
820 q_ptr(q),
821 m_legend(0),
822 m_dataset(new ChartDataSet(q)),
823 m_presenter(new ChartPresenter(q, type)),
824 m_themeManager(new ChartThemeManager(q)),
825 m_type(type)
826{
827 QObject::connect(sender: m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
828 QObject::connect(sender: m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
829 QObject::connect(sender: m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), receiver: m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
830 QObject::connect(sender: m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), receiver: m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
831 QObject::connect(sender: m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
832 QObject::connect(sender: m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
833 QObject::connect(sender: m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), receiver: m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
834 QObject::connect(sender: m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), receiver: m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
835 QObject::connect(sender: m_presenter, signal: &ChartPresenter::plotAreaChanged, context: q, slot: &QChart::plotAreaChanged);
836}
837
838QChartPrivate::~QChartPrivate()
839{
840 delete m_themeManager;
841}
842
843// Hackish solution to the problem of explicitly assigning the default pen/brush/font
844// to a series or axis and having theme override it:
845// Initialize pens, brushes, and fonts to something nobody is likely to ever use,
846// so that default theme initialization will always set these properly.
847QPen &QChartPrivate::defaultPen()
848{
849 static QPen defaultPen(QColor(1, 2, 0), 0.93247536);
850 return defaultPen;
851}
852
853QBrush &QChartPrivate::defaultBrush()
854{
855 static QBrush defaultBrush(QColor(1, 2, 0), Qt::Dense7Pattern);
856 return defaultBrush;
857}
858
859QFont &QChartPrivate::defaultFont()
860{
861 static bool defaultFontInitialized(false);
862 static QFont defaultFont;
863 if (!defaultFontInitialized) {
864 defaultFont.setPointSizeF(8.34563465);
865 defaultFontInitialized = true;
866 }
867 return defaultFont;
868}
869
870void QChartPrivate::init()
871{
872 m_legend = new LegendScroller(q_ptr);
873 q_ptr->setTheme(QChart::ChartThemeLight);
874 q_ptr->setLayout(m_presenter->layout());
875}
876
877void QChartPrivate::zoomIn(qreal factor)
878{
879 QRectF rect = m_presenter->geometry();
880 rect.setWidth(rect.width() / factor);
881 rect.setHeight(rect.height() / factor);
882 rect.moveCenter(p: m_presenter->geometry().center());
883 zoomIn(rect);
884}
885
886void QChartPrivate::zoomIn(const QRectF &rect)
887{
888 if (!rect.isValid())
889 return;
890
891 QRectF r = rect.normalized();
892 const QRectF geometry = m_presenter->geometry();
893 r.translate(p: -geometry.topLeft());
894
895 if (!r.isValid())
896 return;
897
898 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
899 m_presenter->setState(state: ChartPresenter::ZoomInState,point: zoomPoint);
900 m_dataset->zoomInDomain(rect: r);
901 m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF());
902
903}
904
905void QChartPrivate::zoomReset()
906{
907 m_dataset->zoomResetDomain();
908}
909
910bool QChartPrivate::isZoomed()
911{
912 return m_dataset->isZoomedDomain();
913}
914
915void QChartPrivate::zoomOut(qreal factor)
916{
917 const QRectF geometry = m_presenter->geometry();
918
919 QRectF r;
920 r.setSize(geometry.size() / factor);
921 r.moveCenter(p: QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
922 if (!r.isValid())
923 return;
924
925 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
926 m_presenter->setState(state: ChartPresenter::ZoomOutState,point: zoomPoint);
927 m_dataset->zoomOutDomain(rect: r);
928 m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF());
929}
930
931void QChartPrivate::scroll(qreal dx, qreal dy)
932{
933 if (dx < 0) m_presenter->setState(state: ChartPresenter::ScrollLeftState,point: QPointF());
934 if (dx > 0) m_presenter->setState(state: ChartPresenter::ScrollRightState,point: QPointF());
935 if (dy < 0) m_presenter->setState(state: ChartPresenter::ScrollUpState,point: QPointF());
936 if (dy > 0) m_presenter->setState(state: ChartPresenter::ScrollDownState,point: QPointF());
937
938 m_dataset->scrollDomain(dx, dy);
939 m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF());
940}
941
942QT_END_NAMESPACE
943
944#include "moc_qchart.cpp"
945

source code of qtcharts/src/charts/qchart.cpp