##// END OF EJS Templates
Improves spline interpolation...
Michal Klocek -
r622:960bcf5125b7
parent child
Show More
@@ -0,0 +1,127
1 #include "splineanimation_p.h"
2 #include "splinechartitem_p.h"
3
4 Q_DECLARE_METATYPE(QVector<QPointF>)
5 Q_DECLARE_METATYPE(SplineVector)
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 SplineAnimation::SplineAnimation(SplineChartItem* item):ChartAnimation(item),
10 m_item(item),
11 m_dirty(true)
12 {
13 }
14
15 SplineAnimation::~SplineAnimation()
16 {
17 }
18
19 void SplineAnimation::setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,QVector<QPointF>& oldControlPoints,QVector<QPointF>& newControlPoints,int index)
20 {
21 int x = oldPoints.count();
22 int y = newPoints.count();
23
24 Q_ASSERT(newPoints.count()*2-2 == newControlPoints.count());
25
26 if(x!=y && abs(x-y)!=1) {
27 m_oldSpline.first= newPoints;
28 m_oldSpline.second= newControlPoints;
29 oldPoints.resize(newPoints.size());
30 oldControlPoints.resize(newControlPoints.size());
31 SplineVector oldPair;
32 oldPair.first=oldPoints;
33 oldPair.second=oldControlPoints;
34 SplineVector newPair;
35 newPair.first=newPoints;
36 newPair.second=newControlPoints;
37 setKeyValueAt(0.0, qVariantFromValue(oldPair));
38 setKeyValueAt(1.0, qVariantFromValue(newPair));
39 m_dirty=false;
40 }
41 else {
42 if(m_dirty) {
43 m_oldSpline.first = oldPoints;
44 m_oldSpline.second = oldControlPoints;
45 m_dirty=false;
46 }
47 oldPoints = newPoints;
48 oldControlPoints = newControlPoints;
49 if (y<x) {
50 m_oldSpline.first.remove(index); //remove
51 m_oldSpline.second.remove(index*2);
52 m_oldSpline.second.remove(index*2);
53 }
54 if (y>x) {
55 m_oldSpline.first.insert(index,x>0?m_oldSpline.first[index-1]:newPoints[index]); //add
56 m_oldSpline.second.insert((index-1)*2,x>1?m_oldSpline.second[(index-2)*2]:newControlPoints[(index-1)*2]); //add
57 m_oldSpline.second.insert((index-1)*2+1,x>1?m_oldSpline.second[(index-2)*2+1]:newControlPoints[(index-1)*2+1]); //add
58 }
59 SplineVector newPair;
60 newPair.first=newPoints;
61 newPair.second=newControlPoints;
62 setKeyValueAt(0.0, qVariantFromValue(m_oldSpline));
63 setKeyValueAt(1.0, qVariantFromValue(newPair));
64
65 }
66 }
67
68 QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
69 {
70
71 SplineVector startPair = qVariantValue< SplineVector >(start);
72 SplineVector endPair = qVariantValue< SplineVector >(end);
73 SplineVector result;
74
75
76 switch(m_type) {
77
78 case MoveDownAnimation: {
79
80 if(startPair.first.count() != endPair.first.count()) break;
81 Q_ASSERT(startPair.first.count()*2-2 == startPair.second.count());
82 Q_ASSERT(endPair.first.count()*2-2 == endPair.second.count());
83 for(int i =0;i< endPair.first.count();i++) {
84 qreal x = startPair.first[i].x() + ((endPair.first[i].x()- startPair.first[i].x()) * progress);
85 qreal y = startPair.first[i].y() + ((endPair.first[i].y()- startPair.first[i].y()) * progress);
86 result.first << QPointF(x,y);
87 if(i +1 >= endPair.first.count()) continue;
88 x = startPair.second[i*2].x() + ((endPair.second[i*2].x()- startPair.second[i*2].x()) * progress);
89 y = startPair.second[i*2].y() + ((endPair.second[i*2].y()- startPair.second[i*2].y()) * progress);
90 result.second << QPoint(x,y);
91 x = startPair.second[i*2+1].x() + ((endPair.second[i*2+1].x()- startPair.second[i*2+1].x()) * progress);
92 y = startPair.second[i*2+1].y() + ((endPair.second[i*2+1].y()- startPair.second[i*2+1].y()) * progress);
93 result.second << QPoint(x,y);
94 }
95
96 }
97 break;
98 case LineDrawAnimation:{
99 Q_ASSERT(endPair.first.count()*2-2 == endPair.second.count());
100 int count = endPair.first.count()* qBound(0.0, progress, 1.0);
101 for(int i =0;i<count;i++) {
102 result.first << endPair.first[i];
103 if(i+1==count) break;
104 result.second << endPair.second[2*i];
105 result.second << endPair.second[2*i+1];
106 }
107 }
108 break;
109 default:
110 qWarning()<<"Unknow type of animation";
111 break;
112 }
113
114 return qVariantFromValue(result);
115 }
116
117 void SplineAnimation::updateCurrentValue (const QVariant & value )
118 {
119 if(state()!=QAbstractAnimation::Stopped){ //workaround
120 m_dirty=true;
121 QPair<QVector<QPointF >, QVector<QPointF > > pair = qVariantValue< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
122 m_item->setLayout(pair.first,pair.second);
123 }
124 }
125
126
127 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,33
1 #ifndef SPLINEANIMATION_P_H_
2 #define SPLINEANIMATION_P_H_
3 #include "chartanimation_p.h"
4 #include <QPointF>
5
6 typedef QPair<QVector<QPointF >, QVector<QPointF > > SplineVector;
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
11 class SplineChartItem;
12
13 class SplineAnimation : public ChartAnimation
14 {
15 public:
16
17 SplineAnimation(SplineChartItem* item);
18 ~SplineAnimation();
19 void setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,QVector<QPointF>& oldContorlPoints,QVector<QPointF>& newControlPoints,int index);
20
21 protected:
22 QVariant interpolated(const QVariant &start, const QVariant & end, qreal progress ) const;
23 void updateCurrentValue (const QVariant & value );
24
25 private:
26 SplineVector m_oldSpline;
27 SplineChartItem* m_item;
28 bool m_dirty;
29 };
30
31 QTCOMMERCIALCHART_END_NAMESPACE
32
33 #endif
@@ -12,7 +12,7 m_y(1)
12 setChartTitle("Three random line charts");
12 setChartTitle("Three random line charts");
13
13
14 QObject::connect(&m_timer,SIGNAL(timeout()),this,SLOT(handleTimeout()));
14 QObject::connect(&m_timer,SIGNAL(timeout()),this,SLOT(handleTimeout()));
15 m_timer.setInterval(1000);
15 m_timer.setInterval(3000);
16
16
17 m_series0 = new QLineSeries(this);
17 m_series0 = new QLineSeries(this);
18 QPen blue(Qt::blue);
18 QPen blue(Qt::blue);
@@ -49,5 +49,10 void ChartView::handleTimeout()
49 m_y = qrand() % 5 - 2.5;
49 m_y = qrand() % 5 - 2.5;
50 m_series0->add(m_x,m_y);
50 m_series0->add(m_x,m_y);
51 m_series1->add(m_x,m_y);
51 m_series1->add(m_x,m_y);
52 if(m_x>=10)
53 {
54 m_series0->remove(m_x-10);
55 m_series1->remove(m_x-10);
56 }
52 scrollRight();
57 scrollRight();
53 }
58 }
@@ -6,7 +6,9 SOURCES += \
6 $$PWD/chartanimator.cpp \
6 $$PWD/chartanimator.cpp \
7 $$PWD/xyanimation.cpp \
7 $$PWD/xyanimation.cpp \
8 $$PWD/pieanimation.cpp \
8 $$PWD/pieanimation.cpp \
9 $$PWD/piesliceanimation.cpp
9 $$PWD/piesliceanimation.cpp \
10 $$PWD/splineanimation.cpp
11
10
12
11 PRIVATE_HEADERS += \
13 PRIVATE_HEADERS += \
12 $$PWD/axisanimation_p.h \
14 $$PWD/axisanimation_p.h \
@@ -14,4 +16,5 PRIVATE_HEADERS += \
14 $$PWD/chartanimation_p.h \
16 $$PWD/chartanimation_p.h \
15 $$PWD/xyanimation_p.h \
17 $$PWD/xyanimation_p.h \
16 $$PWD/pieanimation_p.h \
18 $$PWD/pieanimation_p.h \
17 $$PWD/piesliceanimation_p.h
19 $$PWD/piesliceanimation_p.h \
20 $$PWD/splineanimation_p.h
@@ -9,7 +9,14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 class ChartAnimation: public QVariantAnimation
9 class ChartAnimation: public QVariantAnimation
10 {
10 {
11 public:
11 public:
12 ChartAnimation(QObject* parent=0):QVariantAnimation(parent){};
12 enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
13 ChartAnimation(QObject* parent=0):QVariantAnimation(parent),m_type(MoveDownAnimation){};
14 void setAnimationType(Animation type){
15 m_type=type;
16 }
17 protected:
18 Animation m_type;
19
13 };
20 };
14
21
15 QTCOMMERCIALCHART_END_NAMESPACE
22 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,9 +1,12
1 #include "chartanimator_p.h"
1 #include "chartanimator_p.h"
2 #include "axisanimation_p.h"
2 #include "axisanimation_p.h"
3 #include "xyanimation_p.h"
3 #include "xyanimation_p.h"
4 #include "splineanimation_p.h"
4 #include "xychartitem_p.h"
5 #include "xychartitem_p.h"
5 #include "pieanimation_p.h"
6 #include "pieanimation_p.h"
6 #include "areachartitem_p.h"
7 #include "areachartitem_p.h"
8 #include "splinechartitem_p.h"
9 #include "scatterchartitem_p.h"
7 #include <QTimer>
10 #include <QTimer>
8
11
9 Q_DECLARE_METATYPE(QVector<QPointF>)
12 Q_DECLARE_METATYPE(QVector<QPointF>)
@@ -33,7 +36,31 void ChartAnimator::addAnimation(AxisItem* item)
33 item->setAnimator(this);
36 item->setAnimator(this);
34 }
37 }
35
38
36 void ChartAnimator::addAnimation(XYChartItem* item)
39 void ChartAnimator::addAnimation(SplineChartItem* item)
40 {
41 ChartAnimation* animation = m_animations.value(item);
42
43 if(!animation) {
44 animation = new SplineAnimation(item);
45 m_animations.insert(item,animation);
46 }
47
48 item->setAnimator(this);
49 }
50
51 void ChartAnimator::addAnimation(ScatterChartItem* item)
52 {
53 ChartAnimation* animation = m_animations.value(item);
54
55 if(!animation) {
56 animation = new XYAnimation(item);
57 m_animations.insert(item,animation);
58 }
59
60 item->setAnimator(this);
61 }
62
63 void ChartAnimator::addAnimation(LineChartItem* item)
37 {
64 {
38 ChartAnimation* animation = m_animations.value(item);
65 ChartAnimation* animation = m_animations.value(item);
39
66
@@ -142,44 +169,57 void ChartAnimator::applyLayout(AxisItem* item , QVector<qreal>& newLayout)
142 QTimer::singleShot(0,animation,SLOT(start()));
169 QTimer::singleShot(0,animation,SLOT(start()));
143 }
170 }
144
171
145 void ChartAnimator::applyLayout(XYChartItem* item, QVector<QPointF>& newPoints)
172 void ChartAnimator::updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints ,QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newControlPoints,int index)
146 {
173 {
147
174 SplineAnimation* animation = static_cast<SplineAnimation*>(m_animations.value(item));
148 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
149
175
150 Q_ASSERT(animation);
176 Q_ASSERT(animation);
151
177
152 QVector<QPointF> oldPoints = item->points();
178 if(newPoints.count()<2 || newControlPoints.count()<2) return;
153
154 if(newPoints.count()==0) return;
155
179
156 bool empty = oldPoints.count()==0;
180 bool empty = oldPoints.count()==0;
157 oldPoints.resize(newPoints.size());
181
158
182
159 if(animation->state()!=QAbstractAnimation::Stopped) {
183 if(animation->state()!=QAbstractAnimation::Stopped) {
160 animation->stop();
184 animation->stop();
161 }
185 }
162
186
163 animation->setDuration(duration);
187 animation->setDuration(duration);
164 if(!empty)
188 if(!empty)
165 animation->setAnimationType(XYAnimation::MoveDownAnimation);
189 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
166 else
190 else
167 animation->setAnimationType(XYAnimation::LineDrawAnimation);
191 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
192
168 animation->setEasingCurve(QEasingCurve::OutQuart);
193 animation->setEasingCurve(QEasingCurve::OutQuart);
169 animation->setValues(oldPoints,newPoints);
194 animation->setValues(oldPoints,newPoints,oldControlPoints,newControlPoints,index);
195
170 QTimer::singleShot(0,animation,SLOT(start()));
196 QTimer::singleShot(0,animation,SLOT(start()));
171 }
197 }
172
198
173 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& newPoints)
199
200 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, int index)
174 {
201 {
175 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
202 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
176
203
177 Q_ASSERT(animation);
204 Q_ASSERT(animation);
178
205
206 if(newPoints.count()==0) return;
207
208 bool empty = oldPoints.count()==0;
209
210
211 if(animation->state()!=QAbstractAnimation::Stopped) {
212 animation->stop();
213 }
214
179 animation->setDuration(duration);
215 animation->setDuration(duration);
180 animation->setAnimationType(XYAnimation::MoveDownAnimation);
216 if(!empty)
217 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
218 else
219 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
220
181 animation->setEasingCurve(QEasingCurve::OutQuart);
221 animation->setEasingCurve(QEasingCurve::OutQuart);
182 animation->updateValues(newPoints);
222 animation->setValues(oldPoints,newPoints,index);
183
223
184 QTimer::singleShot(0,animation,SLOT(start()));
224 QTimer::singleShot(0,animation,SLOT(start()));
185 }
225 }
@@ -8,10 +8,12
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class ChartItem;
10 class ChartItem;
11 class XYChartItem;
12 class AxisItem;
11 class AxisItem;
13 class AreaChartItem;
12 class AreaChartItem;
14
13 class SplineChartItem;
14 class ScatterChartItem;
15 class LineChartItem;
16 class XYChartItem;
15
17
16 class ChartAnimator : public QObject {
18 class ChartAnimator : public QObject {
17
19
@@ -22,14 +24,15 public:
22 virtual ~ChartAnimator();
24 virtual ~ChartAnimator();
23
25
24 void addAnimation(AxisItem* item);
26 void addAnimation(AxisItem* item);
25 void addAnimation(XYChartItem* item);
26 void addAnimation(PieChartItem* item);
27 void addAnimation(PieChartItem* item);
27
28 void addAnimation(ScatterChartItem* item);
29 void addAnimation(LineChartItem* item);
30 void addAnimation(SplineChartItem* item);
28 void removeAnimation(ChartItem* item);
31 void removeAnimation(ChartItem* item);
29
32
30 void animationStarted();
33 void animationStarted();
31 void applyLayout(XYChartItem* item, QVector<QPointF>& layout);
34 void updateLayout(XYChartItem* item, QVector<QPointF>& oldLayout,QVector<QPointF>& newLayout,int index);
32 void updateLayout(XYChartItem* item, QVector<QPointF>& layout);
35 void updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newContorlPoints,int index);
33 void applyLayout(AxisItem* item, QVector<qreal>& layout);
36 void applyLayout(AxisItem* item, QVector<qreal>& layout);
34
37
35 void addAnimation(PieChartItem* item, QPieSlice *slice, PieSliceLayout &layout);
38 void addAnimation(PieChartItem* item, QPieSlice *slice, PieSliceLayout &layout);
@@ -7,7 +7,6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 XYAnimation::XYAnimation(XYChartItem *item):ChartAnimation(item),
8 XYAnimation::XYAnimation(XYChartItem *item):ChartAnimation(item),
9 m_item(item),
9 m_item(item),
10 m_type(MoveDownAnimation),
11 m_dirty(false)
10 m_dirty(false)
12 {
11 {
13 }
12 }
@@ -16,33 +15,31 XYAnimation::~XYAnimation()
16 {
15 {
17 }
16 }
18
17
19 void XYAnimation::setAnimationType(Animation type)
18 void XYAnimation::setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,int index)
20 {
19 {
21 m_type=type;
22 }
23
24 void XYAnimation::setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints)
25 {
26 setKeyValueAt(0.0, qVariantFromValue(oldPoints));
27 setKeyValueAt(1.0, qVariantFromValue(newPoints));
28 m_points = newPoints;
29 m_dirty=false;
30 }
31
20
32 void XYAnimation::updateValues(QVector<QPointF>& newPoints)
21 int x = oldPoints.count();
33 {
22 int y = newPoints.count();
34 if(state()!=QAbstractAnimation::Stopped) {
35 stop();
36 m_dirty=true;
37 }
38
23
39 if(m_dirty) {
24 if(x!=y && abs(x-y)!=1) {
40 m_points=newPoints;
25 m_oldPoints = newPoints;
26 oldPoints.resize(newPoints.size());
27 setKeyValueAt(0.0, qVariantFromValue(oldPoints));
28 setKeyValueAt(1.0, qVariantFromValue(newPoints));
41 m_dirty=false;
29 m_dirty=false;
42 }
30 }
43
31 else {
44 setKeyValueAt(0.0, qVariantFromValue(m_points));
32 if(m_dirty) {
45 setKeyValueAt(1.0, qVariantFromValue(newPoints));
33 m_oldPoints = oldPoints;
34 m_dirty=false;
35 }
36 oldPoints = newPoints;
37 if (y<x) (m_oldPoints.remove(index)); //remove
38 if (y>x) (m_oldPoints.insert(index,x>0?m_oldPoints[index-1]:newPoints[index])); //add
39 setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
40 setKeyValueAt(1.0, qVariantFromValue(newPoints));
41 Q_ASSERT(m_oldPoints.count() == newPoints.count());
42 }
46 }
43 }
47
44
48 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
45 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
@@ -82,16 +79,10 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant & end,
82 void XYAnimation::updateCurrentValue (const QVariant & value )
79 void XYAnimation::updateCurrentValue (const QVariant & value )
83 {
80 {
84 if(state()!=QAbstractAnimation::Stopped){ //workaround
81 if(state()!=QAbstractAnimation::Stopped){ //workaround
82 m_dirty=true;
85 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
83 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
86 m_item->setLayout(vector);
84 m_item->setLayout(vector);
87 }
85 }
88 }
86 }
89
87
90 void XYAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
91 {
92 Q_UNUSED(oldState)
93 if (newState==QAbstractAnimation::Running) m_dirty=true;
94 QVariantAnimation::updateState(newState,oldState);
95 }
96
97 QTCOMMERCIALCHART_END_NAMESPACE
88 QTCOMMERCIALCHART_END_NAMESPACE
@@ -13,19 +13,15 public:
13 enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
13 enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
14 XYAnimation(XYChartItem *item);
14 XYAnimation(XYChartItem *item);
15 ~XYAnimation();
15 ~XYAnimation();
16 void setAnimationType(Animation type);
16 void setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,int index);
17 void setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints);
18 void updateValues(QVector<QPointF>& newPoints);
19
17
20 protected:
18 protected:
21 QVariant interpolated(const QVariant &start, const QVariant & end, qreal progress ) const;
19 QVariant interpolated(const QVariant &start, const QVariant & end, qreal progress ) const;
22 void updateCurrentValue (const QVariant & value );
20 void updateCurrentValue (const QVariant & value );
23 void updateState ( QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
24
21
25 private:
22 private:
26 XYChartItem *m_item;
23 XYChartItem *m_item;
27 Animation m_type;
24 QVector<QPointF> m_oldPoints;
28 QVector<QPointF> m_points;
29 bool m_dirty;
25 bool m_dirty;
30 };
26 };
31
27
@@ -48,6 +48,7 void LineChartItem::setLayout(QVector<QPointF>& points)
48 m_rect = linePath.boundingRect();
48 m_rect = linePath.boundingRect();
49
49
50 XYChartItem::setLayout(points);
50 XYChartItem::setLayout(points);
51
51 }
52 }
52
53
53 void LineChartItem::handleUpdated()
54 void LineChartItem::handleUpdated()
@@ -1,5 +1,6
1 #include "splinechartitem_p.h"
1 #include "splinechartitem_p.h"
2 #include "chartpresenter_p.h"
2 #include "chartpresenter_p.h"
3 #include "chartanimator_p.h"
3 #include <QPainter>
4 #include <QPainter>
4
5
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -24,34 +25,59 QPainterPath SplineChartItem::shape() const
24 return m_path;
25 return m_path;
25 }
26 }
26
27
28 void SplineChartItem::updateLayout(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,int index)
29 {
30 QVector<QPointF> controlPoints;
31
32 controlPoints.resize(newPoints.count()*2-2);
33
34 for (int i = 0; i < newPoints.size() - 1; i++)
35 {
36 controlPoints[2*i] = calculateGeometryControlPoint(2 * i);
37 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
38 }
39
40 if(controlPoints.count()<2) {
41 setLayout(newPoints,controlPoints);
42 return;
43 }
44
45 if(m_animator){
46 m_animator->updateLayout(this,oldPoints,newPoints,m_controlPoints,controlPoints,index);
47 }else{
48 setLayout(newPoints,controlPoints);
49 }
50 }
51
27 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
52 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
28 {
53 {
29 return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
54 return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
30 }
55 }
31
56
32 void SplineChartItem::setLayout(QVector<QPointF>& points)
57 void SplineChartItem::setLayout(QVector<QPointF>& points,QVector<QPointF>& controlPoints)
33 {
58 {
34
59 if(points.size()<2 || controlPoints.size()<2)
35 if(points.size()==0)
36 {
60 {
37 XYChartItem::setLayout(points);
61 XYChartItem::setLayout(points);
62 m_controlPoints=controlPoints;
38 return;
63 return;
39 }
64 }
40
65
41 QPainterPath splinePath;
66 Q_ASSERT(points.count()*2-2 == controlPoints.count());
42 const QPointF& point = points.at(0);
67
43 splinePath.moveTo(point);
68 QPainterPath splinePath(points.at(0));
44
69
45 for (int i = 0; i < points.size() - 1; i++)
70 for (int i = 0; i < points.size() - 1; i++)
46 {
71 {
47 const QPointF& point = points.at(i + 1);
72 const QPointF& point = points.at(i + 1);
48 splinePath.cubicTo(calculateGeometryControlPoint(2 * i), calculateGeometryControlPoint(2 * i + 1), point);
73 splinePath.cubicTo(controlPoints[2*i],controlPoints[2 * i + 1],point);
49 }
74 }
50
75
51 prepareGeometryChange();
76 prepareGeometryChange();
52 m_path = splinePath;
77 m_path = splinePath;
53 m_rect = splinePath.boundingRect();
78 m_rect = splinePath.boundingRect();
54 XYChartItem::setLayout(points);
79 XYChartItem::setLayout(points);
80 m_controlPoints=controlPoints;
55 }
81 }
56
82
57 //handlers
83 //handlers
@@ -5,6 +5,7
5 #include "xychartitem_p.h"
5 #include "xychartitem_p.h"
6 #include <QGraphicsItem>
6 #include <QGraphicsItem>
7
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 class SplineChartItem : public XYChartItem
11 class SplineChartItem : public XYChartItem
@@ -22,7 +23,8 public slots:
22 void handleUpdated();
23 void handleUpdated();
23
24
24 protected:
25 protected:
25 void setLayout(QVector<QPointF>& points);
26 void setLayout(QVector<QPointF>& points,QVector<QPointF>& controlPoints);
27 void updateLayout(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,int index);
26
28
27 private:
29 private:
28 QPointF calculateGeometryControlPoint(int index) const;
30 QPointF calculateGeometryControlPoint(int index) const;
@@ -34,7 +36,9 private:
34 QPen m_linePen;
36 QPen m_linePen;
35 QPen m_pointPen;
37 QPen m_pointPen;
36 bool m_pointsVisible;
38 bool m_pointsVisible;
39 QVector<QPointF> m_controlPoints;
37
40
41 friend class SplineAnimation;
38 };
42 };
39
43
40 QTCOMMERCIALCHART_END_NAMESPACE
44 QTCOMMERCIALCHART_END_NAMESPACE
@@ -115,6 +115,21 void QXYSeries::replace(const QPointF& point)
115 }
115 }
116
116
117 /*!
117 /*!
118 Removes first \a x value and related y value.
119 */
120 void QXYSeries::remove(qreal x)
121 {
122 int index = m_x.indexOf(x);
123
124 if(index==-1) return;
125
126 m_x.remove(index);
127 m_y.remove(index);
128
129 emit pointRemoved(index);
130 }
131
132 /*!
118 Removes current \a x and \a y value.
133 Removes current \a x and \a y value.
119 */
134 */
120 void QXYSeries::remove(qreal x,qreal y)
135 void QXYSeries::remove(qreal x,qreal y)
@@ -22,6 +22,7 public:
22 void add(const QList<QPointF> points);
22 void add(const QList<QPointF> points);
23 void replace(qreal x,qreal y);
23 void replace(qreal x,qreal y);
24 void replace(const QPointF& point);
24 void replace(const QPointF& point);
25 void remove(qreal x);
25 void remove(qreal x, qreal y);
26 void remove(qreal x, qreal y);
26 void remove(const QPointF& point);
27 void remove(const QPointF& point);
27 void removeAll();
28 void removeAll();
@@ -66,23 +66,19 QPointF XYChartItem::calculateDomainPoint(const QPointF& point) const
66 return QPointF(x,y);
66 return QPointF(x,y);
67 }
67 }
68
68
69 void XYChartItem::applyLayout(QVector<QPointF>& points)
69 void XYChartItem::updateLayout(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,int index)
70 {
70 {
71 if(m_animator){
71 if(m_animator){
72 m_animator->applyLayout(this,points);
72 m_animator->updateLayout(this,oldPoints,newPoints,index);
73 }else{
74 setLayout(newPoints);
73 }
75 }
74 else setLayout(points);
75
76 }
77
78 void XYChartItem::updateLayout(QVector<QPointF>& points)
79 {
80 setLayout(points);
81 }
76 }
82
77
83 void XYChartItem::setLayout(QVector<QPointF>& points)
78 void XYChartItem::setLayout(QVector<QPointF>& points)
84 {
79 {
85 m_points = points;
80 m_points = points;
81 update();
86 }
82 }
87
83
88 //handlers
84 //handlers
@@ -91,11 +87,11 void XYChartItem::handlePointAdded(int index)
91 {
87 {
92 Q_ASSERT(index<m_series->count());
88 Q_ASSERT(index<m_series->count());
93 Q_ASSERT(index>=0);
89 Q_ASSERT(index>=0);
94
90 qDebug()<<__FUNCTION__<<index;
95 QPointF point = calculateGeometryPoint(index);
91 QPointF point = calculateGeometryPoint(index);
96 QVector<QPointF> points = m_points;
92 QVector<QPointF> points = m_points;
97 points.insert(index-1,point);
93 points.insert(index,point);
98 updateLayout(points);
94 updateLayout(m_points,points,index);
99 update();
95 update();
100 }
96 }
101 void XYChartItem::handlePointRemoved(int index)
97 void XYChartItem::handlePointRemoved(int index)
@@ -104,7 +100,7 void XYChartItem::handlePointRemoved(int index)
104 Q_ASSERT(index>=0);
100 Q_ASSERT(index>=0);
105 QVector<QPointF> points = m_points;
101 QVector<QPointF> points = m_points;
106 points.remove(index);
102 points.remove(index);
107 updateLayout(points);
103 updateLayout(m_points,points,index);
108 update();
104 update();
109 }
105 }
110
106
@@ -115,7 +111,7 void XYChartItem::handlePointReplaced(int index)
115 QPointF point = calculateGeometryPoint(index);
111 QPointF point = calculateGeometryPoint(index);
116 QVector<QPointF> points = m_points;
112 QVector<QPointF> points = m_points;
117 points.replace(index,point);
113 points.replace(index,point);
118 updateLayout(points);
114 updateLayout(m_points,points,index);
119 update();
115 update();
120 }
116 }
121
117
@@ -128,7 +124,7 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal
128
124
129 if(isEmpty()) return;
125 if(isEmpty()) return;
130 QVector<QPointF> points = calculateGeometryPoints();
126 QVector<QPointF> points = calculateGeometryPoints();
131 applyLayout(points);
127 updateLayout(m_points,points);
132 update();
128 update();
133 }
129 }
134
130
@@ -141,7 +137,7 void XYChartItem::handleGeometryChanged(const QRectF& rect)
141
137
142 if(isEmpty()) return;
138 if(isEmpty()) return;
143 QVector<QPointF> points = calculateGeometryPoints();
139 QVector<QPointF> points = calculateGeometryPoints();
144 applyLayout(points);
140 updateLayout(m_points,points);
145 update();
141 update();
146 }
142 }
147
143
@@ -32,6 +32,7 signals:
32
32
33 protected:
33 protected:
34 virtual void setLayout(QVector<QPointF>& points);
34 virtual void setLayout(QVector<QPointF>& points);
35 virtual void updateLayout(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints,int index = 0);
35 QPointF calculateGeometryPoint(const QPointF& point) const;
36 QPointF calculateGeometryPoint(const QPointF& point) const;
36 QPointF calculateGeometryPoint(int index) const;
37 QPointF calculateGeometryPoint(int index) const;
37 QPointF calculateDomainPoint(const QPointF& point) const;
38 QPointF calculateDomainPoint(const QPointF& point) const;
@@ -39,8 +40,6 protected:
39 void mousePressEvent( QGraphicsSceneMouseEvent * event );
40 void mousePressEvent( QGraphicsSceneMouseEvent * event );
40
41
41 private:
42 private:
42 void applyLayout(QVector<QPointF>& points);
43 void updateLayout(QVector<QPointF>& points);
44 inline bool isEmpty();
43 inline bool isEmpty();
45
44
46 private:
45 private:
General Comments 0
You need to be logged in to leave comments. Login now