PDA

View Full Version : Real Time Plot & CPUPLOT Example



CodeFreak
5th January 2018, 07:47
Hi everyone,
I want to plot real time data in the form like CPUPLOT example which X axis varies according to time changes and
the curve is shifted to the left.
The CPUPLOT example has been decorated by some functions that make it hard a bit for beginners.
I do not have any idea that how X axis shifted according to time.

d_stranz
5th January 2018, 21:27
that make it hard a bit for beginners.

Maybe you shouldn't be trying to run before you have learned how to walk. If you don't know enough C++ or Qt to be able to study an example and understand it, you should probably start with simpler examples and learn from them first.


I do not have any idea that how X axis shifted according to time.

The cpuplot example doesn't actually monitor real CPU performance, it is a simulation that uses a set of fake numbers to show a set of simulated real-time curves that get updated by a timer.

All the real work occurs in the timerEvent() method in cpuplot.cpp.

In the example, there is a "timeData" array which holds the simulated time values; each time the timer fires, it increases each one of the values in the array by 1 second. Time 0 is the time when the program starts, not the real world time, and each value after that is just one second later.

Basically, each time the timerEvent occurs, it

- shifts the performance (y) axis values up by one position,
- inserts a single new y value at the front of each performance array,
- increments every time value by 1 to simulate moving forward in time by one second,
- updates the time axis with the new time range,
- sets the adjusted data and time array values on their curves
- and tells the plot to redraw.

Here is an annotated version of the CpuPlot:: timerEvent() method:



void CpuPlot::timerEvent( QTimerEvent * )
{
// This works backward, from the last item in each data array down to -second- entry
// because we want to shift every element up by one position so we can put a new
// value at position 0
// The "datacount" variable goes from 0 to HISTORY - 1 (the maximum size of the arrays)

for ( int i = dataCount; i > 0; i-- )
{
for ( int c = 0; c < NCpuData; c++ ) // for each data array
{
if ( i < HISTORY )
data[c].data[i] = data[c].data[i-1]; // shift each entry up by one position
}
}

// Put the latest User and System performance values into position 0 of their arrays
// CpuStat::statistic() simply looks up hard-coded values from an array

cpuStat.statistic( data[User].data[0], data[System].data[0] );

// Compute the new Total and Idle performance values from the new User and System values

data[Total].data[0] = data[User].data[0] + data[System].data[0];
data[Idle].data[0] = 100.0 - data[Total].data[0];

// Increase the datacount value unless it has already reached the maximum (HISTORY - 1).
// Once datacount reaches its maximum value, the shifting of the data arrays above will just result
// in the earliest values (at data[User].data[HISTORY - 1], for example) being replaced by the values at
// HISTORY - 2 and therefore just being "scrolled" out of the data arrays.

if ( dataCount < HISTORY )
dataCount++;

// NOW, here's where the time data gets adjusted by adding 1 second to each value in the timeData array
// This results in every time value being shifted forward by 1 second, simulating the movement of time.

// The timeData array was initialized in the CpuPlot constructor by putting HISTORY values into it, starting at
// HISTORY - 1 and going backwards to 0 (that is, timeData[0] = HISTORY - 1 and timeData[HISTORY -1] = 0)

for ( int j = 0; j < HISTORY; j++ )
timeData[j]++;

// and HERE is where the x (time) axis range gets adjusted to reflect the new time range in timeData.
// The axis scale goes backward so that the values for the current time are always the -leftmost- data items.

setAxisScale( QwtPlot::xBottom, timeData[HISTORY - 1], timeData[0] );

// Finally, the new time and performance data have to be re-set onto the plot. The setRawSamples() method
// tells the plot to use the data from the arrays directly instead of making a copy. (setSamples() makes a copy)

for ( int c = 0; c < NCpuData; c++ )
{
data[c].curve->setRawSamples( timeData, data[c].data, dataCount );
}

// And finally, finally, tell the plot to redraw itself since the x-axis range and the curves have all changed.

replot();
}


If you still don't understand after this explanation, then the code really is too hard for your current level of knowledge, and you need to start with something more basic.

Uwe
6th January 2018, 10:30
The cpuplot example doesn't actually monitor real CPU performance, it is a simulation.
Usually it is no simulation - it reads the data from "/proc/stat", what is the API of the kernel to retrieve the real CPU performance !

Only on rather exotic systems where a proc filesystem doesn't exists ( f.e Windows ) it it falls back on values that have been recorded on my box.

Uwe

d_stranz
7th January 2018, 00:50
Usually it is no simulation

Ah, true if you aren't stuck on Windoze (which I would hardly call "exotic" :) ). I was just looking at the beginning of the file and the table of hard-coded values.