创建饼图拆分图
注意:这是 Charts with Widgets 馆例子的一个部分。
创建饼图拆分图
首先,让我们定义一些图表数据。
// Graph is based on data of 'Total consumption of energy increased by 10 per cent in 2010' // Statistics Finland, 13 December 2011 // http://www.stat.fi/til/ekul/2010/ekul_2010_2011-12-13_tie_001_en.html auto series1 = new QPieSeries; series1->setName("Fossil fuels"); series1->append("Oil", 353295); series1->append("Coal", 188500); series1->append("Natural gas", 148680); series1->append("Peat", 94545); auto series2 = new QPieSeries; series2->setName("Renewables"); series2->append("Wood fuels", 319663); series2->append("Hydro power", 45875); series2->append("Wind power", 1060); auto series3 = new QPieSeries; series3->setName("Others"); series3->append("Nuclear energy", 238789); series3->append("Import energy", 37802); series3->append("Other", 32441);
然后我们创建一个图表,我们将数据添加到其中。注意,这是我们自己的图表,它是从 QChart 派生的。
auto donutBreakdown = new DonutBreakdownChart; donutBreakdown->setAnimationOptions(QChart::AllAnimations); donutBreakdown->setTitle("Total consumption of energy in Finland 2010"); donutBreakdown->legend()->setAlignment(Qt::AlignRight); donutBreakdown->addBreakdownSeries(series1, Qt::red); donutBreakdown->addBreakdownSeries(series2, Qt::darkGreen); donutBreakdown->addBreakdownSeries(series3, Qt::darkBlue);
我们的图表工作原理是:在构造函数中创建一个主系列,它聚合由拆分系列提供的数据。这是中心位置的饼图。
DonutBreakdownChart::DonutBreakdownChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QChart(QChart::ChartTypeCartesian, parent, wFlags) { // create the series for main center pie m_mainSeries = new QPieSeries; m_mainSeries->setPieSize(0.7); QChart::addSeries(m_mainSeries); }
当添加拆分系列时,数据用于在主系列中创建一个切片,并且拆分系列本身用于创建一个带状图的段,使其与主系列中的相应切片对齐。
void DonutBreakdownChart::addBreakdownSeries(QPieSeries *breakdownSeries, QColor color) { QFont font("Arial", 8); // add breakdown series as a slice to center pie auto mainSlice = new DonutBreakdownMainSlice(breakdownSeries); mainSlice->setName(breakdownSeries->name()); mainSlice->setValue(breakdownSeries->sum()); m_mainSeries->append(mainSlice); // customize the slice mainSlice->setBrush(color); mainSlice->setLabelVisible(); mainSlice->setLabelColor(Qt::white); mainSlice->setLabelPosition(QPieSlice::LabelInsideHorizontal); mainSlice->setLabelFont(font); // position and customize the breakdown series breakdownSeries->setPieSize(0.8); breakdownSeries->setHoleSize(0.7); breakdownSeries->setLabelsVisible(); const auto slices = breakdownSeries->slices(); for (QPieSlice *slice : slices) { color = color.lighter(115); slice->setBrush(color); slice->setLabelFont(font); } // add the series to the chart QChart::addSeries(breakdownSeries); // recalculate breakdown donut segments recalculateAngles(); // update customize legend markers updateLegendMarkers(); }
下面是如何计算环形段的起始角度和结束角度。
void DonutBreakdownChart::recalculateAngles() { qreal angle = 0; const auto slices = m_mainSeries->slices(); for (QPieSlice *slice : slices) { QPieSeries *breakdownSeries = qobject_cast<DonutBreakdownMainSlice *>(slice)->breakdownSeries(); breakdownSeries->setPieStartAngle(angle); angle += slice->percentage() * 360.0; // full pie is 360.0 breakdownSeries->setPieEndAngle(angle); } }
图例标记已定制以显示拆分百分比。主级别切片的标记被隐藏。
void DonutBreakdownChart::updateLegendMarkers() { // go through all markers const auto allseries = series(); for (QAbstractSeries *series : allseries) { const auto markers = legend()->markers(series); for (QLegendMarker *marker : markers) { auto pieMarker = qobject_cast<QPieLegendMarker *>(marker); if (series == m_mainSeries) { // hide markers from main series pieMarker->setVisible(false); } else { // modify markers from breakdown series pieMarker->setLabel(QString("%1 %2%") .arg(pieMarker->slice()->label()) .arg(pieMarker->slice()->percentage() * 100, 0, 'f', 2)); pieMarker->setFont(QFont("Arial", 8)); } } } }
而是在主级别切片上显示标签上的百分比。
DonutBreakdownMainSlice::DonutBreakdownMainSlice(QPieSeries *breakdownSeries, QObject *parent) : QPieSlice(parent), m_breakdownSeries(breakdownSeries) { connect(this, &DonutBreakdownMainSlice::percentageChanged, this, &DonutBreakdownMainSlice::updateLabel); } ... void DonutBreakdownMainSlice::updateLabel() { setLabel(QString("%1 %2%").arg(m_name).arg(percentage() * 100, 0, 'f', 2)); }
现在我们已经定义了图表,我们可以最终创建一个 QChartView 并显示图表。
createDefaultChartView(donutBreakdown);
© 2024 The Qt Company Ltd. 本文档的贡献包括各自的版权。提供的文档是根据自由软件基金会发布的 GNU 自由文档许可版 1.3 的条款许可的。Qt 和相关标志是 The Qt Company Ltd. 在芬兰和/或世界其他国家的商标。所有其他商标均为各自所有者的财产。