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