<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- examples-donutbreakdown.qdoc --> <title>Donut Chart Breakdown Example | Qt Charts 5.9</title> <link rel="stylesheet" type="text/css" href="style/offline-simple.css" /> <script type="text/javascript"> document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css"); // loading style sheet breaks anchors that were jumped to before // so force jumping to anchor again setTimeout(function() { var anchor = location.hash; // need to jump to different anchor first (e.g. none) location.hash = "#"; setTimeout(function() { location.hash = anchor; }, 0); }, 0); </script> </head> <body> <div class="header" id="qtdocheader"> <div class="main"> <div class="main-rounded"> <div class="navigationbar"> <table><tr> <td >Qt 5.9</td><td ><a href="qtcharts-index.html">Qt Charts</a></td><td ><a href="qtcharts-examples.html">Qt Charts Examples</a></td><td >Donut Chart Breakdown Example</td></tr></table><table class="buildversion"><tr> <td id="buildversion" width="100%" align="right">Qt 5.9.4 Reference Documentation</td> </tr></table> </div> </div> <div class="content"> <div class="line"> <div class="content mainContent"> <div class="sidebar"> <div class="toc"> <h3><a name="toc">Contents</a></h3> <ul> <li class="level1"><a href="#running-the-example">Running the Example</a></li> <li class="level1"><a href="#creating-donut-breakdown-charts">Creating Donut Breakdown Charts</a></li> </ul> </div> <div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title">Donut Chart Breakdown Example</h1> <span class="subtitle"></span> <!-- $$$donutbreakdown-description --> <div class="descr"> <a name="details"></a> <p class="centerAlign"><img src="images/examples_donutbreakdown.png" alt="" /></p><a name="running-the-example"></a> <h2 id="running-the-example">Running the Example</h2> <p>To run the example from Qt Creator, open the <b>Welcome</b> mode and select the example from <b>Examples</b>. For more information, visit Building and Running an Example.</p> <a name="creating-donut-breakdown-charts"></a> <h2 id="creating-donut-breakdown-charts">Creating Donut Breakdown Charts</h2> <p>Let's start by defining some data for the chart.</p> <pre class="cpp"> <span class="comment">// Graph is based on data of 'Total consumption of energy increased by 10 per cent in 2010'</span> <span class="comment">// Statistics Finland, 13 December 2011</span> <span class="comment">// http://www.stat.fi/til/ekul/2010/ekul_2010_2011-12-13_tie_001_en.html</span> <span class="type"><a href="qpieseries.html">QPieSeries</a></span> <span class="operator">*</span>series1 <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpieseries.html">QPieSeries</a></span>(); series1<span class="operator">-</span><span class="operator">></span>setName(<span class="string">"Fossil fuels"</span>); series1<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Oil"</span><span class="operator">,</span> <span class="number">353295</span>); series1<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Coal"</span><span class="operator">,</span> <span class="number">188500</span>); series1<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Natural gas"</span><span class="operator">,</span> <span class="number">148680</span>); series1<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Peat"</span><span class="operator">,</span> <span class="number">94545</span>); <span class="type"><a href="qpieseries.html">QPieSeries</a></span> <span class="operator">*</span>series2 <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpieseries.html">QPieSeries</a></span>(); series2<span class="operator">-</span><span class="operator">></span>setName(<span class="string">"Renewables"</span>); series2<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Wood fuels"</span><span class="operator">,</span> <span class="number">319663</span>); series2<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Hydro power"</span><span class="operator">,</span> <span class="number">45875</span>); series2<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Wind power"</span><span class="operator">,</span> <span class="number">1060</span>); <span class="type"><a href="qpieseries.html">QPieSeries</a></span> <span class="operator">*</span>series3 <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpieseries.html">QPieSeries</a></span>(); series3<span class="operator">-</span><span class="operator">></span>setName(<span class="string">"Others"</span>); series3<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Nuclear energy"</span><span class="operator">,</span> <span class="number">238789</span>); series3<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Import energy"</span><span class="operator">,</span> <span class="number">37802</span>); series3<span class="operator">-</span><span class="operator">></span>append(<span class="string">"Other"</span><span class="operator">,</span> <span class="number">32441</span>); </pre> <p>Then we create a chart where we add the data. Note that this is our own chart derived from <a href="qchart.html">QChart</a>.</p> <pre class="cpp"> DonutBreakdownChart <span class="operator">*</span>donutBreakdown <span class="operator">=</span> <span class="keyword">new</span> DonutBreakdownChart(); donutBreakdown<span class="operator">-</span><span class="operator">></span>setAnimationOptions(<span class="type"><a href="qchart.html">QChart</a></span><span class="operator">::</span>AllAnimations); donutBreakdown<span class="operator">-</span><span class="operator">></span>setTitle(<span class="string">"Total consumption of energy in Finland 2010"</span>); donutBreakdown<span class="operator">-</span><span class="operator">></span>legend()<span class="operator">-</span><span class="operator">></span>setAlignment(<span class="type">Qt</span><span class="operator">::</span>AlignRight); donutBreakdown<span class="operator">-</span><span class="operator">></span>addBreakdownSeries(series1<span class="operator">,</span> <span class="type">Qt</span><span class="operator">::</span>red); donutBreakdown<span class="operator">-</span><span class="operator">></span>addBreakdownSeries(series2<span class="operator">,</span> <span class="type">Qt</span><span class="operator">::</span>darkGreen); donutBreakdown<span class="operator">-</span><span class="operator">></span>addBreakdownSeries(series3<span class="operator">,</span> <span class="type">Qt</span><span class="operator">::</span>darkBlue); </pre> <p>Our own chart works in such a way that we create a main series in the constructor we create a main series, which aggregates the data provided by the breakdown series. This is the piechart in the center.</p> <pre class="cpp"> DonutBreakdownChart<span class="operator">::</span>DonutBreakdownChart(<span class="type">QGraphicsItem</span> <span class="operator">*</span>parent<span class="operator">,</span> <span class="type">Qt</span><span class="operator">::</span>WindowFlags wFlags) : <span class="type"><a href="qchart.html">QChart</a></span>(<span class="type"><a href="qchart.html">QChart</a></span><span class="operator">::</span>ChartTypeCartesian<span class="operator">,</span> parent<span class="operator">,</span> wFlags) { <span class="comment">// create the series for main center pie</span> m_mainSeries <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpieseries.html">QPieSeries</a></span>(); m_mainSeries<span class="operator">-</span><span class="operator">></span>setPieSize(<span class="number">0.7</span>); <span class="type"><a href="qchart.html">QChart</a></span><span class="operator">::</span>addSeries(m_mainSeries); } </pre> <p>When a breakdown series is added the data is used to create a slice in the main series and the breakdown series itself is used to create a segment of a donut positioned so that it is aligned with the corresponding slice in the main series.</p> <pre class="cpp"> <span class="type">void</span> DonutBreakdownChart<span class="operator">::</span>addBreakdownSeries(<span class="type"><a href="qpieseries.html">QPieSeries</a></span> <span class="operator">*</span>breakdownSeries<span class="operator">,</span> <span class="type">QColor</span> color) { <span class="type">QFont</span> font(<span class="string">"Arial"</span><span class="operator">,</span> <span class="number">8</span>); <span class="comment">// add breakdown series as a slice to center pie</span> MainSlice <span class="operator">*</span>mainSlice <span class="operator">=</span> <span class="keyword">new</span> MainSlice(breakdownSeries); mainSlice<span class="operator">-</span><span class="operator">></span>setName(breakdownSeries<span class="operator">-</span><span class="operator">></span>name()); mainSlice<span class="operator">-</span><span class="operator">></span>setValue(breakdownSeries<span class="operator">-</span><span class="operator">></span>sum()); m_mainSeries<span class="operator">-</span><span class="operator">></span>append(mainSlice); <span class="comment">// customize the slice</span> mainSlice<span class="operator">-</span><span class="operator">></span>setBrush(color); mainSlice<span class="operator">-</span><span class="operator">></span>setLabelVisible(); mainSlice<span class="operator">-</span><span class="operator">></span>setLabelColor(<span class="type">Qt</span><span class="operator">::</span>white); mainSlice<span class="operator">-</span><span class="operator">></span>setLabelPosition(<span class="type"><a href="qpieslice.html">QPieSlice</a></span><span class="operator">::</span>LabelInsideHorizontal); mainSlice<span class="operator">-</span><span class="operator">></span>setLabelFont(font); <span class="comment">// position and customize the breakdown series</span> breakdownSeries<span class="operator">-</span><span class="operator">></span>setPieSize(<span class="number">0.8</span>); breakdownSeries<span class="operator">-</span><span class="operator">></span>setHoleSize(<span class="number">0.7</span>); breakdownSeries<span class="operator">-</span><span class="operator">></span>setLabelsVisible(); <span class="keyword">const</span> <span class="keyword">auto</span> slices <span class="operator">=</span> breakdownSeries<span class="operator">-</span><span class="operator">></span>slices(); <span class="keyword">for</span> (<span class="type"><a href="qpieslice.html">QPieSlice</a></span> <span class="operator">*</span>slice : slices) { color <span class="operator">=</span> color<span class="operator">.</span>lighter(<span class="number">115</span>); slice<span class="operator">-</span><span class="operator">></span>setBrush(color); slice<span class="operator">-</span><span class="operator">></span>setLabelFont(font); } <span class="comment">// add the series to the chart</span> <span class="type"><a href="qchart.html">QChart</a></span><span class="operator">::</span>addSeries(breakdownSeries); <span class="comment">// recalculate breakdown donut segments</span> recalculateAngles(); <span class="comment">// update customize legend markers</span> updateLegendMarkers(); } </pre> <p>Here's how the start and end angles for the donut segments are calculated.</p> <pre class="cpp"> <span class="type">void</span> DonutBreakdownChart<span class="operator">::</span>recalculateAngles() { <span class="type">qreal</span> angle <span class="operator">=</span> <span class="number">0</span>; <span class="keyword">const</span> <span class="keyword">auto</span> slices <span class="operator">=</span> m_mainSeries<span class="operator">-</span><span class="operator">></span>slices(); <span class="keyword">for</span> (<span class="type"><a href="qpieslice.html">QPieSlice</a></span> <span class="operator">*</span>slice : slices) { <span class="type"><a href="qpieseries.html">QPieSeries</a></span> <span class="operator">*</span>breakdownSeries <span class="operator">=</span> qobject_cast<span class="operator"><</span>MainSlice <span class="operator">*</span><span class="operator">></span>(slice)<span class="operator">-</span><span class="operator">></span>breakdownSeries(); breakdownSeries<span class="operator">-</span><span class="operator">></span>setPieStartAngle(angle); angle <span class="operator">+</span><span class="operator">=</span> slice<span class="operator">-</span><span class="operator">></span>percentage() <span class="operator">*</span> <span class="number">360.0</span>; <span class="comment">// full pie is 360.0</span> breakdownSeries<span class="operator">-</span><span class="operator">></span>setPieEndAngle(angle); } } </pre> <p>The legend markers are customized to show the breakdown percentage. The markers for the main level slices are hidden.</p> <pre class="cpp"> <span class="type">void</span> DonutBreakdownChart<span class="operator">::</span>updateLegendMarkers() { <span class="comment">// go through all markers</span> <span class="keyword">const</span> <span class="keyword">auto</span> allseries <span class="operator">=</span> series(); <span class="keyword">for</span> (<span class="type"><a href="qabstractseries.html">QAbstractSeries</a></span> <span class="operator">*</span>series : allseries) { <span class="keyword">const</span> <span class="keyword">auto</span> markers <span class="operator">=</span> legend()<span class="operator">-</span><span class="operator">></span>markers(series); <span class="keyword">for</span> (<span class="type"><a href="qlegendmarker.html">QLegendMarker</a></span> <span class="operator">*</span>marker : markers) { <span class="type"><a href="qpielegendmarker.html">QPieLegendMarker</a></span> <span class="operator">*</span>pieMarker <span class="operator">=</span> qobject_cast<span class="operator"><</span><span class="type"><a href="qpielegendmarker.html">QPieLegendMarker</a></span> <span class="operator">*</span><span class="operator">></span>(marker); <span class="keyword">if</span> (series <span class="operator">=</span><span class="operator">=</span> m_mainSeries) { <span class="comment">// hide markers from main series</span> pieMarker<span class="operator">-</span><span class="operator">></span>setVisible(<span class="keyword">false</span>); } <span class="keyword">else</span> { <span class="comment">// modify markers from breakdown series</span> pieMarker<span class="operator">-</span><span class="operator">></span>setLabel(<span class="type">QString</span>(<span class="string">"%1 %2%"</span>) <span class="operator">.</span>arg(pieMarker<span class="operator">-</span><span class="operator">></span>slice()<span class="operator">-</span><span class="operator">></span>label()) <span class="operator">.</span>arg(pieMarker<span class="operator">-</span><span class="operator">></span>slice()<span class="operator">-</span><span class="operator">></span>percentage() <span class="operator">*</span> <span class="number">100</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="char">'f'</span><span class="operator">,</span> <span class="number">2</span>)); pieMarker<span class="operator">-</span><span class="operator">></span>setFont(<span class="type">QFont</span>(<span class="string">"Arial"</span><span class="operator">,</span> <span class="number">8</span>)); } } } } </pre> <p>Instead the main level slices show the percentage on the label.</p> <pre class="cpp"> MainSlice<span class="operator">::</span>MainSlice(<span class="type"><a href="qpieseries.html">QPieSeries</a></span> <span class="operator">*</span>breakdownSeries<span class="operator">,</span> <span class="type">QObject</span> <span class="operator">*</span>parent) : <span class="type"><a href="qpieslice.html">QPieSlice</a></span>(parent)<span class="operator">,</span> m_breakdownSeries(breakdownSeries) { connect(<span class="keyword">this</span><span class="operator">,</span> <span class="operator">&</span>MainSlice<span class="operator">::</span>percentageChanged<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> <span class="operator">&</span>MainSlice<span class="operator">::</span>updateLabel); } <span class="type">void</span> MainSlice<span class="operator">::</span>updateLabel() { <span class="keyword">this</span><span class="operator">-</span><span class="operator">></span>setLabel(<span class="type">QString</span>(<span class="string">"%1 %2%"</span>)<span class="operator">.</span>arg(m_name)<span class="operator">.</span>arg(percentage() <span class="operator">*</span> <span class="number">100</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="char">'f'</span><span class="operator">,</span> <span class="number">2</span>)); } </pre> <p>Now that we have our chart defined, we can finally create a <a href="qchartview.html">QChartView</a> and show the chart.</p> <pre class="cpp"> <span class="type">QMainWindow</span> window; <span class="type"><a href="qchartview.html">QChartView</a></span> <span class="operator">*</span>chartView <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qchartview.html">QChartView</a></span>(donutBreakdown); chartView<span class="operator">-</span><span class="operator">></span>setRenderHint(<span class="type">QPainter</span><span class="operator">::</span>Antialiasing); window<span class="operator">.</span>setCentralWidget(chartView); window<span class="operator">.</span>resize(<span class="number">800</span><span class="operator">,</span> <span class="number">500</span>); window<span class="operator">.</span>show(); </pre> <p>Files:</p> <ul> <li><a href="qtcharts-donutbreakdown-donutbreakdownchart-cpp.html">donutbreakdown/donutbreakdownchart.cpp</a></li> <li><a href="qtcharts-donutbreakdown-donutbreakdownchart-h.html">donutbreakdown/donutbreakdownchart.h</a></li> <li><a href="qtcharts-donutbreakdown-mainslice-cpp.html">donutbreakdown/mainslice.cpp</a></li> <li><a href="qtcharts-donutbreakdown-mainslice-h.html">donutbreakdown/mainslice.h</a></li> <li><a href="qtcharts-donutbreakdown-main-cpp.html">donutbreakdown/main.cpp</a></li> <li><a href="qtcharts-donutbreakdown-donutbreakdown-pro.html">donutbreakdown/donutbreakdown.pro</a></li> </ul> </div> <!-- @@@donutbreakdown --> </div> </div> </div> </div> </div> <div class="footer"> <p> <acronym title="Copyright">©</acronym> 2017 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners.<br> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br> 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. </p> </div> </body> </html>