##// END OF EJS Templates
Add animations to pie. Works but has some visual issues when adding slices.
Jani Honkonen -
r618:249071e508d1
parent child
Show More
@@ -0,0 +1,94
1 #include "PieAnimation_p.h"
2 #include "piesliceanimation_p.h"
3 #include "piechartitem_p.h"
4 #include <QParallelAnimationGroup>
5 #include <QTimer>
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 PieAnimation::PieAnimation(PieChartItem *item)
10 :ChartAnimation(item),
11 m_item(item)
12 {
13 }
14
15 PieAnimation::~PieAnimation()
16 {
17 }
18
19 void PieAnimation::setValues(QVector<PieSliceLayout>& newValues)
20 {
21 PieSliceAnimation *animation = 0;
22
23 foreach (PieSliceLayout endLayout, newValues) {
24 animation = m_animations.value(endLayout.m_data);
25 if (animation) {
26 // existing slice
27 animation->stop();
28 animation->updateValue(endLayout);
29 } else {
30 // new slice
31 animation = new PieSliceAnimation(m_item);
32 m_animations.insert(endLayout.m_data, animation);
33 PieSliceLayout startLayout = endLayout;
34 startLayout.m_radius = 0;
35 //startLayout.m_startAngle = 0;
36 //startLayout.m_angleSpan = 0;
37 animation->setValue(startLayout, endLayout);
38 }
39 animation->setDuration(1000);
40 animation->setEasingCurve(QEasingCurve::OutQuart);
41 QTimer::singleShot(0, animation, SLOT(start())); // TODO: use sequential animation?
42 }
43
44 foreach (QPieSlice *s, m_animations.keys()) {
45 bool isFound = false;
46 foreach (PieSliceLayout layout, newValues) {
47 if (s == layout.m_data)
48 isFound = true;
49 }
50 if (!isFound) {
51 // slice has been deleted
52 animation = m_animations.value(s);
53 animation->stop();
54 PieSliceLayout endLayout = m_animations.value(s)->currentSliceValue();
55 endLayout.m_radius = 0;
56 // TODO: find the actual angle where this slice disappears
57 endLayout.m_startAngle = endLayout.m_startAngle + endLayout.m_angleSpan;
58 endLayout.m_angleSpan = 0;
59 animation->updateValue(endLayout);
60 animation->setDuration(1000);
61 animation->setEasingCurve(QEasingCurve::OutQuart);
62 connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete()));
63 QTimer::singleShot(0, animation, SLOT(start()));
64 }
65 }
66 }
67
68 void PieAnimation::updateValue(PieSliceLayout& endLayout)
69 {
70 PieSliceAnimation *animation = m_animations.value(endLayout.m_data);
71 Q_ASSERT(animation);
72 animation->stop();
73 animation->updateValue(endLayout);
74 animation->setDuration(1000);
75 animation->setEasingCurve(QEasingCurve::OutQuart);
76 QTimer::singleShot(0, animation, SLOT(start()));
77 }
78
79 void PieAnimation::updateCurrentValue(const QVariant &)
80 {
81 // nothing to do...
82 }
83
84 void PieAnimation::destroySliceAnimationComplete()
85 {
86 PieSliceAnimation *animation = static_cast<PieSliceAnimation*>(sender());
87 QPieSlice *slice = m_animations.key(animation);
88 m_item->destroySlice(slice);
89 delete m_animations.take(slice);
90 }
91
92 #include "moc_pieanimation_p.cpp"
93
94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,35
1 #ifndef PIEANIMATION_P_H_
2 #define PIEANIMATION_P_H_
3
4 #include "chartanimation_p.h"
5 #include "piechartitem_p.h"
6 #include "piesliceanimation_p.h"
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 class PieChartItem;
11
12 class PieAnimation : public ChartAnimation
13 {
14 Q_OBJECT
15
16 public:
17 PieAnimation(PieChartItem *item);
18 ~PieAnimation();
19 void setValues(QVector<PieSliceLayout>& newValues);
20 void updateValue(PieSliceLayout& newValue);
21
22 public: // from QVariantAnimation
23 void updateCurrentValue(const QVariant &value);
24
25 public Q_SLOTS:
26 void destroySliceAnimationComplete();
27
28 private:
29 PieChartItem *m_item;
30 QHash<QPieSlice*, PieSliceAnimation*> m_animations;
31 };
32
33 QTCOMMERCIALCHART_END_NAMESPACE
34
35 #endif
@@ -0,0 +1,77
1 #include "PieSliceAnimation_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieslice.h"
4
5 Q_DECLARE_METATYPE(QtCommercialChart::PieSliceLayout)
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 qreal linearPos(qreal start, qreal end, qreal pos)
10 {
11 return start + ((end - start) * pos);
12 }
13
14 QPointF linearPos(QPointF start, QPointF end, qreal pos)
15 {
16 qreal x = linearPos(start.x(), end.x(), pos);
17 qreal y = linearPos(start.y(), end.y(), pos);
18 return QPointF(x, y);
19 }
20
21 PieSliceAnimation::PieSliceAnimation(PieChartItem *item)
22 :QVariantAnimation(item),
23 m_item(item)
24 {
25 }
26
27 PieSliceAnimation::~PieSliceAnimation()
28 {
29 }
30
31 void PieSliceAnimation::setValue(PieSliceLayout& startValue, PieSliceLayout& endValue)
32 {
33 if (state() != QAbstractAnimation::Stopped)
34 stop();
35
36 setKeyValueAt(0.0, qVariantFromValue(startValue));
37 setKeyValueAt(1.0, qVariantFromValue(endValue));
38 }
39
40 void PieSliceAnimation::updateValue(PieSliceLayout& endValue)
41 {
42 if (state() != QAbstractAnimation::Stopped)
43 stop();
44
45 //qDebug() << "PieSliceAnimation::updateValue()" << endValue.m_data->label() << currentSliceValue().m_startAngle << endValue.m_startAngle;
46
47 setKeyValueAt(0.0, qVariantFromValue(currentSliceValue()));
48 setKeyValueAt(1.0, qVariantFromValue(endValue));
49 }
50
51 PieSliceLayout PieSliceAnimation::currentSliceValue()
52 {
53 return qVariantValue<PieSliceLayout>(currentValue());
54 }
55
56 QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
57 {
58 PieSliceLayout startValue = qVariantValue<PieSliceLayout>(start);
59 PieSliceLayout endValue = qVariantValue<PieSliceLayout>(end);
60
61 PieSliceLayout result;
62 result = endValue;
63 result.m_center = linearPos(startValue.m_center, endValue.m_center, progress);
64 result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress);
65 result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress);
66 result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress);
67
68 return qVariantFromValue(result);
69 }
70
71 void PieSliceAnimation::updateCurrentValue(const QVariant &value)
72 {
73 if (state() != QAbstractAnimation::Stopped) //workaround
74 m_item->setLayout(qVariantValue<PieSliceLayout>(value));
75 }
76
77 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,30
1 #ifndef PIESLICEANIMATION_P_H_
2 #define PIESLICEANIMATION_P_H_
3
4 #include "piechartitem_p.h"
5 #include <QVariantAnimation>
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 class PieChartItem;
10
11 class PieSliceAnimation : public QVariantAnimation
12 {
13 public:
14 PieSliceAnimation(PieChartItem *item);
15 ~PieSliceAnimation();
16 void setValue(PieSliceLayout& startValue, PieSliceLayout& endValue);
17 void updateValue(PieSliceLayout& endValue);
18 PieSliceLayout currentSliceValue();
19
20 protected:
21 QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const;
22 void updateCurrentValue(const QVariant &value);
23
24 private:
25 PieChartItem *m_item;
26 };
27
28 QTCOMMERCIALCHART_END_NAMESPACE
29
30 #endif
@@ -287,6 +287,7 public:
287 287 // create chart
288 288 m_chartView = new QChartView();
289 289 m_chartView->setChartTitle("Piechart customization");
290 m_chartView->setAnimationOptions(QChart::AllAnimations);
290 291
291 292 // create series
292 293 m_series = new QPieSeries();
@@ -349,12 +350,15 public:
349 350 m_endAngle->setValue(m_series->pieEndAngle());
350 351 m_endAngle->setSingleStep(1);
351 352
353 QPushButton *addSlice = new QPushButton("Add slice");
354
352 355 QFormLayout* seriesSettingsLayout = new QFormLayout();
353 356 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
354 357 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
355 358 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
356 359 seriesSettingsLayout->addRow("Start angle", m_startAngle);
357 360 seriesSettingsLayout->addRow("End angle", m_endAngle);
361 seriesSettingsLayout->addRow(addSlice);
358 362 QGroupBox* seriesSettings = new QGroupBox("Series");
359 363 seriesSettings->setLayout(seriesSettingsLayout);
360 364
@@ -363,6 +367,7 public:
363 367 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
364 368 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
365 369 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
370 connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice()));
366 371
367 372 // slice settings
368 373 m_sliceName = new QLabel("<click a slice>");
@@ -381,6 +386,7 public:
381 386 m_font = new QPushButton();
382 387 m_labelArmPen = new QPushButton();
383 388 m_labelArmPenTool = new PenTool("Label arm pen", this);
389 QPushButton *removeSlice = new QPushButton("Remove slice");
384 390
385 391 QFormLayout* sliceSettingsLayout = new QFormLayout();
386 392 sliceSettingsLayout->addRow("Selected", m_sliceName);
@@ -393,6 +399,7 public:
393 399 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
394 400 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
395 401 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
402 sliceSettingsLayout->addRow(removeSlice);
396 403 QGroupBox* sliceSettings = new QGroupBox("Slice");
397 404 sliceSettings->setLayout(sliceSettingsLayout);
398 405
@@ -409,6 +416,7 public:
409 416 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
410 417 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
411 418 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
419 connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice()));
412 420
413 421 // create main layout
414 422 QVBoxLayout *settingsLayout = new QVBoxLayout();
@@ -513,6 +521,20 public Q_SLOTS:
513 521 m_font->setText(dialog.currentFont().toString());
514 522 }
515 523
524 void addSlice()
525 {
526 *m_series << new CustomSlice(10.0, "Slice " + QString::number(m_series->count()));
527 }
528
529 void removeSlice()
530 {
531 if (!m_slice)
532 return;
533
534 m_series->remove(m_slice);
535 m_slice = 0;
536 }
537
516 538 private:
517 539 QComboBox *m_themeComboBox;
518 540 QCheckBox *m_aaCheckBox;
@@ -4,10 +4,14 DEPENDPATH += $$PWD
4 4 SOURCES += \
5 5 $$PWD/axisanimation.cpp \
6 6 $$PWD/chartanimator.cpp \
7 $$PWD/xyanimation.cpp
7 $$PWD/xyanimation.cpp \
8 $$PWD/pieanimation.cpp \
9 $$PWD/piesliceanimation.cpp
8 10
9 11 PRIVATE_HEADERS += \
10 12 $$PWD/axisanimation_p.h \
11 13 $$PWD/chartanimator_p.h \
12 14 $$PWD/chartanimation_p.h \
13 $$PWD/xyanimation_p.h No newline at end of file
15 $$PWD/xyanimation_p.h \
16 $$PWD/pieanimation_p.h \
17 $$PWD/piesliceanimation_p.h
@@ -2,6 +2,7
2 2 #include "axisanimation_p.h"
3 3 #include "xyanimation_p.h"
4 4 #include "xychartitem_p.h"
5 #include "pieanimation_p.h"
5 6 #include "areachartitem_p.h"
6 7 #include <QTimer>
7 8
@@ -44,6 +45,18 void ChartAnimator::addAnimation(XYChartItem* item)
44 45 item->setAnimator(this);
45 46 }
46 47
48 void ChartAnimator::addAnimation(PieChartItem* item)
49 {
50 ChartAnimation* animation = m_animations.value(item);
51
52 if(!animation) {
53 animation = new PieAnimation(item);
54 m_animations.insert(item,animation);
55 }
56
57 item->setAnimator(this);
58 }
59
47 60 void ChartAnimator::removeAnimation(ChartItem* item)
48 61 {
49 62 item->setAnimator(0);
@@ -171,6 +184,20 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& newPoints)
171 184 QTimer::singleShot(0,animation,SLOT(start()));
172 185 }
173 186
187 void ChartAnimator::applyLayout(PieChartItem* item, QVector<PieSliceLayout> &layout)
188 {
189 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
190 Q_ASSERT(animation);
191 animation->setValues(layout);
192 }
193
194 void ChartAnimator::updateLayout(PieChartItem* item, PieSliceLayout &layout)
195 {
196 PieAnimation* animation = static_cast<PieAnimation*>(m_animations.value(item));
197 Q_ASSERT(animation);
198 animation->updateValue(layout);
199 }
200
174 201 void ChartAnimator::setState(State state,const QPointF& point)
175 202 {
176 203 m_state=state;
@@ -2,6 +2,7
2 2 #define CHARTANIMATOR_P_H_
3 3 #include "qchartglobal.h"
4 4 #include "chartanimation_p.h"
5 #include "piechartitem_p.h"
5 6 #include <QPointF>
6 7
7 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -22,6 +23,7 public:
22 23
23 24 void addAnimation(AxisItem* item);
24 25 void addAnimation(XYChartItem* item);
26 void addAnimation(PieChartItem* item);
25 27
26 28 void removeAnimation(ChartItem* item);
27 29
@@ -30,6 +32,9 public:
30 32 void updateLayout(XYChartItem* item, QVector<QPointF>& layout);
31 33 void applyLayout(AxisItem* item, QVector<qreal>& layout);
32 34
35 void applyLayout(PieChartItem* item, QVector<PieSliceLayout> &layout);
36 void updateLayout(PieChartItem* item, PieSliceLayout &layout);
37
33 38 void setState(State state,const QPointF& point = QPointF());
34 39
35 40 private:
@@ -224,7 +224,7 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
224 224 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
225 225 PieChartItem* pie = new PieChartItem(m_chart, pieSeries);
226 226 if(m_options.testFlag(QChart::SeriesAnimations)) {
227 // m_animator->addAnimation(pie);
227 m_animator->addAnimation(pie);
228 228 }
229 229 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series));
230 230 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
@@ -3,6 +3,7
3 3 #include "qpieslice.h"
4 4 #include "qpieseries.h"
5 5 #include "chartpresenter_p.h"
6 #include "chartanimator_p.h"
6 7 #include <QDebug>
7 8 #include <QPainter>
8 9
@@ -36,16 +37,24 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QW
36 37
37 38 void PieChartItem::handleSeriesChanged()
38 39 {
39 QVector<PieSliceLayout> sliceLayout = calculateLayout();
40 applyLayout(sliceLayout);
40 QVector<PieSliceLayout> layout = calculateLayout();
41 applyLayout(layout);
41 42 update();
42 43 }
43 44
44 45 void PieChartItem::handleSliceChanged()
45 46 {
46 // TODO: optimize don't need to handle all slices
47 QVector<PieSliceLayout> sliceLayout = calculateLayout();
48 applyLayout(sliceLayout);
47 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
48 Q_ASSERT(m_slices.contains(slice));
49
50 //qDebug() << "PieChartItem::handleSliceChanged" << slice->label();
51
52 // TODO: Optimize. No need to calculate everything.
53 QVector<PieSliceLayout> layout = calculateLayout();
54 foreach (PieSliceLayout sl, layout) {
55 if (sl.m_data == slice)
56 updateLayout(sl);
57 }
49 58 update();
50 59 }
51 60
@@ -93,15 +102,23 QVector<PieSliceLayout> PieChartItem::calculateLayout()
93 102 return layout;
94 103 }
95 104
96 void PieChartItem::applyLayout(const QVector<PieSliceLayout> &layout)
105 void PieChartItem::applyLayout(QVector<PieSliceLayout> &layout)
97 106 {
98 //if(m_animator)
99 // m_animator->applyLayout(this,points);
100 //else
101 setLayout(layout);
107 if (m_animator)
108 m_animator->applyLayout(this, layout);
109 else
110 setLayout(layout);
102 111 }
103 112
104 void PieChartItem::setLayout(const QVector<PieSliceLayout> &layout)
113 void PieChartItem::updateLayout(PieSliceLayout &layout)
114 {
115 if (m_animator)
116 m_animator->updateLayout(this, layout);
117 else
118 setLayout(layout);
119 }
120
121 void PieChartItem::setLayout(QVector<PieSliceLayout> &layout)
105 122 {
106 123 foreach (PieSliceLayout l, layout) {
107 124
@@ -135,8 +152,32 void PieChartItem::setLayout(const QVector<PieSliceLayout> &layout)
135 152 }
136 153
137 154 if (!found)
138 delete m_slices.take(s);
155 destroySlice(s);
156 }
157 }
158
159 void PieChartItem::setLayout(PieSliceLayout &layout)
160 {
161 // find slice
162 PieSlice *slice = m_slices.value(layout.m_data);
163 if (!slice) {
164 slice = new PieSlice(this);
165 m_slices.insert(layout.m_data, slice);
166 connect(layout.m_data, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
167 connect(slice, SIGNAL(clicked()), layout.m_data, SIGNAL(clicked()));
168 connect(slice, SIGNAL(hoverEnter()), layout.m_data, SIGNAL(hoverEnter()));
169 connect(slice, SIGNAL(hoverLeave()), layout.m_data, SIGNAL(hoverLeave()));
139 170 }
171 slice->setLayout(layout);
172 if (m_series->m_slices.contains(layout.m_data)) // Slice has been deleted if not found. Animations ongoing...
173 slice->updateData(layout.m_data);
174 slice->updateGeometry();
175 slice->update();
176 }
177
178 void PieChartItem::destroySlice(QPieSlice *slice)
179 {
180 delete m_slices.take(slice);
140 181 }
141 182
142 183 #include "moc_piechartitem_p.cpp"
@@ -28,10 +28,13 public Q_SLOTS:
28 28 void handleDomainChanged(qreal, qreal, qreal, qreal);
29 29 void handleGeometryChanged(const QRectF& rect);
30 30
31 private:
31 public:
32 32 QVector<PieSliceLayout> calculateLayout();
33 void applyLayout(const QVector<PieSliceLayout> &layout);
34 void setLayout(const QVector<PieSliceLayout> &layout);
33 void applyLayout(QVector<PieSliceLayout> &layout);
34 void updateLayout(PieSliceLayout &layout);
35 void setLayout(QVector<PieSliceLayout> &layout);
36 void setLayout(PieSliceLayout &layout);
37 void destroySlice(QPieSlice *slice);
35 38
36 39 private:
37 40 friend class PieSlice;
@@ -22,8 +22,6 QPointF offset(qreal angle, qreal length)
22 22
23 23 PieSlice::PieSlice(QGraphicsItem* parent)
24 24 :QGraphicsObject(parent),
25 m_startAngle(0),
26 m_angleSpan(0),
27 25 m_isExploded(false),
28 26 m_explodeDistanceFactor(0),
29 27 m_labelVisible(false),
@@ -41,7 +39,7 PieSlice::~PieSlice()
41 39
42 40 QRectF PieSlice::boundingRect() const
43 41 {
44 return m_slicePath.boundingRect();
42 return m_slicePath.boundingRect().united(m_labelTextRect);
45 43 }
46 44
47 45 QPainterPath PieSlice::shape() const
@@ -90,7 +88,6 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
90 88 void PieSlice::setLayout(PieSliceLayout layout)
91 89 {
92 90 m_layout = layout;
93 updateData(layout.m_data);
94 91 }
95 92
96 93 void PieSlice::updateGeometry()
@@ -103,7 +100,7 void PieSlice::updateGeometry()
103 100 // update slice path
104 101 qreal centerAngle;
105 102 QPointF armStart;
106 m_slicePath = slicePath(m_layout.m_center, m_layout.m_radius, m_startAngle, m_angleSpan, &centerAngle, &armStart);
103 m_slicePath = slicePath(m_layout.m_center, m_layout.m_radius, m_layout.m_startAngle, m_layout.m_angleSpan, &centerAngle, &armStart);
107 104
108 105 // update text rect
109 106 m_labelTextRect = labelTextRect(m_labelFont, m_labelText);
@@ -122,8 +119,6 void PieSlice::updateData(const QPieSlice* sliceData)
122 119 {
123 120 // TODO: compare what has changes to avoid unneccesary geometry updates
124 121
125 m_startAngle = sliceData->startAngle();
126 m_angleSpan = sliceData->m_angleSpan;
127 122 m_isExploded = sliceData->isExploded();
128 123 m_explodeDistanceFactor = sliceData->explodeDistanceFactor();
129 124 m_slicePen = sliceData->slicePen();
@@ -19,7 +19,7 class QPieSlice;
19 19 class PieSliceLayout
20 20 {
21 21 public:
22 QPieSlice* m_data;
22 QPieSlice* m_data; // TODO: get rid of this
23 23 QPointF m_center;
24 24 qreal m_radius;
25 25 qreal m_startAngle;
@@ -60,8 +60,6 private:
60 60 PieSliceLayout m_layout;
61 61
62 62 QPainterPath m_slicePath;
63 qreal m_startAngle;
64 qreal m_angleSpan;
65 63 bool m_isExploded;
66 64 qreal m_explodeDistanceFactor;
67 65 bool m_labelVisible;
@@ -511,6 +511,8 void QPieSeries::updateDerivativeData()
511 511 foreach (QPieSlice* s, m_slices)
512 512 m_total += s->value();
513 513
514 // TODO: emit totalChanged?
515
514 516 // we must have some values
515 517 if (m_total == 0) {
516 518 qDebug() << "QPieSeries::updateDerivativeData() total == 0";
@@ -520,31 +522,35 void QPieSeries::updateDerivativeData()
520 522 // update slice attributes
521 523 qreal sliceAngle = m_pieStartAngle;
522 524 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
525 QVector<QPieSlice*> changed;
523 526 foreach (QPieSlice* s, m_slices) {
524 527
525 bool changed = false;
528 bool isChanged = false;
526 529
527 530 qreal percentage = s->value() / m_total;
528 531 if (s->m_percentage != percentage) {
529 532 s->m_percentage = percentage;
530 changed = true;
533 isChanged = true;
531 534 }
532 535
533 536 qreal sliceSpan = pieSpan * percentage;
534 537 if (s->m_angleSpan != sliceSpan) {
535 538 s->m_angleSpan = sliceSpan;
536 changed = true;
539 isChanged = true;
537 540 }
538 541
539 542 if (s->m_startAngle != sliceAngle) {
540 543 s->m_startAngle = sliceAngle;
541 changed = true;
544 isChanged = true;
542 545 }
543 546 sliceAngle += sliceSpan;
544 547
545 if (changed)
546 emit s->changed();
548 if (isChanged)
549 changed << s;
547 550 }
551
552 foreach (QPieSlice* s, changed)
553 emit s->changed();
548 554 }
549 555
550 556 bool QPieSeries::setModel(QAbstractItemModel* model)
@@ -124,6 +124,7 private:
124 124 // TODO: use PIML
125 125 friend class PieChartItem;
126 126 friend class PieSlice;
127 friend class QPieSlice;
127 128
128 129 QList<QPieSlice*> m_slices;
129 130 qreal m_pieRelativeHorPos;
@@ -1,4 +1,5
1 1 #include "qpieslice.h"
2 #include "qpieseries.h"
2 3
3 4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 5
@@ -266,7 +267,12 void QPieSlice::setValue(qreal value)
266 267 {
267 268 if (m_value != value) {
268 269 m_value = value;
269 emit changed();
270
271 QPieSeries *series = qobject_cast<QPieSeries*>(parent());
272 if (series)
273 series->updateDerivativeData(); // will emit changed()
274 else
275 emit changed();
270 276 }
271 277 }
272 278
@@ -8,6 +8,7
8 8 #include <QFont>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 class QPieSeries;
11 12
12 13 class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject
13 14 {
@@ -29,8 +30,6 public:
29 30 bool isLabelVisible() const;
30 31 void setExploded(bool exploded);
31 32 bool isExploded() const;
32 void setExplodeDistanceFactor(qreal factor);
33 qreal explodeDistanceFactor() const;
34 33
35 34 // generated data
36 35 qreal percentage() const;
@@ -48,10 +47,8 public:
48 47 QFont labelFont() const;
49 48 void setLabelArmLengthFactor(qreal factor);
50 49 qreal labelArmLengthFactor() const;
51
52 // TODO: label position in general
53 // setLabelFlags(inside|outside|labelArmOn|labelArmOff|???)
54 // setLabelOrientation(horizontal|vertical|same as slice center angle|???)
50 void setExplodeDistanceFactor(qreal factor);
51 qreal explodeDistanceFactor() const;
55 52
56 53 Q_SIGNALS:
57 54 void clicked();
General Comments 0
You need to be logged in to leave comments. Login now