PDA

View Full Version : QwtScaleDraw is not update in realtime graph



alizadeh91
3rd September 2012, 15:10
Hi,,
I've implemented QwtScaleDraw to make a realtime graph like qwt example(cpu usage example):


class TimeScaleDraw: public QwtScaleDraw
{
public:
TimeScaleDraw(const QTime &base):
baseTime(base)
{
}
virtual QwtText label(double v) const
{
QTime upTime = baseTime.addMSecs((int)v);
return upTime.toString();
}

QTime baseTime;
};

I want to update baseTime to current time in every timer interval instead of adding to the array in every cycle.

i call setAxisScale(QwtPlot::yLeft,timeData[INTERVAL-1],timeData[0]) in every cycle but the timeData array is held to be fix (is 0 to 60 for 60 data to be plotted).)

Actually i want to my array(data of y axis) be fixed but baseTime will update in every cycle.
When i do that the labels are not changing. actually the label function is not calling because when i call setAxisScale in timer scale the scale seems to be constant but because the basetime is changing so it must update itself!!

How can i make this class to update itslef(call the label function whenever i call setAxisScale(QwtPlot::yLeft,timeData[INTERVAL-1],timeData[0]))( the timeData array is fix))

Uwe
3rd September 2012, 19:45
See QwtAbstractScaleDraw::invalidateCache: http://qwt.sourceforge.net/class_qwt_abstract_scale_draw.html#a4ed95cd23c5d77 9c1b05aa5295409aa6

Uwe

alizadeh91
3rd September 2012, 20:12
Thanks Uwe, As i said i override it but the problem is when i want to send current time to its implemented class(QwtScaleDraw) and when my array for y axis is fix and is not changing the y-axis also is not changing and updating. But i don't understand how to do that?

Forget to say my graph is vertically so i said y-axis!!

Added after 5 minutes:

Uwe, What i want to do : I've add QwtPlotGrid to realtime example of qwt. And the girds will moving as time. i want to fix labels to don't move as time. So i want instead of incrementing the array in timer, send current time in timer and add it by a constant array.

Uwe
4th September 2012, 07:30
As i said i override it ...
What has nothing to do with my link about QwtAbstractScaleDraw::invalidateCache ...


class TimeScaleDraw: public QwtScaleDraw
{
public:
....

void setBaseTime( const QTime &time )
{
m_baseTime = time;
invalidateCache();
}

....
private:
QTime m_baseTime;
};

Then the next replot will update the tick labels.

Uwe

alizadeh91
4th September 2012, 10:36
You are my hero man :D

alizadeh91
5th September 2012, 10:56
I'm sorry uwe!! but it won't work!!! it's not rescalling the axis.??

Uwe
5th September 2012, 11:20
What it does is to return different labels for the same values depending on the base time - without rescaling.
When you want to rescale I didn't get what you want to do.

Uwe

alizadeh91
5th September 2012, 12:30
I've implemented the way you suggested with invalidateCache(); But the problem is that when i run the program the real-time-axis is not updating!!! while the basebase time is updating and with that invalidateCache will be called. In the meanwhile when i for example open a dialog on plotter or make a right click on the graph, the real-time-axis will be updated!!! seems some things must be triggered !!! the replot didn't help me either.

Added after 20 minutes:

I've modified the cpuplot example the way i want it and attach it. i'll be very appreciated if take look at it. I've modified the cpuplot file. besides the attached project i've provided snapshots of the changes relative to native code:
sorry i forgot to attach:
81848185


class TimeScaleDraw: public QwtScaleDraw
{
public:
TimeScaleDraw(const QTime &base):
baseTime(base)
{
}
virtual QwtText label(double v) const
{
QTime upTime = baseTime.addSecs((int)v);
return upTime.toString();
}

void setBaseTime( const QTime &time )
{
baseTime = time;
invalidateCache();
}

private:
QTime baseTime;
};

//timer event in cpuplot class
void CpuPlot::timerEvent(QTimerEvent *)
{
for ( int i = dataCount; i > 0; i-- )
{
for ( int c = 0; c < NCpuData; c++ )
{
if ( i < HISTORY )
data[c].data[i] = data[c].data[i-1];
}
}

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

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

if ( dataCount < HISTORY )
dataCount++;
//---I've commented below codes to instead of incrementing array send current time
// for ( int j = 0; j < HISTORY; j++ )
// timeData[j]++;

scaleDraw->setBaseTime(currentTime);



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

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

replot();
}

Uwe
5th September 2012, 15:56
As the modification of the "scales" is not known to the scale widget you have to help with the update:


scaleDraw->setBaseTime(cpuStat.upTime());
axisWidget( QwtPlot::xBottom )->update();
replot();HTH,
Uwe

alizadeh91
5th September 2012, 16:05
That is exactly what i was looking for :)
You've saved a lot of my time.
Thanks again :)