Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML ChartView lineseries with "blank" points
Forum Updated to NodeBB v4.3 + New Features

QML ChartView lineseries with "blank" points

Scheduled Pinned Locked Moved Solved QML and Qt Quick
2 Posts 1 Posters 1.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    davidesalvetti
    wrote on last edited by
    #1

    Hi all,

    I recently started working with qml and in particular with ChartView. I'm developing an app where I need to show a ChartView object with some LineSeries inside. I said "some LineSeries" but the end result should looks like a single line, the problem is that this single line has to be composed by different colours. It is certainly easier to understand with an image:
    Cattura.PNG

    So, here I have two lines, but I would like them to look like one. To do this, I would like to know if there is a way to tell the QXYSeries Object to insert something like a blank point, so that I don't have the straight lines, because they're something that des not represent the line I want to draw. The correct line should look like the following one, but with two different color:
    Catturad.PNG

    This is my current code:
    MyChartView.qml

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    import QtCharts 2.15
    
    ChartView {
        id: chartId
    
        plotArea: Qt.rect(5, 5, chartId.width - 5, chartId.height - 5)
        margins { top: 10; bottom: 10; left: 10; right: 10; }
    
        plotAreaColor: "#000020"
        backgroundColor: "white"
        legend.visible: false
        antialiasing: true
    
        ValueAxis {
            id: yaxis
            min: 0
            max: 100
    
            labelsVisible: false
            gridVisible: false
            minorGridVisible: false
            visible: false
        }
    
        ValueAxis {
            id: xaxis
            min: 0
            max: 100
    
            labelsVisible: false
            gridVisible: false
            minorGridVisible: false
            visible: false
        }
    
        LineSeries {
            id: firstId
            axisX: xaxis
            axisY: yaxis
            useOpenGL: true
            name: "firstId"
            color: "red"
        }
    
        LineSeries {
            id: secondId
            axisX: xaxis
            axisY: yaxis
            useOpenGL: true
    
            name: "secondId"
            color: "white"
        }
    }
    

    cpp

    #include "chart.h"
    
    Chart::Chart(QObject *parent) : BaseChart(parent)
    {
    
    }
    
    void Chart::createDataPoint()
    {
    //this function popolates the firstId and secondId QVector<PointF>
        emit updateData();
    }
    
    void Chart::update(QAbstractSeries *series)
    {
        if (series) {
            QXYSeries *xySeries = static_cast<QXYSeries *>(series);
    
            if (xySeries->name() == "firstId")
                xySeries->replace(firstId);
            else
                xySeries->replace(secondId);
        }
    }
    

    .h

    #include <QObject>
    #include <QtCharts/QXYSeries>
    #include <QtCharts>
    #include <QtCharts/QAbstractSeries>
    #include "basechart.h"
    
    
    class Chart: public BaseChart
    {
        Q_OBJECT
    public:
        explicit Chart(QObject *parent = nullptr);
    
        Q_INVOKABLE void update(QAbstractSeries *series);
    
        void createDataPoint();
    
    signals:
        void updateData();
        void lineChanged();
    
    private:
        QVector<QPointF> firstId;
        QVector<QPointF> secondId;
    
    
    };
    
    

    baseChart.cpp

    #include <QObject>
    #include <QtCharts>
    
    QT_CHARTS_USE_NAMESPACE
    Q_DECLARE_METATYPE(QAbstractSeries *)
    Q_DECLARE_METATYPE(QAbstractAxis *)
    
    namespace charts {
    class BaseChart : public QObject
    {
        Q_OBJECT
    public:
        explicit BaseChart(QObject *parent = nullptr);
    
    
    signals:
    
    protected:
        
    
    };
    }
    

    basechart.h

    BaseChart::BaseChart(QObject *parent) : QObject(parent)
    {
        qRegisterMetaType<QAbstractSeries*>();
        qRegisterMetaType<QAbstractAxis*>();
    }
    
    

    and from this qml I call the update on the series objects

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Layouts 1.15
    
    Item {
        id: container
        anchors.fill: parent
    
        Connections {
            target: chart
            function onUpdateData() {
                console.log("We need to update data")
                chart.update(chartId.series(0))
                chart.update(chartId.series(1))
            }
        }
    
    MyChartView {
                id: chartId
            }
    }
    

    I'm using Qt 5.15.2 on Windows 10 64bit with MinGw64.
    If something is not clear please ask me! I had to delete some part of my code due to privacy policies but I hope it's clear what I would like to do.

    The only solution I can think of right now is to create n-LineSeries object and assign to them the points and the color to display, but I would like to find an easier solution because this means that for my specific purpose I can reach more than 40-50 LineSeries to display on the chart. I would also need to create the LineSeries objects dinamycally from c++, but that should not be a problem.

    Anyway, I know that in some charts libraries there is the possiblity to add something like a NoValue to avoid this behaviour, or there are some tricks, maybe also in Qt is there something similar?

    Thanks in advance!

    D 1 Reply Last reply
    0
    • D davidesalvetti

      Hi all,

      I recently started working with qml and in particular with ChartView. I'm developing an app where I need to show a ChartView object with some LineSeries inside. I said "some LineSeries" but the end result should looks like a single line, the problem is that this single line has to be composed by different colours. It is certainly easier to understand with an image:
      Cattura.PNG

      So, here I have two lines, but I would like them to look like one. To do this, I would like to know if there is a way to tell the QXYSeries Object to insert something like a blank point, so that I don't have the straight lines, because they're something that des not represent the line I want to draw. The correct line should look like the following one, but with two different color:
      Catturad.PNG

      This is my current code:
      MyChartView.qml

      import QtQuick 2.15
      import QtQuick.Controls 2.15
      import QtCharts 2.15
      
      ChartView {
          id: chartId
      
          plotArea: Qt.rect(5, 5, chartId.width - 5, chartId.height - 5)
          margins { top: 10; bottom: 10; left: 10; right: 10; }
      
          plotAreaColor: "#000020"
          backgroundColor: "white"
          legend.visible: false
          antialiasing: true
      
          ValueAxis {
              id: yaxis
              min: 0
              max: 100
      
              labelsVisible: false
              gridVisible: false
              minorGridVisible: false
              visible: false
          }
      
          ValueAxis {
              id: xaxis
              min: 0
              max: 100
      
              labelsVisible: false
              gridVisible: false
              minorGridVisible: false
              visible: false
          }
      
          LineSeries {
              id: firstId
              axisX: xaxis
              axisY: yaxis
              useOpenGL: true
              name: "firstId"
              color: "red"
          }
      
          LineSeries {
              id: secondId
              axisX: xaxis
              axisY: yaxis
              useOpenGL: true
      
              name: "secondId"
              color: "white"
          }
      }
      

      cpp

      #include "chart.h"
      
      Chart::Chart(QObject *parent) : BaseChart(parent)
      {
      
      }
      
      void Chart::createDataPoint()
      {
      //this function popolates the firstId and secondId QVector<PointF>
          emit updateData();
      }
      
      void Chart::update(QAbstractSeries *series)
      {
          if (series) {
              QXYSeries *xySeries = static_cast<QXYSeries *>(series);
      
              if (xySeries->name() == "firstId")
                  xySeries->replace(firstId);
              else
                  xySeries->replace(secondId);
          }
      }
      

      .h

      #include <QObject>
      #include <QtCharts/QXYSeries>
      #include <QtCharts>
      #include <QtCharts/QAbstractSeries>
      #include "basechart.h"
      
      
      class Chart: public BaseChart
      {
          Q_OBJECT
      public:
          explicit Chart(QObject *parent = nullptr);
      
          Q_INVOKABLE void update(QAbstractSeries *series);
      
          void createDataPoint();
      
      signals:
          void updateData();
          void lineChanged();
      
      private:
          QVector<QPointF> firstId;
          QVector<QPointF> secondId;
      
      
      };
      
      

      baseChart.cpp

      #include <QObject>
      #include <QtCharts>
      
      QT_CHARTS_USE_NAMESPACE
      Q_DECLARE_METATYPE(QAbstractSeries *)
      Q_DECLARE_METATYPE(QAbstractAxis *)
      
      namespace charts {
      class BaseChart : public QObject
      {
          Q_OBJECT
      public:
          explicit BaseChart(QObject *parent = nullptr);
      
      
      signals:
      
      protected:
          
      
      };
      }
      

      basechart.h

      BaseChart::BaseChart(QObject *parent) : QObject(parent)
      {
          qRegisterMetaType<QAbstractSeries*>();
          qRegisterMetaType<QAbstractAxis*>();
      }
      
      

      and from this qml I call the update on the series objects

      import QtQuick 2.15
      import QtQuick.Controls 2.15
      import QtQuick.Layouts 1.15
      
      Item {
          id: container
          anchors.fill: parent
      
          Connections {
              target: chart
              function onUpdateData() {
                  console.log("We need to update data")
                  chart.update(chartId.series(0))
                  chart.update(chartId.series(1))
              }
          }
      
      MyChartView {
                  id: chartId
              }
      }
      

      I'm using Qt 5.15.2 on Windows 10 64bit with MinGw64.
      If something is not clear please ask me! I had to delete some part of my code due to privacy policies but I hope it's clear what I would like to do.

      The only solution I can think of right now is to create n-LineSeries object and assign to them the points and the color to display, but I would like to find an easier solution because this means that for my specific purpose I can reach more than 40-50 LineSeries to display on the chart. I would also need to create the LineSeries objects dinamycally from c++, but that should not be a problem.

      Anyway, I know that in some charts libraries there is the possiblity to add something like a NoValue to avoid this behaviour, or there are some tricks, maybe also in Qt is there something similar?

      Thanks in advance!

      D Offline
      D Offline
      davidesalvetti
      wrote on last edited by
      #2

      The solution I adopted in the end is to create dinamically a single LineSeries object for every line color, and that works pretty well even if I have to create 40-50 lineSeries objects.
      I'm not pretty sure that the way I'm adding LineSeries is the best (I don't like the approach I used, but at the moment I don't see other possibilities).
      When I need to draw the lines what I do is:

      1. send a signal from c++ to qml that we need to draw new lines, with the number of lines to be drawn.
      2. with a Connections object I intercept the signal in qml and inside a for I create a new LineSeries element using chartView.CreateSeries(). Then I pass the series back to c++, with the number of the LineSeries created, so that I know which points I have to assign the that LineSeries object.

      I know that is not a clean approach, if somebody has any hints please tell me.

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved