diff options
Diffstat (limited to 'examples/charts/chartsgallery/themewidget.cpp')
-rw-r--r-- | examples/charts/chartsgallery/themewidget.cpp | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/examples/charts/chartsgallery/themewidget.cpp b/examples/charts/chartsgallery/themewidget.cpp new file mode 100644 index 00000000..31afc403 --- /dev/null +++ b/examples/charts/chartsgallery/themewidget.cpp @@ -0,0 +1,353 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "themewidget.h" +#include "ui_themewidget.h" + +#include <QAbstractBarSeries> +#include <QAreaSeries> +#include <QBarSet> +#include <QChartView> +#include <QCheckBox> +#include <QComboBox> +#include <QGridLayout> +#include <QLegend> +#include <QLineSeries> +#include <QPercentBarSeries> +#include <QPieSeries> +#include <QPieSlice> +#include <QRandomGenerator> +#include <QScatterSeries> +#include <QSplineSeries> +#include <QStackedBarSeries> +#include <QValueAxis> + +ThemeWidget::ThemeWidget(QWidget *parent) : + ContentWidget(parent), + m_listCount(3), + m_valueMax(10), + m_valueCount(7), + m_dataTable(generateRandomData(m_listCount, m_valueMax, m_valueCount)), + m_ui(new Ui_ThemeWidgetForm) +{ + m_ui->setupUi(this); + populateThemeBox(); + populateAnimationBox(); + populateLegendBox(); + + //create charts + + QChartView *chartView; + + chartView = new QChartView(createAreaChart(), this); + m_ui->gridLayout->addWidget(chartView, 1, 0); + m_charts << chartView; + + chartView = new QChartView(createPieChart(), this); + // Funny things happen if the pie slice labels do not fit the screen, so we ignore size policy + chartView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + m_ui->gridLayout->addWidget(chartView, 1, 1); + m_charts << chartView; + + //![5] + chartView = new QChartView(createLineChart(), this); + m_ui->gridLayout->addWidget(chartView, 1, 2); + //![5] + m_charts << chartView; + + chartView = new QChartView(createBarChart(m_valueCount), this); + m_ui->gridLayout->addWidget(chartView, 2, 0); + m_charts << chartView; + + chartView = new QChartView(createSplineChart(), this); + m_ui->gridLayout->addWidget(chartView, 2, 1); + m_charts << chartView; + + chartView = new QChartView(createScatterChart(), this); + m_ui->gridLayout->addWidget(chartView, 2, 2); + m_charts << chartView; + + // Set defaults + m_ui->antialiasCheckBox->setChecked(true); + + updateUI(); +} + +ThemeWidget::~ThemeWidget() +{ + delete m_ui; +} + +DataTable ThemeWidget::generateRandomData(int listCount, int valueMax, int valueCount) const +{ + DataTable dataTable; + + // generate random data + for (int i(0); i < listCount; i++) { + DataList dataList; + qreal yValue(0); + for (int j(0); j < valueCount; j++) { + yValue = yValue + QRandomGenerator::global()->bounded(valueMax / (qreal) valueCount); + QPointF value((j + QRandomGenerator::global()->generateDouble()) * ((qreal) m_valueMax / (qreal) valueCount), + yValue); + QString label = "Slice " + QString::number(i) + ":" + QString::number(j); + dataList << Data(value, label); + } + dataTable << dataList; + } + + return dataTable; +} + +void ThemeWidget::populateThemeBox() +{ + // add items to theme combobox + m_ui->themeComboBox->addItem("Light", QChart::ChartThemeLight); + m_ui->themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean); + m_ui->themeComboBox->addItem("Dark", QChart::ChartThemeDark); + m_ui->themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand); + m_ui->themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs); + m_ui->themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast); + m_ui->themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy); + m_ui->themeComboBox->addItem("Qt", QChart::ChartThemeQt); +} + +void ThemeWidget::populateAnimationBox() +{ + // add items to animation combobox + m_ui->animatedComboBox->addItem("No Animations", QChart::NoAnimation); + m_ui->animatedComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations); + m_ui->animatedComboBox->addItem("Series Animations", QChart::SeriesAnimations); + m_ui->animatedComboBox->addItem("All Animations", QChart::AllAnimations); +} + +void ThemeWidget::populateLegendBox() +{ + // add items to legend combobox + m_ui->legendComboBox->addItem("No Legend ", 0); + m_ui->legendComboBox->addItem("Legend Top", Qt::AlignTop); + m_ui->legendComboBox->addItem("Legend Bottom", Qt::AlignBottom); + m_ui->legendComboBox->addItem("Legend Left", Qt::AlignLeft); + m_ui->legendComboBox->addItem("Legend Right", Qt::AlignRight); +} + +QChart *ThemeWidget::createAreaChart() const +{ + auto chart = new QChart; + chart->setTitle("Area Chart"); + + // The lower series initialized to zero values + QLineSeries *lowerSeries = nullptr; + QString name("Series "); + int nameIndex = 0; + for (int i(0); i < m_dataTable.count(); i++) { + auto upperSeries = new QLineSeries(chart); + for (int j(0); j < m_dataTable[i].count(); j++) { + Data data = m_dataTable[i].at(j); + if (lowerSeries) { + const auto &points = lowerSeries->points(); + upperSeries->append(QPointF(j, points[i].y() + data.first.y())); + } else { + upperSeries->append(QPointF(j, data.first.y())); + } + } + auto area = new QAreaSeries(upperSeries, lowerSeries); + area->setName(name + QString::number(nameIndex)); + nameIndex++; + chart->addSeries(area); + lowerSeries = upperSeries; + } + + chart->createDefaultAxes(); + chart->axes(Qt::Horizontal).first()->setRange(0, m_valueCount - 1); + chart->axes(Qt::Vertical).first()->setRange(0, m_valueMax); + // Add space to label to add space between labels and axis + auto axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).first()); + Q_ASSERT(axisY); + axisY->setLabelFormat("%.1f "); + + return chart; +} + +QChart *ThemeWidget::createBarChart(int valueCount) const +{ + Q_UNUSED(valueCount); + auto chart = new QChart; + chart->setTitle("Bar Chart"); + + auto series = new QStackedBarSeries(chart); + for (int i(0); i < m_dataTable.count(); i++) { + auto set = new QBarSet("Bar set " + QString::number(i)); + for (const Data &data : m_dataTable[i]) + *set << data.first.y(); + series->append(set); + } + chart->addSeries(series); + + chart->createDefaultAxes(); + chart->axes(Qt::Vertical).first()->setRange(0, m_valueMax * 2); + // Add space to label to add space between labels and axis + auto axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).first()); + Q_ASSERT(axisY); + axisY->setLabelFormat("%.1f "); + + return chart; +} + +QChart *ThemeWidget::createLineChart() const +{ + //![1] + auto chart = new QChart; + chart->setTitle("Line Chart"); + //![1] + + //![2] + QString name("Series "); + int nameIndex = 0; + for (const DataList &list : m_dataTable) { + auto series = new QLineSeries(chart); + for (const Data &data : list) + series->append(data.first); + series->setName(name + QString::number(nameIndex)); + nameIndex++; + chart->addSeries(series); + } + //![2] + + //![3] + chart->createDefaultAxes(); + chart->axes(Qt::Horizontal).first()->setRange(0, m_valueMax); + chart->axes(Qt::Vertical).first()->setRange(0, m_valueCount); + //![3] + //![4] + // Add space to label to add space between labels and axis + auto axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).first()); + Q_ASSERT(axisY); + axisY->setLabelFormat("%.1f "); + //![4] + + return chart; +} + +QChart *ThemeWidget::createPieChart() const +{ + auto chart = new QChart; + chart->setTitle("Pie Chart"); + + auto series = new QPieSeries(chart); + for (const Data &data : m_dataTable[0]) { + QPieSlice *slice = series->append(data.second, data.first.y()); + if (data == m_dataTable[0].first()) { + // Show the first slice exploded with label + slice->setLabelVisible(); + slice->setExploded(); + slice->setExplodeDistanceFactor(0.5); + } + } + series->setPieSize(0.4); + chart->addSeries(series); + + return chart; +} + +QChart *ThemeWidget::createSplineChart() const +{ + auto chart = new QChart; + chart->setTitle("Spline Chart"); + QString name("Series "); + int nameIndex = 0; + for (const DataList &list : m_dataTable) { + auto series = new QSplineSeries(chart); + for (const Data &data : list) + series->append(data.first); + series->setName(name + QString::number(nameIndex)); + nameIndex++; + chart->addSeries(series); + } + + chart->createDefaultAxes(); + chart->axes(Qt::Horizontal).first()->setRange(0, m_valueMax); + chart->axes(Qt::Vertical).first()->setRange(0, m_valueCount); + + // Add space to label to add space between labels and axis + auto axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).first()); + Q_ASSERT(axisY); + axisY->setLabelFormat("%.1f "); + return chart; +} + +QChart *ThemeWidget::createScatterChart() const +{ + // scatter chart + auto chart = new QChart; + chart->setTitle("Scatter Chart"); + QString name("Series "); + int nameIndex = 0; + for (const DataList &list : m_dataTable) { + auto series = new QScatterSeries(chart); + for (const Data &data : list) + series->append(data.first); + series->setName(name + QString::number(nameIndex)); + nameIndex++; + chart->addSeries(series); + } + + chart->createDefaultAxes(); + chart->axes(Qt::Horizontal).first()->setRange(0, m_valueMax); + chart->axes(Qt::Vertical).first()->setRange(0, m_valueCount); + // Add space to label to add space between labels and axis + auto axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).first()); + Q_ASSERT(axisY); + axisY->setLabelFormat("%.1f "); + return chart; +} + +void ThemeWidget::updateUI() +{ + //![6] + auto theme = static_cast<QChart::ChartTheme>( + m_ui->themeComboBox->itemData(m_ui->themeComboBox->currentIndex()).toInt()); + //![6] + const auto charts = m_charts; + if (!m_charts.isEmpty() && m_charts.at(0)->chart()->theme() != theme) { + for (QChartView *chartView : charts) { + //![7] + chartView->chart()->setTheme(theme); + //![7] + } + } + + // Update antialiasing + //![11] + bool checked = m_ui->antialiasCheckBox->isChecked(); + for (QChartView *chart : charts) + chart->setRenderHint(QPainter::Antialiasing, checked); + //![11] + + // Update animation options + //![9] + QChart::AnimationOptions options( + m_ui->animatedComboBox->itemData(m_ui->animatedComboBox->currentIndex()).toInt()); + if (!m_charts.isEmpty() && m_charts.at(0)->chart()->animationOptions() != options) { + for (QChartView *chartView : charts) + chartView->chart()->setAnimationOptions(options); + } + //![9] + + // Update legend alignment + //![10] + Qt::Alignment alignment( + m_ui->legendComboBox->itemData(m_ui->legendComboBox->currentIndex()).toInt()); + + if (!alignment) { + for (QChartView *chartView : charts) + chartView->chart()->legend()->hide(); + } else { + for (QChartView *chartView : charts) { + chartView->chart()->legend()->setAlignment(alignment); + chartView->chart()->legend()->show(); + } + } + //![10] +} + |