Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Updating a QtChart "manually"
Forum Update on Monday, May 27th 2025

Updating a QtChart "manually"

Scheduled Pinned Locked Moved Solved Mobile and Embedded
7 Posts 2 Posters 1.5k 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.
  • N Offline
    N Offline
    NachoFly
    wrote on last edited by NachoFly
    #1

    Hi,

    I have been struggling with QtCharts for a bit now, the problem I am facing is the following:

    I have got a QtChart which shows a live chart of measured data, the embedded device receives new data each 5ms(200hz). Look at it as a heart monitor: old heartbeats will be removed when a new heartbeat is appended.
    Preferably the chart would update 200 times a second since the data I receive is at 200hz, while it is doable to update this fast on a desktop(it does work on my desktop), my embedded device is simply not fast enough. I have already tried to append only 1 out of 10 values the device receives. While this does work, the graph which is drawn is not a correct representation of the data.

    What I am looking for is appending and removing data without updating the chart itself. After let's say 10 appends/removes the chart get's updated "manually" , this will thus show all data but will only be updated 1 out 10 appends. By updating it manually I am hoping to reduce the load to be able to show all points on the chart.

    What I have tried to do to achieve the manual updating is the following:
    I've blocked the signals from the QSplineSeries to prevent the chart from updating. This does work but the part I am actually stuck at is that I am not able to update the QChart "manually". I have tried looking in the source code of QSplineSeries to see what kind of Signal it emits but it looks more like a maze to me than readable code.

    Does anyone know a solution to be able to update the qchart manually? Or does anyone know a solution to be able to reduce load and be able to update the chart as close as possible to 200 times a second.

    Best regards,

    Martijn

    Gojir4G 1 Reply Last reply
    0
    • N Offline
      N Offline
      NachoFly
      wrote on last edited by NachoFly
      #6

      Okay I might have an idea which might work:

      Instead of 2 QSplineseries(serieA and serieB) I am going to create 4(serieA, serieA2, serieB, serieB2). Only 2 QSplineSeries will be shown at the same time either serieA and serieB or serieA2 and serieB2. While showing serieA and serieB are added to the Chart all new values will be appended to the serieA2 and serieB2. When X amount of new values are added to serieA2 and serieB2 I will remove serieA and serieB and add serieA2 and serieB2. When serieA2 and serieB2 are added all values will be appended to serieA and serieB and so on. Because the new values are appended on a series which is not currently in the chart the chart won't update and will only update when I add the seriesA and serieB as a whole.

      When I finished implementing this I will add the outcome in this post underneath.

      Update with solution:
      @Gojir4 Thanks for brainstoriming with me, sometimes all you need is someone to talk to. Your suggestion for an extra buffer helped alot!

      I've found a solution for my problem and it almost as I described above.

      void Chart::appendValue(unsigned long long xValue, uint16_t yValue)
      {
          count++;
      
          double place = double((xValue % (SECONDS_SHOWN_ON_SCREEN * 1000)) / double(SECONDS_SHOWN_ON_SCREEN * 1000)) * SECONDS_SHOWN_ON_SCREEN;
          if (count == MEASUREMENTS_PER_CHART_UPDATE)
          {
              count = 0;
              removeSeries(m_series);
              removeSeries(n_series);
              m_series = m2_series;
              n_series = n2_series;
              addSeries(m_series);
              addSeries(n_series);
              m_series->attachAxis(m_ax);
              n_series->attachAxis(m_ax);
              m_series->attachAxis(m_ay);
              n_series->attachAxis(m_ay);
          }
          if (previousX > place)
          {
              m_seriesActive = !m_seriesActive;
          }
      
          if (m_seriesActive)
          {
              m2_series->append(place, yValue);
          }
          else
          {
              n2_series->append(place, yValue);
          }
      
          this->previousX = place;
          handleTimeout();
      }
      

      I still have the "double series" as a buffer, all new values are appended to the buffer series which is not shown on the chart. When the counter hits the desired amount of new points per update the old series are removed from the chart. The buffer series are copied to the series which are shown on the chart and the shown series are added to the chart again. It is significantly faster on my desktop but I have not tested it on my embedded device yet.

      If anyone has a better/easier solution feel free to post it!

      Gojir4G 1 Reply Last reply
      0
      • N NachoFly

        Hi,

        I have been struggling with QtCharts for a bit now, the problem I am facing is the following:

        I have got a QtChart which shows a live chart of measured data, the embedded device receives new data each 5ms(200hz). Look at it as a heart monitor: old heartbeats will be removed when a new heartbeat is appended.
        Preferably the chart would update 200 times a second since the data I receive is at 200hz, while it is doable to update this fast on a desktop(it does work on my desktop), my embedded device is simply not fast enough. I have already tried to append only 1 out of 10 values the device receives. While this does work, the graph which is drawn is not a correct representation of the data.

        What I am looking for is appending and removing data without updating the chart itself. After let's say 10 appends/removes the chart get's updated "manually" , this will thus show all data but will only be updated 1 out 10 appends. By updating it manually I am hoping to reduce the load to be able to show all points on the chart.

        What I have tried to do to achieve the manual updating is the following:
        I've blocked the signals from the QSplineSeries to prevent the chart from updating. This does work but the part I am actually stuck at is that I am not able to update the QChart "manually". I have tried looking in the source code of QSplineSeries to see what kind of Signal it emits but it looks more like a maze to me than readable code.

        Does anyone know a solution to be able to update the qchart manually? Or does anyone know a solution to be able to reduce load and be able to update the chart as close as possible to 200 times a second.

        Best regards,

        Martijn

        Gojir4G Offline
        Gojir4G Offline
        Gojir4
        wrote on last edited by
        #2

        @NachoFly said in Updating a QtChart "manually":

        I've blocked the signals from the QSplineSeries to prevent the chart from updating.

        Hi,

        Can't you "unblock" the signal from time to time to update the chart ?

        N 1 Reply Last reply
        0
        • Gojir4G Gojir4

          @NachoFly said in Updating a QtChart "manually":

          I've blocked the signals from the QSplineSeries to prevent the chart from updating.

          Hi,

          Can't you "unblock" the signal from time to time to update the chart ?

          N Offline
          N Offline
          NachoFly
          wrote on last edited by
          #3

          @Gojir4
          Hi, Thanks for the response, I forgot to mention that I already tried that. Unfortunately this does not work and causes a segmentation fault. The segmentation fault is most likely caused by the fact that removing and adding a point on a QSplineseries cause two different signals and not just a general signal which tells the chart that the QSplineseries has changed.
          During the time the QSplineseries' signals were blocked the chart missed signals from the removed and added points. When the QSplineseries' their signals get unblocked and send a new "pointAdded" or "poinRemoved" signal the chart will most likely only process the point which was just added/removed and caused the signal.
          The fact that it most likely only processes the point which caused the signal probably causes the segmentation fault since the new point should be "connected" with a line to the point before that point. Since this point was never added to the chart my best guess is that this causes a segmentation fault.

          Gojir4G 1 Reply Last reply
          1
          • N NachoFly

            @Gojir4
            Hi, Thanks for the response, I forgot to mention that I already tried that. Unfortunately this does not work and causes a segmentation fault. The segmentation fault is most likely caused by the fact that removing and adding a point on a QSplineseries cause two different signals and not just a general signal which tells the chart that the QSplineseries has changed.
            During the time the QSplineseries' signals were blocked the chart missed signals from the removed and added points. When the QSplineseries' their signals get unblocked and send a new "pointAdded" or "poinRemoved" signal the chart will most likely only process the point which was just added/removed and caused the signal.
            The fact that it most likely only processes the point which caused the signal probably causes the segmentation fault since the new point should be "connected" with a line to the point before that point. Since this point was never added to the chart my best guess is that this causes a segmentation fault.

            Gojir4G Offline
            Gojir4G Offline
            Gojir4
            wrote on last edited by
            #4

            @NachoFly Ok, I see, thanks for the explanation.

            So you could use a QVector or QList to store your points, acting like a buffer, and then updating the chart at the frequency you want. So instead of adding 1 out of 10 value, you will add 10 (or 5, or 20...) values at once. Which I think will be probably better in performance, without losing data.

            N 1 Reply Last reply
            0
            • Gojir4G Gojir4

              @NachoFly Ok, I see, thanks for the explanation.

              So you could use a QVector or QList to store your points, acting like a buffer, and then updating the chart at the frequency you want. So instead of adding 1 out of 10 value, you will add 10 (or 5, or 20...) values at once. Which I think will be probably better in performance, without losing data.

              N Offline
              N Offline
              NachoFly
              wrote on last edited by
              #5

              @Gojir4
              I also considered doing that and it indeed sounds like the solution to go with. Unfortunately using the append(const QList<QPointF> &) will just call append(const QPointF &) as many times as there are points in the QList and will thus cause as many signals and updates as adding each point seperately.

              1 Reply Last reply
              0
              • N Offline
                N Offline
                NachoFly
                wrote on last edited by NachoFly
                #6

                Okay I might have an idea which might work:

                Instead of 2 QSplineseries(serieA and serieB) I am going to create 4(serieA, serieA2, serieB, serieB2). Only 2 QSplineSeries will be shown at the same time either serieA and serieB or serieA2 and serieB2. While showing serieA and serieB are added to the Chart all new values will be appended to the serieA2 and serieB2. When X amount of new values are added to serieA2 and serieB2 I will remove serieA and serieB and add serieA2 and serieB2. When serieA2 and serieB2 are added all values will be appended to serieA and serieB and so on. Because the new values are appended on a series which is not currently in the chart the chart won't update and will only update when I add the seriesA and serieB as a whole.

                When I finished implementing this I will add the outcome in this post underneath.

                Update with solution:
                @Gojir4 Thanks for brainstoriming with me, sometimes all you need is someone to talk to. Your suggestion for an extra buffer helped alot!

                I've found a solution for my problem and it almost as I described above.

                void Chart::appendValue(unsigned long long xValue, uint16_t yValue)
                {
                    count++;
                
                    double place = double((xValue % (SECONDS_SHOWN_ON_SCREEN * 1000)) / double(SECONDS_SHOWN_ON_SCREEN * 1000)) * SECONDS_SHOWN_ON_SCREEN;
                    if (count == MEASUREMENTS_PER_CHART_UPDATE)
                    {
                        count = 0;
                        removeSeries(m_series);
                        removeSeries(n_series);
                        m_series = m2_series;
                        n_series = n2_series;
                        addSeries(m_series);
                        addSeries(n_series);
                        m_series->attachAxis(m_ax);
                        n_series->attachAxis(m_ax);
                        m_series->attachAxis(m_ay);
                        n_series->attachAxis(m_ay);
                    }
                    if (previousX > place)
                    {
                        m_seriesActive = !m_seriesActive;
                    }
                
                    if (m_seriesActive)
                    {
                        m2_series->append(place, yValue);
                    }
                    else
                    {
                        n2_series->append(place, yValue);
                    }
                
                    this->previousX = place;
                    handleTimeout();
                }
                

                I still have the "double series" as a buffer, all new values are appended to the buffer series which is not shown on the chart. When the counter hits the desired amount of new points per update the old series are removed from the chart. The buffer series are copied to the series which are shown on the chart and the shown series are added to the chart again. It is significantly faster on my desktop but I have not tested it on my embedded device yet.

                If anyone has a better/easier solution feel free to post it!

                Gojir4G 1 Reply Last reply
                0
                • N NachoFly

                  Okay I might have an idea which might work:

                  Instead of 2 QSplineseries(serieA and serieB) I am going to create 4(serieA, serieA2, serieB, serieB2). Only 2 QSplineSeries will be shown at the same time either serieA and serieB or serieA2 and serieB2. While showing serieA and serieB are added to the Chart all new values will be appended to the serieA2 and serieB2. When X amount of new values are added to serieA2 and serieB2 I will remove serieA and serieB and add serieA2 and serieB2. When serieA2 and serieB2 are added all values will be appended to serieA and serieB and so on. Because the new values are appended on a series which is not currently in the chart the chart won't update and will only update when I add the seriesA and serieB as a whole.

                  When I finished implementing this I will add the outcome in this post underneath.

                  Update with solution:
                  @Gojir4 Thanks for brainstoriming with me, sometimes all you need is someone to talk to. Your suggestion for an extra buffer helped alot!

                  I've found a solution for my problem and it almost as I described above.

                  void Chart::appendValue(unsigned long long xValue, uint16_t yValue)
                  {
                      count++;
                  
                      double place = double((xValue % (SECONDS_SHOWN_ON_SCREEN * 1000)) / double(SECONDS_SHOWN_ON_SCREEN * 1000)) * SECONDS_SHOWN_ON_SCREEN;
                      if (count == MEASUREMENTS_PER_CHART_UPDATE)
                      {
                          count = 0;
                          removeSeries(m_series);
                          removeSeries(n_series);
                          m_series = m2_series;
                          n_series = n2_series;
                          addSeries(m_series);
                          addSeries(n_series);
                          m_series->attachAxis(m_ax);
                          n_series->attachAxis(m_ax);
                          m_series->attachAxis(m_ay);
                          n_series->attachAxis(m_ay);
                      }
                      if (previousX > place)
                      {
                          m_seriesActive = !m_seriesActive;
                      }
                  
                      if (m_seriesActive)
                      {
                          m2_series->append(place, yValue);
                      }
                      else
                      {
                          n2_series->append(place, yValue);
                      }
                  
                      this->previousX = place;
                      handleTimeout();
                  }
                  

                  I still have the "double series" as a buffer, all new values are appended to the buffer series which is not shown on the chart. When the counter hits the desired amount of new points per update the old series are removed from the chart. The buffer series are copied to the series which are shown on the chart and the shown series are added to the chart again. It is significantly faster on my desktop but I have not tested it on my embedded device yet.

                  If anyone has a better/easier solution feel free to post it!

                  Gojir4G Offline
                  Gojir4G Offline
                  Gojir4
                  wrote on last edited by
                  #7

                  @NachoFly It looks like a good approach. I didn't know that about append(), thanks for notice.

                  The only thing I would try is replacing the data instead of having two series, using void QXYSeries::replace(QVector<QPointF> points). It could be interesting to see which solution is faster.

                  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