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
8QT_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
78QXYSeries::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*/
96void 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*/
108void 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*/
134void 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*/
151void 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*/
167void 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*/
185void 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*/
199void 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*/
233void 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*/
252void 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*/
266void 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*/
282void 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*/
316void 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*/
362bool 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*/
391void 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*/
428void 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 */
445bool 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 */
462void 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 */
478void 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 */
494void 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 */
516void 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 */
539void 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 */
562void 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 */
585void 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 */
608void 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 */
634QList<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*/
648qsizetype 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*/
657QList<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*/
672QPointF 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*/
687qsizetype 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
699QXYSeries::~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*/
711void 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
720QColor 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*/
736void 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
745QColor 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*/
844QQmlComponent *QXYSeries::pointDelegate() const
845{
846 Q_D(const QXYSeries);
847 return d->m_pointDelegate;
848}
849
850void 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*/
872bool QXYSeries::isDraggable() const
873{
874 Q_D(const QXYSeries);
875 return d->m_draggable;
876}
877
878void 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
887QXYSeries &QXYSeries::operator<<(QPointF point)
888{
889 append(point);
890 return *this;
891}
892
893QXYSeries &QXYSeries::operator<< (const QList<QPointF>& points)
894{
895 append(points);
896 return *this;
897}
898
899QXYSeriesPrivate::QXYSeriesPrivate() {}
900
901void 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
919bool QXYSeriesPrivate::isPointSelected(qsizetype index) const
920{
921 return m_selectedPoints.contains(value: index);
922}
923
924QT_END_NAMESPACE
925

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtgraphs/src/graphs2d/xychart/qxyseries.cpp