##// END OF EJS Templates
Respect the devicePixelRatio when rendering the scene...
Andy Shaw -
r2859:e59db7a88a36
parent child
Show More
@@ -1,1240 +1,1242
1 /******************************************************************************
1 /******************************************************************************
2 **
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
4 ** Contact: http://www.qt.io/licensing/
5 **
5 **
6 ** This file is part of the Qt Charts module.
6 ** This file is part of the Qt Charts module.
7 **
7 **
8 ** $QT_BEGIN_LICENSE:COMM$
8 ** $QT_BEGIN_LICENSE:COMM$
9 **
9 **
10 ** Commercial License Usage
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** and conditions see http://www.qt.io/terms-conditions. For further
16 ** information use the contact form at http://www.qt.io/contact-us.
16 ** information use the contact form at http://www.qt.io/contact-us.
17 **
17 **
18 ** $QT_END_LICENSE$
18 ** $QT_END_LICENSE$
19 **
19 **
20 ******************************************************************************/
20 ******************************************************************************/
21
21
22 #include "declarativechart.h"
22 #include "declarativechart.h"
23 #include <QtGui/QPainter>
23 #include <QtGui/QPainter>
24 #include "declarativelineseries.h"
24 #include "declarativelineseries.h"
25 #include "declarativeareaseries.h"
25 #include "declarativeareaseries.h"
26 #include "declarativebarseries.h"
26 #include "declarativebarseries.h"
27 #include "declarativepieseries.h"
27 #include "declarativepieseries.h"
28 #include "declarativesplineseries.h"
28 #include "declarativesplineseries.h"
29 #include "declarativeboxplotseries.h"
29 #include "declarativeboxplotseries.h"
30 #include "declarativescatterseries.h"
30 #include "declarativescatterseries.h"
31 #include "declarativechartnode.h"
31 #include "declarativechartnode.h"
32 #include "declarativerendernode.h"
32 #include "declarativerendernode.h"
33 #include <QtCharts/QBarCategoryAxis>
33 #include <QtCharts/QBarCategoryAxis>
34 #include <QtCharts/QValueAxis>
34 #include <QtCharts/QValueAxis>
35 #include <QtCharts/QLogValueAxis>
35 #include <QtCharts/QLogValueAxis>
36 #include <QtCharts/QCategoryAxis>
36 #include <QtCharts/QCategoryAxis>
37 #include <private/qabstractseries_p.h>
37 #include <private/qabstractseries_p.h>
38 #include "declarativemargins.h"
38 #include "declarativemargins.h"
39 #include <private/chartdataset_p.h>
39 #include <private/chartdataset_p.h>
40 #include "declarativeaxes.h"
40 #include "declarativeaxes.h"
41 #include <private/qchart_p.h>
41 #include <private/qchart_p.h>
42 #include <private/chartpresenter_p.h>
42 #include <private/chartpresenter_p.h>
43 #include <QtCharts/QPolarChart>
43 #include <QtCharts/QPolarChart>
44
44
45 #ifndef QT_ON_ARM
45 #ifndef QT_ON_ARM
46 #include <QtCharts/QDateTimeAxis>
46 #include <QtCharts/QDateTimeAxis>
47 #endif
47 #endif
48
48
49 #include <QtWidgets/QGraphicsSceneMouseEvent>
49 #include <QtWidgets/QGraphicsSceneMouseEvent>
50 #include <QtWidgets/QGraphicsSceneHoverEvent>
50 #include <QtWidgets/QGraphicsSceneHoverEvent>
51 #include <QtWidgets/QApplication>
51 #include <QtWidgets/QApplication>
52 #include <QtCore/QTimer>
52 #include <QtCore/QTimer>
53 #include <QtCore/QThread>
53 #include <QtCore/QThread>
54
54
55 QT_CHARTS_BEGIN_NAMESPACE
55 QT_CHARTS_BEGIN_NAMESPACE
56
56
57 /*!
57 /*!
58 \qmltype ChartView
58 \qmltype ChartView
59 \instantiates DeclarativeChart
59 \instantiates DeclarativeChart
60 \inqmlmodule QtCharts
60 \inqmlmodule QtCharts
61
61
62 \brief Chart element.
62 \brief Chart element.
63
63
64 ChartView element is the parent that is responsible for showing different chart series types.
64 ChartView element is the parent that is responsible for showing different chart series types.
65
65
66 The following QML shows how to create a simple chart with one pie series:
66 The following QML shows how to create a simple chart with one pie series:
67 \snippet qmlpiechart/qml/qmlpiechart/main.qml 1
67 \snippet qmlpiechart/qml/qmlpiechart/main.qml 1
68 \snippet qmlpiechart/qml/qmlpiechart/main.qml 2
68 \snippet qmlpiechart/qml/qmlpiechart/main.qml 2
69 \snippet qmlpiechart/qml/qmlpiechart/main.qml 3
69 \snippet qmlpiechart/qml/qmlpiechart/main.qml 3
70
70
71 \beginfloatleft
71 \beginfloatleft
72 \image examples_qmlpiechart.png
72 \image examples_qmlpiechart.png
73 \endfloat
73 \endfloat
74 \clearfloat
74 \clearfloat
75 */
75 */
76
76
77 /*!
77 /*!
78 \qmlproperty Theme ChartView::theme
78 \qmlproperty Theme ChartView::theme
79 Theme defines the visual appearance of the chart, including for example colors, fonts, line
79 Theme defines the visual appearance of the chart, including for example colors, fonts, line
80 widths and chart background.
80 widths and chart background.
81 */
81 */
82
82
83 /*!
83 /*!
84 \qmlproperty Animation ChartView::animationOptions
84 \qmlproperty Animation ChartView::animationOptions
85 Animation configuration of the chart. One of ChartView.NoAnimation, ChartView.GridAxisAnimations,
85 Animation configuration of the chart. One of ChartView.NoAnimation, ChartView.GridAxisAnimations,
86 ChartView.SeriesAnimations or ChartView.AllAnimations.
86 ChartView.SeriesAnimations or ChartView.AllAnimations.
87 */
87 */
88
88
89 /*!
89 /*!
90 \qmlproperty int ChartView::animationDuration
90 \qmlproperty int ChartView::animationDuration
91 The duration of the animation for the chart.
91 The duration of the animation for the chart.
92 */
92 */
93
93
94 /*!
94 /*!
95 \qmlproperty easing ChartView::animationEasingCurve
95 \qmlproperty easing ChartView::animationEasingCurve
96 The easing curve of the animation for the chart.
96 The easing curve of the animation for the chart.
97 */
97 */
98
98
99 /*!
99 /*!
100 \qmlproperty Font ChartView::titleFont
100 \qmlproperty Font ChartView::titleFont
101 The title font of the chart.
101 The title font of the chart.
102
102
103 See the Qt documentation for more details of Font.
103 See the Qt documentation for more details of Font.
104 */
104 */
105
105
106 /*!
106 /*!
107 \qmlproperty string ChartView::title
107 \qmlproperty string ChartView::title
108 The title of the chart, shown on top of the chart.
108 The title of the chart, shown on top of the chart.
109 \sa ChartView::titleColor
109 \sa ChartView::titleColor
110 */
110 */
111
111
112 /*!
112 /*!
113 \qmlproperty color ChartView::titleColor
113 \qmlproperty color ChartView::titleColor
114 The color of the title text.
114 The color of the title text.
115 */
115 */
116
116
117 /*!
117 /*!
118 \qmlproperty Legend ChartView::legend
118 \qmlproperty Legend ChartView::legend
119 The legend of the chart. Legend lists all the series, pie slices and bar sets added on the chart.
119 The legend of the chart. Legend lists all the series, pie slices and bar sets added on the chart.
120 */
120 */
121
121
122 /*!
122 /*!
123 \qmlproperty int ChartView::count
123 \qmlproperty int ChartView::count
124 The count of series added to the chart.
124 The count of series added to the chart.
125 */
125 */
126
126
127 /*!
127 /*!
128 \qmlproperty color ChartView::backgroundColor
128 \qmlproperty color ChartView::backgroundColor
129 The color of the chart's background. By default background color is defined by chart theme.
129 The color of the chart's background. By default background color is defined by chart theme.
130 \sa ChartView::theme
130 \sa ChartView::theme
131 */
131 */
132
132
133 /*!
133 /*!
134 \qmlproperty real ChartView::backgroundRoundness
134 \qmlproperty real ChartView::backgroundRoundness
135 The diameter of the rounding circle at the corners of the chart background.
135 The diameter of the rounding circle at the corners of the chart background.
136 */
136 */
137
137
138 /*!
138 /*!
139 \qmlproperty color ChartView::plotAreaColor
139 \qmlproperty color ChartView::plotAreaColor
140 The color of the background of the chart's plot area. By default plot area background uses chart's
140 The color of the background of the chart's plot area. By default plot area background uses chart's
141 background color.
141 background color.
142 \sa ChartView::backgroundColor
142 \sa ChartView::backgroundColor
143 */
143 */
144
144
145 /*!
145 /*!
146 \qmlproperty list<AbstractAxis> ChartView::axes
146 \qmlproperty list<AbstractAxis> ChartView::axes
147 The axes of the ChartView.
147 The axes of the ChartView.
148 */
148 */
149
149
150 /*!
150 /*!
151 \qmlproperty bool ChartView::dropShadowEnabled
151 \qmlproperty bool ChartView::dropShadowEnabled
152 The chart's border drop shadow. Set to true to enable drop shadow.
152 The chart's border drop shadow. Set to true to enable drop shadow.
153 */
153 */
154
154
155 /*!
155 /*!
156 \qmlproperty rect ChartView::plotArea
156 \qmlproperty rect ChartView::plotArea
157 The area on the ChartView that is used for drawing series. This is the ChartView rect without the
157 The area on the ChartView that is used for drawing series. This is the ChartView rect without the
158 margins.
158 margins.
159 \sa ChartView::margins
159 \sa ChartView::margins
160 */
160 */
161
161
162 /*!
162 /*!
163 \qmlproperty Margins ChartView::margins
163 \qmlproperty Margins ChartView::margins
164 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
164 The minimum margins allowed between the outer bounds and the plotArea of the ChartView. Margins
165 area of ChartView is used for drawing title, axes and legend.
165 area of ChartView is used for drawing title, axes and legend.
166 */
166 */
167
167
168 /*!
168 /*!
169 \qmlproperty bool ChartView::localizeNumbers
169 \qmlproperty bool ChartView::localizeNumbers
170 \since QtCharts 2.0
170 \since QtCharts 2.0
171 When \c{true}, all generated numbers appearing in various series and axis labels will be
171 When \c{true}, all generated numbers appearing in various series and axis labels will be
172 localized using the default QLocale of the application, which defaults to the system locale.
172 localized using the default QLocale of the application, which defaults to the system locale.
173 When \c{false}, the "C" locale is always used.
173 When \c{false}, the "C" locale is always used.
174 Defaults to \c{false}.
174 Defaults to \c{false}.
175
175
176 \sa locale
176 \sa locale
177 */
177 */
178
178
179 /*!
179 /*!
180 \qmlproperty locale ChartView::locale
180 \qmlproperty locale ChartView::locale
181 \since QtCharts 2.0
181 \since QtCharts 2.0
182 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
182 Sets the locale used to format various chart labels when localizeNumbers is \c{true}.
183 This also determines the locale used to format DateTimeAxis labels regardless of
183 This also determines the locale used to format DateTimeAxis labels regardless of
184 localizeNumbers property.
184 localizeNumbers property.
185 Defaults to application default locale at the time the chart is constructed.
185 Defaults to application default locale at the time the chart is constructed.
186
186
187 \sa localizeNumbers
187 \sa localizeNumbers
188 */
188 */
189
189
190 /*!
190 /*!
191 \qmlmethod AbstractSeries ChartView::series(int index)
191 \qmlmethod AbstractSeries ChartView::series(int index)
192 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
192 Returns the series with \a index on the chart. This allows you to loop through the series of a chart together with
193 the count property of the chart.
193 the count property of the chart.
194 */
194 */
195
195
196 /*!
196 /*!
197 \qmlmethod AbstractSeries ChartView::series(string name)
197 \qmlmethod AbstractSeries ChartView::series(string name)
198 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
198 Returns the first series on the chart with \a name. If there is no series with that name, returns null.
199 */
199 */
200
200
201 /*!
201 /*!
202 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
202 \qmlmethod AbstractSeries ChartView::createSeries(SeriesType type, string name, AbstractAxis axisX, AbstractAxis axisY)
203 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
203 Creates a series object of \a type to the chart with name \a name, optional axis \a axisX and
204 optional axis \a axisY. For example:
204 optional axis \a axisY. For example:
205 \code
205 \code
206 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
206 // lineSeries is a LineSeries object that has already been added to the ChartView; re-use it's axes
207 var myAxisX = chartView.axisX(lineSeries);
207 var myAxisX = chartView.axisX(lineSeries);
208 var myAxisY = chartView.axisY(lineSeries);
208 var myAxisY = chartView.axisY(lineSeries);
209 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
209 var scatter = chartView.createSeries(ChartView.SeriesTypeScatter, "scatter series", myAxisX, myAxisY);
210 \endcode
210 \endcode
211 */
211 */
212
212
213 /*!
213 /*!
214 \qmlmethod ChartView::removeSeries(AbstractSeries series)
214 \qmlmethod ChartView::removeSeries(AbstractSeries series)
215 Removes the \a series from the chart. The series object is also destroyed.
215 Removes the \a series from the chart. The series object is also destroyed.
216 */
216 */
217
217
218 /*!
218 /*!
219 \qmlmethod ChartView::removeAllSeries()
219 \qmlmethod ChartView::removeAllSeries()
220 Removes all series from the chart. All the series objects are also destroyed.
220 Removes all series from the chart. All the series objects are also destroyed.
221 */
221 */
222
222
223 /*!
223 /*!
224 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
224 \qmlmethod Axis ChartView::axisX(AbstractSeries series)
225 The x-axis of the series.
225 The x-axis of the series.
226 */
226 */
227
227
228 /*!
228 /*!
229 \qmlmethod ChartView::setAxisX(AbstractAxis axis, AbstractSeries series)
229 \qmlmethod ChartView::setAxisX(AbstractAxis axis, AbstractSeries series)
230 Set the x-axis of the series.
230 Set the x-axis of the series.
231 */
231 */
232
232
233 /*!
233 /*!
234 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
234 \qmlmethod Axis ChartView::axisY(AbstractSeries series)
235 The y-axis of the series.
235 The y-axis of the series.
236 */
236 */
237
237
238 /*!
238 /*!
239 \qmlmethod ChartView::setAxisY(AbstractAxis axis, AbstractSeries series)
239 \qmlmethod ChartView::setAxisY(AbstractAxis axis, AbstractSeries series)
240 Set the y-axis of the series.
240 Set the y-axis of the series.
241 */
241 */
242
242
243 /*!
243 /*!
244 \qmlmethod ChartView::zoom(real factor)
244 \qmlmethod ChartView::zoom(real factor)
245 Zooms in by \a factor on the center of the chart.
245 Zooms in by \a factor on the center of the chart.
246
246
247 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
247 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
248 */
248 */
249
249
250 /*!
250 /*!
251 \qmlmethod ChartView::zoomIn()
251 \qmlmethod ChartView::zoomIn()
252 Zooms in the view by a factor of two.
252 Zooms in the view by a factor of two.
253 */
253 */
254
254
255 /*!
255 /*!
256 \qmlmethod ChartView::zoomIn(rect rectangle)
256 \qmlmethod ChartView::zoomIn(rect rectangle)
257 Zooms in the view to a maximum level at which \a rectangle is still fully visible.
257 Zooms in the view to a maximum level at which \a rectangle is still fully visible.
258 \note This is not supported for polar charts.
258 \note This is not supported for polar charts.
259 */
259 */
260
260
261 /*!
261 /*!
262 \qmlmethod ChartView::zoomOut()
262 \qmlmethod ChartView::zoomOut()
263 Zooms out the view by a factor of two.
263 Zooms out the view by a factor of two.
264 */
264 */
265
265
266 /*!
266 /*!
267 \qmlmethod ChartView::zoomReset()
267 \qmlmethod ChartView::zoomReset()
268 Resets the series domains to what they were before any zoom method was called.
268 Resets the series domains to what they were before any zoom method was called.
269 Note that this will also reset any scrolls and explicit axis range settings done between
269 Note that this will also reset any scrolls and explicit axis range settings done between
270 the first zoom operation and calling this method. If no zoom operation has been
270 the first zoom operation and calling this method. If no zoom operation has been
271 done, this method does nothing.
271 done, this method does nothing.
272 */
272 */
273
273
274 /*!
274 /*!
275 \qmlmethod ChartView::isZoomed()
275 \qmlmethod ChartView::isZoomed()
276 Returns true if any series has a zoomed domain.
276 Returns true if any series has a zoomed domain.
277 */
277 */
278
278
279 /*!
279 /*!
280 \qmlmethod ChartView::scrollLeft(real pixels)
280 \qmlmethod ChartView::scrollLeft(real pixels)
281 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
281 Scrolls to left by \a pixels. This is a convenience function that suits for example for key navigation.
282 */
282 */
283
283
284 /*!
284 /*!
285 \qmlmethod ChartView::scrollRight(real pixels)
285 \qmlmethod ChartView::scrollRight(real pixels)
286 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
286 Scrolls to right by \a pixels. This is a convenience function that suits for example for key navigation.
287 */
287 */
288
288
289 /*!
289 /*!
290 \qmlmethod ChartView::scrollUp(real pixels)
290 \qmlmethod ChartView::scrollUp(real pixels)
291 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
291 Scrolls up by \a pixels. This is a convenience function that suits for example for key navigation.
292 */
292 */
293
293
294 /*!
294 /*!
295 \qmlmethod ChartView::scrollDown(real pixels)
295 \qmlmethod ChartView::scrollDown(real pixels)
296 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
296 Scrolls down by \a pixels. This is a convenience function that suits for example for key navigation.
297 */
297 */
298
298
299 /*!
299 /*!
300 \qmlmethod point ChartView::mapToValue(point position, AbstractSeries series)
300 \qmlmethod point ChartView::mapToValue(point position, AbstractSeries series)
301 Returns the value in the \a series domain that corresponds to the \a position relative to the
301 Returns the value in the \a series domain that corresponds to the \a position relative to the
302 chart.
302 chart.
303 */
303 */
304
304
305 /*!
305 /*!
306 \qmlmethod point ChartView::mapToPosition(point value, AbstractSeries series)
306 \qmlmethod point ChartView::mapToPosition(point value, AbstractSeries series)
307 Returns the position on the chart that corresponds to the \a value in the \a series domain.
307 Returns the position on the chart that corresponds to the \a value in the \a series domain.
308 */
308 */
309
309
310 /*!
310 /*!
311 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
311 \qmlsignal ChartView::seriesAdded(AbstractSeries series)
312 The \a series has been added to the chart.
312 The \a series has been added to the chart.
313 */
313 */
314
314
315 /*!
315 /*!
316 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
316 \qmlsignal ChartView::seriesRemoved(AbstractSeries series)
317 The \a series has been removed from the chart. Please note that \a series is no longer a valid
317 The \a series has been removed from the chart. Please note that \a series is no longer a valid
318 object after the signal handler has completed.
318 object after the signal handler has completed.
319 */
319 */
320
320
321 DeclarativeChart::DeclarativeChart(QQuickItem *parent)
321 DeclarativeChart::DeclarativeChart(QQuickItem *parent)
322 : QQuickItem(parent)
322 : QQuickItem(parent)
323 {
323 {
324 initChart(QChart::ChartTypeCartesian);
324 initChart(QChart::ChartTypeCartesian);
325 }
325 }
326
326
327 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QQuickItem *parent)
327 DeclarativeChart::DeclarativeChart(QChart::ChartType type, QQuickItem *parent)
328 : QQuickItem(parent)
328 : QQuickItem(parent)
329 {
329 {
330 initChart(type);
330 initChart(type);
331 }
331 }
332
332
333 void DeclarativeChart::initChart(QChart::ChartType type)
333 void DeclarativeChart::initChart(QChart::ChartType type)
334 {
334 {
335 m_sceneImage = 0;
335 m_sceneImage = 0;
336 m_sceneImageDirty = false;
336 m_sceneImageDirty = false;
337 m_sceneImageNeedsClear = false;
337 m_sceneImageNeedsClear = false;
338 m_guiThreadId = QThread::currentThreadId();
338 m_guiThreadId = QThread::currentThreadId();
339 m_paintThreadId = 0;
339 m_paintThreadId = 0;
340 m_updatePending = false;
340 m_updatePending = false;
341
341
342 setFlag(ItemHasContents, true);
342 setFlag(ItemHasContents, true);
343
343
344 if (type == QChart::ChartTypePolar)
344 if (type == QChart::ChartTypePolar)
345 m_chart = new QPolarChart();
345 m_chart = new QPolarChart();
346 else
346 else
347 m_chart = new QChart();
347 m_chart = new QChart();
348
348
349 m_chart->d_ptr->m_presenter->glSetUseWidget(false);
349 m_chart->d_ptr->m_presenter->glSetUseWidget(false);
350 m_glXYDataManager = m_chart->d_ptr->m_dataset->glXYSeriesDataManager();
350 m_glXYDataManager = m_chart->d_ptr->m_dataset->glXYSeriesDataManager();
351
351
352 m_scene = new QGraphicsScene(this);
352 m_scene = new QGraphicsScene(this);
353 m_scene->addItem(m_chart);
353 m_scene->addItem(m_chart);
354
354
355 setAntialiasing(QQuickItem::antialiasing());
355 setAntialiasing(QQuickItem::antialiasing());
356 connect(m_scene, &QGraphicsScene::changed, this, &DeclarativeChart::sceneChanged);
356 connect(m_scene, &QGraphicsScene::changed, this, &DeclarativeChart::sceneChanged);
357 connect(this, &DeclarativeChart::needRender, this, &DeclarativeChart::renderScene,
357 connect(this, &DeclarativeChart::needRender, this, &DeclarativeChart::renderScene,
358 Qt::QueuedConnection);
358 Qt::QueuedConnection);
359 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
359 connect(this, SIGNAL(antialiasingChanged(bool)), this, SLOT(handleAntialiasingChanged(bool)));
360
360
361 setAcceptedMouseButtons(Qt::AllButtons);
361 setAcceptedMouseButtons(Qt::AllButtons);
362 setAcceptHoverEvents(true);
362 setAcceptHoverEvents(true);
363
363
364 m_margins = new DeclarativeMargins(this);
364 m_margins = new DeclarativeMargins(this);
365 m_margins->setTop(m_chart->margins().top());
365 m_margins->setTop(m_chart->margins().top());
366 m_margins->setLeft(m_chart->margins().left());
366 m_margins->setLeft(m_chart->margins().left());
367 m_margins->setRight(m_chart->margins().right());
367 m_margins->setRight(m_chart->margins().right());
368 m_margins->setBottom(m_chart->margins().bottom());
368 m_margins->setBottom(m_chart->margins().bottom());
369 connect(m_margins, SIGNAL(topChanged(int,int,int,int)),
369 connect(m_margins, SIGNAL(topChanged(int,int,int,int)),
370 this, SLOT(changeMargins(int,int,int,int)));
370 this, SLOT(changeMargins(int,int,int,int)));
371 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)),
371 connect(m_margins, SIGNAL(bottomChanged(int,int,int,int)),
372 this, SLOT(changeMargins(int,int,int,int)));
372 this, SLOT(changeMargins(int,int,int,int)));
373 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)),
373 connect(m_margins, SIGNAL(leftChanged(int,int,int,int)),
374 this, SLOT(changeMargins(int,int,int,int)));
374 this, SLOT(changeMargins(int,int,int,int)));
375 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)),
375 connect(m_margins, SIGNAL(rightChanged(int,int,int,int)),
376 this, SLOT(changeMargins(int,int,int,int)));
376 this, SLOT(changeMargins(int,int,int,int)));
377 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
377 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesAdded(QAbstractSeries*)));
378 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
378 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SIGNAL(seriesRemoved(QAbstractSeries*)));
379 connect(m_chart, &QChart::plotAreaChanged, this, &DeclarativeChart::plotAreaChanged);
379 connect(m_chart, &QChart::plotAreaChanged, this, &DeclarativeChart::plotAreaChanged);
380 }
380 }
381
381
382 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
382 void DeclarativeChart::handleSeriesAdded(QAbstractSeries *series)
383 {
383 {
384 emit seriesAdded(series);
384 emit seriesAdded(series);
385 }
385 }
386
386
387 void DeclarativeChart::changeMargins(int top, int bottom, int left, int right)
387 void DeclarativeChart::changeMargins(int top, int bottom, int left, int right)
388 {
388 {
389 m_chart->setMargins(QMargins(left, top, right, bottom));
389 m_chart->setMargins(QMargins(left, top, right, bottom));
390 emit marginsChanged();
390 emit marginsChanged();
391 }
391 }
392
392
393 DeclarativeChart::~DeclarativeChart()
393 DeclarativeChart::~DeclarativeChart()
394 {
394 {
395 delete m_chart;
395 delete m_chart;
396 delete m_sceneImage;
396 delete m_sceneImage;
397 }
397 }
398
398
399 void DeclarativeChart::childEvent(QChildEvent *event)
399 void DeclarativeChart::childEvent(QChildEvent *event)
400 {
400 {
401 if (event->type() == QEvent::ChildAdded) {
401 if (event->type() == QEvent::ChildAdded) {
402 if (qobject_cast<QAbstractSeries *>(event->child())) {
402 if (qobject_cast<QAbstractSeries *>(event->child())) {
403 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
403 m_chart->addSeries(qobject_cast<QAbstractSeries *>(event->child()));
404 }
404 }
405 }
405 }
406 }
406 }
407
407
408 void DeclarativeChart::componentComplete()
408 void DeclarativeChart::componentComplete()
409 {
409 {
410 foreach (QObject *child, children()) {
410 foreach (QObject *child, children()) {
411 if (qobject_cast<QAbstractSeries *>(child)) {
411 if (qobject_cast<QAbstractSeries *>(child)) {
412 // Add series to the chart
412 // Add series to the chart
413 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
413 QAbstractSeries *series = qobject_cast<QAbstractSeries *>(child);
414 m_chart->addSeries(series);
414 m_chart->addSeries(series);
415
415
416 // Connect to axis changed signals (unless this is a pie series)
416 // Connect to axis changed signals (unless this is a pie series)
417 if (!qobject_cast<DeclarativePieSeries *>(series)) {
417 if (!qobject_cast<DeclarativePieSeries *>(series)) {
418 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
418 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
419 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
419 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXTopSet(QAbstractAxis*)));
420 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
420 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
421 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
421 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
422 }
422 }
423
423
424 initializeAxes(series);
424 initializeAxes(series);
425 }
425 }
426 }
426 }
427
427
428 QQuickItem::componentComplete();
428 QQuickItem::componentComplete();
429 }
429 }
430
430
431 void DeclarativeChart::seriesAxisAttachHelper(QAbstractSeries *series, QAbstractAxis *axis,
431 void DeclarativeChart::seriesAxisAttachHelper(QAbstractSeries *series, QAbstractAxis *axis,
432 Qt::Orientations orientation,
432 Qt::Orientations orientation,
433 Qt::Alignment alignment)
433 Qt::Alignment alignment)
434 {
434 {
435 if (!series->attachedAxes().contains(axis)) {
435 if (!series->attachedAxes().contains(axis)) {
436 // Remove & delete old axes that are not attached to any other series
436 // Remove & delete old axes that are not attached to any other series
437 foreach (QAbstractAxis* oldAxis, m_chart->axes(orientation, series)) {
437 foreach (QAbstractAxis* oldAxis, m_chart->axes(orientation, series)) {
438 bool otherAttachments = false;
438 bool otherAttachments = false;
439 if (oldAxis != axis) {
439 if (oldAxis != axis) {
440 foreach (QAbstractSeries *oldSeries, m_chart->series()) {
440 foreach (QAbstractSeries *oldSeries, m_chart->series()) {
441 if (oldSeries != series && oldSeries->attachedAxes().contains(oldAxis)) {
441 if (oldSeries != series && oldSeries->attachedAxes().contains(oldAxis)) {
442 otherAttachments = true;
442 otherAttachments = true;
443 break;
443 break;
444 }
444 }
445 }
445 }
446 if (!otherAttachments) {
446 if (!otherAttachments) {
447 m_chart->removeAxis(oldAxis);
447 m_chart->removeAxis(oldAxis);
448 delete oldAxis;
448 delete oldAxis;
449 }
449 }
450 }
450 }
451 }
451 }
452 if (!m_chart->axes(orientation).contains(axis))
452 if (!m_chart->axes(orientation).contains(axis))
453 m_chart->addAxis(axis, alignment);
453 m_chart->addAxis(axis, alignment);
454
454
455 series->attachAxis(axis);
455 series->attachAxis(axis);
456 }
456 }
457 }
457 }
458
458
459 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
459 void DeclarativeChart::handleAxisXSet(QAbstractAxis *axis)
460 {
460 {
461 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
461 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
462 if (axis && s) {
462 if (axis && s) {
463 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignBottom);
463 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignBottom);
464 } else {
464 } else {
465 qWarning() << "Trying to set axisX to null.";
465 qWarning() << "Trying to set axisX to null.";
466 }
466 }
467 }
467 }
468
468
469 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
469 void DeclarativeChart::handleAxisXTopSet(QAbstractAxis *axis)
470 {
470 {
471 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
471 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
472 if (axis && s) {
472 if (axis && s) {
473 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignTop);
473 seriesAxisAttachHelper(s, axis, Qt::Horizontal, Qt::AlignTop);
474 } else {
474 } else {
475 qWarning() << "Trying to set axisXTop to null.";
475 qWarning() << "Trying to set axisXTop to null.";
476 }
476 }
477 }
477 }
478
478
479 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
479 void DeclarativeChart::handleAxisYSet(QAbstractAxis *axis)
480 {
480 {
481 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
481 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
482 if (axis && s) {
482 if (axis && s) {
483 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignLeft);
483 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignLeft);
484 } else {
484 } else {
485 qWarning() << "Trying to set axisY to null.";
485 qWarning() << "Trying to set axisY to null.";
486 }
486 }
487 }
487 }
488
488
489 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
489 void DeclarativeChart::handleAxisYRightSet(QAbstractAxis *axis)
490 {
490 {
491 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
491 QAbstractSeries *s = qobject_cast<QAbstractSeries *>(sender());
492 if (axis && s) {
492 if (axis && s) {
493 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignRight);
493 seriesAxisAttachHelper(s, axis, Qt::Vertical, Qt::AlignRight);
494 } else {
494 } else {
495 qWarning() << "Trying to set axisYRight to null.";
495 qWarning() << "Trying to set axisYRight to null.";
496 }
496 }
497 }
497 }
498
498
499 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
499 void DeclarativeChart::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
500 {
500 {
501 if (newGeometry.isValid()) {
501 if (newGeometry.isValid()) {
502 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
502 if (newGeometry.width() > 0 && newGeometry.height() > 0) {
503 m_chart->resize(newGeometry.width(), newGeometry.height());
503 m_chart->resize(newGeometry.width(), newGeometry.height());
504 }
504 }
505 }
505 }
506 QQuickItem::geometryChanged(newGeometry, oldGeometry);
506 QQuickItem::geometryChanged(newGeometry, oldGeometry);
507 }
507 }
508
508
509 QSGNode *DeclarativeChart::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
509 QSGNode *DeclarativeChart::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
510 {
510 {
511 DeclarativeChartNode *node = static_cast<DeclarativeChartNode *>(oldNode);
511 DeclarativeChartNode *node = static_cast<DeclarativeChartNode *>(oldNode);
512
512
513 if (!node) {
513 if (!node) {
514 node = new DeclarativeChartNode(window());
514 node = new DeclarativeChartNode(window());
515 connect(window(), &QQuickWindow::beforeRendering,
515 connect(window(), &QQuickWindow::beforeRendering,
516 node->glRenderNode(), &DeclarativeRenderNode::render);
516 node->glRenderNode(), &DeclarativeRenderNode::render);
517 }
517 }
518
518
519 const QRectF &bRect = boundingRect();
519 const QRectF &bRect = boundingRect();
520
520
521 // Update GL data
521 // Update GL data
522 if (m_glXYDataManager->dataMap().size() || m_glXYDataManager->mapDirty()) {
522 if (m_glXYDataManager->dataMap().size() || m_glXYDataManager->mapDirty()) {
523 const QRectF &plotArea = m_chart->plotArea();
523 const QRectF &plotArea = m_chart->plotArea();
524 const QSizeF &chartAreaSize = m_chart->size();
524 const QSizeF &chartAreaSize = m_chart->size();
525
525
526 // We can't use chart's plot area directly, as graphicscene has some internal minimum size
526 // We can't use chart's plot area directly, as graphicscene has some internal minimum size
527 const qreal normalizedX = plotArea.x() / chartAreaSize.width();
527 const qreal normalizedX = plotArea.x() / chartAreaSize.width();
528 const qreal normalizedY = plotArea.y() / chartAreaSize.height();
528 const qreal normalizedY = plotArea.y() / chartAreaSize.height();
529 const qreal normalizedWidth = plotArea.width() / chartAreaSize.width();
529 const qreal normalizedWidth = plotArea.width() / chartAreaSize.width();
530 const qreal normalizedHeight = plotArea.height() / chartAreaSize.height();
530 const qreal normalizedHeight = plotArea.height() / chartAreaSize.height();
531
531
532 QRectF adjustedPlotArea(normalizedX * bRect.width(),
532 QRectF adjustedPlotArea(normalizedX * bRect.width(),
533 normalizedY * bRect.height(),
533 normalizedY * bRect.height(),
534 normalizedWidth * bRect.width(),
534 normalizedWidth * bRect.width(),
535 normalizedHeight * bRect.height());
535 normalizedHeight * bRect.height());
536
536
537 const QSize &adjustedPlotSize = adjustedPlotArea.size().toSize();
537 const QSize &adjustedPlotSize = adjustedPlotArea.size().toSize();
538 if (adjustedPlotSize != node->glRenderNode()->textureSize())
538 if (adjustedPlotSize != node->glRenderNode()->textureSize())
539 node->glRenderNode()->setTextureSize(adjustedPlotSize);
539 node->glRenderNode()->setTextureSize(adjustedPlotSize);
540
540
541 node->glRenderNode()->setRect(adjustedPlotArea);
541 node->glRenderNode()->setRect(adjustedPlotArea);
542 node->glRenderNode()->setSeriesData(m_glXYDataManager->mapDirty(),
542 node->glRenderNode()->setSeriesData(m_glXYDataManager->mapDirty(),
543 m_glXYDataManager->dataMap());
543 m_glXYDataManager->dataMap());
544
544
545 // Clear dirty flags from original xy data
545 // Clear dirty flags from original xy data
546 m_glXYDataManager->clearAllDirty();
546 m_glXYDataManager->clearAllDirty();
547 }
547 }
548
548
549 // Copy chart (if dirty) to chart node
549 // Copy chart (if dirty) to chart node
550 if (m_sceneImageDirty) {
550 if (m_sceneImageDirty) {
551 node->createTextureFromImage(*m_sceneImage);
551 node->createTextureFromImage(*m_sceneImage);
552 m_sceneImageDirty = false;
552 m_sceneImageDirty = false;
553 }
553 }
554
554
555 node->setRect(bRect);
555 node->setRect(bRect);
556
556
557 return node;
557 return node;
558 }
558 }
559
559
560 void DeclarativeChart::sceneChanged(QList<QRectF> region)
560 void DeclarativeChart::sceneChanged(QList<QRectF> region)
561 {
561 {
562 const int count = region.size();
562 const int count = region.size();
563 const qreal limitSize = 0.01;
563 const qreal limitSize = 0.01;
564 if (count && !m_updatePending) {
564 if (count && !m_updatePending) {
565 qreal totalSize = 0.0;
565 qreal totalSize = 0.0;
566 for (int i = 0; i < count; i++) {
566 for (int i = 0; i < count; i++) {
567 const QRectF &reg = region.at(i);
567 const QRectF &reg = region.at(i);
568 totalSize += (reg.height() * reg.width());
568 totalSize += (reg.height() * reg.width());
569 if (totalSize >= limitSize)
569 if (totalSize >= limitSize)
570 break;
570 break;
571 }
571 }
572 // Ignore region updates that change less than small fraction of a pixel, as there is
572 // Ignore region updates that change less than small fraction of a pixel, as there is
573 // little point regenerating the image in these cases. These are typically cases
573 // little point regenerating the image in these cases. These are typically cases
574 // where OpenGL series are drawn to otherwise static chart.
574 // where OpenGL series are drawn to otherwise static chart.
575 if (totalSize >= limitSize) {
575 if (totalSize >= limitSize) {
576 m_updatePending = true;
576 m_updatePending = true;
577 // Do async render to avoid some unnecessary renders.
577 // Do async render to avoid some unnecessary renders.
578 emit needRender();
578 emit needRender();
579 } else {
579 } else {
580 // We do want to call update to trigger possible gl series updates.
580 // We do want to call update to trigger possible gl series updates.
581 update();
581 update();
582 }
582 }
583 }
583 }
584 }
584 }
585
585
586 void DeclarativeChart::renderScene()
586 void DeclarativeChart::renderScene()
587 {
587 {
588 m_updatePending = false;
588 m_updatePending = false;
589 m_sceneImageDirty = true;
589 m_sceneImageDirty = true;
590 QSize chartSize = m_chart->size().toSize();
590 QSize chartSize = m_chart->size().toSize();
591 if (!m_sceneImage || chartSize != m_sceneImage->size()) {
591 if (!m_sceneImage || chartSize != m_sceneImage->size()) {
592 delete m_sceneImage;
592 delete m_sceneImage;
593 m_sceneImage = new QImage(chartSize, QImage::Format_ARGB32);
593 qreal dpr = window() ? window()->devicePixelRatio() : 1.0;
594 m_sceneImage = new QImage(chartSize * dpr, QImage::Format_ARGB32);
595 m_sceneImage->setDevicePixelRatio(dpr);
594 m_sceneImageNeedsClear = true;
596 m_sceneImageNeedsClear = true;
595 }
597 }
596
598
597 if (m_sceneImageNeedsClear) {
599 if (m_sceneImageNeedsClear) {
598 m_sceneImage->fill(Qt::transparent);
600 m_sceneImage->fill(Qt::transparent);
599 // Don't clear the flag if chart background has any transparent element to it
601 // Don't clear the flag if chart background has any transparent element to it
600 if (m_chart->backgroundBrush().color().alpha() == 0xff && !m_chart->isDropShadowEnabled())
602 if (m_chart->backgroundBrush().color().alpha() == 0xff && !m_chart->isDropShadowEnabled())
601 m_sceneImageNeedsClear = false;
603 m_sceneImageNeedsClear = false;
602 }
604 }
603 QPainter painter(m_sceneImage);
605 QPainter painter(m_sceneImage);
604 if (antialiasing()) {
606 if (antialiasing()) {
605 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing
607 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing
606 | QPainter::SmoothPixmapTransform);
608 | QPainter::SmoothPixmapTransform);
607 }
609 }
608 QRect renderRect(QPoint(0, 0), chartSize);
610 QRect renderRect(QPoint(0, 0), chartSize);
609 m_scene->render(&painter, renderRect, renderRect);
611 m_scene->render(&painter, renderRect, renderRect);
610 update();
612 update();
611 }
613 }
612
614
613 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
615 void DeclarativeChart::mousePressEvent(QMouseEvent *event)
614 {
616 {
615 m_mousePressScenePoint = event->pos();
617 m_mousePressScenePoint = event->pos();
616 m_mousePressScreenPoint = event->globalPos();
618 m_mousePressScreenPoint = event->globalPos();
617 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
619 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
618 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
620 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
619 m_mousePressButton = event->button();
621 m_mousePressButton = event->button();
620 m_mousePressButtons = event->buttons();
622 m_mousePressButtons = event->buttons();
621
623
622 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
624 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
623 mouseEvent.setWidget(0);
625 mouseEvent.setWidget(0);
624 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
626 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
625 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
627 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
626 mouseEvent.setScenePos(m_mousePressScenePoint);
628 mouseEvent.setScenePos(m_mousePressScenePoint);
627 mouseEvent.setScreenPos(m_mousePressScreenPoint);
629 mouseEvent.setScreenPos(m_mousePressScreenPoint);
628 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
630 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
629 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
631 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
630 mouseEvent.setButtons(m_mousePressButtons);
632 mouseEvent.setButtons(m_mousePressButtons);
631 mouseEvent.setButton(m_mousePressButton);
633 mouseEvent.setButton(m_mousePressButton);
632 mouseEvent.setModifiers(event->modifiers());
634 mouseEvent.setModifiers(event->modifiers());
633 mouseEvent.setAccepted(false);
635 mouseEvent.setAccepted(false);
634
636
635 QApplication::sendEvent(m_scene, &mouseEvent);
637 QApplication::sendEvent(m_scene, &mouseEvent);
636 }
638 }
637
639
638 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
640 void DeclarativeChart::mouseReleaseEvent(QMouseEvent *event)
639 {
641 {
640 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
642 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
641 mouseEvent.setWidget(0);
643 mouseEvent.setWidget(0);
642 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
644 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
643 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
645 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
644 mouseEvent.setScenePos(event->pos());
646 mouseEvent.setScenePos(event->pos());
645 mouseEvent.setScreenPos(event->globalPos());
647 mouseEvent.setScreenPos(event->globalPos());
646 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
648 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
647 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
649 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
648 mouseEvent.setButtons(event->buttons());
650 mouseEvent.setButtons(event->buttons());
649 mouseEvent.setButton(event->button());
651 mouseEvent.setButton(event->button());
650 mouseEvent.setModifiers(event->modifiers());
652 mouseEvent.setModifiers(event->modifiers());
651 mouseEvent.setAccepted(false);
653 mouseEvent.setAccepted(false);
652
654
653 QApplication::sendEvent(m_scene, &mouseEvent);
655 QApplication::sendEvent(m_scene, &mouseEvent);
654
656
655 m_mousePressButtons = event->buttons();
657 m_mousePressButtons = event->buttons();
656 m_mousePressButton = Qt::NoButton;
658 m_mousePressButton = Qt::NoButton;
657 }
659 }
658
660
659 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
661 void DeclarativeChart::hoverMoveEvent(QHoverEvent *event)
660 {
662 {
661 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
663 // Convert hover move to mouse move, since we don't seem to get actual mouse move events.
662 // QGraphicsScene generates hover events from mouse move events, so we don't need
664 // QGraphicsScene generates hover events from mouse move events, so we don't need
663 // to pass hover events there.
665 // to pass hover events there.
664 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
666 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
665 mouseEvent.setWidget(0);
667 mouseEvent.setWidget(0);
666 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
668 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
667 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
669 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
668 mouseEvent.setScenePos(event->pos());
670 mouseEvent.setScenePos(event->pos());
669 // Hover events do not have global pos in them, and the screen position doesn't seem to
671 // Hover events do not have global pos in them, and the screen position doesn't seem to
670 // matter anyway in this use case, so just pass event pos instead of trying to
672 // matter anyway in this use case, so just pass event pos instead of trying to
671 // calculate the real screen position.
673 // calculate the real screen position.
672 mouseEvent.setScreenPos(event->pos());
674 mouseEvent.setScreenPos(event->pos());
673 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
675 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
674 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
676 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
675 mouseEvent.setButtons(m_mousePressButtons);
677 mouseEvent.setButtons(m_mousePressButtons);
676 mouseEvent.setButton(m_mousePressButton);
678 mouseEvent.setButton(m_mousePressButton);
677 mouseEvent.setModifiers(event->modifiers());
679 mouseEvent.setModifiers(event->modifiers());
678 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
680 m_lastMouseMoveScenePoint = mouseEvent.scenePos();
679 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
681 m_lastMouseMoveScreenPoint = mouseEvent.screenPos();
680 mouseEvent.setAccepted(false);
682 mouseEvent.setAccepted(false);
681
683
682 QApplication::sendEvent(m_scene, &mouseEvent);
684 QApplication::sendEvent(m_scene, &mouseEvent);
683 }
685 }
684
686
685 void DeclarativeChart::mouseDoubleClickEvent(QMouseEvent *event)
687 void DeclarativeChart::mouseDoubleClickEvent(QMouseEvent *event)
686 {
688 {
687 m_mousePressScenePoint = event->pos();
689 m_mousePressScenePoint = event->pos();
688 m_mousePressScreenPoint = event->globalPos();
690 m_mousePressScreenPoint = event->globalPos();
689 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
691 m_lastMouseMoveScenePoint = m_mousePressScenePoint;
690 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
692 m_lastMouseMoveScreenPoint = m_mousePressScreenPoint;
691 m_mousePressButton = event->button();
693 m_mousePressButton = event->button();
692 m_mousePressButtons = event->buttons();
694 m_mousePressButtons = event->buttons();
693
695
694 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
696 QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
695 mouseEvent.setWidget(0);
697 mouseEvent.setWidget(0);
696 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
698 mouseEvent.setButtonDownScenePos(m_mousePressButton, m_mousePressScenePoint);
697 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
699 mouseEvent.setButtonDownScreenPos(m_mousePressButton, m_mousePressScreenPoint);
698 mouseEvent.setScenePos(m_mousePressScenePoint);
700 mouseEvent.setScenePos(m_mousePressScenePoint);
699 mouseEvent.setScreenPos(m_mousePressScreenPoint);
701 mouseEvent.setScreenPos(m_mousePressScreenPoint);
700 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
702 mouseEvent.setLastScenePos(m_lastMouseMoveScenePoint);
701 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
703 mouseEvent.setLastScreenPos(m_lastMouseMoveScreenPoint);
702 mouseEvent.setButtons(m_mousePressButtons);
704 mouseEvent.setButtons(m_mousePressButtons);
703 mouseEvent.setButton(m_mousePressButton);
705 mouseEvent.setButton(m_mousePressButton);
704 mouseEvent.setModifiers(event->modifiers());
706 mouseEvent.setModifiers(event->modifiers());
705 mouseEvent.setAccepted(false);
707 mouseEvent.setAccepted(false);
706
708
707 QApplication::sendEvent(m_scene, &mouseEvent);
709 QApplication::sendEvent(m_scene, &mouseEvent);
708 }
710 }
709
711
710 void DeclarativeChart::handleAntialiasingChanged(bool enable)
712 void DeclarativeChart::handleAntialiasingChanged(bool enable)
711 {
713 {
712 setAntialiasing(enable);
714 setAntialiasing(enable);
713 }
715 }
714
716
715 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
717 void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
716 {
718 {
717 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
719 QChart::ChartTheme chartTheme = (QChart::ChartTheme) theme;
718 if (chartTheme != m_chart->theme())
720 if (chartTheme != m_chart->theme())
719 m_chart->setTheme(chartTheme);
721 m_chart->setTheme(chartTheme);
720 }
722 }
721
723
722 DeclarativeChart::Theme DeclarativeChart::theme()
724 DeclarativeChart::Theme DeclarativeChart::theme()
723 {
725 {
724 return (DeclarativeChart::Theme) m_chart->theme();
726 return (DeclarativeChart::Theme) m_chart->theme();
725 }
727 }
726
728
727 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
729 void DeclarativeChart::setAnimationOptions(DeclarativeChart::Animation animations)
728 {
730 {
729 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
731 QChart::AnimationOption animationOptions = (QChart::AnimationOption) animations;
730 if (animationOptions != m_chart->animationOptions())
732 if (animationOptions != m_chart->animationOptions())
731 m_chart->setAnimationOptions(animationOptions);
733 m_chart->setAnimationOptions(animationOptions);
732 }
734 }
733
735
734 DeclarativeChart::Animation DeclarativeChart::animationOptions()
736 DeclarativeChart::Animation DeclarativeChart::animationOptions()
735 {
737 {
736 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
738 if (m_chart->animationOptions().testFlag(QChart::AllAnimations))
737 return DeclarativeChart::AllAnimations;
739 return DeclarativeChart::AllAnimations;
738 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
740 else if (m_chart->animationOptions().testFlag(QChart::GridAxisAnimations))
739 return DeclarativeChart::GridAxisAnimations;
741 return DeclarativeChart::GridAxisAnimations;
740 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
742 else if (m_chart->animationOptions().testFlag(QChart::SeriesAnimations))
741 return DeclarativeChart::SeriesAnimations;
743 return DeclarativeChart::SeriesAnimations;
742 else
744 else
743 return DeclarativeChart::NoAnimation;
745 return DeclarativeChart::NoAnimation;
744 }
746 }
745
747
746 void DeclarativeChart::setAnimationDuration(int msecs)
748 void DeclarativeChart::setAnimationDuration(int msecs)
747 {
749 {
748 if (msecs != m_chart->animationDuration()) {
750 if (msecs != m_chart->animationDuration()) {
749 m_chart->setAnimationDuration(msecs);
751 m_chart->setAnimationDuration(msecs);
750 emit animationDurationChanged(msecs);
752 emit animationDurationChanged(msecs);
751 }
753 }
752 }
754 }
753
755
754 int DeclarativeChart::animationDuration() const
756 int DeclarativeChart::animationDuration() const
755 {
757 {
756 return m_chart->animationDuration();
758 return m_chart->animationDuration();
757 }
759 }
758
760
759 void DeclarativeChart::setAnimationEasingCurve(const QEasingCurve &curve)
761 void DeclarativeChart::setAnimationEasingCurve(const QEasingCurve &curve)
760 {
762 {
761 if (curve != m_chart->animationEasingCurve()) {
763 if (curve != m_chart->animationEasingCurve()) {
762 m_chart->setAnimationEasingCurve(curve);
764 m_chart->setAnimationEasingCurve(curve);
763 emit animationEasingCurveChanged(curve);
765 emit animationEasingCurveChanged(curve);
764 }
766 }
765 }
767 }
766
768
767 QEasingCurve DeclarativeChart::animationEasingCurve() const
769 QEasingCurve DeclarativeChart::animationEasingCurve() const
768 {
770 {
769 return m_chart->animationEasingCurve();
771 return m_chart->animationEasingCurve();
770 }
772 }
771
773
772 void DeclarativeChart::setTitle(QString title)
774 void DeclarativeChart::setTitle(QString title)
773 {
775 {
774 if (title != m_chart->title())
776 if (title != m_chart->title())
775 m_chart->setTitle(title);
777 m_chart->setTitle(title);
776 }
778 }
777 QString DeclarativeChart::title()
779 QString DeclarativeChart::title()
778 {
780 {
779 return m_chart->title();
781 return m_chart->title();
780 }
782 }
781
783
782 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
784 QAbstractAxis *DeclarativeChart::axisX(QAbstractSeries *series)
783 {
785 {
784 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
786 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Horizontal, series);
785 if (axes.count())
787 if (axes.count())
786 return axes[0];
788 return axes[0];
787 return 0;
789 return 0;
788 }
790 }
789
791
790 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
792 QAbstractAxis *DeclarativeChart::axisY(QAbstractSeries *series)
791 {
793 {
792 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
794 QList<QAbstractAxis *> axes = m_chart->axes(Qt::Vertical, series);
793 if (axes.count())
795 if (axes.count())
794 return axes[0];
796 return axes[0];
795 return 0;
797 return 0;
796 }
798 }
797
799
798 QLegend *DeclarativeChart::legend()
800 QLegend *DeclarativeChart::legend()
799 {
801 {
800 return m_chart->legend();
802 return m_chart->legend();
801 }
803 }
802
804
803 void DeclarativeChart::setTitleColor(QColor color)
805 void DeclarativeChart::setTitleColor(QColor color)
804 {
806 {
805 QBrush b = m_chart->titleBrush();
807 QBrush b = m_chart->titleBrush();
806 if (color != b.color()) {
808 if (color != b.color()) {
807 b.setColor(color);
809 b.setColor(color);
808 m_chart->setTitleBrush(b);
810 m_chart->setTitleBrush(b);
809 emit titleColorChanged(color);
811 emit titleColorChanged(color);
810 }
812 }
811 }
813 }
812
814
813 QFont DeclarativeChart::titleFont() const
815 QFont DeclarativeChart::titleFont() const
814 {
816 {
815 return m_chart->titleFont();
817 return m_chart->titleFont();
816 }
818 }
817
819
818 void DeclarativeChart::setTitleFont(const QFont &font)
820 void DeclarativeChart::setTitleFont(const QFont &font)
819 {
821 {
820 m_chart->setTitleFont(font);
822 m_chart->setTitleFont(font);
821 }
823 }
822
824
823 QColor DeclarativeChart::titleColor()
825 QColor DeclarativeChart::titleColor()
824 {
826 {
825 return m_chart->titleBrush().color();
827 return m_chart->titleBrush().color();
826 }
828 }
827
829
828 void DeclarativeChart::setBackgroundColor(QColor color)
830 void DeclarativeChart::setBackgroundColor(QColor color)
829 {
831 {
830 QBrush b = m_chart->backgroundBrush();
832 QBrush b = m_chart->backgroundBrush();
831 if (b.style() != Qt::SolidPattern || color != b.color()) {
833 if (b.style() != Qt::SolidPattern || color != b.color()) {
832 if (color.alpha() < 0xff)
834 if (color.alpha() < 0xff)
833 m_sceneImageNeedsClear = true;
835 m_sceneImageNeedsClear = true;
834 b.setStyle(Qt::SolidPattern);
836 b.setStyle(Qt::SolidPattern);
835 b.setColor(color);
837 b.setColor(color);
836 m_chart->setBackgroundBrush(b);
838 m_chart->setBackgroundBrush(b);
837 emit backgroundColorChanged();
839 emit backgroundColorChanged();
838 }
840 }
839 }
841 }
840
842
841 QColor DeclarativeChart::backgroundColor()
843 QColor DeclarativeChart::backgroundColor()
842 {
844 {
843 return m_chart->backgroundBrush().color();
845 return m_chart->backgroundBrush().color();
844 }
846 }
845
847
846 void QtCharts::DeclarativeChart::setPlotAreaColor(QColor color)
848 void QtCharts::DeclarativeChart::setPlotAreaColor(QColor color)
847 {
849 {
848 QBrush b = m_chart->plotAreaBackgroundBrush();
850 QBrush b = m_chart->plotAreaBackgroundBrush();
849 if (b.style() != Qt::SolidPattern || color != b.color()) {
851 if (b.style() != Qt::SolidPattern || color != b.color()) {
850 b.setStyle(Qt::SolidPattern);
852 b.setStyle(Qt::SolidPattern);
851 b.setColor(color);
853 b.setColor(color);
852 m_chart->setPlotAreaBackgroundBrush(b);
854 m_chart->setPlotAreaBackgroundBrush(b);
853 m_chart->setPlotAreaBackgroundVisible(true);
855 m_chart->setPlotAreaBackgroundVisible(true);
854 emit plotAreaColorChanged();
856 emit plotAreaColorChanged();
855 }
857 }
856 }
858 }
857
859
858 QColor QtCharts::DeclarativeChart::plotAreaColor()
860 QColor QtCharts::DeclarativeChart::plotAreaColor()
859 {
861 {
860 return m_chart->plotAreaBackgroundBrush().color();
862 return m_chart->plotAreaBackgroundBrush().color();
861 }
863 }
862
864
863 void DeclarativeChart::setLocalizeNumbers(bool localize)
865 void DeclarativeChart::setLocalizeNumbers(bool localize)
864 {
866 {
865 if (m_chart->localizeNumbers() != localize) {
867 if (m_chart->localizeNumbers() != localize) {
866 m_chart->setLocalizeNumbers(localize);
868 m_chart->setLocalizeNumbers(localize);
867 emit localizeNumbersChanged();
869 emit localizeNumbersChanged();
868 }
870 }
869 }
871 }
870
872
871 bool DeclarativeChart::localizeNumbers() const
873 bool DeclarativeChart::localizeNumbers() const
872 {
874 {
873 return m_chart->localizeNumbers();
875 return m_chart->localizeNumbers();
874 }
876 }
875
877
876 void QtCharts::DeclarativeChart::setLocale(const QLocale &locale)
878 void QtCharts::DeclarativeChart::setLocale(const QLocale &locale)
877 {
879 {
878 if (m_chart->locale() != locale) {
880 if (m_chart->locale() != locale) {
879 m_chart->setLocale(locale);
881 m_chart->setLocale(locale);
880 emit localeChanged();
882 emit localeChanged();
881 }
883 }
882 }
884 }
883
885
884 QLocale QtCharts::DeclarativeChart::locale() const
886 QLocale QtCharts::DeclarativeChart::locale() const
885 {
887 {
886 return m_chart->locale();
888 return m_chart->locale();
887 }
889 }
888
890
889 int DeclarativeChart::count()
891 int DeclarativeChart::count()
890 {
892 {
891 return m_chart->series().count();
893 return m_chart->series().count();
892 }
894 }
893
895
894 void DeclarativeChart::setDropShadowEnabled(bool enabled)
896 void DeclarativeChart::setDropShadowEnabled(bool enabled)
895 {
897 {
896 if (enabled != m_chart->isDropShadowEnabled()) {
898 if (enabled != m_chart->isDropShadowEnabled()) {
897 m_sceneImageNeedsClear = true;
899 m_sceneImageNeedsClear = true;
898 m_chart->setDropShadowEnabled(enabled);
900 m_chart->setDropShadowEnabled(enabled);
899 dropShadowEnabledChanged(enabled);
901 dropShadowEnabledChanged(enabled);
900 }
902 }
901 }
903 }
902
904
903 bool DeclarativeChart::dropShadowEnabled()
905 bool DeclarativeChart::dropShadowEnabled()
904 {
906 {
905 return m_chart->isDropShadowEnabled();
907 return m_chart->isDropShadowEnabled();
906 }
908 }
907
909
908 qreal DeclarativeChart::backgroundRoundness() const
910 qreal DeclarativeChart::backgroundRoundness() const
909 {
911 {
910 return m_chart->backgroundRoundness();
912 return m_chart->backgroundRoundness();
911 }
913 }
912
914
913 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
915 void DeclarativeChart::setBackgroundRoundness(qreal diameter)
914 {
916 {
915 if (m_chart->backgroundRoundness() != diameter) {
917 if (m_chart->backgroundRoundness() != diameter) {
916 m_sceneImageNeedsClear = true;
918 m_sceneImageNeedsClear = true;
917 m_chart->setBackgroundRoundness(diameter);
919 m_chart->setBackgroundRoundness(diameter);
918 emit backgroundRoundnessChanged(diameter);
920 emit backgroundRoundnessChanged(diameter);
919 }
921 }
920 }
922 }
921
923
922 void DeclarativeChart::zoom(qreal factor)
924 void DeclarativeChart::zoom(qreal factor)
923 {
925 {
924 m_chart->zoom(factor);
926 m_chart->zoom(factor);
925 }
927 }
926
928
927 void DeclarativeChart::zoomIn()
929 void DeclarativeChart::zoomIn()
928 {
930 {
929 m_chart->zoomIn();
931 m_chart->zoomIn();
930 }
932 }
931
933
932 void DeclarativeChart::zoomIn(const QRectF &rectangle)
934 void DeclarativeChart::zoomIn(const QRectF &rectangle)
933 {
935 {
934 m_chart->zoomIn(rectangle);
936 m_chart->zoomIn(rectangle);
935 }
937 }
936
938
937 void DeclarativeChart::zoomOut()
939 void DeclarativeChart::zoomOut()
938 {
940 {
939 m_chart->zoomOut();
941 m_chart->zoomOut();
940 }
942 }
941
943
942 void DeclarativeChart::zoomReset()
944 void DeclarativeChart::zoomReset()
943 {
945 {
944 m_chart->zoomReset();
946 m_chart->zoomReset();
945 }
947 }
946
948
947 bool DeclarativeChart::isZoomed()
949 bool DeclarativeChart::isZoomed()
948 {
950 {
949 return m_chart->isZoomed();
951 return m_chart->isZoomed();
950 }
952 }
951
953
952 void DeclarativeChart::scrollLeft(qreal pixels)
954 void DeclarativeChart::scrollLeft(qreal pixels)
953 {
955 {
954 m_chart->scroll(-pixels, 0);
956 m_chart->scroll(-pixels, 0);
955 }
957 }
956
958
957 void DeclarativeChart::scrollRight(qreal pixels)
959 void DeclarativeChart::scrollRight(qreal pixels)
958 {
960 {
959 m_chart->scroll(pixels, 0);
961 m_chart->scroll(pixels, 0);
960 }
962 }
961
963
962 void DeclarativeChart::scrollUp(qreal pixels)
964 void DeclarativeChart::scrollUp(qreal pixels)
963 {
965 {
964 m_chart->scroll(0, pixels);
966 m_chart->scroll(0, pixels);
965 }
967 }
966
968
967 void DeclarativeChart::scrollDown(qreal pixels)
969 void DeclarativeChart::scrollDown(qreal pixels)
968 {
970 {
969 m_chart->scroll(0, -pixels);
971 m_chart->scroll(0, -pixels);
970 }
972 }
971
973
972 QQmlListProperty<QAbstractAxis> DeclarativeChart::axes()
974 QQmlListProperty<QAbstractAxis> DeclarativeChart::axes()
973 {
975 {
974 return QQmlListProperty<QAbstractAxis>(this, 0,
976 return QQmlListProperty<QAbstractAxis>(this, 0,
975 &DeclarativeChart::axesAppendFunc,
977 &DeclarativeChart::axesAppendFunc,
976 &DeclarativeChart::axesCountFunc,
978 &DeclarativeChart::axesCountFunc,
977 &DeclarativeChart::axesAtFunc,
979 &DeclarativeChart::axesAtFunc,
978 &DeclarativeChart::axesClearFunc);
980 &DeclarativeChart::axesClearFunc);
979 }
981 }
980
982
981 void DeclarativeChart::axesAppendFunc(QQmlListProperty<QAbstractAxis> *list, QAbstractAxis *element)
983 void DeclarativeChart::axesAppendFunc(QQmlListProperty<QAbstractAxis> *list, QAbstractAxis *element)
982 {
984 {
983 // Empty implementation
985 // Empty implementation
984 Q_UNUSED(list);
986 Q_UNUSED(list);
985 Q_UNUSED(element);
987 Q_UNUSED(element);
986 }
988 }
987
989
988 int DeclarativeChart::axesCountFunc(QQmlListProperty<QAbstractAxis> *list)
990 int DeclarativeChart::axesCountFunc(QQmlListProperty<QAbstractAxis> *list)
989 {
991 {
990 if (qobject_cast<DeclarativeChart *>(list->object)) {
992 if (qobject_cast<DeclarativeChart *>(list->object)) {
991 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
993 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
992 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
994 return chart->m_chart->axes(Qt::Horizontal | Qt::Vertical).count();
993 }
995 }
994 return 0;
996 return 0;
995 }
997 }
996
998
997 QAbstractAxis *DeclarativeChart::axesAtFunc(QQmlListProperty<QAbstractAxis> *list, int index)
999 QAbstractAxis *DeclarativeChart::axesAtFunc(QQmlListProperty<QAbstractAxis> *list, int index)
998 {
1000 {
999 if (qobject_cast<DeclarativeChart *>(list->object)) {
1001 if (qobject_cast<DeclarativeChart *>(list->object)) {
1000 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
1002 DeclarativeChart *chart = qobject_cast<DeclarativeChart *>(list->object);
1001 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
1003 QList<QAbstractAxis *> axes = chart->m_chart->axes(Qt::Horizontal | Qt::Vertical, chart->m_chart->series()[0]);
1002 return axes.at(index);
1004 return axes.at(index);
1003 }
1005 }
1004 return 0;
1006 return 0;
1005 }
1007 }
1006
1008
1007 void DeclarativeChart::axesClearFunc(QQmlListProperty<QAbstractAxis> *list)
1009 void DeclarativeChart::axesClearFunc(QQmlListProperty<QAbstractAxis> *list)
1008 {
1010 {
1009 // Empty implementation
1011 // Empty implementation
1010 Q_UNUSED(list);
1012 Q_UNUSED(list);
1011 }
1013 }
1012
1014
1013
1015
1014 QAbstractSeries *DeclarativeChart::series(int index)
1016 QAbstractSeries *DeclarativeChart::series(int index)
1015 {
1017 {
1016 if (index < m_chart->series().count()) {
1018 if (index < m_chart->series().count()) {
1017 return m_chart->series().at(index);
1019 return m_chart->series().at(index);
1018 }
1020 }
1019 return 0;
1021 return 0;
1020 }
1022 }
1021
1023
1022 QAbstractSeries *DeclarativeChart::series(QString seriesName)
1024 QAbstractSeries *DeclarativeChart::series(QString seriesName)
1023 {
1025 {
1024 foreach (QAbstractSeries *series, m_chart->series()) {
1026 foreach (QAbstractSeries *series, m_chart->series()) {
1025 if (series->name() == seriesName)
1027 if (series->name() == seriesName)
1026 return series;
1028 return series;
1027 }
1029 }
1028 return 0;
1030 return 0;
1029 }
1031 }
1030
1032
1031 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
1033 QAbstractSeries *DeclarativeChart::createSeries(int type, QString name, QAbstractAxis *axisX, QAbstractAxis *axisY)
1032 {
1034 {
1033 QAbstractSeries *series = 0;
1035 QAbstractSeries *series = 0;
1034
1036
1035 switch (type) {
1037 switch (type) {
1036 case DeclarativeChart::SeriesTypeLine:
1038 case DeclarativeChart::SeriesTypeLine:
1037 series = new DeclarativeLineSeries();
1039 series = new DeclarativeLineSeries();
1038 break;
1040 break;
1039 case DeclarativeChart::SeriesTypeArea: {
1041 case DeclarativeChart::SeriesTypeArea: {
1040 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
1042 DeclarativeAreaSeries *area = new DeclarativeAreaSeries();
1041 DeclarativeLineSeries *line = new DeclarativeLineSeries();
1043 DeclarativeLineSeries *line = new DeclarativeLineSeries();
1042 line->setParent(area);
1044 line->setParent(area);
1043 area->setUpperSeries(line);
1045 area->setUpperSeries(line);
1044 series = area;
1046 series = area;
1045 break;
1047 break;
1046 }
1048 }
1047 case DeclarativeChart::SeriesTypeStackedBar:
1049 case DeclarativeChart::SeriesTypeStackedBar:
1048 series = new DeclarativeStackedBarSeries();
1050 series = new DeclarativeStackedBarSeries();
1049 break;
1051 break;
1050 case DeclarativeChart::SeriesTypePercentBar:
1052 case DeclarativeChart::SeriesTypePercentBar:
1051 series = new DeclarativePercentBarSeries();
1053 series = new DeclarativePercentBarSeries();
1052 break;
1054 break;
1053 case DeclarativeChart::SeriesTypeBar:
1055 case DeclarativeChart::SeriesTypeBar:
1054 series = new DeclarativeBarSeries();
1056 series = new DeclarativeBarSeries();
1055 break;
1057 break;
1056 case DeclarativeChart::SeriesTypeHorizontalBar:
1058 case DeclarativeChart::SeriesTypeHorizontalBar:
1057 series = new DeclarativeHorizontalBarSeries();
1059 series = new DeclarativeHorizontalBarSeries();
1058 break;
1060 break;
1059 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
1061 case DeclarativeChart::SeriesTypeHorizontalPercentBar:
1060 series = new DeclarativeHorizontalPercentBarSeries();
1062 series = new DeclarativeHorizontalPercentBarSeries();
1061 break;
1063 break;
1062 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
1064 case DeclarativeChart::SeriesTypeHorizontalStackedBar:
1063 series = new DeclarativeHorizontalStackedBarSeries();
1065 series = new DeclarativeHorizontalStackedBarSeries();
1064 break;
1066 break;
1065 case DeclarativeChart::SeriesTypeBoxPlot:
1067 case DeclarativeChart::SeriesTypeBoxPlot:
1066 series = new DeclarativeBoxPlotSeries();
1068 series = new DeclarativeBoxPlotSeries();
1067 break;
1069 break;
1068 case DeclarativeChart::SeriesTypePie:
1070 case DeclarativeChart::SeriesTypePie:
1069 series = new DeclarativePieSeries();
1071 series = new DeclarativePieSeries();
1070 break;
1072 break;
1071 case DeclarativeChart::SeriesTypeScatter:
1073 case DeclarativeChart::SeriesTypeScatter:
1072 series = new DeclarativeScatterSeries();
1074 series = new DeclarativeScatterSeries();
1073 break;
1075 break;
1074 case DeclarativeChart::SeriesTypeSpline:
1076 case DeclarativeChart::SeriesTypeSpline:
1075 series = new DeclarativeSplineSeries();
1077 series = new DeclarativeSplineSeries();
1076 break;
1078 break;
1077 default:
1079 default:
1078 qWarning() << "Illegal series type";
1080 qWarning() << "Illegal series type";
1079 }
1081 }
1080
1082
1081 if (series) {
1083 if (series) {
1082 // Connect to axis changed signals (unless this is a pie series)
1084 // Connect to axis changed signals (unless this is a pie series)
1083 if (!qobject_cast<DeclarativePieSeries *>(series)) {
1085 if (!qobject_cast<DeclarativePieSeries *>(series)) {
1084 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1086 connect(series, SIGNAL(axisXChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1085 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1087 connect(series, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SLOT(handleAxisXSet(QAbstractAxis*)));
1086 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
1088 connect(series, SIGNAL(axisYChanged(QAbstractAxis*)), this, SLOT(handleAxisYSet(QAbstractAxis*)));
1087 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
1089 connect(series, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SLOT(handleAxisYRightSet(QAbstractAxis*)));
1088 }
1090 }
1089
1091
1090 series->setName(name);
1092 series->setName(name);
1091 m_chart->addSeries(series);
1093 m_chart->addSeries(series);
1092
1094
1093 if (!axisX || !axisY)
1095 if (!axisX || !axisY)
1094 initializeAxes(series);
1096 initializeAxes(series);
1095
1097
1096 if (axisX)
1098 if (axisX)
1097 setAxisX(axisX, series);
1099 setAxisX(axisX, series);
1098 if (axisY)
1100 if (axisY)
1099 setAxisY(axisY, series);
1101 setAxisY(axisY, series);
1100 }
1102 }
1101
1103
1102 return series;
1104 return series;
1103 }
1105 }
1104
1106
1105 void DeclarativeChart::removeSeries(QAbstractSeries *series)
1107 void DeclarativeChart::removeSeries(QAbstractSeries *series)
1106 {
1108 {
1107 if (series)
1109 if (series)
1108 m_chart->removeSeries(series);
1110 m_chart->removeSeries(series);
1109 else
1111 else
1110 qWarning("removeSeries: cannot remove null");
1112 qWarning("removeSeries: cannot remove null");
1111 }
1113 }
1112
1114
1113 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
1115 void DeclarativeChart::setAxisX(QAbstractAxis *axis, QAbstractSeries *series)
1114 {
1116 {
1115 if (axis && series)
1117 if (axis && series)
1116 seriesAxisAttachHelper(series, axis, Qt::Horizontal, Qt::AlignBottom);
1118 seriesAxisAttachHelper(series, axis, Qt::Horizontal, Qt::AlignBottom);
1117 }
1119 }
1118
1120
1119 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
1121 void DeclarativeChart::setAxisY(QAbstractAxis *axis, QAbstractSeries *series)
1120 {
1122 {
1121 if (axis && series)
1123 if (axis && series)
1122 seriesAxisAttachHelper(series, axis, Qt::Vertical, Qt::AlignLeft);
1124 seriesAxisAttachHelper(series, axis, Qt::Vertical, Qt::AlignLeft);
1123 }
1125 }
1124
1126
1125 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
1127 QAbstractAxis *DeclarativeChart::defaultAxis(Qt::Orientation orientation, QAbstractSeries *series)
1126 {
1128 {
1127 if (!series) {
1129 if (!series) {
1128 qWarning() << "No axis type defined for null series";
1130 qWarning() << "No axis type defined for null series";
1129 return 0;
1131 return 0;
1130 }
1132 }
1131
1133
1132 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
1134 foreach (QAbstractAxis *existingAxis, m_chart->axes(orientation)) {
1133 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
1135 if (existingAxis->type() == series->d_ptr->defaultAxisType(orientation))
1134 return existingAxis;
1136 return existingAxis;
1135 }
1137 }
1136
1138
1137 switch (series->d_ptr->defaultAxisType(orientation)) {
1139 switch (series->d_ptr->defaultAxisType(orientation)) {
1138 case QAbstractAxis::AxisTypeValue:
1140 case QAbstractAxis::AxisTypeValue:
1139 return new QValueAxis(this);
1141 return new QValueAxis(this);
1140 case QAbstractAxis::AxisTypeBarCategory:
1142 case QAbstractAxis::AxisTypeBarCategory:
1141 return new QBarCategoryAxis(this);
1143 return new QBarCategoryAxis(this);
1142 case QAbstractAxis::AxisTypeCategory:
1144 case QAbstractAxis::AxisTypeCategory:
1143 return new QCategoryAxis(this);
1145 return new QCategoryAxis(this);
1144 #ifndef QT_ON_ARM
1146 #ifndef QT_ON_ARM
1145 case QAbstractAxis::AxisTypeDateTime:
1147 case QAbstractAxis::AxisTypeDateTime:
1146 return new QDateTimeAxis(this);
1148 return new QDateTimeAxis(this);
1147 #endif
1149 #endif
1148 case QAbstractAxis::AxisTypeLogValue:
1150 case QAbstractAxis::AxisTypeLogValue:
1149 return new QLogValueAxis(this);
1151 return new QLogValueAxis(this);
1150 default:
1152 default:
1151 // assume AxisTypeNoAxis
1153 // assume AxisTypeNoAxis
1152 return 0;
1154 return 0;
1153 }
1155 }
1154 }
1156 }
1155
1157
1156 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1158 void DeclarativeChart::initializeAxes(QAbstractSeries *series)
1157 {
1159 {
1158 if (qobject_cast<DeclarativeLineSeries *>(series))
1160 if (qobject_cast<DeclarativeLineSeries *>(series))
1159 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
1161 doInitializeAxes(series, qobject_cast<DeclarativeLineSeries *>(series)->m_axes);
1160 else if (qobject_cast<DeclarativeScatterSeries *>(series))
1162 else if (qobject_cast<DeclarativeScatterSeries *>(series))
1161 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
1163 doInitializeAxes(series, qobject_cast<DeclarativeScatterSeries *>(series)->m_axes);
1162 else if (qobject_cast<DeclarativeSplineSeries *>(series))
1164 else if (qobject_cast<DeclarativeSplineSeries *>(series))
1163 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
1165 doInitializeAxes(series, qobject_cast<DeclarativeSplineSeries *>(series)->m_axes);
1164 else if (qobject_cast<DeclarativeAreaSeries *>(series))
1166 else if (qobject_cast<DeclarativeAreaSeries *>(series))
1165 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
1167 doInitializeAxes(series, qobject_cast<DeclarativeAreaSeries *>(series)->m_axes);
1166 else if (qobject_cast<DeclarativeBarSeries *>(series))
1168 else if (qobject_cast<DeclarativeBarSeries *>(series))
1167 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
1169 doInitializeAxes(series, qobject_cast<DeclarativeBarSeries *>(series)->m_axes);
1168 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
1170 else if (qobject_cast<DeclarativeStackedBarSeries *>(series))
1169 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
1171 doInitializeAxes(series, qobject_cast<DeclarativeStackedBarSeries *>(series)->m_axes);
1170 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
1172 else if (qobject_cast<DeclarativePercentBarSeries *>(series))
1171 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1173 doInitializeAxes(series, qobject_cast<DeclarativePercentBarSeries *>(series)->m_axes);
1172 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1174 else if (qobject_cast<DeclarativeHorizontalBarSeries *>(series))
1173 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1175 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalBarSeries *>(series)->m_axes);
1174 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1176 else if (qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series))
1175 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1177 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalStackedBarSeries *>(series)->m_axes);
1176 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1178 else if (qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series))
1177 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1179 doInitializeAxes(series, qobject_cast<DeclarativeHorizontalPercentBarSeries *>(series)->m_axes);
1178 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1180 else if (qobject_cast<DeclarativeBoxPlotSeries *>(series))
1179 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1181 doInitializeAxes(series, qobject_cast<DeclarativeBoxPlotSeries *>(series)->m_axes);
1180 // else: do nothing
1182 // else: do nothing
1181 }
1183 }
1182
1184
1183 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1185 void DeclarativeChart::doInitializeAxes(QAbstractSeries *series, DeclarativeAxes *axes)
1184 {
1186 {
1185 qreal min;
1187 qreal min;
1186 qreal max;
1188 qreal max;
1187 // Initialize axis X
1189 // Initialize axis X
1188 if (axes->axisX()) {
1190 if (axes->axisX()) {
1189 axes->emitAxisXChanged();
1191 axes->emitAxisXChanged();
1190 } else if (axes->axisXTop()) {
1192 } else if (axes->axisXTop()) {
1191 axes->emitAxisXTopChanged();
1193 axes->emitAxisXTopChanged();
1192 } else {
1194 } else {
1193 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1195 axes->setAxisX(defaultAxis(Qt::Horizontal, series));
1194 findMinMaxForSeries(series, Qt::Horizontal, min, max);
1196 findMinMaxForSeries(series, Qt::Horizontal, min, max);
1195 axes->axisX()->setRange(min, max);
1197 axes->axisX()->setRange(min, max);
1196 }
1198 }
1197
1199
1198 // Initialize axis Y
1200 // Initialize axis Y
1199 if (axes->axisY()) {
1201 if (axes->axisY()) {
1200 axes->emitAxisYChanged();
1202 axes->emitAxisYChanged();
1201 } else if (axes->axisYRight()) {
1203 } else if (axes->axisYRight()) {
1202 axes->emitAxisYRightChanged();
1204 axes->emitAxisYRightChanged();
1203 } else {
1205 } else {
1204 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1206 axes->setAxisY(defaultAxis(Qt::Vertical, series));
1205 findMinMaxForSeries(series, Qt::Vertical, min, max);
1207 findMinMaxForSeries(series, Qt::Vertical, min, max);
1206 axes->axisY()->setRange(min, max);
1208 axes->axisY()->setRange(min, max);
1207 }
1209 }
1208 }
1210 }
1209
1211
1210 void DeclarativeChart::findMinMaxForSeries(QAbstractSeries *series, Qt::Orientations orientation,
1212 void DeclarativeChart::findMinMaxForSeries(QAbstractSeries *series, Qt::Orientations orientation,
1211 qreal &min, qreal &max)
1213 qreal &min, qreal &max)
1212 {
1214 {
1213 if (!series) {
1215 if (!series) {
1214 min = 0.5;
1216 min = 0.5;
1215 max = 0.5;
1217 max = 0.5;
1216 } else {
1218 } else {
1217 AbstractDomain *domain = series->d_ptr->domain();
1219 AbstractDomain *domain = series->d_ptr->domain();
1218 min = (orientation == Qt::Vertical) ? domain->minY() : domain->minX();
1220 min = (orientation == Qt::Vertical) ? domain->minY() : domain->minX();
1219 max = (orientation == Qt::Vertical) ? domain->maxY() : domain->maxX();
1221 max = (orientation == Qt::Vertical) ? domain->maxY() : domain->maxX();
1220
1222
1221 if (min == max) {
1223 if (min == max) {
1222 min -= 0.5;
1224 min -= 0.5;
1223 max += 0.5;
1225 max += 0.5;
1224 }
1226 }
1225 }
1227 }
1226 }
1228 }
1227
1229
1228 QPointF DeclarativeChart::mapToValue(const QPointF &position, QAbstractSeries *series)
1230 QPointF DeclarativeChart::mapToValue(const QPointF &position, QAbstractSeries *series)
1229 {
1231 {
1230 return m_chart->mapToValue(position, series);
1232 return m_chart->mapToValue(position, series);
1231 }
1233 }
1232
1234
1233 QPointF DeclarativeChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
1235 QPointF DeclarativeChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
1234 {
1236 {
1235 return m_chart->mapToPosition(value, series);
1237 return m_chart->mapToPosition(value, series);
1236 }
1238 }
1237
1239
1238 #include "moc_declarativechart.cpp"
1240 #include "moc_declarativechart.cpp"
1239
1241
1240 QT_CHARTS_END_NAMESPACE
1242 QT_CHARTS_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now