##// END OF EJS Templates
adds QLineAnimation fixes
Michal Klocek -
r1271:b11722f80588
parent child
Show More
@@ -1,153 +1,153
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "splineanimation_p.h"
22 22 #include "splinechartitem_p.h"
23 23 #include <QDebug>
24 24
25 25 Q_DECLARE_METATYPE(QVector<QPointF>)
26 26 Q_DECLARE_METATYPE(SplineVector)
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 SplineAnimation::SplineAnimation(SplineChartItem* item):XYAnimation(item),
31 31 m_item(item),
32 32 m_dirty(true)
33 33 {
34 34 }
35 35
36 36 SplineAnimation::~SplineAnimation()
37 37 {
38 38 }
39 39
40 void SplineAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
40 void SplineAnimation::setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
41 41 {
42 42 int x = oldPoints.count();
43 43 int y = newPoints.count();
44 44
45 45 Q_ASSERT(newPoints.count() * 2 - 2 == newControlPoints.count());
46 46
47 47 if (x != y && abs(x - y) != 1) {
48 48 m_oldSpline.first = newPoints;
49 49 m_oldSpline.second = newControlPoints;
50 50 oldPoints.resize(newPoints.size());
51 51 oldControlPoints.resize(newControlPoints.size());
52 52 SplineVector oldPair;
53 53 oldPair.first = oldPoints;
54 54 oldPair.second = oldControlPoints;
55 55 SplineVector newPair;
56 56 newPair.first = newPoints;
57 57 newPair.second = newControlPoints;
58 58 setKeyValueAt(0.0, qVariantFromValue(oldPair));
59 59 setKeyValueAt(1.0, qVariantFromValue(newPair));
60 60 m_dirty = false;
61 61 }
62 62 else {
63 63 if(m_dirty) {
64 64 m_oldSpline.first = oldPoints;
65 65 m_oldSpline.second = oldControlPoints;
66 66 m_dirty = false;
67 67 }
68 68 oldPoints = newPoints;
69 69 oldControlPoints = newControlPoints;
70 70 if (y < x) {
71 71 m_oldSpline.first.remove(index); //remove
72 72 m_oldSpline.second.remove(index * 2);
73 73 m_oldSpline.second.remove(index * 2);
74 74 }
75 75 if (y > x) {
76 76 m_oldSpline.first.insert(index, x > 0 ? m_oldSpline.first[index-1] : newPoints[index]); //add
77 77 m_oldSpline.second.insert((index - 1) * 2, x > 1 ? m_oldSpline.second[(index-2)*2] : newControlPoints[(index - 1) * 2]); //add
78 78 m_oldSpline.second.insert((index - 1) * 2 + 1, x > 1 ? m_oldSpline.second[(index - 2) * 2 + 1] : newControlPoints[(index - 1) * 2 + 1]); //add
79 79 }
80 80 SplineVector newPair;
81 81 newPair.first=newPoints;
82 82 newPair.second=newControlPoints;
83 83 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
84 84 setKeyValueAt(1.0, qVariantFromValue(newPair));
85 85 }
86 86 }
87 87
88 88 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
89 89 {
90 90
91 91 SplineVector startPair = qVariantValue< SplineVector >(start);
92 92 SplineVector endPair = qVariantValue< SplineVector >(end);
93 93 SplineVector result;
94 94
95 95 switch (animationType()) {
96 96
97 97 case RemovePointAnimation:
98 98 case AddPointAnimation:
99 99 case ReplacePointAnimation:
100 100 {
101 101 if (startPair.first.count() != endPair.first.count())
102 102 break;
103 103 Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
104 104 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
105 105 for(int i = 0; i < endPair.first.count(); i++) {
106 106 qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
107 107 qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
108 108 result.first << QPointF(x,y);
109 109 if (i + 1 >= endPair.first.count())
110 110 continue;
111 111 x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
112 112 y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
113 113 result.second << QPoint(x,y);
114 114 x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
115 115 y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
116 116 result.second << QPoint(x,y);
117 117 }
118 118
119 119 }
120 120 break;
121 121 case NewAnimation:{
122 122 Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
123 123 int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
124 124 for(int i = 0; i < count; i++) {
125 125 result.first << endPair.first[i];
126 126 if(i + 1 == count)
127 127 break;
128 128 result.second << endPair.second[2 * i];
129 129 result.second << endPair.second[2 * i + 1];
130 130 }
131 131 }
132 132 break;
133 133 default:
134 134 qWarning() << "Unknown type of animation";
135 135 break;
136 136 }
137 137
138 138 return qVariantFromValue(result);
139 139 }
140 140
141 141 void SplineAnimation::updateCurrentValue (const QVariant &value )
142 142 {
143 143 if (state() != QAbstractAnimation::Stopped) { //workaround
144 144 m_dirty = true;
145 145 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
146 146 m_item->setGeometryPoints(pair.first);
147 147 m_item->setControlGeometryPoints(pair.second);
148 148 m_item->updateGeometry();
149 149 }
150 150 }
151 151
152 152
153 153 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,51 +1,51
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef SPLINEANIMATION_P_H
22 22 #define SPLINEANIMATION_P_H
23 23 #include "xyanimation_p.h"
24 24 #include <QPointF>
25 25
26 26 typedef QPair<QVector<QPointF >, QVector<QPointF > > SplineVector;
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class SplineChartItem;
31 31
32 32 class SplineAnimation : public XYAnimation
33 33 {
34 34 public:
35 35 SplineAnimation(SplineChartItem *item);
36 36 ~SplineAnimation();
37 void setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldContorlPoints, QVector<QPointF> &newControlPoints, int index);
37 void setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldContorlPoints, QVector<QPointF> &newControlPoints, int index = -1);
38 38
39 39 protected:
40 40 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const;
41 41 void updateCurrentValue(const QVariant &value);
42 42
43 43 private:
44 44 SplineVector m_oldSpline;
45 45 SplineChartItem *m_item;
46 46 bool m_dirty;
47 47 };
48 48
49 49 QTCOMMERCIALCHART_END_NAMESPACE
50 50
51 51 #endif
@@ -1,146 +1,153
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xyanimation_p.h"
22 22 #include "xychart_p.h"
23 23 #include <QDebug>
24 24
25 25 Q_DECLARE_METATYPE(QVector<QPointF>)
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 XYAnimation::XYAnimation(XYChart *item):ChartAnimation(item),
30 30 m_item(item),
31 31 m_dirty(false),
32 32 m_type(NewAnimation)
33 33 {
34 34 setDuration(ChartAnimationDuration);
35 35 setEasingCurve(QEasingCurve::OutQuart);
36 36 }
37 37
38 38 XYAnimation::~XYAnimation()
39 39 {
40 40 }
41 41
42 void XYAnimation::setAnimationType(Animation type)
42 void XYAnimation::setup(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints, int index)
43 43 {
44 if (state() != QAbstractAnimation::Stopped) stop();
45 m_type=type;
46 }
44 m_type = NewAnimation;
47 45
48 void XYAnimation::setValues(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints, int index)
49 {
50 if (state() != QAbstractAnimation::Stopped) stop();
46 if (state() != QAbstractAnimation::Stopped){
47 stop();
48 m_dirty=false;
49 }
51 50
52 if (m_item->isDirty()) {
53 m_oldPoints = oldPoints;
54 m_newPoints = newPoints;
55 m_dirty=false;
56 }
57 else {
58 if(m_dirty) {
59 m_newPoints = newPoints;
60 m_oldPoints = oldPoints;
61 m_dirty=false;
62 }
63 }
51 if(!m_dirty){
52 m_dirty = true;
53 m_oldPoints = oldPoints;
54 }
64 55
65 int x = m_oldPoints.count();
66 int y = m_newPoints.count();
56 m_newPoints = newPoints;
67 57
68 if (abs(x - y) == 1) {
69 if (y < x){
70 if(!newPoints.isEmpty()) m_newPoints.insert(index,newPoints[index]);
71 m_index=index;if(newPoints.isEmpty())
72 m_dirty=true;
73 }
74 if (y > x){
75 m_oldPoints.insert(index, x > 0 ? m_oldPoints[index-1] : newPoints[index]);//add
76 }
77 }else{
78 m_newPoints=newPoints;
79 m_dirty=false;
80 m_oldPoints.resize(m_newPoints.size());
81 }
58 int x = m_oldPoints.count();
59 int y = m_newPoints.count();
60
61 if(x - y == 1 && index >= 0 && !newPoints.isEmpty()){
62 //remove point
63 m_newPoints.insert(index, index >= 1 ? m_newPoints[index-1] : newPoints[index]);
64 m_index=index;
65 m_type = RemovePointAnimation;
66 }
67
68 if(x - y == -1 && index >= 0){
69 //add point
70 m_oldPoints.insert(index, x > 0 && index > 1 ? m_oldPoints[index-1] : newPoints[index]);
71 m_index=index;
72 m_type = AddPointAnimation;
73 }
74
75 x = m_oldPoints.count();
76 y = m_newPoints.count();
77
78 if(x != y)
79 {
80 m_type = NewAnimation;
81 }
82 else if(m_type == NewAnimation)
83 {
84 m_type = ReplacePointAnimation;
85 }
82 86
83 87 setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
84 88 setKeyValueAt(1.0, qVariantFromValue(m_newPoints));
85
86 89 }
87 90
88 91 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
89 92 {
90 93 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
91 94 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
92 95 QVector<QPointF> result;
93 96
94 97 switch (m_type) {
95 98
96 99 case ReplacePointAnimation:
97 100 case AddPointAnimation:
98 101 case RemovePointAnimation:
99 102 {
100 if (startVector.count() != endVector.count())
103 if (startVector.count() != endVector.count()){
101 104 break;
105 }
102 106
103 107 for(int i = 0; i < startVector.count(); i++) {
104 108 qreal x = startVector[i].x() + ((endVector[i].x() - startVector[i].x()) * progress);
105 109 qreal y = startVector[i].y() + ((endVector[i].y() - startVector[i].y()) * progress);
106 110 result << QPointF(x, y);
107 111 }
108 112
109 113 }
110 114 break;
111 115 case NewAnimation: {
112 116 for(int i = 0; i < endVector.count() * qBound(qreal(0), progress, qreal(1)); i++)
113 117 result << endVector[i];
114 118 }
115 119 break;
116 120 default:
117 121 qWarning() << "Unknown type of animation";
118 122 break;
119 123 }
120 124
121 125 return qVariantFromValue(result);
122 126 }
123 127
124 128 void XYAnimation::updateCurrentValue (const QVariant &value)
125 129 {
126 130 if(state()!=QAbstractAnimation::Stopped){ //workaround
131
127 132 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
128 133 m_item->setGeometryPoints(vector);
129 134 m_item->updateGeometry();
130 135 m_item->setDirty(true);
136 m_dirty=false;
137
131 138 }
132 139 }
133 140
134 141 void XYAnimation::updateState( QAbstractAnimation::State newState, QAbstractAnimation::State oldState )
135 142 {
136 143 if(oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped)
137 144 {
138 145 if(m_item->isDirty() && m_type==RemovePointAnimation){
139 146 if(!m_newPoints.isEmpty()) m_newPoints.remove(m_index);
140 147 m_item->setGeometryPoints(m_newPoints);
141 148 }
142 149 }
143 150 }
144 151
145 152 #include "moc_chartanimation_p.cpp"
146 153 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,56 +1,55
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef XYANIMATION_P_H
22 22 #define XYANIMATION_P_H
23 23
24 24 #include "chartanimation_p.h"
25 25 #include <QPointF>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 class XYChart;
30 30
31 31 class XYAnimation : public ChartAnimation
32 32 {
33 33 public:
34 34 enum Animation { AddPointAnimation, RemovePointAnimation, ReplacePointAnimation, NewAnimation };
35 35 XYAnimation(XYChart *item);
36 36 ~XYAnimation();
37 void setValues(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints,int index);
38 void setAnimationType(Animation type);
37 void setup(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints,int index = -1);
39 38 Animation animationType() const { return m_type; };
40 39
41 40 protected:
42 41 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress ) const;
43 42 void updateCurrentValue (const QVariant &value );
44 43 void updateState( QAbstractAnimation::State newState, QAbstractAnimation::State oldState );
45 44 private:
46 45 XYChart *m_item;
47 46 QVector<QPointF> m_oldPoints;
48 47 QVector<QPointF> m_newPoints;
49 48 int m_index;
50 49 bool m_dirty;
51 50 Animation m_type;
52 51 };
53 52
54 53 QTCOMMERCIALCHART_END_NAMESPACE
55 54
56 55 #endif
@@ -1,164 +1,168
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "splinechartitem_p.h"
22 22 #include "qsplineseries_p.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "chartanimator_p.h"
25 25 #include <QPainter>
26 26 #include <QGraphicsSceneMouseEvent>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 SplineChartItem::SplineChartItem(QSplineSeries *series, ChartPresenter *presenter) :
31 31 XYChart(series, presenter),
32 32 QGraphicsItem(presenter ? presenter->rootItem() : 0),
33 33 m_series(series),
34 34 m_pointsVisible(false),
35 35 m_animation(0)
36 36 {
37 37 setZValue(ChartPresenter::LineChartZValue);
38 38 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
39 39 handleUpdated();
40 40 }
41 41
42 42 QRectF SplineChartItem::boundingRect() const
43 43 {
44 44 return m_rect;
45 45 }
46 46
47 47 QPainterPath SplineChartItem::shape() const
48 48 {
49 49 return m_path;
50 50 }
51 51
52 52 void SplineChartItem::setAnimation(SplineAnimation* animation)
53 53 {
54 54 m_animation=animation;
55 55 XYChart::setAnimation(animation);
56 56 }
57 57
58 58 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
59 59 {
60 60 m_controlPoints=points;
61 61 }
62 62
63 63 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
64 64 {
65 65 return m_controlPoints;
66 66 }
67 67
68 68 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
69 69 {
70 70 QVector<QPointF> controlPoints;
71 71
72 72 if(newPoints.count()>=2) {
73 73 controlPoints.resize(newPoints.count()*2-2);
74 74 }
75 75
76 76 for (int i = 0; i < newPoints.size() - 1; i++) {
77 77 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
78 78 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
79 79 }
80 80
81 81 if (controlPoints.count()<2) {
82 82 setGeometryPoints(newPoints);
83 83 setControlGeometryPoints(controlPoints);
84 84 updateGeometry();
85 85 return;
86 86 }
87 87
88 88 if (m_animation) {
89 m_animation->setValues(oldPoints,newPoints,m_controlPoints,controlPoints,index);
89 m_animation->setup(oldPoints,newPoints,m_controlPoints,controlPoints,index);
90 setGeometryPoints(newPoints);
91 setDirty(false);
90 92 presenter()->startAnimation(m_animation);
91 93 }
92 94 else {
93 95 setGeometryPoints(newPoints);
94 96 setControlGeometryPoints(controlPoints);
95 97 updateGeometry();
96 98 }
97 99 }
98 100
99 101 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
100 102 {
101 103 return XYChart::calculateGeometryPoint(m_series->d_func()->controlPoint(index));
102 104 }
103 105
104 106 void SplineChartItem::updateGeometry()
105 107 {
106 108 const QVector<QPointF> &points = geometryPoints();
107 109 const QVector<QPointF> &controlPoints = controlGeometryPoints();
108 110
109 111 if ((points.size()<2) || (controlPoints.size()<2)) {
112 prepareGeometryChange();
110 113 m_path = QPainterPath();
114 m_rect = QRect();
111 115 return;
112 116 }
113 117
114 118 Q_ASSERT(points.count()*2-2 == controlPoints.count());
115 119
116 120 QPainterPath splinePath(points.at(0));
117 121
118 122 for (int i = 0; i < points.size() - 1; i++) {
119 123 const QPointF& point = points.at(i + 1);
120 124 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
121 125 }
122 126
123 127 prepareGeometryChange();
124 128 m_path = splinePath;
125 129 m_rect = splinePath.boundingRect();
126 130 setPos(origin());
127 131 }
128 132
129 133 //handlers
130 134
131 135 void SplineChartItem::handleUpdated()
132 136 {
133 137 m_pointsVisible = m_series->pointsVisible();
134 138 m_linePen = m_series->pen();
135 139 m_pointPen = m_series->pen();
136 140 m_pointPen.setWidthF(2*m_pointPen.width());
137 141 update();
138 142 }
139 143
140 144 //painter
141 145
142 146 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
143 147 {
144 148 Q_UNUSED(widget)
145 149 Q_UNUSED(option)
146 150 painter->save();
147 151 painter->setClipRect(clipRect());
148 152 painter->setPen(m_linePen);
149 153 painter->drawPath(m_path);
150 154 if (m_pointsVisible) {
151 155 painter->setPen(m_pointPen);
152 156 painter->drawPoints(geometryPoints());
153 157 }
154 158 painter->restore();
155 159 }
156 160
157 161 void SplineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
158 162 {
159 163 emit XYChart::clicked(calculateDomainPoint(event->pos()));
160 164 }
161 165
162 166 #include "moc_splinechartitem_p.cpp"
163 167
164 168 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,241 +1,222
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xychart_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartanimator_p.h"
26 26 #include <QPainter>
27 27 #include <QAbstractItemModel>
28 28 #include "qxymodelmapper.h"
29 29 #include <QDebug>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 //TODO: optimize : remove points which are not visible
34 34
35 35 XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter):Chart(presenter),
36 36 m_minX(0),
37 37 m_maxX(0),
38 38 m_minY(0),
39 39 m_maxY(0),
40 40 m_series(series),
41 41 m_animation(0),
42 42 m_dirty(true)
43 43 {
44 44 // QObject::connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
45 45 // QObject::connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
46 46 // QObject::connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
47 47 QObject::connect(series, SIGNAL(pointReplaced(int)), this,SLOT(handlePointReplaced(int)));
48 48 QObject::connect(series, SIGNAL(pointAdded(int)), this,SLOT(handlePointAdded(int)));
49 49 QObject::connect(series, SIGNAL(pointRemoved(int)), this,SLOT(handlePointRemoved(int)));
50 50 QObject::connect(this, SIGNAL(clicked(QPointF)), series,SIGNAL(clicked(QPointF)));
51 51 }
52 52
53 53 void XYChart::setGeometryPoints(const QVector<QPointF>& points)
54 54 {
55 55 m_points = points;
56 56 }
57 57
58 58 void XYChart::setClipRect(const QRectF &rect)
59 59 {
60 60 m_clipRect = rect;
61 61 }
62 62
63 63 void XYChart::setAnimation(XYAnimation* animation)
64 64 {
65 65 m_animation=animation;
66 66 }
67 67
68 68 void XYChart::setDirty(bool dirty)
69 69 {
70 70 m_dirty=dirty;
71 71 }
72 72
73 73 QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
74 74 {
75 75 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
76 76 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
77 77 qreal x = (point.x() - m_minX)* deltaX;
78 78 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
79 79 return QPointF(x,y);
80 80 }
81 81
82 82 QPointF XYChart::calculateGeometryPoint(int index) const
83 83 {
84 84 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
85 85 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
86 86 const QList<QPointF>& vector = m_series->points();
87 87 qreal x = (vector[index].x() - m_minX)* deltaX;
88 88 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
89 89 return QPointF(x,y);
90 90 }
91 91
92 92 QVector<QPointF> XYChart::calculateGeometryPoints() const
93 93 {
94 94 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
95 95 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
96 96
97 97 QVector<QPointF> result;
98 98 result.resize(m_series->count());
99 99 const QList<QPointF>& vector = m_series->points();
100 100 for (int i = 0; i < m_series->count(); ++i) {
101 101 qreal x = (vector[i].x() - m_minX)* deltaX;
102 102 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
103 103 result[i].setX(x);
104 104 result[i].setY(y);
105 105 }
106 106 return result;
107 107 }
108 108
109 109 QPointF XYChart::calculateDomainPoint(const QPointF &point) const
110 110 {
111 111 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
112 112 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
113 113 qreal x = point.x()/deltaX +m_minX;
114 114 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
115 115 return QPointF(x,y);
116 116 }
117 117
118 118 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
119 119 {
120
120 121 if (m_animation) {
121 m_animation->setValues(oldPoints, newPoints, index);
122 m_animation->setup(oldPoints, newPoints, index);
122 123 setGeometryPoints(newPoints);
123 124 setDirty(false);
124 125 presenter()->startAnimation(m_animation);
125 126 }
126 127 else {
127 128 setGeometryPoints(newPoints);
128 129 updateGeometry();
129 130 }
130 131 }
131 132
132 133 //handlers
133 134
134 135 void XYChart::handlePointAdded(int index)
135 136 {
136 137 Q_ASSERT(index<m_series->count());
137 138 Q_ASSERT(index>=0);
138 139
139 140 QVector<QPointF> points;
140 141
141 if(m_animation) {
142 m_animation->setAnimationType(XYAnimation::AddPointAnimation);
143 }
144
145 142 if(m_dirty) {
146 143 points = calculateGeometryPoints();
147 144 } else {
148 145 points = m_points;
149 146 QPointF point = calculateGeometryPoint(index);
150 147 points.insert(index, point);
151 148 }
152 149
153 150 updateChart(m_points,points,index);
154 151 }
155 152
156 153 void XYChart::handlePointRemoved(int index)
157 154 {
158 155 Q_ASSERT(index<=m_series->count());
159 156 Q_ASSERT(index>=0);
160 157
161 158 QVector<QPointF> points;
162 159
163 if(m_animation) {
164 m_animation->setAnimationType(XYAnimation::RemovePointAnimation);
165 }
166
167 160 if(m_dirty) {
168 161 points = calculateGeometryPoints();
169 162 } else {
170 163 points = m_points;
171 164 points.remove(index);
172 165 }
173 166
174 167 updateChart(m_points,points,index);
175 168 }
176 169
177 170 void XYChart::handlePointReplaced(int index)
178 171 {
179 172 Q_ASSERT(index<m_series->count());
180 173 Q_ASSERT(index>=0);
181 174
182 175 QVector<QPointF> points;
183 176
184 if(m_animation) {
185 m_animation->setAnimationType(XYAnimation::ReplacePointAnimation);
186 }
187
188 177 if(m_dirty) {
189 178 points = calculateGeometryPoints();
190 179 } else {
191 180 QPointF point = calculateGeometryPoint(index);
192 181 points = m_points;
193 182 points.replace(index,point);
194 183 }
195 184
196 185 updateChart(m_points,points,index);
197 186 }
198 187
199 188 void XYChart::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
200 189 {
201 190 m_minX=minX;
202 191 m_maxX=maxX;
203 192 m_minY=minY;
204 193 m_maxY=maxY;
205 194 if (isEmpty()) return;
206 195
207 196 QVector<QPointF> points = calculateGeometryPoints();
208 197
209 if(m_animation) {
210 m_animation->setAnimationType(XYAnimation::ReplacePointAnimation);
211 }
212
213 198 updateChart(m_points,points);
214 199 }
215 200
216 201 void XYChart::handleGeometryChanged(const QRectF &rect)
217 202 {
218 203 Q_ASSERT(rect.isValid());
219 204 m_size=rect.size();
220 205 m_clipRect=rect.translated(-rect.topLeft());
221 206 m_origin=rect.topLeft();
222 207
223 208 if (isEmpty()) return;
224 209
225 210 QVector<QPointF> points = calculateGeometryPoints();
226 211
227 if(m_animation) {
228 m_animation->setAnimationType(XYAnimation::NewAnimation);
229 }
230
231 212 updateChart(m_points,points);
232 213 }
233 214
234 215 bool XYChart::isEmpty()
235 216 {
236 217 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty();
237 218 }
238 219
239 220 #include "moc_xychart_p.cpp"
240 221
241 222 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,96 +1,96
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef XYCHARTITEM_H
22 22 #define XYCHARTITEM_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include "chartitem_p.h"
26 26 #include "xyanimation_p.h"
27 27 #include <QPen>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 class ChartPresenter;
32 32 class QXYSeries;
33 33
34 34 class XYChart : public Chart
35 35 {
36 36 Q_OBJECT
37 37 public:
38 38 explicit XYChart(QXYSeries *series, ChartPresenter *presenter);
39 39 ~XYChart(){};
40 40
41 41 void setGeometryPoints(const QVector<QPointF>& points);
42 42 QVector<QPointF> geometryPoints() const { return m_points; }
43 43
44 44 void setClipRect(const QRectF &rect);
45 45 QRectF clipRect() const { return m_clipRect; }
46 46
47 47 QSizeF size() const { return m_size; }
48 48 QPointF origin() const { return m_origin; }
49 49
50 50 void setAnimation(XYAnimation* animation);
51 51 ChartAnimation* animation() const { return m_animation; }
52 52 virtual void updateGeometry() = 0;
53 53
54 54 bool isDirty() const { return m_dirty; }
55 55 void setDirty(bool dirty);
56 56
57 57 public Q_SLOTS:
58 58 void handlePointAdded(int index);
59 59 void handlePointRemoved(int index);
60 60 void handlePointReplaced(int index);
61 61 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
62 62 void handleGeometryChanged(const QRectF &size);
63 63
64 64 Q_SIGNALS:
65 65 void clicked(const QPointF& point);
66 66
67 67 protected:
68 virtual void updateChart(QVector<QPointF> &oldPoints,QVector<QPointF> &newPoints,int index = 0);
68 virtual void updateChart(QVector<QPointF> &oldPoints,QVector<QPointF> &newPoints,int index = -1);
69 69 QPointF calculateGeometryPoint(const QPointF &point) const;
70 70 QPointF calculateGeometryPoint(int index) const;
71 71 QPointF calculateDomainPoint(const QPointF &point) const;
72 72 QVector<QPointF> calculateGeometryPoints() const;
73 73
74 74 private:
75 75 inline bool isEmpty();
76 76
77 77 private:
78 78 qreal m_minX;
79 79 qreal m_maxX;
80 80 qreal m_minY;
81 81 qreal m_maxY;
82 82 QXYSeries* m_series;
83 83 QSizeF m_size;
84 84 QPointF m_origin;
85 85 QRectF m_clipRect;
86 86 QVector<QPointF> m_points;
87 87 XYAnimation* m_animation;
88 88 bool m_dirty;
89 89
90 90 friend class AreaChartItem;
91 91
92 92 };
93 93
94 94 QTCOMMERCIALCHART_END_NAMESPACE
95 95
96 96 #endif
General Comments 0
You need to be logged in to leave comments. Login now