I build a three-dimensional graph using QtDataVisualization .

 Q3DScatter *scatter = new Q3DScatter; QScatterDataProxy *proxy = new QScatterDataProxy; QScatter3DSeries *series = new QScatter3DSeries(proxy); //... void addItem(double x, double y, double z){ QScatterDataItem item; item.setX(x); item.setY(y); item.setZ(z); proxy->addItem(item); } 

The problem is that the addItem method addItem called quite often in a parallel thread. And every time the scatter updated. With a large number of points (thousands), "friezes" begin. While only one solution comes to mind, accumulate points and add hundreds at once:

 void addItem(double x, double y, double z){ static QScatterDataArray items; QScatterDataItem item; item.setX(x); item.setY(y); item.setZ(z); items.append(item); if(items.size() >= 100){ proxy->addItems(items); } } 

As for me it is a crutch. Can someone know any option or event with which you can do something so that the schedule is not updated entirely for the sake of each new point?

UPD:

Based on the answer @ alexis031182, it will not work "nicely". I do something like this:

 class Scatter : public QWidget{ QScatterDataProxy *_proxy; QScatterDataArray _items; int _timerId; //... public: Scatter(): _timer(startTimer(100)) {} //... protected: void timerEvent(QTimerEvent *event){ if(event->timerId() != _timerId){ return; } event->accept(); if(_items.empty()){ return; } _proxy->addItems(_items); _items.clear(); } }; 

    1 answer 1

    The problem is that the addItem method is called quite often in a parallel thread.

    The addItem() method belongs to a certain arbitrary class, however, the QScatterDataProxy::addItems() method, which is called internally, is already, if I may say so, a GUI part. Accordingly, if there is no corresponding processing within the QScatterDataProxy method for the inconsistency of the current flow to the main one (and most likely it is not), then there may be various consequences, including “friezes” on the screen.

    Try calling QScatterDataProxy::addItems() exclusively on the main thread. Since this method is not a slot, and it is not marked as Q_INVOKABLE , you will have to create a separate custom functionality that will insert the collected data into the proxy container. Also, as an option, you can multithreadedly accumulate data in QScatterDataArray , and already in the main stream, read them by timer.

    One more thing is probably a typo:

     void addItem(double x, double y, double z){ static QScatterDataArray items; QScatterDataItem item; item.setX(x); item.setY(y); item.setZ(z); items.append(item); if(items.size() >= 100){ proxy->addItems(items); } } 

    The code does not clear items after inserting a series of points. Accordingly, the second hundred of inserted points will contain the first one. The next insertion will add three hundred points, instead of the new ones, etc.

    As for the insertion of points in series, this is the right approach. This is also stated in the help section "Dealing with real-time data". A reason is also mentioned there, in view of which a complete redrawing of the chart can be made:

    If you have to keep track of your data, you can slow down. For the best performance with the scatter graphs, only keep the data proxy.

    If in your own words, the subsidence occurs due to the definition of the boundaries of visibility of the incoming points with unassorted coordinates.

    • one
      I carefully looked at the code, I realized that I was wrong. The addItem method addItem called in a slot that is jerking from another thread. So all right, addItem is executed in the main thread. - yrHeTaTeJlb
    • one
      Help read. I realized that I’ll have to accumulate data and reset the timer in a proxy - yrHeTaTeJlb