diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp index 0f03195..332e286 100644 --- a/src/chartpresenter.cpp +++ b/src/chartpresenter.cpp @@ -138,9 +138,8 @@ void ChartPresenter::handleSeriesAdded(QChartSeries* series) break; } case QChartSeries::SeriesTypePie: { - QPieSeries *pieSeries = qobject_cast(series); - PiePresenter* pie = new PiePresenter(m_chart, pieSeries); - QObject::connect(pieSeries, SIGNAL(changed(const PieChangeSet&)), pie, SLOT(handleSeriesChanged(const PieChangeSet&))); + QPieSeries *s = qobject_cast(series); + PiePresenter* pie = new PiePresenter(m_chart, s); QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&))); QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)), pie, SLOT(handleDomainChanged(const Domain&))); m_chartItems.insert(series, pie); diff --git a/src/charttheme.cpp b/src/charttheme.cpp index b0d31bd..758055b 100644 --- a/src/charttheme.cpp +++ b/src/charttheme.cpp @@ -7,12 +7,15 @@ #include "stackedbarchartseries.h" #include "percentbarchartseries.h" #include "qlinechartseries.h" +#include "qpieseries.h" + //items #include "axisitem_p.h" #include "bargroup.h" #include "stackedbargroup.h" #include "linechartitem_p.h" #include "percentbargroup.h" +#include "piepresenter.h" //themes #include "chartthemevanilla_p.h" @@ -98,6 +101,12 @@ void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count) decorate(i,s,count); break; } + case QChartSeries::SeriesTypePie: { + QPieSeries* s = static_cast(series); + PiePresenter* i = static_cast(item); + decorate(i,s,count); + break; + } default: qDebug()<<"Wrong item to be decorated by theme"; break; @@ -146,5 +155,16 @@ void ChartTheme::decorate(PercentBarGroup* item, PercentBarChartSeries* series,i item->addColor(QColor(255,128,0,128)); } +void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/) +{ + // TODO: Does not work well. We need to generate enough different colors + // based on available theme and not use the same color twice. + for (int i=0; icount(); i++) { + QPieSlice slice = series->slice(i); + slice.m_color = m_seriesColor.at(i % m_seriesColor.count()); + series->update(i, slice); + } +} + QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/charttheme_p.h b/src/charttheme_p.h index 835ed8c..bc7d3d9 100644 --- a/src/charttheme_p.h +++ b/src/charttheme_p.h @@ -17,6 +17,8 @@ class StackedBarGroup; class StackedBarChartSeries; class PercentBarChartSeries; class PercentBarGroup; +class PiePresenter; +class QPieSeries; class ChartTheme { @@ -31,6 +33,7 @@ public: void decorate(BarGroup* item, BarChartSeries* series,int count); void decorate(StackedBarGroup* item, StackedBarChartSeries* series,int count); void decorate(PercentBarGroup* item, PercentBarChartSeries* series,int count); + void decorate(PiePresenter* item, QPieSeries* series, int count); protected: QChart::ChartTheme m_id; diff --git a/src/piechart/piepresenter.cpp b/src/piechart/piepresenter.cpp index eb8c435..6765892 100644 --- a/src/piechart/piepresenter.cpp +++ b/src/piechart/piepresenter.cpp @@ -2,6 +2,7 @@ #include "piepresenter.h" #include "pieslice.h" #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -11,8 +12,14 @@ PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series) : { Q_ASSERT(parent); Q_ASSERT(series); + m_rect = parentItem()->boundingRect(); setAcceptHoverEvents(true); + qsrand(QTime::currentTime().msec()); // for random color generation + + connect(series, SIGNAL(changed(const PieChangeSet&)), this, SLOT(handleSeriesChanged(const PieChangeSet&))); + connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry())); + connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry())); } PiePresenter::~PiePresenter() @@ -21,14 +28,21 @@ PiePresenter::~PiePresenter() delete m_slices.takeLast(); } -void PiePresenter::handleSeriesChanged(const PieChangeSet& changeSet) +void PiePresenter::handleSeriesChanged(const PieChangeSet& /*changeSet*/) { const qreal fullPie = 360; qreal total = 0; - // calculate total - foreach (QPieSlice sliceData, m_pieSeries->slices()) - total += sliceData.m_value; + // calculate total and set random color if there is no color + for (int i=0; icount(); i++) { + QPieSlice& slice = m_pieSeries->m_slices[i]; + total += slice.m_value; + if (slice.m_color == QColor::Invalid) { + slice.m_color.setRed(qrand() % 255); + slice.m_color.setGreen(qrand() % 255); + slice.m_color.setBlue(qrand() % 255); + } + } // TODO: no need to create new slices in case size changed; we should re-use the existing ones while (m_slices.count()) diff --git a/src/piechart/piepresenter.h b/src/piechart/piepresenter.h index 4083d1d..f24489f 100644 --- a/src/piechart/piepresenter.h +++ b/src/piechart/piepresenter.h @@ -22,13 +22,13 @@ public: // from QGraphicsItem void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} public: - void updateGeometry(); QRectF pieRect() const { return m_pieRect; } public Q_SLOTS: void handleSeriesChanged(const PieChangeSet& changeSet); void handleDomainChanged(const Domain& domain); void handleGeometryChanged(const QRectF& rect); + void updateGeometry(); private: friend class PieSlice; diff --git a/src/piechart/pieslice.cpp b/src/piechart/pieslice.cpp index 64bea43..f43f7d7 100644 --- a/src/piechart/pieslice.cpp +++ b/src/piechart/pieslice.cpp @@ -4,6 +4,7 @@ #include #include #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -63,23 +64,20 @@ void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option painter->drawText(m_center, sliceData().m_label); } -void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent * event) +void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* event) { - QGraphicsItem::hoverEnterEvent(event); m_brush = QBrush(sliceData().m_color.lighter()); update(); } -void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent * event) +void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) { - QGraphicsItem::hoverLeaveEvent(event); m_brush = QBrush(sliceData().m_color); update(); } -void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent *event) +void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/) { - QGraphicsItem::mousePressEvent(event); QPieSlice data = sliceData(); data.m_isExploded = !data.m_isExploded; (static_cast(parentItem()))->m_pieSeries->update(m_seriesIndex, data); diff --git a/src/piechart/qpieseries.cpp b/src/piechart/qpieseries.cpp index a636363..880818e 100644 --- a/src/piechart/qpieseries.cpp +++ b/src/piechart/qpieseries.cpp @@ -17,8 +17,19 @@ QPieSeries::~QPieSeries() } -void QPieSeries::set(QList slices) +bool QPieSeries::setData(QList data) { + QList slices; + foreach (int value, data) + slices << QPieSlice(value, QString::number(value)); + return set(slices); +} + +bool QPieSeries::set(QList slices) +{ + if (!slices.count()) + return false; + PieChangeSet changeSet; for (int i=slices.count(); i slices) m_slices = slices; emit changed(changeSet); + return true; } -void QPieSeries::add(QList slices) +bool QPieSeries::add(QList slices) { + if (!slices.count()) + return false; + PieChangeSet changeSet; for (int i=0; i() << slice); + return add(QList() << slice); } QPieSlice QPieSeries::slice(int index) const @@ -71,15 +87,21 @@ bool QPieSeries::update(int index, QPieSlice slice) void QPieSeries::setSizeFactor(qreal factor) { - if (factor > 0.0) + if (factor < 0.0) + return; + + if (m_sizeFactor != factor) { m_sizeFactor = factor; - emit sizeFactorChanged(); + emit sizeFactorChanged(); + } } void QPieSeries::setPosition(PiePosition position) { - m_position = position; - emit positionChanged(); + if (m_position != position) { + m_position = position; + emit positionChanged(); + } } #include "moc_qpieseries.cpp" diff --git a/src/piechart/qpieseries.h b/src/piechart/qpieseries.h index 4cd4bdb..f423702 100644 --- a/src/piechart/qpieseries.h +++ b/src/piechart/qpieseries.h @@ -15,14 +15,14 @@ class QPieSlice { public: QPieSlice() - :m_value(0), m_label(""), m_color(Qt::white), m_isExploded(false) {} + :m_value(0), m_label(""), m_color(QColor::Invalid), m_isExploded(false) {} - QPieSlice(qreal value, QString label, QColor color, bool exploded = false) + QPieSlice(qreal value, QString label = "", QColor color = QColor::Invalid, bool exploded = false) :m_value(value), m_label(label), m_color(color), m_isExploded(exploded) {} public: qreal m_value; QString m_label; - QColor m_color; + QColor m_color; // TODO: should we even define color here? bool m_isExploded; }; @@ -53,11 +53,12 @@ public: public: // from QChartSeries QChartSeriesType type() const { return QChartSeries::SeriesTypePie; } + virtual bool setData(QList data); public: - void set(QList slices); - void add(QList slices); - void add(QPieSlice slice); + bool set(QList slices); + bool add(QList slices); + bool add(QPieSlice slice); int count() const { return m_slices.count(); } @@ -84,6 +85,7 @@ Q_SIGNALS: private: Q_DISABLE_COPY(QPieSeries) + friend class PiePresenter; // TODO: use PIML QList m_slices; qreal m_sizeFactor;