LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Arbitrary axis label in strip chart

Hello all (again),
I know there's been lots of improvements to the strip charts in recent
versions, so is it possible to use arbitrary strings on the horizontal
(time) axis of a strip chart ?

Say when I send the new points in with PlotStripChart(), can I also mark the
event on the axis with a function call like MarkStrip("Open valve") so that
it moves along with the strip ? (with a grid line and/or a tick mark).

And if not, I think it would make a nice addition to have a custom display
format and an associated function for that purpose.
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 1 of 11
(4,644 Views)

Thanks for the suggestion, Gillaume. It's a good idea, and we might implement it in a future release.

 

Currently, although you can associate arbitrary strings with specific x-values, you can't have both strings and numeric (or time) values in the axis at the same time. You have to choose one or the other, which would probably not be very helpful for you.

 

Luis

0 Kudos
Message 2 of 11
(4,618 Views)
> Thanks for the suggestion, Gillaume. It's a good idea, and we might
> implement it in
> a future release. Currently, although you can associate arbitrary
> strings with
> specific x-values, you can't have both strings and numeric (or time)
> values in the axis
> at the same time. You have to choose one or the other, which would
> probably not be
> very helpful for you. Luis

I hope this makes the cut into the next version.
One reason that having text associated with specific x value is not
necessarily a good thing is for instance the following case: you have a stip
chart that adds a data point at _irregular_ interval (so the x axis is
basically time-based). Every once in a while you feed the current time
string into the axis, where it scrolls to the left as new values are added.
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 3 of 11
(4,596 Views)

So, it looks as if you're trying to work around the fact that the strip chart does not support non-uniform gaps between data points. Ideally, it should support it, and that is currently on of our higher priorities for improving the chart. So, for example, if you were to plot your first point at 10sec, the second at 20sec, and the third at 40sec, there should be twice as wide a gap between the second and third points, as between the first and the second points. This is something that you can't do today, since all three points are always equally spaced.

 

I'm not yet completely sure how your workaround of adding an arbitrary text label solves this problem. I suppose that placing a label under the last point that you plot might indicate thewhat  "real" time value for that point should be. And that means that you are hiding the default numeric/time labels of the x-axis, correct? So, for example, are you trying to get your axis to look something like this:

 

 

            |----------|----------|----------|----------|----------|----------|

            0         10         20         40         70         75         150

 

If so, I take it that you don't mind that the intervals are always equal, even if the "fake" labels represent non-equally-spaced data?

 

If this is the case, then you can  achieve this today by using axis label strings. You just have to associate a new label string with each successive point that you plot, like this:

 

0 - 0

1 - 10

2 - 20

3 - 40

4 - 70

5 - 75

6 - 150

...

 

(and as old data points scroll out of view, you should also remove the corresponding labels)

 

But having said this, the ideal solution, of course, would be for the strip chart to support non-uniform plotting, so that all this work would be unnecessary.

 

Luis

0 Kudos
Message 4 of 11
(4,589 Views)
I almost managed to do what I want using a combination of InsertAxisItem and
DeleteAxisItem, but one simple thing is missing: the x-axis coordinate of
the last point that was added to the strip chart !

if I use PlotStripChartPoint(Pnl, PNL_STRIP, Y), what is the X coordinate ?

If the strip is full and already scrolling, I can use GetAxisScalingMode to
get the Max coordinate, but that's not the right solution at the begining.

Thanks
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 5 of 11
(4,568 Views)

There isn't anything you can call that will give you the x-value. I think you'll just have to keep a counter for how many times you call PlotStripChartPoint and that's what your x-value (you will have to scale it, you change the x-axis gain from 1.0 to something else).

 

Luis

0 Kudos
Message 6 of 11
(4,562 Views)
> There isn't anything you can call that will give you the x-value. I think
> you'll just
> have to keep a counter for how many times you call PlotStripChartPoint and
> that's
> what your x-value (you will have to scale it, you change the x-axis gain
> from 1.0 to
> something else). Luis

I guess using a counter until the side is reached is a workaround. Is there
a reason why the x coordinate can't be obtained through some
GetCtrlAttribute call ? It could be used for a lot of things.

I have a more general question still on topic: I tried to use the absolute
time X axis, but it's not reliable (or I'm doing something wrong). I start
it as such so the the left is _now_ and each new point adds a given number
of seconds.

SetCtrlAttribute(S->Pnl, PNL_STRIPCHART, ATTR_XAXIS_OFFSET,
(double)time(NULL));
SetCtrlAttribute(S->Pnl, PNL_STRIPCHART, ATTR_XAXIS_GAIN, RefreshRate);

Then I have a timer call at a given rate. But this rate is not exact,
there's some drift (delayed interrupts?). So after a while the time values
written on the axis do not correspond anymore to the current time, and it
doesn't take long.

Try it with a program that does some heavy lifting while the timer ticks...
Maybe an async timer would be more precise in that case, but I'd be happy if
I can just label the X axis myself.
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 7 of 11
(4,534 Views)

Hello Gillaume,

 

The time units displayed in the chart are not sync'ed with any real clock. The values that are displayed are a function of the initial time that you specify on the axis, the plotting rate (or gain) that tells the graph the time interval between consecutive points, and the number of points that you've plotted so far. So, if your actual plotting rate becomes out of sync with the real-world time, then the time displayed in the chart will also become out of sync. In other words, it's the ideal time, not the real time.

 

If you're using a UI timer control to control your plotting rate, then it's expected that this will not be very accurate. The UI timer controls are okay for simple tasks, or for large intervals, or for applications in which the exact time isn't very important. Otherwise, you're better off using an async timer callback instead, which should definitely be more accurate.

 

Luis

0 Kudos
Message 8 of 11
(4,524 Views)

Hi Guillaume,

 

The screenshot from the "CVI for Linux" page looks like you have what you need in the new version:

 

http://sine.ni.com/nips/cds/view/p/lang/en/nid/203157 

 

Isn't that what you were asking for in the first post of this thread?

S. Eren BALCI
IMESTEK
0 Kudos
Message 9 of 11
(4,516 Views)
> The screenshot from the "CVI for Linux" page
> looks like you have what you need in the new version:

There's no version number mentioned on this page. Is there a new version of
CVI Linux ? When is the next one due ?

Well, between this, absolute time axis and the ability to define custom axis
labels, yes, there's more or less everything. I implemented what I needed
like that:

int CVICALLBACK cb_StripTimer (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2) {
static struct tm LastTM={0,0,0,0,0,0,0,0,0};

switch (event) {
case EVENT_TIMER_TICK:
CurrentTime=time (NULL);
CurrentTM=*localtime (&CurrentTime); // Corresponding time structure
strftime(CurrentTimeStr, 20, "%Y%m%d-%H%M%S", &CurrentTM);
strftime(CurrentTimeShortStr, 20, TimeFrmt, &CurrentTM);

switch (ChartsDuration) { // The changes are empirical
default:NeedNewLabel=(CurrentTM.tm_sec/20!=LastTM.tm_sec/20); break;
case 2 :NeedNewLabel=(CurrentTM.tm_min !=LastTM.tm_min ); break;
case 3 :NeedNewLabel=(CurrentTM.tm_min/10!=LastTM.tm_min/10); break;
case 4 :NeedNewLabel=(CurrentTM.tm_min/30!=LastTM.tm_min/30); break;
case 5 :NeedNewLabel=(CurrentTM.tm_hour/2!=LastTM.tm_hour/2); break;
case 6 :NeedNewLabel=(CurrentTM.tm_hour/6!=LastTM.tm_hour/6); break;
case 7 :NeedNewLabel=(CurrentTM.tm_yday !=LastTM.tm_yday ); break;
}
LastTM=CurrentTM;

UpdateStripCharts();
CurrentX++;
break;
}
return 0;
}

void UpdateStripCharts() {
double Min, CurrentValue, LowVal;
...
PlotStripChart(Pnl, PNL_STRIPCHART, ValAnal, NbAnal, 0, 0, VAL_INTEGER);

if (NeedNewLabel) {
// This is invalid until the scrolling has begun
GetAxisScalingMode (Pnl, PNL_STRIPCHART, VAL_BOTTOM_XAXIS, NULL, &Min,
&CurrentValue);
InsertAxisItem (Pnl, PNL_STRIPCHART, VAL_BOTTOM_XAXIS, -1,
CurrentTimeShortStr, Min(CurrentX, CurrentValue));

// Drop first label if below Min
GetAxisItem (Pnl, PNL_STRIPCHART, VAL_BOTTOM_XAXIS, 0, NULL, &LowVal);
if (LowVal<Min)
DeleteAxisItem (Pnl, PNL_STRIPCHART, VAL_BOTTOM_XAXIS, 0, 1);
}
}
}
--
Guillaume Dargaud
http://www.gdargaud.net/


0 Kudos
Message 10 of 11
(4,507 Views)