Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Fast way of populating QScatterSeries in QtCharts?



  • Hello,
    I'm developing a desktop application that draws charts, including scatter charts. Because these scatter charts have a lot of data points (on the order of 7-8 million each) and I need to draw 5 of these charts, the time required to display the chart really adds up. In order to improve the user experience I tried using QThread s and the signal-slot mechanism to parallelize the populating of the scatter series. (For each graph, there will be one seperate QThread to populate the corresponding scatter series. Each scatter series will be populated by just one thread.) However, it takes even longer than in the sequential case. I'm suspecting that because QScatterSeries are UI elements it cannot be parallelized and it is being executed sequential. My questions are:

    1. Am I correct in thinking that the operation of appending data to scatter series cannot be parallelized?
    2. As a general question: How can I make this process faster?
      You can see my code below.
    //SeriesPopulater.h
    class SeriesPopulater : public QObject{
    Q_OBJECT
    public: 
    SeriesPopulater(int graphIndex, QScatterSeries *series, QObject *parent);
    ~SeriesPopulater();
    signals:
    void done(int, QScatterSeries *);
    void cleanup();
    private slots:
    void populate();
    private:
    int graphIndex;
    QScatterSeries *series;
    };
    
    //SeriesPopulater.cpp
    SeriesPopulater::SeriesPopulater(int graphIndex, QScatterSeries *series,  QObject *parent)
    	: QObject(parent)
    {
    	this->graphIndex = graphIndex;
    	this->series = series;
    	
    }
    
    void SeriesPopulater::populate()
    {
    	std::normal_distribution<double> dist(10.0, 2.0);
    	unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    	std::default_random_engine generator(seed);
    	for (int i = 0; i < 8000000; i++) { // Just generate 8000000 random numbers.
    		series->append(i, dist(generator));
    	}
    
    	emit done(graphIndex, series);
    	emit cleanup();
    	
    }
    
    SeriesPopulater::~SeriesPopulater()
    {
    }
    
    
    
    //Main program
    //PSEUDOCODE
    //For each graph do
    SeriesPopulater *p = new SeriesPopulater(1, chart1, scatterSeries1, this);
    				QThread *th = new QThread();
    				th->setPriority(QThread::TimeCriticalPriority);
    				p->moveToThread(th);
    				connect(th, SIGNAL(started()), p, SLOT(populate()));
    				connect(p, SIGNAL(done(int, QScatterSeries *)), this, SLOT(handleThreadDone(int, QScatterSeries *)));
    				connect(p, SIGNAL(cleanup()), th, SLOT(quit()));
    				connect(th, SIGNAL(finished()), p, SLOT(deleteLater()));
    				connect(th, SIGNAL(finished()), th, SLOT(deleteLater()));
    
    				th->start();
    
    
    //The slot handleThreadDone(int, QScatterSeries *)
    //PSEUDOCODE
    switch(graphIndex){
    case 1:
    chart1->addSeries(series);
    scatterSeries1->attachAxis(axisX1);
    scatterSeries1->attachAxis(axisY1);
    chartView1->repaint();
    break;
    case 2:
    chart2->addSeries(series);
    scatterSeries2->attachAxis(axisX2);
    scatterSeries2->attachAxis(axisY2);
    chartView2->repaint();
    break;
    
    //////
    //////OTHER OPTIONS
    }
    

  • Lifetime Qt Champion

    Hi,

    With that many point you might want to try Qwt which may be better suited.



  • That's a bit complicated, because the project is almost complete and I have used the QtCharts and QtDataVisualization frameworks for that. Is there a way to do it with the capabilities of the Qt framework without using Qwt? Thanks.


Log in to reply