📄 graph.cc
字号:
// graph.cc --- graph reads data and writes out a plot file.const char *copyright_notice = "\Copyright (C) 1989 Free Software Foundation \n\ \n\This file is part of GNU CC. \n\ \n\GNU CC is distributed in the hope that it will be useful, \n\but WITHOUT ANY WARRANTY. No author or distributor \n\accepts responsibility to anyone for the consequences of using it \n\or for whether it serves any particular purpose or works at all, \n\unless he says so in writing. Refer to the GNU CC General Public \n\License for full details. \n\ \n\Everyone is granted permission to copy, modify and redistribute \n\GNU CC, but only under the conditions described in the \n\GNU CC General Public License. A copy of this license is \n\supposed to have been given to you along with GNU CC so you \n\can know your rights and responsibilities. It should be in a \n\file named COPYING. Among other things, the copyright notice \n\and this notice must be preserved on all copies. \n\";#include "read_data.h"#include "eGetOpt.h"#include "ePlotFile.h"#include "tick_intrvl.h"#include <builtin.h>#include <strstream.h>const char *usage_message = "\ [options...]\n\\n\ Option: Description:\n\ -C print copyright notice\n\ -D binary double precision data\n\ -E use extended plot file format\n\ -H CHARACTER_HEIGHT fractional height of characters\n\ -I binary integer data\n\ -K switch symbol for each new line\n\ -L switch line style for each new line\n\ -M [x|y] MARGIN margin between data and edges of box\n\ -N TICKS number of tick marks on each axis\n\ -P SIZE plot file coordinate range\n\ -S SYMBOL_NUMBER SYMBOL_SIZE draw symbols at each point\n\ -T TICK_SIZE fractional size of tick marks\n\ -W CHARACTER_WIDTH fractional width of characters\n\ -X X_LABEL label printed below the x axis\n\ -Y Y_LABEL label printed right of the y axis\n\ -a STEP_SIZE LOWER_LIMIT generate abcissa, read only y values\n\ -b break lines whenever x decreases\n\ -c POINT_LABEL default label printed at each point\n\ -d print debugging information\n\ -g GRID_STYLE draw a grid in the plot\n\ -h HEIGHT fractional height of the plot\n\ -l TOP_LABEL label printed above the plot\n\ -m LINE_MODE solid and dashed lines\n\ -r RIGHT move plot right by fractional ammount\n\ -s save the screen - do not erase\n\ -t transpose x ans y axes\n\ -u UP move plot up by fractional ammount\n\ -w WIDTH fractional width of the plot\n\ -x [lTB] LOWER_LIMIT UPPER_LIMIT log scale, axis limits\n\ -y [lLR] LOWER_LIMIT UPPER_LIMIT log scale, axis limits\n\ -z do not read data from standard input\n\";// Here are the command line option data and flags:String default_label; // default label at each point.String top_label; // label above the plot.String x_label; // x axis labelString y_label; // y axis labeldata_type input_data = ASCII; // the type of data to be read in.double char_height = .03; // fractional height of printed charactersdouble char_width = .02; // fractional width of printed charactersdouble height = .8; // fraction height of the plot.double lower_limit = 0.; // lower limit in x for generated valuesdouble no_of_ticks = 5.; // number of tick marks on the axes.double right = .1; // the fractional margin on the right side.double size_of_ticks = .01; // fractional size of the tick marks.double spacing = 1.; // stepsize for equally spaced generated valuesdouble symbol_size = .01; // index of symbol drawn at each point.double up = .1; // the fractional margin above the plot.double width = .8; // fraction width of the plot.double x_lower_limit = HUGE; // HUGE means get it from the datadouble x_margin = 0.0; // fractional margin between data and boxdouble x_upper_limit = HUGE; // HUGE means get it from the datadouble y_lower_limit = HUGE; // HUGE means get it from the datadouble y_margin = 0.05; // fractional margin between data and boxdouble y_upper_limit = HUGE; // HUGE means get it from the dataint abcissa_flag = 0; // nonzero means generate x axiz valuesint break_flag = 0; // break the line whenever x decreases.int debug_flag = 0; // verbose debugging output.int extended_plot_format = 0; // nonzero means use adjusted labels.int grid_style = 1; // style of box and or axes.int line_style = 0; // the type of line drawn to connect points.int no_standard_input = 0; // nonzero means do not read from standard inputint plot_size = 4096; // upper limit of plot file coordinatesint save_screen_flag = 0; // nonzero means do not erase before plotting.int switch_style = 0; // switch line style for each new curveint switch_symbols = 0; // switch symbols when starting each new curveint symbol_number = -1; // index of symbol drawn at each point.int transpose_axes_flag = 0; // nonzero means interchange x and y axes.int x_label_on_top = 0; // nonzero means label tick marks on right sideint x_log_scale = 0; // the x axis is log scaleint y_label_on_right = 0; // nonzero means label tick marks on topint y_log_scale = 0; // the y axis is log scale// the names of line styles recognized in the unix plot file convention.char *line_style_name[] ={ "solid", "longdashed", "dotted", "disconnected", "dotdashed", "shortdashed" };const int no_of_line_styles = sizeof(line_style_name)/sizeof(line_style_name[0]);// This is all the data describing how to draw the symbols. typedef enum op {END, CONT, MOVE, CIRCLE}; // a graphic operationstruct coord // a component coordintate within a symbol{ double x, y; // fractional coordinates op operation; // the type of graphic};struct coord symbol[][10] = // set of symbols{ { // plus sign { -.5, .0, MOVE}, { .5, .0, CONT}, { .0, -.5, MOVE}, { .0, .5, CONT}, { .0, .0, END} }, { // cross { -.5, -.5, MOVE}, { .5, .5, CONT}, { .5, -.5, MOVE}, { -.5, .5, CONT}, { .0, .0, END} }, { // diamond { -.5, .0, MOVE}, { .0, .5, CONT}, { .5, .0, CONT}, { .0, -.5, CONT}, { -.5, .0, CONT}, { .0, .0, END} }, { // square { -.5, -.5, MOVE}, { -.5, .5, CONT}, { .5, .5, CONT}, { .5, -.5, CONT}, { -.5, -.5, CONT}, { .0, .0, END} }, { // triangle { -.5, -.5, MOVE}, { .0, .86603, CONT}, { .5, -.5, CONT}, { -.5, -.5, CONT}, { .0, .0, END} }, { // circle { .5, .0, CIRCLE}, { .0, .0, END} }, { // circle with a line through it { .5, .0, CIRCLE}, { .0, -.5, MOVE}, { .0, .5, CONT}, { .0, .0, END} } // add more symbols here...};const int no_of_symbols = sizeof(symbol) / sizeof(symbol[0]);// Here are the functions for transforming and clipping.inline int px (double t) // transform fractional x to plot x{ return (int) (plot_size * (width * t + right)); // should we round rather than // truncate here?}inline int py (double t) // transform fractional x to plot x{ return (int) (plot_size * (height * t + up));}inline double clip (double t){ return (t >? 0.) <? 1.;}// uppper and lower bounds on the datadouble xmin = HUGE, ymin = HUGE, xmax = -HUGE, ymax = -HUGE;double log_xmin, log_ymin, log_xmax, log_ymax;inline double fx (double t) // transform data x to fractional x{ return x_log_scale ? (log (t) - log_xmin) / (log_xmax - log_xmin) : (t - xmin) / (xmax - xmin);}inline double fy (double t) // transform data y to fractional y{ return y_log_scale ? (log (t) - log_ymin) / (log_ymax - log_ymin) : (t - ymin) / (ymax - ymin);}inline int in_box (double x, double y) // return 1 if point is inside box{ return (x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax);}intmain (int argc, char **argv){ eGetOpt getopt (argc, argv, "CDEH::IJKLM::N::P::ST::W::X::Y::a::bc::dg::h::l::m::r::stu::vw::x::y::z"); int option_char; int error_occurred = 0; // non zero for a bad command line option while (EOF != (option_char = getopt ())) switch (option_char) { case 'C': cerr << copyright_notice; break; case 'D': input_data = DOUBLE; break; case 'E': extended_plot_format++; break; case 'H': getopt.next_arg (char_height); break; case 'I': input_data = INT; break; case 'K': switch_symbols++; break; case 'L': switch_style++; break; case 'M': if ('x' == getopt.first_char()) {getopt.optind++; getopt.next_arg (x_margin);} break; if ('y' == getopt.first_char()) {getopt.optind++; getopt.next_arg (y_margin);} break; case 'N': getopt.next_arg (no_of_ticks); break; case 'P': getopt.next_arg (plot_size); break; case 'S': getopt.next_arg (symbol_number); getopt.next_arg (symbol_size); break; case 'T': getopt.next_arg (size_of_ticks); break; case 'W': getopt.next_arg (char_width); break; case 'X': getopt.next_arg (x_label); break; case 'Y': getopt.next_arg (y_label); break; case 'a': abcissa_flag++; getopt.next_arg (spacing); getopt.next_arg (lower_limit); break; case 'b': break_flag++; break; case 'c': getopt.next_arg (default_label); break; case 'd': debug_flag++; break; case 'g': getopt.next_arg (grid_style); break; case 'h': getopt.next_arg (height); break; case 'l': getopt.next_arg (top_label); break; case 'm': getopt.next_arg (line_style); break; case 'r': getopt.next_arg (right); break; case 's': save_screen_flag++; break; case 't': transpose_axes_flag++; break; case 'u': getopt.next_arg (up); break; case 'v': cerr << "graph version 0.\n"; break; case 'w': getopt.next_arg (width); break; case 'x': while (isalpha (getopt.first_char())) { switch (getopt.first_char()) { case 'T': x_label_on_top++; getopt.optind++; break; case 'B': x_label_on_top=0; getopt.optind++; break; case 'l': x_log_scale++; getopt.optind++; break; } } getopt.next_arg (x_lower_limit); getopt.next_arg (x_upper_limit); break; case 'y': while (isalpha (getopt.first_char())) { switch (getopt.first_char()) { case 'L': y_label_on_right=0; getopt.optind++; break; case 'R': y_label_on_right++; getopt.optind++; break; case 'l': y_log_scale++; getopt.optind++; break; } } getopt.next_arg (y_lower_limit); getopt.next_arg (y_upper_limit); break; case 'z': no_standard_input++; break; case '?': error_occurred++; } if (error_occurred) { cerr << "usage" sp argv[0] sp usage_message; exit (-1); } // Complain if the plot does not fits on page if (up < 0.) cerr << "Warning: the plot may extend below the bottom of the page.\n"; if (up + height > 1.) cerr << "Warning: the plot may extend above the top of the page.\n"; if (right < 0.) cerr << "Warning: the plot may extend beyond the left edge of the page.\n"; if (right + width > 1.) cerr << "Warning: the plot may extend beyond the right edge of the page.\n"; // now we start reading in all the data. pointXPlex point; // all the data is held in an array of points // read data from standard input. if (! no_standard_input) read_data (cin, "(stdard input)", point, abcissa_flag, lower_limit, spacing, symbol_number, input_data, switch_symbols); // read data files specified on command line. int i; for (i=getopt.optind; i<getopt.nargc; i++) { char *filename = getopt.nargv[i]; ifstream input_file(filename); if (cin.readable ()) read_data (cin, filename, point, abcissa_flag, lower_limit, spacing, symbol_number, input_data, switch_symbols); } // The data is read in. Look for limits. ePlotFile plot_file (fileno (stdout)); if (!save_screen_flag) plot_file.erase (); if (point.length () <= 0) { // Complain if there is no data. cerr << argv[0] << ": Warning, no data found in input files.\n"; xmin = 0; ymin = 1; xmax = 0; ymax = 1; } else { // if there is data... if (debug_flag) for (i = point.low (); i < point.fence (); point.next (i)) { cerr << point[i].x sp point[i].y; if (point[i].label) cerr sp point[i].label;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -