⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ascii_chart.c

📁 用于OMNeT++的模板
💻 C
📖 第 1 页 / 共 2 页
字号:
/* code modified Sept 1999 to produce bar charts as well as pies * Copyright (C) 1999 Chris Elliott ( cje2@york.ac.uk ) and Bernhard Reiter  * GNU public licence still applies * -X labels X axis of bar chart -Y labels Y axis of chart *  * v0.05 bug with -Y often giving a seg fault traced to fault on optarg list * v0.1 -r adius and -d istance options control size in  bar chart *//* Bernhard Reiter 	Fri Oct 10 20:07:12 MET DST 1997 * $Id: piechart.c,v 1.11 1999/04/03 10:26:32 breiter Exp $ * * Copyright (C) 1997,1998 by Bernhard Reiter  *  *    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 *   along with this program; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *	 *	Creates bar or piechart, must be linked with a libplot library *	reads ascii input file from stdin. * *	format: one slice per line. every trailing tab and space will *		be ignored. The string after the last tab or space is *		will be scanned as value. The beginnign is the label-text. *		Empty lines and lines starting with "#" are ignored * *	TODO: many improvements possible. *		- make stuff more dynamic (input linelength and max # of slices) *		- better handling of progname *		- move much stuff into command line options *		e.g.	 *			+ fonts *			+ rotation of the pie *		- use getopt_long *		- make better assumptions on how to place the labels *		- add printing percentage numbers and values;as options *		- special handling of very small slices *		- make multi line labels possible *		- multi-line titles? *		- does every system have strdup(), strncpy()? *		-  *		... * *	THANKS: To "Martin J. Evans" <martin@mjedev.demon.co.uk> *		for pointing out that some systems do not terminate *		the target string after strncpy(). *		 *		Jan-Oliver Wagner <jwagner@usf.uni-osnabrueck.de> *		created first version ito work with gnuplotutils-2.2. */#include <stdio.h>#include <plot.h>#include <unistd.h>#define min(X, Y)  ((X) < (Y) ? (X) : (Y))#define max(X, Y)  ((X) > (Y) ? (X) : (Y))#define VERSION "0.91 "void print_version(FILE * file){	fprintf(file, "ascii_chart version " VERSION "\n");	fprintf(file, "Copyright (C) 1998, 1999 by Bernhard Reiter & Chris Elliott. \n" "The GNU GENERAL PUBLIC LICENSE applies. " "Absolutly No Warranty!\n");#ifdef DEBUG	fprintf(file, "compiled with option: DEBUG\n");#endif}/* * $Log: piechart.c,v $ * Revision 1.11  1999/04/03  10:26:32  breiter * adapted to plotutils-2.2: added pl_ to all function calls * adjusted help text * more return values are checked now, as the function provide more of them * end circle and middle point are only drawn if LINEWIDTH is not default * changed constant name LINEWIDTH_LINES -> LINEWIDTH * end circle and middle point LINEWIDTH is multiplied with a factor(~1.2) now * extra external variables for getopt() are commented out * * Revision 1.10  1998/07/28  13:41:54  breiter * - Terminating strncpy()ed string now. Thanks to "Martin J. Evans" * for reporting this problem. * - Removed hard limit on label-size. * - Changed inputline buffersize to a new constant defined as LINE_BUFSIZ. * - Cleaned up some comments. * version number incremented to 0.8 * * Revision 1.9  1998/07/07  23:44:26  breiter * added -C option for specifing colors * version number is 0.7 now. * * Revision 1.8  1998/07/07  17:04:40  breiter * major improvements: * - more structure: moves code into functions: process_arguments(),read_stdin() * - new scanning -> multi word labels are possible now * - two new options: -r radius and -d text distance * - errmsgs and usage are printed to stderr now, but to stdout, wenn requested * - fixed debug output typo * * Revision 1.7  1998/01/31  16:13:02  breiter * changed fill() -> filltype() as fill() is only temporarily supported * * Revision 1.6  1998/01/31  16:05:40  breiter * using a path to draw one slice now. This is far simpler. * No need for LINEWIDTH_FILL anymore. * * Revision 1.5  1998/01/30  16:06:37  breiter * adapted for use with libplot from plotutils-2.0 * added +T display-type commandline option therefore. * * Revision 1.4  1997/10/11  17:19:14  breiter * cosmetic changes. version information enhanced. * * Revision 1.3  1997/10/11  16:31:56  breiter * version information enhanced. * * Revision 1.2  1997/10/11  16:09:15  breiter * bug fixes. small improvements. userspace is always square now. * * Revision 1.1  1997/10/11  15:07:27  breiter * Initial revision * */#include <stdlib.h>#include <math.h>#include <string.h>				/* for strdup() *//* this program used getopt and relys on that it is included in the  * stdlib. I wanted to use getopt_long from Gnu, but it is not included * in the clib i have here. So it is still left TODO. *//******************************************************************************* * Configurations -- change, what you like * 	If time permits some stuff could be influenced by command line options ******************************************************************************//*	Color in which the separating lines and the circle are drawn */#define LINECOLOR "black"/* LINEWIDTH is for the separating lines and the arcs * if closing circle and middle point will be drawn, a factor will be applied * -1 means default ; 0.02 might be a usefull value */#define LINEWIDTH -1/* Some hardcoded limits: * the max number of slices (^=MAXSLICES). * LINE_BUFSIZ is the maxmumlength of input-lines. *(You see, how lasy i was. I was not using some object orientated language *	like objective-c and left all the neat dynamic string handling for *	the interested hacker and or some version in the future.) */#define MAXSLICES 65#define LINE_BUFSIZ 256/* if an input line starts with this character, it is ignored.		*/#define COMMENTCHAR '#'/* Colors the slices are getting filled with. * the color names are feed into the libplot functions. * The plotutils distribution contains a file doc/colors.txt which lists the * recogized names. * * if the nullpointer is reached the color pointer is resetted starting * with the first color again. */char *colortable[MAXSLICES] = {	/* colors changed by chris */	"red", "blue", "green", "yellow",	"firebrick", "aliceblue", "greenyellow", "wheat",	NULL};/******************************************************************************* * Beware: This following code is for hackers only. * 	( Yeah, it is not THAT bad, you can risk a look, if you know some C ..) ******************************************************************************//* Program structure outline: *	- get all options  *	- read all input data (only from stdin so far) *	- print *		+ init stuff *		+ print title *		+ print color part for slices *		+ print separating lines and circle *		+ print labels *		+ clean up stuff *//* A nice structure, we will fill some of it, when we read the input. */struct slice{	char *text;					/* label for the slice          */	double value;				/* value for the slice          */};/* one global variable. It is needed everywhere..				*/char *progname;					/*  for printing errors out     *//* declarations of functions defined after main()			 */void process_arguments(int argc, char **argv, char **display_type, char **title, char **xtext, char **ytext, int *isPie, double *radius, double *text_distance, char *colortable[]);void read_stdin(int *n_slices, struct slice *slices[MAXSLICES]);/* Attention: Main Progam to be started.... :)				*/int main(int argc, char **argv){	char *title = NULL;			/* Title of the chart           */	char *xtext = NULL;			/* X axis Title of the chart            */	char *mytext = NULL;		/* Y axis Title of the chart            */	int return_value;			/* return value for libplot calls.  */	char *display_type = "meta";	/* default libplot output format    */	int handle;					/* handle for open plotter      */	struct slice *slices[MAXSLICES];	/* the array of slices          */	int n_slices = 0;			/* number of slices in slices[] ;)  */	int t;						/* loop var(s)              */	double slice_max, sum;		/* max and sum of all slice values chris        */	int neg_flag;	/* check all values > 0 chris */	double radius = 0.8;		/* radius of the circle in plot coords  */	double text_distance = 0;	/* distance of text from circle     */	int isPie = 0;				/* switch mode; chris */	double text_space;/* vars for ymax */	char buffer[55];	double ymax;	int ystep;	int nf[4] = { 2, 5, 2, 0 };	int n = 1;	ymax = 1.0;	ystep = 0;	process_arguments(argc, argv, &display_type, &title, &xtext, &mytext, &isPie, &radius, &text_distance, colortable);	read_stdin(&n_slices, slices);/* Let us find the sum and  max and check for negative values *//* code added to by chris */	sum = 0;	slice_max = 1.;	neg_flag = 0;	for (t = 0; t < n_slices; t++)	{		sum += slices[t]->value;		slice_max = max(slice_max, slices[t]->value);		if (slices[t]->value < 0)			neg_flag++;	}	if (neg_flag)	{		fprintf(stderr, "Some data were apparently less than zero. \nThis version of the program does not plot negative values.\n");		exit(1);	}/* initialising one plot session	*/	/* specify type of plotter      */	handle = pl_newpl(display_type, NULL, stdout, stderr);	if (handle < 0)	{		fprintf(stderr, "The plotter could not be created.\n");		exit(1);	}	return_value = pl_selectpl(handle);	if (return_value < 0)	{		fprintf(stderr, "The plotter does not exist or could not be selected.\n");		exit(1);	}	return_value = pl_openpl();	if (return_value < 0)	{		fprintf(stderr, "The selected plotter could not be opened!\n");		exit(1);	}/* now decide to plot bar or pie */	if (isPie)	{		/* creating your user coordinates   */		if (title)			return_value = pl_fspace(-1.4, -1.4, 1.4, 1.4);		else			return_value = pl_fspace(-1.2, -1.2, 1.2, 1.2);		if (return_value)		{			fprintf(stderr, "fspace returned %d!\n", return_value);		}/* we should be ready to plot pie, now! */		/* i like to think in degrees.      */#define X(radius,angle) (cos(angle)*(radius))#define Y(radius,angle) (sin(angle)*(radius))#define RAD(angle) (((angle)/180.)*M_PI)#define XY(radius,angle) (X((radius),RAD(angle))),(Y((radius),RAD(angle)))/* plot title if there is one */		if (title && *title)		{			pl_fmove(0, radius + text_distance + 0.2);			pl_alabel('c', 'b', title);		}		pl_pencolorname(LINECOLOR);/* and now for the slices		*/		{			double distance, angle = 0;			char **color = colortable;			double r = radius;	/*the radius of the slice circle */			pl_savestate();			pl_joinmod("round");			/* drawing the slices           */			pl_filltype(1);			pl_flinewidth(LINEWIDTH);			pl_pencolorname(LINECOLOR);			for (t = 0; t < n_slices; t++)				/* draw one path for every slice    */			{				distance = (slices[t]->value / sum) * 360.;				pl_fillcolorname(*color);				pl_fmove(0, 0);	/* start at center..            */				pl_fcont(XY(r, angle));				if (distance > 179)				{				/* we need to draw a semicircle first   */					/* we have to be sure to draw 					   counterclockwise (180 wouldn`t work 					   in all cases)            */					pl_farc(0, 0, XY(r, angle), XY(r, angle + 179));					angle += 179;					distance -= 179;				}				pl_farc(0, 0, XY(r, angle), XY(r, angle + distance));				pl_fcont(0, 0);	/* return to center         */				pl_endpath();	/* not really necessary, but intuitive  */				angle += distance;	/* log fraction of circle already drawn */				color++;		/* next color for next slice        */				if (!*color)					color = colortable;	/* start over if all colors used   */			}			/* the closing circle and middle point  */			/* only, if LINEWIDTH!=default  */			if (LINEWIDTH != -1)			{				/* add %5 to compensate for arc obstrution */				pl_flinewidth(LINEWIDTH * 1.2);				pl_filltype(0);				pl_fcircle(0., 0., r);				pl_colorname(LINECOLOR);				pl_filltype(1);				pl_fpoint(0, 0);			}			pl_restorestate();		}/* and now for the text		*/		{			double distance, angle = 0, place;			double r = radius + text_distance;	/* radius of circle where text is placed */			char h, v;			pl_savestate();			for (t = 0; t < n_slices; t++)			{				distance = (slices[t]->value / sum) * 360.;				/* let us calculate the position ...    */				place = angle + 0.5 * distance;				/* and the alignment            */				if (place < 180)					v = 'b';				else					v = 't';				if (place < 90 || place > 270)					h = 'l';				else					h = 'r';				/* plot now!                */				pl_fmove(XY(r, place));				pl_alabel(h, v, slices[t]->text);				angle += distance;			}			pl_restorestate();		}	}							/* end of is Pie */	else	{							/* next part plots bars , chris */		if (title || xtext || mytext)		{			text_space = -2.0 - text_distance;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -