1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2017 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Charts module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 or (at your option) any later version |
20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by |
21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include <QtCharts/QScatterSeries> |
31 | #include <private/qscatterseries_p.h> |
32 | #include <private/scatterchartitem_p.h> |
33 | #include <private/chartdataset_p.h> |
34 | #include <private/charttheme_p.h> |
35 | #include <private/scatteranimation_p.h> |
36 | #include <private/qchart_p.h> |
37 | |
38 | /*! |
39 | \class QScatterSeries |
40 | \inmodule QtCharts |
41 | \brief The QScatterSeries class presents data in scatter charts. |
42 | |
43 | The scatter data is displayed as a collection of points on the chart. For |
44 | each point, two values are specified that determine its position on the |
45 | horizontal axis and the vertical axis. |
46 | |
47 | \image examples_scatterchart.png |
48 | |
49 | The following code snippet illustrates how to create a basic scatter chart: |
50 | \code |
51 | QScatterSeries* series = new QScatterSeries(); |
52 | series->append(0, 6); |
53 | series->append(2, 4); |
54 | ... |
55 | chart->addSeries(series); |
56 | \endcode |
57 | |
58 | For more information, see \l{ScatterChart Example} and |
59 | \l {Scatter Interactions Example}. |
60 | */ |
61 | /*! |
62 | \qmltype ScatterSeries |
63 | \instantiates QScatterSeries |
64 | \inqmlmodule QtCharts |
65 | |
66 | \inherits XYSeries |
67 | |
68 | \brief The ScatterSeries type presents data in scatter charts. |
69 | |
70 | The scatter data is displayed as a collection of points on the chart. For |
71 | each point, two values are specified that determine its position on the |
72 | horizontal axis and the vertical axis. |
73 | |
74 | \image examples_qmlchart5.png |
75 | |
76 | The following QML code shows how to create a chart with two simple scatter |
77 | series: |
78 | \snippet qmlchart/qml/qmlchart/View5.qml 1 |
79 | |
80 | For more information, see \l{Qml Charts Example}. |
81 | */ |
82 | |
83 | /*! |
84 | \enum QScatterSeries::MarkerShape |
85 | |
86 | This enum value describes the shape used when rendering marker items. |
87 | |
88 | \value MarkerShapeCircle |
89 | The marker is a circle. This is the default value. |
90 | \value MarkerShapeRectangle |
91 | The marker is a rectangle. |
92 | */ |
93 | |
94 | /*! |
95 | \property QScatterSeries::brush |
96 | \brief The brush used to draw the scatter series markers. |
97 | |
98 | The brush can be an image that can be created using QPainterPath, |
99 | for example. |
100 | */ |
101 | |
102 | /*! |
103 | \qmlproperty brush ScatterSeries::brush |
104 | The brush used to draw the scatter series markers. |
105 | */ |
106 | |
107 | /*! |
108 | \property QScatterSeries::color |
109 | \brief The color used to fill the series markers. |
110 | |
111 | This is a convenience property for modifying the color of the brush. |
112 | \sa QScatterSeries::brush() |
113 | */ |
114 | |
115 | /*! |
116 | \property QScatterSeries::borderColor |
117 | \brief The color used to draw the marker borders. |
118 | |
119 | This is a convenience property for modifying the color of the pen. |
120 | \sa QScatterSeries::pen() |
121 | */ |
122 | |
123 | /*! |
124 | \qmlproperty int ScatterSeries::count |
125 | The number of data points in the series. |
126 | */ |
127 | |
128 | /*! |
129 | \qmlproperty color ScatterSeries::borderColor |
130 | The color used to draw the marker borders. |
131 | */ |
132 | |
133 | /*! |
134 | \qmlproperty real ScatterSeries::borderWidth |
135 | The width of the border line. By default, the width is 2.0. |
136 | */ |
137 | |
138 | /*! |
139 | \property QScatterSeries::markerShape |
140 | \brief The shape of the marker used to render the points in the series. |
141 | |
142 | The default shape is MarkerShapeCircle. |
143 | |
144 | \sa MarkerShape |
145 | */ |
146 | /*! |
147 | \qmlproperty enumeration ScatterSeries::markerShape |
148 | |
149 | The shape used when rendering marker items: |
150 | |
151 | \value ScatterSeries.MarkerShapeCircle |
152 | The marker is a circle. This is the default value. |
153 | \value ScatterSeries.MarkerShapeRectangle |
154 | The marker is a rectangle. |
155 | */ |
156 | |
157 | /*! |
158 | \property QScatterSeries::markerSize |
159 | \brief The size of the marker used to render the points in the series. |
160 | |
161 | The default size is 15.0. |
162 | */ |
163 | /*! |
164 | \qmlproperty real ScatterSeries::markerSize |
165 | The size of the marker used to render the points in the series. |
166 | The default size is 15.0. |
167 | */ |
168 | |
169 | /*! |
170 | \qmlproperty string ScatterSeries::brushFilename |
171 | The name of the file used as a brush for the series. |
172 | */ |
173 | |
174 | /*! |
175 | \fn void QScatterSeries::colorChanged(QColor color) |
176 | This signal is emitted when the fill (brush) color changes to \a color. |
177 | */ |
178 | |
179 | /*! |
180 | \fn void QScatterSeries::borderColorChanged(QColor color) |
181 | This signal is emitted when the line (pen) color changes to \a color. |
182 | */ |
183 | |
184 | /*! |
185 | \fn void QScatterSeries::markerShapeChanged(MarkerShape shape) |
186 | This signal is emitted when the marker shape changes to \a shape. |
187 | */ |
188 | |
189 | /*! |
190 | \fn void QScatterSeries::markerSizeChanged(qreal size) |
191 | This signal is emitted when the marker size changes to \a size. |
192 | */ |
193 | |
194 | QT_CHARTS_BEGIN_NAMESPACE |
195 | |
196 | /*! |
197 | Constructs a series object that is a child of \a parent. |
198 | */ |
199 | QScatterSeries::QScatterSeries(QObject *parent) |
200 | : QXYSeries(*new QScatterSeriesPrivate(this), parent) |
201 | { |
202 | } |
203 | |
204 | /*! |
205 | Deletes the scatter series. |
206 | |
207 | \note Adding the series to QChart transfers the ownership to the chart. |
208 | */ |
209 | QScatterSeries::~QScatterSeries() |
210 | { |
211 | Q_D(QScatterSeries); |
212 | if (d->m_chart) |
213 | d->m_chart->removeSeries(series: this); |
214 | } |
215 | |
216 | /*! |
217 | \reimp |
218 | */ |
219 | QAbstractSeries::SeriesType QScatterSeries::type() const |
220 | { |
221 | return QAbstractSeries::SeriesTypeScatter; |
222 | } |
223 | |
224 | /*! |
225 | \reimp |
226 | */ |
227 | void QScatterSeries::setPen(const QPen &pen) |
228 | { |
229 | Q_D(QXYSeries); |
230 | if (d->m_pen != pen) { |
231 | bool emitColorChanged = d->m_pen.color() != pen.color(); |
232 | d->m_pen = pen; |
233 | emit d->updated(); |
234 | if (emitColorChanged) |
235 | emit borderColorChanged(color: pen.color()); |
236 | } |
237 | } |
238 | |
239 | /*! |
240 | \reimp |
241 | */ |
242 | void QScatterSeries::setBrush(const QBrush &brush) |
243 | { |
244 | Q_D(QScatterSeries); |
245 | if (d->m_brush != brush) { |
246 | bool emitColorChanged = d->m_brush.color() != brush.color(); |
247 | d->m_brush = brush; |
248 | emit d->updated(); |
249 | if (emitColorChanged) |
250 | emit colorChanged(color: brush.color()); |
251 | } |
252 | } |
253 | |
254 | QBrush QScatterSeries::brush() const |
255 | { |
256 | Q_D(const QScatterSeries); |
257 | if (d->m_brush == QChartPrivate::defaultBrush()) |
258 | return QBrush(); |
259 | else |
260 | return d->m_brush; |
261 | } |
262 | |
263 | void QScatterSeries::setColor(const QColor &color) |
264 | { |
265 | QBrush b = brush(); |
266 | if (b == QChartPrivate::defaultBrush()) |
267 | b = QBrush(); |
268 | if (b == QBrush()) |
269 | b.setStyle(Qt::SolidPattern); |
270 | b.setColor(color); |
271 | setBrush(b); |
272 | } |
273 | |
274 | QColor QScatterSeries::color() const |
275 | { |
276 | return brush().color(); |
277 | } |
278 | |
279 | void QScatterSeries::setBorderColor(const QColor &color) |
280 | { |
281 | QPen p = pen(); |
282 | if (p == QChartPrivate::defaultPen()) |
283 | p = QPen(); |
284 | p.setColor(color); |
285 | setPen(p); |
286 | } |
287 | |
288 | QColor QScatterSeries::borderColor() const |
289 | { |
290 | return pen().color(); |
291 | } |
292 | |
293 | QScatterSeries::MarkerShape QScatterSeries::markerShape() const |
294 | { |
295 | Q_D(const QScatterSeries); |
296 | return d->m_shape; |
297 | } |
298 | |
299 | void QScatterSeries::setMarkerShape(MarkerShape shape) |
300 | { |
301 | Q_D(QScatterSeries); |
302 | if (d->m_shape != shape) { |
303 | d->m_shape = shape; |
304 | emit d->updated(); |
305 | emit markerShapeChanged(shape); |
306 | } |
307 | } |
308 | |
309 | qreal QScatterSeries::markerSize() const |
310 | { |
311 | Q_D(const QScatterSeries); |
312 | return d->m_size; |
313 | } |
314 | |
315 | void QScatterSeries::setMarkerSize(qreal size) |
316 | { |
317 | Q_D(QScatterSeries); |
318 | |
319 | if (!qFuzzyCompare(p1: d->m_size, p2: size)) { |
320 | d->m_size = size; |
321 | emit d->updated(); |
322 | emit markerSizeChanged(size); |
323 | } |
324 | } |
325 | |
326 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
327 | |
328 | QScatterSeriesPrivate::QScatterSeriesPrivate(QScatterSeries *q) |
329 | : QXYSeriesPrivate(q), |
330 | m_shape(QScatterSeries::MarkerShapeCircle), |
331 | m_size(15.0) |
332 | { |
333 | } |
334 | |
335 | void QScatterSeriesPrivate::initializeGraphics(QGraphicsItem* parent) |
336 | { |
337 | Q_Q(QScatterSeries); |
338 | ScatterChartItem *scatter = new ScatterChartItem(q,parent); |
339 | m_item.reset(other: scatter); |
340 | QAbstractSeriesPrivate::initializeGraphics(parent); |
341 | } |
342 | |
343 | void QScatterSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced) |
344 | { |
345 | Q_Q(QScatterSeries); |
346 | const QList<QColor> colors = theme->seriesColors(); |
347 | const QList<QGradient> gradients = theme->seriesGradients(); |
348 | |
349 | if (forced || QChartPrivate::defaultPen() == m_pen) { |
350 | QPen pen; |
351 | pen.setColor(ChartThemeManager::colorAt(gradient: gradients.at(i: index % gradients.size()), pos: 0.0)); |
352 | pen.setWidthF(2); |
353 | q->setPen(pen); |
354 | } |
355 | |
356 | if (forced || QChartPrivate::defaultBrush() == m_brush) { |
357 | QBrush brush(colors.at(i: index % colors.size())); |
358 | q->setBrush(brush); |
359 | } |
360 | |
361 | if (forced || QChartPrivate::defaultPen().color() == m_pointLabelsColor) { |
362 | QColor color = theme->labelBrush().color(); |
363 | q->setPointLabelsColor(color); |
364 | } |
365 | } |
366 | |
367 | void QScatterSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration, |
368 | QEasingCurve &curve) |
369 | { |
370 | ScatterChartItem *item = static_cast<ScatterChartItem *>(m_item.data()); |
371 | Q_ASSERT(item); |
372 | |
373 | if (item->animation()) |
374 | item->animation()->stopAndDestroyLater(); |
375 | |
376 | if (options.testFlag(flag: QChart::SeriesAnimations)) |
377 | item->setAnimation(new ScatterAnimation(item, duration, curve)); |
378 | else |
379 | item->setAnimation(0); |
380 | |
381 | QAbstractSeriesPrivate::initializeAnimations(options, duration, curve); |
382 | } |
383 | |
384 | QT_CHARTS_END_NAMESPACE |
385 | |
386 | #include "moc_qscatterseries.cpp" |
387 | |