##// 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
@@ -1,53 +1,58
1 #include "chartview.h"
1 #include "chartview.h"
2 #include <QSplineSeries>
2 #include <QSplineSeries>
3 #include <QTime>
3 #include <QTime>
4
4
5 ChartView::ChartView(QWidget* parent):QChartView(parent),
5 ChartView::ChartView(QWidget* parent):QChartView(parent),
6 m_step(1),
6 m_step(1),
7 m_x(0),
7 m_x(0),
8 m_y(1)
8 m_y(1)
9 {
9 {
10 QTime now = QTime::currentTime();
10 QTime now = QTime::currentTime();
11 qsrand((uint)now.msec());
11 qsrand((uint)now.msec());
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);
19 blue.setWidth(3);
19 blue.setWidth(3);
20 m_series0->setPen(blue);
20 m_series0->setPen(blue);
21
21
22
22
23 m_series1 = new QSplineSeries(this);
23 m_series1 = new QSplineSeries(this);
24 QPen green(Qt::green);
24 QPen green(Qt::green);
25 green.setWidth(3);
25 green.setWidth(3);
26 m_series1->setPen(green);
26 m_series1->setPen(green);
27
27
28
28
29 m_series0->add(m_x,m_y);
29 m_series0->add(m_x,m_y);
30 m_series1->add(m_x,m_y);
30 m_series1->add(m_x,m_y);
31
31
32 setChartTitle("Simple EKG exmaple");
32 setChartTitle("Simple EKG exmaple");
33 addSeries(m_series0);
33 addSeries(m_series0);
34 addSeries(m_series1);
34 addSeries(m_series1);
35 axisY()->setRange(-5,5);
35 axisY()->setRange(-5,5);
36 axisX()->setRange(-9,1);
36 axisX()->setRange(-9,1);
37 axisX()->setTicksCount(11);
37 axisX()->setTicksCount(11);
38 m_timer.start();
38 m_timer.start();
39 }
39 }
40
40
41 ChartView::~ChartView()
41 ChartView::~ChartView()
42 {
42 {
43
43
44 }
44 }
45
45
46 void ChartView::handleTimeout()
46 void ChartView::handleTimeout()
47 {
47 {
48 m_x+=m_step;
48 m_x+=m_step;
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 }
@@ -1,17 +1,20
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/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 \
13 $$PWD/chartanimator_p.h \
15 $$PWD/chartanimator_p.h \
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
@@ -1,19 +1,26
1 #ifndef CHARTANIMATION_H_
1 #ifndef CHARTANIMATION_H_
2 #define CHARTANIMATION_H_
2 #define CHARTANIMATION_H_
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QVariantAnimation>
5 #include <QVariantAnimation>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
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
16
23
17
24
18
25
19 #endif /* AXISITEM_H_ */
26 #endif /* AXISITEM_H_ */
@@ -1,221 +1,261
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>)
10 Q_DECLARE_METATYPE(QVector<qreal>)
13 Q_DECLARE_METATYPE(QVector<qreal>)
11
14
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
16
14 const static int duration = 1000;
17 const static int duration = 1000;
15
18
16 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
19 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
17 {
20 {
18 }
21 }
19
22
20 ChartAnimator::~ChartAnimator()
23 ChartAnimator::~ChartAnimator()
21 {
24 {
22 }
25 }
23
26
24 void ChartAnimator::addAnimation(AxisItem* item)
27 void ChartAnimator::addAnimation(AxisItem* item)
25 {
28 {
26 ChartAnimation* animation = m_animations.value(item);
29 ChartAnimation* animation = m_animations.value(item);
27
30
28 if(!animation) {
31 if(!animation) {
29 animation = new AxisAnimation(item);
32 animation = new AxisAnimation(item);
30 m_animations.insert(item,animation);
33 m_animations.insert(item,animation);
31 }
34 }
32
35
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
40 if(!animation) {
67 if(!animation) {
41 animation = new XYAnimation(item);
68 animation = new XYAnimation(item);
42 m_animations.insert(item,animation);
69 m_animations.insert(item,animation);
43 }
70 }
44
71
45 item->setAnimator(this);
72 item->setAnimator(this);
46 }
73 }
47
74
48 void ChartAnimator::addAnimation(PieChartItem* item)
75 void ChartAnimator::addAnimation(PieChartItem* item)
49 {
76 {
50 ChartAnimation* animation = m_animations.value(item);
77 ChartAnimation* animation = m_animations.value(item);
51
78
52 if(!animation) {
79 if(!animation) {
53 animation = new PieAnimation(item);
80 animation = new PieAnimation(item);
54 m_animations.insert(item,animation);
81 m_animations.insert(item,animation);
55 }
82 }
56
83
57 item->setAnimator(this);
84 item->setAnimator(this);
58 }
85 }
59
86
60 void ChartAnimator::removeAnimation(ChartItem* item)
87 void ChartAnimator::removeAnimation(ChartItem* item)
61 {
88 {
62 item->setAnimator(0);
89 item->setAnimator(0);
63 m_animations.remove(item);
90 m_animations.remove(item);
64 }
91 }
65
92
66 void ChartAnimator::applyLayout(AxisItem* item , QVector<qreal>& newLayout)
93 void ChartAnimator::applyLayout(AxisItem* item , QVector<qreal>& newLayout)
67 {
94 {
68 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
95 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
69
96
70 Q_ASSERT(animation);
97 Q_ASSERT(animation);
71
98
72 QVector<qreal> oldLayout = item->layout();
99 QVector<qreal> oldLayout = item->layout();
73
100
74 if(newLayout.count()==0) return;
101 if(newLayout.count()==0) return;
75
102
76 switch(m_state)
103 switch(m_state)
77 {
104 {
78 case ZoomOutState: {
105 case ZoomOutState: {
79 QRectF rect = item->geometry();
106 QRectF rect = item->geometry();
80 oldLayout.resize(newLayout.count());
107 oldLayout.resize(newLayout.count());
81
108
82 for(int i=0,j=oldLayout.count()-1;i<(oldLayout.count()+1)/2;i++,j--)
109 for(int i=0,j=oldLayout.count()-1;i<(oldLayout.count()+1)/2;i++,j--)
83 {
110 {
84 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.bottom();
111 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.bottom();
85 oldLayout[j]= item->axisType()==AxisItem::X_AXIS?rect.right():rect.top();
112 oldLayout[j]= item->axisType()==AxisItem::X_AXIS?rect.right():rect.top();
86 }
113 }
87 }
114 }
88 break;
115 break;
89 case ZoomInState: {
116 case ZoomInState: {
90 int index = qMin(oldLayout.count()*(item->axisType()==AxisItem::X_AXIS?m_point.x():(1 -m_point.y())),newLayout.count()-1.0);
117 int index = qMin(oldLayout.count()*(item->axisType()==AxisItem::X_AXIS?m_point.x():(1 -m_point.y())),newLayout.count()-1.0);
91 oldLayout.resize(newLayout.count());
118 oldLayout.resize(newLayout.count());
92
119
93 for(int i=0;i<oldLayout.count();i++)
120 for(int i=0;i<oldLayout.count();i++)
94 {
121 {
95 oldLayout[i]= oldLayout[index];
122 oldLayout[i]= oldLayout[index];
96 }
123 }
97 }
124 }
98 break;
125 break;
99 case ScrollDownState:
126 case ScrollDownState:
100 case ScrollRightState: {
127 case ScrollRightState: {
101 oldLayout.resize(newLayout.count());
128 oldLayout.resize(newLayout.count());
102
129
103 for(int i=0, j=i+1;i<oldLayout.count()-1;i++,j++)
130 for(int i=0, j=i+1;i<oldLayout.count()-1;i++,j++)
104 {
131 {
105 oldLayout[i]= oldLayout[j];
132 oldLayout[i]= oldLayout[j];
106 }
133 }
107 }
134 }
108 break;
135 break;
109 case ScrollUpState:
136 case ScrollUpState:
110 case ScrollLeftState: {
137 case ScrollLeftState: {
111 oldLayout.resize(newLayout.count());
138 oldLayout.resize(newLayout.count());
112
139
113 for(int i=oldLayout.count()-1, j=i-1;i>0;i--,j--)
140 for(int i=oldLayout.count()-1, j=i-1;i>0;i--,j--)
114 {
141 {
115 oldLayout[i]= oldLayout[j];
142 oldLayout[i]= oldLayout[j];
116 }
143 }
117 }
144 }
118 break;
145 break;
119 default: {
146 default: {
120 oldLayout.resize(newLayout.count());
147 oldLayout.resize(newLayout.count());
121 QRectF rect = item->geometry();
148 QRectF rect = item->geometry();
122 for(int i=0, j=oldLayout.count()-1;i<oldLayout.count();i++,j--)
149 for(int i=0, j=oldLayout.count()-1;i<oldLayout.count();i++,j--)
123 {
150 {
124 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.top();
151 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.top();
125 }
152 }
126 }
153 }
127 break;
154 break;
128 }
155 }
129
156
130
157
131 if(animation->state()!=QAbstractAnimation::Stopped) {
158 if(animation->state()!=QAbstractAnimation::Stopped) {
132 animation->stop();
159 animation->stop();
133 }
160 }
134
161
135 animation->setDuration(duration);
162 animation->setDuration(duration);
136 animation->setEasingCurve(QEasingCurve::OutQuart);
163 animation->setEasingCurve(QEasingCurve::OutQuart);
137 QVariantAnimation::KeyValues value;
164 QVariantAnimation::KeyValues value;
138 animation->setKeyValues(value); //workaround for wrong interpolation call
165 animation->setKeyValues(value); //workaround for wrong interpolation call
139 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
166 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
140 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
167 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
141
168
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 }
186
226
187 void ChartAnimator::addAnimation(PieChartItem* item, QPieSlice *slice, PieSliceLayout &layout)
227 void ChartAnimator::addAnimation(PieChartItem* item, QPieSlice *slice, PieSliceLayout &layout)
188 {
228 {
189 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
229 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
190 Q_ASSERT(animation);
230 Q_ASSERT(animation);
191 animation->addSlice(slice, layout);
231 animation->addSlice(slice, layout);
192 }
232 }
193
233
194 void ChartAnimator::removeAnimation(PieChartItem* item, QPieSlice *slice)
234 void ChartAnimator::removeAnimation(PieChartItem* item, QPieSlice *slice)
195 {
235 {
196 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
236 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
197 Q_ASSERT(animation);
237 Q_ASSERT(animation);
198 animation->removeSlice(slice);
238 animation->removeSlice(slice);
199 }
239 }
200
240
201 void ChartAnimator::updateLayout(PieChartItem* item, QVector<PieSliceLayout> &layout)
241 void ChartAnimator::updateLayout(PieChartItem* item, QVector<PieSliceLayout> &layout)
202 {
242 {
203 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
243 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
204 Q_ASSERT(animation);
244 Q_ASSERT(animation);
205 animation->updateValues(layout);
245 animation->updateValues(layout);
206 }
246 }
207
247
208 void ChartAnimator::updateLayout(PieChartItem* item, PieSliceLayout &layout)
248 void ChartAnimator::updateLayout(PieChartItem* item, PieSliceLayout &layout)
209 {
249 {
210 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
250 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
211 Q_ASSERT(animation);
251 Q_ASSERT(animation);
212 animation->updateValue(layout);
252 animation->updateValue(layout);
213 }
253 }
214
254
215 void ChartAnimator::setState(State state,const QPointF& point)
255 void ChartAnimator::setState(State state,const QPointF& point)
216 {
256 {
217 m_state=state;
257 m_state=state;
218 m_point=point;
258 m_point=point;
219 }
259 }
220
260
221 QTCOMMERCIALCHART_END_NAMESPACE
261 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,50 +1,53
1 #ifndef CHARTANIMATOR_P_H_
1 #ifndef CHARTANIMATOR_P_H_
2 #define CHARTANIMATOR_P_H_
2 #define CHARTANIMATOR_P_H_
3 #include "qchartglobal.h"
3 #include "qchartglobal.h"
4 #include "chartanimation_p.h"
4 #include "chartanimation_p.h"
5 #include "piechartitem_p.h"
5 #include "piechartitem_p.h"
6 #include <QPointF>
6 #include <QPointF>
7
7
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
18 public:
20 public:
19 //TODO: this should be flags in case of two state at the time
21 //TODO: this should be flags in case of two state at the time
20 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState,ScrollRightState,ZoomInState,ZoomOutState};
22 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState,ScrollRightState,ZoomInState,ZoomOutState};
21 ChartAnimator(QObject *parent = 0);
23 ChartAnimator(QObject *parent = 0);
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);
36 void removeAnimation(PieChartItem* item, QPieSlice *slice);
39 void removeAnimation(PieChartItem* item, QPieSlice *slice);
37 void updateLayout(PieChartItem* item, QVector<PieSliceLayout> &layout);
40 void updateLayout(PieChartItem* item, QVector<PieSliceLayout> &layout);
38 void updateLayout(PieChartItem* item, PieSliceLayout &layout);
41 void updateLayout(PieChartItem* item, PieSliceLayout &layout);
39
42
40 void setState(State state,const QPointF& point = QPointF());
43 void setState(State state,const QPointF& point = QPointF());
41
44
42 private:
45 private:
43 QMap<ChartItem*,ChartAnimation*> m_animations;
46 QMap<ChartItem*,ChartAnimation*> m_animations;
44 State m_state;
47 State m_state;
45 QPointF m_point;
48 QPointF m_point;
46 };
49 };
47
50
48 QTCOMMERCIALCHART_END_NAMESPACE
51 QTCOMMERCIALCHART_END_NAMESPACE
49
52
50 #endif
53 #endif
@@ -1,97 +1,88
1 #include "xyanimation_p.h"
1 #include "xyanimation_p.h"
2 #include "xychartitem_p.h"
2 #include "xychartitem_p.h"
3
3
4 Q_DECLARE_METATYPE(QVector<QPointF>)
4 Q_DECLARE_METATYPE(QVector<QPointF>)
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
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 }
14
13
15 XYAnimation::~XYAnimation()
14 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
49 {
46 {
50 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
47 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
51 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
48 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
52 QVector<QPointF> result;
49 QVector<QPointF> result;
53
50
54 switch(m_type) {
51 switch(m_type) {
55
52
56 case MoveDownAnimation: {
53 case MoveDownAnimation: {
57
54
58 if(startVector.count() != endVector.count()) break;
55 if(startVector.count() != endVector.count()) break;
59
56
60 for(int i =0;i< startVector.count();i++) {
57 for(int i =0;i< startVector.count();i++) {
61 qreal x = startVector[i].x() + ((endVector[i].x()- startVector[i].x()) * progress);
58 qreal x = startVector[i].x() + ((endVector[i].x()- startVector[i].x()) * progress);
62 qreal y = startVector[i].y() + ((endVector[i].y()- startVector[i].y()) * progress);
59 qreal y = startVector[i].y() + ((endVector[i].y()- startVector[i].y()) * progress);
63 result << QPointF(x,y);
60 result << QPointF(x,y);
64 }
61 }
65
62
66 }
63 }
67 break;
64 break;
68 case LineDrawAnimation:{
65 case LineDrawAnimation:{
69 for(int i =0;i< endVector.count()* qBound(0.0, progress, 1.0);i++) {
66 for(int i =0;i< endVector.count()* qBound(0.0, progress, 1.0);i++) {
70 result << endVector[i];
67 result << endVector[i];
71 }
68 }
72 }
69 }
73 break;
70 break;
74 default:
71 default:
75 qWarning()<<"Unknow type of animation";
72 qWarning()<<"Unknow type of animation";
76 break;
73 break;
77 }
74 }
78
75
79 return qVariantFromValue(result);
76 return qVariantFromValue(result);
80 }
77 }
81
78
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
@@ -1,34 +1,30
1 #ifndef XYCHARTANIMATION_P_H_
1 #ifndef XYCHARTANIMATION_P_H_
2 #define XYCHARTANIMATION_P_H_
2 #define XYCHARTANIMATION_P_H_
3 #include "chartanimation_p.h"
3 #include "chartanimation_p.h"
4 #include <QPointF>
4 #include <QPointF>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 class XYChartItem;
8 class XYChartItem;
9
9
10 class XYAnimation : public ChartAnimation
10 class XYAnimation : public ChartAnimation
11 {
11 {
12 public:
12 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
32 QTCOMMERCIALCHART_END_NAMESPACE
28 QTCOMMERCIALCHART_END_NAMESPACE
33
29
34 #endif
30 #endif
@@ -1,82 +1,83
1 #include "linechartitem_p.h"
1 #include "linechartitem_p.h"
2 #include "qlineseries.h"
2 #include "qlineseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include <QPainter>
4 #include <QPainter>
5
5
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 //TODO: optimize : remove points which are not visible
9 //TODO: optimize : remove points which are not visible
10
10
11 LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):XYChartItem(series,parent),
11 LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):XYChartItem(series,parent),
12 m_series(series),
12 m_series(series),
13 m_pointsVisible(false)
13 m_pointsVisible(false)
14 {
14 {
15 setZValue(ChartPresenter::LineChartZValue);
15 setZValue(ChartPresenter::LineChartZValue);
16 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
16 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
17 handleUpdated();
17 handleUpdated();
18 }
18 }
19
19
20 QRectF LineChartItem::boundingRect() const
20 QRectF LineChartItem::boundingRect() const
21 {
21 {
22 return m_rect;
22 return m_rect;
23 }
23 }
24
24
25 QPainterPath LineChartItem::shape() const
25 QPainterPath LineChartItem::shape() const
26 {
26 {
27 return m_path;
27 return m_path;
28 }
28 }
29
29
30 void LineChartItem::setLayout(QVector<QPointF>& points)
30 void LineChartItem::setLayout(QVector<QPointF>& points)
31 {
31 {
32 if(points.size()==0)
32 if(points.size()==0)
33 {
33 {
34 XYChartItem::setLayout(points);
34 XYChartItem::setLayout(points);
35 return;
35 return;
36 }
36 }
37
37
38 QList<QGraphicsItem*> items = m_items.childItems();
38 QList<QGraphicsItem*> items = m_items.childItems();
39
39
40 QPainterPath linePath(points.at(0));
40 QPainterPath linePath(points.at(0));
41
41
42 for(int i=1; i< points.size();i++) {
42 for(int i=1; i< points.size();i++) {
43 linePath.lineTo(points.at(i));
43 linePath.lineTo(points.at(i));
44 }
44 }
45
45
46 prepareGeometryChange();
46 prepareGeometryChange();
47 m_path = linePath;
47 m_path = linePath;
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()
54 {
55 {
55 m_pointsVisible = m_series->pointsVisible();
56 m_pointsVisible = m_series->pointsVisible();
56 m_linePen = m_series->pen();
57 m_linePen = m_series->pen();
57 m_pointPen = m_series->pen();
58 m_pointPen = m_series->pen();
58 m_pointPen.setWidthF(2*m_pointPen.width());
59 m_pointPen.setWidthF(2*m_pointPen.width());
59 update();
60 update();
60 }
61 }
61
62
62 //painter
63 //painter
63
64
64 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
65 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
65 {
66 {
66 Q_UNUSED(widget)
67 Q_UNUSED(widget)
67 Q_UNUSED(option)
68 Q_UNUSED(option)
68
69
69 painter->save();
70 painter->save();
70 painter->setPen(m_linePen);
71 painter->setPen(m_linePen);
71 painter->setClipRect(clipRect());
72 painter->setClipRect(clipRect());
72 painter->drawPath(m_path);
73 painter->drawPath(m_path);
73 if(m_pointsVisible){
74 if(m_pointsVisible){
74 painter->setPen(m_pointPen);
75 painter->setPen(m_pointPen);
75 painter->drawPoints(points());
76 painter->drawPoints(points());
76 }
77 }
77 painter->restore();
78 painter->restore();
78 }
79 }
79
80
80 #include "moc_linechartitem_p.cpp"
81 #include "moc_linechartitem_p.cpp"
81
82
82 QTCOMMERCIALCHART_END_NAMESPACE
83 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,90 +1,116
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
6
7
7 SplineChartItem::SplineChartItem(QSplineSeries* series, QGraphicsItem *parent) :
8 SplineChartItem::SplineChartItem(QSplineSeries* series, QGraphicsItem *parent) :
8 XYChartItem(series, parent),
9 XYChartItem(series, parent),
9 m_series(series),
10 m_series(series),
10 m_pointsVisible(false)
11 m_pointsVisible(false)
11 {
12 {
12 setZValue(ChartPresenter::LineChartZValue);
13 setZValue(ChartPresenter::LineChartZValue);
13 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
14 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
14 handleUpdated();
15 handleUpdated();
15 }
16 }
16
17
17 QRectF SplineChartItem::boundingRect() const
18 QRectF SplineChartItem::boundingRect() const
18 {
19 {
19 return m_rect;
20 return m_rect;
20 }
21 }
21
22
22 QPainterPath SplineChartItem::shape() const
23 QPainterPath SplineChartItem::shape() const
23 {
24 {
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
58
84
59 void SplineChartItem::handleUpdated()
85 void SplineChartItem::handleUpdated()
60 {
86 {
61 m_pointsVisible = m_series->pointsVisible();
87 m_pointsVisible = m_series->pointsVisible();
62 m_linePen = m_series->pen();
88 m_linePen = m_series->pen();
63 m_pointPen = m_series->pen();
89 m_pointPen = m_series->pen();
64 m_pointPen.setWidthF(2*m_pointPen.width());
90 m_pointPen.setWidthF(2*m_pointPen.width());
65 update();
91 update();
66 }
92 }
67
93
68 //painter
94 //painter
69
95
70 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
96 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
71 {
97 {
72 Q_UNUSED(widget)
98 Q_UNUSED(widget)
73 Q_UNUSED(option)
99 Q_UNUSED(option)
74
100
75 painter->save();
101 painter->save();
76 painter->setClipRect(clipRect());
102 painter->setClipRect(clipRect());
77 painter->setPen(m_linePen);
103 painter->setPen(m_linePen);
78 painter->drawPath(m_path);
104 painter->drawPath(m_path);
79 if(m_pointsVisible){
105 if(m_pointsVisible){
80 painter->setPen(m_pointPen);
106 painter->setPen(m_pointPen);
81 painter->drawPoints(points());
107 painter->drawPoints(points());
82 }
108 }
83 painter->restore();
109 painter->restore();
84 }
110 }
85
111
86
112
87
113
88 #include "moc_splinechartitem_p.cpp"
114 #include "moc_splinechartitem_p.cpp"
89
115
90 QTCOMMERCIALCHART_END_NAMESPACE
116 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,42 +1,46
1 #ifndef SPLINECHARTITEM_P_H
1 #ifndef SPLINECHARTITEM_P_H
2 #define SPLINECHARTITEM_P_H
2 #define SPLINECHARTITEM_P_H
3
3
4 #include "qsplineseries.h"
4 #include "qsplineseries.h"
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
11 {
12 {
12 Q_OBJECT
13 Q_OBJECT
13 public:
14 public:
14 SplineChartItem(QSplineSeries* series, QGraphicsItem *parent = 0);
15 SplineChartItem(QSplineSeries* series, QGraphicsItem *parent = 0);
15
16
16 //from QGraphicsItem
17 //from QGraphicsItem
17 QRectF boundingRect() const;
18 QRectF boundingRect() const;
18 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
19 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
19 QPainterPath shape() const;
20 QPainterPath shape() const;
20
21
21 public slots:
22 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;
29
31
30 private:
32 private:
31 QSplineSeries* m_series;
33 QSplineSeries* m_series;
32 QPainterPath m_path;
34 QPainterPath m_path;
33 QRectF m_rect;
35 QRectF m_rect;
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
41
45
42 #endif // SPLINECHARTITEM_P_H
46 #endif // SPLINECHARTITEM_P_H
@@ -1,318 +1,333
1 #include "qxyseries.h"
1 #include "qxyseries.h"
2
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
4
5 /*!
5 /*!
6 \class QXYSeries
6 \class QXYSeries
7 \brief The QXYSeries class is a base class for line, spline and scatter series.
7 \brief The QXYSeries class is a base class for line, spline and scatter series.
8 */
8 */
9
9
10 /*!
10 /*!
11 \fn QPen QXYSeries::pen() const
11 \fn QPen QXYSeries::pen() const
12 \brief Returns pen used to draw points for series.
12 \brief Returns pen used to draw points for series.
13 \sa setPen()
13 \sa setPen()
14 */
14 */
15
15
16 /*!
16 /*!
17 \fn QBrush QXYSeries::brush() const
17 \fn QBrush QXYSeries::brush() const
18 \brief Returns brush used to draw points for series.
18 \brief Returns brush used to draw points for series.
19 \sa setBrush()
19 \sa setBrush()
20 */
20 */
21
21
22 /*!
22 /*!
23 \fn void QXYSeries::clicked(const QPointF& point)
23 \fn void QXYSeries::clicked(const QPointF& point)
24 \brief Signal is emitted when user clicks the \a point on chart.
24 \brief Signal is emitted when user clicks the \a point on chart.
25 */
25 */
26
26
27 /*!
27 /*!
28 \fn void QXYSeries::pointReplaced(int index)
28 \fn void QXYSeries::pointReplaced(int index)
29 \brief \internal \a index
29 \brief \internal \a index
30 */
30 */
31
31
32 /*!
32 /*!
33 \fn void QXYSeries::pointAdded(int index)
33 \fn void QXYSeries::pointAdded(int index)
34 \brief \internal \a index
34 \brief \internal \a index
35 */
35 */
36
36
37 /*!
37 /*!
38 \fn void QXYSeries::pointRemoved(int index)
38 \fn void QXYSeries::pointRemoved(int index)
39 \brief \internal \a index
39 \brief \internal \a index
40 */
40 */
41
41
42 /*!
42 /*!
43 \fn void QXYSeries::updated()
43 \fn void QXYSeries::updated()
44 \brief \internal
44 \brief \internal
45 */
45 */
46
46
47 /*!
47 /*!
48 Constructs empty series object which is a child of \a parent.
48 Constructs empty series object which is a child of \a parent.
49 When series object is added to QChartView or QChart instance ownerships is transfered.
49 When series object is added to QChartView or QChart instance ownerships is transfered.
50 */
50 */
51 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
51 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
52 {
52 {
53 m_mapX = -1;
53 m_mapX = -1;
54 m_mapY = -1;
54 m_mapY = -1;
55 m_mapOrientation = Qt::Vertical;
55 m_mapOrientation = Qt::Vertical;
56 // m_mapYOrientation = Qt::Vertical;
56 // m_mapYOrientation = Qt::Vertical;
57 }
57 }
58 /*!
58 /*!
59 Destroys the object. Series added to QChartView or QChart instances are owned by those,
59 Destroys the object. Series added to QChartView or QChart instances are owned by those,
60 and are deleted when mentioned object are destroyed.
60 and are deleted when mentioned object are destroyed.
61 */
61 */
62 QXYSeries::~QXYSeries()
62 QXYSeries::~QXYSeries()
63 {
63 {
64 }
64 }
65
65
66 /*!
66 /*!
67 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
67 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
68 */
68 */
69 void QXYSeries::add(qreal x,qreal y)
69 void QXYSeries::add(qreal x,qreal y)
70 {
70 {
71 Q_ASSERT(m_x.size() == m_y.size());
71 Q_ASSERT(m_x.size() == m_y.size());
72 m_x<<x;
72 m_x<<x;
73 m_y<<y;
73 m_y<<y;
74 emit pointAdded(m_x.size()-1);
74 emit pointAdded(m_x.size()-1);
75 }
75 }
76
76
77 /*!
77 /*!
78 This is an overloaded function.
78 This is an overloaded function.
79 Adds data \a point to the series. Points are connected with lines on the chart.
79 Adds data \a point to the series. Points are connected with lines on the chart.
80 */
80 */
81 void QXYSeries::add(const QPointF& point)
81 void QXYSeries::add(const QPointF& point)
82 {
82 {
83 add(point.x(),point.y());
83 add(point.x(),point.y());
84 }
84 }
85
85
86 /*!
86 /*!
87 This is an overloaded function.
87 This is an overloaded function.
88 Adds list of data \a points to the series. Points are connected with lines on the chart.
88 Adds list of data \a points to the series. Points are connected with lines on the chart.
89 */
89 */
90 void QXYSeries::add(const QList<QPointF> points)
90 void QXYSeries::add(const QList<QPointF> points)
91 {
91 {
92 foreach(const QPointF& point , points) {
92 foreach(const QPointF& point , points) {
93 add(point.x(),point.y());
93 add(point.x(),point.y());
94 }
94 }
95 }
95 }
96
96
97 /*!
97 /*!
98 Modifies \a y value for given \a x a value.
98 Modifies \a y value for given \a x a value.
99 */
99 */
100 void QXYSeries::replace(qreal x,qreal y)
100 void QXYSeries::replace(qreal x,qreal y)
101 {
101 {
102 int index = m_x.indexOf(x);
102 int index = m_x.indexOf(x);
103 m_x[index]=x;
103 m_x[index]=x;
104 m_y[index]=y;
104 m_y[index]=y;
105 emit pointReplaced(index);
105 emit pointReplaced(index);
106 }
106 }
107
107
108 /*!
108 /*!
109 This is an overloaded function.
109 This is an overloaded function.
110 Replaces current y value of for given \a point x value with \a point y value.
110 Replaces current y value of for given \a point x value with \a point y value.
111 */
111 */
112 void QXYSeries::replace(const QPointF& point)
112 void QXYSeries::replace(const QPointF& point)
113 {
113 {
114 replace(point.x(),point.y());
114 replace(point.x(),point.y());
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)
121 {
136 {
122 int index =-1;
137 int index =-1;
123 do{
138 do{
124 index = m_x.indexOf(x,index+1);
139 index = m_x.indexOf(x,index+1);
125 }while(index !=-1 && m_y.at(index)!=y);
140 }while(index !=-1 && m_y.at(index)!=y);
126
141
127 if(index==-1) return;
142 if(index==-1) return;
128
143
129 m_x.remove(index);
144 m_x.remove(index);
130 m_y.remove(index);
145 m_y.remove(index);
131 emit pointRemoved(index);
146 emit pointRemoved(index);
132 }
147 }
133
148
134 /*!
149 /*!
135 Removes current \a point x value. Note \a point y value is ignored.
150 Removes current \a point x value. Note \a point y value is ignored.
136 */
151 */
137 void QXYSeries::remove(const QPointF& point)
152 void QXYSeries::remove(const QPointF& point)
138 {
153 {
139 remove(point.x(),point.y());
154 remove(point.x(),point.y());
140 }
155 }
141
156
142 /*!
157 /*!
143 Removes all data points from the series.
158 Removes all data points from the series.
144 */
159 */
145 void QXYSeries::removeAll()
160 void QXYSeries::removeAll()
146 {
161 {
147 m_x.clear();
162 m_x.clear();
148 m_y.clear();
163 m_y.clear();
149 }
164 }
150
165
151 /*!
166 /*!
152 \internal \a pos
167 \internal \a pos
153 */
168 */
154 qreal QXYSeries::x(int pos) const
169 qreal QXYSeries::x(int pos) const
155 {
170 {
156 if (m_model)
171 if (m_model)
157 if (m_mapOrientation == Qt::Vertical)
172 if (m_mapOrientation == Qt::Vertical)
158 // consecutive data is read from model's column
173 // consecutive data is read from model's column
159 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
174 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
160 else
175 else
161 // consecutive data is read from model's row
176 // consecutive data is read from model's row
162 return m_model->data(m_model->index(m_mapX, pos), Qt::DisplayRole).toDouble();
177 return m_model->data(m_model->index(m_mapX, pos), Qt::DisplayRole).toDouble();
163 else
178 else
164 // model is not specified, return the data from series' internal data store
179 // model is not specified, return the data from series' internal data store
165 return m_x.at(pos);
180 return m_x.at(pos);
166 }
181 }
167
182
168 /*!
183 /*!
169 \internal \a pos
184 \internal \a pos
170 */
185 */
171 qreal QXYSeries::y(int pos) const
186 qreal QXYSeries::y(int pos) const
172 {
187 {
173 if (m_model)
188 if (m_model)
174 if (m_mapOrientation == Qt::Vertical)
189 if (m_mapOrientation == Qt::Vertical)
175 // consecutive data is read from model's column
190 // consecutive data is read from model's column
176 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
191 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
177 else
192 else
178 // consecutive data is read from model's row
193 // consecutive data is read from model's row
179 return m_model->data(m_model->index(m_mapY, pos), Qt::DisplayRole).toDouble();
194 return m_model->data(m_model->index(m_mapY, pos), Qt::DisplayRole).toDouble();
180 else
195 else
181 // model is not specified, return the data from series' internal data store
196 // model is not specified, return the data from series' internal data store
182 return m_y.at(pos);
197 return m_y.at(pos);
183 }
198 }
184
199
185 /*!
200 /*!
186 Returns number of data points within series.
201 Returns number of data points within series.
187 */
202 */
188 int QXYSeries::count() const
203 int QXYSeries::count() const
189 {
204 {
190 Q_ASSERT(m_x.size() == m_y.size());
205 Q_ASSERT(m_x.size() == m_y.size());
191
206
192 if (m_model) {
207 if (m_model) {
193 if (m_mapOrientation == Qt::Vertical)
208 if (m_mapOrientation == Qt::Vertical)
194 // data is in a column, so return the number of items in single column
209 // data is in a column, so return the number of items in single column
195 return m_model->rowCount();
210 return m_model->rowCount();
196 else
211 else
197 // data is in a row, so return the number of items in single row
212 // data is in a row, so return the number of items in single row
198 return m_model->columnCount();
213 return m_model->columnCount();
199 }
214 }
200
215
201 // model is not specified, return the number of points in the series internal data store
216 // model is not specified, return the number of points in the series internal data store
202 return m_x.size();
217 return m_x.size();
203 }
218 }
204
219
205 /*!
220 /*!
206 Returns the data points of the series.
221 Returns the data points of the series.
207 */
222 */
208 QList<QPointF> QXYSeries::data()
223 QList<QPointF> QXYSeries::data()
209 {
224 {
210 QList<QPointF> data;
225 QList<QPointF> data;
211 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
226 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
212 data.append(QPointF(m_x.at(i), m_y.at(i)));
227 data.append(QPointF(m_x.at(i), m_y.at(i)));
213 return data;
228 return data;
214 }
229 }
215
230
216
231
217 /*!
232 /*!
218 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
233 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
219 pen from chart theme is used.
234 pen from chart theme is used.
220 \sa QChart::setChartTheme()
235 \sa QChart::setChartTheme()
221 */
236 */
222 void QXYSeries::setPen(const QPen& pen)
237 void QXYSeries::setPen(const QPen& pen)
223 {
238 {
224 if(pen!=m_pen){
239 if(pen!=m_pen){
225 m_pen=pen;
240 m_pen=pen;
226 emit updated();
241 emit updated();
227 }
242 }
228 }
243 }
229
244
230 /*!
245 /*!
231 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
246 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
232 from chart theme setting is used.
247 from chart theme setting is used.
233 \sa QChart::setChartTheme()
248 \sa QChart::setChartTheme()
234 */
249 */
235
250
236 void QXYSeries::setBrush(const QBrush& brush)
251 void QXYSeries::setBrush(const QBrush& brush)
237 {
252 {
238 if(brush!=m_brush){
253 if(brush!=m_brush){
239 m_brush=brush;
254 m_brush=brush;
240 emit updated();
255 emit updated();
241 }
256 }
242 }
257 }
243
258
244
259
245 /*!
260 /*!
246 Stream operator for adding a data \a point to the series.
261 Stream operator for adding a data \a point to the series.
247 \sa add()
262 \sa add()
248 */
263 */
249
264
250 QXYSeries& QXYSeries::operator<< (const QPointF &point)
265 QXYSeries& QXYSeries::operator<< (const QPointF &point)
251 {
266 {
252 add(point);
267 add(point);
253 return *this;
268 return *this;
254 }
269 }
255
270
256
271
257 /*!
272 /*!
258 Stream operator for adding a list of \a points to the series.
273 Stream operator for adding a list of \a points to the series.
259 \sa add()
274 \sa add()
260 */
275 */
261
276
262 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
277 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
263 {
278 {
264 add(points);
279 add(points);
265 return *this;
280 return *this;
266 }
281 }
267
282
268
283
269 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
284 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
270 {
285 {
271 Q_UNUSED(bottomRight)
286 Q_UNUSED(bottomRight)
272
287
273 if (m_mapOrientation == Qt::Vertical)
288 if (m_mapOrientation == Qt::Vertical)
274 emit pointReplaced(topLeft.row());
289 emit pointReplaced(topLeft.row());
275 else
290 else
276 emit pointReplaced(topLeft.column());
291 emit pointReplaced(topLeft.column());
277 }
292 }
278
293
279 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
294 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
280 {
295 {
281 Q_UNUSED(parent)
296 Q_UNUSED(parent)
282 Q_UNUSED(end)
297 Q_UNUSED(end)
283 emit pointAdded(start);
298 emit pointAdded(start);
284 }
299 }
285
300
286 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
301 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
287 {
302 {
288 Q_UNUSED(parent)
303 Q_UNUSED(parent)
289 Q_UNUSED(end)
304 Q_UNUSED(end)
290 emit pointRemoved(start);
305 emit pointRemoved(start);
291 }
306 }
292
307
293 bool QXYSeries::setModel(QAbstractItemModel* model) {
308 bool QXYSeries::setModel(QAbstractItemModel* model) {
294 m_model = model;
309 m_model = model;
295 // for (int i = 0; i < m_model->rowCount(); i++)
310 // for (int i = 0; i < m_model->rowCount(); i++)
296 // emit pointAdded(i);
311 // emit pointAdded(i);
297 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
312 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
298 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
313 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
299 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
314 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
300 return true;
315 return true;
301 }
316 }
302
317
303 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
318 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
304 {
319 {
305 m_mapX = modelX;
320 m_mapX = modelX;
306 m_mapY = modelY;
321 m_mapY = modelY;
307 m_mapOrientation = orientation;
322 m_mapOrientation = orientation;
308 }
323 }
309
324
310 //void QXYSeries::setModelMappingY(int modelLineIndex, Qt::Orientation orientation)
325 //void QXYSeries::setModelMappingY(int modelLineIndex, Qt::Orientation orientation)
311 //{
326 //{
312 // m_mapY = modelLineIndex;
327 // m_mapY = modelLineIndex;
313 // m_mapYOrientation = orientation;
328 // m_mapYOrientation = orientation;
314 //}
329 //}
315
330
316 #include "moc_qxyseries.cpp"
331 #include "moc_qxyseries.cpp"
317
332
318 QTCOMMERCIALCHART_END_NAMESPACE
333 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,76 +1,77
1 #ifndef QXYSERIES_H_
1 #ifndef QXYSERIES_H_
2 #define QXYSERIES_H_
2 #define QXYSERIES_H_
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qseries.h"
5 #include "qseries.h"
6 #include <QDebug>
6 #include <QDebug>
7 #include <QPen>
7 #include <QPen>
8 #include <QBrush>
8 #include <QBrush>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
12 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 protected:
15 protected:
16 QXYSeries(QObject* parent=0);
16 QXYSeries(QObject* parent=0);
17 virtual ~QXYSeries();
17 virtual ~QXYSeries();
18
18
19 public:
19 public:
20 void add(qreal x, qreal y);
20 void add(qreal x, qreal y);
21 void add(const QPointF& point);
21 void add(const QPointF& point);
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();
28
29
29 int count() const;
30 int count() const;
30 qreal x(int pos) const;
31 qreal x(int pos) const;
31 qreal y(int pos) const;
32 qreal y(int pos) const;
32 QList<QPointF> data();
33 QList<QPointF> data();
33
34
34 QXYSeries& operator << (const QPointF &point);
35 QXYSeries& operator << (const QPointF &point);
35 QXYSeries& operator << (const QList<QPointF> points);
36 QXYSeries& operator << (const QList<QPointF> points);
36
37
37 void setPen(const QPen& pen);
38 void setPen(const QPen& pen);
38 QPen pen() const {return m_pen;}
39 QPen pen() const {return m_pen;}
39 void setBrush(const QBrush& pen);
40 void setBrush(const QBrush& pen);
40 QBrush brush() const {return m_brush;}
41 QBrush brush() const {return m_brush;}
41
42
42 bool setModel(QAbstractItemModel* model);
43 bool setModel(QAbstractItemModel* model);
43 QAbstractItemModel* model() {return m_model;}
44 QAbstractItemModel* model() {return m_model;}
44
45
45 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
46 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
46 // void setModelMappingY(int modelLineIndex, Qt::Orientation orientation = Qt::Vertical);
47 // void setModelMappingY(int modelLineIndex, Qt::Orientation orientation = Qt::Vertical);
47
48
48 private slots:
49 private slots:
49 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
50 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
50 void modelDataAdded(QModelIndex parent, int start, int end);
51 void modelDataAdded(QModelIndex parent, int start, int end);
51 void modelDataRemoved(QModelIndex parent, int start, int end);
52 void modelDataRemoved(QModelIndex parent, int start, int end);
52
53
53 signals:
54 signals:
54 void clicked(const QPointF& point);
55 void clicked(const QPointF& point);
55 void updated();
56 void updated();
56 void pointReplaced(int index);
57 void pointReplaced(int index);
57 void pointRemoved(int index);
58 void pointRemoved(int index);
58 void pointAdded(int index);
59 void pointAdded(int index);
59
60
60 protected:
61 protected:
61 QVector<qreal> m_x;
62 QVector<qreal> m_x;
62 QVector<qreal> m_y;
63 QVector<qreal> m_y;
63
64
64 QPen m_pen;
65 QPen m_pen;
65 QBrush m_brush;
66 QBrush m_brush;
66
67
67 // QAbstractItemModel* m_model;
68 // QAbstractItemModel* m_model;
68 int m_mapX;
69 int m_mapX;
69 Qt::Orientation m_mapOrientation;
70 Qt::Orientation m_mapOrientation;
70 int m_mapY;
71 int m_mapY;
71 // Qt::Orientation m_mapYOrientation;
72 // Qt::Orientation m_mapYOrientation;
72 };
73 };
73
74
74 QTCOMMERCIALCHART_END_NAMESPACE
75 QTCOMMERCIALCHART_END_NAMESPACE
75
76
76 #endif
77 #endif
@@ -1,161 +1,157
1 #include "xychartitem_p.h"
1 #include "xychartitem_p.h"
2 #include "qxyseries.h"
2 #include "qxyseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartanimator_p.h"
4 #include "chartanimator_p.h"
5 #include <QPainter>
5 #include <QPainter>
6 #include <QGraphicsSceneMouseEvent>
6 #include <QGraphicsSceneMouseEvent>
7
7
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 //TODO: optimize : remove points which are not visible
11 //TODO: optimize : remove points which are not visible
12
12
13 XYChartItem::XYChartItem(QXYSeries* series, QGraphicsItem *parent):ChartItem(parent),
13 XYChartItem::XYChartItem(QXYSeries* series, QGraphicsItem *parent):ChartItem(parent),
14 m_minX(0),
14 m_minX(0),
15 m_maxX(0),
15 m_maxX(0),
16 m_minY(0),
16 m_minY(0),
17 m_maxY(0),
17 m_maxY(0),
18 m_series(series)
18 m_series(series)
19 {
19 {
20 QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
20 QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
21 QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
21 QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
22 QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
22 QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
23 QObject::connect(this,SIGNAL(clicked(const QPointF&)),series,SIGNAL(clicked(const QPointF&)));
23 QObject::connect(this,SIGNAL(clicked(const QPointF&)),series,SIGNAL(clicked(const QPointF&)));
24 }
24 }
25
25
26 QPointF XYChartItem::calculateGeometryPoint(const QPointF& point) const
26 QPointF XYChartItem::calculateGeometryPoint(const QPointF& point) const
27 {
27 {
28 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
28 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
29 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
29 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
30 qreal x = (point.x() - m_minX)* deltaX;
30 qreal x = (point.x() - m_minX)* deltaX;
31 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
31 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
32 return QPointF(x,y);
32 return QPointF(x,y);
33 }
33 }
34
34
35
35
36 QPointF XYChartItem::calculateGeometryPoint(int index) const
36 QPointF XYChartItem::calculateGeometryPoint(int index) const
37 {
37 {
38 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
38 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
39 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
39 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
40 qreal x = (m_series->x(index) - m_minX)* deltaX;
40 qreal x = (m_series->x(index) - m_minX)* deltaX;
41 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
41 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
42 return QPointF(x,y);
42 return QPointF(x,y);
43 }
43 }
44
44
45 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
45 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
46 {
46 {
47 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
47 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
48 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
48 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
49
49
50 QVector<QPointF> points;
50 QVector<QPointF> points;
51 points.reserve(m_series->count());
51 points.reserve(m_series->count());
52 for (int i = 0; i < m_series->count(); ++i) {
52 for (int i = 0; i < m_series->count(); ++i) {
53 qreal x = (m_series->x(i) - m_minX)* deltaX;
53 qreal x = (m_series->x(i) - m_minX)* deltaX;
54 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
54 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
55 points << QPointF(x,y);
55 points << QPointF(x,y);
56 }
56 }
57 return points;
57 return points;
58 }
58 }
59
59
60 QPointF XYChartItem::calculateDomainPoint(const QPointF& point) const
60 QPointF XYChartItem::calculateDomainPoint(const QPointF& point) const
61 {
61 {
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
64 qreal x = point.x()/deltaX +m_minX;
64 qreal x = point.x()/deltaX +m_minX;
65 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
65 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
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
89
85
90 void XYChartItem::handlePointAdded(int index)
86 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)
102 {
98 {
103 Q_ASSERT(index<m_series->count() + 1);
99 Q_ASSERT(index<m_series->count() + 1);
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
111 void XYChartItem::handlePointReplaced(int index)
107 void XYChartItem::handlePointReplaced(int index)
112 {
108 {
113 Q_ASSERT(index<m_series->count());
109 Q_ASSERT(index<m_series->count());
114 Q_ASSERT(index>=0);
110 Q_ASSERT(index>=0);
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
122 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
118 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
123 {
119 {
124 m_minX=minX;
120 m_minX=minX;
125 m_maxX=maxX;
121 m_maxX=maxX;
126 m_minY=minY;
122 m_minY=minY;
127 m_maxY=maxY;
123 m_maxY=maxY;
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
135 void XYChartItem::handleGeometryChanged(const QRectF& rect)
131 void XYChartItem::handleGeometryChanged(const QRectF& rect)
136 {
132 {
137 Q_ASSERT(rect.isValid());
133 Q_ASSERT(rect.isValid());
138 m_size=rect.size();
134 m_size=rect.size();
139 m_clipRect=rect.translated(-rect.topLeft());
135 m_clipRect=rect.translated(-rect.topLeft());
140 setPos(rect.topLeft());
136 setPos(rect.topLeft());
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
148
144
149 bool XYChartItem::isEmpty()
145 bool XYChartItem::isEmpty()
150 {
146 {
151 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
147 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
152 }
148 }
153
149
154 void XYChartItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
150 void XYChartItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
155 {
151 {
156 emit clicked(calculateDomainPoint(event->pos()));
152 emit clicked(calculateDomainPoint(event->pos()));
157 }
153 }
158
154
159 #include "moc_xychartitem_p.cpp"
155 #include "moc_xychartitem_p.cpp"
160
156
161 QTCOMMERCIALCHART_END_NAMESPACE
157 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,63 +1,62
1 #ifndef XYCHARTITEM_H
1 #ifndef XYCHARTITEM_H
2 #define XYCHARTITEM_H
2 #define XYCHARTITEM_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include <QPen>
6 #include <QPen>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class ChartPresenter;
10 class ChartPresenter;
11 class QXYSeries;
11 class QXYSeries;
12
12
13 class XYChartItem : public QObject , public ChartItem
13 class XYChartItem : public QObject , public ChartItem
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 public:
16 public:
17 explicit XYChartItem(QXYSeries* series, QGraphicsItem *parent = 0);
17 explicit XYChartItem(QXYSeries* series, QGraphicsItem *parent = 0);
18 ~ XYChartItem(){};
18 ~ XYChartItem(){};
19
19
20 QVector<QPointF> points() const {return m_points;}
20 QVector<QPointF> points() const {return m_points;}
21 QRectF clipRect() const { return m_clipRect;}
21 QRectF clipRect() const { return m_clipRect;}
22
22
23 public slots:
23 public slots:
24 void handlePointAdded(int index);
24 void handlePointAdded(int index);
25 void handlePointRemoved(int index);
25 void handlePointRemoved(int index);
26 void handlePointReplaced(int index);
26 void handlePointReplaced(int index);
27 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
27 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
28 void handleGeometryChanged(const QRectF& size);
28 void handleGeometryChanged(const QRectF& size);
29
29
30 signals:
30 signals:
31 void clicked(const QPointF& point);
31 void clicked(const QPointF& point);
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;
38 QVector<QPointF> calculateGeometryPoints() const;
39 QVector<QPointF> calculateGeometryPoints() const;
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:
47 qreal m_minX;
46 qreal m_minX;
48 qreal m_maxX;
47 qreal m_maxX;
49 qreal m_minY;
48 qreal m_minY;
50 qreal m_maxY;
49 qreal m_maxY;
51 QXYSeries* m_series;
50 QXYSeries* m_series;
52 QSizeF m_size;
51 QSizeF m_size;
53 QRectF m_clipRect;
52 QRectF m_clipRect;
54 QVector<QPointF> m_points;
53 QVector<QPointF> m_points;
55
54
56 friend class XYAnimation;
55 friend class XYAnimation;
57 friend class AreaChartItem;
56 friend class AreaChartItem;
58
57
59 };
58 };
60
59
61 QTCOMMERCIALCHART_END_NAMESPACE
60 QTCOMMERCIALCHART_END_NAMESPACE
62
61
63 #endif
62 #endif
General Comments 0
You need to be logged in to leave comments. Login now