diff --git a/examples/donutbreakdown/donutbreakdown.pro b/examples/donutbreakdown/donutbreakdown.pro index c46c3bb..0e75db6 100644 --- a/examples/donutbreakdown/donutbreakdown.pro +++ b/examples/donutbreakdown/donutbreakdown.pro @@ -4,6 +4,7 @@ TARGET = donutbreakdown SOURCES += main.cpp\ - widget.cpp + donutbreakdownchart.cpp -HEADERS += widget.h +HEADERS += \ + donutbreakdownchart.h diff --git a/examples/donutbreakdown/donutbreakdownchart.cpp b/examples/donutbreakdown/donutbreakdownchart.cpp new file mode 100644 index 0000000..5c6325a --- /dev/null +++ b/examples/donutbreakdown/donutbreakdownchart.cpp @@ -0,0 +1,73 @@ +#include "donutbreakdownchart.h" +#include + +QTCOMMERCIALCHART_USE_NAMESPACE + +//![1] +DonutBreakdownChart::DonutBreakdownChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) + :QChart(parent, wFlags) +{ + // create the series for main center pie + mainSeries = new QPieSeries(); + mainSeries->setPieSize(0.7); + addSeries(mainSeries); +} +//![1] + +//![2] +void DonutBreakdownChart::addBreakdownSeries(QPieSeries *breakdownSeries, QColor color) +{ + // add breakdown series as a slice to center pie + QPieSlice *slice = mainSeries->append(breakdownSeries->name(), breakdownSeries->sum()); + + // customize the slice + slice->setBrush(color); + slice->setLabelVisible(); + slice->setLabelColor(Qt::white); + slice->setLabelPosition(QPieSlice::LabelInsideHorizontal); + + // position and customize the breakdown series + breakdownSeries->setPieSize(0.8); + breakdownSeries->setHoleSize(0.7); + breakdownSeries->setLabelsVisible(); + foreach (QPieSlice *slice, breakdownSeries->slices()) { + color = color.lighter(110); + slice->setBrush(color); + slice->setLabelFont(QFont("Arial", 7)); + slice->setLabelArmLengthFactor(0.05); + } + + // add the series to the chart + addSeries(breakdownSeries); + + // recalculate breakdown donut segments + recalculateAngles(); +} +//![2] + +void DonutBreakdownChart::recalculateAngles() +{ + qreal angle = 0; + foreach (QPieSlice *slice, mainSeries->slices()) { + QPieSeries *s = find(slice->label()); + if (s) { + s->setPieStartAngle(angle); + angle += slice->percentage() * 360.0; + s->setPieEndAngle(angle); + } + } +} + +QPieSeries *DonutBreakdownChart::find(QString seriesName) const +{ + // find pieseries by name + foreach (QAbstractSeries *series, this->series()) { + QPieSeries *s = qobject_cast(series); + if (!s) + continue; + if (s->name() == seriesName) + return s; + } + return 0; +} + diff --git a/examples/donutbreakdown/donutbreakdownchart.h b/examples/donutbreakdown/donutbreakdownchart.h new file mode 100644 index 0000000..2fd79ed --- /dev/null +++ b/examples/donutbreakdown/donutbreakdownchart.h @@ -0,0 +1,23 @@ +#ifndef DONUTBREAKDOWNCHART_H +#define DONUTBREAKDOWNCHART_H + +#include +#include + +QTCOMMERCIALCHART_USE_NAMESPACE + +class DonutBreakdownChart : public QChart +{ +public: + DonutBreakdownChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); + void addBreakdownSeries(QPieSeries *series, QColor color); + +private: + void recalculateAngles(); + QPieSeries *find(QString seriesName) const; + +private: + QPieSeries *mainSeries; +}; + +#endif // DONUTBREAKDOWNCHART_H diff --git a/examples/donutbreakdown/main.cpp b/examples/donutbreakdown/main.cpp index 7b1f424..8f0bc26 100644 --- a/examples/donutbreakdown/main.cpp +++ b/examples/donutbreakdown/main.cpp @@ -1,11 +1,55 @@ #include -#include "widget.h" +#include +#include +#include "donutbreakdownchart.h" + +QTCOMMERCIALCHART_USE_NAMESPACE int main(int argc, char *argv[]) { QApplication a(argc, argv); - Widget w; - w.show(); + + // Data from http://www.stat.fi/til/ekul/2010/ekul_2010_2011-12-13_tie_001_en.html + + //![1] + QPieSeries *series1 = new QPieSeries(); + series1->setName("Fossil"); + series1->append("Oil", 353295); + series1->append("Wood", 319663); + series1->append("Coal", 188500); + series1->append("Natural gas", 148680); + series1->append("Peat", 94545); + + QPieSeries *series2 = new QPieSeries(); + series2->setName("Renewable"); + series2->append("Hydro power", 45875); + series2->append("Wind power", 1060); + + QPieSeries *series3 = new QPieSeries(); + series3->setName("Other"); + series3->append("Nuclear energy", 238789); + series3->append("Import energy", 37802); + series3->append("Others", 32441); + //![1] + + //![2] + DonutBreakdownChart *donutBreakdown = new DonutBreakdownChart(); + donutBreakdown->setAnimationOptions(QChart::AllAnimations); + donutBreakdown->setTitle("Total consumption of energy in Finland 2010"); + donutBreakdown->legend()->setVisible(false); + donutBreakdown->addBreakdownSeries(series1, Qt::red); + donutBreakdown->addBreakdownSeries(series2, Qt::darkGreen); + donutBreakdown->addBreakdownSeries(series3, Qt::darkBlue); + //![2] + + //![3] + QMainWindow window; + QChartView* chartView = new QChartView(donutBreakdown); + chartView->setRenderHint(QPainter::Antialiasing); + window.setCentralWidget(chartView); + window.resize(800, 600); + window.show(); + //![3] return a.exec(); } diff --git a/examples/donutbreakdown/widget.cpp b/examples/donutbreakdown/widget.cpp deleted file mode 100644 index d944bda..0000000 --- a/examples/donutbreakdown/widget.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "widget.h" -#include -#include -#include -#include -#include -#include -#include - -QTCOMMERCIALCHART_USE_NAMESPACE - -Widget::Widget(QWidget *parent) - : QWidget(parent), - mainData(0) -{ - setMinimumSize(800, 600); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - - //! [1] - QChartView *chartView = new QChartView; - chartView->setRenderHint(QPainter::Antialiasing); - QChart *chart = chartView->chart(); - chart->setAnimationOptions(QChart::AllAnimations); - chart->legend()->setVisible(false); - chart->setTitle("Donut breakdown example"); - //! [1] - - //! [2] - mainData = new QPieSeries; - mainData->setPieSize(0.6); - //! [2] - - //! [3] - for (int j = 0; j < 4; j++) { - // create new slice for the mainData - QPieSlice *slice = new QPieSlice; - slice->setLabelColor(Qt::white); - mainData->append(slice); - - // create a new detailed data for the slice - QPieSeries *donut = new QPieSeries; - donut->setHoleSize(mainData->pieSize()); - donut->setPieSize(mainData->pieSize() + 0.15); - - // when mainData slice is redrawn make sure the detailed data slices are aligned with it - connect(slice, SIGNAL(startAngleChanged()), this, SLOT(updatedStartAngle())); - connect(slice, SIGNAL(angleSpanChanged()), this, SLOT(updatedAngleSpan())); - - // create the detailed data - for (int j = 0; j < 3; j++) { - qreal value = 10 + qrand() % 100; - QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value); - donut->append(slice); - } - donut->setLabelsPosition(QPieSlice::LabelOutside); - donut->setLabelsVisible(); - detailedData.append(donut); - - // update the value and label of mainData - slice->setValue(donut->sum()); - slice->setLabel(QString("%1").arg(donut->sum())); - } - //! [3] - - //! [4] - mainData->setLabelsVisible(); - mainData->setLabelsPosition(QPieSlice::LabelInsideHorizontal); - chartView->chart()->addSeries(mainData); - for (int i = 0; i < detailedData.count(); i++) - chartView->chart()->addSeries(detailedData.at(i)); - //! [4] - - //! [5] - // create main layout - QGridLayout* mainLayout = new QGridLayout; - mainLayout->addWidget(chartView, 1, 1); - setLayout(mainLayout); - //! [5] - - //! [6] - // modify the value of one detailed slice every 2.5 sec - QTimer *updateTimer = new QTimer(this); - connect(updateTimer, SIGNAL(timeout()), this, SLOT(highlight())); - updateTimer->start(2500); - //! [6] -} - -Widget::~Widget() -{ - -} - - //! [7] -void Widget::updatedStartAngle() -{ - // when the mainData slice has been updated the detailed data QPieSeries object as well - QPieSlice* slice = qobject_cast(sender()); - QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice)); - detailsDonut->setPieStartAngle(slice->startAngle()); -} - -void Widget::updatedAngleSpan() -{ - // when the mainData slice has been updated the detailed data QPieSeries object as well - QPieSlice* slice = qobject_cast(sender()); - QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice)); - detailsDonut->setPieEndAngle(slice->startAngle() + slice->angleSpan()); -} - //! [7] - - //! [8] -void Widget::highlight() -{ - // choose one random detailed data slice to be updated. - detailIndex = qrand() % mainData->count(); - sliceIndex = qrand() % detailedData.at(detailIndex)->count(); - - // set the slice to exploded to make the change easier to observe - detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded(); - - // give the user time to focus on the slice that will be changed - QTimer::singleShot(1000, this, SLOT(updateRotation())); -} - -void Widget::updateRotation() -{ - // update the selected slice - qreal newValue = 10 + qrand() % 100; - detailedData.at(detailIndex)->slices().at(sliceIndex)->setValue(newValue); - detailedData.at(detailIndex)->slices().at(sliceIndex)->setLabel(QString("%1").arg(newValue)); - - // update the mainData slice with a new sum of the detailed data values - mainData->slices().at(detailIndex)->setValue(detailedData.at(detailIndex)->sum()); - mainData->slices().at(detailIndex)->setLabel(QString("%1").arg(detailedData.at(detailIndex)->sum())); - - // change the explode state of the selected slice back to normal - detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded(false); -} - //! [8] diff --git a/examples/donutbreakdown/widget.h b/examples/donutbreakdown/widget.h deleted file mode 100644 index c03196c..0000000 --- a/examples/donutbreakdown/widget.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef WIDGET_H -#define WIDGET_H - -#include -#include - -QTCOMMERCIALCHART_USE_NAMESPACE - -class Widget : public QWidget -{ - Q_OBJECT - -public: - Widget(QWidget *parent = 0); - ~Widget(); - -public slots: - void updatedStartAngle(); - void updatedAngleSpan(); - void updateRotation(); - void highlight(); - -private: - QPieSeries *mainData; - QList detailedData; - int detailIndex; - int sliceIndex; -}; - -#endif // WIDGET_H diff --git a/examples/donutchart/main.cpp b/examples/donutchart/main.cpp index 789b9b7..4ffd520 100644 --- a/examples/donutchart/main.cpp +++ b/examples/donutchart/main.cpp @@ -46,9 +46,9 @@ int main(int argc, char *argv[]) chartView->setRenderHint(QPainter::Antialiasing); chartView->chart()->setTitle("Donut with a lemon glaze (100g)"); chartView->chart()->addSeries(series); - chartView->chart()->legend()->setAlignment(Qt::AlignBottom); + chartView->chart()->legend()->setAlignment(Qt::AlignLeft); chartView->chart()->setTheme(QChart::ChartThemeBlueCerulean); - chartView->chart()->legend()->setFont(QFont("Arial", 7)); + //chartView->chart()->legend()->setFont(QFont("Arial", 7)); //![2] //![3]