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
Qt 6.11 is out! See what's new in the release blog

QML ChartView lineseries with "blank" points

Scheduled Pinned Locked Moved Solved QML and Qt Quick
2 Posts 1 Posters 2.0k 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