PDA

View Full Version : [Solved]Unable to calculate proper intervals for time plot



C403
4th June 2013, 09:53
Hey,

I've got this plot with a custom canvas, curve, legend and plotpicker. Everything works great. I'm trying to add date/time support on the x axis. This plot receives real time data and replots as new values arrive, x axis is time. For testing purposes I am firing off a signal every 1000ms that adds a point with a random [0,120] value on the y axis and the current time on the x axis. For the plot I am assigning the following for the scales:

From the StockChart example:

class DateScaleDraw: public QwtDateScaleDraw
{
public:
DateScaleDraw(Qt::TimeSpec timeSpec):
QwtDateScaleDraw( timeSpec )
{
setDateFormat(QwtDate::Millisecond, "hh:mm:ss:zzz\nddd dd MMM");
setDateFormat(QwtDate::Second, "HH:MM:ss\nddd dd MMM");
setDateFormat(QwtDate::Minute, "HH:MM\nddd dd MMM");
setDateFormat(QwtDate::Hour, "MM:MM\nddd dd MMM");
setDateFormat(QwtDate::Day, "ddd dd MMM yyyy");
setDateFormat(QwtDate::Week, "Www");
setDateFormat(QwtDate::Month, "MMM yyyy");
setDateFormat(QwtDate::Year, "yyyy");
}

};

Now:

QwtDateScaleDraw *scaleDraw = new DateScaleDraw(Qt::UTC );
QwtDateScaleEngine *scaleEngine = new QwtDateScaleEngine(Qt::UTC);

setAxisScaleDraw( QwtPlot::xBottom, scaleDraw );
setAxisScaleEngine( QwtPlot::xBottom, scaleEngine );

When my program starts the chart displays an empty canvas with the time scale starting at 1970, which is fine. However, as soon as data comes in from the timer the x axis readjusts to years, instead of seconds (how it should be, as far as I know) and the following happens:

http://s16.postimg.org/mfq8zsoed/Untitled.png

The points all get compressed on to the same line, since they are all only seconds apart and the axis is adjusting to years.

How can I force a fixed interval between the points (say, 60 seconds/minutes/hours/etc), I already have the moving and scrolling code in place after this interval is set, I'm just unsure as to how to do it for time values.

For non-time points I do this:

setAxisScale(QwtPlot::xBottom, m_curves[0]->data()->size()-m_pointsToDisplay, m_curves[0]->data()->size()); Which gives me a nice interval of size m_pointsToDisplay, but it doesn't seem to work for the datetime engine.

Thanks, OC.

Edit: Nevermind, I got it. I did the following, for whomever is interested:


double startx = data->sample(data->size()-m_pointsToDisplay).x();
double endx = data->sample(data->size()-1).x();
setAxisScale(QwtPlot::xBottom, startx, endx);

My data samples are in ms since epoch, so that worked well. Thanks anyhow, awesome work Uwe (In case you see this)

Uwe
4th June 2013, 10:18
Date/Time scales are expecting values as "msecs since Epoch" , but the range you are setting for the xBottom scale has nothing to do with it. For translating date/time values into doubles ( and v.v ) see QwtDate.

Uwe

PS: When implementing the date/time classes I noticed, that there is another use case, where a scale has to display a time interval ( msecs since some start point ), what is unrelated to the real date/time. But as it was too late for Qwt 6.1 I decided to postpone this one for the next release.

C403
4th June 2013, 17:47
Date/Time scales are expecting values as "msecs since Epoch" , but the range you are setting for the xBottom scale has nothing to do with it. For translating date/time values into doubles ( and v.v ) see QwtDate.

Uwe

PS: When implementing the date/time classes I noticed, that there is another use case, where a scale has to display a time interval ( msecs since some start point ), what is unrelated to the real date/time. But as it was too late for Qwt 6.1 I decided to postpone this one for the next release.

I am sending my x axis values as QDateTime::currentMSecsSinceEpoch() (or an equivalent representation). As a side note: this function returns an int64, and failing to cast this to a double causes problems for QwtDate.

I got my fixed scale working just fine, so once again, thanks.

-OC

Uwe
4th June 2013, 19:10
As a side note: this function returns an int64, and failing to cast this to a double causes problems for QwtDate.
Yes an int64 is no double and can't simply be casted - but as the plot framework works with doubles there is no way to get around these rounding issues.

By the way be aware of the fact that Qt5 and Qt4 differ internally how QDateTime stores the value. With Qt4 you run into overflows much earlier.

Uwe