1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Charts module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 or (at your option) any later version
20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29 #include "widget.h"
30 #include <QtCharts/QChartView>
31 #include <QtCharts/QChart>
32 #include <QtCharts/QLegend>
33 #include <QtCharts/QPieSeries>
34 #include <QtCharts/QPieSlice>
35 #include <QtCore/QRandomGenerator>
36 #include <QtWidgets/QGridLayout>
37 #include <QtCore/QTimer>
38 
39 QT_CHARTS_USE_NAMESPACE
40 
Widget(QWidget * parent)41 Widget::Widget(QWidget *parent)
42     : QWidget(parent)
43 {
44     setMinimumSize(800, 600);
45 
46     //! [1]
47     QChartView *chartView = new QChartView;
48     chartView->setRenderHint(QPainter::Antialiasing);
49     QChart *chart = chartView->chart();
50     chart->legend()->setVisible(false);
51     chart->setTitle("Nested donuts demo");
52     chart->setAnimationOptions(QChart::AllAnimations);
53     //! [1]
54 
55     //! [2]
56     qreal minSize = 0.1;
57     qreal maxSize = 0.9;
58     int donutCount = 5;
59     //! [2]
60 
61     //! [3]
62     for (int i = 0; i < donutCount; i++) {
63         QPieSeries *donut = new QPieSeries;
64         int sliceCount =  3 + QRandomGenerator::global()->bounded(3);
65         for (int j = 0; j < sliceCount; j++) {
66             qreal value = 100 + QRandomGenerator::global()->bounded(100);
67             QPieSlice *slice = new QPieSlice(QString("%1").arg(value), value);
68             slice->setLabelVisible(true);
69             slice->setLabelColor(Qt::white);
70             slice->setLabelPosition(QPieSlice::LabelInsideTangential);
71             connect(slice, &QPieSlice::hovered, this, &Widget::explodeSlice);
72             donut->append(slice);
73             donut->setHoleSize(minSize + i * (maxSize - minSize) / donutCount);
74             donut->setPieSize(minSize + (i + 1) * (maxSize - minSize) / donutCount);
75         }
76         m_donuts.append(donut);
77         chartView->chart()->addSeries(donut);
78     }
79     //! [3]
80 
81     // create main layout
82     //! [4]
83     QGridLayout *mainLayout = new QGridLayout;
84     mainLayout->addWidget(chartView, 1, 1);
85     setLayout(mainLayout);
86     //! [4]
87 
88     //! [5]
89     updateTimer = new QTimer(this);
90     connect(updateTimer, &QTimer::timeout, this, &Widget::updateRotation);
91     updateTimer->start(1250);
92     //! [5]
93 }
94 
~Widget()95 Widget::~Widget()
96 {
97 
98 }
99 
100 //! [6]
updateRotation()101 void Widget::updateRotation()
102 {
103     for (int i = 0; i < m_donuts.count(); i++) {
104         QPieSeries *donut = m_donuts.at(i);
105         qreal phaseShift =  -50 + QRandomGenerator::global()->bounded(100);
106         donut->setPieStartAngle(donut->pieStartAngle() + phaseShift);
107         donut->setPieEndAngle(donut->pieEndAngle() + phaseShift);
108     }
109 }
110 //! [6]
111 
112 //! [7]
explodeSlice(bool exploded)113 void Widget::explodeSlice(bool exploded)
114 {
115     QPieSlice *slice = qobject_cast<QPieSlice *>(sender());
116     if (exploded) {
117         updateTimer->stop();
118         qreal sliceStartAngle = slice->startAngle();
119         qreal sliceEndAngle = slice->startAngle() + slice->angleSpan();
120 
121         QPieSeries *donut = slice->series();
122         qreal seriesIndex = m_donuts.indexOf(donut);
123         for (int i = seriesIndex + 1; i < m_donuts.count(); i++) {
124             m_donuts.at(i)->setPieStartAngle(sliceEndAngle);
125             m_donuts.at(i)->setPieEndAngle(360 + sliceStartAngle);
126         }
127     } else {
128         for (int i = 0; i < m_donuts.count(); i++) {
129             m_donuts.at(i)->setPieStartAngle(0);
130             m_donuts.at(i)->setPieEndAngle(360);
131         }
132         updateTimer->start();
133     }
134     slice->setExploded(exploded);
135 }
136 //! [7]
137