##// END OF EJS Templates
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
Jani Honkonen -
r668:ea2480445e4a
parent child
Show More
@@ -1,261 +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 "splineanimation_p.h"
5 #include "xychartitem_p.h"
5 #include "xychartitem_p.h"
6 #include "pieanimation_p.h"
6 #include "pieanimation_p.h"
7 #include "areachartitem_p.h"
7 #include "areachartitem_p.h"
8 #include "splinechartitem_p.h"
8 #include "splinechartitem_p.h"
9 #include "scatterchartitem_p.h"
9 #include "scatterchartitem_p.h"
10 #include <QTimer>
10 #include <QTimer>
11
11
12 Q_DECLARE_METATYPE(QVector<QPointF>)
12 Q_DECLARE_METATYPE(QVector<QPointF>)
13 Q_DECLARE_METATYPE(QVector<qreal>)
13 Q_DECLARE_METATYPE(QVector<qreal>)
14
14
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
16
16
17 const static int duration = 1000;
17 const static int duration = 1000;
18
18
19 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
19 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
20 {
20 {
21 }
21 }
22
22
23 ChartAnimator::~ChartAnimator()
23 ChartAnimator::~ChartAnimator()
24 {
24 {
25 }
25 }
26
26
27 void ChartAnimator::addAnimation(AxisItem* item)
27 void ChartAnimator::addAnimation(AxisItem* item)
28 {
28 {
29 ChartAnimation* animation = m_animations.value(item);
29 ChartAnimation* animation = m_animations.value(item);
30
30
31 if(!animation) {
31 if(!animation) {
32 animation = new AxisAnimation(item);
32 animation = new AxisAnimation(item);
33 m_animations.insert(item,animation);
33 m_animations.insert(item,animation);
34 }
34 }
35
35
36 item->setAnimator(this);
36 item->setAnimator(this);
37 }
37 }
38
38
39 void ChartAnimator::addAnimation(SplineChartItem* item)
39 void ChartAnimator::addAnimation(SplineChartItem* item)
40 {
40 {
41 ChartAnimation* animation = m_animations.value(item);
41 ChartAnimation* animation = m_animations.value(item);
42
42
43 if(!animation) {
43 if(!animation) {
44 animation = new SplineAnimation(item);
44 animation = new SplineAnimation(item);
45 m_animations.insert(item,animation);
45 m_animations.insert(item,animation);
46 }
46 }
47
47
48 item->setAnimator(this);
48 item->setAnimator(this);
49 }
49 }
50
50
51 void ChartAnimator::addAnimation(ScatterChartItem* item)
51 void ChartAnimator::addAnimation(ScatterChartItem* item)
52 {
52 {
53 ChartAnimation* animation = m_animations.value(item);
53 ChartAnimation* animation = m_animations.value(item);
54
54
55 if(!animation) {
55 if(!animation) {
56 animation = new XYAnimation(item);
56 animation = new XYAnimation(item);
57 m_animations.insert(item,animation);
57 m_animations.insert(item,animation);
58 }
58 }
59
59
60 item->setAnimator(this);
60 item->setAnimator(this);
61 }
61 }
62
62
63 void ChartAnimator::addAnimation(LineChartItem* item)
63 void ChartAnimator::addAnimation(LineChartItem* item)
64 {
64 {
65 ChartAnimation* animation = m_animations.value(item);
65 ChartAnimation* animation = m_animations.value(item);
66
66
67 if(!animation) {
67 if(!animation) {
68 animation = new XYAnimation(item);
68 animation = new XYAnimation(item);
69 m_animations.insert(item,animation);
69 m_animations.insert(item,animation);
70 }
70 }
71
71
72 item->setAnimator(this);
72 item->setAnimator(this);
73 }
73 }
74
74
75 void ChartAnimator::addAnimation(PieChartItem* item)
75 void ChartAnimator::addAnimation(PieChartItem* item)
76 {
76 {
77 ChartAnimation* animation = m_animations.value(item);
77 ChartAnimation* animation = m_animations.value(item);
78
78
79 if(!animation) {
79 if(!animation) {
80 animation = new PieAnimation(item);
80 animation = new PieAnimation(item);
81 m_animations.insert(item,animation);
81 m_animations.insert(item,animation);
82 }
82 }
83
83
84 item->setAnimator(this);
84 item->setAnimator(this);
85 }
85 }
86
86
87 void ChartAnimator::removeAnimation(ChartItem* item)
87 void ChartAnimator::removeAnimation(ChartItem* item)
88 {
88 {
89 item->setAnimator(0);
89 item->setAnimator(0);
90 m_animations.remove(item);
90 m_animations.remove(item);
91 }
91 }
92
92
93 void ChartAnimator::updateLayout(AxisItem* item , QVector<qreal>& newLayout)
93 void ChartAnimator::updateLayout(AxisItem* item , QVector<qreal>& newLayout)
94 {
94 {
95 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
95 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
96
96
97 Q_ASSERT(animation);
97 Q_ASSERT(animation);
98
98
99 QVector<qreal> oldLayout = item->layout();
99 QVector<qreal> oldLayout = item->layout();
100
100
101 if(newLayout.count()==0) return;
101 if(newLayout.count()==0) return;
102
102
103 switch(m_state)
103 switch(m_state)
104 {
104 {
105 case ZoomOutState: {
105 case ZoomOutState: {
106 QRectF rect = item->geometry();
106 QRectF rect = item->geometry();
107 oldLayout.resize(newLayout.count());
107 oldLayout.resize(newLayout.count());
108
108
109 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--)
110 {
110 {
111 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.bottom();
111 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.bottom();
112 oldLayout[j]= item->axisType()==AxisItem::X_AXIS?rect.right():rect.top();
112 oldLayout[j]= item->axisType()==AxisItem::X_AXIS?rect.right():rect.top();
113 }
113 }
114 }
114 }
115 break;
115 break;
116 case ZoomInState: {
116 case ZoomInState: {
117 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);
118 oldLayout.resize(newLayout.count());
118 oldLayout.resize(newLayout.count());
119
119
120 for(int i=0;i<oldLayout.count();i++)
120 for(int i=0;i<oldLayout.count();i++)
121 {
121 {
122 oldLayout[i]= oldLayout[index];
122 oldLayout[i]= oldLayout[index];
123 }
123 }
124 }
124 }
125 break;
125 break;
126 case ScrollDownState:
126 case ScrollDownState:
127 case ScrollRightState: {
127 case ScrollRightState: {
128 oldLayout.resize(newLayout.count());
128 oldLayout.resize(newLayout.count());
129
129
130 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++)
131 {
131 {
132 oldLayout[i]= oldLayout[j];
132 oldLayout[i]= oldLayout[j];
133 }
133 }
134 }
134 }
135 break;
135 break;
136 case ScrollUpState:
136 case ScrollUpState:
137 case ScrollLeftState: {
137 case ScrollLeftState: {
138 oldLayout.resize(newLayout.count());
138 oldLayout.resize(newLayout.count());
139
139
140 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--)
141 {
141 {
142 oldLayout[i]= oldLayout[j];
142 oldLayout[i]= oldLayout[j];
143 }
143 }
144 }
144 }
145 break;
145 break;
146 default: {
146 default: {
147 oldLayout.resize(newLayout.count());
147 oldLayout.resize(newLayout.count());
148 QRectF rect = item->geometry();
148 QRectF rect = item->geometry();
149 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--)
150 {
150 {
151 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.top();
151 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.top();
152 }
152 }
153 }
153 }
154 break;
154 break;
155 }
155 }
156
156
157
157
158 if(animation->state()!=QAbstractAnimation::Stopped) {
158 if(animation->state()!=QAbstractAnimation::Stopped) {
159 animation->stop();
159 animation->stop();
160 }
160 }
161
161
162 animation->setDuration(duration);
162 animation->setDuration(duration);
163 animation->setEasingCurve(QEasingCurve::OutQuart);
163 animation->setEasingCurve(QEasingCurve::OutQuart);
164 QVariantAnimation::KeyValues value;
164 QVariantAnimation::KeyValues value;
165 animation->setKeyValues(value); //workaround for wrong interpolation call
165 animation->setKeyValues(value); //workaround for wrong interpolation call
166 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
166 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
167 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
167 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
168
168
169 QTimer::singleShot(0,animation,SLOT(start()));
169 QTimer::singleShot(0,animation,SLOT(start()));
170 }
170 }
171
171
172 void ChartAnimator::updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints ,QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newControlPoints,int index)
172 void ChartAnimator::updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints ,QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newControlPoints,int index)
173 {
173 {
174 SplineAnimation* animation = static_cast<SplineAnimation*>(m_animations.value(item));
174 SplineAnimation* animation = static_cast<SplineAnimation*>(m_animations.value(item));
175
175
176 Q_ASSERT(animation);
176 Q_ASSERT(animation);
177
177
178 if(newPoints.count()<2 || newControlPoints.count()<2) return;
178 if(newPoints.count()<2 || newControlPoints.count()<2) return;
179
179
180 bool empty = oldPoints.count()==0;
180 bool empty = oldPoints.count()==0;
181
181
182
182
183 if(animation->state()!=QAbstractAnimation::Stopped) {
183 if(animation->state()!=QAbstractAnimation::Stopped) {
184 animation->stop();
184 animation->stop();
185 }
185 }
186
186
187 animation->setDuration(duration);
187 animation->setDuration(duration);
188 if(!empty)
188 if(!empty)
189 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
189 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
190 else
190 else
191 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
191 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
192
192
193 animation->setEasingCurve(QEasingCurve::OutQuart);
193 animation->setEasingCurve(QEasingCurve::OutQuart);
194 animation->setValues(oldPoints,newPoints,oldControlPoints,newControlPoints,index);
194 animation->setValues(oldPoints,newPoints,oldControlPoints,newControlPoints,index);
195
195
196 QTimer::singleShot(0,animation,SLOT(start()));
196 QTimer::singleShot(0,animation,SLOT(start()));
197 }
197 }
198
198
199
199
200 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, int index)
200 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, int index)
201 {
201 {
202 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
202 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
203
203
204 Q_ASSERT(animation);
204 Q_ASSERT(animation);
205
205
206 if(newPoints.count()==0) return;
206 if(newPoints.count()==0) return;
207
207
208 bool empty = oldPoints.count()==0;
208 bool empty = oldPoints.count()==0;
209
209
210
210
211 if(animation->state()!=QAbstractAnimation::Stopped) {
211 if(animation->state()!=QAbstractAnimation::Stopped) {
212 animation->stop();
212 animation->stop();
213 }
213 }
214
214
215 animation->setDuration(duration);
215 animation->setDuration(duration);
216 if(!empty)
216 if(!empty)
217 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
217 animation->setAnimationType(ChartAnimation::MoveDownAnimation);
218 else
218 else
219 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
219 animation->setAnimationType(ChartAnimation::LineDrawAnimation);
220
220
221 animation->setEasingCurve(QEasingCurve::OutQuart);
221 animation->setEasingCurve(QEasingCurve::OutQuart);
222 animation->setValues(oldPoints,newPoints,index);
222 animation->setValues(oldPoints,newPoints,index);
223
223
224 QTimer::singleShot(0,animation,SLOT(start()));
224 QTimer::singleShot(0,animation,SLOT(start()));
225 }
225 }
226
226
227 void ChartAnimator::addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout, bool isEmpty)
227 void ChartAnimator::addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
228 {
228 {
229 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
229 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
230 Q_ASSERT(animation);
230 Q_ASSERT(animation);
231 animation->addSlice(slice, layout, isEmpty);
231 animation->addSlice(slice, sliceData, isEmpty);
232 }
232 }
233
233
234 void ChartAnimator::removeAnimation(PieChartItem* item, QPieSlice *slice)
234 void ChartAnimator::removeAnimation(PieChartItem* item, QPieSlice *slice)
235 {
235 {
236 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
236 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
237 Q_ASSERT(animation);
237 Q_ASSERT(animation);
238 animation->removeSlice(slice);
238 animation->removeSlice(slice);
239 }
239 }
240
240
241 void ChartAnimator::updateLayout(PieChartItem* item, const PieLayout &layout)
241 void ChartAnimator::updateLayout(PieChartItem* item, const PieLayout &layout)
242 {
242 {
243 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
243 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
244 Q_ASSERT(animation);
244 Q_ASSERT(animation);
245 animation->updateValues(layout);
245 animation->updateValues(layout);
246 }
246 }
247
247
248 void ChartAnimator::updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout)
248 void ChartAnimator::updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceData &sliceData)
249 {
249 {
250 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
250 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
251 Q_ASSERT(animation);
251 Q_ASSERT(animation);
252 animation->updateValue(slice, layout);
252 animation->updateValue(slice, sliceData);
253 }
253 }
254
254
255 void ChartAnimator::setState(State state,const QPointF& point)
255 void ChartAnimator::setState(State state,const QPointF& point)
256 {
256 {
257 m_state=state;
257 m_state=state;
258 m_point=point;
258 m_point=point;
259 }
259 }
260
260
261 QTCOMMERCIALCHART_END_NAMESPACE
261 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,53 +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 AxisItem;
11 class AxisItem;
12 class AreaChartItem;
12 class AreaChartItem;
13 class SplineChartItem;
13 class SplineChartItem;
14 class ScatterChartItem;
14 class ScatterChartItem;
15 class LineChartItem;
15 class LineChartItem;
16 class XYChartItem;
16 class XYChartItem;
17
17
18 class ChartAnimator : public QObject {
18 class ChartAnimator : public QObject {
19
19
20 public:
20 public:
21 //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
22 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState,ScrollRightState,ZoomInState,ZoomOutState};
22 enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState,ScrollRightState,ZoomInState,ZoomOutState};
23 ChartAnimator(QObject *parent = 0);
23 ChartAnimator(QObject *parent = 0);
24 virtual ~ChartAnimator();
24 virtual ~ChartAnimator();
25
25
26 void addAnimation(AxisItem* item);
26 void addAnimation(AxisItem* item);
27 void addAnimation(PieChartItem* item);
27 void addAnimation(PieChartItem* item);
28 void addAnimation(ScatterChartItem* item);
28 void addAnimation(ScatterChartItem* item);
29 void addAnimation(LineChartItem* item);
29 void addAnimation(LineChartItem* item);
30 void addAnimation(SplineChartItem* item);
30 void addAnimation(SplineChartItem* item);
31 void removeAnimation(ChartItem* item);
31 void removeAnimation(ChartItem* item);
32
32
33 void animationStarted();
33 void animationStarted();
34 void updateLayout(XYChartItem* item, QVector<QPointF>& oldLayout,QVector<QPointF>& newLayout,int index);
34 void updateLayout(XYChartItem* item, QVector<QPointF>& oldLayout,QVector<QPointF>& newLayout,int index);
35 void updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newContorlPoints,int index);
35 void updateLayout(SplineChartItem* item, QVector<QPointF>& oldPoints , QVector<QPointF>& newPoints, QVector<QPointF>& oldControlPoints, QVector<QPointF>& newContorlPoints,int index);
36 void updateLayout(AxisItem* item, QVector<qreal>& layout);
36 void updateLayout(AxisItem* item, QVector<qreal>& layout);
37
37
38 void addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout, bool isEmpty);
38 void addAnimation(PieChartItem* item, QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty);
39 void removeAnimation(PieChartItem* item, QPieSlice *slice);
39 void removeAnimation(PieChartItem* item, QPieSlice *slice);
40 void updateLayout(PieChartItem* item, const PieLayout &layout);
40 void updateLayout(PieChartItem* item, const PieLayout &layout);
41 void updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceLayout &layout);
41 void updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceData &sliceData);
42
42
43 void setState(State state,const QPointF& point = QPointF());
43 void setState(State state,const QPointF& point = QPointF());
44
44
45 private:
45 private:
46 QMap<ChartItem*,ChartAnimation*> m_animations;
46 QMap<ChartItem*,ChartAnimation*> m_animations;
47 State m_state;
47 State m_state;
48 QPointF m_point;
48 QPointF m_point;
49 };
49 };
50
50
51 QTCOMMERCIALCHART_END_NAMESPACE
51 QTCOMMERCIALCHART_END_NAMESPACE
52
52
53 #endif
53 #endif
@@ -1,92 +1,92
1 #include "pieanimation_p.h"
1 #include "pieanimation_p.h"
2 #include "piesliceanimation_p.h"
2 #include "piesliceanimation_p.h"
3 #include "piechartitem_p.h"
3 #include "piechartitem_p.h"
4 #include <QParallelAnimationGroup>
4 #include <QParallelAnimationGroup>
5 #include <QTimer>
5 #include <QTimer>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 PieAnimation::PieAnimation(PieChartItem *item)
9 PieAnimation::PieAnimation(PieChartItem *item)
10 :ChartAnimation(item),
10 :ChartAnimation(item),
11 m_item(item)
11 m_item(item)
12 {
12 {
13 }
13 }
14
14
15 PieAnimation::~PieAnimation()
15 PieAnimation::~PieAnimation()
16 {
16 {
17 }
17 }
18
18
19 void PieAnimation::updateValues(const PieLayout &newValues)
19 void PieAnimation::updateValues(const PieLayout &newValues)
20 {
20 {
21 foreach (QPieSlice* s, newValues.keys())
21 foreach (QPieSlice* s, newValues.keys())
22 updateValue(s, newValues.value(s));
22 updateValue(s, newValues.value(s));
23 }
23 }
24
24
25 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceLayout &endLayout)
25 void PieAnimation::updateValue(QPieSlice *slice, const PieSliceData &sliceData)
26 {
26 {
27 PieSliceAnimation *animation = m_animations.value(slice);
27 PieSliceAnimation *animation = m_animations.value(slice);
28 Q_ASSERT(animation);
28 Q_ASSERT(animation);
29 animation->stop();
29 animation->stop();
30
30
31 animation->updateValue(endLayout);
31 animation->updateValue(sliceData);
32 animation->setDuration(1000);
32 animation->setDuration(1000);
33 animation->setEasingCurve(QEasingCurve::OutQuart);
33 animation->setEasingCurve(QEasingCurve::OutQuart);
34
34
35 QTimer::singleShot(0, animation, SLOT(start()));
35 QTimer::singleShot(0, animation, SLOT(start()));
36 }
36 }
37
37
38 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceLayout &endLayout, bool isEmpty)
38 void PieAnimation::addSlice(QPieSlice *slice, const PieSliceData &sliceData, bool isEmpty)
39 {
39 {
40 PieSliceAnimation *animation = new PieSliceAnimation(m_item, slice);
40 PieSliceAnimation *animation = new PieSliceAnimation(m_item, slice);
41 m_animations.insert(slice, animation);
41 m_animations.insert(slice, animation);
42
42
43 PieSliceLayout startLayout = endLayout;
43 PieSliceData startValue = sliceData;
44 startLayout.m_radius = 0;
44 startValue.m_radius = 0;
45 if (isEmpty)
45 if (isEmpty)
46 startLayout.m_startAngle = 0;
46 startValue.m_startAngle = 0;
47 else
47 else
48 startLayout.m_startAngle = endLayout.m_startAngle + (endLayout.m_angleSpan/2);
48 startValue.m_startAngle = sliceData.m_startAngle + (sliceData.m_angleSpan/2);
49 startLayout.m_angleSpan = 0;
49 startValue.m_angleSpan = 0;
50 animation->setValue(startLayout, endLayout);
50 animation->setValue(startValue, sliceData);
51
51
52 animation->setDuration(1000);
52 animation->setDuration(1000);
53 animation->setEasingCurve(QEasingCurve::OutQuart);
53 animation->setEasingCurve(QEasingCurve::OutQuart);
54 QTimer::singleShot(0, animation, SLOT(start()));
54 QTimer::singleShot(0, animation, SLOT(start()));
55 }
55 }
56
56
57 void PieAnimation::removeSlice(QPieSlice *slice)
57 void PieAnimation::removeSlice(QPieSlice *slice)
58 {
58 {
59 PieSliceAnimation *animation = m_animations.value(slice);
59 PieSliceAnimation *animation = m_animations.value(slice);
60 Q_ASSERT(animation);
60 Q_ASSERT(animation);
61 animation->stop();
61 animation->stop();
62
62
63 PieSliceLayout endLayout = animation->currentSliceValue();
63 PieSliceData endValue = animation->currentSliceValue();
64 endLayout.m_radius = 0;
64 endValue.m_radius = 0;
65 // TODO: find the actual angle where this slice disappears
65 // TODO: find the actual angle where this slice disappears
66 endLayout.m_startAngle = endLayout.m_startAngle + endLayout.m_angleSpan;
66 endValue.m_startAngle = endValue.m_startAngle + endValue.m_angleSpan;
67 endLayout.m_angleSpan = 0;
67 endValue.m_angleSpan = 0;
68
68
69 animation->updateValue(endLayout);
69 animation->updateValue(endValue);
70 animation->setDuration(1000);
70 animation->setDuration(1000);
71 animation->setEasingCurve(QEasingCurve::OutQuart);
71 animation->setEasingCurve(QEasingCurve::OutQuart);
72
72
73 connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete()));
73 connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete()));
74 QTimer::singleShot(0, animation, SLOT(start()));
74 QTimer::singleShot(0, animation, SLOT(start()));
75 }
75 }
76
76
77 void PieAnimation::updateCurrentValue(const QVariant &)
77 void PieAnimation::updateCurrentValue(const QVariant &)
78 {
78 {
79 // nothing to do...
79 // nothing to do...
80 }
80 }
81
81
82 void PieAnimation::destroySliceAnimationComplete()
82 void PieAnimation::destroySliceAnimationComplete()
83 {
83 {
84 PieSliceAnimation *animation = static_cast<PieSliceAnimation*>(sender());
84 PieSliceAnimation *animation = static_cast<PieSliceAnimation*>(sender());
85 QPieSlice *slice = m_animations.key(animation);
85 QPieSlice *slice = m_animations.key(animation);
86 m_item->destroySlice(slice);
86 m_item->destroySlice(slice);
87 delete m_animations.take(slice);
87 delete m_animations.take(slice);
88 }
88 }
89
89
90 #include "moc_pieanimation_p.cpp"
90 #include "moc_pieanimation_p.cpp"
91
91
92 QTCOMMERCIALCHART_END_NAMESPACE
92 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,37 +1,37
1 #ifndef PIEANIMATION_P_H_
1 #ifndef PIEANIMATION_P_H_
2 #define PIEANIMATION_P_H_
2 #define PIEANIMATION_P_H_
3
3
4 #include "chartanimation_p.h"
4 #include "chartanimation_p.h"
5 #include "piechartitem_p.h"
5 #include "piechartitem_p.h"
6 #include "piesliceanimation_p.h"
6 #include "piesliceanimation_p.h"
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class PieChartItem;
10 class PieChartItem;
11
11
12 class PieAnimation : public ChartAnimation
12 class PieAnimation : public ChartAnimation
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15
15
16 public:
16 public:
17 PieAnimation(PieChartItem *item);
17 PieAnimation(PieChartItem *item);
18 ~PieAnimation();
18 ~PieAnimation();
19 void updateValues(const PieLayout &newValues);
19 void updateValues(const PieLayout &newValues);
20 void updateValue(QPieSlice *slice, const PieSliceLayout &newValue);
20 void updateValue(QPieSlice *slice, const PieSliceData &newValue);
21 void addSlice(QPieSlice *slice, const PieSliceLayout &endLayout, bool isEmpty);
21 void addSlice(QPieSlice *slice, const PieSliceData &endValue, bool isEmpty);
22 void removeSlice(QPieSlice *slice);
22 void removeSlice(QPieSlice *slice);
23
23
24 public: // from QVariantAnimation
24 public: // from QVariantAnimation
25 void updateCurrentValue(const QVariant &value);
25 void updateCurrentValue(const QVariant &value);
26
26
27 public Q_SLOTS:
27 public Q_SLOTS:
28 void destroySliceAnimationComplete();
28 void destroySliceAnimationComplete();
29
29
30 private:
30 private:
31 PieChartItem *m_item;
31 PieChartItem *m_item;
32 QHash<QPieSlice*, PieSliceAnimation*> m_animations;
32 QHash<QPieSlice*, PieSliceAnimation*> m_animations;
33 };
33 };
34
34
35 QTCOMMERCIALCHART_END_NAMESPACE
35 QTCOMMERCIALCHART_END_NAMESPACE
36
36
37 #endif
37 #endif
@@ -1,107 +1,107
1 #include "piesliceanimation_p.h"
1 #include "piesliceanimation_p.h"
2 #include "piechartitem_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4
4
5 Q_DECLARE_METATYPE(QtCommercialChart::PieSliceLayout)
5 Q_DECLARE_METATYPE(QtCommercialChart::PieSliceData)
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 qreal linearPos(qreal start, qreal end, qreal pos)
9 qreal linearPos(qreal start, qreal end, qreal pos)
10 {
10 {
11 return start + ((end - start) * pos);
11 return start + ((end - start) * pos);
12 }
12 }
13
13
14 QPointF linearPos(QPointF start, QPointF end, qreal pos)
14 QPointF linearPos(QPointF start, QPointF end, qreal pos)
15 {
15 {
16 qreal x = linearPos(start.x(), end.x(), pos);
16 qreal x = linearPos(start.x(), end.x(), pos);
17 qreal y = linearPos(start.y(), end.y(), pos);
17 qreal y = linearPos(start.y(), end.y(), pos);
18 return QPointF(x, y);
18 return QPointF(x, y);
19 }
19 }
20
20
21 QPen linearPos(QPen start, QPen end, qreal pos)
21 QPen linearPos(QPen start, QPen end, qreal pos)
22 {
22 {
23 QColor c;
23 QColor c;
24 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
24 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
25 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
25 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
26 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
26 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
27 end.setColor(c);
27 end.setColor(c);
28 return end;
28 return end;
29 }
29 }
30
30
31 QBrush linearPos(QBrush start, QBrush end, qreal pos)
31 QBrush linearPos(QBrush start, QBrush end, qreal pos)
32 {
32 {
33 QColor c;
33 QColor c;
34 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
34 c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos));
35 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
35 c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos));
36 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
36 c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos));
37 end.setColor(c);
37 end.setColor(c);
38 return end;
38 return end;
39 }
39 }
40
40
41 PieSliceAnimation::PieSliceAnimation(PieChartItem *item, QPieSlice *slice)
41 PieSliceAnimation::PieSliceAnimation(PieChartItem *item, QPieSlice *slice)
42 :QVariantAnimation(item),
42 :QVariantAnimation(item),
43 m_item(item),
43 m_item(item),
44 m_slice(slice)
44 m_slice(slice)
45 {
45 {
46 }
46 }
47
47
48 PieSliceAnimation::~PieSliceAnimation()
48 PieSliceAnimation::~PieSliceAnimation()
49 {
49 {
50 }
50 }
51
51
52 void PieSliceAnimation::setValue(const PieSliceLayout &startValue, const PieSliceLayout &endValue)
52 void PieSliceAnimation::setValue(const PieSliceData &startValue, const PieSliceData &endValue)
53 {
53 {
54 if (state() != QAbstractAnimation::Stopped)
54 if (state() != QAbstractAnimation::Stopped)
55 stop();
55 stop();
56
56
57 m_currentValue = startValue;
57 m_currentValue = startValue;
58
58
59 setKeyValueAt(0.0, qVariantFromValue(startValue));
59 setKeyValueAt(0.0, qVariantFromValue(startValue));
60 setKeyValueAt(1.0, qVariantFromValue(endValue));
60 setKeyValueAt(1.0, qVariantFromValue(endValue));
61 }
61 }
62
62
63 void PieSliceAnimation::updateValue(const PieSliceLayout &endValue)
63 void PieSliceAnimation::updateValue(const PieSliceData &endValue)
64 {
64 {
65 if (state() != QAbstractAnimation::Stopped)
65 if (state() != QAbstractAnimation::Stopped)
66 stop();
66 stop();
67
67
68 setKeyValueAt(0.0, qVariantFromValue(m_currentValue));
68 setKeyValueAt(0.0, qVariantFromValue(m_currentValue));
69 setKeyValueAt(1.0, qVariantFromValue(endValue));
69 setKeyValueAt(1.0, qVariantFromValue(endValue));
70 }
70 }
71
71
72 PieSliceLayout PieSliceAnimation::currentSliceValue()
72 PieSliceData PieSliceAnimation::currentSliceValue()
73 {
73 {
74 // NOTE:
74 // NOTE:
75 // We must use an internal current value because QVariantAnimation::currentValue() is updated
75 // We must use an internal current value because QVariantAnimation::currentValue() is updated
76 // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue()
76 // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue()
77 // will have the end value set from the first call and the second call will interpolate that instead of
77 // will have the end value set from the first call and the second call will interpolate that instead of
78 // the original current value as it was before the first call.
78 // the original current value as it was before the first call.
79 return m_currentValue;
79 return m_currentValue;
80 }
80 }
81
81
82 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
82 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
83 {
83 {
84 PieSliceLayout startValue = qVariantValue<PieSliceLayout>(start);
84 PieSliceData startValue = qVariantValue<PieSliceData>(start);
85 PieSliceLayout endValue = qVariantValue<PieSliceLayout>(end);
85 PieSliceData endValue = qVariantValue<PieSliceData>(end);
86
86
87 PieSliceLayout result;
87 PieSliceData result;
88 result = endValue;
88 result = endValue;
89 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
89 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
90 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
90 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
91 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
91 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
92 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
92 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
93 result.m_pen = linearPos(startValue.m_pen, endValue.m_pen, progress);
93 result.m_pen = linearPos(startValue.m_pen, endValue.m_pen, progress);
94 result.m_brush = linearPos(startValue.m_brush, endValue.m_brush, progress);
94 result.m_brush = linearPos(startValue.m_brush, endValue.m_brush, progress);
95
95
96 return qVariantFromValue(result);
96 return qVariantFromValue(result);
97 }
97 }
98
98
99 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
99 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
100 {
100 {
101 if (state() != QAbstractAnimation::Stopped) { //workaround
101 if (state() != QAbstractAnimation::Stopped) { //workaround
102 m_currentValue = qVariantValue<PieSliceLayout>(value);
102 m_currentValue = qVariantValue<PieSliceData>(value);
103 m_item->setLayout(m_slice, m_currentValue);
103 m_item->setLayout(m_slice, m_currentValue);
104 }
104 }
105 }
105 }
106
106
107 QTCOMMERCIALCHART_END_NAMESPACE
107 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,33 +1,33
1 #ifndef PIESLICEANIMATION_P_H_
1 #ifndef PIESLICEANIMATION_P_H_
2 #define PIESLICEANIMATION_P_H_
2 #define PIESLICEANIMATION_P_H_
3
3
4 #include "piechartitem_p.h"
4 #include "piechartitem_p.h"
5 #include <QVariantAnimation>
5 #include <QVariantAnimation>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 class PieChartItem;
9 class PieChartItem;
10 class QPieSlice;
10 class QPieSlice;
11
11
12 class PieSliceAnimation : public QVariantAnimation
12 class PieSliceAnimation : public QVariantAnimation
13 {
13 {
14 public:
14 public:
15 PieSliceAnimation(PieChartItem *item, QPieSlice *slice);
15 PieSliceAnimation(PieChartItem *item, QPieSlice *slice);
16 ~PieSliceAnimation();
16 ~PieSliceAnimation();
17 void setValue(const PieSliceLayout &startValue, const PieSliceLayout &endValue);
17 void setValue(const PieSliceData &startValue, const PieSliceData &endValue);
18 void updateValue(const PieSliceLayout &endValue);
18 void updateValue(const PieSliceData &endValue);
19 PieSliceLayout currentSliceValue();
19 PieSliceData currentSliceValue();
20
20
21 protected:
21 protected:
22 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const;
22 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const;
23 void updateCurrentValue(const QVariant &value);
23 void updateCurrentValue(const QVariant &value);
24
24
25 private:
25 private:
26 PieChartItem *m_item;
26 PieChartItem *m_item;
27 QPieSlice *m_slice;
27 QPieSlice *m_slice;
28 PieSliceLayout m_currentValue;
28 PieSliceData m_currentValue;
29 };
29 };
30
30
31 QTCOMMERCIALCHART_END_NAMESPACE
31 QTCOMMERCIALCHART_END_NAMESPACE
32
32
33 #endif
33 #endif
@@ -1,198 +1,210
1 #include "piechartitem_p.h"
1 #include "piechartitem_p.h"
2 #include "pieslice_p.h"
2 #include "pieslice_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include "chartdataset_p.h"
6 #include "chartdataset_p.h"
7 #include "chartanimator_p.h"
7 #include "chartanimator_p.h"
8 #include <QDebug>
8 #include <QDebug>
9 #include <QPainter>
9 #include <QPainter>
10 #include <QTimer>
10 #include <QTimer>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent)
14 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent)
15 :ChartItem(parent),
15 :ChartItem(parent),
16 m_series(series),
16 m_series(series),
17 m_presenter(presenter)
17 m_presenter(presenter)
18 {
18 {
19 Q_ASSERT(series);
19 Q_ASSERT(series);
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
20 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
21 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
22 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
24
24
25 QTimer::singleShot(0, this, SLOT(initialize()));
25 QTimer::singleShot(0, this, SLOT(initialize()));
26
26
27 // Note: the following does not affect as long as the item does not have anything to paint
27 // Note: the following does not affect as long as the item does not have anything to paint
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieChartItem::~PieChartItem()
31 PieChartItem::~PieChartItem()
32 {
32 {
33 // slices deleted automatically through QGraphicsItem
33 // slices deleted automatically through QGraphicsItem
34 }
34 }
35
35
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
36 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
37 {
37 {
38 Q_UNUSED(painter)
38 Q_UNUSED(painter)
39 // TODO: paint shadows for all components
39 // TODO: paint shadows for all components
40 // - get paths from items & merge & offset and draw with shadow color?
40 // - get paths from items & merge & offset and draw with shadow color?
41 //painter->setBrush(QBrush(Qt::red));
41 //painter->setBrush(QBrush(Qt::red));
42 //painter->drawRect(m_debugRect);
42 //painter->drawRect(m_debugRect);
43 }
43 }
44
44
45 void PieChartItem::initialize()
45 void PieChartItem::initialize()
46 {
46 {
47 handleSlicesAdded(m_series->m_slices);
47 handleSlicesAdded(m_series->m_slices);
48 }
48 }
49
49
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
50 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
51 {
51 {
52 bool isEmpty = m_slices.isEmpty();
52 bool isEmpty = m_slices.isEmpty();
53
53
54 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
54 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
55
55
56 foreach (QPieSlice *s, slices) {
56 foreach (QPieSlice *s, slices) {
57 PieSlice* slice = new PieSlice(this);
57 PieSlice* slice = new PieSlice(this);
58 m_slices.insert(s, slice);
58 m_slices.insert(s, slice);
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
59 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
60 connect(slice, SIGNAL(clicked()), s, SIGNAL(clicked()));
60 connect(slice, SIGNAL(clicked()), s, SIGNAL(clicked()));
61 connect(slice, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
61 connect(slice, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
62 connect(slice, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
62 connect(slice, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
63
63
64 PieSliceLayout layout = calculateSliceLayout(s);
64 PieSliceData data = sliceData(s);
65
65
66 if (m_animator)
66 if (m_animator)
67 m_animator->addAnimation(this, s, layout, isEmpty);
67 m_animator->addAnimation(this, s, data, isEmpty);
68 else
68 else
69 setLayout(s, layout);
69 setLayout(s, data);
70 }
70 }
71 }
71 }
72
72
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
73 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
74 {
74 {
75 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
75 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
76
76
77 foreach (QPieSlice *s, slices) {
77 foreach (QPieSlice *s, slices) {
78 if (m_animator)
78 if (m_animator)
79 m_animator->removeAnimation(this, s);
79 m_animator->removeAnimation(this, s);
80 else
80 else
81 destroySlice(s);
81 destroySlice(s);
82 }
82 }
83 }
83 }
84
84
85 void PieChartItem::handlePieLayoutChanged()
85 void PieChartItem::handlePieLayoutChanged()
86 {
86 {
87 PieLayout layout = calculateLayout();
87 PieLayout layout = calculateLayout();
88 applyLayout(layout);
88 applyLayout(layout);
89 update();
89 update();
90 }
90 }
91
91
92 void PieChartItem::handleSliceChanged()
92 void PieChartItem::handleSliceChanged()
93 {
93 {
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
95 Q_ASSERT(m_slices.contains(slice));
95 Q_ASSERT(m_slices.contains(slice));
96 PieSliceLayout layout = calculateSliceLayout(slice);
96 PieSliceData data = sliceData(slice);
97 updateLayout(slice, layout);
97 updateLayout(slice, data);
98 update();
98 update();
99 }
99 }
100
100
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
101 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
102 {
102 {
103 // TODO
103 // TODO
104 }
104 }
105
105
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
106 void PieChartItem::handleGeometryChanged(const QRectF& rect)
107 {
107 {
108 prepareGeometryChange();
108 prepareGeometryChange();
109 m_rect = rect;
109 m_rect = rect;
110 handlePieLayoutChanged();
110 handlePieLayoutChanged();
111 }
111 }
112
112
113 void PieChartItem::calculatePieLayout()
113 void PieChartItem::calculatePieLayout()
114 {
114 {
115 // find pie center coordinates
115 // find pie center coordinates
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
116 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
117 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
118
118
119 // find maximum radius for pie
119 // find maximum radius for pie
120 m_pieRadius = m_rect.height() / 2;
120 m_pieRadius = m_rect.height() / 2;
121 if (m_rect.width() < m_rect.height())
121 if (m_rect.width() < m_rect.height())
122 m_pieRadius = m_rect.width() / 2;
122 m_pieRadius = m_rect.width() / 2;
123
123
124 // apply size factor
124 // apply size factor
125 m_pieRadius *= m_series->pieSize();
125 m_pieRadius *= m_series->pieSize();
126 }
126 }
127
127
128 PieSliceLayout PieChartItem::calculateSliceLayout(QPieSlice *slice)
128 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
129 {
129 {
130 PieSliceLayout sliceLayout;
130 PieSliceData sliceData;
131 sliceLayout.m_center = PieSlice::sliceCenter(m_pieCenter, m_pieRadius, slice);
131
132 sliceLayout.m_radius = m_pieRadius;
132 // TODO:
133 sliceLayout.m_startAngle = slice->startAngle();
133 // sliceData = slice->m_data;
134 sliceLayout.m_angleSpan = slice->m_angleSpan;
134
135 sliceLayout.m_pen = slice->m_slicePen;
135 sliceData.m_center = PieSlice::sliceCenter(m_pieCenter, m_pieRadius, slice);
136 sliceLayout.m_brush = slice->m_sliceBrush;
136 sliceData.m_radius = m_pieRadius;
137 return sliceLayout;
137 sliceData.m_startAngle = slice->startAngle();
138 sliceData.m_angleSpan = slice->m_angleSpan;
139
140 sliceData.m_pen = slice->m_slicePen;
141 sliceData.m_brush = slice->m_sliceBrush;
142
143 sliceData.m_isExploded = slice->isExploded();
144 sliceData.m_explodeDistanceFactor = slice->explodeDistanceFactor();
145
146 sliceData.m_labelVisible = slice->isLabelVisible();
147 sliceData.m_labelText = slice->label();
148 sliceData.m_labelFont = slice->labelFont();
149 sliceData.m_labelArmLengthFactor = slice->labelArmLengthFactor();
150 sliceData.m_labelArmPen = slice->labelArmPen();
151
152 return sliceData;
138 }
153 }
139
154
140 PieLayout PieChartItem::calculateLayout()
155 PieLayout PieChartItem::calculateLayout()
141 {
156 {
142 calculatePieLayout();
157 calculatePieLayout();
143 PieLayout layout;
158 PieLayout layout;
144 foreach (QPieSlice* s, m_series->slices()) {
159 foreach (QPieSlice* s, m_series->slices()) {
145 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
160 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
146 layout.insert(s, calculateSliceLayout(s));
161 layout.insert(s, sliceData(s));
147 }
162 }
148 return layout;
163 return layout;
149 }
164 }
150
165
151 void PieChartItem::applyLayout(const PieLayout &layout)
166 void PieChartItem::applyLayout(const PieLayout &layout)
152 {
167 {
153 if (m_animator)
168 if (m_animator)
154 m_animator->updateLayout(this, layout);
169 m_animator->updateLayout(this, layout);
155 else
170 else
156 setLayout(layout);
171 setLayout(layout);
157 }
172 }
158
173
159 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceLayout &layout)
174 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
160 {
175 {
161 if (m_animator)
176 if (m_animator)
162 m_animator->updateLayout(this, slice, layout);
177 m_animator->updateLayout(this, slice, sliceData);
163 else
178 else
164 setLayout(slice, layout);
179 setLayout(slice, sliceData);
165 }
180 }
166
181
167 void PieChartItem::setLayout(const PieLayout &layout)
182 void PieChartItem::setLayout(const PieLayout &layout)
168 {
183 {
169 foreach (QPieSlice *slice, layout.keys()) {
184 foreach (QPieSlice *slice, layout.keys()) {
170 PieSlice *s = m_slices.value(slice);
185 PieSlice *s = m_slices.value(slice);
171 Q_ASSERT(s);
186 Q_ASSERT(s);
172 s->setLayout(layout.value(slice));
187 s->setSliceData(layout.value(slice));
173 s->updateData(slice);
174 s->updateGeometry();
188 s->updateGeometry();
175 s->update();
189 s->update();
176 }
190 }
177 }
191 }
178
192
179 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceLayout &layout)
193 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
180 {
194 {
181 // find slice
195 // find slice
182 PieSlice *s = m_slices.value(slice);
196 PieSlice *s = m_slices.value(slice);
183 Q_ASSERT(s);
197 Q_ASSERT(s);
184 s->setLayout(layout);
198 s->setSliceData(sliceData);
185 if (m_series->m_slices.contains(slice)) // Slice has been deleted if not found. Animations ongoing...
186 s->updateData(slice);
187 s->updateGeometry();
199 s->updateGeometry();
188 s->update();
200 s->update();
189 }
201 }
190
202
191 void PieChartItem::destroySlice(QPieSlice *slice)
203 void PieChartItem::destroySlice(QPieSlice *slice)
192 {
204 {
193 delete m_slices.take(slice);
205 delete m_slices.take(slice);
194 }
206 }
195
207
196 #include "moc_piechartitem_p.cpp"
208 #include "moc_piechartitem_p.cpp"
197
209
198 QTCOMMERCIALCHART_END_NAMESPACE
210 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,59
1 #ifndef PIECHARTITEM_H
1 #ifndef PIECHARTITEM_H
2 #define PIECHARTITEM_H
2 #define PIECHARTITEM_H
3
3
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include "pieslice_p.h"
6 #include "pieslice_p.h"
7
7
8 class QGraphicsItem;
8 class QGraphicsItem;
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 class QPieSlice;
10 class QPieSlice;
11 class ChartPresenter;
11 class ChartPresenter;
12
12
13 typedef QHash<QPieSlice*, PieSliceLayout> PieLayout;
13 typedef QHash<QPieSlice*, PieSliceData> PieLayout;
14
14
15 class PieChartItem : public QObject, public ChartItem
15 class PieChartItem : public QObject, public ChartItem
16 {
16 {
17 Q_OBJECT
17 Q_OBJECT
18
18
19 public:
19 public:
20 // TODO: use a generic data class instead of x and y
20 // TODO: use a generic data class instead of x and y
21 PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent);
21 PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent);
22 ~PieChartItem();
22 ~PieChartItem();
23
23
24 public: // from QGraphicsItem
24 public: // from QGraphicsItem
25 QRectF boundingRect() const { return m_rect; }
25 QRectF boundingRect() const { return m_rect; }
26 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
26 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
27
27
28 public Q_SLOTS:
28 public Q_SLOTS:
29 void initialize();
29 void initialize();
30 void handleSlicesAdded(QList<QPieSlice*> slices);
30 void handleSlicesAdded(QList<QPieSlice*> slices);
31 void handleSlicesRemoved(QList<QPieSlice*> slices);
31 void handleSlicesRemoved(QList<QPieSlice*> slices);
32 void handlePieLayoutChanged();
32 void handlePieLayoutChanged();
33 void handleSliceChanged();
33 void handleSliceChanged();
34 void handleDomainChanged(qreal, qreal, qreal, qreal);
34 void handleDomainChanged(qreal, qreal, qreal, qreal);
35 void handleGeometryChanged(const QRectF& rect);
35 void handleGeometryChanged(const QRectF& rect);
36
36
37 public:
37 public:
38 void calculatePieLayout();
38 void calculatePieLayout();
39 PieSliceLayout calculateSliceLayout(QPieSlice *slice);
39 PieSliceData sliceData(QPieSlice *slice);
40 PieLayout calculateLayout();
40 PieLayout calculateLayout();
41 void applyLayout(const PieLayout &layout);
41 void applyLayout(const PieLayout &layout);
42 void updateLayout(QPieSlice *slice, const PieSliceLayout &layout);
42 void updateLayout(QPieSlice *slice, const PieSliceData &sliceData);
43 void setLayout(const PieLayout &layout);
43 void setLayout(const PieLayout &layout);
44 void setLayout(QPieSlice *slice, const PieSliceLayout &layout);
44 void setLayout(QPieSlice *slice, const PieSliceData &sliceData);
45 void destroySlice(QPieSlice *slice);
45 void destroySlice(QPieSlice *slice);
46
46
47 private:
47 private:
48 friend class PieSlice;
48 friend class PieSlice;
49 QHash<QPieSlice*, PieSlice*> m_slices;
49 QHash<QPieSlice*, PieSlice*> m_slices;
50 QPieSeries *m_series;
50 QPieSeries *m_series;
51 QRectF m_rect;
51 QRectF m_rect;
52 QPointF m_pieCenter;
52 QPointF m_pieCenter;
53 qreal m_pieRadius;
53 qreal m_pieRadius;
54 ChartPresenter *m_presenter;
54 ChartPresenter *m_presenter;
55 };
55 };
56
56
57 QTCOMMERCIALCHART_END_NAMESPACE
57 QTCOMMERCIALCHART_END_NAMESPACE
58
58
59 #endif // PIECHARTITEM_H
59 #endif // PIECHARTITEM_H
@@ -1,202 +1,184
1 #include "pieslice_p.h"
1 #include "pieslice_p.h"
2 #include "piechartitem_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 #define PI 3.14159265 // TODO: is this defined in some header?
14 #define PI 3.14159265 // TODO: is this defined in some header?
15
15
16 QPointF offset(qreal angle, qreal length)
16 QPointF offset(qreal angle, qreal length)
17 {
17 {
18 qreal dx = qSin(angle*(PI/180)) * length;
18 qreal dx = qSin(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
20 return QPointF(dx, -dy);
20 return QPointF(dx, -dy);
21 }
21 }
22
22
23 PieSlice::PieSlice(QGraphicsItem* parent)
23 PieSlice::PieSlice(QGraphicsItem* parent)
24 :QGraphicsObject(parent),
24 :QGraphicsObject(parent)
25 m_isExploded(false),
26 m_explodeDistanceFactor(0),
27 m_labelVisible(false),
28 m_labelArmLengthFactor(0)
29 {
25 {
30 setAcceptHoverEvents(true);
26 setAcceptHoverEvents(true);
31 setAcceptedMouseButtons(Qt::LeftButton);
27 setAcceptedMouseButtons(Qt::LeftButton);
32 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
33 }
29 }
34
30
35 PieSlice::~PieSlice()
31 PieSlice::~PieSlice()
36 {
32 {
37
33
38 }
34 }
39
35
40 QRectF PieSlice::boundingRect() const
36 QRectF PieSlice::boundingRect() const
41 {
37 {
42 return m_boundingRect;
38 return m_boundingRect;
43 }
39 }
44
40
45 QPainterPath PieSlice::shape() const
41 QPainterPath PieSlice::shape() const
46 {
42 {
47 // Don't include the label and label arm.
43 // Don't include the label and label arm.
48 // This is used to detect a mouse clicks. We do not want clicks from label.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
49 return m_slicePath;
45 return m_slicePath;
50 }
46 }
51
47
52 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
53 {
49 {
54 painter->setClipRect(parentItem()->boundingRect());
50 painter->setClipRect(parentItem()->boundingRect());
55
51
56 painter->save();
52 painter->save();
57 painter->setPen(m_layout.m_pen);
53 painter->setPen(m_data.m_pen);
58 painter->setBrush(m_layout.m_brush);
54 painter->setBrush(m_data.m_brush);
59 painter->drawPath(m_slicePath);
55 painter->drawPath(m_slicePath);
60 painter->restore();
56 painter->restore();
61
57
62 if (m_labelVisible) {
58 if (m_data.m_labelVisible) {
63 painter->save();
59 painter->save();
64 painter->setPen(m_labelArmPen);
60 painter->setPen(m_data.m_labelArmPen);
65 painter->drawPath(m_labelArmPath);
61 painter->drawPath(m_labelArmPath);
66 painter->restore();
62 painter->restore();
67
63
68 painter->setFont(m_labelFont);
64 painter->setFont(m_data.m_labelFont);
69 painter->drawText(m_labelTextRect.bottomLeft(), m_labelText);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
70 }
66 }
71 }
67 }
72
68
73 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
69 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
74 {
70 {
75 emit hoverEnter();
71 emit hoverEnter();
76 }
72 }
77
73
78 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
74 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
79 {
75 {
80 emit hoverLeave();
76 emit hoverLeave();
81 }
77 }
82
78
83 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
79 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
84 {
80 {
85 emit clicked();
81 emit clicked();
86 }
82 }
87
83
88 void PieSlice::setLayout(PieSliceLayout layout)
84 void PieSlice::setSliceData(PieSliceData sliceData)
89 {
85 {
90 m_layout = layout;
86 m_data = sliceData;
91 }
87 }
92
88
93 void PieSlice::updateGeometry()
89 void PieSlice::updateGeometry()
94 {
90 {
95 if (m_layout.m_radius <= 0)
91 if (m_data.m_radius <= 0)
96 return;
92 return;
97
93
98 prepareGeometryChange();
94 prepareGeometryChange();
99
95
100 // update slice path
96 // update slice path
101 qreal centerAngle;
97 qreal centerAngle;
102 QPointF armStart;
98 QPointF armStart;
103 m_slicePath = slicePath(m_layout.m_center, m_layout.m_radius, m_layout.m_startAngle, m_layout.m_angleSpan, &centerAngle, &armStart);
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
104
100
105 // update text rect
101 // update text rect
106 m_labelTextRect = labelTextRect(m_labelFont, m_labelText);
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
107
103
108 // update label arm path
104 // update label arm path
109 QPointF labelTextStart;
105 QPointF labelTextStart;
110 m_labelArmPath = labelArmPath(armStart, centerAngle, m_layout.m_radius * m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
111
107
112 // update text position
108 // update text position
113 m_labelTextRect.moveBottomLeft(labelTextStart);
109 m_labelTextRect.moveBottomLeft(labelTextStart);
114
110
115 // update bounding rect
111 // update bounding rect
116 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
117 }
113 }
118
114
119 void PieSlice::updateData(const QPieSlice* sliceData)
120 {
121 // TODO: compare what has changes to avoid unneccesary geometry updates
122
123 m_isExploded = sliceData->isExploded();
124 m_explodeDistanceFactor = sliceData->explodeDistanceFactor();
125
126 m_labelVisible = sliceData->isLabelVisible();
127 m_labelText = sliceData->label();
128 m_labelFont = sliceData->labelFont();
129 m_labelArmLengthFactor = sliceData->labelArmLengthFactor();
130 m_labelArmPen = sliceData->labelArmPen();
131 }
132
133 QPointF PieSlice::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
115 QPointF PieSlice::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
134 {
116 {
135 if (slice->isExploded()) {
117 if (slice->isExploded()) {
136 qreal centerAngle = slice->startAngle() + (slice->m_angleSpan/2);
118 qreal centerAngle = slice->startAngle() + (slice->m_angleSpan/2);
137 qreal len = radius * slice->explodeDistanceFactor();
119 qreal len = radius * slice->explodeDistanceFactor();
138 qreal dx = qSin(centerAngle*(PI/180)) * len;
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
139 qreal dy = -qCos(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
140 point += QPointF(dx, dy);
122 point += QPointF(dx, dy);
141 }
123 }
142 return point;
124 return point;
143 }
125 }
144
126
145 QPainterPath PieSlice::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
127 QPainterPath PieSlice::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
146 {
128 {
147 // calculate center angle
129 // calculate center angle
148 *centerAngle = startAngle + (angleSpan/2);
130 *centerAngle = startAngle + (angleSpan/2);
149
131
150 // calculate slice rectangle
132 // calculate slice rectangle
151 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
152
134
153 // slice path
135 // slice path
154 // TODO: draw the shape so that it might have a hole in the center
136 // TODO: draw the shape so that it might have a hole in the center
155 QPainterPath path;
137 QPainterPath path;
156 path.moveTo(rect.center());
138 path.moveTo(rect.center());
157 path.arcTo(rect, -startAngle + 90, -angleSpan);
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
158 path.closeSubpath();
140 path.closeSubpath();
159
141
160 // calculate label arm start point
142 // calculate label arm start point
161 *armStart = center;
143 *armStart = center;
162 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
163
145
164 return path;
146 return path;
165 }
147 }
166
148
167 QPainterPath PieSlice::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
149 QPainterPath PieSlice::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
168 {
150 {
169 qreal dx = qSin(angle*(PI/180)) * length;
151 qreal dx = qSin(angle*(PI/180)) * length;
170 qreal dy = -qCos(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
171 QPointF parm1 = start + QPointF(dx, dy);
153 QPointF parm1 = start + QPointF(dx, dy);
172
154
173 QPointF parm2 = parm1;
155 QPointF parm2 = parm1;
174 if (angle < 180) { // arm swings the other way on the left side
156 if (angle < 180) { // arm swings the other way on the left side
175 parm2 += QPointF(textWidth, 0);
157 parm2 += QPointF(textWidth, 0);
176 *textStart = parm1;
158 *textStart = parm1;
177 }
159 }
178 else {
160 else {
179 parm2 += QPointF(-textWidth,0);
161 parm2 += QPointF(-textWidth,0);
180 *textStart = parm2;
162 *textStart = parm2;
181 }
163 }
182
164
183 // elevate the text position a bit so that it does not hit the line
165 // elevate the text position a bit so that it does not hit the line
184 *textStart += QPointF(0, -5);
166 *textStart += QPointF(0, -5);
185
167
186 QPainterPath path;
168 QPainterPath path;
187 path.moveTo(start);
169 path.moveTo(start);
188 path.lineTo(parm1);
170 path.lineTo(parm1);
189 path.lineTo(parm2);
171 path.lineTo(parm2);
190
172
191 return path;
173 return path;
192 }
174 }
193
175
194 QRectF PieSlice::labelTextRect(QFont font, QString text)
176 QRectF PieSlice::labelTextRect(QFont font, QString text)
195 {
177 {
196 QFontMetricsF fm(font);
178 QFontMetricsF fm(font);
197 return fm.boundingRect(text);
179 return fm.boundingRect(text);
198 }
180 }
199
181
200 #include "moc_pieslice_p.cpp"
182 #include "moc_pieslice_p.cpp"
201
183
202 QTCOMMERCIALCHART_END_NAMESPACE
184 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,80 +1,79
1 #ifndef PIESLICE_H
1 #ifndef PIESLICE_H
2 #define PIESLICE_H
2 #define PIESLICE_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 #include "qpieseries.h"
6 #include "qpieseries.h"
7 #include <QGraphicsItem>
7 #include <QGraphicsItem>
8 #include <QRectF>
8 #include <QRectF>
9 #include <QColor>
9 #include <QColor>
10 #include <QPen>
10 #include <QPen>
11
11
12 #define PIESLICE_LABEL_GAP 5
12 #define PIESLICE_LABEL_GAP 5
13
13
14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 class PieChartItem;
15 class PieChartItem;
16 class PieSliceLabel;
16 class PieSliceLabel;
17 class QPieSlice;
17 class QPieSlice;
18
18
19 class PieSliceLayout
19 class PieSliceData
20 {
20 {
21 public:
21 public:
22 QPointF m_center;
22 QPointF m_center;
23 qreal m_radius;
23 qreal m_radius;
24 qreal m_startAngle;
24 qreal m_startAngle;
25 qreal m_angleSpan;
25 qreal m_angleSpan;
26
26 QPen m_pen;
27 QPen m_pen;
27 QBrush m_brush;
28 QBrush m_brush;
29
30 bool m_isExploded;
31 qreal m_explodeDistanceFactor;
32
33 bool m_labelVisible;
34 QString m_labelText;
35 QFont m_labelFont;
36 qreal m_labelArmLengthFactor;
37 QPen m_labelArmPen;
28 };
38 };
29
39
30 class PieSlice : public QGraphicsObject
40 class PieSlice : public QGraphicsObject
31 {
41 {
32 Q_OBJECT
42 Q_OBJECT
33
43
34 public:
44 public:
35 PieSlice(QGraphicsItem* parent = 0);
45 PieSlice(QGraphicsItem* parent = 0);
36 ~PieSlice();
46 ~PieSlice();
37
47
38 public: // from QGraphicsItem
48 public: // from QGraphicsItem
39 QRectF boundingRect() const;
49 QRectF boundingRect() const;
40 QPainterPath shape() const;
50 QPainterPath shape() const;
41 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
42 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
52 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
43 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
53 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
44 void mousePressEvent(QGraphicsSceneMouseEvent *event);
54 void mousePressEvent(QGraphicsSceneMouseEvent *event);
45
55
46 Q_SIGNALS:
56 Q_SIGNALS:
47 void clicked();
57 void clicked();
48 void hoverEnter();
58 void hoverEnter();
49 void hoverLeave();
59 void hoverLeave();
50
60
51 public:
61 public:
52 void setLayout(PieSliceLayout layout);
62 void setSliceData(PieSliceData sliceData);
53 void updateGeometry();
63 void updateGeometry();
54 void updateData(const QPieSlice *sliceData);
55 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
64 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
56 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
65 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
57 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
66 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
58 static QRectF labelTextRect(QFont font, QString text);
67 static QRectF labelTextRect(QFont font, QString text);
59
68
60 private:
69 private:
61 PieSliceLayout m_layout;
70 PieSliceData m_data;
62 QRectF m_boundingRect;
71 QRectF m_boundingRect;
63
64 QPainterPath m_slicePath;
72 QPainterPath m_slicePath;
65 bool m_isExploded;
66 qreal m_explodeDistanceFactor;
67 bool m_labelVisible;
68
69 QPainterPath m_labelArmPath;
73 QPainterPath m_labelArmPath;
70 qreal m_labelArmLengthFactor;
71 QPen m_labelArmPen;
72
73 QRectF m_labelTextRect;
74 QRectF m_labelTextRect;
74 QFont m_labelFont;
75 QString m_labelText;
76 };
75 };
77
76
78 QTCOMMERCIALCHART_END_NAMESPACE
77 QTCOMMERCIALCHART_END_NAMESPACE
79
78
80 #endif // PIESLICE_H
79 #endif // PIESLICE_H
General Comments 0
You need to be logged in to leave comments. Login now