How to update/redraw QChart after data is added to QLineSeries?

Lennart Rolland picture Lennart Rolland · Mar 25, 2017 · Viewed 14.2k times · Source

I am generating some data that I want to chart using QChart & friends. This is my first time using QChart, and so basically what I did was copy the QLineSeries Example and modify it to my needs. My current code looks like this:

    quint64 last=0;
    quint64 *lastp=&last;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , series( nullptr )
{
    ui->setupUi(this);
    QChart *chart = new QChart();
    series=new QLineSeries(chart);
    chart->legend()->hide();
    chart->addSeries(series);
    chart->createDefaultAxes();
    chart->setTitle("Simple line chart example");
    QChartView *chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    setCentralWidget(chartView);
    GeneticTask *gTask = new GeneticTask();
    connect(gTask, &GeneticTask::point, this, [=](QPointF pt) {
        // New point added to series
        *series<<pt;
        // Limit updates to once per second
        quint64 now=QDateTime::currentMSecsSinceEpoch();
        if(now-(*lastp)>1000) {
            qDebug()<<"UPDATE";
            // [A] WHAT TO PUT HERE TO HAVE CHART REDRAW WITH NEW DATA?
            *lastp=now;
        }
    }
    );
    QThreadPool::globalInstance()->start(gTask);
}

When I run this code I would expect my new data to show up in the graph, but it does not, so my question is: How can I have the chart update to show the new data? In other words, what should I put in the code where the comment reads [A]?

Answer

Ervin Szilagyi picture Ervin Szilagyi · Mar 25, 2017

Appending a value to QLineSeries using the operator << or the append method should repaint the graph. If it does not happen form some reason, you could trying calling the repaint method on the QChartView.

Here is some code that will center the data once it is added with a cap of at most once per second:

// Global or class scope or
qreal max=-10000000000;
qreal min=-max;
qreal *maxp=&max;
qreal *minp=&min;

// Same scope as before
connect(gTask, &GeneticTask::point, this, [=](QPointF pt) {
        if(pt.y()>*maxp) {
            *maxp=pt.y();
        }
        if(pt.y()<*minp) {
            *minp=pt.y();
        }
        *series<<pt;
        quint64 now=QDateTime::currentMSecsSinceEpoch();
        if(now-(*lastp)>1000) {
            qDebug()<<"UPDATE";
            chart->axisX()->setRange(0,series->count());
            chart->axisY()->setRange(*minp,*maxp);

            *lastp=now;
        }
    }
);