diff --git a/src/animations/piesliceanimation.cpp b/src/animations/piesliceanimation.cpp index 31982c8..e144e7d 100644 --- a/src/animations/piesliceanimation.cpp +++ b/src/animations/piesliceanimation.cpp @@ -18,6 +18,26 @@ QPointF linearPos(QPointF start, QPointF end, qreal pos) return QPointF(x, y); } +QPen linearPos(QPen start, QPen end, qreal pos) +{ + QColor c; + c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos)); + c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos)); + c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos)); + end.setColor(c); + return end; +} + +QBrush linearPos(QBrush start, QBrush end, qreal pos) +{ + QColor c; + c.setRedF(linearPos(start.color().redF(), end.color().redF(), pos)); + c.setGreenF(linearPos(start.color().greenF(), end.color().greenF(), pos)); + c.setBlueF(linearPos(start.color().blueF(), end.color().blueF(), pos)); + end.setColor(c); + return end; +} + PieSliceAnimation::PieSliceAnimation(PieChartItem *item, QPieSlice *slice) :QVariantAnimation(item), m_item(item), @@ -34,6 +54,8 @@ void PieSliceAnimation::setValue(const PieSliceLayout &startValue, const PieSlic if (state() != QAbstractAnimation::Stopped) stop(); + m_currentValue = startValue; + setKeyValueAt(0.0, qVariantFromValue(startValue)); setKeyValueAt(1.0, qVariantFromValue(endValue)); } @@ -43,13 +65,18 @@ void PieSliceAnimation::updateValue(const PieSliceLayout &endValue) if (state() != QAbstractAnimation::Stopped) stop(); - setKeyValueAt(0.0, qVariantFromValue(currentSliceValue())); + setKeyValueAt(0.0, qVariantFromValue(m_currentValue)); setKeyValueAt(1.0, qVariantFromValue(endValue)); } PieSliceLayout PieSliceAnimation::currentSliceValue() { - return qVariantValue(currentValue()); + // NOTE: + // We must use an internal current value because QVariantAnimation::currentValue() is updated + // before the animation is actually started. So if we get 2 updateValue() calls in a row the currentValue() + // will have the end value set from the first call and the second call will interpolate that instead of + // the original current value as it was before the first call. + return m_currentValue; } QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const @@ -63,15 +90,18 @@ QVariant PieSliceAnimation::interpolated(const QVariant &start, const QVariant & 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); + result.m_pen = linearPos(startValue.m_pen, endValue.m_pen, progress); + result.m_brush = linearPos(startValue.m_brush, endValue.m_brush, progress); return qVariantFromValue(result); } void PieSliceAnimation::updateCurrentValue(const QVariant &value) { - PieSliceLayout layout = qVariantValue(value); - if (state() != QAbstractAnimation::Stopped) //workaround - m_item->setLayout(m_slice, layout); + if (state() != QAbstractAnimation::Stopped) { //workaround + m_currentValue = qVariantValue(value); + m_item->setLayout(m_slice, m_currentValue); + } } QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/animations/piesliceanimation_p.h b/src/animations/piesliceanimation_p.h index fdaba6a..c79d1bd 100644 --- a/src/animations/piesliceanimation_p.h +++ b/src/animations/piesliceanimation_p.h @@ -25,6 +25,7 @@ protected: private: PieChartItem *m_item; QPieSlice *m_slice; + PieSliceLayout m_currentValue; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp index b8fa568..52436dc 100644 --- a/src/chartpresenter.cpp +++ b/src/chartpresenter.cpp @@ -212,7 +212,7 @@ void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain) case QSeries::SeriesTypePie: { QPieSeries *pieSeries = static_cast(series); - PieChartItem* pie = new PieChartItem(m_chart, pieSeries); + PieChartItem* pie = new PieChartItem(pieSeries, this, m_chart); if(m_options.testFlag(QChart::SeriesAnimations)) { m_animator->addAnimation(pie); } diff --git a/src/chartpresenter_p.h b/src/chartpresenter_p.h index f7de94e..78d5d19 100644 --- a/src/chartpresenter_p.h +++ b/src/chartpresenter_p.h @@ -39,7 +39,10 @@ public: int margin() const; QRectF geometry() const; - ChartAnimator* animator() const {return m_animator;}; + + ChartAnimator* animator() const {return m_animator;} + ChartTheme *theme() { return m_chartTheme; } + ChartDataSet *dataSet() { return m_dataset; } void setChartTheme(QChart::ChartTheme theme,bool force = true); QChart::ChartTheme chartTheme(); @@ -52,6 +55,7 @@ public: void zoomOut(); void zoomReset(); void scroll(int dx,int dy); + private: void createConnections(); void resetAllElements(); diff --git a/src/piechart/piechartitem.cpp b/src/piechart/piechartitem.cpp index d3c8448..6df5137 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 "chartdataset_p.h" #include "chartanimator_p.h" #include #include @@ -10,9 +11,10 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE -PieChartItem::PieChartItem(QGraphicsItem *parent, QPieSeries *series) +PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent) :ChartItem(parent), - m_series(series) + m_series(series), + m_presenter(presenter) { Q_ASSERT(series); connect(series, SIGNAL(added(QList)), this, SLOT(handleSlicesAdded(QList))); @@ -49,6 +51,8 @@ void PieChartItem::handleSlicesAdded(QList slices) { bool isEmpty = m_slices.isEmpty(); + m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series)); + foreach (QPieSlice *s, slices) { PieSlice* slice = new PieSlice(this); m_slices.insert(s, slice); @@ -68,6 +72,8 @@ void PieChartItem::handleSlicesAdded(QList slices) void PieChartItem::handleSlicesRemoved(QList slices) { + m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series)); + foreach (QPieSlice *s, slices) { if (m_animator) m_animator->removeAnimation(this, s); @@ -126,6 +132,8 @@ PieSliceLayout PieChartItem::calculateSliceLayout(QPieSlice *slice) sliceLayout.m_radius = m_pieRadius; sliceLayout.m_startAngle = slice->startAngle(); sliceLayout.m_angleSpan = slice->m_angleSpan; + sliceLayout.m_pen = slice->m_slicePen; + sliceLayout.m_brush = slice->m_sliceBrush; return sliceLayout; } diff --git a/src/piechart/piechartitem_p.h b/src/piechart/piechartitem_p.h index 21252c9..9dda481 100644 --- a/src/piechart/piechartitem_p.h +++ b/src/piechart/piechartitem_p.h @@ -8,6 +8,7 @@ class QGraphicsItem; QTCOMMERCIALCHART_BEGIN_NAMESPACE class QPieSlice; +class ChartPresenter; typedef QHash PieLayout; @@ -17,7 +18,7 @@ class PieChartItem : public QObject, public ChartItem public: // TODO: use a generic data class instead of x and y - PieChartItem(QGraphicsItem *parent, QPieSeries *series); + PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent); ~PieChartItem(); public: // from QGraphicsItem @@ -50,7 +51,7 @@ private: QRectF m_rect; QPointF m_pieCenter; qreal m_pieRadius; - QRectF m_debugRect; + ChartPresenter *m_presenter; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/piechart/pieslice.cpp b/src/piechart/pieslice.cpp index dae1f67..5c52656 100644 --- a/src/piechart/pieslice.cpp +++ b/src/piechart/pieslice.cpp @@ -54,8 +54,8 @@ void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option painter->setClipRect(parentItem()->boundingRect()); painter->save(); - painter->setPen(m_slicePen); - painter->setBrush(m_sliceBrush); + painter->setPen(m_layout.m_pen); + painter->setBrush(m_layout.m_brush); painter->drawPath(m_slicePath); painter->restore(); @@ -122,8 +122,6 @@ void PieSlice::updateData(const QPieSlice* sliceData) m_isExploded = sliceData->isExploded(); m_explodeDistanceFactor = sliceData->explodeDistanceFactor(); - m_slicePen = sliceData->slicePen(); - m_sliceBrush = sliceData->sliceBrush(); m_labelVisible = sliceData->isLabelVisible(); m_labelText = sliceData->label(); diff --git a/src/piechart/pieslice_p.h b/src/piechart/pieslice_p.h index 5de85aa..115e091 100644 --- a/src/piechart/pieslice_p.h +++ b/src/piechart/pieslice_p.h @@ -23,6 +23,8 @@ public: qreal m_radius; qreal m_startAngle; qreal m_angleSpan; + QPen m_pen; + QBrush m_brush; }; class PieSlice : public QGraphicsObject @@ -63,8 +65,6 @@ private: bool m_isExploded; qreal m_explodeDistanceFactor; bool m_labelVisible; - QPen m_slicePen; - QBrush m_sliceBrush; QPainterPath m_labelArmPath; qreal m_labelArmLengthFactor;