home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
100-199
/
ff166.lzh
/
AutoGraf
/
dograf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-11-22
|
11KB
|
502 lines
/*
dograf.c : subroutine to draw graph
By Joel Swank September 3, 1988
Version 1.0
*/
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <graphics/display.h>
#include <graphics/text.h>
#include <ctype.h>
/*************
* Hooks to the rest of the program
*************/
extern char nodatamsg[];
extern char tempbuf[];
extern char filename[];
#define MenuList1 Menu1
extern struct Menu Menu1;
extern struct Window *Wind;
extern struct RastPort *rp;
extern struct IntuiText oktxt;
extern int numrecs;
extern int fileread;
/* save areas for graphing data */
int yrsave[1000]; /* save year of each entry */
float costsave[1000]; /* save averaged cost data of each entry */
float milesave[1000]; /* save averaged mile data of each entry */
float pricesave[1000]; /* save price data of each entry */
float odsave[1000]; /* save odometer data of each entry */
float rawcost[1000]; /* save cost data of each entry */
/* flags for which grafs to display */
extern int cpm;
extern int ppg;
extern int mpg;
extern int syr; /* for requested start year */
extern int eyr; /* for requested end year */
/* Local data */
/*
* Data describing the NEXT gadget
*
*/
SHORT BorderVectorsM[] = {
0,0,
42,0,
42,15,
0,15,
0,0
};
struct Border BorderM = {
-2,-1, /* XY origin relative to container TopLeft */
1,2,JAM2, /* front pen, back pen and drawmode */
5, /* number of XY vectors */
BorderVectorsM, /* pointer to XY vectors */
NULL /* next border in list */
};
struct IntuiText ITextM = {
1,2,JAM2, /* front and back text pens, drawmode and fill byte */
5,4, /* XY origin relative to container TopLeft */
NULL, /* font pointer or NULL for default */
(UBYTE *)"NEXT", /* pointer to text */
NULL /* next IntuiText structure */
};
struct Gadget GadgetM = {
NULL, /* next gadget */
5,142, /* origin XY of hit box relative to window TopLeft */
39,14, /* hit box width and height */
NULL, /* gadget flags */
RELVERIFY, /* activation flags */
BOOLGADGET, /* gadget type flags */
(APTR)&BorderM, /* gadget border or image to be rendered */
NULL, /* alternate imagery for selection */
&ITextM, /* first IntuiText structure */
0L, /* gadget mutual-exclude long word */
NULL, /* SpecialInfo structure */
NULL, /* user-definable data */
NULL /* pointer to user-definable data */
};
/*
* Data describing the DONE gadget
*
*/
SHORT BorderVectorsM1[] = {
0,0,
42,0,
42,15,
0,15,
0,0
};
struct Border BorderM1 = {
-2,-1, /* XY origin relative to container TopLeft */
1,2,JAM2, /* front pen, back pen and drawmode */
5, /* number of XY vectors */
BorderVectorsM1, /* pointer to XY vectors */
NULL /* next border in list */
};
struct IntuiText ITextM1 = {
1,2,JAM2, /* front and back text pens, drawmode and fill byte */
5,4, /* XY origin relative to container TopLeft */
NULL, /* font pointer or NULL for default */
(UBYTE *)"DONE", /* pointer to text */
NULL /* next IntuiText structure */
};
struct Gadget GadgetM1 = {
NULL, /* next gadget */
5,50, /* origin XY of hit box relative to window TopLeft */
39,14, /* hit box width and height */
NULL, /* gadget flags */
RELVERIFY, /* activation flags */
BOOLGADGET, /* gadget type flags */
(APTR)&BorderM1, /* gadget border or image to be rendered */
NULL, /* alternate imagery for selection */
&ITextM1, /* first IntuiText structure */
0L, /* gadget mutual-exclude long word */
NULL, /* SpecialInfo structure */
NULL, /* user-definable data */
NULL /* pointer to user-definable data */
};
float vertscale, horizscale;
float max, min; /* main max and min */
float vsize; /* verticle range */
char textbuf[80];
char titlebuf[80];
int first = TRUE;
int prevyear = 0; /* detecting year change */
long yval, xval;
/*
* draw_graph : draw requested graphs
*/
draw_graph()
{
long i;
/* put up grafing gadgets */
AddGadget(Wind,&GadgetM,(USHORT) ~0);
AddGadget(Wind,&GadgetM1,(USHORT) ~0);
/* disable all menu items except quit & print */
for (i=0; i<6; i++)
{
if (i == 4) continue; /* skip print */
OffMenu(Wind, (USHORT) SHIFTITEM(i));
}
/* add mouse reporting to window */
ReportMouse(TRUE,Wind);
/* do requested graphs */
while (1)
{
if (ppg)
{
if (do_graph('p') == 0) break;
}
if (cpm)
{
if (do_graph('c') == 0) break;
}
if (mpg)
{
if (do_graph('m') == 0) break;
}
}
/* delete mouse reporting from window */
ReportMouse(FALSE,Wind);
/* remove grafing gadgets */
RemoveGadget(Wind,&GadgetM);
RemoveGadget(Wind,&GadgetM1);
/* enable all menu items */
for (i=0; i<7; i++)
{
if (!fileread) /* if no file read . . . */
{
if (i=1) continue; /* skip draw and avgs */
if (i=2) continue;
}
OnMenu(Wind, (USHORT) SHIFTITEM(i));
}
clr_grf();
}
/*
* do_graph : draw one graph from 'mode' and stored data
*/
do_graph(mode)
char mode; /* what to graph, p=price/gal, m=mile/gal, c=cost/mile */
{
struct IntuiMessage *msg;
char *patptr;
char *patpt2;
int i, ystart = -1;
int yend, year;
int mousex, mx, my;
register count;
clr_grf();
/*************************************************
Select data, and find max/min
*************************************************/
max = 0;
min = 1e10;
for (count=0; count<numrecs; count++)
{
year = yrsave[count];
/* eliminate undesired years */
if (eyr != -1)
{
if (year > eyr) break;
}
if (syr != -1)
{
if (year < syr) continue;
}
if (ystart == -1) ystart = count; /* remenber first */
/* find the max and min */
switch (mode)
{
case 'c':
if (costsave[count] > 0)
{
if (costsave[count] > max) max = costsave[count];
if (costsave[count] < min) min = costsave[count];
}
break;
case 'm':
if(milesave[count] > 0)
{
if (milesave[count] > max) max = milesave[count];
if (milesave[count] < min) min = milesave[count];
}
break;
case 'p':
if (pricesave[count] > max) max = pricesave[count];
if (pricesave[count] < min) min = pricesave[count];
break;
}
}
yend = count;
if (ystart == -1 || yend-ystart < 2)
{
AutoRequest(Wind,&nodatamsg,0L,&oktxt,0L,0L,300L,75L);
return(0);
}
/*************************************************
Calculate scale factors
*************************************************/
switch (mode)
{
case 'c':
strcpy(titlebuf,"Cents per Mile of Travel - File ");
break;
case 'm':
strcpy(titlebuf,"Miles per Gallon of Gasoline - File ");
break;
case 'p':
strcpy(titlebuf,"Dollars per Gallon of Gasoline - File ");
break;
}
vsize = (max - min) *1.1;
vertscale = 180.0/vsize;
horizscale = 570.0/ (float) (yend-ystart);
strcat(titlebuf,filename);
SetWindowTitles(Wind,(UBYTE *) titlebuf, -1L);
/* if (!wb)
{
printf("Vert scale = %f\n",vertscale);
printf("Horiz scale = %f\n",horizscale);
printf("Max = %f\n",max);
printf("Min = %f\n",min);
} */
/*************************************************
draw axis and vertical labels
*************************************************/
Move(rp,50L,15L);
Draw(rp,50L,183L);
Draw(rp,635,183L);
Move(rp,50L,105L);
Draw(rp,635,105L);
switch (mode)
{
case 'c':
patptr = "%5.2f";
patpt2 = "%5.2f cents/mi";
break;
case 'm':
patptr = "%5.2f";
patpt2 = "%5.2f mi/gal";
break;
case 'p':
patptr = "%5.3f";
patpt2 = "$%5.3f $/gal";
break;
}
/* dray Y axis labels */
Move(rp,5L,18L);
sprintf(textbuf,patptr,min+vsize);
Text(rp,(UBYTE *) textbuf, (long) strlen(textbuf));
Move(rp,5L,107L);
sprintf(textbuf,patptr,min+vsize/2);
Text(rp,(UBYTE *) textbuf, (long) strlen(textbuf));
Move(rp,5L,187L);
sprintf(textbuf,patptr,min);
Text(rp,(UBYTE *) textbuf, (long) strlen(textbuf));
/* draw min and max values */
Move(rp,65L,30L);
sprintf(tempbuf,patpt2,max);
strcpy(textbuf,"Maximum = ");
strcat(textbuf,tempbuf);
Text(rp,(UBYTE *) textbuf, (long) strlen(textbuf));
Move(rp,400L,170L);
sprintf(tempbuf,patpt2,min);
strcpy(textbuf,"Minimum = ");
strcat(textbuf,tempbuf);
Text(rp,(UBYTE *) textbuf, (long) strlen(textbuf));
/*************************************************
MAIN Drawing Routine
*************************************************/
first = TRUE;
prevyear = 0;
for (count=ystart ; count< yend; count++)
{
year = yrsave[count];
switch (mode)
{
case 'c':
if (costsave[count] == 0) yval = 0;
else yval = 180L - (long) ((costsave[count] - min) * vertscale);
break;
case 'm':
if (milesave[count] == 0) yval = 0;
else yval = 180L - (long) ((milesave[count] - min) * vertscale);
break;
case 'p':
yval = 180L - (long) ((pricesave[count] - min) * vertscale);
break;
}
xval = (long) ( ((float) (count-ystart)) * horizscale)+50;
if (yval != 0) /* don't draw zero entrys */
{
if (first)
{
Move(rp,xval, yval);
first = FALSE;
}
else Draw(rp,xval, yval);
}
/* printf("X=%ld, y=%ld\n",xval,yval); */
if (year != prevyear) /* draw horiz label */
{
sprintf(textbuf,"%2d",year%100);
Move(rp,xval-TextLength(rp,textbuf, (long) strlen(textbuf))/2, 196L);
Text(rp,(UBYTE *) textbuf, (long) strlen(textbuf));
Move(rp,xval,180L); /* tick marks */
Draw(rp,xval,186L);
Move(rp,xval, yval);
}
prevyear = year;
}
/* redraw Gadgets */
RefreshGadgets(&GadgetM,Wind,0L);
RefreshGadgets(&GadgetM1,Wind,0L);
/*************************************************
WAIT for Close, NEXT or DONE Gadget and manage
the mouse reporting
*************************************************/
while (1)
{
int menunum;
struct MenuItem *item, *ItemAddress();
Wait( 1L << Wind->UserPort->mp_SigBit); /* wait on mesg */
while(msg = (struct IntuiMessage *) GetMsg(Wind->UserPort)) {
switch(msg->Class) {
case CLOSEWINDOW:
ReplyMsg(msg);
done(0);
case GADGETUP:
ReplyMsg(msg);
if (msg->IAddress == &GadgetM) return(1); /* next graf */
if (msg->IAddress == &GadgetM1) return(0); /* next file */
continue;
case MENUPICK: /* only print and quit are allowed */
menunum = msg->Code;
ReplyMsg(msg);
while (menunum != MENUNULL)
{
switch(ITEMNUM(menunum))
{
case 4:
do_print();
break;
case 6:
done(0);
}
item = ItemAddress(&MenuList1,menunum);
menunum = item->NextSelect;
}
continue;
case MOUSEMOVE:
mx = msg->MouseX;
my = msg->MouseY;
ReplyMsg(msg);
if (mx<50 || my>180) continue; /* off grafics area */
if (mx != mousex) /* if x has changed */
{
int index;
float val;
mousex =mx;
/* get data value for current mouse X */
index = (int) ( ((float) mx - 50) / horizscale) - ystart;
if (index < ystart || index >= yend) continue;
switch (mode)
{
case 'c':
val = costsave[index];
break;
case 'm':
val = milesave[index];
break;
case 'p':
val = pricesave[index];
break;
}
/* Draw the value */
Move(rp,65L,20L);
sprintf(tempbuf,patpt2,val);
strcpy(textbuf,"Mouse @ ");
strcat(textbuf,tempbuf);
Text(rp,(UBYTE *) textbuf, (long) strlen(textbuf));
}
continue;
}
ReplyMsg(msg);
}
}
}