I saw how the CPU plot sample utilized subclassing QwtScaleDraw to make sure the displayed labels texts show the time. I've modified the class to use QDateTime instead of QTime and allowed to change the base time:
{
public:
baseTime(initialTime)
{
}
virtual QwtText label
(double v
) const {
QDateTime upTime
= baseTime.
addMSecs((int)v
);
return upTime.time().toString();
}
void updateBaseTime
(const QDateTime &updatedInitialTime
) {
baseTime = updatedInitialTime;
}
private:
};
class TimeScaleDraw: public QwtScaleDraw
{
public:
TimeScaleDraw(const QDateTime &initialTime):
baseTime(initialTime)
{
}
virtual QwtText label(double v) const
{
QDateTime upTime = baseTime.addMSecs((int)v);
return upTime.time().toString();
}
void updateBaseTime(const QDateTime &updatedInitialTime)
{
baseTime = updatedInitialTime;
}
private:
QDateTime baseTime;
};
To copy to clipboard, switch view to plain text mode
In my scenario I want to make sure the graph only displays the latest 10 seconds of data. On some updates I detect if the base time should be modified:
{
// mBaseTime is a QDateTime member of the class
double msecsToLatest = mBaseTime.msecsTo(latestDisplayed);
if (msecsToLatest > displayedRangeInMsecs)
{
mBaseTime = latestDisplayed.addMSecs(-displayedRangeInMsecs);
TimeScaleDraw
* scaleDraw
= (TimeScaleDraw
*)axisScaleDraw
(QwtPlot::xBottom);
scaleDraw->updateBaseTime(mBaseTime);
setAxisScale
(QwtPlot::xBottom,
0, displayedRangeInMsecs
);
}
return mBaseTime;
}
QDateTime MyPlot::setXAxisScale(QDateTime latestDisplayed, double displayedRangeInMsecs)
{
// mBaseTime is a QDateTime member of the class
double msecsToLatest = mBaseTime.msecsTo(latestDisplayed);
if (msecsToLatest > displayedRangeInMsecs)
{
mBaseTime = latestDisplayed.addMSecs(-displayedRangeInMsecs);
TimeScaleDraw* scaleDraw = (TimeScaleDraw*)axisScaleDraw(QwtPlot::xBottom);
scaleDraw->updateBaseTime(mBaseTime);
setAxisScale(QwtPlot::xBottom, 0, displayedRangeInMsecs);
}
return mBaseTime;
}
To copy to clipboard, switch view to plain text mode
Immediately after this code I draw points and call replot();
Even though the base time is updated the scale doesn't change. The expected behavior would be that my 0 becomes the updated base time.
Is there anything I'm missing? Is there a method to call for redrawing of the scale map?
Added after 19 minutes:
For now I have resolved this issue by always initializing a new TimeScaleDraw instead of updating the baseTime member.
// These two lines replaced
//TimeScaleDraw* scaleDraw = (TimeScaleDraw*)axisScaleDraw(QwtPlot::xBottom);
//scaleDraw->updateBaseTime(mBaseTime);
// with this:
setAxisScaleDraw
(QwtPlot::xBottom,
new TimeScaleDraw
(mBaseTime
));
// These two lines replaced
//TimeScaleDraw* scaleDraw = (TimeScaleDraw*)axisScaleDraw(QwtPlot::xBottom);
//scaleDraw->updateBaseTime(mBaseTime);
// with this:
setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw(mBaseTime));
To copy to clipboard, switch view to plain text mode
I'd still love to hear why my previous solution wouldn't work.
Bookmarks