[SOLVED]QChart scatter graph will not update



  • I am fiddling with QChart, started with a dem@o program (scatterinteractions), added a 'data producer' class to see if I could have a chart to view data coming in from data acquisition. I discovered this is quite similar to another demo program (dynamicspline), but what I wanted was a separate thread producing data. I dont understand why this program does not work, it is as if the QChart is not getting the new data, but I inserted debugging to show data in the title of the graph, and it is clearly there. Why does the graph not update to show the scatter data as it comes in?

    I am attaching several source files, not sure I can separate out just one element to post here. Any help would be appreciated, I am evaluating QChart for possible roll into a large project I have been maintaining for > 10 years (started as Qt3).

    The .pro file:
    @
    !include( ../examples.pri ) {
    error( "Couldn't find the examples.pri file!" )
    }

    TARGET = scatterinteractions
    SOURCES += main.cpp
    chartview.cpp
    dataprod.cpp
    HEADERS +=
    chartview.h
    dataprod.h
    @

    Here's the ChartView.h
    @
    #ifndef CHARTVIEW_H
    #define CHARTVIEW_H

    #include <QChartGlobal>
    #include <QChartView>
    #include <QScatterSeries>
    #include "dataprod.h"

    QTCOMMERCIALCHART_USE_NAMESPACE

    class ChartView : public QChartView
    {
    Q_OBJECT

    public:
    ChartView(QWidget *parent = 0);
    ~ChartView();

    private slots:
    void handleNewData(const QPointF &nd);

    private:
    QScatterSeries *m_scatter;
    QScatterSeries *m_scatter2;
    dataprod m_Producer;
    };

    #endif // CHARTVIEW_H
    @

    The ChartView.cpp:
    @
    #include "chartview.h"
    #include <math.h>
    #include <QDebug>

    QTCOMMERCIALCHART_USE_NAMESPACE

    ChartView::ChartView(QWidget *parent)
    : QChartView(new QChart(), parent),
    m_scatter(0),
    m_scatter2(0)
    {
    setRenderHint(QPainter::Antialiasing);

    chart()->setTitle("Click to interact with scatter points");
    chart()->setAnimationOptions(QChart::SeriesAnimations);
    
    m_scatter = new QScatterSeries();
    m_scatter->setName("scatter1");
    m_scatter->setBorderColor(Qt::black);
    m_scatter->setColor(Qt::red);
    m_scatter->setMarkerShape(QScatterSeries::MarkerShapeRectangle);
    m_scatter->setMarkerSize(2.0);
    
    m_scatter2 = new QScatterSeries();
    m_scatter2->setName("scatter2");
    m_scatter2->setBorderColor(Qt::black);
    m_scatter2->setMarkerShape(QScatterSeries::MarkerShapeCircle);
    m_scatter2->setMarkerSize(2.0);
    m_scatter2->setMarkerSize(1.8);
    
    chart()->addSeries(m_scatter);
    chart()->addSeries(m_scatter2);
    chart()->createDefaultAxes();
    chart()->axisX()->setRange(0, 10.0);
    chart()->axisY()->setRange(-25.0, 25.0);
    
    connect(&m_Producer, SIGNAL(valueChanged(QPointF)), this, SLOT(handleNewData(QPointF)));
    m_Producer.setDelT(0.01);
    m_Producer.doInitData();
    m_Producer.doStart();
    

    }

    ChartView::
    ~ChartView()
    {
    }

    void
    ChartView::handleNewData(const QPointF &point)
    {
    m_scatter->append(point.x(),point.y());
    int sCt=m_scatter->count();
    QString msg=QString("Chart: #Pts=%1; X=%2; y=%3").arg(sCt).arg(point.x(),4,'g',3).arg(point.y(),4,'g',3);
    chart()->setTitle(msg);
    }
    @

    Now the data producer class:
    Header:
    @
    #ifndef DATAPROD_H
    #define DATAPROD_H

    #include <QObject>
    #include <QPointF>
    #include <QTimerEvent>

    class dataprod : public QObject
    {
    Q_OBJECT
    public:
    explicit dataprod(QObject *parent = 0);
    void setDelT(qreal v) {m_rDelT=v;}
    void doStart();
    void doInitData();

    signals:
    void valueChanged(QPointF newPt);

    private slots:
    void timerTick(qreal);

    protected:
    void timerEvent(QTimerEvent *);

    QPointF m_Data;
    qreal m_rDelT;
    
    int m_timerId;
    
    const qreal _noiseMag;
    
    const qreal _sin1Mag, _sin1Freq;
    const qreal _sin2Mag, _sin2Freq;
    

    };

    #endif // DATAPROD_H
    @

    And the .cpp file:
    @
    #include "dataprod.h"
    #include <math.h>

    dataprod::dataprod(QObject *parent) :
    QObject(parent), m_Data(0.0,0.0),
    _sin1Mag(5.0),_noiseMag(1.0),_sin1Freq(0.1),
    _sin2Mag(3.0),_sin2Freq(0.08),m_timerId(0)
    {
    }

    void
    dataprod::timerTick(qreal dt)
    {
    m_Data.rx()+=dt;
    qreal yval=_sin1Magsin(23.14159265359m_Data.rx()_sin1Freq);
    yval+=_sin1Mag/2.0;
    m_Data.setY(yval);
    emit valueChanged(m_Data);
    }

    void
    dataprod::timerEvent(QTimerEvent evt)
    {
    if (evt->timerId()==m_timerId)
    {
    m_Data.rx()+=m_rDelT;
    qreal yval=_sin1Mag
    sin(23.14159265359m_Data.rx()*_sin1Freq);
    yval+=_sin1Mag/2.0;
    m_Data.setY(yval);
    emit valueChanged(m_Data);
    }
    }

    void
    dataprod::doStart()
    {
    m_timerId=startTimer(10,Qt::PreciseTimer);
    }

    void
    dataprod::doInitData()
    {
    int i;
    for (i=0;i<100;i++)
    timerTick(0.01);
    }
    @


  • Lifetime Qt Champion

    Hi and welcome to DevNet,

    I have no access to QChart, but what does the doc say about addSeries ? Does it take the data and show them ? Or can the series be dynamically updated ?

    Maybe there is an update function to call after updating the series ?

    Hope these ideas help



  • According to the docs and the examples, when addSeries is appended, the graph should update automatically. I actually worked through a solution, have no clue what the difference is, but I went back to the example and added things step-by-step and it now works, though it did raise other issues. Will open a new thread for those.


  • Lifetime Qt Champion

    Glad that you made it work !

    Don't forget to update the thread's title to solved so other forum users may know that a solution has been found :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.