Unsolved High CPU Usage when updating Chart Axis
-
Hi,
I'm trying to make a DateTime chart with live data. I have a timer on the chart that when triggered appends the latest value against the current time and sets the new min and max on the x axis.
I have tested just appending data and the performance is fine however the changing of the axis is causing the GUI thread to hit 100% usage after a short amount of time.
Is there a way to do this that has reasonable performance?
Example code:
ChartView { property double dataToAppend: -1; property int amountOfPoints: 200; antialiasing:true; backgroundColor:"transparent"; height:453; objectName:"chart"; theme:ChartView.ChartThemeDark; title:"Untitled"; width:1015; x:315; y:43; ValueAxis{id:"axisY"; max:3000; min:0;} DateTimeAxis{format:"mm:ss:z"; id:"axisX"; min:new Date(); max:new Date(); tickCount:10;} SplineSeries{axisX:axisX; axisY:axisY; name:"untitled"; objectName:"series"; useOpenGL:true;} Timer{ id:"refreshTimer" interval:1 / 60 * 1000 onTriggered:{ if(parent.series(0).count >= amountOfPoints) { parent.series(0).remove(0); } var now = new Date(); axisX.min = new Date(parent.series(0).at(0).x); axisX.max = now; parent.series(0).append(now.getTime(), parent.dataToAppend); } repeat:true; running:parent.dataToAppend >= 0; } }
-
Seems like you are consuming same data over and over again. Try this:
parent.series(0).append(now.getTime(), parent.dataToAppend); parent.dataToAppend = -1 // data consumed
-
Hi,
The dataToAppend property gets updated from a second process when new data arrives. As the graph is using a DateTimeAxis the point is to keep appending the data on a regular interval even if it hasn't changed to show the latest value.
The problem is that in order to show the newest data point, I'm having to change the max property of the axis to the latest timestamp. Doing this is causing the GUI thread to lock up.
Changing
parent.series(0).append(now.getTime(), parent.dataToAppend);
to
parent.series(0).append(now.getTime(), Math.random() * 3000);
Should result in the same problem.
-
I played with the Intel profiler a bit. Whenever axisX.min or axisY.min changes, a bunch of highly time consuming functions are called (like internal QtCharts::QDateTimeAxisPrivate::setRange()). I don't think you can do much here. I would rather take another approach - use 'fixed' axisX.min and axisX.max (check the 'Qml Oscillosope' example) and ovelay ChartView's 'native' x-axis legend with your custom legend component that updates on timer tick...
-
I suspected that would probably be the case with the axis changes. I expected real time charting to be a fairly common use case, so I was hoping there was an official way of solving this that I had missed.
The custom legend is an interesting idea, I'll take a look into it. Alternatively I have found that QCustomPlot supply a realtime demo http://www.qcustomplot.com/index.php/demos/realtimedatademo.
Thanks for taking a look into it.