Sophie

Sophie

distrib > Mageia > 7 > armv7hl > media > core-updates > by-pkgid > 845e36bb3ecce380666d628d88446962 > files > 273

qtdatavis3d5-doc-5.12.6-1.mga7.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- qmlbars.qdoc -->
  <title>Qt Quick 2 Bars Example | Qt Data Visualization 5.12.6</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.12</td><td ><a href="qtdatavisualization-index.html">Qt Data Visualization</a></td><td >Qt Quick 2 Bars Example</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right"><a href="qtdatavisualization-index.html">Qt Data Visualization | Commercial or GPLv3</a></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="#data">Data</a></li>
<li class="level1"><a href="#custom-axis-labels">Custom Axis Labels</a></li>
<li class="level1"><a href="#switching-series">Switching Series</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Qt Quick 2 Bars Example</h1>
<span class="subtitle"></span>
<!-- $$$qmlbars-brief -->
<p>Using <a href="qml-qtdatavisualization-bars3d.html">Bars3D</a> in a QML application.</p>
<!-- @@@qmlbars -->
<!-- $$$qmlbars-description -->
<div class="descr"> <a name="details"></a>
<p>The Qt Quick 2 bars example shows how to make a simple 3D bar graph using <a href="qml-qtdatavisualization-bars3d.html">Bars3D</a> and Qt Quick 2.</p>
<p class="centerAlign"><img src="images/qmlbars-example.png" alt="" /></p><p>The interesting thing about this example is switching series and displaying more than one series at once. We'll concentrate on those and skip explaining the basic <a href="qml-qtdatavisualization-bars3d.html">Bars3D</a> functionality - for more detailed QML example documentation, see <a href="qtdatavisualization-qmlscatter-example.html">Qt Quick 2 Scatter Example</a>.</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="data"></a>
<h2 id="data">Data</h2>
<p>The example data is monthly income and expenses of a fictional company over several years. The data is defined in a list model in <code>Data.qml</code> like this:</p>
<pre class="qml">

  ListModel {
      id: dataModel
      ListElement{ timestamp: "2006-01"; expenses: "-4";  income: "5" }
      ListElement{ timestamp: "2006-02"; expenses: "-5";  income: "6" }
      ListElement{ timestamp: "2006-03"; expenses: "-7";  income: "4" }
      ...

</pre>
<p>Each data item has three roles: timestamp, income, and expenses. The timestamp value is in format: <code>&lt;four digit year&gt;-&lt;two digit month&gt;</code>. Years and months are natural to map to rows and columns of a bar chart, but we can only show either income or expenses as the value.</p>
<p>Now we need to add the data to the <a href="qml-qtdatavisualization-bars3d.html">Bars3D</a> graph. We will create two <a href="qml-qtdatavisualization-bar3dseries.html">Bar3DSeries</a> inside it, starting with a series for the income:</p>
<pre class="qml">

  Bar3DSeries {
      id: barSeries
      itemLabelFormat: "Income, @colLabel, @rowLabel: @valueLabel"
      baseGradient: barGradient

      ItemModelBarDataProxy {
          id: modelProxy
          itemModel: graphData.model
          rowRole: "timestamp"
          columnRole: "timestamp"
          valueRole: "income"
          rowRolePattern: /^(\d\d\d\d).*$/
          columnRolePattern: /^.*-(\d\d)$/
          rowRoleReplace: "\\1"
          columnRoleReplace: "\\1"
          multiMatchBehavior: ItemModelBarDataProxy.MMBCumulative
      }
      ...

</pre>
<p>The data is attached to the <code>itemModel</code> property of the <a href="qml-qtdatavisualization-itemmodelbardataproxy.html">ItemModelBarDataProxy</a> inside the series. For <code>valueRole</code> we simply specify the <code>income</code> field, as it contains the value we want, but getting the years and months is a bit more complicated, since they are both found in the same field. To extract those values, we specify the <code>timestamp</code> field for both <code>rowRole</code> and <code>columnRole</code>, and additionally specify a search pattern and a replace rule for those roles to extract the correct portion of the field contents for each role. The search pattern is a normal JavaScript regular expression and the replace rule specifies what the field content that matches the regular expression is replaced with. In this case we want to replace the entire field content with just the year or the month, which is the first captured substring for both rows and columns. For more information how the replace using regular expressions works, see QString::replace(const QRegExp &amp;rx, const QString &amp;after) function documentation.</p>
<p>The <code>multiMatchBehavior</code> property specifies what to do in case multiple item model items match the same row/column combination. In this case we want to add their values together. This property has no effect when we are showing values for each month, as there are no duplicate months in our item model, but it becomes relevant later when we want to show the yearly totals.</p>
<p>Then we add another series for the expenses:</p>
<pre class="qml">

  Bar3DSeries {
      id: secondarySeries
      visible: false
      itemLabelFormat: "Expenses, @colLabel, @rowLabel: -@valueLabel"
      baseGradient: secondaryGradient

      ItemModelBarDataProxy {
          id: secondaryProxy
          itemModel: graphData.model
          rowRole: "timestamp"
          columnRole: "timestamp"
          valueRole: "expenses"
          rowRolePattern: /^(\d\d\d\d).*$/
          columnRolePattern: /^.*-(\d\d)$/
          valueRolePattern: /-/
          rowRoleReplace: "\\1"
          columnRoleReplace: "\\1"
          multiMatchBehavior: ItemModelBarDataProxy.MMBCumulative
      }
      ...

</pre>
<p>The model contains expenses as negative values, but we want to show them as positive bars, so that we can easily compare them to income bars. We use <code>valueRolePattern</code> to remove the minus sign to achieve this. No replacement string needs to be specified as the default replacement is an empty string.</p>
<p>We use the <code>visible</code> property of the series to hide the second series for now.</p>
<a name="custom-axis-labels"></a>
<h2 id="custom-axis-labels">Custom Axis Labels</h2>
<p>One interesting tidbit about axes is that we redefine the category labels for column axis in <code>Axes.qml</code>. This is done because the data contains numbers for months, which we don't want to use for our column labels:</p>
<pre class="qml">

  CategoryAxis3D {
      id: columnAxis
      labels: ["January", "February", "March", "April", "May", "June",
          "July", "August", "September", "October", "November", "December"]
      labelAutoRotation: 30
  }

</pre>
<p>We also set automatic axis label rotation to make axis labels more readable at low camera angles.</p>
<a name="switching-series"></a>
<h2 id="switching-series">Switching Series</h2>
<p>In the <code>main.qml</code>, we set up the graph and various UI elements. There are three interesting code blocks we want to highlight here. The first one shows how to change the visualized data between income, expenses, and both, by simply changing visibility of the two series:</p>
<pre class="qml">

  onClicked: {
      if (text === "Show Expenses") {
          barSeries.visible = false
          secondarySeries.visible = true
          barGraph.valueAxis.labelFormat = "-%.2f M\u20AC"
          secondarySeries.itemLabelFormat = "Expenses, @colLabel, @rowLabel: @valueLabel"
          text = "Show Both"
      } else if (text === "Show Both") {
          barSeries.visible = true
          barGraph.valueAxis.labelFormat = "%.2f M\u20AC"
          secondarySeries.itemLabelFormat = "Expenses, @colLabel, @rowLabel: -@valueLabel"
          text = "Show Income"
      } else { // text === "Show Income"
          secondarySeries.visible = false
          text = "Show Expenses"
      }
  }

</pre>
<p>The axis label format and item selection label formats are tweaked to get the negative sign showing properly for expenses, which were actually resolved as positive values.</p>
<p>The second interesting block is where we change the visualized data by adjusting the proxy propertes:</p>
<pre class="qml">

  onClicked: {
      if (text === "Show yearly totals") {
          modelProxy.autoRowCategories = true
          secondaryProxy.autoRowCategories = true
          modelProxy.columnRolePattern = /^.*$/
          secondaryProxy.columnRolePattern = /^.*$/
          graphAxes.value.autoAdjustRange = true
          barGraph.columnAxis = graphAxes.total
          text = "Show all years"
      } else if (text === "Show all years") {
          modelProxy.autoRowCategories = true
          secondaryProxy.autoRowCategories = true
          modelProxy.columnRolePattern = /^.*-(\d\d)$/
          secondaryProxy.columnRolePattern = /^.*-(\d\d)$/
          graphAxes.value.min = 0
          graphAxes.value.max = 35
          barGraph.columnAxis = graphAxes.column
          text = "Show 2010 - 2012"
      } else { // text === "Show 2010 - 2012"
          // Explicitly defining row categories, since we do not want to show data for
          // all years in the model, just for the selected ones.
          modelProxy.autoRowCategories = false
          secondaryProxy.autoRowCategories = false
          modelProxy.rowCategories = ["2010", "2011", "2012"]
          secondaryProxy.rowCategories = ["2010", "2011", "2012"]
          text = "Show yearly totals"
      }
  }

</pre>
<p>To show yearly totals, we need to combine the twelve months of each year into a single bar. We achieve this by specifying a <code>columnRolePattern</code> that matches all model items. That way the data proxy will only have a single column. The cumulative <code>multiMatchBehavior</code> we specified earlier for the proxy becomes relevant now, causing the values of all twelve months of each year to be added up into a single bar.</p>
<p>To show just a subset of years, we set <code>autoRowCategories</code> to false on the <a href="qml-qtdatavisualization-itemmodelbardataproxy.html">ItemModelBarDataProxy</a> item and define the row categories explicitly. This way, only the items in specified row categories are visualized.</p>
<p>The third interesting block shows how to get the row and column index of an item if you know the row and column values by using <a href="qml-qtdatavisualization-itemmodelbardataproxy.html">ItemModelBarDataProxy</a> methods <code>rowCategoryIndex()</code> and <code>columnCategoryIndex()</code>:</p>
<pre class="qml">

  onCurrentRowChanged: {
      var timestamp = graphData.model.get(currentRow).timestamp
      var pattern = /(\d\d\d\d)-(\d\d)/
      var matches = pattern.exec(timestamp)
      var rowIndex = modelProxy.rowCategoryIndex(matches[1])
      var colIndex
      if (barGraph.columnAxis === graphAxes.total)
          colIndex = 0 // Just one column when showing yearly totals
      else
          colIndex = modelProxy.columnCategoryIndex(matches[2])
      if (selectedSeries.visible)
          mainview.selectedSeries.selectedBar = Qt.point(rowIndex, colIndex)
      else if (barSeries.visible)
          barSeries.selectedBar = Qt.point(rowIndex, colIndex)
      else
          secondarySeries.selectedBar = Qt.point(rowIndex, colIndex)
  }

</pre>
<p>Files:</p>
<ul>
<li><a href="qtdatavisualization-qmlbars-main-cpp.html">qmlbars/main.cpp</a></li>
<li><a href="qtdatavisualization-qmlbars-qml-qmlbars-axes-qml.html">qmlbars/qml/qmlbars/Axes.qml</a></li>
<li><a href="qtdatavisualization-qmlbars-qml-qmlbars-data-qml.html">qmlbars/qml/qmlbars/Data.qml</a></li>
<li><a href="qtdatavisualization-qmlbars-qml-qmlbars-main-qml.html">qmlbars/qml/qmlbars/main.qml</a></li>
<li><a href="qtdatavisualization-qmlbars-qmlbars-pro.html">qmlbars/qmlbars.pro</a></li>
<li><a href="qtdatavisualization-qmlbars-qmlbars-qrc.html">qmlbars/qmlbars.qrc</a></li>
</ul>
</div>
<!-- @@@qmlbars -->
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2019 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>