View Raw SPL
/*****************************************************************************
* *
* XYCHART.SPL Copyright (C) 2007 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Overlays an XY table in a stripchart fashion *
* *
* Revisions: 27 Feb 2007 RRR Creation *
* 1 Mar 2007 RRR color support *
* *
*****************************************************************************/
#include
#if @HELP_XYCHART
XYCHART
Purpose: Overlays a multi-column XY table with separate stacked scales.
Syntax: XYCHART(xytable, altscales, gap, xgrid, ygrid, color1, ..., colorN)
xytable - Optional. A multi-column series where the first
column is the X values for the remaining columns.
Defaults the table in the current window.
altscales - Optional. An integer, the scales location.
0: left side of window (default)
1: alternate left and right sides
gap - Optional. A real bewteen 0 and 100. The
percentage gap between each overlay. Defaults
to 0.0, no gap.
xgrid - Optional. An integer, the X grid style for
each overlay.
-1: inherit current window style (default)
0: no grids
1: solid
2: dashed
3: dotted
ygrid - Optional. An integer, the Y grid style for
each overlay. Defaults to XGRID.
-1: inherit current window style
0: no grids
1: solid
2: dashed
3: dotted
colorN - Optional. A list of integers, the color for each
series. Defaults to -1, each series automatically
set to a different color. If only one color is
specified, all the series are set to that color.
Returns: Nothing, the series are displayed as a stacked stripchart.
Example:
W1: xychart(ravel(1..100, 1..100, gnorm(100, 1), integ(gnorm(100,1))))
W1 contains a stripchart of 3 XY series spaced equally apart. The
X values are set to the values of the first column.
Example:
W1: xychart(ravel(1..100, 1..100, gnorm(100, 1), integ(gnorm(100,1))), 1, 10, 3, lblue)
Same as above accept the scales alternate, a 10 percent gap is
inserted between each overlay, dotted grids are displayed and
each series is plotted in light blue.
Example:
W1: xychart(ravel(1..100, 1..100, gnorm(100, 1), integ(gnorm(100,1))), 1, 10, 3)
W2: integ(w1);xychart(1, 10, 3);setcolor(lred, 3)
W1 contains a 3 trace stripchart. W2 integrates each trace and
displays a stripchart with alternating scales, a 10 percent gap
and dotted grids. The color of the third trace is set to light
red.
When W1 changes, W2 will automatically integrate each series in
W1 and display the result in W2 as a stripchart.
Remarks:
XYCHART can operate on a XY table input series as shown in
the first example. The first column of the table is used
as the X values for the remaining columns. XYCHART can
also be used to set a plot style as part a Window formula
(shown in W2 of the last example) or on a standalone
basis.
If no colors are specified, each series is automatically
plotted in a different color.
If only one color is specified, all series are plotted in
that color.
XYCHART uses SPANY and SETY to arrange the series as
overlays with separate, stacked scales.
See STRIPCHART for a generic stripchart function.
See Also:
Setyauto
Spany
Staggery
Stripchart
#endif
/* create an xy stripchart display */
xychart(argv)
{
local i, k, gap, alt, s, nc, nfoc, xgrid, ygrid;
local n, color, colors, colset, incolors;
/* disable display */
poff;
numser = 0;
alt = 0; /* alternating scales - off */
gap = 0.0; /* gap between overlays as percentage - none */
xgrid = -1; /* xgrid style - unspecified */
ygrid = -1; /* ygrid style - unspecified */
colset = 0; /* color unspecified */
/* parse args */
if (argc > 0)
{
loop (i = 1..argc)
{
if (isarray(getargv(i)))
{
/* input series */
numser++;
}
else
{
/* alternative scales, gap percentage and grids */
alt = castint(getargv(i));
if (argc > i)
{
gap = castreal(getargv(i + 1));
}
if (argc > i + 1)
{
xgrid = castint(getargv(i + 2));
}
if (argc > i + 2)
{
ygrid = castint(getargv(i + 3));
}
else
{
ygrid = xgrid;
}
if (argc > i + 3)
{
/* remaining values are colors */
n = argc - i - 3;
incolors = -1 * ones(n, 1);
loop (k = 1..n)
{
incolors[k] = castint(getargv(k + i + 3));
}
colset = 1;
}
break;
}
}
}
if (numser > 0)
{
/* stick empty series in window to preserve window formula */
{};
/* have list of series - create overlays */
loop (i = 1..numser)
{
nc = numcols(getargv(i));
if (nc > 1)
{
/* assume first column is x values */
x = col(getargv(i), 1);
loop (k = 2..nc)
{
if (i == 1 && k == 2)
{
/* primary XY series */
xy(x, col(getargv(i), 2));
}
else
{
overlay(xy(x, col(getargv(i), k)));
}
}
}
else
{
if (i == 1)
{
getargv(i);
}
else
{
overlay(getargv(i));
}
}
}
/* default grids to primary series grid style */
if (xgrid < 0)
{
xgrid = getgridstyle(1);
}
if (ygrid < 0)
{
ygrid = getgridstyle(2);
}
}
else
{
/* no series args - check window for resident series */
if (getfocus(-1) == 1)
{
if (numitems > 1)
{
/* have multiple items, use stripchart function */
return(stripchart(argv));
}
/* have series but no overlays */
nc = numcols(W0);
/* get all series */
s = w0[.., ..];
if (nc > 1)
{
/* assume first column is x values */
x = col(s, 1);
loop (k = 2..nc)
{
if (k == 2)
{
/* primary XY series */
xy(x, col(s, 2));
}
else
{
overlay(xy(x, col(s, k)));
}
}
}
else
{
W0 = s;
}
}
/* default grids to primary series grid style */
if (xgrid < 0)
{
xgrid = getgridstyle(1);
}
if (ygrid < 0)
{
ygrid = getgridstyle(2);
}
}
/* number of overlayed spans */
nfoc = getfocus(-1);
/* overlay colors */
colors = -1 * ones(nfoc, 1);
if (colset)
{
if (length(incolors) == 1)
{
/* special case, set all colors */
color = incolors[1];
if (color == -1)
{
/* default to primary series color */
color = getwcolor(1);
}
colors[1..nfoc] = color;
}
else
{
/* use passed in colors */
n = min(nfoc, length(incolors));
colors[1..n] = incolors[1..n];
}
}
/* arrange all overlays with span and y range */
loop (i = 1..nfoc)
{
xychart_arrange(i, nfoc, alt, gap, xgrid, ygrid, colors[i]);
}
/* sync XY */
sync(3);
/* process as one item */
itemprocess(1);
/* show it */
pon;
}
/* set span and y range for stripchart display */
xychart_arrange(n, nfoc, alt, gap, xgrid, ygrid, color)
{
local f, yt, rt, rb, off, s, k;
if (argc < 2) nfoc = getfocus(-1);
if (argc < 3) alt = 0;
if (argc < 4) gap = 0;
if (argc < 5) xgrid = -1;
if (argc < 6) ygrid = xgrid;
if (argc < 7) color = -1;
/* get current focus and sync */
f = getfocus();
s = getsync();
/* focus on current trace with no syncing */
focus(1);
sync(0);
focus(n);
/* reset ytics and autoscale to find plot range */
setytic(-1);
setyauto(-1, -1);
setxtic(-1);
setxauto(-1, -1);
if (n == 1 && itemtype(refseries(1)) == 1)
{
/* range fix if first item is XY */
sety(min, max);
}
else
{
autoscale();
}
/* set scales - check for alternating y scale location */
if (n == 1)
{
/* first trace - Y left, X bottom with labels */
scales(2);
}
else
{
if (alt)
{
/* Y left or right with labels */
(n % 2 == 0) ? scales(14) : scales(13);
}
else
{
/* Y left with labels */
scales(13);
}
}
/* stagger and span for this focus */
staggery(0);
spany(min, max);
/* save tic interval */
yt = ytic;
if (getylog)
{
/* handle log scales */
#if 0
rt = real(ceil(log10(max / 10 ^ yt)) + yt);
rb = real(floor(log10(min / 10 ^ yt)) + yt);
#else
/* use automatic range */
rt = log10(getyt);
rb = log10(getyb);
#endif
}
else
{
/* linear scales */
rt = ceil(max / yt) * yt;
rb = floor(min / yt) * yt;
}
/* total plot range including gap percentage */
rg = (rt - rb) * (1 + gap / 100);
/* offset in window for this plot */
off = (nfoc + 1 - 2 * n);
/* plot factors for this plot */
k = (nfoc - 1) / 2;
off = (k - n + 1) * rg;
/* set y range to position this focus */
if (getylog)
{
sety(10 ^ (rb + (1 - n) * rg), 10 ^ (rt + (2 * k + 1 - n) * rg));
}
else
{
sety(rb + (1 - n) * rg, rt + (2 * k + 1 - n) * rg);
}
/* tics and grids */
setytic(yt);
if (xgrid >= 0)
{
setgridstyle(1, xgrid);
}
if (ygrid >= 0)
{
setgridstyle(2, ygrid);
}
if (color >= 0)
{
setcolor(color);
}
/* set vertical autoscale parameters */
setyauto(getyb, getyt);
focus(f);
sync(s);
return();
}