Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QChart and series replace issue
QtWS25 Last Chance

QChart and series replace issue

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 3 Posters 948 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
    dmitttri
    wrote on last edited by
    #1

    Hi everyone,
    thanks for your great support! I am not well versed with Qt, and at the moment I am developing a small utility real-time data recorder, which use QChart as the data plotter control. Let me briefly explain the exact issue I am facing at the moment.

    I have a dedicated data receiver thread, running at 100ms period. In this thread I am receiving 16 channels of integer data samples For each data channel, there is one QLineSeries object, added to the QChart object. In each thread processing cycle, I am converting integers to QPointF and directly calling replace method for all series (in a for loop). Effectively I get received data to scroll right to left, as data arrives.

    While this approach works fine with 8 or 12 channels, as number of channels grows up, application starts to lag and becomes entirely non-responsive.

    My understanding was that each replace call on series, will trigger implicit QChart repainting, which takes processing place in the main Qt loop. Seems that my data receiver thread is requesting to many repaint events, which can't be processed in 100ms, and then burden accumulates, making my app unusable.

    I was wondering if there is any option to temporary disable QChart repaint, until I fully replace all series, and then trigger one single repaint, after all 16 series were fully replaced?

    Thanks for any hints!

    JonBJ 1 Reply Last reply
    0
    • D dmitttri

      Hi everyone,
      thanks for your great support! I am not well versed with Qt, and at the moment I am developing a small utility real-time data recorder, which use QChart as the data plotter control. Let me briefly explain the exact issue I am facing at the moment.

      I have a dedicated data receiver thread, running at 100ms period. In this thread I am receiving 16 channels of integer data samples For each data channel, there is one QLineSeries object, added to the QChart object. In each thread processing cycle, I am converting integers to QPointF and directly calling replace method for all series (in a for loop). Effectively I get received data to scroll right to left, as data arrives.

      While this approach works fine with 8 or 12 channels, as number of channels grows up, application starts to lag and becomes entirely non-responsive.

      My understanding was that each replace call on series, will trigger implicit QChart repainting, which takes processing place in the main Qt loop. Seems that my data receiver thread is requesting to many repaint events, which can't be processed in 100ms, and then burden accumulates, making my app unusable.

      I was wondering if there is any option to temporary disable QChart repaint, until I fully replace all series, and then trigger one single repaint, after all 16 series were fully replaced?

      Thanks for any hints!

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by
      #2

      @dmitttri said in QChart and series replace issue:

      I have a dedicated data receiver thread, running at 100ms period. In this thread I am receiving 16 channels of integer data samples For each data channel, there is one QLineSeries object, added to the QChart object. In each thread processing cycle, I am converting integers to QPointF and directly calling replace method for all series (in a for loop)

      Does this mean that a subsidiary thread is directly writing to/updating the QChart object in the UI? Or do you correctly do the updates in the main UI thread? If so do you send signals? How often? Do you "batch up" the data for update on the chart? I'm not understanding this area, need to understand when and where the chart is getting updated before advising on "repaints".

      D 1 Reply Last reply
      0
      • JonBJ JonB

        @dmitttri said in QChart and series replace issue:

        I have a dedicated data receiver thread, running at 100ms period. In this thread I am receiving 16 channels of integer data samples For each data channel, there is one QLineSeries object, added to the QChart object. In each thread processing cycle, I am converting integers to QPointF and directly calling replace method for all series (in a for loop)

        Does this mean that a subsidiary thread is directly writing to/updating the QChart object in the UI? Or do you correctly do the updates in the main UI thread? If so do you send signals? How often? Do you "batch up" the data for update on the chart? I'm not understanding this area, need to understand when and where the chart is getting updated before advising on "repaints".

        D Offline
        D Offline
        dmitttri
        wrote on last edited by
        #3

        @JonB said in QChart and series replace issue:

        @dmitttri said in QChart and series replace issue:

        I have a dedicated data receiver thread, running at 100ms period. In this thread I am receiving 16 channels of integer data samples For each data channel, there is one QLineSeries object, added to the QChart object. In each thread processing cycle, I am converting integers to QPointF and directly calling replace method for all series (in a for loop)

        Does this mean that a subsidiary thread is directly writing to/updating the QChart object in the UI?

        Yes, thread sleeps 100ms, and when it wakes up, it reads latest arrived data, and then for each of 16 channels it directly calls replace for all 16 series in the QChart

        Or do you correctly do the updates in the main UI thread? If so do you send signals?

        Series updates were performed directly in a dedicated thread, for performance reasons, and avoid signals.

        How often?

        Every 100ms, I receive approx 2000 points on each of 16 channels, and then I call replace for each channel in a loop

        Do you "batch up" the data for update on the chart?

        No, received integer points are being converted to QPointF list, and passed directly to series replace method.

        I'm not understanding this area, need to understand when and where the chart is getting updated before advising on "repaints".

        Thanks a lot for any kind of support, I may learn something useful here.

        JonBJ 1 Reply Last reply
        0
        • D dmitttri

          @JonB said in QChart and series replace issue:

          @dmitttri said in QChart and series replace issue:

          I have a dedicated data receiver thread, running at 100ms period. In this thread I am receiving 16 channels of integer data samples For each data channel, there is one QLineSeries object, added to the QChart object. In each thread processing cycle, I am converting integers to QPointF and directly calling replace method for all series (in a for loop)

          Does this mean that a subsidiary thread is directly writing to/updating the QChart object in the UI?

          Yes, thread sleeps 100ms, and when it wakes up, it reads latest arrived data, and then for each of 16 channels it directly calls replace for all 16 series in the QChart

          Or do you correctly do the updates in the main UI thread? If so do you send signals?

          Series updates were performed directly in a dedicated thread, for performance reasons, and avoid signals.

          How often?

          Every 100ms, I receive approx 2000 points on each of 16 channels, and then I call replace for each channel in a loop

          Do you "batch up" the data for update on the chart?

          No, received integer points are being converted to QPointF list, and passed directly to series replace method.

          I'm not understanding this area, need to understand when and where the chart is getting updated before advising on "repaints".

          Thanks a lot for any kind of support, I may learn something useful here.

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #4

          @dmitttri said in QChart and series replace issue:

          Yes, thread sleeps 100ms, and when it wakes up, it reads latest arrived data, and then for each of 16 channels it directly calls replace for all 16 series in the QChart

          Before you go any further, that is not supposed to be allowed in Qt widgets. Threads may not update a widget directly, and I assume replace on a series counts as doing just that. You should wait to see if someone else confirms this, hopefully posting here.

          D 1 Reply Last reply
          0
          • JonBJ JonB

            @dmitttri said in QChart and series replace issue:

            Yes, thread sleeps 100ms, and when it wakes up, it reads latest arrived data, and then for each of 16 channels it directly calls replace for all 16 series in the QChart

            Before you go any further, that is not supposed to be allowed in Qt widgets. Threads may not update a widget directly, and I assume replace on a series counts as doing just that. You should wait to see if someone else confirms this, hopefully posting here.

            D Offline
            D Offline
            dmitttri
            wrote on last edited by dmitttri
            #5

            @JonB said in QChart and series replace issue:

            @dmitttri said in QChart and series replace issue:

            Yes, thread sleeps 100ms, and when it wakes up, it reads latest arrived data, and then for each of 16 channels it directly calls replace for all 16 series in the QChart

            Before you go any further, that is not supposed to be allowed in Qt widgets. Threads may not update a widget directly, and I assume replace on a series counts as doing just that. You should wait to see if someone else confirms this, hopefully posting here.

            Thanks for reply! I do realize that updating widgets concurrently with Qt main processing loop may look like a risky operation, and it was done primary because during recording process, QChart series will be updated only form this particular thread, and to avoid signals. Why? It makes things more complex, someone shall take care that data to be plotted (received data) is consistent and not touched while receiver thread is running. This means making a copy of all series contents, to be updated (replaced) in the main Qt loop context.

            But even with such by book approach, we still have the same issue. One has to call replace in a loop (outside of thread context), and if it takes more time than receiver thread period (send update request signals), then I will end up with the same issue again (more plotting requests than QChart can serve in a given time period)

            JonBJ 1 Reply Last reply
            0
            • D dmitttri

              @JonB said in QChart and series replace issue:

              @dmitttri said in QChart and series replace issue:

              Yes, thread sleeps 100ms, and when it wakes up, it reads latest arrived data, and then for each of 16 channels it directly calls replace for all 16 series in the QChart

              Before you go any further, that is not supposed to be allowed in Qt widgets. Threads may not update a widget directly, and I assume replace on a series counts as doing just that. You should wait to see if someone else confirms this, hopefully posting here.

              Thanks for reply! I do realize that updating widgets concurrently with Qt main processing loop may look like a risky operation, and it was done primary because during recording process, QChart series will be updated only form this particular thread, and to avoid signals. Why? It makes things more complex, someone shall take care that data to be plotted (received data) is consistent and not touched while receiver thread is running. This means making a copy of all series contents, to be updated (replaced) in the main Qt loop context.

              But even with such by book approach, we still have the same issue. One has to call replace in a loop (outside of thread context), and if it takes more time than receiver thread period (send update request signals), then I will end up with the same issue again (more plotting requests than QChart can serve in a given time period)

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by
              #6

              @dmitttri
              It's not just a "risky operation", it's not allowed. So if you use it I don't see how people can help you address its performance.

              I would assume that using replace (properly) would only cause the chart to update when its next paint event is processed.

              My understanding was that each replace call on series, will trigger implicit QChart repainting,

              I would hope that it would only mark the chart for update, which is different from a direct repaint. Multiple calls can be coalesced into the next actual repaint.

              If you do not get a better answer which achieves the responsiveness you require you might either "thin out" the datapoints or the frequency of updates. If your usage is really heavy/fast QChart is known to be perhaps not the greatest component, I don't know if something else or written yourself would work better, last resort.

              D 1 Reply Last reply
              0
              • D Offline
                D Offline
                dmitttri
                wrote on last edited by
                #7

                I may reformulate my question as; If QChart has multiple series N attached, and we want to replace all N series at once, is there any method to do series replace in one go, and end up with only one QChart repaint? (and not calling replace N times, where each one triggers QChart repainting)

                SGaistS 1 Reply Last reply
                0
                • D dmitttri

                  I may reformulate my question as; If QChart has multiple series N attached, and we want to replace all N series at once, is there any method to do series replace in one go, and end up with only one QChart repaint? (and not calling replace N times, where each one triggers QChart repainting)

                  SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi,

                  I don't know the module internals so I currently cannot comment on that part but one workaround that comes to mind is to block the widget updates while replacing all the series and then enable them again. That should avoid the "repaint storm" you are getting.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  D 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @dmitttri
                    It's not just a "risky operation", it's not allowed. So if you use it I don't see how people can help you address its performance.

                    I would assume that using replace (properly) would only cause the chart to update when its next paint event is processed.

                    My understanding was that each replace call on series, will trigger implicit QChart repainting,

                    I would hope that it would only mark the chart for update, which is different from a direct repaint. Multiple calls can be coalesced into the next actual repaint.

                    If you do not get a better answer which achieves the responsiveness you require you might either "thin out" the datapoints or the frequency of updates. If your usage is really heavy/fast QChart is known to be perhaps not the greatest component, I don't know if something else or written yourself would work better, last resort.

                    D Offline
                    D Offline
                    dmitttri
                    wrote on last edited by
                    #9

                    @JonB said in QChart and series replace issue:

                    @dmitttri
                    It's not just a "risky operation", it's not allowed. So if you use it I don't see how people can help you address its performance.

                    Yes, and I will definitely try the option with proper approach, signals and keep any updates outside of the receiver thread. Thanks. At least, having the same issue with proper way of doing it, will make my inquiry easier to respond to.

                    I would assume that using replace (properly) would only cause the chart to update when its next paint event is processed.

                    My understanding was that each replace call on series, will trigger implicit QChart repainting,

                    I would hope that it would only mark the chart for update, which is different from a direct repaint. Multiple calls can be coalesced into the next actual repaint.

                    If you do not get a better answer which achieves the responsiveness you require you might either "thin out" the datapoints or the frequency of updates. If your usage is really heavy/fast QChart is known to be perhaps not the greatest component, I don't know if something else or written yourself would work better, last resort.

                    Unfortunately seems you are right regarding QChart not being the best choice for high performance plotting of larger data sets. Anyhow, thanks for precise clarifications.

                    SGaistS 1 Reply Last reply
                    0
                    • D dmitttri

                      @JonB said in QChart and series replace issue:

                      @dmitttri
                      It's not just a "risky operation", it's not allowed. So if you use it I don't see how people can help you address its performance.

                      Yes, and I will definitely try the option with proper approach, signals and keep any updates outside of the receiver thread. Thanks. At least, having the same issue with proper way of doing it, will make my inquiry easier to respond to.

                      I would assume that using replace (properly) would only cause the chart to update when its next paint event is processed.

                      My understanding was that each replace call on series, will trigger implicit QChart repainting,

                      I would hope that it would only mark the chart for update, which is different from a direct repaint. Multiple calls can be coalesced into the next actual repaint.

                      If you do not get a better answer which achieves the responsiveness you require you might either "thin out" the datapoints or the frequency of updates. If your usage is really heavy/fast QChart is known to be perhaps not the greatest component, I don't know if something else or written yourself would work better, last resort.

                      Unfortunately seems you are right regarding QChart not being the best choice for high performance plotting of larger data sets. Anyhow, thanks for precise clarifications.

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @dmitttri the new QtGraphs module might be more tailored to your needs. (Note that I have not used it yet).

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • SGaistS SGaist

                        Hi,

                        I don't know the module internals so I currently cannot comment on that part but one workaround that comes to mind is to block the widget updates while replacing all the series and then enable them again. That should avoid the "repaint storm" you are getting.

                        D Offline
                        D Offline
                        dmitttri
                        wrote on last edited by
                        #11

                        @SGaist said in QChart and series replace issue:

                        Hi,

                        I don't know the module internals so I currently cannot comment on that part but one workaround that comes to mind is to block the widget updates while replacing all the series and then enable them again. That should avoid the "repaint storm" you are getting.

                        Yeah, I was trying to achieve such effect somehow, for example with setViewportUpdateMode(QGraphicsView::NoViewportUpdate), update series, and then revert back the default UpdateMode, but this was not a successful approach.

                        Anyway thanks a lot for your hints!

                        SGaistS 1 Reply Last reply
                        0
                        • D dmitttri

                          @SGaist said in QChart and series replace issue:

                          Hi,

                          I don't know the module internals so I currently cannot comment on that part but one workaround that comes to mind is to block the widget updates while replacing all the series and then enable them again. That should avoid the "repaint storm" you are getting.

                          Yeah, I was trying to achieve such effect somehow, for example with setViewportUpdateMode(QGraphicsView::NoViewportUpdate), update series, and then revert back the default UpdateMode, but this was not a successful approach.

                          Anyway thanks a lot for your hints!

                          SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @dmitttri I was rather thinking about QWidget::setUpdatesEnabled.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          D 1 Reply Last reply
                          0
                          • SGaistS SGaist

                            @dmitttri I was rather thinking about QWidget::setUpdatesEnabled.

                            D Offline
                            D Offline
                            dmitttri
                            wrote on last edited by
                            #13

                            @SGaist said in QChart and series replace issue:

                            @dmitttri I was rather thinking about QWidget::setUpdatesEnabled.

                            Thanks, I will try it!

                            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