/* xshistogram - XLISP interface to IVIEW dynamic graphics package. */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
#include "xlisp.h"
#include "xlstat.h"
#define HIST_MAX_BINS 50
#define HIST_INITIAL_BINS 6
#define NOT_IN_HIST -2
#define NO_MORE_POINTS -1
#define BIN_POINTER -1
#define HIST_CLICK_WIDTH 1
#define HIST_CLICK_HEIGHT 1
typedef struct hist_point {
int left, top, width, height, next;
} HistPoint;
typedef struct hist_bin {
int low, high, count, height, smallest;
} Bin;
typedef struct hist {
Bin bins[HIST_MAX_BINS];
char *point_data;
int num_bins, num_showing;
} *IViewHist;
extern LVAL s_histogram_internals, sk_draw, sk_redraw, sk_resize, s_true,
s_scale_type, sk_show, sk_show_window;
extern LVAL xsapplysubr(), iview_isnew(), makearglist();
/* forward declarations */
LOCAL VOID bad_hist_data(V);
LOCAL VOID IViewHistSetNumBins P3H(LVAL, LVAL, int);
LOCAL VOID clear_bins P1H(LVAL);
LOCAL VOID draw_hist P2H(IVIEW_WINDOW, LVAL);
LOCAL VOID initialize_points P4H(IVIEW_WINDOW, LVAL, int, int);
LOCAL int insert_point P5H(IVIEW_WINDOW, LVAL, int, int, int);
LOCAL int remove_non_showing_points P2H(IVIEW_WINDOW, LVAL);
LOCAL VOID find_point_rects P2H(IVIEW_WINDOW, LVAL);
LOCAL VOID hilite_points P2H(IVIEW_WINDOW, LVAL);
LOCAL int sect_point_rect P6H(LVAL, int, int, int, int, int);
LOCAL int sort_bins P2H(IVIEW_WINDOW, LVAL);
LOCAL VOID size_bins P2H(IVIEW_WINDOW, LVAL);
LOCAL VOID draw_hist_point_state P4H(IVIEW_WINDOW, LVAL, int, int);
LOCAL VOID set_density_range P3H(IVIEW_WINDOW, int, double);
static LVAL gethistdata P1C(LVAL, object)
{
LVAL val;
val = slot_value(object, s_histogram_internals);
if (! consp(val) || !adatap(car(val))) bad_hist_data();
return(val);
}
static HistPoint *getpointdata P1C(LVAL, hdata)
{
if (adatap(cdr(hdata)))
return((HistPoint *) StRPtr(getadaddr(cdr(hdata))));
else return(NULL);
}
static IViewHist getinternals P1C(LVAL, hdata)
{
if (getadaddr(car(hdata)) == NULL) bad_hist_data();
return((IViewHist) getadaddr(car(hdata)));
}
static VOID gethistargs P3C(IVIEW_WINDOW *, w, LVAL *, object, LVAL *, hdata)
{
*object = xlgaobject();
if (w != NULL) *w = (IVIEW_WINDOW) GETIVIEWADDRESS(*object);
if (hdata != NULL) *hdata = gethistdata(*object);
}
VOID newhistinternals P1C(LVAL, object)
{
LVAL val;
xlsave1(val);
val = newadata(sizeof(struct hist), 1, FALSE);
val = consa(val);
set_slot_value(object, s_histogram_internals, val);
xlpop();
}
static VOID allocate_internal_points P2C(LVAL, object, int, n)
{
LVAL val;
val = gethistdata(object);
if (adatap(cdr(val)))
reallocaddata(cdr(val), sizeof(struct hist_point), n);
else
rplacd(val, newadata(sizeof(struct hist_point), n, TRUE));
}
static VOID clear_internal_points P1C(LVAL, object)
{
LVAL val;
val = slot_value(object, s_histogram_internals);
if (! consp(val) || ! adatap(cdr(val))) bad_hist_data();
freeadata(cdr(val));
}
LOCAL VOID bad_hist_data(V) { xlfail("bad internal histogram data"); }
/**************************************************************************/
/** **/
/** Histogram Creation Functions **/
/** **/
/**************************************************************************/
LVAL iview_hist_isnew(V)
{
LVAL object, args, hdata;
int vars;
object = xlgaobject();
vars = getfixnum(xlgafixnum());
if (vars < 1) xlfail("bad number of variables for histogram");
newhistinternals(object);
hdata = gethistdata(object);
IViewHistSetNumBins(object, hdata, HIST_INITIAL_BINS);
clear_bins(hdata);
xlsave1(args);
args = makearglist(xlargc, xlargv);
args = cons(cvfixnum((FIXTYPE) (vars + 1)), args);
args = cons(object, args);
xsapplysubr(iview_isnew, args);
xlpop();
return(object);
}
LVAL iview_hist_allocate(V)
{
LVAL object;
IVIEW_WINDOW w;
int vars, show;
StGWWinInfo *gwinfo;
object = xlgaobject();
show = xsboolkey(sk_show, TRUE);
gwinfo = StGWObWinInfo(object);
w = IViewNew(object);
initialize_iview(w, object);
vars = IViewNumVariables(w);
StGrSetClickRange(gwinfo, HIST_CLICK_WIDTH, HIST_CLICK_HEIGHT);
StGrSetContentVariables(gwinfo, 0, vars - 1);
/* use StShowWindow to show (map) window but NOT send :resize or :redraw */
if (show) StShowWindow(w);
return(object);
}
/**************************************************************************/
/** **/
/** State Accessors and Mutators **/
/** **/
/**************************************************************************/
LOCAL VOID IViewHistSetNumBins P3C(LVAL, object, LVAL, hdata, int, n)
{
IViewHist h = getinternals(hdata);
if (n < 1 || n > HIST_MAX_BINS) return;
h->num_bins = n;
send_message(object, sk_resize);
}
static int IViewHistNumBins P1C(LVAL, hdata)
{
IViewHist h = getinternals(hdata);
return(h->num_bins);
}
LVAL iview_hist_num_bins(V)
{
LVAL object, hdata;
IVIEW_WINDOW w;
int bins;
gethistargs(&w, &object, &hdata);
if (moreargs()) {
bins = getfixnum(xlgafixnum());
IViewHistSetNumBins(object, hdata, bins);
check_redraw(object, TRUE, TRUE);
}
return(cvfixnum((FIXTYPE) IViewHistNumBins(hdata)));
}
LVAL iview_hist_bin_counts(V)
{
LVAL object, hdata, result, next;
IVIEW_WINDOW w;
int i, bins;
IViewHist h;
gethistargs(&w, &object, &hdata);
xllastarg();
if (hdata == NULL || (h = getinternals(hdata)) == NULL) result = NIL;
else {
bins = h->num_bins;
xlsave1(result);
result = mklist(bins, NIL);
for (i = 0, next = result; i < bins; i++, next = cdr(next))
rplaca(next, cvfixnum((FIXTYPE) h->bins[i].count));
xlpop();
}
return(result);
}
/**************************************************************************/
/** **/
/** Data Functions **/
/** **/
/**************************************************************************/
LVAL iview_hist_add_points(V)
{
IVIEW_WINDOW w;
int old_n, n;
LVAL object, data, hdata;
gethistargs(&w, &object, &hdata);
if (IVIEW_WINDOW_NULL(w)) return(NIL);
old_n = IViewNumPoints(w);
xlsave1(data);
data = xlgetarg();
data = (fixp(data) || (consp(data) && seqp(car(data))))
? data : consa(data);
internal_iview_add_points(w, object, data);
xlpop();
n = IViewNumPoints(w);
allocate_internal_points(object, n);
initialize_points(w, hdata, old_n, n);
check_add_to_screen(object, 'P', old_n, n, TRUE);
return(NIL);
}
LVAL iview_hist_clear_points(V)
{
IVIEW_WINDOW w;
LVAL object, hdata;
gethistargs(&w, &object, &hdata);
if (! IVIEW_WINDOW_NULL(w)) {
IViewClearPoints(w);
clear_bins(hdata);
clear_internal_points(object);
check_redraw(object, TRUE, TRUE);
}
return(NIL);
}
/**************************************************************************/
/** **/
/** Drawing and Resizing Functions **/
/** **/
/**************************************************************************/
static VOID IViewHistResize P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
IViewStdResize(w);
clear_bins(hdata);
initialize_points(w, hdata, 0, IViewNumPoints(w));
}
static VOID IViewHistRedrawContent P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
int left, top, width, height, x, y, vleft, vtop, vwidth, vheight;
StGWWinInfo *gwinfo;
gwinfo = IViewWindowWinInfo(w);
if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
IViewGetContentMarginRect(w, &left, &top, &width, &height);
StGrGetContentVariables(gwinfo, &x, &y);
StGWStartBuffering(gwinfo);
StGWSetClipRect(gwinfo, TRUE, left, top, width + 1, height + 1);
/*StGWEraseRect(gwinfo, left, top, width + 1, height + 1);*/
IViewClearContent(w);
sort_bins(w, hdata);
size_bins(w, hdata);
draw_hist(w, hdata);
IViewDrawDataLines(w, x, y, 0, IViewNumLines(w));
#ifdef USESTRINGS
IViewDrawDataStrings(w, x, y, 0, IViewNumStrings(w));
#endif /* USESTRINGS */
StGWBufferToScreen(gwinfo, left, top, width + 1, height + 1);
StGWGetViewRect(gwinfo, &vleft, &vtop, &vwidth, &vheight);
StGWSetClipRect(gwinfo, TRUE, vleft, vtop, vwidth, vheight);
if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
IViewResetScreenStates(w);
}
LVAL iview_hist_resize(V)
{
LVAL object, hdata;
IVIEW_WINDOW w;
gethistargs(&w, &object, &hdata);
if (! IVIEW_WINDOW_NULL(w)) IViewHistResize(w, hdata);
return(NIL);
}
LVAL iview_hist_redraw_content(V)
{
LVAL object, hdata;
IVIEW_WINDOW w;
gethistargs(&w, &object, &hdata);
if (! IVIEW_WINDOW_NULL(w)) IViewHistRedrawContent(w, hdata);
return(NIL);
}
LVAL iview_hist_adjust_to_data(V)
{
LVAL object;
IVIEW_WINDOW w;
StGWWinInfo *gwinfo;
double low, high;
int ticks, labeled, x, y, scaled, bins;
char *label;
LVAL arg, hdata;
gethistargs(&w, &object, &hdata);
if (! IVIEW_WINDOW_NULL(w)) {
gwinfo = StGWObWinInfo(object);
StGrObAdjustToData(object, FALSE);
scaled = (slot_value(object, s_scale_type) != NIL) ? TRUE : FALSE;
StGrGetContentVariables(gwinfo, &x, &y);
IViewGetRange(w, x, &low, &high);
label = IViewVariableLabel(w, x);
labeled = (label != NULL && strlen(label) != 0) ? TRUE : FALSE;
ticks = 4;
GetNiceRange(&low, &high, &ticks);
IViewSetRange(w, x, low, high);
IViewSetXaxis(w, ! scaled, labeled, ticks);
bins = 5 + log(1.0 + IViewNumPoints(w));
GetNiceRange(&low, &high, &bins);
if (bins > 1) bins --;
if (bins > 30) bins = 30;
IViewHistSetNumBins(object, hdata, bins);
if (! xlgetkeyarg(sk_draw, &arg)) arg = s_true;
if (arg != NIL) send_message(object, sk_resize);
if (arg != NIL) send_message(object, sk_redraw);
}
return(NIL);
}
/**************************************************************************/
/** **/
/** Mouse Functions **/
/** **/
/**************************************************************************/
LVAL iview_hist_adjust_screen(V)
{
IVIEW_WINDOW w;
LVAL object, hdata;
int x, y, lines_only = FALSE;
StGWWinInfo *gwinfo;
gethistargs(&w, &object, &hdata);
if (IVIEW_WINDOW_NULL(w)) return(NIL);
gwinfo = StGWObWinInfo(object);
if (StGrDirty(gwinfo)) {
StGrSetDirty(gwinfo, FALSE);
if (lines_only) {
if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
StGrGetContentVariables(gwinfo, &x, &y);
IViewDrawDataLines(w, x, y, 0, IViewNumLines(w));
#ifdef USESTRINGS
IViewDrawDataStrings(w, x, y, 0, IViewNumStrings(w));
#endif /* USESTRINGS */
if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
}
else {
IViewHistResize(w, hdata);
IViewHistRedrawContent(w, hdata);
}
}
return(NIL);
}
LVAL iview_hist_adjust_points_in_rect(V)
{
int i, n, in_rect;
PointState point_state;
IVIEW_WINDOW w;
int left, top, width, height;
PointState state;
LVAL object, hdata;
gethistargs(&w, &object, &hdata);
left = getfixnum(xlgafixnum());
top = getfixnum(xlgafixnum());
width = getfixnum(xlgafixnum());
height = getfixnum(xlgafixnum());
state = decode_point_state(xlgetarg());
if (IVIEW_WINDOW_NULL(w)) return(NIL);
IViewCheckLinks(w);
n = IViewNumPoints(w);
if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
for (i = 0; i < n; i++) {
point_state = IViewPointState(w, i);
if (! IViewPointMasked(w, i) && point_state != pointInvisible) {
in_rect = sect_point_rect(hdata, i, left, top, width, height);
if (in_rect && (int) point_state < (int) state) {
IViewSetPointState(w, i, state);
}
else if (! in_rect
&& state == pointHilited
&& point_state == pointHilited) {
IViewSetPointState(w, i, pointNormal);
}
}
}
IViewAdjustScreens(w);
if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
return(NIL);
}
LVAL iview_hist_mark_points_in_rect(V)
{
int i, n, in_rect;
PointState point_state;
IVIEW_WINDOW w;
int left, top, width, height;
LVAL object, hdata;
gethistargs(&w, &object, &hdata);
left = getfixnum(xlgafixnum());
top = getfixnum(xlgafixnum());
width = getfixnum(xlgafixnum());
height = getfixnum(xlgafixnum());
if (IVIEW_WINDOW_NULL(w)) return(NIL);
n = IViewNumPoints(w);
for (i = 0; i < n; i++) {
point_state = IViewPointState(w, i);
if (! IViewPointMasked(w, i) && point_state != pointInvisible) {
in_rect = sect_point_rect(hdata, i, left, top, width, height);
IViewSetPointMark(w, i, in_rect);
}
}
return(NIL);
}
LVAL iview_hist_adjust_screen_point(V)
{
IVIEW_WINDOW w;
LVAL object, hdata;
int point;
PointState state, screen_state;
gethistargs(&w, &object, &hdata);
point = getfixnum(xlgafixnum());
if (! IVIEW_WINDOW_NULL(w) && ! IViewPointMasked(w, point)) {
state = IViewPointState(w, point);
screen_state = IViewPointScreenState(w, point);
if (state == pointInvisible || screen_state == pointInvisible) {
StGrSetDirty(StGWObWinInfo(object), TRUE);
}
else {
draw_hist_point_state(w, hdata, point, state);
}
}
return(NIL);
}
/**************************************************************************/
/** **/
/** Internal Functions **/
/** **/
/**************************************************************************/
LOCAL VOID clear_bins P1C(LVAL, hdata)
{
IViewHist h = getinternals(hdata);
int i;
for (i = 0; i < h->num_bins; i++) {
h->bins[i].low = 0;
h->bins[i].high = 0;
h->bins[i].count = 0;
h->bins[i].height = 0;
h->bins[i].smallest = NO_MORE_POINTS;
}
}
LOCAL int sort_bins P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
IViewHist h = getinternals(hdata);
int i, k, low, high, val, x, y, n = IViewNumPoints(w);
int changed = FALSE;
StGWWinInfo *gwinfo;
gwinfo = IViewWindowWinInfo(w);
StGrGetContentVariables(gwinfo, &x, &y);
IViewGetScreenRange(w, x, &low, &high);
if (high <= low) return(FALSE);
if (remove_non_showing_points(w, hdata)) changed = TRUE;
for (i = 0; i < h->num_bins; i++) h->bins[i].count = 0;
h->num_showing = 0;
for (i = 0; i < n; i++) {
if (! IViewPointMasked(w, i) && IViewPointState(w, i) != pointInvisible) {
val = IViewPointScreenValue(w, x, i);
k = (h->num_bins * (val - low)) / (high - low);
if (k == h->num_bins && val == high) k--; /* on boundary of last bin */
if (k >= 0 && k < h->num_bins) {
h->bins[k].count++;
if (insert_point(w, hdata, x, i, k)) changed = TRUE;
h->num_showing++;
}
}
}
return(changed);
}
LOCAL VOID size_bins P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
IViewHist h = getinternals(hdata);
int i, low, high, width, x, y, maxcount, m;
double factor, density, x_low, x_high, range;
StGWWinInfo *gwinfo = IViewWindowWinInfo(w);
StGrGetContentVariables(gwinfo, &x, &y);
StGrGetContentRect(gwinfo, &low, NULL, &width, NULL);
high = low + width;
maxcount = 1;
for (i = 0; i < h->num_bins; i++) {
h->bins[i].low = low + (i * (high - low)) / h->num_bins;
h->bins[i].high = low + ((i + 1) * (high - low)) / h->num_bins;
maxcount = (h->bins[i].count > maxcount) ? h->bins[i].count : maxcount;
}
IViewGetScreenRange(w, y, &low, &high);
IViewGetScaledRange(w, x, &x_low, &x_high);
range = x_high - x_low;
m = h->num_showing;
density = (range > 0.0 && m > 0) ? 1.2 * (h->num_bins * maxcount / range) / m : 1.0;
set_density_range(w, y, density);
factor = ((double) (high - low)) / (maxcount * 1.2);
for (i = 0; i < h->num_bins; i++) {
h->bins[i].height = h->bins[i].count * factor;
}
find_point_rects(w, hdata);
}
LOCAL VOID draw_hist P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
IViewHist h = getinternals(hdata);
int i, left, top, width, height, content_top, content_height;
StGWWinInfo *gwinfo = IViewWindowWinInfo(w);
StGrGetContentRect(gwinfo, NULL, &content_top, NULL, &content_height);
for (i = 0; i < h->num_bins; i++) {
left = h->bins[i].low;
top = content_top + content_height - h->bins[i].height;
width = h->bins[i].high - left + 1;
height = h->bins[i].height + 1;
StGWFrameRect(gwinfo, left, top, width, height);
}
hilite_points(w, hdata);
}
LOCAL VOID initialize_points P4C(IVIEW_WINDOW, w, LVAL, hdata, int, m, int, n)
{
HistPoint *points;
int i;
if (m < 0 || n > IViewNumPoints(w)) return;
points = getpointdata(hdata);
for (i = m; i < n; i++) {
points[i].left = 0;
points[i].top = 0;
points[i].width = 0;
points[i].height = 0;
points[i].next = NOT_IN_HIST;
}
}
LOCAL int insert_point P5C(IVIEW_WINDOW, w, LVAL, hdata, int, var, int, p, int, bin)
{
IViewHist h = getinternals(hdata);
int last, current, bin_value, point_value;
HistPoint* points;
points = getpointdata(hdata);
if (points[p].next != NOT_IN_HIST) return(FALSE); /* already in hist */
point_value = IViewPointScreenValue(w, var, p);
last = BIN_POINTER;
current = h->bins[bin].smallest;
bin_value = (current >= 0) ? IViewPointScreenValue(w, var, current) : 0;
while (bin_value < point_value && current != NO_MORE_POINTS) {
last = current;
current = points[current].next;
bin_value = (current >= 0) ? IViewPointScreenValue(w, var, current) : 0;
}
points[p].next = current;
if (last == BIN_POINTER) h->bins[bin].smallest = p;
else points[last].next = p;
return(TRUE);
}
LOCAL int remove_non_showing_points P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
IViewHist h = getinternals(hdata);
int last, next, showing, p, bin;
HistPoint* points;
int changed = FALSE;
points = getpointdata(hdata);
for (bin = 0; bin < h->num_bins; bin++)
for (p = h->bins[bin].smallest, last = BIN_POINTER; p >= 0;) {
showing = (! IViewPointMasked(w, p) && IViewPointState(w, p) != pointInvisible);
if (showing) {
last = p;
p = points[p].next;
}
else {
changed = TRUE;
if (last == BIN_POINTER) h->bins[bin].smallest = points[p].next;
else points[last].next = points[p].next;
next = points[p].next;
points[p].next = NOT_IN_HIST;
p = next;
}
}
return(changed);
}
LOCAL VOID find_point_rects P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
IViewHist h = getinternals(hdata);
int showing, p, k, bin, bin_width, bin_left, height, bottom, top, count, base;
HistPoint* points;
StGWWinInfo *gwinfo;
gwinfo = IViewWindowWinInfo(w);
points = getpointdata(hdata);
StGrGetContentOrigin(gwinfo, NULL, &base);
for (bin = 0; bin < h->num_bins; bin++) {
bin_left = h->bins[bin].low + 1;
bin_width = h->bins[bin].high - h->bins[bin].low - 1;
count = h->bins[bin].count;
height = h->bins[bin].height - 1;
for (p = h->bins[bin].smallest, k = 0; p >= 0; p = points[p].next) {
showing = (! IViewPointMasked(w, p) && IViewPointState(w, p) != pointInvisible);
if (showing) {
points[p].left = bin_left;
points[p].width = bin_width;
bottom = base - ((count > 0) ? (height * k) / count : 0);
top = base - ((count > 0) ? (height * (k + 1)) / count : 0);
points[p].top = top;
points[p].height = bottom - top;
k++;
}
}
}
}
LOCAL VOID hilite_points P2C(IVIEW_WINDOW, w, LVAL, hdata)
{
int p, n = IViewNumPoints(w);
HistPoint* points;
int oldcolor = 0, color = 0, use_color;
StGWWinInfo *gwinfo;
gwinfo = IViewWindowWinInfo(w);
points = getpointdata(hdata);
if (points == NULL) return;
use_color = StGWUseColor(gwinfo);
for (p = 0; p < n; p++)
if (points[p].next != NOT_IN_HIST && IViewPointState(w, p) != pointNormal) {
if (use_color) {
oldcolor = StGWDrawColor(gwinfo);
color = IViewPointColor(w, p);
if (color != NOCOLOR) StGWSetDrawColor(gwinfo, color);
}
StGWPaintRect(gwinfo, points[p].left, points[p].top,
points[p].width, points[p].height);
if (use_color && color != NOCOLOR) StGWSetDrawColor(gwinfo, oldcolor);
}
}
LOCAL int sect_point_rect P6C(LVAL, hdata,
int, p,
int, left, int, top, int, width, int, height)
{
int right, bottom, p_right, p_bottom;
HistPoint* points;
points = getpointdata(hdata);
right = left + width;
bottom = top + height;
p_right = points[p].left + points[p].width;
p_bottom = points[p].top + points[p].height;
left = (left > points[p].left) ? left : points[p].left;
top = (top > points[p].top) ? top : points[p].top;
right = (right < p_right) ? right : p_right;
bottom = (bottom < p_bottom) ? bottom : p_bottom;
return((left <= right) && (top <= bottom));
}
LOCAL VOID draw_hist_point_state P4C(IVIEW_WINDOW, w, LVAL, hdata, int, p, int, state)
{
HistPoint* points;
int oldcolor = 0 , color = 0, use_color;
StGWWinInfo *gwinfo;
gwinfo = IViewWindowWinInfo(w);
points = getpointdata(hdata);
if (state == pointNormal)
StGWEraseRect(gwinfo, points[p].left, points[p].top,
points[p].width, points[p].height);
else {
use_color = StGWUseColor(gwinfo);
if (use_color) {
oldcolor = StGWDrawColor(gwinfo);
color = IViewPointColor(w, p);
if (color != NOCOLOR) StGWSetDrawColor(gwinfo, color);
}
StGWPaintRect(gwinfo, points[p].left, points[p].top,
points[p].width, points[p].height);
if (use_color && color != NOCOLOR) StGWSetDrawColor(gwinfo, oldcolor);
}
IViewSetPointScreenState(w, p, (PointState) state);
}
LOCAL VOID set_density_range P3C(IVIEW_WINDOW, w, int, y, double, density)
{
int showing, labeled, ticks;
double low = 0.0;
IViewGetYaxis(w, &showing, &labeled, &ticks);
if (showing) {
GetNiceRange(&low, &density, &ticks);
IViewSetYaxis(w, showing, labeled, ticks);
}
IViewSetRange(w, y, 0.0, density);
}
syntax highlighted by Code2HTML, v. 0.9.1