##// END OF EJS Templates
Documented the donutdrilldown chart example
Marek Rosa -
r1714:d63ddbb6caa3
parent child
Show More
@@ -0,0 +1,52
1 /*!
2 \example examples/donutdrilldown
3 \title Donut chart drilldown example
4 \subtitle
5
6 This example shows how to use create a donut drilldown chart using QPieSeries API.
7
8 Let's start by creating a QChartView instance and enabling the Antialiasing on it. Last line enables the animations of the chart.
9
10 \snippet ../examples/donutdrilldown/widget.cpp 1
11
12 PieSeries is used to present the general data.
13
14 \snippet ../examples/donutdrilldown/widget.cpp 2
15
16 Following block of code creates the slices for the mainData QPieSeries.
17 Then for every created slice a new series is created that stores the detailed data.
18 The details series is set to be a donut. Its size is adjusted so that it wraps around the mainData pie.
19 Next two signals from the mainData pie's slices are connected. This is used to keep the mainData slices agligned with their respective details series.
20
21 \snippet ../examples/donutdrilldown/widget.cpp 3
22
23 Set the labels of the mainData to enabled and their postion to Outside.
24 Then add the mainData and detailedData series to the chart.
25
26 \snippet ../examples/donutdrilldown/widget.cpp 4
27
28 Finally the widget is placed in a layout used by the application.
29
30 \snippet ../examples/donutdrilldown/widget.cpp 5
31
32 To show that the detailed data stays aligned with the main data every 2.5 sec. one of the slices is modified.
33 It should be noted that int this example the mainData slices should not be modified directly as the change
34 cannot be applied to the detailed slices without the extra knowledge on how the split looks like.
35
36 \snippet ../examples/donutdrilldown/widget.cpp 6
37
38 When the mainData slice layout is changed the detailed data layout has to be modified accordingly.
39 This is achived by setting the start and end angle of the detailed series.
40
41 \snippet ../examples/donutdrilldown/widget.cpp 7
42
43 Highlight slot selects a random slice for the modification.
44 The slice is set to exploded to notify the user that its going to be changed.
45 The actual data modification is delayed by 1 sec to give a user a chance to focus on the slice.
46
47 Then the slice is modified. Respective mainData slice is modified as well to contain as the value the sum of the detailed series slices values.
48 Finally the slice exploded state is set to false.
49
50 \snippet ../examples/donutdrilldown/widget.cpp 8
51
52 */
@@ -1,119 +1,136
1 1 #include "widget.h"
2 2 #include <QGridLayout>
3 3
4 4 #include <QPieSlice>
5 5 #include <QTime>
6 6 #include <QChartView>
7 7 #include <QTimer>
8 8
9 9 QTCOMMERCIALCHART_USE_NAMESPACE
10 10
11 11 Widget::Widget(QWidget *parent)
12 12 : QWidget(parent),
13 13 mainData(0)
14 14 {
15 15 setMinimumSize(800, 600);
16 16 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
17 17
18 //! [1]
18 19 QChartView *chartView = new QChartView;
19 20 chartView->setRenderHint(QPainter::Antialiasing);
20 21 chartView->chart()->setAnimationOptions(QChart::AllAnimations);
22 //! [1]
21 23
24 //! [2]
22 25 mainData = new QPieSeries;
23 26 mainData->setPieSize(0.6);
27 //! [2]
28
29 //! [3]
24 30 for (int j = 0; j < 4; j++) {
25 31 // create new slice for the mainData
26 32 QPieSlice *slice = new QPieSlice;
27 33 slice->setLabelColor(Qt::white);
28 34 mainData->append(slice);
29 35
30 36 // create a new detailed data for the slice
31 37 QPieSeries *donut = new QPieSeries;
32 38 donut->setDonut();
33 39 donut->setDonutInnerSize(mainData->pieSize());
34 40 donut->setPieSize(mainData->pieSize() + 0.15);
35 41
36 42 // when mainData slice is redrawn make sure the detailed data slices are aligned with it
37 43 connect(slice, SIGNAL(startAngleChanged()), this, SLOT(updatedStartAngle()));
38 44 connect(slice, SIGNAL(angleSpanChanged()), this, SLOT(updatedAngleSpan()));
39 45
40 46 // create the detailed data
41 47 for (int j = 0; j < 3; j++) {
42 48 qreal value = 10 + qrand() % 100;
43 49 QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value);
44 50 donut->append(slice);
45 51 }
46 52 donut->setLabelsPosition(QPieSlice::LabelOutside);
47 53 donut->setLabelsVisible();
48 54 detailedData.append(donut);
49 55
50 56 // update the value and label of mainData
51 57 slice->setValue(donut->sum());
52 58 slice->setLabel(QString("%1").arg(donut->sum()));
53 59 }
60 //! [3]
54 61
62 //! [4]
55 63 mainData->setLabelsVisible();
56 64 mainData->setLabelsPosition(QPieSlice::LabelInside);
57 65 chartView->chart()->addSeries(mainData);
58 66 for (int i = 0; i < detailedData.count(); i++)
59 67 chartView->chart()->addSeries(detailedData.at(i));
68 //! [4]
60 69
70 //! [5]
61 71 // create main layout
62 72 QGridLayout* mainLayout = new QGridLayout;
63 73 mainLayout->addWidget(chartView, 1, 1);
64 74 setLayout(mainLayout);
75 //! [5]
65 76
77 //! [6]
66 78 // modify the value of one detailed slice every 2.5 sec
67 79 QTimer *updateTimer = new QTimer(this);
68 80 connect(updateTimer, SIGNAL(timeout()), this, SLOT(highlight()));
69 81 updateTimer->start(2500);
82 //! [6]
70 83 }
71 84
72 85 Widget::~Widget()
73 86 {
74 87
75 88 }
76 89
90 //! [7]
77 91 void Widget::updatedStartAngle()
78 92 {
79 93 // when the mainData slice has been updated the detailed data QPieSeries object as well
80 94 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
81 95 QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice));
82 96 detailsDonut->setPieStartAngle(slice->startAngle());
83 97 }
84 98
85 99 void Widget::updatedAngleSpan()
86 100 {
87 101 // when the mainData slice has been updated the detailed data QPieSeries object as well
88 102 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
89 103 QPieSeries *detailsDonut = detailedData.at(slice->series()->slices().indexOf(slice));
90 104 detailsDonut->setPieEndAngle(slice->startAngle() + slice->angleSpan());
91 105 }
106 //! [7]
107
108 //! [8]
109 void Widget::highlight()
110 {
111 // choose one random detailed data slice to be updated.
112 detailIndex = qrand() % mainData->count();
113 sliceIndex = qrand() % detailedData.at(detailIndex)->count();
114
115 // set the slice to exploded to make the change easier to observe
116 detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded();
117
118 // give the user time to focus on the slice that will be changed
119 QTimer::singleShot(1000, this, SLOT(updateRotation()));
120 }
92 121
93 122 void Widget::updateRotation()
94 123 {
95 124 // update the selected slice
96 125 qreal newValue = 10 + qrand() % 100;
97 126 detailedData.at(detailIndex)->slices().at(sliceIndex)->setValue(newValue);
98 127 detailedData.at(detailIndex)->slices().at(sliceIndex)->setLabel(QString("%1").arg(newValue));
99 128
100 129 // update the mainData slice with a new sum of the detailed data values
101 130 mainData->slices().at(detailIndex)->setValue(detailedData.at(detailIndex)->sum());
102 131 mainData->slices().at(detailIndex)->setLabel(QString("%1").arg(detailedData.at(detailIndex)->sum()));
103 132
104 133 // change the explode state of the selected slice back to normal
105 134 detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded(false);
106 135 }
107
108 void Widget::highlight()
109 {
110 // choose one random detailed data slice to be updated.
111 detailIndex = qrand() % mainData->count();
112 sliceIndex = qrand() % detailedData.at(detailIndex)->count();
113
114 // set the slice to exploded to make the change easier to observe
115 detailedData.at(detailIndex)->slices().at(sliceIndex)->setExploded();
116
117 // give the user time to focus on the slice that will be changed
118 QTimer::singleShot(1000, this, SLOT(updateRotation()));
119 }
136 //! [8]
General Comments 0
You need to be logged in to leave comments. Login now