DoughnutChart2D Example

#include "mainwindow.h"

#include <QVariant>
#include <QGroupBox>
#include <QCheckBox>
#include <QComboBox>
#include <QSpinBox>
#include <QFormLayout>

/* MainWindow */
MainWindow::MainWindow()
    : DemoChartWindow(tr("Pie Chart 2D"))
{
    setChart(Q_NULL);
    createSeriesParametrs();
    createDoughnutSeries();
    updateValueParameters();
}

void MainWindow::createSeriesParametrs()
{
    // Option Series
    QGroupBox* seriesTypeGroup = createGroupParameters(tr("Series"));
    QFormLayout* localLayout = (QFormLayout*)seriesTypeGroup->layout();

    m_explodedCheckBox = new QCheckBox(tr("Exploded"), seriesTypeGroup);
    connect(m_explodedCheckBox, SIGNAL(stateChanged(int)), this, SLOT(explodedSeriesChanged(int)));

    m_rotateSlider = new QSlider(Qt::Horizontal, seriesTypeGroup);
    m_rotateSlider->setRange(-180, 180);
    m_rotateSlider->setSliderPosition(0);
    m_rotateSlider->setSingleStep(1);
    connect(m_rotateSlider, SIGNAL(valueChanged(int)), this, SLOT(rotateSeriesChanged(int)));

    m_editorHole = new QSpinBox(seriesTypeGroup);
    m_editorHole->setMinimumWidth(60);
    m_editorHole->setRange(0, 100);
    m_editorHole->setValue(60);
    connect(m_editorHole, SIGNAL(valueChanged(int)), this, SLOT(holeSeriesChanged(int)));

    // Layouts Series
    localLayout->addRow(m_explodedCheckBox);
    localLayout->addRow(new QLabel(tr("Pie Rotation Angle:"), seriesTypeGroup));
    localLayout->addRow(m_rotateSlider);

    m_captionEditorHole = new QLabel(tr("Hole Radius:"), seriesTypeGroup);
    localLayout->addRow(m_captionEditorHole);
    localLayout->addRow(m_editorHole);

    // Option Labels
    m_dataLabelsGroup = createGroupParameters(tr("Show Data Labels"), true);
    localLayout = (QFormLayout*)m_dataLabelsGroup->layout();

    connect(m_dataLabelsGroup, SIGNAL(toggled(bool)), this, SLOT(showDataLabels(bool)));
    m_posDataLabelsSwitcher = new QComboBox(m_dataLabelsGroup);

    m_posDataLabelsSwitcher->addItem(tr("Label Outside"), QVariant(ChartPieSeriesLabel::PieLabelOutside));
    m_posDataLabelsSwitcher->addItem(tr("Label Inside"),  QVariant(ChartPieSeriesLabel::PieLabelInside));
    m_posDataLabelsSwitcher->addItem(tr("Label Radial"),  QVariant(ChartPieSeriesLabel::PieLabelRadial));
    m_posDataLabelsSwitcher->setCurrentIndex(0);
    connect(m_posDataLabelsSwitcher, SIGNAL(currentIndexChanged(int)), this, SLOT(labelsPositionChanged(int)));
    // Layouts Series
    localLayout->addRow(m_posDataLabelsSwitcher);
}

static void createPiePoint(ChartPieSeries* series, const QString& legendText, qreal value, bool special = false)
{
    QString str = legendText;
    QString strValue;
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
    strValue = strValue.asprintf(", %.01f", value);
#else
    strValue = strValue.sprintf(", %.01f", value);
#endif
    str += strValue;

    ChartDataPoint* point = series->add(value, special);
    point->setLabel(str);
    point->setLegendText(legendText);
}

void MainWindow::createDoughnutSeries()
{
    createTitle(tr("Travel"), QColor(Qt::white));

    m_chart->legend()->setVisible(true);
    m_chart->legend()->setTextColor(Qt::white);
    m_chart->legend()->setVerticalAlignment(ChartLegend::LegendFar);
    m_chart->setBackgroundBrush(QBrush(QPixmap(QStringLiteral(":/res/plane.png"))));

    ChartDoughnutSeries2D* series = new ChartDoughnutSeries2D();
    m_chart->appendSeries(series);

    ::createPiePoint(series, QObject::tr("Other"), 1131, true);
    ::createPiePoint(series, QObject::tr("USA"), 1139, true);
    ::createPiePoint(series, QObject::tr("Taiwan"), 823, true);
    ::createPiePoint(series, QObject::tr("France"), 423);
    ::createPiePoint(series, QObject::tr("China"), 223);
    ::createPiePoint(series, QObject::tr("Australia"), 523);
    ::createPiePoint(series, QObject::tr("Germany"), 724);
    ::createPiePoint(series, QObject::tr("Italy"), 1025);
    setValueHole(60);

    ChartSeriesLabel* seriesLabel = m_chart->series().at(0)->label();
    seriesLabel->setLineColor(Qt::white);
    seriesLabel->setTextColor(Qt::white);
    seriesLabel->setBackgroundColor(QColor(Qt::transparent));
    seriesLabel->setBorderColor(Qt::white);
    m_chart->legend()->setBorderColor(Qt::white);
}

void MainWindow::setValueHole(int val)
{
    ChartDoughnutSeries2D* series2D = (ChartDoughnutSeries2D*)m_chart->series().at(0);
    Q_ASSERT(series2D != Q_NULL);
    series2D->setHolePercent(val);
}

void MainWindow::updateValueParameters()
{
    DemoChartWindow::updateValueParameters();
    labelsPositionChanged(m_posDataLabelsSwitcher->currentIndex());
    explodedSeriesChanged(m_explodedCheckBox->checkState());
    rotateSeriesChanged(m_rotateSlider->value());
    if (m_editorHole->isEnabled())
        holeSeriesChanged(m_editorHole->value());
}

void MainWindow::labelsPositionChanged(int index)
{
    QVariant var = m_posDataLabelsSwitcher->itemData(index);

    const SeriesList& listSeries = m_chart->series();

    for (int i = 0, count = listSeries.count(); i < count; ++i)
    {
        ChartDoughnutSeries2D* series = (ChartDoughnutSeries2D*)listSeries.at(i);
        ChartPieSeriesLabel* label = (ChartPieSeriesLabel*)series->label();
        label->setPosition((ChartPieSeriesLabel::PieLabelPosition)(var.toUInt()));
    }
}

void MainWindow::explodedSeriesChanged(int state)
{
    const SeriesList& listSeries = m_chart->series();

    for (int i = 0, count = listSeries.count(); i < count; ++i)
    {
        ChartDoughnutSeries2D* series = (ChartDoughnutSeries2D*)listSeries.at(i);
        series->setExplodeRelativeSizePercent(state == Qt::Checked ? 15 : 0);
    }
}

void MainWindow::rotateSeriesChanged(int value)
{
    const SeriesList& listSeries = m_chart->series();

    for (int i = 0, count = listSeries.count(); i < count; ++i)
    {
        ChartDoughnutSeries2D* series = (ChartDoughnutSeries2D*)listSeries.at(i);
        series->setRotation(value);
    }
}

void MainWindow::holeSeriesChanged(int value)
{
    const SeriesList& listSeries = m_chart->series();

    for (int i = 0, count = listSeries.count(); i < count; ++i)
    {
        ChartDoughnutSeries2D* series = (ChartDoughnutSeries2D*)listSeries.at(i);
        series->setHolePercent(value);
    }
}