home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
pc.louisiana.edu/pub/unix/
/
Louisiana_UNIX.tar
/
Louisiana_UNIX
/
xspread3.0.zoo
/
plot_stk_bar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-02
|
16KB
|
488 lines
/*
* Copyright (C) 1992 Board of Regents of the University of Wisconsin
* on behalf of the Department of Electrical Engineering and Computer
* Science, University of Wisconsin-Milwaukee, Milwaukee, WI 53201.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* a copy of which is included here in file "GNU_GENERAL"
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The programs in this directory were developed by software engineering
* teams as part of the course "Introduction to Software Engineering"
* under the supervision of Professor G. Davida.
* This is a modification of a program written or modified by
* others. The original copyrights, as per GNU General Public License,
* may still be applicable. The UWM copyright is applicable only
* the those parts generated at UWM.
*
* Please send all changes, enhancements, and other comments about this
* software to
* soft-eng@cs.uwm.edu
*
* No Warranty, expressed or implied, comes with this software.
* This software is intended to be used by not-for-profit
* organizations or by individuals for personal HOME use.
* This software, or any of its parts, may not be used by for-profit
* organization, regardless of application or intended product or
* customer, without the permission of the Board of Regents of the
* University of Wisconsin is strictly forbidden.
*
* Contact: soft-eng@cs.uwm.edu
* or
*
* Software Engineering Coordinator
* Computer Science
* Department of EECS
* University of Wisconsin - Milwaukee
* Milwaukee, WI 53201
* 414-229-4677
*
* HISTORY,CLAIMS and CONTRIBUTIONS
*/
/*************************************************************************
* This procedure displays a stacked bar graph for the values chosen *
* by the user. It displays one bar for each row chosen and 'stacks' *
* one section for each column chosen. It uses patterns located in *
* the file pattern.h *
* Dan Gruber - December 1991 *
* Modified 5/94 by Dan Coppersmith to improve user friendliness of *
* error messages. *
*************************************************************************
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "config.h"
#include "plot.h"
#include "pattern.h"
#include "graphic_gvar.h"
#include "sc.h"
#include "scXstuff.h"
#include <math.h>
#define TITLE "XSPREAD-Grapher (Stacked Bar Plot)"
#define PIX_SEP 5
#ifndef irint
#define irint(x) floor((x)+0.5)
#endif
XWMHints SBwmh = {
(InputHint|StateHint), /*flags*/
False, /*input*/
NormalState, /*initial_state*/
0, /*icon pixmap*/
0, /*icon window*/
0, 0, /*icon location*/
0, /*icon mask*/
0, /*Window group*/
};
plot_stacked_bar()
{ int argc = 0;
char **argv;
double max_y, min_y, Y_Range;
int i,j,k; /* Iteration variables */
int grid_l_x; /* The size of the grid separators */
int grid_l_y;
int grid_h;
int height, width; /* Height and width of a bar */
char str[100]; /* The label to be drawn */
int text_w; /* The width of a label in pixels */
int len; /* The length of a label */
int x,y; /* X and Y coordinates for the bar */
struct ent *p, *val;
int looping = 1; /* Continue looping variable */
int draw = 0; /* Continue drawing variable */
int first_bar = 1; /* first bar flag */
int number_of_bars; /* Total number of bars */
int bars = 0; /* Current bar */
int labelsize; /* Maximum size of label to be drawn */
double Row_Total[20]; /* Row Total */
int Y_Position[20]; /* Position to draw next portion of bar */
Pixmap Pattern; /* Type of pattern to be drawn */
/*
* Decide the scale for x and y axes
*/
for (i=graphic_range[0].r1; i<=graphic_range[0].r2; i++)
{
p=lookat(i,graphic_range[0].c);
if(!(p->label)) continue;
bars++;
Row_Total[bars] = 0;
Y_Position[bars] = 0;
}
if (bars < 1)
{
fprintf(stderr,"\007");
if (graphic_range[0].r2 - graphic_range[0].r1 > 1)
message("x values must be strings");
else
message("Not enough valid X labels");
return;
}
number_of_bars = bars;
if (g_auto_man[1] == 'M') {
max_y = graphic_scale[1][1];
min_y = graphic_scale[1][0];
}
else {
for (j=1; j < GRAPHRANGES; j++){
if (*(graphic_range[j].col) == '\0') continue;
bars = 0;
for (i=graphic_range[j].r1; i<=graphic_range[j].r2; i++)
{
p=lookat(i,graphic_range[j].c);
/* if(!(p->flags & is_valid)) continue; */
bars++;
Row_Total[bars] = Row_Total[bars] + (p->v);
if (first_bar){
min_y = p->v;
first_bar = 0;
} else
min_y = Min(min_y, p->v);
}
}
first_bar = 1;
for (i=1; i<=bars; i++){
if (first_bar){
max_y = Row_Total[i];
first_bar = 0;
} else {
max_y = Max(max_y, Row_Total[i]);
}
}
min_y -= 0.1*(fabs(min_y));
max_y += 0.1*(fabs(max_y));
}
max_y = ceil(max_y);
min_y = floor(min_y);
/*
* Select colors for the border, the window background, and the
* foreground.
*/
bd = WhitePixel(dpy, DefaultScreen(dpy));
bg = BlackPixel(dpy, DefaultScreen(dpy));
fg = WhitePixel(dpy, DefaultScreen(dpy));
/*
* Set the border width of the window, and the gap between the text
* and the edge of the window, "pad".
*/
pad = BORDER;
bw = 1;
/*
* Deal with providing the window with an initial position & size.
* Fill out the XSizeHints struct to inform the window manager. See
* Sections 9.1.6 & 10.3.
*/
xsh.width = XTextWidth(curfont, TITLE, 80 + pad * 2);
xsh.flags = (PPosition | PSize);
xsh.height = WIN_H;
xsh.width = WIN_W;
xsh.x = (DisplayWidth(dpy, DefaultScreen(dpy)) - xsh.width) / 2;
xsh.y = (DisplayHeight(dpy, DefaultScreen(dpy)) - xsh.height) / 2;
/*
* Create the Window with the information in the XSizeHints, the
* border width, and the border & background pixels. See Section 3.3.
*/
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
xsh.x, xsh.y, xsh.width, xsh.height,
bw, bd, bg);
/*
* Set the standard properties for the window managers. See Section
* 9.1.
*/
XSetStandardProperties(dpy, win, TITLE, TITLE, None, argv,
argc, &xsh);
XSetWMHints(dpy, win, &SBwmh);
/*
* Ensure that the window's colormap field points to the default
* colormap, so that the window manager knows the correct colormap to
* use for the window. See Section 3.2.9. Also, set the window's Bit
* Gravity to reduce Expose events.
*/
xswa.colormap = DefaultColormap(dpy, DefaultScreen(dpy));
xswa.bit_gravity = CenterGravity;
XChangeWindowAttributes(dpy, win, (CWColormap | CWBitGravity), &xswa);
/*
* Map the window to make it visible. See Section 3.5.
*/
XMapWindow(dpy, win);
/*
* Find out how big the window is now, so that we can center
* the text in it.
*/
if (XGetWindowAttributes(dpy, win, &xwa) == 0){
fprintf(stderr,"Stacked Bar Plot: Can't access attributes for graph window\n");
exit(1);
}
XClearWindow(dpy, win);
XSelectInput(dpy,win, ButtonPressMask|KeyPressMask|ExposureMask);
while (looping) {
XEvent event;
XNextEvent(dpy,&event);
switch(event.type)
{
case KeyPress:
case ButtonPress: looping = 0;
break;
case Expose: draw = 1;
}
if (!draw) continue;
XDrawRectangle(dpy,win,maingcreversed,
RECT_X,RECT_Y,RECT_W,RECT_H);
/*
* Calculate the length of the grid lines. grid_l_x and
* grid_l_y are set to '0' if a line should not be drawn.
*/
if (graphic_grid == 'H')
{
grid_l_x = RECT_W;
grid_l_y = 0;
}
else if (graphic_grid == 'V')
{
grid_l_x = 0;
grid_l_y = RECT_H;
}
else if (graphic_grid == 'B')
{
grid_l_x = RECT_W;
grid_l_y = RECT_H;
}
else
{
grid_l_x = 0;
grid_l_y = 0;
}
Y_Range = max_y - min_y;
/* The width of each bar */
width = (RECT_W - (PIX_SEP * (number_of_bars)))/number_of_bars;
grid_h = RECT_H /10;
/* Draw the grid along with the labels on the Y-Axis */
for (i=0; i<11; i++) {
if (i > 0 && i < 10)
XDrawLine(dpy,win,maingcreversed,
RECT_X-4, RECT_Y+i*grid_h,
RECT_X, RECT_Y+i*grid_h);
XDrawLine(dpy,win,maingcreversed,
RECT_X, RECT_Y+i*grid_h,
RECT_X+grid_l_x, RECT_Y+i*grid_h);
XDrawLine(dpy,win,maingcreversed,
RECT_X + RECT_W,RECT_Y+i*grid_h,
RECT_X+RECT_W - grid_l_x, RECT_Y+i*grid_h);
sprintf(str,"%.1f",(max_y - Y_Range*i/10));
len = strlen(str);
text_w = XTextWidth(curfont,str,len+2);
XDrawImageString(dpy,win,maingcreversed,
RECT_X - text_w,
RECT_Y + i*grid_h + curfontheight/3,
str,len);
} /*end for loop*/
for (i=1; i < number_of_bars; i++) {
x = RECT_X + (PIX_SEP * i) + (width * i);
XDrawLine(dpy,win,maingcreversed,
x, RECT_Y, x, RECT_Y+grid_l_y);
XDrawLine(dpy,win,maingcreversed,
x, RECT_Y+RECT_H, x, RECT_Y+RECT_H-grid_l_y);
} /*end for loop*/
/*
*
* Draw titles at top of graph
*
*/
len = strlen(graphic_title[0]);
text_w = XTextWidth(curfont, graphic_title[0], len);
XDrawImageString(dpy,win,maingcreversed,
(WIN_W - text_w)/2, RECT_Y/3,
graphic_title[0], len);
len = strlen(graphic_title[1]);
text_w = XTextWidth(curfont, graphic_title[1],len);
XDrawImageString(dpy,win,maingcreversed,
(WIN_W - text_w)/2, RECT_Y*2/3,
graphic_title[1],len);
len = strlen(graphic_title[2]);
text_w=XTextWidth(curfont,graphic_title[2],len);
XDrawImageString(dpy,win,maingcreversed,
(WIN_W-text_w)/2, RECT_H+RECT_Y*3/2,
graphic_title[2],len);
len = strlen(graphic_title[3]);
text_w=XTextWidth(curfont,graphic_title[3],len);
if ((RECT_X-text_w) < 0)
x = curfontwidth;
else
x = RECT_X-text_w;
XDrawImageString(dpy,win,maingcreversed,
x, RECT_Y - curfontheight,
graphic_title[3],len);
/* --------------------------------------------------------------------*/
/* This next section will read values of the x and y center points */
/* and find the maximum and minimum values for each, then set the */
/* width and height paramters, convert x and y so that the origin */
/* is at the lower left corner of the window, and then finally */
/* draw and fill the bars. */
/* ------------------------------------------------------------------- */
/*
* Draw Labels on the X-Axis
*/
labelsize = irint(floor(width/(double)curfontwidth)-1);
y = RECT_Y + RECT_H + curfontheight;
bars = 0;
for (i=graphic_range[0].r1;i<=graphic_range[0].r2; i++)
{
p = lookat(i,graphic_range[0].c);
if (!(p->label)) continue;
strncpy(str, p->label, labelsize);
str[labelsize] = '\0';
x = RECT_X+(PIX_SEP*bars)+(width*bars)+(width/2);
x = x - (curfontwidth*strlen(str))/2;
bars++;
XDrawImageString(dpy,win,maingcreversed,
x,y,
str,strlen(str));
}
bars = 0;
for (i=graphic_range[0].r1; i<=graphic_range[0].r2; i++)
{
bars++;
Y_Position[bars] = 0;
}
for (i = 1; i < GRAPHRANGES; i++){
if (*(graphic_range[i].col) == '\0') continue;
bars = 0;
for(j=graphic_range[0].r1, k=graphic_range[i].r1;
(j<=graphic_range[0].r2) && (k<=graphic_range[i].r2); j++, k++){
if (!((p=lookat(j,graphic_range[0].c))->label)) continue;
x = RECT_X + ((PIX_SEP)*(bars)) + (width*bars);
bars++;
if (!((val=lookat(j,graphic_range[i].c))->flags & is_valid)
|| (val->v < min_y) || (val->v > max_y)) continue;
/*
* Calculate the height of the bar. If it is the 'lowest'
* piece of the bar, subtract off the value of the min_y
* for an accurate height.
*/
if (i == 1)
height = irint((val->v - min_y) / Y_Range * RECT_H);
else
height = irint(val->v / Y_Range * RECT_H);
y = RECT_Y + RECT_H - height - Y_Position[bars];
Y_Position[bars] = Y_Position[bars] + height;
/* clear the area before drawing the bar */
if (graphic_grid != 'C')
XClearArea(dpy,win,x,y,width,height,False);
/* choose a pattern to be used */
switch (i) {
case 1 : Pattern = XCreateBitmapFromData(dpy,win,white_bits,
white_width, white_height);
break;
case 2 : Pattern = XCreateBitmapFromData(dpy,win,gray3_bits,
gray3_width, gray3_height);
break;
case 3 : Pattern = XCreateBitmapFromData(dpy,win,gray5_bits,
gray5_width, gray5_height);
break;
case 4 : Pattern = XCreateBitmapFromData(dpy,win,gray2_bits,
gray2_width, gray2_height);
break;
case 5 : Pattern = XCreateBitmapFromData(dpy,win,gray4_bits,
gray4_width, gray4_height);
break;
case 6 : Pattern = XCreateBitmapFromData(dpy,win,gray1_bits,
gray1_width, gray1_height);
break; }
/* Display a filled portion of the bar */
XSetStipple(dpy, maingcreversed, Pattern);
XSetFillStyle(dpy, maingcreversed, FillStippled);
XFillRectangle(dpy,win,maingcreversed,x,y,width,height);
/* Draw a solid outline around the bar */
XSetFillStyle(dpy, maingcreversed, FillSolid);
XDrawRectangle(dpy,win,maingcreversed,x,y,width,height);
}
}
}
XUnmapWindow(dpy, win);
XDestroyWindow(dpy, win);
}