From 249071e508d1758a0968a7d89a3d264c75cd104d 2012-03-16 07:53:49 From: Jani Honkonen Date: 2012-03-16 07:53:49 Subject: [PATCH] Add animations to pie. Works but has some visual issues when adding slices. --- diff --git a/demos/piechartcustomization/main.cpp b/demos/piechartcustomization/main.cpp index 973fc30..13d9b17 100644 --- a/demos/piechartcustomization/main.cpp +++ b/demos/piechartcustomization/main.cpp @@ -287,6 +287,7 @@ public: // create chart m_chartView = new QChartView(); m_chartView->setChartTitle("Piechart customization"); + m_chartView->setAnimationOptions(QChart::AllAnimations); // create series m_series = new QPieSeries(); @@ -349,12 +350,15 @@ public: m_endAngle->setValue(m_series->pieEndAngle()); m_endAngle->setSingleStep(1); + QPushButton *addSlice = new QPushButton("Add slice"); + QFormLayout* seriesSettingsLayout = new QFormLayout(); seriesSettingsLayout->addRow("Horizontal position", m_hPosition); seriesSettingsLayout->addRow("Vertical position", m_vPosition); seriesSettingsLayout->addRow("Size factor", m_sizeFactor); seriesSettingsLayout->addRow("Start angle", m_startAngle); seriesSettingsLayout->addRow("End angle", m_endAngle); + seriesSettingsLayout->addRow(addSlice); QGroupBox* seriesSettings = new QGroupBox("Series"); seriesSettings->setLayout(seriesSettingsLayout); @@ -363,6 +367,7 @@ public: connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings())); connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings())); connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings())); + connect(addSlice, SIGNAL(clicked()), this, SLOT(addSlice())); // slice settings m_sliceName = new QLabel(""); @@ -381,6 +386,7 @@ public: m_font = new QPushButton(); m_labelArmPen = new QPushButton(); m_labelArmPenTool = new PenTool("Label arm pen", this); + QPushButton *removeSlice = new QPushButton("Remove slice"); QFormLayout* sliceSettingsLayout = new QFormLayout(); sliceSettingsLayout->addRow("Selected", m_sliceName); @@ -393,6 +399,7 @@ public: sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor); sliceSettingsLayout->addRow("Exploded", m_sliceExploded); sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor); + sliceSettingsLayout->addRow(removeSlice); QGroupBox* sliceSettings = new QGroupBox("Slice"); sliceSettings->setLayout(sliceSettingsLayout); @@ -409,6 +416,7 @@ public: connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings())); connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings())); connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings())); + connect(removeSlice, SIGNAL(clicked()), this, SLOT(removeSlice())); // create main layout QVBoxLayout *settingsLayout = new QVBoxLayout(); @@ -513,6 +521,20 @@ public Q_SLOTS: m_font->setText(dialog.currentFont().toString()); } + void addSlice() + { + *m_series << new CustomSlice(10.0, "Slice " + QString::number(m_series->count())); + } + + void removeSlice() + { + if (!m_slice) + return; + + m_series->remove(m_slice); + m_slice = 0; + } + private: QComboBox *m_themeComboBox; QCheckBox *m_aaCheckBox; diff --git a/src/animations/animations.pri b/src/animations/animations.pri index 124acee..5b0d655 100644 --- a/src/animations/animations.pri +++ b/src/animations/animations.pri @@ -4,10 +4,14 @@ DEPENDPATH += $$PWD SOURCES += \ $$PWD/axisanimation.cpp \ $$PWD/chartanimator.cpp \ - $$PWD/xyanimation.cpp + $$PWD/xyanimation.cpp \ + $$PWD/pieanimation.cpp \ + $$PWD/piesliceanimation.cpp PRIVATE_HEADERS += \ $$PWD/axisanimation_p.h \ $$PWD/chartanimator_p.h \ $$PWD/chartanimation_p.h \ - $$PWD/xyanimation_p.h \ No newline at end of file + $$PWD/xyanimation_p.h \ + $$PWD/pieanimation_p.h \ + $$PWD/piesliceanimation_p.h diff --git a/src/animations/chartanimator.cpp b/src/animations/chartanimator.cpp index aa176c8..7ef3645 100644 --- a/src/animations/chartanimator.cpp +++ b/src/animations/chartanimator.cpp @@ -2,6 +2,7 @@ #include "axisanimation_p.h" #include "xyanimation_p.h" #include "xychartitem_p.h" +#include "pieanimation_p.h" #include "areachartitem_p.h" #include @@ -44,6 +45,18 @@ void ChartAnimator::addAnimation(XYChartItem* item) item->setAnimator(this); } +void ChartAnimator::addAnimation(PieChartItem* item) +{ + ChartAnimation* animation = m_animations.value(item); + + if(!animation) { + animation = new PieAnimation(item); + m_animations.insert(item,animation); + } + + item->setAnimator(this); +} + void ChartAnimator::removeAnimation(ChartItem* item) { item->setAnimator(0); @@ -171,6 +184,20 @@ void ChartAnimator::updateLayout(XYChartItem* item, QVector& newPoints) QTimer::singleShot(0,animation,SLOT(start())); } +void ChartAnimator::applyLayout(PieChartItem* item, QVector &layout) +{ + PieAnimation* animation = static_cast(m_animations.value(item)); + Q_ASSERT(animation); + animation->setValues(layout); +} + +void ChartAnimator::updateLayout(PieChartItem* item, PieSliceLayout &layout) +{ + PieAnimation* animation = static_cast(m_animations.value(item)); + Q_ASSERT(animation); + animation->updateValue(layout); +} + void ChartAnimator::setState(State state,const QPointF& point) { m_state=state; diff --git a/src/animations/chartanimator_p.h b/src/animations/chartanimator_p.h index dc430a7..cb28d53 100644 --- a/src/animations/chartanimator_p.h +++ b/src/animations/chartanimator_p.h @@ -2,6 +2,7 @@ #define CHARTANIMATOR_P_H_ #include "qchartglobal.h" #include "chartanimation_p.h" +#include "piechartitem_p.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -22,6 +23,7 @@ public: void addAnimation(AxisItem* item); void addAnimation(XYChartItem* item); + void addAnimation(PieChartItem* item); void removeAnimation(ChartItem* item); @@ -30,6 +32,9 @@ public: void updateLayout(XYChartItem* item, QVector& layout); void applyLayout(AxisItem* item, QVector& layout); + void applyLayout(PieChartItem* item, QVector &layout); + void updateLayout(PieChartItem* item, PieSliceLayout &layout); + void setState(State state,const QPointF& point = QPointF()); private: diff --git a/src/animations/pieanimation.cpp b/src/animations/pieanimation.cpp new file mode 100644 index 0000000..367c782 --- /dev/null +++ b/src/animations/pieanimation.cpp @@ -0,0 +1,94 @@ +#include "PieAnimation_p.h" +#include "piesliceanimation_p.h" +#include "piechartitem_p.h" +#include +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +PieAnimation::PieAnimation(PieChartItem *item) + :ChartAnimation(item), + m_item(item) +{ +} + +PieAnimation::~PieAnimation() +{ +} + +void PieAnimation::setValues(QVector& newValues) +{ + PieSliceAnimation *animation = 0; + + foreach (PieSliceLayout endLayout, newValues) { + animation = m_animations.value(endLayout.m_data); + if (animation) { + // existing slice + animation->stop(); + animation->updateValue(endLayout); + } else { + // new slice + animation = new PieSliceAnimation(m_item); + m_animations.insert(endLayout.m_data, animation); + PieSliceLayout startLayout = endLayout; + startLayout.m_radius = 0; + //startLayout.m_startAngle = 0; + //startLayout.m_angleSpan = 0; + animation->setValue(startLayout, endLayout); + } + animation->setDuration(1000); + animation->setEasingCurve(QEasingCurve::OutQuart); + QTimer::singleShot(0, animation, SLOT(start())); // TODO: use sequential animation? + } + + foreach (QPieSlice *s, m_animations.keys()) { + bool isFound = false; + foreach (PieSliceLayout layout, newValues) { + if (s == layout.m_data) + isFound = true; + } + if (!isFound) { + // slice has been deleted + animation = m_animations.value(s); + animation->stop(); + PieSliceLayout endLayout = m_animations.value(s)->currentSliceValue(); + endLayout.m_radius = 0; + // TODO: find the actual angle where this slice disappears + endLayout.m_startAngle = endLayout.m_startAngle + endLayout.m_angleSpan; + endLayout.m_angleSpan = 0; + animation->updateValue(endLayout); + animation->setDuration(1000); + animation->setEasingCurve(QEasingCurve::OutQuart); + connect(animation, SIGNAL(finished()), this, SLOT(destroySliceAnimationComplete())); + QTimer::singleShot(0, animation, SLOT(start())); + } + } +} + +void PieAnimation::updateValue(PieSliceLayout& endLayout) +{ + PieSliceAnimation *animation = m_animations.value(endLayout.m_data); + Q_ASSERT(animation); + animation->stop(); + animation->updateValue(endLayout); + animation->setDuration(1000); + animation->setEasingCurve(QEasingCurve::OutQuart); + QTimer::singleShot(0, animation, SLOT(start())); +} + +void PieAnimation::updateCurrentValue(const QVariant &) +{ + // nothing to do... +} + +void PieAnimation::destroySliceAnimationComplete() +{ + PieSliceAnimation *animation = static_cast(sender()); + QPieSlice *slice = m_animations.key(animation); + m_item->destroySlice(slice); + delete m_animations.take(slice); +} + +#include "moc_pieanimation_p.cpp" + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/animations/pieanimation_p.h b/src/animations/pieanimation_p.h new file mode 100644 index 0000000..4e70469 --- /dev/null +++ b/src/animations/pieanimation_p.h @@ -0,0 +1,35 @@ +#ifndef PIEANIMATION_P_H_ +#define PIEANIMATION_P_H_ + +#include "chartanimation_p.h" +#include "piechartitem_p.h" +#include "piesliceanimation_p.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class PieChartItem; + +class PieAnimation : public ChartAnimation +{ + Q_OBJECT + +public: + PieAnimation(PieChartItem *item); + ~PieAnimation(); + void setValues(QVector& newValues); + void updateValue(PieSliceLayout& newValue); + +public: // from QVariantAnimation + void updateCurrentValue(const QVariant &value); + +public Q_SLOTS: + void destroySliceAnimationComplete(); + +private: + PieChartItem *m_item; + QHash m_animations; +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif diff --git a/src/animations/piesliceanimation.cpp b/src/animations/piesliceanimation.cpp new file mode 100644 index 0000000..47e5189 --- /dev/null +++ b/src/animations/piesliceanimation.cpp @@ -0,0 +1,77 @@ +#include "PieSliceAnimation_p.h" +#include "piechartitem_p.h" +#include "qpieslice.h" + +Q_DECLARE_METATYPE(QtCommercialChart::PieSliceLayout) + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +qreal linearPos(qreal start, qreal end, qreal pos) +{ + return start + ((end - start) * pos); +} + +QPointF linearPos(QPointF start, QPointF end, qreal pos) +{ + qreal x = linearPos(start.x(), end.x(), pos); + qreal y = linearPos(start.y(), end.y(), pos); + return QPointF(x, y); +} + +PieSliceAnimation::PieSliceAnimation(PieChartItem *item) + :QVariantAnimation(item), + m_item(item) +{ +} + +PieSliceAnimation::~PieSliceAnimation() +{ +} + +void PieSliceAnimation::setValue(PieSliceLayout& startValue, PieSliceLayout& endValue) +{ + if (state() != QAbstractAnimation::Stopped) + stop(); + + setKeyValueAt(0.0, qVariantFromValue(startValue)); + setKeyValueAt(1.0, qVariantFromValue(endValue)); +} + +void PieSliceAnimation::updateValue(PieSliceLayout& endValue) +{ + if (state() != QAbstractAnimation::Stopped) + stop(); + + //qDebug() << "PieSliceAnimation::updateValue()" << endValue.m_data->label() << currentSliceValue().m_startAngle << endValue.m_startAngle; + + setKeyValueAt(0.0, qVariantFromValue(currentSliceValue())); + setKeyValueAt(1.0, qVariantFromValue(endValue)); +} + +PieSliceLayout PieSliceAnimation::currentSliceValue() +{ + return qVariantValue(currentValue()); +} + +QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const +{ + PieSliceLayout startValue = qVariantValue(start); + PieSliceLayout endValue = qVariantValue(end); + + PieSliceLayout result; + result = endValue; + result.m_center = linearPos(startValue.m_center, endValue.m_center, progress); + result.m_radius = linearPos(startValue.m_radius, endValue.m_radius, progress); + result.m_startAngle = linearPos(startValue.m_startAngle, endValue.m_startAngle, progress); + result.m_angleSpan = linearPos(startValue.m_angleSpan, endValue.m_angleSpan, progress); + + return qVariantFromValue(result); +} + +void PieSliceAnimation::updateCurrentValue(const QVariant &value) +{ + if (state() != QAbstractAnimation::Stopped) //workaround + m_item->setLayout(qVariantValue(value)); +} + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/animations/piesliceanimation_p.h b/src/animations/piesliceanimation_p.h new file mode 100644 index 0000000..5afff87 --- /dev/null +++ b/src/animations/piesliceanimation_p.h @@ -0,0 +1,30 @@ +#ifndef PIESLICEANIMATION_P_H_ +#define PIESLICEANIMATION_P_H_ + +#include "piechartitem_p.h" +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class PieChartItem; + +class PieSliceAnimation : public QVariantAnimation +{ +public: + PieSliceAnimation(PieChartItem *item); + ~PieSliceAnimation(); + void setValue(PieSliceLayout& startValue, PieSliceLayout& endValue); + void updateValue(PieSliceLayout& endValue); + PieSliceLayout currentSliceValue(); + +protected: + QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress) const; + void updateCurrentValue(const QVariant &value); + +private: + PieChartItem *m_item; +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp index 5f416bd..88e06e4 100644 --- a/src/chartpresenter.cpp +++ b/src/chartpresenter.cpp @@ -224,7 +224,7 @@ void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain) QPieSeries *pieSeries = static_cast(series); PieChartItem* pie = new PieChartItem(m_chart, pieSeries); if(m_options.testFlag(QChart::SeriesAnimations)) { - // m_animator->addAnimation(pie); + m_animator->addAnimation(pie); } m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series)); QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&))); diff --git a/src/piechart/piechartitem.cpp b/src/piechart/piechartitem.cpp index bf4e4cd..0fd7ba7 100644 --- a/src/piechart/piechartitem.cpp +++ b/src/piechart/piechartitem.cpp @@ -3,6 +3,7 @@ #include "qpieslice.h" #include "qpieseries.h" #include "chartpresenter_p.h" +#include "chartanimator_p.h" #include #include @@ -36,16 +37,24 @@ void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QW void PieChartItem::handleSeriesChanged() { - QVector sliceLayout = calculateLayout(); - applyLayout(sliceLayout); + QVector layout = calculateLayout(); + applyLayout(layout); update(); } void PieChartItem::handleSliceChanged() { - // TODO: optimize don't need to handle all slices - QVector sliceLayout = calculateLayout(); - applyLayout(sliceLayout); + QPieSlice* slice = qobject_cast(sender()); + Q_ASSERT(m_slices.contains(slice)); + + //qDebug() << "PieChartItem::handleSliceChanged" << slice->label(); + + // TODO: Optimize. No need to calculate everything. + QVector layout = calculateLayout(); + foreach (PieSliceLayout sl, layout) { + if (sl.m_data == slice) + updateLayout(sl); + } update(); } @@ -93,15 +102,23 @@ QVector PieChartItem::calculateLayout() return layout; } -void PieChartItem::applyLayout(const QVector &layout) +void PieChartItem::applyLayout(QVector &layout) { - //if(m_animator) - // m_animator->applyLayout(this,points); - //else - setLayout(layout); + if (m_animator) + m_animator->applyLayout(this, layout); + else + setLayout(layout); } -void PieChartItem::setLayout(const QVector &layout) +void PieChartItem::updateLayout(PieSliceLayout &layout) +{ + if (m_animator) + m_animator->updateLayout(this, layout); + else + setLayout(layout); +} + +void PieChartItem::setLayout(QVector &layout) { foreach (PieSliceLayout l, layout) { @@ -135,8 +152,32 @@ void PieChartItem::setLayout(const QVector &layout) } if (!found) - delete m_slices.take(s); + destroySlice(s); + } +} + +void PieChartItem::setLayout(PieSliceLayout &layout) +{ + // find slice + PieSlice *slice = m_slices.value(layout.m_data); + if (!slice) { + slice = new PieSlice(this); + m_slices.insert(layout.m_data, slice); + connect(layout.m_data, SIGNAL(changed()), this, SLOT(handleSliceChanged())); + connect(slice, SIGNAL(clicked()), layout.m_data, SIGNAL(clicked())); + connect(slice, SIGNAL(hoverEnter()), layout.m_data, SIGNAL(hoverEnter())); + connect(slice, SIGNAL(hoverLeave()), layout.m_data, SIGNAL(hoverLeave())); } + slice->setLayout(layout); + if (m_series->m_slices.contains(layout.m_data)) // Slice has been deleted if not found. Animations ongoing... + slice->updateData(layout.m_data); + slice->updateGeometry(); + slice->update(); +} + +void PieChartItem::destroySlice(QPieSlice *slice) +{ + delete m_slices.take(slice); } #include "moc_piechartitem_p.cpp" diff --git a/src/piechart/piechartitem_p.h b/src/piechart/piechartitem_p.h index 253348a..6ea55c7 100644 --- a/src/piechart/piechartitem_p.h +++ b/src/piechart/piechartitem_p.h @@ -28,10 +28,13 @@ public Q_SLOTS: void handleDomainChanged(qreal, qreal, qreal, qreal); void handleGeometryChanged(const QRectF& rect); -private: +public: QVector calculateLayout(); - void applyLayout(const QVector &layout); - void setLayout(const QVector &layout); + void applyLayout(QVector &layout); + void updateLayout(PieSliceLayout &layout); + void setLayout(QVector &layout); + void setLayout(PieSliceLayout &layout); + void destroySlice(QPieSlice *slice); private: friend class PieSlice; diff --git a/src/piechart/pieslice.cpp b/src/piechart/pieslice.cpp index fb55ef9..20f576c 100644 --- a/src/piechart/pieslice.cpp +++ b/src/piechart/pieslice.cpp @@ -22,8 +22,6 @@ QPointF offset(qreal angle, qreal length) PieSlice::PieSlice(QGraphicsItem* parent) :QGraphicsObject(parent), - m_startAngle(0), - m_angleSpan(0), m_isExploded(false), m_explodeDistanceFactor(0), m_labelVisible(false), @@ -41,7 +39,7 @@ PieSlice::~PieSlice() QRectF PieSlice::boundingRect() const { - return m_slicePath.boundingRect(); + return m_slicePath.boundingRect().united(m_labelTextRect); } QPainterPath PieSlice::shape() const @@ -90,7 +88,6 @@ void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/) void PieSlice::setLayout(PieSliceLayout layout) { m_layout = layout; - updateData(layout.m_data); } void PieSlice::updateGeometry() @@ -103,7 +100,7 @@ void PieSlice::updateGeometry() // update slice path qreal centerAngle; QPointF armStart; - m_slicePath = slicePath(m_layout.m_center, m_layout.m_radius, m_startAngle, m_angleSpan, ¢erAngle, &armStart); + m_slicePath = slicePath(m_layout.m_center, m_layout.m_radius, m_layout.m_startAngle, m_layout.m_angleSpan, ¢erAngle, &armStart); // update text rect m_labelTextRect = labelTextRect(m_labelFont, m_labelText); @@ -122,8 +119,6 @@ void PieSlice::updateData(const QPieSlice* sliceData) { // TODO: compare what has changes to avoid unneccesary geometry updates - m_startAngle = sliceData->startAngle(); - m_angleSpan = sliceData->m_angleSpan; m_isExploded = sliceData->isExploded(); m_explodeDistanceFactor = sliceData->explodeDistanceFactor(); m_slicePen = sliceData->slicePen(); diff --git a/src/piechart/pieslice_p.h b/src/piechart/pieslice_p.h index 953ce35..ec50820 100644 --- a/src/piechart/pieslice_p.h +++ b/src/piechart/pieslice_p.h @@ -19,7 +19,7 @@ class QPieSlice; class PieSliceLayout { public: - QPieSlice* m_data; + QPieSlice* m_data; // TODO: get rid of this QPointF m_center; qreal m_radius; qreal m_startAngle; @@ -60,8 +60,6 @@ private: PieSliceLayout m_layout; QPainterPath m_slicePath; - qreal m_startAngle; - qreal m_angleSpan; bool m_isExploded; qreal m_explodeDistanceFactor; bool m_labelVisible; diff --git a/src/piechart/qpieseries.cpp b/src/piechart/qpieseries.cpp index 4b22081..46f2833 100644 --- a/src/piechart/qpieseries.cpp +++ b/src/piechart/qpieseries.cpp @@ -511,6 +511,8 @@ void QPieSeries::updateDerivativeData() foreach (QPieSlice* s, m_slices) m_total += s->value(); + // TODO: emit totalChanged? + // we must have some values if (m_total == 0) { qDebug() << "QPieSeries::updateDerivativeData() total == 0"; @@ -520,31 +522,35 @@ void QPieSeries::updateDerivativeData() // update slice attributes qreal sliceAngle = m_pieStartAngle; qreal pieSpan = m_pieEndAngle - m_pieStartAngle; + QVector changed; foreach (QPieSlice* s, m_slices) { - bool changed = false; + bool isChanged = false; qreal percentage = s->value() / m_total; if (s->m_percentage != percentage) { s->m_percentage = percentage; - changed = true; + isChanged = true; } qreal sliceSpan = pieSpan * percentage; if (s->m_angleSpan != sliceSpan) { s->m_angleSpan = sliceSpan; - changed = true; + isChanged = true; } if (s->m_startAngle != sliceAngle) { s->m_startAngle = sliceAngle; - changed = true; + isChanged = true; } sliceAngle += sliceSpan; - if (changed) - emit s->changed(); + if (isChanged) + changed << s; } + + foreach (QPieSlice* s, changed) + emit s->changed(); } bool QPieSeries::setModel(QAbstractItemModel* model) diff --git a/src/piechart/qpieseries.h b/src/piechart/qpieseries.h index bd4e34c..1924f73 100644 --- a/src/piechart/qpieseries.h +++ b/src/piechart/qpieseries.h @@ -124,6 +124,7 @@ private: // TODO: use PIML friend class PieChartItem; friend class PieSlice; + friend class QPieSlice; QList m_slices; qreal m_pieRelativeHorPos; diff --git a/src/piechart/qpieslice.cpp b/src/piechart/qpieslice.cpp index 80ce8a6..91a713b 100644 --- a/src/piechart/qpieslice.cpp +++ b/src/piechart/qpieslice.cpp @@ -1,4 +1,5 @@ #include "qpieslice.h" +#include "qpieseries.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -266,7 +267,12 @@ void QPieSlice::setValue(qreal value) { if (m_value != value) { m_value = value; - emit changed(); + + QPieSeries *series = qobject_cast(parent()); + if (series) + series->updateDerivativeData(); // will emit changed() + else + emit changed(); } } diff --git a/src/piechart/qpieslice.h b/src/piechart/qpieslice.h index abaf88c..48f169a 100644 --- a/src/piechart/qpieslice.h +++ b/src/piechart/qpieslice.h @@ -8,6 +8,7 @@ #include QTCOMMERCIALCHART_BEGIN_NAMESPACE +class QPieSeries; class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject { @@ -29,8 +30,6 @@ public: bool isLabelVisible() const; void setExploded(bool exploded); bool isExploded() const; - void setExplodeDistanceFactor(qreal factor); - qreal explodeDistanceFactor() const; // generated data qreal percentage() const; @@ -48,10 +47,8 @@ public: QFont labelFont() const; void setLabelArmLengthFactor(qreal factor); qreal labelArmLengthFactor() const; - - // TODO: label position in general - // setLabelFlags(inside|outside|labelArmOn|labelArmOff|???) - // setLabelOrientation(horizontal|vertical|same as slice center angle|???) + void setExplodeDistanceFactor(qreal factor); + qreal explodeDistanceFactor() const; Q_SIGNALS: void clicked();