widget.cpp
139 lines
| 4.5 KiB
| text/x-c
|
CppLexer
Marek Rosa
|
r1697 | #include "widget.h" | ||
#include <QGridLayout> | ||||
#include <QPieSlice> | ||||
#include <QTime> | ||||
#include <QChartView> | ||||
Marek Rosa
|
r1838 | #include <QChart> | ||
#include <QLegend> | ||||
Marek Rosa
|
r1697 | #include <QTimer> | ||
QTCOMMERCIALCHART_USE_NAMESPACE | ||||
Widget::Widget(QWidget *parent) | ||||
: QWidget(parent), | ||||
mainData(0) | ||||
{ | ||||
setMinimumSize(800, 600); | ||||
qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); | ||||
Marek Rosa
|
r1714 | //! [1] | ||
Marek Rosa
|
r1697 | QChartView *chartView = new QChartView; | ||
chartView->setRenderHint(QPainter::Antialiasing); | ||||
Marek Rosa
|
r1838 | QChart *chart = chartView->chart(); | ||
chart->setAnimationOptions(QChart::AllAnimations); | ||||
chart->legend()->setVisible(false); | ||||
Marek Rosa
|
r1843 | chart->setTitle("Donut breakdown example"); | ||
Marek Rosa
|
r1714 | //! [1] | ||
Marek Rosa
|
r1697 | |||
Marek Rosa
|
r1714 | //! [2] | ||
Marek Rosa
|
r1697 | mainData = new QPieSeries; | ||
Marek Rosa
|
r1712 | mainData->setPieSize(0.6); | ||
Marek Rosa
|
r1714 | //! [2] | ||
//! [3] | ||||
Marek Rosa
|
r1697 | 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; | ||||
Marek Rosa
|
r1838 | donut->setHoleSize(mainData->pieSize()); | ||
Marek Rosa
|
r1712 | donut->setPieSize(mainData->pieSize() + 0.15); | ||
Marek Rosa
|
r1697 | |||
// 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); | ||||
} | ||||
Marek Rosa
|
r1712 | donut->setLabelsPosition(QPieSlice::LabelOutside); | ||
donut->setLabelsVisible(); | ||||
Marek Rosa
|
r1697 | detailedData.append(donut); | ||
// update the value and label of mainData | ||||
slice->setValue(donut->sum()); | ||||
slice->setLabel(QString("%1").arg(donut->sum())); | ||||
} | ||||
Marek Rosa
|
r1714 | //! [3] | ||
Marek Rosa
|
r1697 | |||
Marek Rosa
|
r1714 | //! [4] | ||
Marek Rosa
|
r1697 | mainData->setLabelsVisible(); | ||
Jani Honkonen
|
r1759 | mainData->setLabelsPosition(QPieSlice::LabelInsideHorizontal); | ||
Marek Rosa
|
r1697 | chartView->chart()->addSeries(mainData); | ||
for (int i = 0; i < detailedData.count(); i++) | ||||
chartView->chart()->addSeries(detailedData.at(i)); | ||||
Marek Rosa
|
r1714 | //! [4] | ||
Marek Rosa
|
r1697 | |||
Marek Rosa
|
r1714 | //! [5] | ||
Marek Rosa
|
r1697 | // create main layout | ||
QGridLayout* mainLayout = new QGridLayout; | ||||
mainLayout->addWidget(chartView, 1, 1); | ||||
setLayout(mainLayout); | ||||
Marek Rosa
|
r1714 | //! [5] | ||
Marek Rosa
|
r1697 | |||
Marek Rosa
|
r1714 | //! [6] | ||
Marek Rosa
|
r1697 | // 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); | ||||
Marek Rosa
|
r1714 | //! [6] | ||
Marek Rosa
|
r1697 | } | ||
Widget::~Widget() | ||||
{ | ||||
} | ||||
Marek Rosa
|
r1714 | //! [7] | ||
Marek Rosa
|
r1697 | void Widget::updatedStartAngle() | ||
{ | ||||
// when the mainData slice has been updated the detailed data QPieSeries object as well | ||||
QPieSlice* slice = qobject_cast<QPieSlice *>(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<QPieSlice *>(sender()); | ||||
QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice)); | ||||
detailsDonut->setPieEndAngle(slice->startAngle() + slice->angleSpan()); | ||||
} | ||||
Marek Rosa
|
r1714 | //! [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())); | ||||
} | ||||
Marek Rosa
|
r1697 | |||
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); | ||||
} | ||||
Marek Rosa
|
r1714 | //! [8] | ||