##// END OF EJS Templates
Further animation fixes...
Miikka Heikkinen -
r2492:5a6d23b6b72f
parent child
Show More
@@ -0,0 +1,50
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #include "scatteranimation_p.h"
22 #include "scatterchartitem_p.h"
23 #include <QDebug>
24
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
27 ScatterAnimation::ScatterAnimation(ScatterChartItem *item)
28 : XYAnimation(item)
29 {
30 }
31
32 ScatterAnimation::~ScatterAnimation()
33 {
34 }
35
36 void ScatterAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
37 {
38 XYAnimation::updateState(newState, oldState);
39
40 if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped
41 && animationType() == RemovePointAnimation) {
42 // Removing a point from scatter chart will keep extra marker item after animation stops.
43 // Also, if the removed point was not the last one in series, points after the removed one
44 // will report wrong coordinates when clicked. To fix these issues, update geometry after
45 // point removal animation has finished.
46 chartItem()->updateGeometry();
47 }
48 }
49
50 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,50
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 // W A R N I N G
22 // -------------
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
27 //
28 // We mean it.
29
30 #ifndef SCATTERANIMATION_P_H
31 #define SCATTERANIMATION_P_H
32 #include "xyanimation_p.h"
33
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35
36 class ScatterChartItem;
37
38 class ScatterAnimation : public XYAnimation
39 {
40 public:
41 ScatterAnimation(ScatterChartItem *item);
42 ~ScatterAnimation();
43
44 protected:
45 void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
46 };
47
48 QTCOMMERCIALCHART_END_NAMESPACE
49
50 #endif
@@ -1,19 +1,21
1 INCLUDEPATH += $$PWD
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
2 DEPENDPATH += $$PWD
3
3
4 SOURCES += \
4 SOURCES += \
5 $$PWD/axisanimation.cpp \
5 $$PWD/axisanimation.cpp \
6 $$PWD/xyanimation.cpp \
6 $$PWD/xyanimation.cpp \
7 $$PWD/pieanimation.cpp \
7 $$PWD/pieanimation.cpp \
8 $$PWD/piesliceanimation.cpp \
8 $$PWD/piesliceanimation.cpp \
9 $$PWD/splineanimation.cpp \
9 $$PWD/splineanimation.cpp \
10 $$PWD/baranimation.cpp
10 $$PWD/baranimation.cpp \
11 $$PWD/scatteranimation.cpp
11
12
12 PRIVATE_HEADERS += \
13 PRIVATE_HEADERS += \
13 $$PWD/axisanimation_p.h \
14 $$PWD/axisanimation_p.h \
14 $$PWD/chartanimation_p.h \
15 $$PWD/chartanimation_p.h \
15 $$PWD/xyanimation_p.h \
16 $$PWD/xyanimation_p.h \
16 $$PWD/pieanimation_p.h \
17 $$PWD/pieanimation_p.h \
17 $$PWD/piesliceanimation_p.h \
18 $$PWD/piesliceanimation_p.h \
18 $$PWD/splineanimation_p.h \
19 $$PWD/splineanimation_p.h \
19 $$PWD/baranimation_p.h
20 $$PWD/baranimation_p.h \
21 $$PWD/scatteranimation_p.h
@@ -1,204 +1,210
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "splineanimation_p.h"
21 #include "splineanimation_p.h"
22 #include "splinechartitem_p.h"
22 #include "splinechartitem_p.h"
23 #include <QDebug>
23 #include <QDebug>
24
24
25 Q_DECLARE_METATYPE(QVector<QPointF>)
25 Q_DECLARE_METATYPE(QVector<QPointF>)
26 Q_DECLARE_METATYPE(SplineVector)
26 Q_DECLARE_METATYPE(SplineVector)
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 SplineAnimation::SplineAnimation(SplineChartItem *item)
30 SplineAnimation::SplineAnimation(SplineChartItem *item)
31 : XYAnimation(item),
31 : XYAnimation(item),
32 m_item(item),
32 m_item(item),
33 m_valid(false)
33 m_valid(false)
34 {
34 {
35 }
35 }
36
36
37 SplineAnimation::~SplineAnimation()
37 SplineAnimation::~SplineAnimation()
38 {
38 {
39 }
39 }
40
40
41 void SplineAnimation::setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
41 void SplineAnimation::setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
42 {
42 {
43 if (newPoints.count() * 2 - 2 != newControlPoints.count() || newControlPoints.count() < 2) {
43 if (newPoints.count() * 2 - 2 != newControlPoints.count() || newControlPoints.count() < 2) {
44 m_valid = false;
44 m_valid = false;
45 m_dirty = false;
45 m_dirty = false;
46 m_item->setGeometryPoints(newPoints);
46 m_item->setGeometryPoints(newPoints);
47 m_item->setControlGeometryPoints(newControlPoints);
47 m_item->setControlGeometryPoints(newControlPoints);
48 m_item->setDirty(false);
48 m_item->setDirty(false);
49 m_item->updateGeometry();
49 m_item->updateGeometry();
50 return;
50 return;
51 }
51 }
52
52
53 m_type = NewAnimation;
53 m_type = NewAnimation;
54
54
55 if (state() != QAbstractAnimation::Stopped) {
55 if (state() != QAbstractAnimation::Stopped) {
56 stop();
56 stop();
57 m_dirty = false;
57 m_dirty = false;
58 }
58 }
59
59
60 if (!m_dirty) {
60 if (!m_dirty) {
61 m_dirty = true;
61 m_dirty = true;
62 m_oldSpline.first = oldPoints;
62 m_oldSpline.first = oldPoints;
63 m_oldSpline.second = oldControlPoints;
63 m_oldSpline.second = oldControlPoints;
64 }
64 }
65
65
66 m_newSpline.first = newPoints;
66 m_newSpline.first = newPoints;
67 m_newSpline.second = newControlPoints;
67 m_newSpline.second = newControlPoints;
68
68
69
69
70 int x = m_oldSpline.first.count();
70 int x = m_oldSpline.first.count();
71 int y = m_newSpline.first.count();
71 int y = m_newSpline.first.count();
72
72
73 if (x - y == 1 && index >= 0 && y > 0) {
73 if (x - y == 1 && index >= 0 && y > 0) {
74 //remove point
74 //remove point
75 if (index > 0) {
75 if (index > 0) {
76 m_newSpline.first.insert(index, newPoints[index - 1]);
76 m_newSpline.first.insert(index, newPoints[index - 1]);
77 m_newSpline.second.insert((index - 1) * 2, newPoints[index - 1]);
77 m_newSpline.second.insert((index - 1) * 2, newPoints[index - 1]);
78 m_newSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]);
78 m_newSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]);
79 } else {
79 } else {
80 m_newSpline.first.insert(index, newPoints[index]);
80 m_newSpline.first.insert(0, newPoints[index]);
81 m_newSpline.second.insert(index * 2, newPoints[index]);
81 m_newSpline.second.insert(0, newPoints[index]);
82 m_newSpline.second.insert(index * 2 + 1, newPoints[index]);
82 m_newSpline.second.insert(1, newPoints[index]);
83 }
83 }
84 m_index = index;
84 m_index = index;
85 m_type = RemovePointAnimation;
85 m_type = RemovePointAnimation;
86 }
86 }
87
87
88 if (x - y == -1 && index >= 0) {
88 if (x - y == -1 && index >= 0) {
89 //add point
89 //add point
90 if (index > 0) {
90 if (index > 0) {
91 m_oldSpline.first.insert(index, newPoints[index - 1]);
91 m_oldSpline.first.insert(index, newPoints[index - 1]);
92 m_oldSpline.second.insert((index - 1) * 2, newPoints[index - 1]);
92 m_oldSpline.second.insert((index - 1) * 2, newPoints[index - 1]);
93 m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]);
93 m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]);
94 } else {
94 } else {
95 m_oldSpline.first.insert(index, newPoints[index]);
95 m_oldSpline.first.insert(0, newPoints[index]);
96 m_oldSpline.second.insert((index - 1) * 2, newPoints[index]);
96 m_oldSpline.second.insert(0, newPoints[index]);
97 m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index]);
97 m_oldSpline.second.insert(1, newPoints[index]);
98 }
98 }
99 m_index = index;
99 m_index = index;
100 m_type = AddPointAnimation;
100 m_type = AddPointAnimation;
101 }
101 }
102
102
103 x = m_oldSpline.first.count();
103 x = m_oldSpline.first.count();
104 y = m_newSpline.first.count();
104 y = m_newSpline.first.count();
105
105
106 if (x != y) {
106 if (x != y) {
107 m_type = NewAnimation;
107 m_type = NewAnimation;
108 } else if (m_type == NewAnimation) {
108 } else if (m_type == NewAnimation) {
109 m_type = ReplacePointAnimation;
109 m_type = ReplacePointAnimation;
110 }
110 }
111
111
112
112
113 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
113 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
114 setKeyValueAt(1.0, qVariantFromValue(m_newSpline));
114 setKeyValueAt(1.0, qVariantFromValue(m_newSpline));
115
115
116 m_valid = true;
116 m_valid = true;
117
117
118 }
118 }
119
119
120 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
120 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
121 {
121 {
122
122
123 SplineVector startPair = qvariant_cast< SplineVector >(start);
123 SplineVector startPair = qvariant_cast< SplineVector >(start);
124 SplineVector endPair = qvariant_cast< SplineVector >(end);
124 SplineVector endPair = qvariant_cast< SplineVector >(end);
125 SplineVector result;
125 SplineVector result;
126
126
127 switch (animationType()) {
127 switch (animationType()) {
128 case RemovePointAnimation:
128 case RemovePointAnimation:
129 case AddPointAnimation:
129 case AddPointAnimation:
130 case ReplacePointAnimation: {
130 case ReplacePointAnimation: {
131 if (startPair.first.count() != endPair.first.count())
131 if (startPair.first.count() != endPair.first.count())
132 break;
132 break;
133 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
133 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
134 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
134 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
135 for (int i = 0; i < endPair.first.count(); i++) {
135 for (int i = 0; i < endPair.first.count(); i++) {
136 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
136 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
137 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
137 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
138 result.first << QPointF(x, y);
138 result.first << QPointF(x, y);
139 if (i + 1 >= endPair.first.count())
139 if (i + 1 >= endPair.first.count())
140 continue;
140 continue;
141 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
141 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
142 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
142 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
143 result.second << QPointF(x, y);
143 result.second << QPointF(x, y);
144 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
144 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
145 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
145 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
146 result.second << QPointF(x, y);
146 result.second << QPointF(x, y);
147 }
147 }
148 }
148 }
149 break;
149 break;
150 case NewAnimation: {
150 case NewAnimation: {
151 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
151 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
152 int count = endPair.first.count() * qBound(qreal(0), progress, qreal(1));
152 int count = endPair.first.count() * qBound(qreal(0), progress, qreal(1));
153 for (int i = 0; i < count; i++) {
153 for (int i = 0; i < count; i++) {
154 result.first << endPair.first[i];
154 result.first << endPair.first[i];
155 if (i + 1 == count)
155 if (i + 1 == count)
156 break;
156 break;
157 result.second << endPair.second[2 * i];
157 result.second << endPair.second[2 * i];
158 result.second << endPair.second[2 * i + 1];
158 result.second << endPair.second[2 * i + 1];
159 }
159 }
160 }
160 }
161 break;
161 break;
162 default:
162 default:
163 qWarning() << "Unknown type of animation";
163 qWarning() << "Unknown type of animation";
164 break;
164 break;
165 }
165 }
166
166
167 return qVariantFromValue(result);
167 return qVariantFromValue(result);
168 }
168 }
169
169
170 void SplineAnimation::updateCurrentValue(const QVariant &value)
170 void SplineAnimation::updateCurrentValue(const QVariant &value)
171 {
171 {
172 if (state() != QAbstractAnimation::Stopped && m_valid) { //workaround
172 if (state() != QAbstractAnimation::Stopped && m_valid) { //workaround
173 QPair<QVector<QPointF >, QVector<QPointF > > pair = qvariant_cast< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
173 QPair<QVector<QPointF >, QVector<QPointF > > pair = qvariant_cast< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
174 m_item->setGeometryPoints(pair.first);
174 m_item->setGeometryPoints(pair.first);
175 m_item->setControlGeometryPoints(pair.second);
175 m_item->setControlGeometryPoints(pair.second);
176 m_item->updateGeometry();
176 m_item->updateGeometry();
177 m_item->setDirty(true);
177 m_item->setDirty(true);
178 m_dirty = false;
178 m_dirty = false;
179 }
179 }
180 }
180 }
181
181
182 void SplineAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
182 void SplineAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
183 {
183 {
184 XYAnimation::updateState(newState, oldState);
184 XYAnimation::updateState(newState, oldState);
185
185
186 if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped) {
186 if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped) {
187 if (m_item->isDirty() && m_type == RemovePointAnimation) {
187 if (m_item->isDirty() && m_type == RemovePointAnimation) {
188 if (!m_newSpline.first.isEmpty()) {
188 if (!m_newSpline.first.isEmpty()) {
189 m_newSpline.first.remove(m_index);
189 if (m_index) {
190 m_newSpline.second.remove((m_index - 1) * 2);
190 m_newSpline.first.remove(m_index);
191 m_newSpline.second.remove((m_index - 1) * 2);
191 m_newSpline.second.remove((m_index - 1) * 2);
192 m_newSpline.second.remove((m_index - 1) * 2);
193 } else {
194 m_newSpline.first.remove(0);
195 m_newSpline.second.remove(0);
196 m_newSpline.second.remove(0);
197 }
192 }
198 }
193 m_item->setGeometryPoints(m_newSpline.first);
199 m_item->setGeometryPoints(m_newSpline.first);
194 m_item->setControlGeometryPoints(m_newSpline.second);
200 m_item->setControlGeometryPoints(m_newSpline.second);
195 }
201 }
196 }
202 }
197
203
198 if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) {
204 if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) {
199 if (!m_valid)
205 if (!m_valid)
200 stop();
206 stop();
201 }
207 }
202 }
208 }
203
209
204 QTCOMMERCIALCHART_END_NAMESPACE
210 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,66 +1,67
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef XYANIMATION_P_H
30 #ifndef XYANIMATION_P_H
31 #define XYANIMATION_P_H
31 #define XYANIMATION_P_H
32
32
33 #include "chartanimation_p.h"
33 #include "chartanimation_p.h"
34 #include <QPointF>
34 #include <QPointF>
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37
37
38 class XYChart;
38 class XYChart;
39
39
40 class XYAnimation : public ChartAnimation
40 class XYAnimation : public ChartAnimation
41 {
41 {
42 protected:
42 protected:
43 enum Animation { AddPointAnimation, RemovePointAnimation, ReplacePointAnimation, NewAnimation };
43 enum Animation { AddPointAnimation, RemovePointAnimation, ReplacePointAnimation, NewAnimation };
44 public:
44 public:
45 XYAnimation(XYChart *item);
45 XYAnimation(XYChart *item);
46 ~XYAnimation();
46 ~XYAnimation();
47 void setup(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints, int index = -1);
47 void setup(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints, int index = -1);
48 Animation animationType() const { return m_type; };
48 Animation animationType() const { return m_type; };
49
49
50 protected:
50 protected:
51 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const;
51 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const;
52 void updateCurrentValue(const QVariant &value);
52 void updateCurrentValue(const QVariant &value);
53 void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
53 void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
54 XYChart *chartItem() { return m_item; }
54 protected:
55 protected:
55 Animation m_type;
56 Animation m_type;
56 bool m_dirty;
57 bool m_dirty;
57 int m_index;
58 int m_index;
58 private:
59 private:
59 XYChart *m_item;
60 XYChart *m_item;
60 QVector<QPointF> m_oldPoints;
61 QVector<QPointF> m_oldPoints;
61 QVector<QPointF> m_newPoints;
62 QVector<QPointF> m_newPoints;
62 };
63 };
63
64
64 QTCOMMERCIALCHART_END_NAMESPACE
65 QTCOMMERCIALCHART_END_NAMESPACE
65
66
66 #endif
67 #endif
@@ -1,287 +1,301
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qscatterseries.h"
21 #include "qscatterseries.h"
22 #include "qscatterseries_p.h"
22 #include "qscatterseries_p.h"
23 #include "scatterchartitem_p.h"
23 #include "scatterchartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "scatteranimation_p.h"
26
27
27 /*!
28 /*!
28 \class QScatterSeries
29 \class QScatterSeries
29 \brief The QScatterSeries class is used for making scatter charts.
30 \brief The QScatterSeries class is used for making scatter charts.
30
31
31 \mainclass
32 \mainclass
32
33
33 The scatter data is displayed as a collection of points on the chart. Each point determines the position on the horizontal axis
34 The scatter data is displayed as a collection of points on the chart. Each point determines the position on the horizontal axis
34 and the vertical axis.
35 and the vertical axis.
35
36
36 \image examples_scatterchart.png
37 \image examples_scatterchart.png
37
38
38 Creating basic scatter chart is simple:
39 Creating basic scatter chart is simple:
39 \code
40 \code
40 QScatterSeries* series = new QScatterSeries();
41 QScatterSeries* series = new QScatterSeries();
41 series->append(0, 6);
42 series->append(0, 6);
42 series->append(2, 4);
43 series->append(2, 4);
43 ...
44 ...
44 chart->addSeries(series);
45 chart->addSeries(series);
45 \endcode
46 \endcode
46 */
47 */
47 /*!
48 /*!
48 \qmlclass ScatterSeries QScatterSeries
49 \qmlclass ScatterSeries QScatterSeries
49 \inherits XYSeries
50 \inherits XYSeries
50
51
51 The following QML shows how to create a chart with two simple scatter series:
52 The following QML shows how to create a chart with two simple scatter series:
52 \snippet ../demos/qmlchart/qml/qmlchart/View5.qml 1
53 \snippet ../demos/qmlchart/qml/qmlchart/View5.qml 1
53
54
54 \beginfloatleft
55 \beginfloatleft
55 \image demos_qmlchart5.png
56 \image demos_qmlchart5.png
56 \endfloat
57 \endfloat
57 \clearfloat
58 \clearfloat
58 */
59 */
59
60
60 /*!
61 /*!
61 \enum QScatterSeries::MarkerShape
62 \enum QScatterSeries::MarkerShape
62
63
63 This enum describes the shape used when rendering marker items.
64 This enum describes the shape used when rendering marker items.
64
65
65 \value MarkerShapeCircle
66 \value MarkerShapeCircle
66 \value MarkerShapeRectangle
67 \value MarkerShapeRectangle
67 */
68 */
68
69
69 /*!
70 /*!
70 \property QScatterSeries::color
71 \property QScatterSeries::color
71 Fill (brush) color of the series. This is a convenience property for modifying the color of brush.
72 Fill (brush) color of the series. This is a convenience property for modifying the color of brush.
72 \sa QScatterSeries::brush()
73 \sa QScatterSeries::brush()
73 */
74 */
74
75
75 /*!
76 /*!
76 \property QScatterSeries::borderColor
77 \property QScatterSeries::borderColor
77 Line (pen) color of the series. This is a convenience property for modifying the color of pen.
78 Line (pen) color of the series. This is a convenience property for modifying the color of pen.
78 \sa QScatterSeries::pen()
79 \sa QScatterSeries::pen()
79 */
80 */
80 /*!
81 /*!
81 \qmlproperty color ScatterSeries::borderColor
82 \qmlproperty color ScatterSeries::borderColor
82 Border (pen) color of the series.
83 Border (pen) color of the series.
83 */
84 */
84
85
85 /*!
86 /*!
86 \qmlproperty real ScatterSeries::borderWidth
87 \qmlproperty real ScatterSeries::borderWidth
87 The width of the border line. By default the width is 2.0.
88 The width of the border line. By default the width is 2.0.
88 */
89 */
89
90
90 /*!
91 /*!
91 \property QScatterSeries::markerShape
92 \property QScatterSeries::markerShape
92 Defines the shape of the marker used to draw the points in the series. The default shape is MarkerShapeCircle.
93 Defines the shape of the marker used to draw the points in the series. The default shape is MarkerShapeCircle.
93 */
94 */
94 /*!
95 /*!
95 \qmlproperty MarkerShape ScatterSeries::markerShape
96 \qmlproperty MarkerShape ScatterSeries::markerShape
96 Defines the shape of the marker used to draw the points in the series. One of ScatterSeries
97 Defines the shape of the marker used to draw the points in the series. One of ScatterSeries
97 ScatterSeries.MarkerShapeCircle or ScatterSeries.MarkerShapeRectangle.
98 ScatterSeries.MarkerShapeCircle or ScatterSeries.MarkerShapeRectangle.
98 The default shape is ScatterSeries.MarkerShapeCircle.
99 The default shape is ScatterSeries.MarkerShapeCircle.
99 */
100 */
100
101
101 /*!
102 /*!
102 \property QScatterSeries::markerSize
103 \property QScatterSeries::markerSize
103 Defines the size of the marker used to draw the points in the series. The default size is 15.0.
104 Defines the size of the marker used to draw the points in the series. The default size is 15.0.
104 */
105 */
105 /*!
106 /*!
106 \qmlproperty real ScatterSeries::markerSize
107 \qmlproperty real ScatterSeries::markerSize
107 Defines the size of the marker used to draw the points in the series. The default size is 15.0.
108 Defines the size of the marker used to draw the points in the series. The default size is 15.0.
108 */
109 */
109
110
110 /*!
111 /*!
111 \fn void QScatterSeries::colorChanged(QColor color)
112 \fn void QScatterSeries::colorChanged(QColor color)
112 Signal is emitted when the fill (brush) color has changed to \a color.
113 Signal is emitted when the fill (brush) color has changed to \a color.
113 */
114 */
114
115
115 /*!
116 /*!
116 \fn void QScatterSeries::borderColorChanged(QColor color)
117 \fn void QScatterSeries::borderColorChanged(QColor color)
117 Signal is emitted when the line (pen) color has changed to \a color.
118 Signal is emitted when the line (pen) color has changed to \a color.
118 */
119 */
119 /*!
120 /*!
120 \qmlsignal ScatterSeries::borderColorChanged(color color)
121 \qmlsignal ScatterSeries::borderColorChanged(color color)
121 Signal is emitted when the line (pen) color has changed to \a color.
122 Signal is emitted when the line (pen) color has changed to \a color.
122 */
123 */
123
124
124 /*!
125 /*!
125 \fn QChartSeriesType QScatterSeries::type() const
126 \fn QChartSeriesType QScatterSeries::type() const
126 Returns QChartSeries::SeriesTypeScatter.
127 Returns QChartSeries::SeriesTypeScatter.
127 \sa QAbstractSeries, SeriesType
128 \sa QAbstractSeries, SeriesType
128 */
129 */
129
130
130 QTCOMMERCIALCHART_BEGIN_NAMESPACE
131 QTCOMMERCIALCHART_BEGIN_NAMESPACE
131
132
132 /*!
133 /*!
133 Constructs a series object which is a child of \a parent.
134 Constructs a series object which is a child of \a parent.
134 */
135 */
135 QScatterSeries::QScatterSeries(QObject *parent)
136 QScatterSeries::QScatterSeries(QObject *parent)
136 : QXYSeries(*new QScatterSeriesPrivate(this), parent)
137 : QXYSeries(*new QScatterSeriesPrivate(this), parent)
137 {
138 {
138 }
139 }
139
140
140 /*!
141 /*!
141 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
142 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
142 */
143 */
143 QScatterSeries::~QScatterSeries()
144 QScatterSeries::~QScatterSeries()
144 {
145 {
145 Q_D(QScatterSeries);
146 Q_D(QScatterSeries);
146 if (d->m_chart)
147 if (d->m_chart)
147 d->m_chart->removeSeries(this);
148 d->m_chart->removeSeries(this);
148 }
149 }
149
150
150 QAbstractSeries::SeriesType QScatterSeries::type() const
151 QAbstractSeries::SeriesType QScatterSeries::type() const
151 {
152 {
152 return QAbstractSeries::SeriesTypeScatter;
153 return QAbstractSeries::SeriesTypeScatter;
153 }
154 }
154
155
155 /*!
156 /*!
156 Sets \a pen used for drawing points' border on the chart. If the pen is not defined, the
157 Sets \a pen used for drawing points' border on the chart. If the pen is not defined, the
157 pen from chart theme is used.
158 pen from chart theme is used.
158 \sa QChart::setTheme()
159 \sa QChart::setTheme()
159 */
160 */
160 void QScatterSeries::setPen(const QPen &pen)
161 void QScatterSeries::setPen(const QPen &pen)
161 {
162 {
162 Q_D(QXYSeries);
163 Q_D(QXYSeries);
163 if (d->m_pen != pen) {
164 if (d->m_pen != pen) {
164 bool emitColorChanged = d->m_pen.color() != pen.color();
165 bool emitColorChanged = d->m_pen.color() != pen.color();
165 d->m_pen = pen;
166 d->m_pen = pen;
166 emit d->updated();
167 emit d->updated();
167 if (emitColorChanged)
168 if (emitColorChanged)
168 emit borderColorChanged(pen.color());
169 emit borderColorChanged(pen.color());
169 }
170 }
170 }
171 }
171
172
172 /*!
173 /*!
173 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
174 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
174 from chart theme setting is used.
175 from chart theme setting is used.
175 \sa QChart::setTheme()
176 \sa QChart::setTheme()
176 */
177 */
177 void QScatterSeries::setBrush(const QBrush &brush)
178 void QScatterSeries::setBrush(const QBrush &brush)
178 {
179 {
179 Q_D(QScatterSeries);
180 Q_D(QScatterSeries);
180 if (d->m_brush != brush) {
181 if (d->m_brush != brush) {
181 bool emitColorChanged = d->m_brush.color() != brush.color();
182 bool emitColorChanged = d->m_brush.color() != brush.color();
182 d->m_brush = brush;
183 d->m_brush = brush;
183 emit d->updated();
184 emit d->updated();
184 if (emitColorChanged)
185 if (emitColorChanged)
185 emit colorChanged(brush.color());
186 emit colorChanged(brush.color());
186 }
187 }
187 }
188 }
188
189
189 void QScatterSeries::setColor(const QColor &color)
190 void QScatterSeries::setColor(const QColor &color)
190 {
191 {
191 QBrush b = brush();
192 QBrush b = brush();
192 if (b == QBrush())
193 if (b == QBrush())
193 b.setStyle(Qt::SolidPattern);
194 b.setStyle(Qt::SolidPattern);
194 b.setColor(color);
195 b.setColor(color);
195 setBrush(b);
196 setBrush(b);
196 }
197 }
197
198
198 QColor QScatterSeries::color() const
199 QColor QScatterSeries::color() const
199 {
200 {
200 return brush().color();
201 return brush().color();
201 }
202 }
202
203
203 void QScatterSeries::setBorderColor(const QColor &color)
204 void QScatterSeries::setBorderColor(const QColor &color)
204 {
205 {
205 QPen p = pen();
206 QPen p = pen();
206 if (p.color() != color) {
207 if (p.color() != color) {
207 p.setColor(color);
208 p.setColor(color);
208 setPen(p);
209 setPen(p);
209 }
210 }
210 }
211 }
211
212
212 QColor QScatterSeries::borderColor() const
213 QColor QScatterSeries::borderColor() const
213 {
214 {
214 return pen().color();
215 return pen().color();
215 }
216 }
216
217
217 QScatterSeries::MarkerShape QScatterSeries::markerShape() const
218 QScatterSeries::MarkerShape QScatterSeries::markerShape() const
218 {
219 {
219 Q_D(const QScatterSeries);
220 Q_D(const QScatterSeries);
220 return d->m_shape;
221 return d->m_shape;
221 }
222 }
222
223
223 void QScatterSeries::setMarkerShape(MarkerShape shape)
224 void QScatterSeries::setMarkerShape(MarkerShape shape)
224 {
225 {
225 Q_D(QScatterSeries);
226 Q_D(QScatterSeries);
226 if (d->m_shape != shape) {
227 if (d->m_shape != shape) {
227 d->m_shape = shape;
228 d->m_shape = shape;
228 emit d->updated();
229 emit d->updated();
229 }
230 }
230 }
231 }
231
232
232 qreal QScatterSeries::markerSize() const
233 qreal QScatterSeries::markerSize() const
233 {
234 {
234 Q_D(const QScatterSeries);
235 Q_D(const QScatterSeries);
235 return d->m_size;
236 return d->m_size;
236 }
237 }
237
238
238 void QScatterSeries::setMarkerSize(qreal size)
239 void QScatterSeries::setMarkerSize(qreal size)
239 {
240 {
240 Q_D(QScatterSeries);
241 Q_D(QScatterSeries);
241
242
242 if (!qFuzzyCompare(d->m_size, size)) {
243 if (!qFuzzyCompare(d->m_size, size)) {
243 d->m_size = size;
244 d->m_size = size;
244 emit d->updated();
245 emit d->updated();
245 }
246 }
246 }
247 }
247
248
248 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
249 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
249
250
250 QScatterSeriesPrivate::QScatterSeriesPrivate(QScatterSeries *q)
251 QScatterSeriesPrivate::QScatterSeriesPrivate(QScatterSeries *q)
251 : QXYSeriesPrivate(q),
252 : QXYSeriesPrivate(q),
252 m_shape(QScatterSeries::MarkerShapeCircle),
253 m_shape(QScatterSeries::MarkerShapeCircle),
253 m_size(15.0)
254 m_size(15.0)
254 {
255 {
255 }
256 }
256
257
257 void QScatterSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
258 void QScatterSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
258 {
259 {
259 Q_Q(QScatterSeries);
260 Q_Q(QScatterSeries);
260 ScatterChartItem *scatter = new ScatterChartItem(q,parent);
261 ScatterChartItem *scatter = new ScatterChartItem(q,parent);
261 m_item.reset(scatter);
262 m_item.reset(scatter);
262 QAbstractSeriesPrivate::initializeGraphics(parent);
263 QAbstractSeriesPrivate::initializeGraphics(parent);
263 }
264 }
264
265
265 void QScatterSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
266 void QScatterSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
266 {
267 {
267 Q_Q(QScatterSeries);
268 Q_Q(QScatterSeries);
268 QPen pen;
269 QPen pen;
269 QBrush brush;
270 QBrush brush;
270 const QList<QColor> colors = theme->seriesColors();
271 const QList<QColor> colors = theme->seriesColors();
271 const QList<QGradient> gradients = theme->seriesGradients();
272 const QList<QGradient> gradients = theme->seriesGradients();
272
273
273 if (forced || pen == m_pen) {
274 if (forced || pen == m_pen) {
274 pen.setColor(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0));
275 pen.setColor(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0));
275 pen.setWidthF(2);
276 pen.setWidthF(2);
276 q->setPen(pen);
277 q->setPen(pen);
277 }
278 }
278
279
279 if (forced || brush == m_brush) {
280 if (forced || brush == m_brush) {
280 QBrush brush(colors.at(index % colors.size()));
281 QBrush brush(colors.at(index % colors.size()));
281 q->setBrush(brush);
282 q->setBrush(brush);
282 }
283 }
283 }
284 }
284
285
286 void QScatterSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
287 {
288 ScatterChartItem *item = static_cast<ScatterChartItem *>(m_item.data());
289 Q_ASSERT(item);
290
291 if (options.testFlag(QChart::SeriesAnimations))
292 item->setAnimation(new ScatterAnimation(item));
293 else
294 item->setAnimation(0);
295
296 QAbstractSeriesPrivate::initializeAnimations(options);
297 }
298
285 #include "moc_qscatterseries.cpp"
299 #include "moc_qscatterseries.cpp"
286
300
287 QTCOMMERCIALCHART_END_NAMESPACE
301 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,52 +1,53
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QSCATTERSERIES_P_H
30 #ifndef QSCATTERSERIES_P_H
31 #define QSCATTERSERIES_P_H
31 #define QSCATTERSERIES_P_H
32
32
33 #include "qxyseries_p.h"
33 #include "qxyseries_p.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 class QScatterSeriesPrivate: public QXYSeriesPrivate
37 class QScatterSeriesPrivate: public QXYSeriesPrivate
38 {
38 {
39 public:
39 public:
40 QScatterSeriesPrivate(QScatterSeries *q);
40 QScatterSeriesPrivate(QScatterSeries *q);
41 void initializeGraphics(QGraphicsItem* parent);
41 void initializeGraphics(QGraphicsItem* parent);
42 void initializeTheme(int index, ChartTheme* theme, bool forced = false);
42 void initializeTheme(int index, ChartTheme* theme, bool forced = false);
43 void initializeAnimations(QtCommercialChart::QChart::AnimationOptions options);
43
44
44 private:
45 private:
45 QScatterSeries::MarkerShape m_shape;
46 QScatterSeries::MarkerShape m_shape;
46 qreal m_size;
47 qreal m_size;
47 Q_DECLARE_PUBLIC(QScatterSeries)
48 Q_DECLARE_PUBLIC(QScatterSeries)
48 };
49 };
49
50
50 QTCOMMERCIALCHART_END_NAMESPACE
51 QTCOMMERCIALCHART_END_NAMESPACE
51
52
52 #endif
53 #endif
@@ -1,207 +1,207
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "scatterchartitem_p.h"
21 #include "scatterchartitem_p.h"
22 #include "qscatterseries.h"
22 #include "qscatterseries.h"
23 #include "qscatterseries_p.h"
23 #include "qscatterseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "abstractdomain_p.h"
25 #include "abstractdomain_p.h"
26 #include "qchart.h"
26 #include "qchart.h"
27 #include <QPainter>
27 #include <QPainter>
28 #include <QGraphicsScene>
28 #include <QGraphicsScene>
29 #include <QDebug>
29 #include <QDebug>
30 #include <QGraphicsSceneMouseEvent>
30 #include <QGraphicsSceneMouseEvent>
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 ScatterChartItem::ScatterChartItem(QScatterSeries *series, QGraphicsItem *item)
34 ScatterChartItem::ScatterChartItem(QScatterSeries *series, QGraphicsItem *item)
35 : XYChart(series,item),
35 : XYChart(series,item),
36 m_series(series),
36 m_series(series),
37 m_items(this),
37 m_items(this),
38 m_visible(true),
38 m_visible(true),
39 m_shape(QScatterSeries::MarkerShapeRectangle),
39 m_shape(QScatterSeries::MarkerShapeRectangle),
40 m_size(15)
40 m_size(15)
41 {
41 {
42 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
42 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
43 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
43 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
44 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
44 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
45
45
46 setZValue(ChartPresenter::ScatterSeriesZValue);
46 setZValue(ChartPresenter::ScatterSeriesZValue);
47 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
47 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
48
48
49 handleUpdated();
49 handleUpdated();
50
50
51 m_items.setHandlesChildEvents(false);
51 m_items.setHandlesChildEvents(false);
52 }
52 }
53
53
54 QRectF ScatterChartItem::boundingRect() const
54 QRectF ScatterChartItem::boundingRect() const
55 {
55 {
56 return m_rect;
56 return m_rect;
57 }
57 }
58
58
59 void ScatterChartItem::createPoints(int count)
59 void ScatterChartItem::createPoints(int count)
60 {
60 {
61 for (int i = 0; i < count; ++i) {
61 for (int i = 0; i < count; ++i) {
62
62
63 QGraphicsItem *item = 0;
63 QGraphicsItem *item = 0;
64
64
65 switch (m_shape) {
65 switch (m_shape) {
66 case QScatterSeries::MarkerShapeCircle: {
66 case QScatterSeries::MarkerShapeCircle: {
67 item = new CircleMarker(0, 0, m_size, m_size, this);
67 item = new CircleMarker(0, 0, m_size, m_size, this);
68 const QRectF &rect = item->boundingRect();
68 const QRectF &rect = item->boundingRect();
69 item->setPos(-rect.width() / 2, -rect.height() / 2);
69 item->setPos(-rect.width() / 2, -rect.height() / 2);
70 break;
70 break;
71 }
71 }
72 case QScatterSeries::MarkerShapeRectangle:
72 case QScatterSeries::MarkerShapeRectangle:
73 item = new RectangleMarker(0, 0, m_size, m_size, this);
73 item = new RectangleMarker(0, 0, m_size, m_size, this);
74 item->setPos(-m_size / 2, -m_size / 2);
74 item->setPos(-m_size / 2, -m_size / 2);
75 break;
75 break;
76 default:
76 default:
77 qWarning() << "Unsupported marker type";
77 qWarning() << "Unsupported marker type";
78 break;
78 break;
79 }
79 }
80 m_items.addToGroup(item);
80 m_items.addToGroup(item);
81 }
81 }
82 }
82 }
83
83
84 void ScatterChartItem::deletePoints(int count)
84 void ScatterChartItem::deletePoints(int count)
85 {
85 {
86 QList<QGraphicsItem *> items = m_items.childItems();
86 QList<QGraphicsItem *> items = m_items.childItems();
87
87
88 for (int i = 0; i < count; ++i) {
88 for (int i = 0; i < count; ++i) {
89 QGraphicsItem *item = items.takeLast();
89 QGraphicsItem *item = items.takeLast();
90 m_markerMap.remove(item);
90 m_markerMap.remove(item);
91 delete(item);
91 delete(item);
92 }
92 }
93 }
93 }
94
94
95 void ScatterChartItem::markerSelected(QGraphicsItem *marker)
95 void ScatterChartItem::markerSelected(QGraphicsItem *marker)
96 {
96 {
97 emit XYChart::clicked(m_markerMap[marker]);
97 emit XYChart::clicked(m_markerMap[marker]);
98 }
98 }
99
99
100 void ScatterChartItem::markerHovered(QGraphicsItem *marker, bool state)
100 void ScatterChartItem::markerHovered(QGraphicsItem *marker, bool state)
101 {
101 {
102 emit XYChart::hovered(m_markerMap[marker], state);
102 emit XYChart::hovered(m_markerMap[marker], state);
103 }
103 }
104
104
105 void ScatterChartItem::updateGeometry()
105 void ScatterChartItem::updateGeometry()
106 {
106 {
107
107
108 const QVector<QPointF>& points = geometryPoints();
108 const QVector<QPointF>& points = geometryPoints();
109
109
110 if (points.size() == 0) {
110 if (points.size() == 0) {
111 deletePoints(m_items.childItems().count());
111 deletePoints(m_items.childItems().count());
112 return;
112 return;
113 }
113 }
114
114
115 int diff = m_items.childItems().size() - points.size();
115 int diff = m_items.childItems().size() - points.size();
116
116
117 if (diff > 0)
117 if (diff > 0)
118 deletePoints(diff);
118 deletePoints(diff);
119 else if (diff < 0)
119 else if (diff < 0)
120 createPoints(-diff);
120 createPoints(-diff);
121
121
122 if (diff != 0)
122 if (diff != 0)
123 handleUpdated();
123 handleUpdated();
124
124
125 QList<QGraphicsItem *> items = m_items.childItems();
125 QList<QGraphicsItem *> items = m_items.childItems();
126
126
127 QRectF clipRect(QPointF(0,0),domain()->size());
127 QRectF clipRect(QPointF(0,0),domain()->size());
128
128
129 QVector<bool> offGridStatus = offGridStatusVector();
129 QVector<bool> offGridStatus = offGridStatusVector();
130 const int seriesLastIndex = m_series->count() - 1;
130 const int seriesLastIndex = m_series->count() - 1;
131
131
132 for (int i = 0; i < points.size(); i++) {
132 for (int i = 0; i < points.size(); i++) {
133 QGraphicsItem *item = items.at(i);
133 QGraphicsItem *item = items.at(i);
134 const QPointF &point = points.at(i);
134 const QPointF &point = points.at(i);
135 const QRectF &rect = item->boundingRect();
135 const QRectF &rect = item->boundingRect();
136 // During remove/append animation series may have different number of points,
136 // During remove animation series may have different number of points,
137 // so ensure we don't go over the index. Animation handling itself ensures that
137 // so ensure we don't go over the index. Animation handling itself ensures that
138 // if there is actually no points in the series, then it won't generate a fake point,
138 // if there is actually no points in the series, then it won't generate a fake point,
139 // so we can be assured there is always at least one point in m_series here.
139 // so we can be assured there is always at least one point in m_series here.
140 // Note that marker map values can be technically incorrect during the animation,
140 // Note that marker map values can be technically incorrect during the animation,
141 // if it was caused by an insert, but this shouldn't be a problem as the points are
141 // if it was caused by an insert, but this shouldn't be a problem as the points are
142 // fake anyway.
142 // fake anyway. After remove animation stops, geometry is updated to correct one.
143 m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i));
143 m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i));
144 item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
144 item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
145
145
146 if (!m_visible || offGridStatus.at(i))
146 if (!m_visible || offGridStatus.at(i))
147 item->setVisible(false);
147 item->setVisible(false);
148 else
148 else
149 item->setVisible(true);
149 item->setVisible(true);
150 }
150 }
151
151
152 prepareGeometryChange();
152 prepareGeometryChange();
153 m_rect = clipRect;
153 m_rect = clipRect;
154 }
154 }
155
155
156 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
156 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
157 {
157 {
158 Q_UNUSED(painter)
158 Q_UNUSED(painter)
159 Q_UNUSED(option)
159 Q_UNUSED(option)
160 Q_UNUSED(widget)
160 Q_UNUSED(widget)
161 }
161 }
162
162
163 void ScatterChartItem::setPen(const QPen &pen)
163 void ScatterChartItem::setPen(const QPen &pen)
164 {
164 {
165 foreach (QGraphicsItem *item , m_items.childItems())
165 foreach (QGraphicsItem *item , m_items.childItems())
166 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
166 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
167 }
167 }
168
168
169 void ScatterChartItem::setBrush(const QBrush &brush)
169 void ScatterChartItem::setBrush(const QBrush &brush)
170 {
170 {
171 foreach (QGraphicsItem *item , m_items.childItems())
171 foreach (QGraphicsItem *item , m_items.childItems())
172 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
172 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
173 }
173 }
174
174
175 void ScatterChartItem::handleUpdated()
175 void ScatterChartItem::handleUpdated()
176 {
176 {
177 int count = m_items.childItems().count();
177 int count = m_items.childItems().count();
178
178
179 if (count == 0)
179 if (count == 0)
180 return;
180 return;
181
181
182 bool recreate = m_visible != m_series->isVisible()
182 bool recreate = m_visible != m_series->isVisible()
183 || m_size != m_series->markerSize()
183 || m_size != m_series->markerSize()
184 || m_shape != m_series->markerShape();
184 || m_shape != m_series->markerShape();
185
185
186 m_visible = m_series->isVisible();
186 m_visible = m_series->isVisible();
187 m_size = m_series->markerSize();
187 m_size = m_series->markerSize();
188 m_shape = m_series->markerShape();
188 m_shape = m_series->markerShape();
189 setOpacity(m_series->opacity());
189 setOpacity(m_series->opacity());
190
190
191 if (recreate) {
191 if (recreate) {
192 // TODO: optimize handleUpdate to recreate points only in case shape changed
192 // TODO: optimize handleUpdate to recreate points only in case shape changed
193 deletePoints(count);
193 deletePoints(count);
194 createPoints(count);
194 createPoints(count);
195
195
196 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
196 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
197 updateGeometry();
197 updateGeometry();
198 }
198 }
199
199
200 setPen(m_series->pen());
200 setPen(m_series->pen());
201 setBrush(m_series->brush());
201 setBrush(m_series->brush());
202 update();
202 update();
203 }
203 }
204
204
205 #include "moc_scatterchartitem_p.cpp"
205 #include "moc_scatterchartitem_p.cpp"
206
206
207 QTCOMMERCIALCHART_END_NAMESPACE
207 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,191 +1,191
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "xychart_p.h"
21 #include "xychart_p.h"
22 #include "qxyseries.h"
22 #include "qxyseries.h"
23 #include "qxyseries_p.h"
23 #include "qxyseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "abstractdomain_p.h"
25 #include "abstractdomain_p.h"
26 #include "qxymodelmapper.h"
26 #include "qxymodelmapper.h"
27 #include "qabstractaxis_p.h"
27 #include "qabstractaxis_p.h"
28 #include <QPainter>
28 #include <QPainter>
29 #include <QAbstractItemModel>
29 #include <QAbstractItemModel>
30
30
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 //TODO: optimize : remove points which are not visible
34 //TODO: optimize : remove points which are not visible
35
35
36 XYChart::XYChart(QXYSeries *series, QGraphicsItem *item):
36 XYChart::XYChart(QXYSeries *series, QGraphicsItem *item):
37 ChartItem(series->d_func(),item),
37 ChartItem(series->d_func(),item),
38 m_series(series),
38 m_series(series),
39 m_animation(0),
39 m_animation(0),
40 m_dirty(true)
40 m_dirty(true)
41 {
41 {
42 QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int)));
42 QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int)));
43 QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced()));
43 QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced()));
44 QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
44 QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
45 QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int)));
45 QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int)));
46 QObject::connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF)));
46 QObject::connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF)));
47 QObject::connect(this, SIGNAL(hovered(QPointF,bool)), series, SIGNAL(hovered(QPointF,bool)));
47 QObject::connect(this, SIGNAL(hovered(QPointF,bool)), series, SIGNAL(hovered(QPointF,bool)));
48 }
48 }
49
49
50 void XYChart::setGeometryPoints(const QVector<QPointF> &points)
50 void XYChart::setGeometryPoints(const QVector<QPointF> &points)
51 {
51 {
52 m_points = points;
52 m_points = points;
53 }
53 }
54
54
55 void XYChart::setAnimation(XYAnimation *animation)
55 void XYChart::setAnimation(XYAnimation *animation)
56 {
56 {
57 m_animation = animation;
57 m_animation = animation;
58 }
58 }
59
59
60 void XYChart::setDirty(bool dirty)
60 void XYChart::setDirty(bool dirty)
61 {
61 {
62 m_dirty = dirty;
62 m_dirty = dirty;
63 }
63 }
64
64
65 // Returns a vector with same size as geometryPoints vector, indicating
65 // Returns a vector with same size as geometryPoints vector, indicating
66 // the off grid status of points.
66 // the off grid status of points.
67 QVector<bool> XYChart::offGridStatusVector()
67 QVector<bool> XYChart::offGridStatusVector()
68 {
68 {
69 qreal minX = domain()->minX();
69 qreal minX = domain()->minX();
70 qreal maxX = domain()->maxX();
70 qreal maxX = domain()->maxX();
71 qreal minY = domain()->minY();
71 qreal minY = domain()->minY();
72 qreal maxY = domain()->maxY();
72 qreal maxY = domain()->maxY();
73
73
74 QVector<bool> returnVector;
74 QVector<bool> returnVector;
75 returnVector.resize(m_points.size());
75 returnVector.resize(m_points.size());
76 // During remove/append animation series may have different number of points,
76 // During remove animation series may have different number of points,
77 // so ensure we don't go over the index. No need to check for zero points, this
77 // so ensure we don't go over the index. No need to check for zero points, this
78 // will not be called in such a situation.
78 // will not be called in such a situation.
79 const int seriesLastIndex = m_series->count() - 1;
79 const int seriesLastIndex = m_series->count() - 1;
80
80
81 for (int i = 0; i < m_points.size(); i++) {
81 for (int i = 0; i < m_points.size(); i++) {
82 const QPointF &seriesPoint = m_series->at(qMin(seriesLastIndex, i));
82 const QPointF &seriesPoint = m_series->at(qMin(seriesLastIndex, i));
83 if (seriesPoint.x() < minX
83 if (seriesPoint.x() < minX
84 || seriesPoint.x() > maxX
84 || seriesPoint.x() > maxX
85 || seriesPoint.y() < minY
85 || seriesPoint.y() < minY
86 || seriesPoint.y() > maxY) {
86 || seriesPoint.y() > maxY) {
87 returnVector[i] = true;
87 returnVector[i] = true;
88 } else {
88 } else {
89 returnVector[i] = false;
89 returnVector[i] = false;
90 }
90 }
91 }
91 }
92 return returnVector;
92 return returnVector;
93 }
93 }
94
94
95 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
95 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
96 {
96 {
97
97
98 if (m_animation) {
98 if (m_animation) {
99 m_animation->setup(oldPoints, newPoints, index);
99 m_animation->setup(oldPoints, newPoints, index);
100 m_points = newPoints;
100 m_points = newPoints;
101 setDirty(false);
101 setDirty(false);
102 presenter()->startAnimation(m_animation);
102 presenter()->startAnimation(m_animation);
103 } else {
103 } else {
104 m_points = newPoints;
104 m_points = newPoints;
105 updateGeometry();
105 updateGeometry();
106 }
106 }
107 }
107 }
108
108
109 //handlers
109 //handlers
110
110
111 void XYChart::handlePointAdded(int index)
111 void XYChart::handlePointAdded(int index)
112 {
112 {
113 Q_ASSERT(index < m_series->count());
113 Q_ASSERT(index < m_series->count());
114 Q_ASSERT(index >= 0);
114 Q_ASSERT(index >= 0);
115
115
116 QVector<QPointF> points;
116 QVector<QPointF> points;
117
117
118 if (m_dirty || m_points.isEmpty()) {
118 if (m_dirty || m_points.isEmpty()) {
119 points = domain()->calculateGeometryPoints(m_series->points());
119 points = domain()->calculateGeometryPoints(m_series->points());
120 } else {
120 } else {
121 points = m_points;
121 points = m_points;
122 QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData);
122 QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData);
123 if (!m_validData)
123 if (!m_validData)
124 m_points.clear();
124 m_points.clear();
125 else
125 else
126 points.insert(index, point);
126 points.insert(index, point);
127 }
127 }
128
128
129 updateChart(m_points, points, index);
129 updateChart(m_points, points, index);
130 }
130 }
131
131
132 void XYChart::handlePointRemoved(int index)
132 void XYChart::handlePointRemoved(int index)
133 {
133 {
134 Q_ASSERT(index <= m_series->count());
134 Q_ASSERT(index <= m_series->count());
135 Q_ASSERT(index >= 0);
135 Q_ASSERT(index >= 0);
136
136
137 QVector<QPointF> points;
137 QVector<QPointF> points;
138
138
139 if (m_dirty || m_points.isEmpty()) {
139 if (m_dirty || m_points.isEmpty()) {
140 points = domain()->calculateGeometryPoints(m_series->points());
140 points = domain()->calculateGeometryPoints(m_series->points());
141 } else {
141 } else {
142 points = m_points;
142 points = m_points;
143 points.remove(index);
143 points.remove(index);
144 }
144 }
145
145
146 updateChart(m_points, points, index);
146 updateChart(m_points, points, index);
147 }
147 }
148
148
149 void XYChart::handlePointReplaced(int index)
149 void XYChart::handlePointReplaced(int index)
150 {
150 {
151 Q_ASSERT(index < m_series->count());
151 Q_ASSERT(index < m_series->count());
152 Q_ASSERT(index >= 0);
152 Q_ASSERT(index >= 0);
153
153
154 QVector<QPointF> points;
154 QVector<QPointF> points;
155
155
156 if (m_dirty || m_points.isEmpty()) {
156 if (m_dirty || m_points.isEmpty()) {
157 points = domain()->calculateGeometryPoints(m_series->points());
157 points = domain()->calculateGeometryPoints(m_series->points());
158 } else {
158 } else {
159 QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData);
159 QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData);
160 if (!m_validData)
160 if (!m_validData)
161 m_points.clear();
161 m_points.clear();
162 points = m_points;
162 points = m_points;
163 if (m_validData)
163 if (m_validData)
164 points.replace(index, point);
164 points.replace(index, point);
165 }
165 }
166
166
167 updateChart(m_points, points, index);
167 updateChart(m_points, points, index);
168 }
168 }
169
169
170 void XYChart::handlePointsReplaced()
170 void XYChart::handlePointsReplaced()
171 {
171 {
172 // All the points were replaced -> recalculate
172 // All the points were replaced -> recalculate
173 QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points());
173 QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points());
174 updateChart(m_points, points, -1);
174 updateChart(m_points, points, -1);
175 }
175 }
176
176
177 void XYChart::handleDomainUpdated()
177 void XYChart::handleDomainUpdated()
178 {
178 {
179 if (isEmpty()) return;
179 if (isEmpty()) return;
180 QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points());
180 QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points());
181 updateChart(m_points, points);
181 updateChart(m_points, points);
182 }
182 }
183
183
184 bool XYChart::isEmpty()
184 bool XYChart::isEmpty()
185 {
185 {
186 return domain()->isEmpty() || m_series->points().isEmpty();
186 return domain()->isEmpty() || m_series->points().isEmpty();
187 }
187 }
188
188
189 #include "moc_xychart_p.cpp"
189 #include "moc_xychart_p.cpp"
190
190
191 QTCOMMERCIALCHART_END_NAMESPACE
191 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now