home *** CD-ROM | disk | FTP | other *** search
- /* xsscatmat - 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 get_plot_layout(IVIEW_WINDOW,int *,int *,int *),
- DrawLabel(IVIEW_WINDOW,int),find_current_plot(IVIEW_WINDOW,int,int),
- ScatDrawPoint(IVIEW_WINDOW,int,PointState,PointState),
- scat_draw_point(IVIEW_WINDOW,int,PointState),
- find_current_plot(IVIEW_WINDOW,int,int);
- LVAL scatmat_add_data(int),iview_scatmat_mouse(int);
- #else
- void get_plot_layout(),
- DrawLabel(),find_current_plot(),
- ScatDrawPoint(),
- scat_draw_point(),
- find_current_plot();
- LVAL scatmat_add_data(),iview_scatmat_mouse();
- #endif ANSI
-
- #define SCAT_PLOT_GAP 1
- #define SCAT_INSET 4
- #define LABEL_OFFSET 5
- #define MAX_NUM_VARS 10
-
- #define VAR_FORMAT "var %d"
- #define POINT_FORMAT "%d"
-
- static int pdata[MAX_NUM_VARS];
-
- static struct {
- int x, y, left, top, size, bottom;
- } current;
-
- /**************************************************************************/
- /** **/
- /** Plot Creation Functions **/
- /** **/
- /**************************************************************************/
-
- LVAL iview_scatmat_allocate()
- {
- LVAL object;
- int i, vars, show;
- IVIEW_WINDOW w;
- char s[100];
-
- object = xlgaobject();
- show = xsboolkey(sk_show, TRUE);
-
- get_iview_ivars(object, &vars);
- if (vars < 2) xlfail("Too few variables for scatmat");
- if (vars > MAX_NUM_VARS) xlfail("Too many variables for scatmat");
-
- w = IViewNew(object);
-
- /* should replace this by something lisp-based +++++++ */
- for (i = 0; i < vars; i++) {
- sprintf(s, VAR_FORMAT, i);
- IViewSetVariableLabel(w, i, s);
- IViewSetRange(w, i, 0.0, 1.0);
- }
-
- initialize_iview(w, object);
- /* use StShowWindow to show (map) window but NOT send :resize or :redraw */
- if (show) StShowWindow(w);
- return(object);
- }
-
- /**************************************************************************/
- /** **/
- /** Data Functions **/
- /** **/
- /**************************************************************************/
-
- static LVAL scatmat_add_data(which)
- int which;
- {
- IVIEW_WINDOW w;
- LVAL data, object;
- int old_n, n;
-
- object = xlgaobject();
- w = GETIVIEWADDRESS(object);
- if (w == nil) return(NIL);
- data = xlgetarg();
-
- switch(which) {
- case 'P':
- old_n = IViewNumPoints(w);
- internal_iview_add_points(w, object, data);
- n = IViewNumPoints(w);
- break;
- case 'L':
- old_n = IViewNumLines(w);
- internal_iview_add_lines(w, object, data);
- n = IViewNumLines(w);
- break;
- #ifdef USESTRINGS
- case 'S':
- old_n = IViewNumStrings(w);
- internal_iview_add_strings(w, object, data);
- n = IViewNumStrings(w);
- break;
- #endif /* USESTRINGS */
- }
-
- check_add_to_screen(object, which, old_n, n, TRUE);
-
- return(NIL);
- }
-
- LVAL iview_scatmat_add_points() { return(scatmat_add_data('P')); }
- LVAL iview_scatmat_add_lines() { return(scatmat_add_data('L')); }
- #ifdef USESTRINGS
- LVAL iview_scatmat_add_strings() { return(scatmat_add_data('S')); }
- #endif /* USESTRINGS */
-
- /**************************************************************************/
- /** **/
- /** Drawing and Resizing Functions **/
- /** **/
- /**************************************************************************/
-
- LVAL iview_scatmat_resize()
- {
- int vars;
- int i, top, left, subsize, low, high;
- IVIEW_WINDOW w;
- LVAL object;
-
- object = xlgaobject();
- xllastarg();
-
- w = GETIVIEWADDRESS(object);
- if (w == nil) return(NIL);
-
- vars = IViewNumVariables(w);
- IViewSetFixedAspect(w, TRUE);
- IViewStdResize(w);
-
- get_plot_layout(w, &left, &top, &subsize);
-
- for (i = 0; i < vars; i++) {
- low = i * (subsize + SCAT_PLOT_GAP) + 2 * SCAT_INSET + SCAT_PLOT_GAP;
- high = low + subsize - 3 * SCAT_INSET;
- IViewSetScreenRange(w, i, low, high);
- }
- return(NIL);
- }
-
- LVAL iview_scatmat_redraw_content()
- {
- int vars;
- int left, top, subleft, subtop, subsize;
- int viewleft, viewtop, viewwidth, viewheight;
- int i, j;
- double low, high;
- char s[100];
- IVIEW_WINDOW w;
- LVAL object, scale_type;
- /* char */ StGWWinInfo *gwinfo; /* changed JKL */
-
- object = xlgaobject();
- xllastarg();
-
- gwinfo = StGWObWinInfo(object);
- w = GETIVIEWADDRESS(object);
- if (w == nil) return(NIL);
-
- vars = IViewNumVariables(w);
- if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
- StGWGetViewRect(gwinfo, &viewleft, &viewtop, &viewwidth, &viewheight);
- get_plot_layout(w, &left, &top, &subsize);
- scale_type = slot_value(object, s_scale_type);
-
- StGWStartBuffering(gwinfo);
- StGWEraseRect(gwinfo, viewleft, viewtop, viewwidth, viewheight);
- for (i = 0; i < vars; i++)
- for (j = 0; j < vars; j++) {
- subleft = left + j * (SCAT_PLOT_GAP + subsize);
- subtop = top + (vars - i - 1) * (SCAT_PLOT_GAP + subsize);
- StGWFrameRect(gwinfo, subleft, subtop, subsize, subsize);
- if (i == j && scale_type == NIL) {
- if (IViewVariableLabel(w, i) != 0)
- StGWDrawText(gwinfo, IViewVariableLabel(w, i),
- subleft + subsize / 2, subtop + subsize / 2, 1, 0);
- IViewGetRange(w, i, &low, &high);
- sprintf(s, "%.3lg", high);
- StGWDrawText(gwinfo, s,
- subleft + subsize - SCAT_INSET,
- subtop + SCAT_INSET, 2, 1);
- sprintf(s, "%.3lg", low);
- StGWDrawText(gwinfo, s,
- subleft + SCAT_INSET,
- subtop + subsize - SCAT_INSET, 0, 0);
- }
- else if (i != j) {
- IViewDrawDataPoints(w, i, j, 0, IViewNumPoints(w));
- IViewDrawDataLines(w, i, j, 0, IViewNumLines(w));
- #ifdef USESTRINGS
- IViewDrawDataStrings(w, i, j, 0, IViewNumStrings(w));
- #endif /* USESTRINGS */
- }
- }
- StGWBufferToScreen(gwinfo, viewleft, viewtop, viewwidth, viewheight);
- if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
- IViewResetScreenStates(w);
- return(NIL);
- }
-
- /**************************************************************************/
- /** **/
- /** Mouse Functions **/
- /** **/
- /**************************************************************************/
-
- /*extern LVAL peekarg(); in headers JKL */
-
- static LVAL iview_scatmat_mouse(click)
- int click;
- {
- IVIEW_WINDOW w;
- LVAL object;
- int x, y;
-
- object = xlgaobject();
- w = GETIVIEWADDRESS(object);
-
- if (w != nil) {
- x = fixp(peekarg(0)) ? getfixnum(peekarg(0)) : 0;
- y = fixp(peekarg(1)) ? getfixnum(peekarg(1)) : 0;
- find_current_plot(w, x, y);
- if (click) IViewDoClick(object);
- else IViewDoMotion(object);
- }
- return(NIL);
- }
-
- LVAL iview_scatmat_click() { return(iview_scatmat_mouse(TRUE)); }
- LVAL iview_scatmat_motion() { return(iview_scatmat_mouse(FALSE)); }
-
- LVAL iview_scatmat_adjust_screen_point()
- {
- LVAL object;
- int point;
- IVIEW_WINDOW w;
- PointState state, screen_state;
-
- object = xlgaobject();
- point = getfixnum(xlgafixnum());
- xllastarg();
-
- w = GETIVIEWADDRESS(object);
- if (w == nil) return(NIL);
-
- if (! IViewPointMasked(w, point)) {
- state = IViewPointState(w, point);
- screen_state = IViewPointScreenState(w, point);
- if (state == pointInvisible || screen_state == pointInvisible) {
- StGrSetDirty(StGWObWinInfo(object), TRUE);
- }
- else {
- scat_draw_point(w, point, state);
- }
- }
-
- return(NIL);
- }
-
- LVAL iview_scatmat_adjust_points_in_rect()
- {
- int var1, var2, x, y, px, py;
- int i, n, in_rect, right, bottom, left, top, width, height;
- PointState point_state, state;
- IVIEW_WINDOW w;
- LVAL object;
- /* char*/ StGWWinInfo *gwinfo; /* changed JKL */
-
- object = xlgaobject();
- w = GETIVIEWADDRESS(object);
- left = getfixnum(xlgafixnum());
- top = getfixnum(xlgafixnum());
- width = getfixnum(xlgafixnum());
- height = getfixnum(xlgafixnum());
- state = decode_point_state(xlgetarg());
- xllastarg();
-
- if (w == nil) return(NIL);
- gwinfo = StGWObWinInfo(object);
-
- IViewCheckLinks(w);
- n = IViewNumPoints(w);
- bottom = top + height;
- right = left + width;
- StGrGetContentVariables(gwinfo, &var1, &var2);
- StGrGetContentOrigin(gwinfo, &x, &y);
-
- if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
-
- for (i = 0; i < n; i++) {
- point_state = IViewPointState(w, i);
- if (! IViewPointMasked(w, i) && point_state != pointInvisible) {
- px = x + IViewPointScreenValue(w, var1, i);
- py = y - IViewPointScreenValue(w, var2, i);
- in_rect = (var1 != var2
- && px >= left && px <= right && py >= top && py <= bottom);
- 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_scatmat_mark_points_in_rect()
- {
- int var1, var2;
- int left, top, width, height;
- IVIEW_WINDOW w;
- LVAL object;
- /*char*/ StGWWinInfo *gwinfo; /* changed JKL */
-
- object = xlgaobject();
- w = GETIVIEWADDRESS(object);
- left = getfixnum(xlgafixnum());
- top = getfixnum(xlgafixnum());
- width = getfixnum(xlgafixnum());
- height = getfixnum(xlgafixnum());
- xllastarg();
-
- if (w == nil) return(NIL);
- gwinfo = StGWObWinInfo(object);
-
- StGrGetContentVariables(gwinfo, &var1, &var2);
- if (var1 == var2) IViewClearPointMarks(w);
- else IViewStdMarkPointsInRect(w, left, top, width, height);
- return(NIL);
- }
-
- /**************************************************************************/
- /** **/
- /** Internal Functions **/
- /** **/
- /**************************************************************************/
-
- static void get_plot_layout(w,subleft,subtop,subsize)
- IVIEW_WINDOW w;
- int *subleft, *subtop, *subsize;
- {
- int vars, left, top, width, height, delta;
- /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
-
- vars = IViewNumVariables(w);
- StGrGetContentRect(gwinfo, &left, &top, &width, &height);
-
- if (subleft != nil && subtop != nil && subsize != nil) {
- *subsize = (width - SCAT_PLOT_GAP * (vars + 1)) / vars;
- if (*subsize < 0) *subsize = 0;
-
- delta = (width - (vars * *subsize + (vars - 1) * SCAT_PLOT_GAP)) / 2;
- if (delta < 0) delta = 0;
-
- *subleft = left + delta;
- *subtop = top + delta;
- }
- }
-
- static void ScatDrawPoint(w, point, state, screen_state)
- IVIEW_WINDOW w;
- int point;
- PointState state, screen_state;
- {
- int vars = IViewNumVariables(w);
- int left, bottom;
- int oldwidth, oldheight, newwidth, newheight;
- int i, j;
- int x, y, oldsym, newsym, sym, hsym, replace;
- /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
- ColorCode color, oldcolor, use_color = StGWUseColor(gwinfo);
-
- IViewGetPointSymbol(w, point, &sym, &hsym);
- oldsym = (screen_state == pointNormal) ? sym : hsym;
- newsym = (state == pointNormal) ? sym : hsym;
- if (state == pointInvisible) return;
-
- StGWGetSymbolSize(oldsym, &oldwidth, &oldheight);
- StGWGetSymbolSize(newsym, &newwidth, &newheight);
- replace = (oldwidth > newwidth || oldheight > newheight);
-
- IViewGetScreenPointValues(w, point, pdata);
-
- StGrGetContentOrigin(gwinfo, &left, &bottom);
- if (use_color) {
- oldcolor = StGWDrawColor(gwinfo);
- color = IViewPointColor(w, point);
- if (color >= 0) StGWSetDrawColor(gwinfo, color);
- }
- for (i = 0; i < vars; i++) {
- y = bottom - pdata[i];
- for (j = 0; j < vars; j++)
- if (i != j) {
- x = left + pdata[j];
- if (replace) StGWReplaceSymbol(gwinfo, oldsym, newsym, x, y);
- else StGWDrawSymbol(gwinfo, newsym, x, y);
- }
- }
- if (use_color && color >= 0) StGWSetDrawColor(gwinfo, oldcolor);
- }
-
- static void DrawLabel(w, point)
- IVIEW_WINDOW w;
- int point;
- {
- int vars = IViewNumVariables(w);
- int left, bottom;
- int i, j;
- int x, y;
- char *label;
- /*char*/ StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
- int mode = StGWDrawMode(gwinfo);
-
- label = IViewPointLabel(w, point);
- if (label == nil) return;
-
- for (i = 0; i < vars; i++) pdata[i] = IViewPointScreenValue(w, i, point);
- StGrGetContentOrigin(gwinfo, &left, &bottom);
- for (i = 0; i < vars; i++) {
- y = bottom - pdata[i] - LABEL_OFFSET;
- for (j = 0; j < vars; j++)
- if (i != j) {
- x = left + pdata[j] + LABEL_OFFSET;
- StGWSetDrawMode(gwinfo, 1);
- StGWDrawString(gwinfo, label, x, y);
- StGWSetDrawMode(gwinfo, mode);
- }
- }
- }
-
- static void find_current_plot(w, x, y)
- IVIEW_WINDOW w;
- int x, y;
- {
- int width, height;
- int left, top, subsize, vars;
- /*char*/StGWWinInfo *gwinfo = IViewWindowWinInfo(w); /* changed JKL */
-
- vars = IViewNumVariables(w);
-
- if (IViewMouseMode(w) == brushing) {
- IViewGetBrush(w, nil, nil, &width, &height);
- x -= width / 2;
- y -= height / 2;
- }
-
- get_plot_layout(w, &left, &top, &subsize);
- subsize += SCAT_PLOT_GAP;
- current.x = (x - left) / subsize;
- current.y = (top + vars * subsize - y - SCAT_PLOT_GAP) / subsize;
- if (current.x < 0 || current.x >= vars
- || current.y < 0 || current.y >= vars) {
- current.x = 0;
- current.y = 0;
- }
- current.size = vars * subsize - SCAT_PLOT_GAP;
- current.left = left;
- current.top = top;
- current.bottom = current.left + current.top + current.size;
- StGrSetContentVariables(gwinfo, current.x, current.y);
- }
-
- static void scat_draw_point(w, i, state)
- IVIEW_WINDOW w;
- int i;
- PointState state;
- {
- int showingLabels = IViewShowingLabels(w);
-
- if (state == pointNormal && showingLabels) DrawLabel(w, i); /* to erase */
- ScatDrawPoint(w, i, state, state);
- if (state != pointNormal && showingLabels) DrawLabel(w, i); /* to draw */
- IViewSetPointScreenState(w, i, state);
- }
-
-