home *** CD-ROM | disk | FTP | other *** search
- /* xsnewplots - 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 "osdef.h"
- #ifdef ANSI
- #include "xlproto.h"
- #include "xlsproto.h"
- #include "iviewproto.h"
- #include "Stproto.h"
- #else
- #include "xlfun.h"
- #include "xlsfun.h"
- #include "iviewfun.h"
- #include "Stfun.h"
- #endif ANSI
- #include "xlsvar.h"
-
- #ifdef ANSI
- void set_scale_shift(IVIEW_WINDOW,int,double,double),
- add_data(int ,LVAL,LVAL,LVAL),
- get_data(int,LVAL *,int *,LVAL *,int *),check_data(int,LVAL),
- adjust_plot_to_data(LVAL,LVAL);
- LVAL make_iview_object(int,int,LVAL),newplot(int);
- #else
- void set_scale_shift(),
- add_data()
- get_data(),check_data(),
- adjust_plot_to_data();
- LVAL make_iview_object(),newplot();
- #endif ANSI
-
- static void set_scale_shift(w, var, scale, shift)
- IVIEW_WINDOW w;
- int var;
- double scale, shift;
- {
- double old_scale, old_shift;
-
- old_scale = IViewScale(w, var);
- old_shift = IViewShift(w, var);
- if (scale != 0.0 && old_scale != 0.0) {
- scale = scale / old_scale;
- shift = shift - scale * old_shift;
- IViewApplyScaleShift(w, var, scale, shift);
- }
- }
-
- void StGrObAdjustToData(object, draw)
- LVAL object;
- int draw;
- {
- IVIEW_WINDOW w;
- double low, high, range, center;
- int i, vars;
- LVAL scale_type;
-
- w = GETIVIEWADDRESS(object);
- if (w != nil) {
- scale_type = slot_value(object, s_scale_type);
- vars = IViewNumVariables(w);
- high = 1.0; low = -high;
- if (scale_type == s_variable) {
- high = sqrt((double) vars); low = - high;
- for (i = 0; i < vars; i++) {
- IViewScaleToRange(w, i, -1.0, 1.0);
- IViewSetScaledRange(w, i, low, high);
- }
- }
- else if (scale_type == s_fixed) {
- if (vars > 0) {
- IViewGetVisibleRange(w, 0, &low, &high);
- set_scale_shift(w, 0, 1.0, -(high + low) / 2.0);
- range = high - low;
- for (i = 1; i < vars; i++) {
- IViewGetVisibleRange(w, i, &low, &high);
- set_scale_shift(w, i, 1.0, -(high + low) / 2.0);
- if (high - low > range) range = high - low;
- }
- range = sqrt((double) vars) * range / 2;
- for (i = 0; i < vars; i++) {
- center = -IViewShift(w, i);
- IViewSetRange(w, i, center - range, center + range);
- }
- }
- }
- else {
- for (i = 0; i < vars; i++) {
- IViewApplyScaleShift(w, i, 1.0, 0.0);
- IViewGetVisibleRange(w, i, &low, &high);
- IViewSetRange(w, i, low, high);
- }
- }
- if (draw) {
- send_message(object, sk_resize);
- send_message(object, sk_redraw);
- }
- }
- }
-
- LVAL iview_adjust_to_data()
- {
- LVAL object;
- LVAL arg;
- int draw;
-
- object = xlgaobject();
- if (! xlgetkeyarg(sk_draw, &arg)) arg = s_true;
- draw = (arg != NIL) ? TRUE : FALSE;
- StGrObAdjustToData(object, draw);
- return(NIL);
- }
-
- static LVAL make_iview_object(which, vars, rest)
- int which, vars;
- LVAL rest;
- {
- LVAL proto, object, args;
-
- switch (which) {
- case 'H': proto = getvalue(s_histogram_proto); break;
- case 'P':
- case 'L': proto = getvalue(s_scatterplot_proto); break;
- case 'R': proto = getvalue(s_spin_proto); break;
- case 'S': proto = getvalue(s_scatmat_proto); break;
- case 'N': proto = getvalue(s_name_list_proto); break;
- default: xlfail("unknown iview proto");
- }
-
- xlsave1(args);
- args = cons(NIL, rest);
- args = cons(sk_show, args);
- /* cons protects its arguments, so the new fixnum should be safe */
- args = cons(cvfixnum((FIXTYPE) vars), args);
- object = apply_send(proto, sk_new, args);
- xlpop();
- return(object);
- }
-
- static void get_data(which, data, vars, rest, show)
- int which, *vars, *show;
- LVAL *data, *rest;
- {
- LVAL x, y;
- int n;
-
- if (data == nil || vars == nil) return;
-
- switch (which) {
- case 'H':
- *data = xlgetarg();
- *vars = (consp(*data) && sequencep(car(*data))) ? seqlen(*data) : 1;
- *show = xsboolkey(sk_show, TRUE);
- *rest = makearglist(xlargc, xlargv);
- break;
- case 'P':
- case 'L':
- x = xlgetarg();
- if (consp(x) && sequencep(car(x))) *data = x;
- else {
- y = xlgetarg();
- *data = list2(x, y);
- }
- *vars = (consp(*data) && sequencep(car(*data))) ? seqlen(*data) : 1;
- *show = xsboolkey(sk_show, TRUE);
- *rest = makearglist(xlargc, xlargv);
- break;
- case 'R':
- case 'S':
- *data = xlgalist();
- *vars = seqlen(*data);
- *show = xsboolkey(sk_show, TRUE);
- *rest = makearglist(xlargc, xlargv);
- break;
- case 'N':
- *vars = 0;
- *data = xlgetarg();
- *show = xsboolkey(sk_show, TRUE);
- *rest = makearglist(xlargc, xlargv);
- if (! numberp(*data)) {
- n = seqlen(*data);
- *rest = cons(*data, *rest);
- *rest = cons(sk_point_labels, *rest);
- *data = cvfixnum((FIXTYPE) n);
- }
- break;
- default: xlfail("unknown iview proto");
- }
- }
-
- static void check_data(which, data)
- int which;
- LVAL data;
- {
- switch (which) {
- case 'H': break;
- case 'P':
- case 'L':
- case 'R':
- case 'S':
- if (! consp(data)) xlerror("not a list of sequences", data);
- for (; consp(data); data = cdr(data))
- if (! sequencep(car(data))) xlerror("not a sequence", car(data));
- break;
- case 'N': break;
- default: xlfail("unknown iview proto");
- }
- }
-
- static void add_data(which, object, data, rest)
- int which;
- LVAL object, data, rest;
- {
- LVAL args, message;
-
- xlsave1(args);
- args = cons(NIL, rest);
- args = cons(sk_draw, args);
- args = cons(data, args);
-
- switch (which) {
- case 'H':
- case 'P':
- case 'R':
- case 'S':
- case 'N': message = sk_add_points; break;
- case 'L': message = sk_add_lines; break;
- default: xlfail("unknown iview proto");
- }
-
- apply_send(object, message, args);
- xlpop();
- }
-
- static void adjust_plot_to_data(object, rest)
- LVAL object, rest;
- {
- LVAL args;
-
- xlsave1(args);
- args = cons(NIL, rest);
- args = cons(sk_draw, args);
- apply_send(object, sk_adjust_to_data, args);
- xlpop();
- }
-
- static LVAL newplot(which)
- int which;
- {
- int vars, show;
- LVAL object, data, rest, args;
-
- if (! StHasWindows()) xlfail("not available without windows");
-
- xlstkcheck(4);
- xlsave(object);
- xlsave(data);
- xlsave(args);
- xlsave(rest);
-
- get_data(which, &data, &vars, &rest, &show);
- check_data(which, data);
- object = make_iview_object(which, vars, rest);
- add_data(which, object, data, rest);
- adjust_plot_to_data(object, rest);
-
- xlpopn(4);
-
- if (show) send_message(object, sk_show_window);
-
- return(object);
- }
-
- LVAL xshistogram() { return(newplot('H')); }
- LVAL xsplot_points() { return(newplot('P')); }
- LVAL xsplot_lines() { return(newplot('L')); }
- LVAL xsspin_plot() { return(newplot('R')); }
- LVAL xsscatterplot_matrix() { return(newplot('S')); }
- LVAL xsnamelist() { return(newplot('N')); }
-