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 const auto series = d_ptr->m_dataset->series();
278 for (QAbstractSeries *s : series) {
279 removeSeries(series: s);
280 delete s;
281 }
282}
283
284/*!
285 Sets the brush that is used for painting the background of the chart area to \a brush.
286 */
287void QChart::setBackgroundBrush(const QBrush &brush)
288{
289 d_ptr->m_presenter->setBackgroundBrush(brush);
290}
291
292/*!
293 Gets the brush that is used for painting the background of the chart area.
294 */
295QBrush QChart::backgroundBrush() const
296{
297 return d_ptr->m_presenter->backgroundBrush();
298}
299
300/*!
301 Sets the pen that is used for painting the background of the chart area to \a pen.
302 */
303void QChart::setBackgroundPen(const QPen &pen)
304{
305 d_ptr->m_presenter->setBackgroundPen(pen);
306}
307
308/*!
309 Gets the pen that is used for painting the background of the chart area.
310 */
311QPen QChart::backgroundPen() const
312{
313 return d_ptr->m_presenter->backgroundPen();
314}
315
316void QChart::setTitle(const QString &title)
317{
318 d_ptr->m_presenter->setTitle(title);
319}
320
321QString QChart::title() const
322{
323 return d_ptr->m_presenter->title();
324}
325
326/*!
327 Sets the font that is used for drawing the chart title to \a font.
328 */
329void QChart::setTitleFont(const QFont &font)
330{
331 d_ptr->m_presenter->setTitleFont(font);
332}
333
334/*!
335 Gets the font that is used for drawing the chart title.
336 */
337QFont QChart::titleFont() const
338{
339 return d_ptr->m_presenter->titleFont();
340}
341
342/*!
343 Sets the brush used for drawing the title text to \a brush.
344 */
345void QChart::setTitleBrush(const QBrush &brush)
346{
347 d_ptr->m_presenter->setTitleBrush(brush);
348}
349
350/*!
351 Returns the brush used for drawing the title text.
352 */
353QBrush QChart::titleBrush() const
354{
355 return d_ptr->m_presenter->titleBrush();
356}
357
358void QChart::setTheme(QChart::ChartTheme theme)
359{
360 d_ptr->m_themeManager->setTheme(theme);
361}
362
363QChart::ChartTheme QChart::theme() const
364{
365 return d_ptr->m_themeManager->theme()->id();
366}
367
368/*!
369 Zooms into the view by a factor of two.
370 */
371void QChart::zoomIn()
372{
373 d_ptr->zoomIn(factor: 2.0);
374}
375
376/*!
377 Zooms into the view to a maximum level at which the rectangle \a rect is still
378 fully visible.
379 \note Applying a zoom may modify properties of attached axes, for instance QAbstractAxis::min
380 and QAbstractAxis::max.
381 \note This is not supported for polar charts.
382 */
383void QChart::zoomIn(const QRectF &rect)
384{
385 if (d_ptr->m_type == QChart::ChartTypePolar)
386 return;
387 d_ptr->zoomIn(rect);
388}
389
390/*!
391 Zooms out of the view by a factor of two.
392 \note This will do nothing if the result would contain an invalid logarithmic axis range.
393 */
394void QChart::zoomOut()
395{
396 d_ptr->zoomOut(factor: 2.0);
397}
398
399/*!
400 Zooms into the view by the custom factor \a factor.
401
402 A factor over 1.0 zooms into the view and a factor between 0.0 and 1.0 zooms
403 out of it.
404 */
405void QChart::zoom(qreal factor)
406{
407 if (qFuzzyCompare(p1: factor, p2: 0))
408 return;
409
410 if (qFuzzyCompare(p1: factor, p2: (qreal)1.0))
411 return;
412
413 if (factor < 0)
414 return;
415
416 if (factor > 1.0)
417 d_ptr->zoomIn(factor);
418 else
419 d_ptr->zoomOut(factor: 1.0 / factor);
420}
421
422
423/*!
424 Resets the series domains to what they were before any zoom method was called.
425
426 \note This will also reset scrolling and explicit axis range settings specified between
427 the first zoom operation and calling this method. If no zoom operation has been
428 performed, this method does nothing.
429 */
430void QChart::zoomReset()
431{
432 d_ptr->zoomReset();
433}
434
435/*!
436 Returns \c true if any series has a zoomed domain.
437 */
438bool QChart::isZoomed()
439{
440 return d_ptr->isZoomed();
441}
442
443/*!
444 \deprecated
445 Use axes() instead.
446
447 Returns a pointer to the horizontal axis attached to the specified \a series.
448 If no series is specified, the first horizontal axis added to the chart is returned.
449
450 \sa addAxis(), QAbstractSeries::attachAxis()
451 */
452QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
453{
454 QList<QAbstractAxis *> axisList = axes(orientation: Qt::Horizontal, series);
455 if (axisList.size())
456 return axisList[0];
457 return 0;
458}
459
460/*!
461 \deprecated
462 Use axes() instead.
463
464 Returns a pointer to the vertical axis attached to the specified \a series.
465 If no series is specified, the first vertical axis added to the chart is returned.
466
467 \sa addAxis(), QAbstractSeries::attachAxis()
468 */
469QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
470{
471 QList<QAbstractAxis *> axisList = axes(orientation: Qt::Vertical, series);
472 if (axisList.size())
473 return axisList[0];
474 return 0;
475}
476
477/*!
478 Returns the axes attached to the series \a series with the orientation specified
479 by \a orientation. If no series is specified, all axes added to the chart with
480 the specified orientation are returned.
481
482 \sa addAxis(), createDefaultAxes()
483 */
484QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
485{
486 QList<QAbstractAxis *> result ;
487
488 if (series) {
489 const auto axes = series->attachedAxes();
490 for (QAbstractAxis *axis : axes) {
491 if (orientation.testFlag(flag: axis->orientation()))
492 result << axis;
493 }
494 } else {
495 const auto axes = d_ptr->m_dataset->axes();
496 for (QAbstractAxis *axis : axes) {
497 if (orientation.testFlag(flag: axis->orientation()) && !result.contains(t: axis))
498 result << axis;
499 }
500 }
501
502 return result;
503}
504
505/*!
506 Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
507 the chart will be deleted.
508
509 \note This function has to be called after all series have been added to the chart. The axes created by this function
510 will NOT get automatically attached to any series added to the chart after this function has been called.
511 A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
512 if there are other series with properly attached axes also present.
513
514 \table
515 \header
516 \li Series type
517 \li Horizontal axis (X)
518 \li Vertical axis (Y)
519 \row
520 \li QXYSeries
521 \li QValueAxis
522 \li QValueAxis
523 \row
524 \li QBarSeries
525 \li QBarCategoryAxis
526 \li QValueAxis
527 \row
528 \li QPieSeries
529 \li None
530 \li None
531 \endtable
532
533 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.
534 If there are several series of different types added to the chart, then each series gets its own axes pair.
535
536 The axes specific to the series can be later obtained from the chart by providing the series
537 as the parameter for the axes() function call.
538 QPieSeries does not create any axes.
539
540 \sa axes(), QAbstractSeries::attachAxis()
541 */
542void QChart::createDefaultAxes()
543{
544 d_ptr->m_dataset->createDefaultAxes();
545}
546
547/*!
548 Returns the legend object of the chart. Ownership stays with the chart.
549 */
550QLegend *QChart::legend() const
551{
552 return d_ptr->m_legend;
553}
554
555void QChart::setMargins(const QMargins &margins)
556{
557 d_ptr->m_presenter->layout()->setMargins(margins);
558}
559
560QMargins QChart::margins() const
561{
562 return d_ptr->m_presenter->layout()->margins();
563}
564
565QChart::ChartType QChart::chartType() const
566{
567 return d_ptr->m_type;
568}
569
570QRectF QChart::plotArea() const
571{
572 return d_ptr->m_presenter->geometry();
573}
574
575void QChart::setPlotArea(const QRectF &rect)
576{
577 d_ptr->m_presenter->setFixedGeometry(rect);
578}
579
580/*!
581 Sets the brush used to fill the background of the plot area of the chart to \a brush.
582
583 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
584 */
585void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
586{
587 d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
588}
589
590/*!
591 Returns the brush used to fill the background of the plot area of the chart.
592
593 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
594 */
595QBrush QChart::plotAreaBackgroundBrush() const
596{
597 return d_ptr->m_presenter->plotAreaBackgroundBrush();
598}
599
600/*!
601 Sets the pen used to draw the background of the plot area of the chart to \a pen.
602
603 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
604 */
605void QChart::setPlotAreaBackgroundPen(const QPen &pen)
606{
607 d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
608}
609
610/*!
611 Returns the pen used to draw the background of the plot area of the chart.
612
613 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
614 */
615QPen QChart::plotAreaBackgroundPen() const
616{
617 return d_ptr->m_presenter->plotAreaBackgroundPen();
618}
619
620void QChart::setPlotAreaBackgroundVisible(bool visible)
621{
622 d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
623}
624
625bool QChart::isPlotAreaBackgroundVisible() const
626{
627 return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
628}
629
630void QChart::setLocalizeNumbers(bool localize)
631{
632 d_ptr->m_presenter->setLocalizeNumbers(localize);
633}
634
635bool QChart::localizeNumbers() const
636{
637 return d_ptr->m_presenter->localizeNumbers();
638}
639
640void QChart::setLocale(const QLocale &locale)
641{
642 d_ptr->m_presenter->setLocale(locale);
643}
644
645QLocale QChart::locale() const
646{
647 return d_ptr->m_presenter->locale();
648}
649
650void QChart::setAnimationOptions(AnimationOptions options)
651{
652 d_ptr->m_presenter->setAnimationOptions(options);
653}
654
655QChart::AnimationOptions QChart::animationOptions() const
656{
657 return d_ptr->m_presenter->animationOptions();
658}
659
660void QChart::setAnimationDuration(int msecs)
661{
662 d_ptr->m_presenter->setAnimationDuration(msecs);
663}
664
665int QChart::animationDuration() const
666{
667 return d_ptr->m_presenter->animationDuration();
668}
669
670void QChart::setAnimationEasingCurve(const QEasingCurve &curve)
671{
672 d_ptr->m_presenter->setAnimationEasingCurve(curve);
673}
674
675QEasingCurve QChart::animationEasingCurve() const
676{
677 return d_ptr->m_presenter->animationEasingCurve();
678}
679
680/*!
681 Scrolls the visible area of the chart by the distance specified by \a dx and \a dy.
682
683 For polar charts, \a dx indicates the angle along the angular axis instead of distance.
684 */
685void QChart::scroll(qreal dx, qreal dy)
686{
687 d_ptr->scroll(dx,dy);
688}
689
690void QChart::setBackgroundVisible(bool visible)
691{
692 d_ptr->m_presenter->setBackgroundVisible(visible);
693}
694
695bool QChart::isBackgroundVisible() const
696{
697 return d_ptr->m_presenter->isBackgroundVisible();
698}
699
700void QChart::setDropShadowEnabled(bool enabled)
701{
702 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
703}
704
705bool QChart::isDropShadowEnabled() const
706{
707 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
708}
709
710void QChart::setBackgroundRoundness(qreal diameter)
711{
712 d_ptr->m_presenter->setBackgroundRoundness(diameter);
713}
714
715qreal QChart::backgroundRoundness() const
716{
717 return d_ptr->m_presenter->backgroundRoundness();
718}
719
720/*!
721 Returns all series that are added to the chart.
722
723 \sa addSeries(), removeSeries(), removeAllSeries()
724*/
725QList<QAbstractSeries *> QChart::series() const
726{
727 return d_ptr->m_dataset->series();
728}
729
730/*!
731 \deprecated
732 Use addAxis() instead.
733
734 Adds the axis \a axis to the chart and attaches it to the series \a series as a
735 bottom-aligned horizontal axis.
736 The chart takes ownership of both the axis and the series.
737 Any horizontal axes previously attached to the series are deleted.
738
739 \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
740*/
741void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
742{
743 const QList<QAbstractAxis*> list = axes(orientation: Qt::Horizontal, series);
744
745 for (QAbstractAxis *a : list) {
746 d_ptr->m_dataset->removeAxis(axis: a);
747 delete a;
748 }
749
750 if (!d_ptr->m_dataset->axes().contains(t: axis))
751 d_ptr->m_dataset->addAxis(axis, alignment: Qt::AlignBottom);
752 d_ptr->m_dataset->attachAxis(series, axis);
753}
754
755/*!
756 \deprecated
757 Use addAxis() instead.
758
759 Adds the axis \a axis to the chart and attaches it to the series \a series as a
760 left-aligned vertical axis.
761 The chart takes ownership of both the axis and the series.
762 Any vertical axes previously attached to the series are deleted.
763
764 \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
765*/
766void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
767{
768 const QList<QAbstractAxis*> list = axes(orientation: Qt::Vertical, series);
769
770 for (QAbstractAxis *a : list) {
771 d_ptr->m_dataset->removeAxis(axis: a);
772 delete a;
773 }
774
775 if (!d_ptr->m_dataset->axes().contains(t: axis))
776 d_ptr->m_dataset->addAxis(axis, alignment: Qt::AlignLeft);
777 d_ptr->m_dataset->attachAxis(series, axis);
778}
779
780/*!
781 Adds the axis \a axis to the chart aligned as specified by \a alignment.
782 The chart takes the ownership of the axis.
783
784 \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
785*/
786void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
787{
788 d_ptr->m_dataset->addAxis(axis, alignment);
789}
790
791/*!
792 Removes the axis \a axis from the chart.
793 The chart releases the ownership of the specified \a axis object.
794
795 \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
796*/
797void QChart::removeAxis(QAbstractAxis *axis)
798{
799 d_ptr->m_dataset->removeAxis(axis);
800}
801
802/*!
803 Returns the value in the series specified by \a series at the position
804 specified by \a position in a chart.
805*/
806QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
807{
808 return d_ptr->m_dataset->mapToValue(position, series);
809}
810
811/*!
812 Returns the position on the chart that corresponds to the value \a value in the
813 series specified by \a series.
814*/
815QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
816{
817 return d_ptr->m_dataset->mapToPosition(value, series);
818}
819
820//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
821
822QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
823 q_ptr(q),
824 m_legend(0),
825 m_dataset(new ChartDataSet(q)),
826 m_presenter(new ChartPresenter(q, type)),
827 m_themeManager(new ChartThemeManager(q)),
828 m_type(type)
829{
830 QObject::connect(sender: m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
831 QObject::connect(sender: m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
832 QObject::connect(sender: m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), receiver: m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
833 QObject::connect(sender: m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), receiver: m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
834 QObject::connect(sender: m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), receiver: m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
835 QObject::connect(sender: m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), receiver: m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
836 QObject::connect(sender: m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), receiver: m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
837 QObject::connect(sender: m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), receiver: m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
838 QObject::connect(sender: m_presenter, signal: &ChartPresenter::plotAreaChanged, context: q, slot: &QChart::plotAreaChanged);
839}
840
841QChartPrivate::~QChartPrivate()
842{
843 delete m_themeManager;
844}
845
846// Hackish solution to the problem of explicitly assigning the default pen/brush/font
847// to a series or axis and having theme override it:
848// Initialize pens, brushes, and fonts to something nobody is likely to ever use,
849// so that default theme initialization will always set these properly.
850QPen &QChartPrivate::defaultPen()
851{
852 static QPen defaultPen(QColor(1, 2, 0), 0.93247536);
853 return defaultPen;
854}
855
856QBrush &QChartPrivate::defaultBrush()
857{
858 static QBrush defaultBrush(QColor(1, 2, 0), Qt::Dense7Pattern);
859 return defaultBrush;
860}
861
862QFont &QChartPrivate::defaultFont()
863{
864 static bool defaultFontInitialized(false);
865 static QFont defaultFont;
866 if (!defaultFontInitialized) {
867 defaultFont.setPointSizeF(8.34563465);
868 defaultFontInitialized = true;
869 }
870 return defaultFont;
871}
872
873void QChartPrivate::init()
874{
875 m_legend = new LegendScroller(q_ptr);
876 q_ptr->setTheme(QChart::ChartThemeLight);
877 q_ptr->setLayout(m_presenter->layout());
878}
879
880void QChartPrivate::zoomIn(qreal factor)
881{
882 QRectF rect = m_presenter->geometry();
883 rect.setWidth(rect.width() / factor);
884 rect.setHeight(rect.height() / factor);
885 rect.moveCenter(p: m_presenter->geometry().center());
886 zoomIn(rect);
887}
888
889void QChartPrivate::zoomIn(const QRectF &rect)
890{
891 if (!rect.isValid())
892 return;
893
894 QRectF r = rect.normalized();
895 const QRectF geometry = m_presenter->geometry();
896 r.translate(p: -geometry.topLeft());
897
898 if (!r.isValid())
899 return;
900
901 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
902 m_presenter->setState(state: ChartPresenter::ZoomInState,point: zoomPoint);
903 m_dataset->zoomInDomain(rect: r);
904 m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF());
905
906}
907
908void QChartPrivate::zoomReset()
909{
910 m_dataset->zoomResetDomain();
911}
912
913bool QChartPrivate::isZoomed()
914{
915 return m_dataset->isZoomedDomain();
916}
917
918void QChartPrivate::zoomOut(qreal factor)
919{
920 const QRectF geometry = m_presenter->geometry();
921
922 QRectF r;
923 r.setSize(geometry.size() / factor);
924 r.moveCenter(p: QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
925 if (!r.isValid())
926 return;
927
928 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
929 m_presenter->setState(state: ChartPresenter::ZoomOutState,point: zoomPoint);
930 m_dataset->zoomOutDomain(rect: r);
931 m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF());
932}
933
934void QChartPrivate::scroll(qreal dx, qreal dy)
935{
936 if (dx < 0) m_presenter->setState(state: ChartPresenter::ScrollLeftState,point: QPointF());
937 if (dx > 0) m_presenter->setState(state: ChartPresenter::ScrollRightState,point: QPointF());
938 if (dy < 0) m_presenter->setState(state: ChartPresenter::ScrollUpState,point: QPointF());
939 if (dy > 0) m_presenter->setState(state: ChartPresenter::ScrollDownState,point: QPointF());
940
941 m_dataset->scrollDomain(dx, dy);
942 m_presenter->setState(state: ChartPresenter::ShowState,point: QPointF());
943}
944
945QT_END_NAMESPACE
946
947#include "moc_qchart.cpp"
948

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