Qt 5.7 | Qt Charts | OpenGL Accelerated Series Example | datasource.cpp Example File

Qt 5.7.1 Reference Documentation

# datasource.cpp Example File

openglseries/datasource.cpp

      /****************************************************************************
      **
      ** Copyright (C) 2016 The Qt Company Ltd.
      ** Contact: https://www.qt.io/licensing/
      **
      ** This file is part of the Qt Charts module of the Qt Toolkit.
      **
      ** $QT_BEGIN_LICENSE:GPL$
      ** Commercial License Usage
      ** Licensees holding valid commercial Qt licenses may use this file in
      ** accordance with the commercial license agreement provided with the
      ** Software or, alternatively, in accordance with the terms contained in
      ** a written agreement between you and The Qt Company. For licensing terms
      ** and conditions see https://www.qt.io/terms-conditions. For further
      ** information use the contact form at https://www.qt.io/contact-us.
      **
      ** GNU General Public License Usage
      ** Alternatively, this file may be used under the terms of the GNU
      ** General Public License version 3 or (at your option) any later version
      ** approved by the KDE Free Qt Foundation. The licenses are as published by
      ** the Free Software Foundation and appearing in the file LICENSE.GPL3
      ** included in the packaging of this file. Please review the following
      ** information to ensure the GNU General Public License requirements will
      ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
      **
      ** $QT_END_LICENSE$
      **
      ****************************************************************************/

      #include "datasource.h"
      #include <QtCore/QtMath>

      QT_CHARTS_USE_NAMESPACE

      DataSource::DataSource(QObject *parent) :
          QObject(parent),
          m_index(-1)
      {
          generateData(0, 0, 0);
      }

      void DataSource::update(QAbstractSeries *series, int seriesIndex)
      {
          if (series) {
              QXYSeries *xySeries = static_cast<QXYSeries *>(series);
              const QVector<QVector<QPointF> > &seriesData = m_data.at(seriesIndex);
              if (seriesIndex == 0)
                  m_index++;
              if (m_index > seriesData.count() - 1)
                  m_index = 0;

              QVector<QPointF> points = seriesData.at(m_index);
              // Use replace instead of clear + append, it's optimized for performance
              xySeries->replace(points);
          }
      }

      void DataSource::handleSceneChanged()
      {
          m_dataUpdater.start();
      }

      void DataSource::updateAllSeries()
      {
          static int frameCount = 0;
          static QString labelText = QStringLiteral("FPS: %1");

          for (int i = 0; i < m_seriesList.size(); i++)
              update(m_seriesList[i], i);

          frameCount++;
          int elapsed = m_fpsTimer.elapsed();
          if (elapsed >= 1000) {
              elapsed = m_fpsTimer.restart();
              qreal fps = qreal(0.1 * int(10000.0 * (qreal(frameCount) / qreal(elapsed))));
              m_fpsLabel->setText(labelText.arg(QString::number(fps, 'f', 1)));
              m_fpsLabel->adjustSize();
              frameCount = 0;
          }
      }

      void DataSource::startUpdates(const QList<QXYSeries *> &seriesList, QLabel *fpsLabel)
      {
          m_seriesList = seriesList;
          m_fpsLabel = fpsLabel;

          m_dataUpdater.setInterval(0);
          m_dataUpdater.setSingleShot(true);
          QObject::connect(&m_dataUpdater, &QTimer::timeout,
                           this, &DataSource::updateAllSeries);

          m_fpsTimer.start();
          updateAllSeries();
      }

      void DataSource::generateData(int seriesCount, int rowCount, int colCount)
      {
          // Remove previous data
          foreach (QVector<QVector<QPointF> > seriesData, m_data) {
              foreach (QVector<QPointF> row, seriesData)
                  row.clear();
          }

          m_data.clear();

          qreal xAdjustment = 20.0 / (colCount * rowCount);
          qreal yMultiplier = 3.0 / qreal(seriesCount);

          // Append the new data depending on the type
          for (int k(0); k < seriesCount; k++) {
              QVector<QVector<QPointF> > seriesData;
              qreal height = qreal(k) * (10.0 / qreal(seriesCount)) + 0.3;
              for (int i(0); i < rowCount; i++) {
                  QVector<QPointF> points;
                  points.reserve(colCount);
                  for (int j(0); j < colCount; j++) {
                      qreal x(0);
                      qreal y(0);
                      // data with sin + random component
                      y = height + (yMultiplier * qSin(3.14159265358979 / 50 * j)
                                    + (yMultiplier * (qreal) rand() / (qreal) RAND_MAX));
                      // 0.000001 added to make values logaxis compatible
                      x = 0.000001 + 20.0 * (qreal(j) / qreal(colCount)) + (xAdjustment * qreal(i));
                      points.append(QPointF(x, y));
                  }
                  seriesData.append(points);
              }
              m_data.append(seriesData);
          }
      }