这个示例展示了图表在不同内置主题的外观。
此示例显示了一些受支持的图表类型的不同内置主题的外观。
具体讲解在:
http://doc.qt.io/qt-5/qtcharts-chartthemes-example.html
QPair:
QPair
类模板: template
参数:class T1是第一个值的数据类型,class T2是第二个值的数据类型。
功能:pair将一对值(可以是不同的数据类型)组合成一个值,两个值可以分别用pair的两个公有函数first和second访问。
https://blog.csdn.net/Superman___007/article/details/89335836
QChartView: QChartView是一个可以显示图表的独立小部件。图表需要显示在该部件上。
QChart:QChart类管理图表系列、图例和轴的图形表示。各种类型图需要显示在图表上。
QLineSeries: QLineSeries类用折线图表示数据。
QStackedBarSeries: QStackedBarSeries类将一系列数据显示为垂直堆叠的条形图,每个类别有一个条形图。
QPieSlice: QPieSeries类以饼状图的形式表示数据。
QSplineSeries: QSplineSeries类将数据表示为样条图。
QScatterSeries:QScatterSeries类用散点图表示数据。
void ThemeWidget::updateUI()
{
//![6] 获取当前选中的主题
QChart::ChartTheme theme = static_cast(
m_ui->themeComboBox->itemData(m_ui->themeComboBox->currentIndex()).toInt());
//![6]
const auto charts = m_charts;
// 如果存入的chartview为空,并且第零个和当前选中的主题不一致,则更新view的主题
if (!m_charts.isEmpty() && m_charts.at(0)->chart()->theme() != theme)
{
for (QChartView *chartView : charts)
{
//![7] 更新当前视图对应的图表的主题
chartView->chart()->setTheme(theme);
//![7]
}
// Set palette colors based on selected theme
//![8]
QPalette pal = window()->palette();
if (theme == QChart::ChartThemeLight)
{
pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
//![8]
}
else if (theme == QChart::ChartThemeDark)
{
pal.setColor(QPalette::Window, QRgb(0x121218));
pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
}
else if (theme == QChart::ChartThemeBlueCerulean)
{
pal.setColor(QPalette::Window, QRgb(0x40434a));
pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
}
else if (theme == QChart::ChartThemeBrownSand)
{
pal.setColor(QPalette::Window, QRgb(0x9e8965));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
}
else if (theme == QChart::ChartThemeBlueNcs)
{
pal.setColor(QPalette::Window, QRgb(0x018bba));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
}
else if (theme == QChart::ChartThemeHighContrast)
{
pal.setColor(QPalette::Window, QRgb(0xffab03));
pal.setColor(QPalette::WindowText, QRgb(0x181818));
}
else if (theme == QChart::ChartThemeBlueIcy)
{
pal.setColor(QPalette::Window, QRgb(0xcee7f0));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
}
else
{
pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
}
// 根据选中的主题,并设置对应的窗口颜色和窗口文本的颜色,来设置当前窗口的颜色
window()->setPalette(pal);
}
// 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());
// 按照当前animation的项,来更新图标的视图
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]
}
DataTable ThemeWidget::generateRandomData(int listCount, int valueMax, int valueCount) const
{
DataTable dataTable;
// generate random data
// m_dataList: 中三个成员,即三条线的数据
for (int i(0); i < listCount; i++)
{
DataList dataList;
qreal yValue(0);
// valueMax: 10
// valueCount: 7
for (int j(0); j < valueCount; j++)
{
// [static] QRandomGenerator *QRandomGenerator::global():
// 返回一个指向使用securelyseed()进行种子化的共享QRandomGenerator的指针。
// 这个函数应该用于创建随机数据,而不需要为特定用途创建安全的QRandomGenerator,
// 也不需要存储相当大的QRandomGenerator对象。
// double QRandomGenerator::bounded(double highest):
// 生成一个在0(包含)和最高(排除)之间的随机双精度值。该函数等价于并实现为:
// return generateDouble() * highest;
// 最大参数为负,结果也为负;如果它是无穷大或NaN,结果将是无穷大或NaN也是(即,不是随机的)。
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);
// QRandomGenerator类允许从高质量的随机数生成器中获取随机值。
qDebug() << "random value: " << QRandomGenerator::global()->generateDouble();
qDebug() << "xValue: " << (j + QRandomGenerator::global()->generateDouble()) * ((qreal) m_valueMax / (qreal) valueCount);
qDebug() << "yValue: " << yValue;
qDebug() << "label: " << label;
// 将(点位置,标签名)添加到数据列表dataList中
dataList << Data(value, label);
}
// 将三条线的数据逐条添加进数据表中
dataTable << dataList;
}
return dataTable;
}
QChart *ThemeWidget::createAreaChart() const
{
// 创建表格
QChart *chart = new QChart();
// 设置标题
chart->setTitle("Area chart");
// The lower series initialized to zero values
// QLineSeries: 折线图是用直线连接的一系列数据点来显示信息的。
QLineSeries *lowerSeries = 0;
QString name("Series ");
int nameIndex = 0;
for (int i(0); i < m_dataTable.count(); i++)
{
// 为该表格创建上行线型图
QLineSeries *upperSeries = new QLineSeries(chart);
for (int j(0); j < m_dataTable[i].count(); j++)
{
Data data = m_dataTable[i].at(j);
// 如果底行超过了x轴,即lowerSeries>0, 则需要加上底轴的y坐标;
if (lowerSeries)
{
const QVector& points = lowerSeries->pointsVector();
upperSeries->append(QPointF(j, points[i].y() + data.first.y()));
}
else
{
// 将某一条折线图的上行的点,一一填入upperSeries
upperSeries->append(QPointF(j, data.first.y()));
qDebug() << "x: " << j;
qDebug() << "y: " << data.first.y();
}
}
// 一条上行折线 + 一条下行折线 =》 一个区域图
QAreaSeries *area = new QAreaSeries(upperSeries, lowerSeries);
area->setName(name + QString::number(nameIndex));
nameIndex++;
// 为表格添加该区域图
chart->addSeries(area);
// 把上次的上行赋值给下一次的底行,这样就开始迭代往上
lowerSeries = upperSeries;
}
// 根据已经添加到图表中的系列为图表创建轴。之前添加到图表中的任何轴都将被删除。
chart->createDefaultAxes();
// x,y: 添加x,y轴的坐标值
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
QValueAxis *axisY = qobject_cast(chart->axes(Qt::Vertical).first());
Q_ASSERT(axisY);
// 设置Y轴坐标的精确度
axisY->setLabelFormat("%.2f ");
return chart;
}
QChart *ThemeWidget::createPieChart() const
{
QChart *chart = new QChart();
chart->setTitle("Pie chart");
QPieSeries *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();
// 设置分开的距离为0.5
slice->setExplodeDistanceFactor(0.5);
}
}
// 设置饼状图的半径为0.4,范围在:(0,1)
series->setPieSize(0.4);
// 表格添加该饼状图
chart->addSeries(series);
return chart;
}
QChart *ThemeWidget::createLineChart() const
{
//![1]
QChart *chart = new QChart();
chart->setTitle("Line chart");
//![1]
//![2]
QString name("Series ");
int nameIndex = 0;
// m_dataTable: QList
QChart *ThemeWidget::createBarChart(int valueCount) const
{
Q_UNUSED(valueCount);
QChart *chart = new QChart();
chart->setTitle("Bar chart");
// StackedBar:堆叠条形图
QStackedBarSeries *series = new QStackedBarSeries(chart);
for (int i(0); i < m_dataTable.count(); i++)
{
// 添加一种条形图barset
QBarSet *set = new QBarSet("Bar set " + QString::number(i));
for (const Data &data : m_dataTable[i])
// 添加当前的点的y坐标,到该条形图中
*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
QValueAxis *axisY = qobject_cast(chart->axes(Qt::Vertical).first());
Q_ASSERT(axisY);
axisY->setLabelFormat("%.1f ");
return chart;
}
QChart *ThemeWidget::createSplineChart() const
{
QChart *chart = new QChart();
chart->setTitle("Spline chart");
QString name("Series ");
int nameIndex = 0;
for (const DataList &list : m_dataTable)
{
// 创建一条曲线图
QSplineSeries *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
QValueAxis *axisY = qobject_cast(chart->axes(Qt::Vertical).first());
Q_ASSERT(axisY);
axisY->setLabelFormat("%.1f ");
return chart;
}
QChart *ThemeWidget::createScatterChart() const
{
// scatter chart
QChart *chart = new QChart();
chart->setTitle("Scatter chart");
QString name("Series ");
int nameIndex = 0;
for (const DataList &list : m_dataTable)
{
// 创建一条散布图
QScatterSeries *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
QValueAxis *axisY = qobject_cast(chart->axes(Qt::Vertical).first());
Q_ASSERT(axisY);
axisY->setLabelFormat("%.1f ");
return chart;
}