创建方框-圆iskers 图表
注: 这是 "带 Widgets 图库的图表"示例的一部分。
该示例还展示了如何从文件中读取非连续数据、排列数据并找出绘制箱形须线图所需的中位数。
为了显示两家公司的份额偏差,我们首先创建了两个QBoxPlotSeries 来处理月度数据。
auto acmeSeries = new QBoxPlotSeries; acmeSeries->setName("Acme Ltd"); auto boxWhiskSeries = new QBoxPlotSeries; boxWhiskSeries->setName("BoxWhisk Inc");
QFile 该类用于打开保存非连续数据的文本文件。BoxDataReader 是一个辅助类,用于读取文本文件并从数据中找出极值和中值。稍后将对 BoxDataReader 进行详细说明。方法 readBox 读取数值并将其设置为 项,该方法将返回给调用者。返回的 项被添加到序列中。QBoxSet QBoxSet
QFile acmeData(":boxplot_a"); const QString errorTemplate = QStringLiteral("Failed to load '%1' file."); if (!acmeData.open(QIODevice::ReadOnly | QIODevice::Text)) { m_loadError = errorTemplate.arg(acmeData.fileName()); return false; } BoxPlotDataReader dataReader(&acmeData); while (!dataReader.atEnd()) { QBoxSet *set = dataReader.readBox(); if (set) acmeSeries->append(set); }
本节将打开第二个文件,以读取第二家公司的数据。
QFile boxwhiskData(":boxplot_b"); if (!boxwhiskData.open(QIODevice::ReadOnly | QIODevice::Text)) { m_loadError = errorTemplate.arg(acmeData.fileName()); return false; } dataReader.readFile(&boxwhiskData); while (!dataReader.atEnd()) { QBoxSet *set = dataReader.readBox(); if (set) boxWhiskSeries->append(set); }
在此代码片段中,将创建一个新的QChart 实例,并将先前创建的系列添加到该实例中。同时还定义了标题,并将动画设置为 SeriesAnimation。
auto chart = new QChart; chart->addSeries(acmeSeries); chart->addSeries(boxWhiskSeries); chart->setTitle("Acme Ltd. and BoxWhisk Inc. share deviation in 2012"); chart->setAnimationOptions(QChart::SeriesAnimations);
在此,我们要求图表为我们的演示创建默认坐标轴。我们还通过查询图表中坐标轴的指针来设置垂直坐标轴的范围,然后设置该坐标轴的最小和最大值。
chart->createDefaultAxes(); chart->axes(Qt::Vertical).first()->setMin(15.0); chart->axes(Qt::Horizontal).first()->setMax(34.0);
在本节中,我们将图例设置为可见,并将其置于图表底部。
chart->legend()->setVisible(true); chart->legend()->setAlignment(Qt::AlignBottom);
最后,我们将图表添加到视图中。我们还将打开 chartView 的抗锯齿功能。
createDefaultChartView(chart);
图表就可以显示了。
这里将详细解释 readBox 方法。
首先,从文件中读取一行,以 # 开头的行会被视为注释行,因此会被拒绝。
QString line = m_textStream.readLine(); if (line.startsWith("#")) return nullptr;
在该文件中,数据按数字、空格、数字或空格排列。在此代码段中,该行被分割成单个数字字符串,存储在QStringList 中。
QStringList strList = line.split(QLatin1Char(' '), Qt::SkipEmptyParts);
sortedList 将按连续顺序保存数字,在本代码段中,我们将展示如何做到这一点。首先,清空 sortedList,然后从 strList 中读取数字,并以双倍格式存储到 sortedList 中。qSort 方法将 sortedList 从最小的开始按连续顺序排列。
m_sortedList.clear(); for (int i = 1; i < strList.count(); i++) m_sortedList.append(strList.at(i).toDouble()); std::sort(m_sortedList.begin(), m_sortedList.end());
下面的代码示例展示了如何从连续数据中选择极值和中值。首先创建一个新的QBoxSet 。下极值和上极值的选择很简单,它们只是排序列表中的第一个和最后一个项目。对于中位数,我们使用一个辅助方法 findMedian(稍后将解释)。对于上半部分的中位数,如果数字的数量是偶数或不等,我们需要调整开始数字。下半部分的尾数自然来自四舍五入。
auto box = new QBoxSet(strList.first()); box->setValue(QBoxSet::LowerExtreme, m_sortedList.first()); box->setValue(QBoxSet::UpperExtreme, m_sortedList.last()); box->setValue(QBoxSet::Median, findMedian(0, count)); box->setValue(QBoxSet::LowerQuartile, findMedian(0, count / 2)); box->setValue(QBoxSet::UpperQuartile, findMedian(count / 2 + (count % 2), count));
下面是查找中位数方法的代码示例。如果数字的数量不均匀,我们会从中间选取一个数字。对于偶数,我们从中间选取两个数字,然后计算平均值。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.