📄 ascii_chart.c
字号:
else { text_space = -1.0 - text_distance; } /* x0, y0, x1 y1 but it has to be square for the fonts */ return_value = pl_fspace(text_space / radius, text_space / radius, (10.0 - text_space) / radius, (10.0 - text_space) / radius); if (return_value) { fprintf(stderr, "fspace returned %d!\n", return_value); }/* we should be ready to plot bars, now! *//* plot title if there is one */ if (title && *title) { pl_ffontsize(0.6); pl_fmove(5, 11); pl_alabel('c', 'c', title); /* cnetered */ }/* plot X axis title if there is one */ if (xtext && *xtext) { pl_ffontsize(0.7); pl_fmove(5, 1.5 * text_space); pl_alabel('c', 'c', xtext); /* cnetered */ }/* plot Y axis title if there is one */ if (mytext && *mytext) { pl_ffontsize(0.7); pl_fmove(0.95 * text_space, 6); pl_ftextangle(90); pl_alabel('c', 'c', mytext); pl_ftextangle(0); }/* find y max */ while (ymax < slice_max) { ymax = ymax * nf[n]; n++; if (nf[n]) n = 0; } pl_line(0, 0, 0, 10.0 * ymax / slice_max);/* plot Y axis */ while (ystep < ymax) { pl_fline(-0.3, 10 * (double) ystep / slice_max, 0.0, 10 * ystep / slice_max); pl_fmove(0.3 * text_space, 10 * (double) ystep / slice_max); sprintf(buffer, "%d", ystep); pl_alabel('r', 'c', buffer); ystep = ystep + ymax / 10; if (ystep < 1) ystep++; } pl_pencolorname(LINECOLOR);/* and now for the bars */ { char **color = colortable; pl_savestate(); pl_joinmod("round"); pl_filltype(1); pl_flinewidth(LINEWIDTH); pl_pencolorname(LINECOLOR); for (t = 0; t < n_slices; t++) { pl_fillcolorname(*color); pl_fbox(10.0 * (double) (t) / (double) (n_slices), 0, 10.0 * (double) (t + 1) / (double) (n_slices), 10 * slices[t]->value / slice_max); color++; /* next color for next slice */ if (!*color) color = colortable; /* start over if all colors used */ } /* end of for each slice */ pl_restorestate(); }/* and now for the text */ { char just; just = 'c'; pl_savestate(); pl_ffontsize(0.65); if (n_slices > 3) { pl_ftextangle(90); /* degrees */ just = 'r'; } for (t = 0; t < n_slices; t++) {/* plot now! */ pl_fmove(10.0 * (double) (t + 0.5) / (double) (n_slices), 0.3 * text_space); pl_alabel(just, 'c', slices[t]->text); } pl_restorestate(); } } /* end of is ! Pie */ /* end a plot sesssion */ return_value = pl_closepl(); if (return_value < 0) { fprintf(stderr, "The plotter could not be closed.\n"); /* no exit, because we try to delete the plotter */ }/* need to select a different plotter in order to deleter our */ return_value = pl_selectpl(0); if (return_value < 0) { fprintf(stderr, "Default Plotter could not be selected!\n"); } return_value = pl_deletepl(handle); /* clean up by deleting used plotter */ if (return_value < 0) { fprintf(stderr, "Selected Plotter could not be deleted!\n"); } return 0;}/************************************************************************ * functions */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[]){/* well, we do not have the gnu getopt long here. :-( * so i use getopt for now */ int c; extern char *optarg; /* optint,opterr,optopt relate to getopt(),see manpage */ /* but we do not use them so far */ /* extern int optind,opterr,optopt; */ int errflg = 0; int show_usage = 0; int show_version = 0; int specified_display_type = 0; char **help; /* will help splitting the colornames */ char *arg; /* one string argument */ *isPie = 0; /* ie do a bar chart */ progname = argv[0]; /* fill the only global variable */ while ((c = getopt(argc, argv, "Vt:T:r:d:C:h:X:Y:P")) != EOF) switch (c) {/* chris did some debugging here */ case 't':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif if (*title) errflg++; else *title = strdup(optarg);#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'X':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif if (*xtext) errflg++; else *xtext = strdup(optarg);#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'Y':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif if (*ytext) errflg++; else *ytext = strdup(optarg);#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'T':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif if (specified_display_type) errflg++; else { specified_display_type++; *display_type = strdup(optarg); }#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'P':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif *isPie = 1;/* ie try to plot as pie chart */#ifdef DEBUG fprintf(stderr, " OK \n");#endif break; case 'r':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif *radius = atof(optarg); if (*radius < 0.1 || *radius > 1.2) errflg++;#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'd':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif *text_distance = atof(optarg); if (*text_distance < (-2.0) || *text_distance > 1.2) errflg++; /* we have a second check after processing all options */#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'C':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif help = colortable; arg = strdup(optarg); *help++ = strtok(arg, ",\0"); if (!*help) errflg++; else while ((*(help++) = strtok(NULL, ",\0")));#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'V':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif if (show_version) errflg++; else show_version++;#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case 'h':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif if (show_usage) errflg++; else show_usage++;#ifdef DEBUG fprintf(stderr, "OK \n");#endif break; case '?':#ifdef DEBUG fprintf(stderr, "Reading switch %c arg %s ", c, optarg);#endif errflg++; } /* check if text_distance is reasonable */ if (*text_distance < (-*radius)) errflg++; if (!(*isPie)) *radius = sqrt(*radius); /* for bar charts only */ /* or else the size gets too small to see */ if (errflg) { fprintf(stderr, "parameters were bad!\n"); show_usage++; } if (show_version) { print_version(stdout); exit(1); } if (show_usage) { FILE *f = stdout; if (errflg) f = stderr; else f = stdout; print_version(f); fprintf(f, "usage: %s [options]\n", progname); fprintf(f, "\t the stdin is read once.\n"); fprintf(f, "\t options are:\n" "\t\t-P Use Pie rather than Bar chart ( not -X -Y )\n" "\t\t-t Title\tset \"Title\" as chart title\n" "\t\t-X XTitle\tset \"XTitle\" as barchart X axis title\n" "\t\t-Y YTitle\tset \"YTitle\" as barchart Y axis title\n" "\t\t-T Display-Type\tone of " "X, ps, fig, hpgl, tek, meta, ai, pnm, gif\n" "\t\t\t\t(or whatever your libplot version supports)\n" "\t\t\t\t(meta is the default)\n" "\t\t-r size of chart\tfloat out of [0.1;1.2] default:0.8\n" "\t\t-d textdistance around chart \tfloat out of " "[-radius;1.2] default:0.0\n" "\t\t-C colornames\tcomma separated list of colornames\n" "\t\t\t\t(see valid names in color.txt of plotutils doc.)\n" "\t\t-h\t\tprint this help and exit\n" "\t\t-V\t\tprint version and exit\n"); exit(1); }/* Everything is fine with the options now ... */}void read_stdin(int *n_slices, struct slice *slices[MAXSLICES]){ char line[LINE_BUFSIZ]; /* input line buffer *//* So, let us read the standardinput */ while (!(feof(stdin) || ferror(stdin))) { char *c; /* string return from fgets */ struct slice *aslice; /* freshly filled slice-structure */ int r; /* help variable for scanning */ char *s, *t; /* help variables for scanning */ c = fgets(line, LINE_BUFSIZ, stdin); if (!c) continue; /* encountered error of eof */ if (line[strlen(line) - 1] != '\n') { fprintf(stderr, "line was too long!\n"); exit(2); } /* strip newline */ line[strlen(line) - 1] = '\0'; /* strip carridge return, if there is one */ if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0'; /* Skip empty lines or lines beginning * with COMMENTCHAR */ if (!(line[0] == COMMENTCHAR || !(line) || strlen(line) == 0)) {#ifdef DEBUG fprintf(stderr, "Scanning line: %s\n", line);#endif aslice = malloc(sizeof(struct slice)); if (!aslice) perror(progname), exit(10); /* scanning the last part * after a tab or space as number */ /* delete trailing tabs and spaces */ r = strlen(line); while (r > 0 && (line[r - 1] == ' ' || line[r - 1] == '\t')) line[r-- - 1] = '\0'; /* scan for last tab or space */ s = strrchr(line, ' '); t = strrchr(line, '\t'); s = (s > t ? s : t); /* which is the last white-space? */ /*use full string,if no whitespace found else copy text up to whitespace and get enough memory */ if (s == NULL) { if (!(aslice->text = malloc(1))) perror(progname), exit(10); aslice->text[0] = '\0'; s = line; } else { if (!(aslice->text = malloc(strlen(line) - strlen(s) + 1))) perror(progname), exit(10); strncpy(aslice->text, line, strlen(line) - strlen(s)); /*some systems don`t terminate target string in strncpy, so we have to do it */ aslice->text[strlen(line) - strlen(s)] = '\0'; } /* scan last string for number */ r = sscanf(s, "%lf", &aslice->value); if (r != 1) fprintf(stderr, "number in line couldn`t be scanned\n"), exit(8); if (*n_slices >= MAXSLICES) fprintf(stderr, "too many slices\n"), exit(8); slices[(*n_slices)++] = aslice; } } if (ferror(stdin)) { perror(progname); exit(5); }#ifdef DEBUG fprintf(stderr, "Read %d slices!\n", *n_slices);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -