/* 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 "xlstat.h"
#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"
extern LVAL s_scale_type, sk_show, sk_show_window;
static int pdata[MAX_NUM_VARS];
static struct {
int x, y, left, top, size, bottom;
} current;
/* forward declarations */
LOCAL VOID get_plot_layout P4H(IVIEW_WINDOW, int *, int *, int *);
LOCAL VOID find_current_plot P3H(IVIEW_WINDOW, int, int);
LOCAL VOID scat_draw_point P3H(IVIEW_WINDOW, int, PointState);
/**************************************************************************/
/** **/
/** Plot Creation Functions **/
/** **/
/**************************************************************************/
LVAL iview_scatmat_allocate(V)
{
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 P1C(int, which)
{
IVIEW_WINDOW w;
LVAL data, object;
int old_n = 0, n = 0;
object = xlgaobject();
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
if (IVIEW_WINDOW_NULL(w)) 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(V) { return(scatmat_add_data('P')); }
LVAL iview_scatmat_add_lines(V) { return(scatmat_add_data('L')); }
#ifdef USESTRINGS
LVAL iview_scatmat_add_strings(V) { return(scatmat_add_data('S')); }
#endif /* USESTRINGS */
/**************************************************************************/
/** **/
/** Drawing and Resizing Functions **/
/** **/
/**************************************************************************/
LVAL iview_scatmat_resize(V)
{
int vars;
int i, top, left, subsize, low, high;
IVIEW_WINDOW w;
LVAL object;
object = xlgaobject();
xllastarg();
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
if (IVIEW_WINDOW_NULL(w)) 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(V)
{
int vars;
int left, top, subleft, subtop, subsize;
int cmleft, cmtop, cmwidth, cmheight;
int i, j;
double low, high;
char s[100];
IVIEW_WINDOW w;
LVAL object, scale_type;
StGWWinInfo *gwinfo;
object = xlgaobject();
xllastarg();
gwinfo = StGWObWinInfo(object);
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
if (IVIEW_WINDOW_NULL(w)) return(NIL);
vars = IViewNumVariables(w);
if (IViewMouseMode(w) == brushing) IViewEraseBrush(w);
IViewGetContentMarginRect(w, &cmleft, &cmtop, &cmwidth, &cmheight);
get_plot_layout(w, &left, &top, &subsize);
scale_type = slot_value(object, s_scale_type);
/**** should set/reset clip rectangle */
StGWStartBuffering(gwinfo);
/*StGWEraseRect(gwinfo, cmleft, cmtop, cmwidth + 1, cmheight + 1);*/
IViewClearContent(w);
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, "%.3g", high);
StGWDrawText(gwinfo, s,
subleft + subsize - SCAT_INSET,
subtop + SCAT_INSET, 2, 1);
sprintf(s, "%.3g", 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, cmleft, cmtop, cmwidth + 1, cmheight + 1);
if (IViewMouseMode(w) == brushing) IViewDrawBrush(w);
IViewResetScreenStates(w);
return(NIL);
}
/**************************************************************************/
/** **/
/** Mouse Functions **/
/** **/
/**************************************************************************/
static LVAL iview_scatmat_mouse P1C(int, click)
{
IVIEW_WINDOW w;
LVAL object;
int x, y;
object = xlgaobject();
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
if (! IVIEW_WINDOW_NULL(w)) {
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(V) { return(iview_scatmat_mouse(TRUE)); }
LVAL iview_scatmat_motion(V) { return(iview_scatmat_mouse(FALSE)); }
LVAL iview_scatmat_adjust_screen_point(V)
{
LVAL object;
int point;
IVIEW_WINDOW w;
PointState state, screen_state;
object = xlgaobject();
point = getfixnum(xlgafixnum());
xllastarg();
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
if (IVIEW_WINDOW_NULL(w)) 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(V)
{
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;
StGWWinInfo *gwinfo;
object = xlgaobject();
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
left = getfixnum(xlgafixnum());
top = getfixnum(xlgafixnum());
width = getfixnum(xlgafixnum());
height = getfixnum(xlgafixnum());
state = decode_point_state(xlgetarg());
xllastarg();
if (IVIEW_WINDOW_NULL(w)) 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(V)
{
int var1, var2;
int left, top, width, height;
IVIEW_WINDOW w;
LVAL object;
StGWWinInfo *gwinfo;
object = xlgaobject();
w = (IVIEW_WINDOW) GETIVIEWADDRESS(object);
left = getfixnum(xlgafixnum());
top = getfixnum(xlgafixnum());
width = getfixnum(xlgafixnum());
height = getfixnum(xlgafixnum());
xllastarg();
if (IVIEW_WINDOW_NULL(w)) 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 **/
/** **/
/**************************************************************************/
LOCAL VOID get_plot_layout P4C(IVIEW_WINDOW, w, int *, subleft, int *, subtop, int *, subsize)
{
int vars, left, top, width, height, delta;
StGWWinInfo *gwinfo = IViewWindowWinInfo(w);
vars = IViewNumVariables(w);
StGrGetContentRect(gwinfo, &left, &top, &width, &height);
if (subleft != NULL && subtop != NULL && subsize != NULL) {
*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 P4C(IVIEW_WINDOW, w, int, point,
PointState, state, PointState, 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;
StGWWinInfo *gwinfo = IViewWindowWinInfo(w);
int color = 0, oldcolor = 0, 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 != NOCOLOR) 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 != NOCOLOR) StGWSetDrawColor(gwinfo, oldcolor);
}
static VOID DrawLabel P2C(IVIEW_WINDOW, w, int, point)
{
int vars = IViewNumVariables(w);
int left, bottom;
int i, j;
int x, y;
char *label;
StGWWinInfo *gwinfo = IViewWindowWinInfo(w);
int mode = StGWDrawMode(gwinfo);
label = IViewPointLabel(w, point);
if (label == NULL) 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);
}
}
}
LOCAL VOID find_current_plot P3C(IVIEW_WINDOW, w, int, x, int, y)
{
int width, height;
int left, top, subsize, vars;
StGWWinInfo *gwinfo = IViewWindowWinInfo(w);
vars = IViewNumVariables(w);
if (IViewMouseMode(w) == brushing) {
IViewGetBrush(w, NULL, NULL, &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);
}
LOCAL VOID scat_draw_point P3C(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);
}
syntax highlighted by Code2HTML, v. 0.9.1