1 | // Copyright (C) 2023 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <QtGraphs/qxyseries.h> |
5 | #include <private/qxyseries_p.h> |
6 | #include <private/charthelpers_p.h> |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | /*! |
11 | \class QXYSeries |
12 | \inmodule QtGraphs |
13 | \ingroup graphs_2D |
14 | \brief The QXYSeries class is a parent class for all x & y series classes. |
15 | |
16 | In QXYSeries, data points are defined as a list of QPointF, defining X and Y positions. |
17 | |
18 | \sa QLineSeries, QScatterSeries |
19 | */ |
20 | /*! |
21 | \qmltype XYSeries |
22 | \nativetype QXYSeries |
23 | \inqmlmodule QtGraphs |
24 | \ingroup graphs_qml_2D |
25 | \inherits AbstractSeries |
26 | \brief A parent type for all x & y series types. |
27 | |
28 | In XYSeries, data points are defined as a list of point types, defining X and Y positions. |
29 | */ |
30 | |
31 | /*! |
32 | \fn void QXYSeries::pointReplaced(qsizetype index) |
33 | This signal is emitted when a point is replaced at the position specified by |
34 | \a index. |
35 | \sa replace() |
36 | */ |
37 | /*! |
38 | \qmlsignal XYSeries::pointReplaced(int index) |
39 | This signal is emitted when a point is replaced at the position specified by |
40 | \a index. |
41 | */ |
42 | |
43 | /*! |
44 | \fn void QXYSeries::pointsReplaced() |
45 | This signal is emitted when all points are replaced. |
46 | */ |
47 | /*! |
48 | \qmlsignal XYSeries::pointsReplaced() |
49 | This signal is emitted when all points are replaced. |
50 | */ |
51 | |
52 | /*! |
53 | \qmlsignal XYSeries::colorChanged(color color) |
54 | This signal is emitted when the line color changes to \a color. |
55 | */ |
56 | |
57 | /*! |
58 | \qmlsignal XYSeries::selectedColorChanged(color color) |
59 | This signal is emitted when the color of selected series changes to \a color. |
60 | */ |
61 | |
62 | /*! |
63 | \qmlsignal XYSeries::selectedPointsChanged() |
64 | This signal is emitted when the set of selected points changes. |
65 | */ |
66 | |
67 | /*! |
68 | \qmlsignal XYSeries::pointMarkerChanged() |
69 | This signal is emitted when a point is changed. |
70 | */ |
71 | |
72 | /*! |
73 | \qmlsignal XYSeries::draggableChanged() |
74 | This signal is emitted when a series becomes draggable by a mouse/touch or |
75 | becomes fixed. |
76 | */ |
77 | |
78 | QXYSeries::QXYSeries(QXYSeriesPrivate &dd, QObject *parent) |
79 | : QAbstractSeries(dd, parent) |
80 | { |
81 | QObject::connect(sender: this, signal: &QXYSeries::selectedPointsChanged, context: this, slot: &QAbstractSeries::update); |
82 | QObject::connect(sender: this, signal: &QXYSeries::pointAdded, context: this, slot: &QAbstractSeries::update); |
83 | QObject::connect(sender: this, signal: &QXYSeries::pointReplaced, context: this, slot: &QAbstractSeries::update); |
84 | QObject::connect(sender: this, signal: &QXYSeries::pointsReplaced, context: this, slot: &QAbstractSeries::update); |
85 | QObject::connect(sender: this, signal: &QXYSeries::pointRemoved, context: this, slot: &QAbstractSeries::update); |
86 | QObject::connect(sender: this, signal: &QXYSeries::pointsRemoved, context: this, slot: &QAbstractSeries::update); |
87 | } |
88 | |
89 | /*! |
90 | \qmlmethod XYSeries::append(real x, real y) |
91 | Appends a point with the coordinates \a x and \a y to the series. |
92 | */ |
93 | /*! |
94 | Appends a point with the coordinates \a x and \a y to the series. |
95 | */ |
96 | void QXYSeries::append(qreal x, qreal y) |
97 | { |
98 | append(point: QPointF(x, y)); |
99 | } |
100 | |
101 | /*! |
102 | \qmlmethod XYSeries::append(point point) |
103 | Appends a point with the coordinates \a point to the series. |
104 | */ |
105 | /*! |
106 | Appends a point with the coordinates \a point to the series. |
107 | */ |
108 | void QXYSeries::append(QPointF point) |
109 | { |
110 | Q_D(QXYSeries); |
111 | |
112 | if (isValidValue(point)) { |
113 | if (d->m_graphTransition && d->m_graphTransition->initialized() |
114 | && d->m_graphTransition->contains(type: QGraphAnimation::GraphAnimationType::GraphPoint)) { |
115 | d->m_graphTransition->stop(); |
116 | d->m_graphTransition->onPointChanged(type: QGraphTransition::TransitionType::PointAdded, |
117 | index: d->m_points.size(), |
118 | point); |
119 | } else { |
120 | d->m_points << point; |
121 | emit pointAdded(index: d->m_points.size() - 1); |
122 | emit countChanged(); |
123 | } |
124 | } |
125 | } |
126 | |
127 | /*! |
128 | \qmlmethod XYSeries::append(list<point> points) |
129 | Appends points with the coordinates \a points to the series. |
130 | */ |
131 | /*! |
132 | Appends points with the coordinates \a points to the series. |
133 | */ |
134 | void QXYSeries::append(const QList<QPointF> &points) |
135 | { |
136 | for (const QPointF &point : points) |
137 | append(point); |
138 | } |
139 | |
140 | /*! |
141 | \qmlmethod XYSeries::replace(real oldX, real oldY, real newX, real newY) |
142 | Replaces the point with the coordinates \a oldX and \a oldY with the point |
143 | with the coordinates \a newX and \a newY. Does nothing if the old point does |
144 | not exist. |
145 | */ |
146 | /*! |
147 | Replaces the point with the coordinates \a oldX and \a oldY with the point |
148 | with the coordinates \a newX and \a newY. Does nothing if the old point does |
149 | not exist. |
150 | */ |
151 | void QXYSeries::replace(qreal oldX, qreal oldY, qreal newX, qreal newY) |
152 | { |
153 | replace(oldPoint: QPointF(oldX, oldY), newPoint: QPointF(newX, newY)); |
154 | } |
155 | |
156 | /*! |
157 | \qmlmethod XYSeries::replace(point oldPoint, point newPoint) |
158 | Replaces the point with the coordinates \a oldPoint with the point |
159 | with the coordinates \a newPoint. Does nothing if the old point does |
160 | not exist. |
161 | */ |
162 | /*! |
163 | Replaces the point with the coordinates \a oldPoint with the point |
164 | with the coordinates \a newPoint. Does nothing if the old point does |
165 | not exist. |
166 | */ |
167 | void QXYSeries::replace(QPointF oldPoint, QPointF newPoint) |
168 | { |
169 | Q_D(QXYSeries); |
170 | qsizetype index = d->m_points.indexOf(t: oldPoint); |
171 | if (index == -1) |
172 | return; |
173 | replace(index, newPoint); |
174 | } |
175 | |
176 | /*! |
177 | \qmlmethod XYSeries::replace(int index, real newX, real newY) |
178 | Replaces the point at the position specified by \a index with the point |
179 | that has the coordinates \a newX and \a newY. |
180 | */ |
181 | /*! |
182 | Replaces the point at the position specified by \a index with the point |
183 | that has the coordinates \a newX and \a newY. |
184 | */ |
185 | void QXYSeries::replace(qsizetype index, qreal newX, qreal newY) |
186 | { |
187 | replace(index, newPoint: QPointF(newX, newY)); |
188 | } |
189 | |
190 | /*! |
191 | \qmlmethod XYSeries::replace(int index, point newPoint) |
192 | Replaces the point at the position specified by \a index with the point |
193 | that has the coordinates \a newPoint. |
194 | */ |
195 | /*! |
196 | Replaces the point at the position specified by \a index with the point |
197 | that has the coordinates \a newPoint. |
198 | */ |
199 | void QXYSeries::replace(qsizetype index, QPointF newPoint) |
200 | { |
201 | Q_D(QXYSeries); |
202 | |
203 | if (index < 0 || index >= d->m_points.size()) |
204 | return; |
205 | |
206 | if (isValidValue(point: newPoint)) { |
207 | if (d->m_graphTransition && d->m_graphTransition->initialized() |
208 | && d->m_graphTransition->contains(type: QGraphAnimation::GraphAnimationType::GraphPoint)) { |
209 | d->m_graphTransition->stop(); |
210 | d->m_graphTransition->onPointChanged(type: QGraphTransition::TransitionType::PointReplaced, |
211 | index, |
212 | point: newPoint); |
213 | } else { |
214 | d->m_points[index] = newPoint; |
215 | emit pointReplaced(index); |
216 | } |
217 | } |
218 | } |
219 | |
220 | /*! |
221 | \qmlmethod XYSeries::replace(list<point> points) |
222 | Replaces the current points with the points specified by \a points |
223 | \note This is much faster than replacing data points one by one, or first |
224 | clearing all data, and then appending the new data. Emits \l pointsReplaced |
225 | when the points have been replaced. |
226 | */ |
227 | /*! |
228 | Replaces the current points with the points specified by \a points |
229 | \note This is much faster than replacing data points one by one, or first |
230 | clearing all data, and then appending the new data. Emits \l pointsReplaced |
231 | when the points have been replaced. |
232 | */ |
233 | void QXYSeries::replace(const QList<QPointF> &points) |
234 | { |
235 | Q_D(QXYSeries); |
236 | bool hasDifferentSize = d->m_points.size() != points.size(); |
237 | d->m_points = points; |
238 | emit pointsReplaced(); |
239 | if (hasDifferentSize) |
240 | emit countChanged(); |
241 | } |
242 | |
243 | /*! |
244 | \qmlmethod XYSeries::remove(real x, real y) |
245 | Removes the point with the coordinates \a x and \a y from the series. Does |
246 | nothing if the point does not exist. |
247 | */ |
248 | /*! |
249 | Removes the point with the coordinates \a x and \a y from the series. Does |
250 | nothing if the point does not exist. |
251 | */ |
252 | void QXYSeries::remove(qreal x, qreal y) |
253 | { |
254 | remove(point: QPointF(x, y)); |
255 | } |
256 | |
257 | /*! |
258 | \qmlmethod XYSeries::remove(point point) |
259 | Removes the point with the coordinates \a point from the series. Does |
260 | nothing if the point does not exist. |
261 | */ |
262 | /*! |
263 | Removes the point with the coordinates \a point from the series. Does |
264 | nothing if the point does not exist. |
265 | */ |
266 | void QXYSeries::remove(QPointF point) |
267 | { |
268 | Q_D(QXYSeries); |
269 | qsizetype index = d->m_points.indexOf(t: point); |
270 | if (index == -1) |
271 | return; |
272 | remove(index); |
273 | } |
274 | |
275 | /*! |
276 | \qmlmethod XYSeries::remove(int index) |
277 | Removes the point at the position specified by \a index from the series. |
278 | */ |
279 | /*! |
280 | Removes the point at the position specified by \a index from the series. |
281 | */ |
282 | void QXYSeries::remove(qsizetype index) |
283 | { |
284 | Q_D(QXYSeries); |
285 | |
286 | if (index < 0 || index >= d->m_points.size()) |
287 | return; |
288 | |
289 | if (d->m_graphTransition && d->m_graphTransition->initialized() |
290 | && d->m_graphTransition->contains(type: QGraphAnimation::GraphAnimationType::GraphPoint)) { |
291 | d->m_graphTransition->stop(); |
292 | d->m_graphTransition->onPointChanged(type: QGraphTransition::TransitionType::PointRemoved, |
293 | index, |
294 | point: {}); |
295 | } else { |
296 | d->m_points.remove(i: index); |
297 | bool callSignal = false; |
298 | d->setPointSelected(index, selected: false, callSignal); |
299 | |
300 | emit pointRemoved(index); |
301 | emit countChanged(); |
302 | if (callSignal) |
303 | emit selectedPointsChanged(); |
304 | } |
305 | } |
306 | |
307 | /*! |
308 | \qmlmethod XYSeries::removeMultiple(int index, int count) |
309 | Removes the number of points specified by \a count from the series starting |
310 | at the position specified by \a index. |
311 | */ |
312 | /*! |
313 | Removes the number of points specified by \a count from the series starting |
314 | at the position specified by \a index. |
315 | */ |
316 | void QXYSeries::removeMultiple(qsizetype index, qsizetype count) |
317 | { |
318 | // This function doesn't overload remove as there is chance for it to get mixed up with |
319 | // remove(qreal, qreal) overload in some implicit casting cases. |
320 | Q_D(QXYSeries); |
321 | |
322 | if (index < 0 || count < 1 || index + count > d->m_points.size()) |
323 | return; |
324 | |
325 | if (count > 0) { |
326 | d->m_points.remove(i: index, n: count); |
327 | |
328 | bool callSignal = false; |
329 | if (!d->m_selectedPoints.empty()) { |
330 | QSet<qsizetype> selectedAfterRemoving; |
331 | |
332 | for (const qsizetype &selectedPointIndex : std::as_const(t&: d->m_selectedPoints)) { |
333 | if (selectedPointIndex < index) { |
334 | selectedAfterRemoving << selectedPointIndex; |
335 | } else if (selectedPointIndex >= index + count) { |
336 | selectedAfterRemoving << selectedPointIndex - int(count); |
337 | callSignal = true; |
338 | } else { |
339 | callSignal = true; |
340 | } |
341 | } |
342 | |
343 | d->m_selectedPoints = selectedAfterRemoving; |
344 | } |
345 | |
346 | emit pointsRemoved(index, count); |
347 | emit countChanged(); |
348 | if (callSignal) |
349 | emit selectedPointsChanged(); |
350 | } |
351 | } |
352 | |
353 | /*! |
354 | \qmlmethod bool XYSeries::take(point point) |
355 | Takes a point, specified by \a point, out of the series if found. Returns \c true if |
356 | the operation is successful. |
357 | */ |
358 | /*! |
359 | Takes a point, specified by \a point, out of the series if found. Returns \c true if |
360 | the operation is successful. |
361 | */ |
362 | bool QXYSeries::take(QPointF point) |
363 | { |
364 | Q_D(QXYSeries); |
365 | |
366 | for (int i = 0; i < d->m_points.size(); ++i) { |
367 | if (d->m_points[i] == point) { |
368 | d->m_points.removeAt(i); |
369 | return true; |
370 | } |
371 | } |
372 | |
373 | return false; |
374 | } |
375 | |
376 | /*! |
377 | \qmlmethod XYSeries::insert(int index, point point) |
378 | Inserts a point with the coordinates \a point to the position specified |
379 | by \a index in the series. If the index is 0 or less than 0, the point is |
380 | prepended to the list of points. If the index is equal to or greater than |
381 | than the number of points in the series, the point is appended to the |
382 | list of points. |
383 | */ |
384 | /*! |
385 | Inserts a point with the coordinates \a point to the position specified |
386 | by \a index in the series. If the index is 0 or less than 0, the point is |
387 | prepended to the list of points. If the index is equal to or greater than |
388 | than the number of points in the series, the point is appended to the |
389 | list of points. |
390 | */ |
391 | void QXYSeries::insert(qsizetype index, QPointF point) |
392 | { |
393 | Q_D(QXYSeries); |
394 | |
395 | if (isValidValue(point)) { |
396 | index = qMax(a: 0, b: qMin(a: index, b: d->m_points.size())); |
397 | |
398 | d->m_points.insert(i: index, t: point); |
399 | |
400 | bool callSignal = false; |
401 | if (!d->m_selectedPoints.isEmpty()) { |
402 | // if point was inserted we need to move already selected points by 1 |
403 | QSet<qsizetype> selectedAfterInsert; |
404 | for (const auto &value : std::as_const(t&: d->m_selectedPoints)) { |
405 | if (value >= index) { |
406 | selectedAfterInsert << value + 1; |
407 | callSignal = true; |
408 | } else { |
409 | selectedAfterInsert << value; |
410 | } |
411 | } |
412 | d->m_selectedPoints = selectedAfterInsert; |
413 | } |
414 | |
415 | emit pointAdded(index); |
416 | if (callSignal) |
417 | emit selectedPointsChanged(); |
418 | } |
419 | } |
420 | |
421 | /*! |
422 | \qmlmethod XYSeries::clear() |
423 | Removes all points from the series. |
424 | */ |
425 | /*! |
426 | Removes all points from the series. |
427 | */ |
428 | void QXYSeries::clear() |
429 | { |
430 | Q_D(QXYSeries); |
431 | removeMultiple(index: 0, count: d->m_points.size()); |
432 | } |
433 | |
434 | /*! |
435 | \qmlmethod bool XYSeries::isPointSelected(int index) |
436 | Returns true if point at given \a index is among selected points and false otherwise. |
437 | \note Selected points are drawn using the selected color if it was specified. |
438 | \sa selectedPoints, setPointSelected(), selectedColor |
439 | */ |
440 | /*! |
441 | Returns true if point at given \a index is among selected points and false otherwise. |
442 | \note Selected points are drawn using the selected color if it was specified. |
443 | \sa selectedPoints, setPointSelected(), setSelectedColor() |
444 | */ |
445 | bool QXYSeries::isPointSelected(qsizetype index) const |
446 | { |
447 | Q_D(const QXYSeries); |
448 | return d->isPointSelected(index); |
449 | } |
450 | |
451 | /*! |
452 | \qmlmethod XYSeries::selectPoint(int index) |
453 | Marks point at \a index as selected. |
454 | \note Emits QXYSeries::selectedPointsChanged |
455 | \sa setPointSelected() |
456 | */ |
457 | /*! |
458 | Marks point at \a index as selected. |
459 | \note Emits QXYSeries::selectedPointsChanged |
460 | \sa setPointSelected() |
461 | */ |
462 | void QXYSeries::selectPoint(qsizetype index) |
463 | { |
464 | setPointSelected(index, selected: true); |
465 | } |
466 | |
467 | /*! |
468 | \qmlmethod XYSeries::deselectPoint(int index) |
469 | Deselects point at given \a index. |
470 | \note Emits QXYSeries::selectedPointsChanged |
471 | \sa setPointSelected() |
472 | */ |
473 | /*! |
474 | Deselects point at given \a index. |
475 | \note Emits QXYSeries::selectedPointsChanged |
476 | \sa setPointSelected() |
477 | */ |
478 | void QXYSeries::deselectPoint(qsizetype index) |
479 | { |
480 | setPointSelected(index, selected: false); |
481 | } |
482 | |
483 | /*! |
484 | \qmlmethod XYSeries::setPointSelected(int index, bool selected) |
485 | Marks point at given \a index as either selected or deselected as specified by \a selected. |
486 | \note Selected points are drawn using the selected color if it was specified. Emits QXYSeries::selectedPointsChanged |
487 | \sa selectAllPoints(), selectedColor |
488 | */ |
489 | /*! |
490 | Marks point at given \a index as either selected or deselected as specified by \a selected. |
491 | \note Selected points are drawn using the selected color if it was specified. Emits QXYSeries::selectedPointsChanged |
492 | \sa selectAllPoints(), setSelectedColor() |
493 | */ |
494 | void QXYSeries::setPointSelected(qsizetype index, bool selected) |
495 | { |
496 | Q_D(QXYSeries); |
497 | |
498 | bool callSignal = false; |
499 | d->setPointSelected(index, selected, callSignal); |
500 | |
501 | if (callSignal) |
502 | emit selectedPointsChanged(); |
503 | } |
504 | |
505 | /*! |
506 | \qmlmethod XYSeries::selectAllPoints() |
507 | Marks all points in the series as selected, |
508 | \note Emits QXYSeries::selectedPointsChanged |
509 | \sa setPointSelected() |
510 | */ |
511 | /*! |
512 | Marks all points in the series as selected, |
513 | \note Emits QXYSeries::selectedPointsChanged |
514 | \sa setPointSelected() |
515 | */ |
516 | void QXYSeries::selectAllPoints() |
517 | { |
518 | Q_D(QXYSeries); |
519 | |
520 | bool callSignal = false; |
521 | for (int i = 0; i < d->m_points.size(); ++i) |
522 | d->setPointSelected(index: i, selected: true, callSignal); |
523 | |
524 | if (callSignal) |
525 | emit selectedPointsChanged(); |
526 | } |
527 | |
528 | /*! |
529 | \qmlmethod XYSeries::deselectAllPoints() |
530 | Deselects all points in the series. |
531 | \note Emits QXYSeries::selectedPointsChanged |
532 | \sa setPointSelected() |
533 | */ |
534 | /*! |
535 | Deselects all points in the series. |
536 | \note Emits QXYSeries::selectedPointsChanged |
537 | \sa setPointSelected() |
538 | */ |
539 | void QXYSeries::deselectAllPoints() |
540 | { |
541 | Q_D(QXYSeries); |
542 | |
543 | bool callSignal = false; |
544 | for (int i = 0; i < d->m_points.size(); ++i) |
545 | d->setPointSelected(index: i, selected: false, callSignal); |
546 | |
547 | if (callSignal) |
548 | emit selectedPointsChanged(); |
549 | } |
550 | |
551 | /*! |
552 | \qmlmethod XYSeries::selectPoints(list<int> indexes) |
553 | Marks multiple points passed in a \a indexes list as selected. |
554 | \note Emits QXYSeries::selectedPointsChanged |
555 | \sa setPointSelected() |
556 | */ |
557 | /*! |
558 | Marks multiple points passed in a \a indexes list as selected. |
559 | \note Emits QXYSeries::selectedPointsChanged |
560 | \sa setPointSelected() |
561 | */ |
562 | void QXYSeries::selectPoints(const QList<qsizetype> &indexes) |
563 | { |
564 | Q_D(QXYSeries); |
565 | |
566 | bool callSignal = false; |
567 | for (const qsizetype &index : indexes) |
568 | d->setPointSelected(index, selected: true, callSignal); |
569 | |
570 | if (callSignal) |
571 | emit selectedPointsChanged(); |
572 | } |
573 | |
574 | /*! |
575 | \qmlmethod XYSeries::deselectPoints(list<int> indexes) |
576 | Marks multiple points passed in a \a indexes list as deselected. |
577 | \note Emits QXYSeries::selectedPointsChanged |
578 | \sa setPointSelected() |
579 | */ |
580 | /*! |
581 | Marks multiple points passed in a \a indexes list as deselected. |
582 | \note Emits QXYSeries::selectedPointsChanged |
583 | \sa setPointSelected() |
584 | */ |
585 | void QXYSeries::deselectPoints(const QList<qsizetype> &indexes) |
586 | { |
587 | Q_D(QXYSeries); |
588 | |
589 | bool callSignal = false; |
590 | for (const qsizetype &index : indexes) |
591 | d->setPointSelected(index, selected: false, callSignal); |
592 | |
593 | if (callSignal) |
594 | emit selectedPointsChanged(); |
595 | } |
596 | |
597 | /*! |
598 | \qmlmethod XYSeries::toggleSelection(list<int> indexes) |
599 | Changes selection state of points at given \a indexes to the opposite one. |
600 | \note Emits QXYSeries::selectedPointsChanged |
601 | \sa setPointSelected() |
602 | */ |
603 | /*! |
604 | Changes selection state of points at given \a indexes to the opposite one. |
605 | \note Emits QXYSeries::selectedPointsChanged |
606 | \sa setPointSelected() |
607 | */ |
608 | void QXYSeries::toggleSelection(const QList<qsizetype> &indexes) |
609 | { |
610 | Q_D(QXYSeries); |
611 | |
612 | bool callSignal = false; |
613 | for (const qsizetype &index : indexes) |
614 | d->setPointSelected(index, selected: !isPointSelected(index), callSignal); |
615 | |
616 | if (callSignal) |
617 | emit selectedPointsChanged(); |
618 | } |
619 | |
620 | /*! |
621 | \property QXYSeries::selectedPoints |
622 | \brief The indexes of the points which are currently selected. |
623 | */ |
624 | /*! |
625 | \qmlproperty list<int> XYSeries::selectedPoints |
626 | The indexes of the points which are currently selected. |
627 | */ |
628 | |
629 | /*! |
630 | Returns a list of points indexes marked as selected. |
631 | Selected points are visible regardless of points visibility. |
632 | \sa setPointSelected() |
633 | */ |
634 | QList<qsizetype> QXYSeries::selectedPoints() const |
635 | { |
636 | Q_D(const QXYSeries); |
637 | return QList<qsizetype>(d->m_selectedPoints.begin(), d->m_selectedPoints.end()); |
638 | } |
639 | |
640 | /*! |
641 | \property QXYSeries::count |
642 | \brief Returns the number of data points in a series. |
643 | */ |
644 | /*! |
645 | \qmlproperty int XYSeries::count |
646 | Returns the number of data points in a series. |
647 | */ |
648 | qsizetype QXYSeries::count() const |
649 | { |
650 | Q_D(const QXYSeries); |
651 | return d->m_points.size(); |
652 | } |
653 | |
654 | /*! |
655 | Returns the points in the series. |
656 | */ |
657 | QList<QPointF> QXYSeries::points() const |
658 | { |
659 | Q_D(const QXYSeries); |
660 | return d->m_points; |
661 | } |
662 | |
663 | /*! |
664 | \qmlmethod point XYSeries::at(int index) |
665 | Returns the point at the position specified by \a index. Returns (0, 0) if |
666 | the index is not valid. |
667 | */ |
668 | /*! |
669 | Returns the point at the position specified by \a index. Returns (0, 0) if |
670 | the index is not valid. |
671 | */ |
672 | QPointF QXYSeries::at(qsizetype index) const |
673 | { |
674 | Q_D(const QXYSeries); |
675 | return d->m_points.at(i: index); |
676 | } |
677 | |
678 | /*! |
679 | \qmlmethod int XYSeries::find(point point) |
680 | Finds and returns the index of the first matching point found as defined by \a point. |
681 | Returns -1 if the point is not found. |
682 | */ |
683 | /*! |
684 | Finds and returns the index of the first matching point found as defined by \a point. |
685 | Returns -1 if the point is not found. |
686 | */ |
687 | qsizetype QXYSeries::find(QPointF point) const |
688 | { |
689 | Q_D(const QXYSeries); |
690 | |
691 | for (qsizetype i = 0; i < d->m_points.size(); ++i) { |
692 | if (d->m_points[i] == point) |
693 | return i; |
694 | } |
695 | |
696 | return -1; |
697 | } |
698 | |
699 | QXYSeries::~QXYSeries() {} |
700 | |
701 | /*! |
702 | \property QXYSeries::color |
703 | \brief The main color of the series. For QLineSeries this means the line color and |
704 | for QScatterSeries the color of the point. |
705 | */ |
706 | /*! |
707 | \qmlproperty color XYSeries::color |
708 | The main color of the series. For LineSeries this means the line color and |
709 | for ScatterSeries the color of the point |
710 | */ |
711 | void QXYSeries::setColor(QColor newColor) |
712 | { |
713 | Q_D(QXYSeries); |
714 | if (color() != newColor) { |
715 | d->m_color = newColor; |
716 | emit colorChanged(color: newColor); |
717 | } |
718 | } |
719 | |
720 | QColor QXYSeries::color() const |
721 | { |
722 | Q_D(const QXYSeries); |
723 | return d->m_color; |
724 | } |
725 | |
726 | /*! |
727 | \property QXYSeries::selectedColor |
728 | \brief The main color of the selected series. For QLineSeries this means the line color and |
729 | for QScatterSeries the color of the point. |
730 | */ |
731 | /*! |
732 | \qmlproperty color XYSeries::selectedColor |
733 | The main color of the selected series. For LineSeries this means the line color and |
734 | for ScatterSeries the color of the point |
735 | */ |
736 | void QXYSeries::setSelectedColor(QColor color) |
737 | { |
738 | Q_D(QXYSeries); |
739 | if (selectedColor() != color) { |
740 | d->m_selectedColor = color; |
741 | emit selectedColorChanged(color); |
742 | } |
743 | } |
744 | |
745 | QColor QXYSeries::selectedColor() const |
746 | { |
747 | Q_D(const QXYSeries); |
748 | return d->m_selectedColor; |
749 | } |
750 | |
751 | /*! |
752 | \property QXYSeries::pointDelegate |
753 | \brief A custom QML Component used as a marker for data points. |
754 | |
755 | The dynamic properties available for this component are: |
756 | |
757 | \table |
758 | \header |
759 | \li Type |
760 | \li Name |
761 | \li Description |
762 | \row |
763 | \li bool |
764 | \li pointSelected |
765 | \li This value is true when the point is selected, meaning that the point index |
766 | is in \l{QXYSeries::selectedPoints}. |
767 | \row |
768 | \li QColor |
769 | \li pointColor |
770 | \li The color of the series. This value comes either from the \l QGraphsTheme |
771 | or from \l{QXYSeries::color} if the \l QXYSeries overrides the color. |
772 | \row |
773 | \li QColor |
774 | \li pointBorderColor |
775 | \li The border color of the series. This value comes from the \l QGraphsTheme. |
776 | \row |
777 | \li QColor |
778 | \li pointSelectedColor |
779 | \li The selected color of the series. This value comes either from the \l QGraphsTheme |
780 | or from \l{QXYSeries::selectedColor} if the \l QXYSeries overrides the color. |
781 | \row |
782 | \li qreal |
783 | \li pointBorderWidth |
784 | \li The border width of the series. This value comes from the \l QGraphsTheme. |
785 | \row |
786 | \li qreal |
787 | \li pointValueX |
788 | \li The value of the \l{QXYPoint::x} at this position. |
789 | \row |
790 | \li qreal |
791 | \li pointValueY |
792 | \li The value of the \l{QXYPoint::y} at this position. |
793 | \endtable |
794 | |
795 | To use any of these, add property with the defined name into your custom component. |
796 | For example \c{"property color pointColor"} and \c{"property real pointValueX"}. |
797 | */ |
798 | /*! |
799 | \qmlproperty Component XYSeries::pointDelegate |
800 | A custom QML Component used as a marker for data points. |
801 | |
802 | The dynamic properties available for this component are: |
803 | |
804 | \table |
805 | \header |
806 | \li Type |
807 | \li Name |
808 | \li Description |
809 | \row |
810 | \li bool |
811 | \li pointSelected |
812 | \li This value is true when the point is selected. |
813 | \row |
814 | \li Color |
815 | \li pointColor |
816 | \li The color of the series. This value comes either from the \l GraphsTheme |
817 | or from \l{XYSeries::color} if the \l XYSeries overrides the color. |
818 | \row |
819 | \li Color |
820 | \li pointBorderColor |
821 | \li The border color of the series. This value comes from the \l GraphsTheme. |
822 | \row |
823 | \li Color |
824 | \li pointSelectedColor |
825 | \li The selected color of the series. This value comes either from the \l GraphsTheme |
826 | or from \l{XYSeries::selectedColor} if the \l XYSeries overrides the color. |
827 | \row |
828 | \li real |
829 | \li pointBorderWidth |
830 | \li The border width of the series. This value comes from the \l GraphsTheme. |
831 | \row |
832 | \li real |
833 | \li pointValueX |
834 | \li The value of the \l{XYPoint::x} at this position. |
835 | \row |
836 | \li real |
837 | \li pointValueY |
838 | \li The value of the \l{XYPoint::y} at this position. |
839 | \endtable |
840 | |
841 | To use any of these, add property with the defined name into your custom component. |
842 | For example \c{"property color pointColor"} and \c{"property real pointValueX"}. |
843 | */ |
844 | QQmlComponent *QXYSeries::pointDelegate() const |
845 | { |
846 | Q_D(const QXYSeries); |
847 | return d->m_pointDelegate; |
848 | } |
849 | |
850 | void QXYSeries::setPointDelegate(QQmlComponent *newPointDelegate) |
851 | { |
852 | Q_D(QXYSeries); |
853 | if (d->m_pointDelegate == newPointDelegate) |
854 | return; |
855 | d->m_pointDelegate = newPointDelegate; |
856 | emit pointDelegateChanged(); |
857 | emit update(); |
858 | } |
859 | |
860 | /*! |
861 | \property QXYSeries::draggable |
862 | \brief Controls if the series is draggable. |
863 | |
864 | Controls if the series can be dragged with mouse/touch. |
865 | By default, \a draggable is set to \c false. |
866 | */ |
867 | /*! |
868 | \qmlproperty bool QXYSeries::draggable |
869 | Controls if the series can be dragged with mouse/touch. |
870 | By default, \a draggable is set to \c false. |
871 | */ |
872 | bool QXYSeries::isDraggable() const |
873 | { |
874 | Q_D(const QXYSeries); |
875 | return d->m_draggable; |
876 | } |
877 | |
878 | void QXYSeries::setDraggable(bool newDraggable) |
879 | { |
880 | Q_D(QXYSeries); |
881 | if (d->m_draggable == newDraggable) |
882 | return; |
883 | d->m_draggable = newDraggable; |
884 | emit draggableChanged(); |
885 | } |
886 | |
887 | QXYSeries &QXYSeries::operator<<(QPointF point) |
888 | { |
889 | append(point); |
890 | return *this; |
891 | } |
892 | |
893 | QXYSeries &QXYSeries::operator<< (const QList<QPointF>& points) |
894 | { |
895 | append(points); |
896 | return *this; |
897 | } |
898 | |
899 | QXYSeriesPrivate::QXYSeriesPrivate() {} |
900 | |
901 | void QXYSeriesPrivate::setPointSelected(qsizetype index, bool selected, bool &callSignal) |
902 | { |
903 | if (index < 0 || index > m_points.size() - 1) |
904 | return; |
905 | |
906 | if (selected) { |
907 | if (!isPointSelected(index)) { |
908 | m_selectedPoints << index; |
909 | callSignal = true; |
910 | } |
911 | } else { |
912 | if (isPointSelected(index)) { |
913 | m_selectedPoints.remove(value: index); |
914 | callSignal = true; |
915 | } |
916 | } |
917 | } |
918 | |
919 | bool QXYSeriesPrivate::isPointSelected(qsizetype index) const |
920 | { |
921 | return m_selectedPoints.contains(value: index); |
922 | } |
923 | |
924 | QT_END_NAMESPACE |
925 |
Definitions
- QXYSeries
- append
- append
- append
- replace
- replace
- replace
- replace
- replace
- remove
- remove
- remove
- removeMultiple
- take
- insert
- clear
- isPointSelected
- selectPoint
- deselectPoint
- setPointSelected
- selectAllPoints
- deselectAllPoints
- selectPoints
- deselectPoints
- toggleSelection
- selectedPoints
- count
- points
- at
- find
- ~QXYSeries
- setColor
- color
- setSelectedColor
- selectedColor
- pointDelegate
- setPointDelegate
- isDraggable
- setDraggable
- operator<<
- operator<<
- QXYSeriesPrivate
- setPointSelected
Start learning QML with our Intro Training
Find out more