#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); //! [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]