file: scatterplot.c

/* scatterplot.c - function to plot data using scatterplots for XmdvTool */ /* Copyright 1994, Matthew O. Ward * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without fee * is granted provided that the above copyright notice appears in all copies. * It is provided "as is" without express or implied warranty. */ /* generate scatterplots by dividing drawing area into N by N grid and draw each data sample N * N times. Draw grids, vertical and horizontal labels, and grids. Redraw bits under brush if state set to ON */ #include "XmdvTool.h" #include "scatterplot.h" #include "brush.h" #include "brush_oper.h" extern Widget appShell; extern GC gc, xor_gc; extern unsigned long color_cells[NUM_COLOR_CELLS]; extern XColor outline_col; extern int dims, data_size; extern double dim_min[MAXDIM], dim_max[MAXDIM]; extern char names[MAXDIM][MAXLABEL]; extern double *br_pos, *br_size; /* the brushes */ extern Brush brushes[MAXBRUSH]; extern int curr_dim; /* is this a color display? */ extern int COLOR; extern int X_SIZE, Y_SIZE; Arg wargs[10]; char message[MAXLABEL]; void do_scat(Widget w) { int i, j, k, x, y, dx, dy, boxwidth, boxheight; double data[MAXDIM]; XFontStruct *font; /* the font to draw text with */ int font_height; /* the height of the font */ int dummy; /* dummy var passed to XTextExtents() */ XCharStruct overall; /* for finding extents */ int brush; /* the current brush number */ unsigned long pixel; /* the brush color pixel value */ void get_data(); boxwidth = X_SIZE/dims; boxheight = Y_SIZE/dims; XSetForeground(XtDisplay(w),gc, color_cells[CCELL_TEXT]); /* default box size just divides up drawing area */ /* if brush coverage is on, draw regions covered by brush in outline color */ if(COLOR == 1) for(brush=0; brush<MAXBRUSH; brush++) { /* if this brush is not being displayed, skip it */ if(brushes[brush].display == FALSE) continue; /* set the appropriate brush color */ XSetForeground(XtDisplay(w),gc, color_cells[BRUSH_COLOR(brush)]); for(j=0; j<dims; j++) for(k=0; k<dims; k++) { /* normalize the position for the start of the brush */ x = (brushes[brush].pos[j] - brushes[brush].size[j]/2. - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); y = (dim_max[k] - brushes[brush].pos[k] - brushes[brush].size[k]/2.) * ((double) boxheight) / (dim_max[k] - dim_min[k]); /* adjust start of brush if it oversteps boundary for box */ if(x < 0) x = 0; if(y < 0) y = 0; /* normalize brush size to box size */ /* adjust size of brush if it oversteps boundary for box */ if((brushes[brush].pos[j] + brushes[brush].size[j]/2.) > dim_max[j]) dx = (dim_max[j]-brushes[brush].pos[j] + brushes[brush].size[j]/2.)*((double) boxwidth) / (dim_max[j] - dim_min[j]); else if((brushes[brush].pos[j] - brushes[brush].size[j]/2.) < dim_min[j]) dx = (brushes[brush].pos[j]+brushes[brush].size[j]/2. - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); else dx = (brushes[brush].size[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); if((brushes[brush].pos[k] + brushes[brush].size[k]/2.) > dim_max[k]) dy = (dim_max[k]-brushes[brush].pos[k] + brushes[brush].size[k]/2.) * ((double) boxheight) / (dim_max[k] - dim_min[k]); else if((brushes[brush].pos[k] - brushes[brush].size[k]/2.) < dim_min[k]) dy =(brushes[brush].pos[k]+brushes[brush].size[k]/2. - dim_min[k]) * ((double) boxheight) / (dim_max[k] - dim_min[k]); else dy = (brushes[brush].size[k]) * ((double) boxheight) / (dim_max[k] - dim_min[k]); XFillRectangle(XtDisplay(w), XtWindow(w), gc, j*boxwidth+x, k*boxheight+ y, dx, dy); } /* draw boundary coverage if necessary */ if(brushes[brush].bound != BOUND_STEP) ScatterDrawBound(brush); } /* draw grid */ XSetForeground(XtDisplay(w),gc, color_cells[CCELL_TEXT]); for(i = 0;i < dims;i++) for(j = 0;j < dims;j++) XDrawRectangle(XtDisplay(w), XtWindow(w), gc, i*boxwidth, j*boxheight, boxwidth, boxheight); /* do labels */ /* get the font */ font = XQueryFont(XtDisplay(w), XGContextFromGC(gc)); /* Get initial extents */ XTextExtents(font, "X", 1, &dummy, &dummy, &dummy, &overall); font_height = overall.ascent + overall.descent; /* draw horizontal labels */ /* add letters one at a time until space runs out */ for(i=0; i<dims; i++) { /* initial coordinates */ x = i*boxwidth + font_height * 1.1; y = font_height * 1.1; for(j=0; j<strlen(names[i]); j++) { XTextExtents(font, &names[i][j], 1, &dummy, &dummy, &dummy, &overall); if(x+overall.width > (i+1)*boxwidth-overall.width) break; XDrawString(XtDisplay(w), XtWindow(w), gc, x, y, &names[i][j], 1); x += overall.width; } } /* draw vertical labels */ /* add letters one at a time until space runs out */ for(i=0; i<dims; i++) { /* initial coordinates */ x = font_height/2; y = i*boxheight + font_height*1.1; for(j=0; j<strlen(names[i]); j++) { XTextExtents(font, &names[i][j], 1, &dummy, &dummy, &dummy, &overall); y += overall.ascent + font_height * 0.2; if(y > (i+1)*boxheight-font_height) break; XDrawString(XtDisplay(w), XtWindow(w), gc, x, y, &names[i][j], 1); y += overall.descent; } } if(COLOR == 1) { /* first draw all points in the data color */ for(i=0; i<data_size; i++) { get_data(data, i); pixel = ColorFromOperations(data); /* if this point is masked, skip it */ if(pixel == COLOR_NONE) continue; /* first time through only paint regular data */ if(pixel != color_cells[CCELL_DATA]) continue; XSetForeground(XtDisplay(w),gc, pixel); for(j=0; j<dims; j++) for(k=0; k<dims; k++) { x = (data[j] - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); y = (dim_max[k] - data[k] ) * ((double) boxheight) / (dim_max[k] - dim_min[k]); XFillRectangle(XtDisplay(w), XtWindow(w), gc, j*boxwidth+x, k*boxheight+ y, DSIZE, DSIZE); } } /* now paint all points covered by an operation */ for(i=0; i<data_size; i++) { get_data(data, i); pixel = ColorFromOperations(data); /* if this point is masked, skip it */ if(pixel == COLOR_NONE) continue; /* second time through don't paint regular data */ if(pixel == color_cells[CCELL_DATA]) continue; XSetForeground(XtDisplay(w),gc, pixel); for(j=0; j<dims; j++) for(k=0; k<dims; k++) { x = (data[j] - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); y = (dim_max[k] - data[k] ) * ((double) boxheight) / (dim_max[k] - dim_min[k]); XFillRectangle(XtDisplay(w), XtWindow(w), gc, j*boxwidth+x, k*boxheight+ y, DSIZE, DSIZE); } } } else { XSetForeground(XtDisplay(w),gc, color_cells[CCELL_TEXT]); for(i = 0;i < data_size;i++) { get_data(data, i); for(j = 0;j < dims;j++) for(k = 0;k < dims;k++) { x = (data[j] - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); y = (dim_max[k] - data[k] ) * ((double) boxheight) / (dim_max[k] - dim_min[k]); XFillRectangle(XtDisplay(w), XtWindow(w), gc, j*boxwidth+x, k*boxheight+ y, DSIZE, DSIZE); } } } } /* * RedrawSingleScatter() - Redraw a single point on the scatterplot * display. Usefull for multi-sel. */ void RedrawSingleScatter(Widget w, int point) { int j, k, x, y, boxwidth, boxheight; double data[MAXDIM]; void get_data(); boxwidth = X_SIZE/dims; boxheight = Y_SIZE/dims; /* set the color */ if(COLOR == 1) { if(MultiSelectCovered(point)) XSetForeground(XtDisplay(w),gc, color_cells[CCELL_PAINT]); else if(covered(data) == 1) XSetForeground(XtDisplay(w),gc, color_cells[CCELL_HIGHLIGHT]); else XSetForeground(XtDisplay(w),gc, color_cells[CCELL_DATA]); } else XSetForeground(XtDisplay(w),gc, color_cells[CCELL_TEXT]); /* draw the point */ get_data(data, point); for(j = 0;j < dims;j++) for(k = 0;k < dims;k++) { x = (data[j] - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); y = (dim_max[k] - data[k] ) * ((double) boxheight) / (dim_max[k] - dim_min[k]); XFillRectangle(XtDisplay(w), XtWindow(w), gc, j*boxwidth+x, k*boxheight+ y, DSIZE, DSIZE); } } /* * ScatterDrawAverage() - Draw an average value on the scatterplot * display. * * PARAMETERS * data The average point to draw * * RETURNS * void */ void ScatterDrawAverage(double data[MAXDIM]) { Widget canvas_w; int j, k, x, y, boxwidth, boxheight; /* get the canvas widget */ if(!(canvas_w = WcFullNameToWidget(appShell,"*canvas"))) { fprintf(stderr, "Error getting *canvas in ScatterDrawAverage()\n"); return; } boxwidth = X_SIZE/dims; boxheight = Y_SIZE/dims; /* draw the point */ for(j=0; j<dims; j++) for(k=0; k<dims; k++) { x = (data[j] - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); y = (dim_max[k] - data[k] ) * ((double) boxheight) / (dim_max[k] - dim_min[k]); XFillRectangle(XtDisplay(canvas_w), XtWindow(canvas_w), gc, j*boxwidth+x, k*boxheight+ y, DSIZE, DSIZE); } } /* * ScatterDrawBound() - Draw the brush boundary in the scatterplot * view. * * PARAMETERS * brush Brush number to draw boundary for * * RETURNS * void */ void ScatterDrawBound(int brush) { Widget canvas_w; /* the canvas */ int j, k, x, y, dx, dy, boxwidth, boxheight; /* get the canvas widget */ if(!(canvas_w = WcFullNameToWidget(appShell,"*canvas"))) { fprintf(stderr, "Error getting *canvas in ScatterDrawBound()\n"); return; } boxwidth = X_SIZE/dims; boxheight = Y_SIZE/dims; /* set the appropriate brush color */ XSetForeground(XtDisplay(canvas_w), xor_gc, color_cells[BRUSH_COLOR(brush)]); for(j=0; j<dims; j++) for(k=0; k<dims; k++) { /* normalize the position for the start of the brush */ x = (brushes[brush].pos[j] - brushes[brush].size[j]/2. - brushes[brush].bound_offset[j] - dim_min[j]) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); y = (dim_max[k] - brushes[brush].pos[k] - brushes[brush].size[k]/2.0 - brushes[brush].bound_offset[k]) * ((double) boxheight) / (dim_max[k] - dim_min[k]); /* adjust start of brush if it oversteps boundary for box */ if(x < 0) x = 0; if(y < 0) y = 0; /* normalize brush size to box size */ /* adjust size of brush if it oversteps boundary for box */ if((brushes[brush].pos[j] + brushes[brush].size[j]/2.0 + brushes[brush].bound_offset[j]) > dim_max[j]) dx = (dim_max[j]-brushes[brush].pos[j] + brushes[brush].size[j]/2.0 + brushes[brush].bound_offset[j]) *((double) boxwidth) / (dim_max[j] - dim_min[j]); else if((brushes[brush].pos[j] - brushes[brush].size[j]/2.0 - brushes[brush].bound_offset[j]) < dim_min[j]) dx = (brushes[brush].pos[j] + brushes[brush].size[j]/2. + brushes[brush].bound_offset[j] - dim_min[j] ) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); else dx = (brushes[brush].size[j] + brushes[brush].bound_offset[j]*2.0) * ((double) boxwidth) / (dim_max[j] - dim_min[j]); if((brushes[brush].pos[k] + brushes[brush].size[k]/2. + brushes[brush].bound_offset[k]) > dim_max[k]) dy = (dim_max[k]-brushes[brush].pos[k] + brushes[brush].size[k]/2.0 + brushes[brush].bound_offset[k]) * ((double) boxheight) / (dim_max[k] - dim_min[k]); else if((brushes[brush].pos[k] - brushes[brush].size[k]/2. - brushes[brush].bound_offset[k]) < dim_min[k]) dy =(brushes[brush].pos[k] + brushes[brush].size[k]/2. + brushes[brush].bound_offset[k] - dim_min[k]) * ((double) boxheight) / (dim_max[k] - dim_min[k]); else dy = (brushes[brush].size[k] + brushes[brush].bound_offset[k]*2.0) * ((double) boxheight) / (dim_max[k] - dim_min[k]); XDrawRectangle(XtDisplay(canvas_w), XtWindow(canvas_w), xor_gc, j*boxwidth+x, k*boxheight+ y, dx, dy); } }


Back to Source File Index


C++ to HTML Conversion by ctoohtml