Unsolved Multiple real time plots/charts
-
@VRonin I have "8 and more" charts simultaneously open and not one chart with 8 and more data points. Each chart does not have more than 3 data point series. As I understand the QAbstractTableModel is only for one single chart correct? So this probably wont safe me the majority of the performance but is still a good point for QCharts.
-
@framet said in Multiple real time plots/charts:
QAbstractTableModel is only for one single chart correct?
Nope. actually it QAbstractTableModel is perfect for when you have more than 1 chart.
How did you try to update the charts before?
-
@VRonin I'm currently not in the office so I cannot check to be 100% but i think i just added the to the respective QLineSeries.
-
@VRonin said in Multiple real time plots/charts:
Nope. actually it QAbstractTableModel is perfect for when you have more than 1 chart.
hey @VRonin im currently working on a test with QAbstractTableModel.
I have a model with 100 rows and 4 columns. If new values would overflow the memory a just start at row zero again.
The problem what I have and I can't find any solution for it is that when I update a specific row and emit dataChanged(topLeft,bottomRight) with the updated values QChart updates/repaints the hole model which leads to flickering when you go above 10 HZ.Is there a way to reimplement this QChart behavior or is there a flag to set?
Cheers
frametEdit: here is an example with 2 HZ https://imgur.com/a/DYR7L
Edit 2: just found out with linesSeries.setUseOpenGL() decreases the flickering
-
Wow, it's unbelievably slow... I'll prepare a minimal example and see if I get the same
-
Below are two tests with TableModel (100,4)
Both tests run with 20 HZ
With OpenGL on LineSeries enabledTest 1) Single chart https://imgur.com/a/Sfe20
Test 2) 6 charts http://imgur.com/a/FpicuWith OpenGL on LineSeries disabled
Test 3) 6 charts http://imgur.com/a/mnFagAs you can see the problem of QT getting slower with more charts relaying on the same Model still exists.
Edit: just to clarify YES the test before was with 2 HZ and those tests here are with 20 HZ :)
-
Tryed:
#include <QWidget> #include <QTimer> #include <QStandardItemModel> #include <QtCharts/QChart> #include <QtCharts/QChartView> #include <QGridLayout> #include <QtCharts/QVXYModelMapper> #include <QtCharts/QLineSeries> #include <cmath> QT_CHARTS_USE_NAMESPACE class TestChart : public QWidget { Q_OBJECT Q_DISABLE_COPY(TestChart) public: explicit TestChart(QWidget *parent = Q_NULLPTR) :QWidget(parent) , maixLength(360) , frequency(20.0) , shift(0.0) , currentCounter(0.0) , pi(std::acos(-1)) { m_model = new QStandardItemModel(this); m_model->insertColumns(0, 3); //m_model->insertRows(0, maixLength); m_updateTimer = new QTimer(this); m_updateTimer->setInterval(1000.0 / frequency); connect(m_updateTimer, &QTimer::timeout, this, &TestChart::addSeriesData); QGridLayout* mainLay = new QGridLayout(this); for (int i = 0; i < 15; ++i) { QLineSeries *sineSeries = new QLineSeries; sineSeries->setName("Sine Wave"); QVXYModelMapper *mapper = new QVXYModelMapper(this); mapper->setXColumn(0); mapper->setYColumn(1); mapper->setSeries(sineSeries); mapper->setModel(m_model); sineSeries->setColor(Qt::red); QLineSeries *cosineSeries = new QLineSeries; cosineSeries->setName("Cosine Wave"); mapper = new QVXYModelMapper(this); mapper->setXColumn(0); mapper->setYColumn(2); mapper->setSeries(cosineSeries); mapper->setModel(m_model); cosineSeries->setColor(Qt::blue); QChart *chart = new QChart(); chart->legend()->hide(); chart->addSeries(sineSeries); chart->addSeries(cosineSeries); chart->createDefaultAxes(); chart->axisX(sineSeries)->setMin(0); chart->axisX(sineSeries)->setMax(maixLength); chart->axisX(cosineSeries)->setMin(0); chart->axisX(cosineSeries)->setMax(maixLength); chart->axisY(sineSeries)->setMin(-1); chart->axisY(sineSeries)->setMax(1); chart->axisY(cosineSeries)->setMin(-1); chart->axisY(cosineSeries)->setMax(1); chart->setTitle("Simple line chart example"); QChartView *chartView = new QChartView(chart); chartView->setRenderHint(QPainter::Antialiasing); mainLay->addWidget(chartView,i/5,i%5 ); } m_updateTimer->start(); } private slots: void addSeriesData() { if (m_model->rowCount() <= currentCounter) m_model->insertRows(m_model->rowCount(), currentCounter - m_model->rowCount() + 1); m_model->setData(m_model->index(currentCounter, 0), currentCounter); m_model->setData(m_model->index(currentCounter, 1), std::sin((shift+currentCounter)*pi / 180.0)); m_model->setData(m_model->index(currentCounter, 2), std::cos((shift + currentCounter)*pi / 180.0)); currentCounter += 1.0; if (currentCounter >= maixLength) { currentCounter = 0.0; shift += 90; } } private: const double pi; double shift; double currentCounter; double frequency; QTimer* m_updateTimer; QAbstractItemModel* m_model; const int maixLength; };
15 charts, you are right, 20Hz it's not great even if in release mode is better.
-
Do you have any idea how to get 15 charts without severe performance issues?
Except outsourcing single Charts to seperate Qt-Applications and send data over ipc or something in this direction. -
I think yo have to decouple the data arrival frequency to the frequency you send the data to the chart.
In the QAbstractTableModel instead of emitting
dataChanged()
directly, every time a new datapoint arrives (re)start a signle shot timer that emits the signal. I'll try implementing it and update this postEDIT:
My method increased but not to an acceptable level. I have to give up
-
@VRonin thank you for your time and effort!!!
I still have some ideas left. Will post it here when one gives an acceptable result.
cheers!
-
@framet Hey framet. Did you find a solution?
-
I am working with a application that has 12 curves and I am have the same problem, if I increase the number of curves, the performance decrease. I use qcustomplot. I need to plot 300pixels/second. Does anyone have some ideas?