Search code examples
c++qtqt5updatesqchart

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


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]?


Solution

  • 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;
            }
        }
    );