1 #define	GRAPH_VERBOSE
2 /*
3  * Copyright � 1993, 1999, 2000, 2001 Free Software Foundation, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this software; see the file COPYING.  If not, write to
17  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 /*
21  * $Id: graph.c,v 1.22 2001/02/13 23:38:05 danny Exp $
22  *
23  * This file contains the functions to maintain the internal graphing
24  * data structures in Oleo.
25  */
26 
27 #undef	GRAPH_VERBOSE
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #ifdef	WITH_DMALLOC
34 #include <dmalloc.h>
35 #endif
36 
37 #include <ctype.h>
38 #include <stdlib.h>
39 
40 #include "global.h"
41 #include "graph.h"
42 #include "cmd.h"
43 #include "line.h"
44 #include "io-term.h"
45 #include "info.h"
46 #include "cell.h"
47 #include "regions.h"
48 #include "ref.h"
49 #include "io-utils.h"
50 
51 char * graph_axis_name [graph_num_axis] =
52 {
53   "x", "y"
54 };
55 
56 static char * graph_plot_styles [] =
57 {
58   "lines",
59   "points",
60   "linespoints",
61   "impulses",
62   "dots",
63    0
64 };
65 
66 int graph_ornt_row_magic[graph_num_pair_orientations] = { 0, 1, 0 };
67 int graph_ornt_col_magic[graph_num_pair_orientations] = { 1, 0, 0 };
68 
69 enum graph_axis
chr_to_axis(int c)70 chr_to_axis (int c)
71 {
72   if (isupper (c))
73     c = tolower (c);
74   switch (c)
75     {
76     case 'x':
77       return graph_x;
78     case 'y':
79       return graph_y;
80     }
81   io_error_msg ("Unkown graph-axis `%c' (try `x' or `y')", c);
82   return graph_x;		/* not reached, actualy. */
83 }
84 
85 char *
line_to_q_char(struct line line)86 line_to_q_char (struct line line)
87 {
88   static struct line tmp_line;
89   char *str;
90 
91   str = line.buf;
92 
93   set_line (&tmp_line, "\"");
94   while (*str)
95     {
96       switch (*str)
97 	{
98 	case '"':
99 /* gnuplot doesn't like escaped quotation marks in titles anyway.
100  * If you want to support them, you'll have to protect against
101  * progressive buildup, since this stores the post-escaping string
102  * back into the original char.
103  */
104 /*        catn_line (&tmp_line, "\\\"", 2); */
105 	  break;
106 	default:
107 	  catn_line (&tmp_line, str, 1);
108 	  break;
109 	}
110       ++str;
111     }
112   catn_line (&tmp_line, "\"", 1);
113 
114   set_line(&line, tmp_line.buf);
115 
116   return line.buf;
117 }
118 
119 char *
char_to_q_char(char * str)120 char_to_q_char (char *str)
121 {
122   char *tmp;
123 
124   static struct line tmp_line;
125   set_line (&tmp_line, str);
126   tmp = line_to_q_char (tmp_line);
127   return (tmp);
128 }
129 
130 void
graph_set_axis_title(int axis_c,char * title)131 graph_set_axis_title (int axis_c, char * title)
132 {
133   enum graph_axis axis = chr_to_axis (axis_c);
134 #ifdef	GRAPH_VERBOSE
135   fprintf(stderr, "graph_set_axis_title(%c,%s)\n", axis_c, title);
136 #endif
137   set_line (&Global->PlotGlobal->graph_axis_title [axis], char_to_q_char (title));
138 }
139 
140 char *
graph_get_axis_title(int axis_c)141 graph_get_axis_title (int axis_c)
142 {
143   enum graph_axis axis = chr_to_axis (axis_c);
144   return Global->PlotGlobal->graph_axis_title[axis].buf;
145 }
146 
147 void
graph_set_logness(int axis_c,int explicit,int newval)148 graph_set_logness (int axis_c, int explicit, int newval)
149 {
150   enum graph_axis axis = chr_to_axis (axis_c);
151   static struct line msg_buf;
152 
153   if (!explicit)
154     newval = !Global->PlotGlobal->graph_logness [axis];
155   else
156     newval = (newval > 0);
157 
158   Global->PlotGlobal->graph_logness [axis] = newval;
159   sprint_line (&msg_buf, "%slogarithmic %s%s",
160 	       ((Global->PlotGlobal->graph_logness [graph_x] || Global->PlotGlobal->graph_logness [graph_y])
161 		? "" : "no"),
162 	       Global->PlotGlobal->graph_logness[graph_x] ? "x" : "",
163 	       Global->PlotGlobal->graph_logness[graph_y] ? "y" : "");
164 #if 0
165   io_info_msg ("set %s", msg_buf.buf);
166 #endif
167 }
168 
169 int
graph_get_logness(int axis_c)170 graph_get_logness(int axis_c)
171 {
172   enum graph_axis axis = chr_to_axis (axis_c);
173   return Global->PlotGlobal->graph_logness [axis];
174 }
175 
176 void
graph_check_range(char * val)177 graph_check_range (char * val)
178 {
179   if (says_default (val))
180     return;
181   while (isspace (*val)) ++val;
182   if (*val == '-') ++val;
183   while (isspace (*val)) ++val;
184   if (!isdigit (*val))
185     io_error_msg
186       ("Illegal range specifier %s (should be a number or `def').", val);
187   else
188     {
189       while (*val)
190 	if (isspace (*val) || isdigit (*val))
191 	  ++val;
192 	else
193 	  break;
194       while (isspace (*val)) ++val;
195       if (*val == '.') ++val;
196       while (*val)
197 	if (isspace (*val) || isdigit (*val))
198 	  ++val;
199 	else
200 	  io_error_msg
201 	    ("Illegal range specifier %s (should be a number or `def').", val);
202     }
203 
204 }
205 
206 
207 void
graph_set_axis_lo(int axis_c,char * val)208 graph_set_axis_lo (int axis_c, char * val)
209 {
210   enum graph_axis axis = chr_to_axis (axis_c);
211 #ifdef	GRAPH_VERBOSE
212   fprintf(stderr, "graph_set_axis_lo(%c,%s)\n", axis_c, val);
213 #endif
214   graph_check_range (val);
215   set_line (&Global->PlotGlobal->graph_rng_lo [axis], val);
216   Global->PlotGlobal->XYMin[axis] = atof(val);
217   Global->PlotGlobal->graph_axis_symbols [axis].lr = NON_ROW;
218 }
219 
220 
221 void
graph_set_axis_hi(int axis_c,char * val)222 graph_set_axis_hi (int axis_c, char * val)
223 {
224   enum graph_axis axis = chr_to_axis (axis_c);
225 #ifdef	GRAPH_VERBOSE
226   fprintf(stderr, "graph_set_axis_hi(%c,%s)\n", axis_c, val);
227 #endif
228   graph_check_range (val);
229   set_line (&Global->PlotGlobal->graph_rng_hi [axis], val);
230   Global->PlotGlobal->XYMax[axis] = atof(val);
231   Global->PlotGlobal->graph_axis_symbols [axis].lr = NON_ROW;
232 }
233 
234 void
graph_default_axis_labels(int axis_c)235 graph_default_axis_labels (int axis_c)
236 {
237   enum graph_axis axis = chr_to_axis (axis_c);
238   Global->PlotGlobal->graph_axis_labels [axis].lr = NON_ROW;
239 }
240 
241 int
graph_check_style(char * name)242 graph_check_style (char * name)
243 {
244   int x =
245     words_member (graph_plot_styles, parray_len (graph_plot_styles), name);
246   if (x < 0)
247     io_error_msg
248       ("Invalid line style %s. (Try M-x describe-function set-graph-style).");
249   return x;
250 }
251 
252 
253 void
graph_set_style(int data_set,char * style)254 graph_set_style(int data_set, char * style)
255 {
256   if ((data_set < 0) || (data_set >= NUM_DATASETS))
257     io_error_msg
258       ("set-graph-style -- data-set out of range: %d (should be in [0..%d])",
259        data_set, NUM_DATASETS);
260 #if 0
261   {
262   int x = graph_check_style (style);
263   set_line (&Global->PlotGlobal->graph_style[data_set], graph_plot_styles [x]);
264   }
265 #endif
266 }
267 
268 void
graph_set_data_title(int data_set,char * title)269 graph_set_data_title (int data_set, char * title)
270 {
271   if ((data_set < 0) || (data_set >= NUM_DATASETS))
272     io_error_msg
273       ("set-graph-title -- data-set out of range: %d (should be in [0..%d])",
274        data_set, NUM_DATASETS);
275 #ifdef	GRAPH_VERBOSE
276   fprintf(stderr, "graph_set_data_title(%d,%s)\n", data_set, title);
277 #endif
278   set_line (&Global->PlotGlobal->graph_title [data_set], title);
279 }
280 
281 char *
graph_get_data_title(int data_set)282 graph_get_data_title(int data_set)
283 {
284   if ((data_set < 0) || (data_set >= NUM_DATASETS))
285     return NULL;
286   return Global->PlotGlobal->graph_title[data_set].buf;
287 }
288 
289 void
plotutils_set_data(int data_set,struct rng * rng)290 plotutils_set_data(int data_set, struct rng *rng)
291 {
292   if ((data_set < 0) || (data_set >= NUM_DATASETS))
293     io_error_msg
294       ("set-graph-data -- data-set out of range: %d (should be in [0..%d])",
295        data_set, NUM_DATASETS);
296   Global->PlotGlobal->graph_data[data_set] = *rng;
297 }
298 
299 void
graph_set_data(int data_set,struct rng * rng)300 graph_set_data(int data_set, struct rng * rng)
301 {
302   if ((data_set < 0) || (data_set >= NUM_DATASETS))
303     io_error_msg
304       ("set-graph-data -- data-set out of range: %d (should be in [0..%d])",
305        data_set, NUM_DATASETS);
306   Global->PlotGlobal->graph_data[data_set] = *rng;
307 }
308 
309 struct rng
graph_get_data(int data_set)310 graph_get_data(int data_set)
311 {
312 	return Global->PlotGlobal->graph_data[data_set];
313 }
314 
315 
316 void
graph_presets(void)317 graph_presets (void)
318 {
319   enum graph_axis axis;
320 
321   if (using_curses) {
322 	if (getenv("DISPLAY")) {
323 		/*
324 		 * We're using curses in an X environment, let's
325 		 * default to Tektronix on stdout.
326 		 */
327 		plotutils_tek();
328 		plotutils_set_filename("-");
329 	} else {
330 		graph_postscript ("#plot.ps", 'd', 'm', "TimesRoman", 12);
331 	}
332   } else {
333 #if 0
334     graph_x11_mono ();
335 #endif
336   }
337 
338     for (axis = graph_x; axis < graph_num_axis; ++axis)
339       {
340 	int axis_c = graph_axis_name [axis][0];
341 	Global->PlotGlobal->graph_logness [axis] = 0;
342 	graph_set_axis_title (axis_c, "");
343 	graph_set_axis_lo (axis_c, "def");
344 	graph_set_axis_hi (axis_c, "def");
345 	graph_set_axis_title (axis_c, "");
346 	graph_default_axis_labels (axis_c);
347       }
348 }
349 
350 void
graph_clear_datasets(void)351 graph_clear_datasets (void)
352 {
353   int x;
354   for (x = 0; x < NUM_DATASETS; ++x)
355     {
356       graph_set_style(x, "lines");
357       graph_set_data_title(x, "");
358       Global->PlotGlobal->graph_data[x].lr = NON_ROW;
359     }
360 }
361 
362 
363 void
init_graphing(void)364 init_graphing (void)
365 {
366   PlotInit();
367 
368   graph_presets ();
369   graph_clear_datasets ();
370 
371   XYxAuto = XYyAuto = 1;
372 }
373 
374 void
for_pairs_in(struct rng * rng,enum graph_pair_ordering order,fpi_thunk thunk,void * frame)375 for_pairs_in (struct rng * rng, enum graph_pair_ordering order, fpi_thunk thunk, void * frame)
376 {
377   CELLREF r;
378   CELLREF c;
379   enum graph_pair_orientation ornt = order % graph_num_pair_orientations;
380   enum graph_ordering dir = ORDER_OF_PAIRS(order);
381   int r_inc = 1 + graph_ornt_row_magic [ornt];
382   int c_inc = 1 + graph_ornt_col_magic [ornt];
383   if (dir == graph_rows)
384     {
385       r = rng->lr;
386       while (1)
387 	{
388 	  c = rng->lc;
389 	  while (1)
390 	    {
391 	      CELLREF y_r = r + graph_ornt_row_magic [ornt];
392 	      CELLREF y_c = c + graph_ornt_col_magic [ornt];
393 	      CELL * cell = find_cell (y_r, y_c);
394 	      thunk (frame, cell, y_r, y_c);
395 	      if ((rng->hc - c) < c_inc)
396 		break;
397 	      c += c_inc;
398 	    }
399 	  if ((rng->hr - r) < r_inc)
400 	    break;
401 	  r += r_inc;
402 	}
403     }
404   else
405     {
406       c = rng->lc;
407       while (1)
408 	{
409 	  r = rng->lr;
410 	  while (1)
411 	    {
412 	      CELLREF y_r = r + graph_ornt_row_magic [ornt];
413 	      CELLREF y_c = c + graph_ornt_col_magic [ornt];
414 	      CELL * cell = find_cell (y_r, y_c);
415 	      thunk (frame, cell, y_r, y_c);
416 	      if ((rng->hr - r) < r_inc)
417 		break;
418 	      r += r_inc;
419 	    }
420 	  if ((rng->hc - c) < c_inc)
421 	    break;
422 	  c += c_inc;
423 	}
424     }
425 }
426 
427 static char *graph_plot_title = NULL;
428 
429 void
graph_set_title(char * t)430 graph_set_title(char *t)
431 {
432 	if (graph_plot_title)
433 		free(graph_plot_title);
434 	graph_plot_title = strdup(t);
435 #ifdef	GRAPH_VERBOSE
436 	fprintf(stderr, "graph_set_title(%s)\n", t);
437 #endif
438 }
439 
440 char *
graph_get_title(void)441 graph_get_title(void)
442 {
443 	return	graph_plot_title;
444 }
445 
446 void
graph_set_axis_auto(int axis,int set)447 graph_set_axis_auto(int axis, int set)
448 {
449 	if (axis == 0  || axis == 1)
450 		Global->PlotGlobal->XYAuto[axis] = set;
451 	else {
452 		io_error_msg("Invalid graph axis %d, must be 0 or 1", axis);
453 	}
454 #ifdef	GRAPH_VERBOSE
455 	fprintf(stderr, "graph_set_axis_auto(%d,%d)\n", axis, set);
456 #endif
457 }
458 
459 int
graph_get_axis_auto(int axis)460 graph_get_axis_auto(int axis)
461 {
462 	if (axis == 0  || axis == 1)
463 		return Global->PlotGlobal->XYAuto[axis];
464 
465 	io_error_msg("Invalid graph axis %d, must be 0 or 1", axis);
466 	return 1;
467 }
468 
469 double
graph_get_axis_lo(int axis)470 graph_get_axis_lo(int axis)
471 {
472 	if (axis < 0 || axis > graph_num_axis) {
473 		io_error_msg("graph_get_axis_lo : invalid graph axis %d, must be 0 or 1", axis);
474 		return 0.0;
475 	}
476 	return Global->PlotGlobal->XYMin[axis];
477 }
478 
479 double
graph_get_axis_hi(int axis)480 graph_get_axis_hi(int axis)
481 {
482 	if (axis < 0 || axis > graph_num_axis) {
483 		io_error_msg("graph_get_axis_hi: invalid graph axis %d, must be 0 or 1", axis);
484 		return 0.0;
485 	}
486 	return Global->PlotGlobal->XYMax[axis];
487 }
488 
489 void
graph_set_linetooffscreen(int set)490 graph_set_linetooffscreen(int set)
491 {
492 	Global->PlotGlobal->LineToOffscreen = set;
493 #ifdef	GRAPH_VERBOSE
494 	fprintf(stderr, "graph_set_linetooffscreen(%d)\n", set);
495 #endif
496 }
497 
498 int
graph_get_linetooffscreen(void)499 graph_get_linetooffscreen(void)
500 {
501 	return Global->PlotGlobal->LineToOffscreen;
502 }
503 
504 /*
505  * Axis tick marks
506  */
507 void
graph_set_axis_ticks(int axis,int ticktype,char * fmt)508 graph_set_axis_ticks(int axis, int ticktype, char *fmt)
509 {
510 #ifdef	GRAPH_VERBOSE
511 	fprintf(stderr, "graph_set_axis_ticks(%d, %d, %s)\n", axis, ticktype, fmt);
512 #endif
513 
514 	if (axis < 0 || axis > graph_num_axis) {
515 		io_error_msg("graph_set_axis_ticks: invalid graph axis %d, must be 0 or 1", axis);
516 		return;
517 	}
518 
519 	Global->PlotGlobal->ticktype[axis] = ticktype;
520 	Global->PlotGlobal->tickformat[axis] = fmt;
521 }
522 
523 int
graph_get_axis_ticktype(int axis)524 graph_get_axis_ticktype(int axis)
525 {
526 	if (axis < 0 || axis > graph_num_axis) {
527 		io_error_msg("graph_get_axis_ticktype: invalid graph axis %d, must be 0 or 1", axis);
528 		return 0;
529 	}
530 
531 	return Global->PlotGlobal->ticktype[axis];
532 }
533 
534 char *
graph_get_axis_tickformat(int axis)535 graph_get_axis_tickformat(int axis)
536 {
537 	if (axis < 0 || axis > graph_num_axis) {
538 		io_error_msg("graph_get_axis_tickformat: invalid graph axis %d, must be 0 or 1", axis);
539 		return 0;
540 	}
541 
542 	return Global->PlotGlobal->tickformat[axis];
543 }
544 
545 void
graph_postscript(char * file,int kind,int spectrum,char * font,int pt_size)546 graph_postscript (char * file, int kind, int spectrum, char * font, int pt_size)
547 {
548   if (isupper (kind))
549     kind = tolower (kind);
550   if (isupper (spectrum))
551     spectrum = tolower (spectrum);
552   if (!index ("led", kind))
553     io_error_msg
554       ("Incorrect postscript graph type %c (should be one of l, e, or c)",
555        kind);
556   if (!index ("mc", spectrum))
557     io_error_msg
558       ("Incorrect postscript color type %c (should be either m or c)",
559        spectrum);
560 #if 0
561   sprint_line (&graph_term_cmd,
562                "postscript %c %c %s %d  # Postscript",
563                kind, spectrum, char_to_q_char (font), pt_size);
564   set_line (&graph_output_file, file);
565 #endif
566 }
567 
568 /*
569  * Show a GNU Plotutils chart.
570  *
571  * In the Motif interface, ...
572  * The client parameter is the function (from plot.c) which will
573  * handle the plotting. We pass it to RedrawPlotutilsWindow() too.
574  */
575 void
graph_plot(void)576 graph_plot(void)
577 {
578 #ifdef	HAVE_LIBPLOT
579 	FILE	*fp = NULL;
580 	int	havepipe = 0;
581 
582 	if (Global->PlotGlobal->output_file) {
583 	    /* Treat stdout ("-") case */
584 	    if (strcmp(Global->PlotGlobal->output_file, "-") == 0)
585 		fp = stdout;
586 	    else if (Global->PlotGlobal->output_file[0] == '|') {
587 		/* FIX ME treat pipe */
588 		havepipe = 1;
589 	    } else {
590 		fp = fopen(Global->PlotGlobal->output_file, "w");
591 	    }
592 	}
593 
594 	if (fp == NULL) {
595 		io_error_msg("Cannot open file '%s'", Global->PlotGlobal->output_file);
596 		return;
597 	}
598 
599 	PuPlot(Global->PlotGlobal->graph_type, Global->PlotGlobal->device, fp);
600 
601 	if (havepipe) {
602 		/* FIX ME */
603 	} else if (fp == stdout && using_curses) {
604 		;	/* Don't do a thing, curses would die. */
605 	} else {
606 		fclose(fp);
607 	}
608 #endif
609 }
610 
611 void
plotutils_set_device(enum graph_device d)612 plotutils_set_device(enum graph_device d)
613 {
614 	Global->PlotGlobal->device = d;
615 }
616 
617 void
plotutils_metaplot(void)618 plotutils_metaplot(void)
619 {
620 	Global->PlotGlobal->device = GRAPH_METAFILE;
621 }
622 
623 void
plotutils_illustrator(void)624 plotutils_illustrator(void)
625 {
626 	Global->PlotGlobal->device = GRAPH_ILLUSTRATOR;
627 }
628 
629 void
plotutils_fig(void)630 plotutils_fig(void)
631 {
632 	Global->PlotGlobal->device = GRAPH_FIG;
633 }
634 
635 void
plotutils_x_mono(void)636 plotutils_x_mono(void)
637 {
638 	Global->PlotGlobal->device = GRAPH_X_MONO;
639 }
640 
641 void
plotutils_x_color(void)642 plotutils_x_color(void)
643 {
644 	Global->PlotGlobal->device = GRAPH_X;
645 }
646 
647 void
plotutils_png(void)648 plotutils_png(void)
649 {
650 	Global->PlotGlobal->device = GRAPH_PNG;
651 }
652 
653 void
plotutils_gif(void)654 plotutils_gif(void)
655 {
656 	Global->PlotGlobal->device = GRAPH_GIF;
657 }
658 
659 void
plotutils_pcl(void)660 plotutils_pcl(void)
661 {
662 	Global->PlotGlobal->device = GRAPH_PCL;
663 }
664 
665 void
plotutils_hpgl(void)666 plotutils_hpgl(void)
667 {
668 	Global->PlotGlobal->device = GRAPH_HPGL;
669 }
670 
671 void
plotutils_tek(void)672 plotutils_tek(void)
673 {
674 	Global->PlotGlobal->device = GRAPH_TEK;
675 }
676 
677 void
plotutils_regis(void)678 plotutils_regis(void)
679 {
680 	Global->PlotGlobal->device = GRAPH_REGIS;
681 }
682 
683 void
plotutils_make_info(void)684 plotutils_make_info(void)
685 {
686 #ifdef	HAVE_LIBPLOT
687   struct info_buffer	*ib = find_or_make_info ("graphing-parameters");
688   enum graph_axis	axis;
689   int			x;
690 
691   clear_info (ib);
692 
693   print_info(ib, "");
694   switch (Global->PlotGlobal->graph_type) {
695 	case GRAPH_XY:
696 		print_info(ib, "Graph type is XY plot.");
697 		break;
698 	case GRAPH_BAR:
699 		print_info(ib, "Graph type is BAR chart.");
700 		break;
701 	case GRAPH_PIE:
702 		print_info(ib, "Graph type is PIE chart.");
703 		break;
704   }
705   print_info(ib, "");
706   print_info(ib,
707 	"Parameter		Value");
708   print_info(ib, "");
709   switch (Global->PlotGlobal->device) {
710   case GRAPH_TEK:
711     print_info(ib, "output type		%s", "Tektronix");
712     break;
713   case GRAPH_X:
714   case GRAPH_X_MONO:
715     print_info(ib, "output type		%s", "X window");
716     break;
717   case GRAPH_PNG:
718     print_info(ib, "output type		%s", "PNG");
719     break;
720   case GRAPH_GIF:
721     print_info(ib, "output type		%s", "GIF");
722     break;
723   case GRAPH_METAFILE:
724     print_info(ib, "output type		%s", "GNU metafile");
725     break;
726   case GRAPH_ILLUSTRATOR:
727     print_info(ib, "output type		%s", "Adobe Illustrator");
728     break;
729   case GRAPH_FIG:
730     print_info(ib, "output type		%s", "FIG");
731     break;
732   case GRAPH_PCL:
733     print_info(ib, "output type		%s", "PCL");
734     break;
735   case GRAPH_HPGL:
736     print_info(ib, "output type		%s", "HP GL");
737     break;
738   case GRAPH_POSTSCRIPT:
739     print_info(ib, "output type		%s", "PostScript");
740     break;
741   case GRAPH_REGIS:
742     print_info(ib, "output type         %s", "ReGIS");
743     break;
744   case GRAPH_NONE:
745   default:
746     print_info(ib, "output type		???");
747     break;
748   };
749 
750   if (Global->PlotGlobal->output_file)
751     print_info(ib,
752        "output file		%s",
753 	Global->PlotGlobal->output_file);
754 
755   for (axis = graph_x; axis <= graph_y; ++axis)
756     print_info(ib,
757        "%s-axis title		%s",
758        graph_axis_name[axis], Global->PlotGlobal->graph_axis_title[axis].buf);
759 
760   print_info(ib,
761        "logarithmic axes	%s",
762        (Global->PlotGlobal->graph_logness[graph_x]
763 	? (Global->PlotGlobal->graph_logness[graph_y] ? "x,y" : "x")
764 	: (Global->PlotGlobal->graph_logness[graph_y] ? "y" : "-neither-")));
765 
766   for (axis = graph_x; axis <= graph_y; ++axis) {
767 	print_info(ib,
768 		"%s-axis range		[%s..%s]",
769 	   graph_axis_name [axis],
770 	   Global->PlotGlobal->graph_rng_lo[axis].buf, Global->PlotGlobal->graph_rng_hi[axis].buf,
771 	   Global->PlotGlobal->graph_rng_hi[axis].buf, Global->PlotGlobal->graph_rng_hi[axis].buf);
772     }
773 
774   for (axis = graph_x; axis <= graph_y; ++axis) {
775       if (Global->PlotGlobal->graph_axis_labels[axis].lr != NON_ROW)
776 	print_info(ib,
777 	   	"%s-axis labels		%s",
778 	   graph_axis_name[axis],
779 	   range_name(&Global->PlotGlobal->graph_axis_labels[axis]));
780     }
781 
782     for (x = 0; x < NUM_DATASETS; ++x)
783       if (Global->PlotGlobal->graph_data [x].lr != NON_ROW)
784       {
785 	print_info (ib, "");
786 	print_info (ib,"Data Set %d%s%s",
787 		    x,
788 		    Global->PlotGlobal->graph_title[x].buf[0] ? " entitled " : "",
789 		    Global->PlotGlobal->graph_title[x].buf);
790 	print_info (ib,"  data for this set: %s",
791 		    range_name (&Global->PlotGlobal->graph_data[x]));
792 	print_info (ib,"  style for this set: %s",
793 		    (Global->PlotGlobal->style[x] == GRAPH_STYLE_DEFAULT) ? "default" :
794 		    (Global->PlotGlobal->style[x] == GRAPH_STYLE_LINES) ? "lines" :
795 		    (Global->PlotGlobal->style[x] == GRAPH_STYLE_MARKS) ? "marks" :
796 		    (Global->PlotGlobal->style[x] == GRAPH_STYLE_BOTH) ? "both" :
797 		    (Global->PlotGlobal->style[x] == GRAPH_STYLE_NONE) ? "none" : "???"
798 		);
799 	print_info (ib,"");
800       }
801 #endif
802 }
803 
804 void
plotutils_set_axis_labels(int axis_c,struct rng * rng)805 plotutils_set_axis_labels(int axis_c, struct rng * rng)
806 {
807   enum graph_axis axis = chr_to_axis (axis_c);
808   Global->PlotGlobal->graph_axis_labels [axis] = *rng;
809 }
810 
811 void
plotutils_set_filename(char * file)812 plotutils_set_filename(char *file)
813 {
814   if (Global->PlotGlobal->output_file)
815 	free(Global->PlotGlobal->output_file);
816   Global->PlotGlobal->output_file = strdup(file);
817 }
818 
plotutils_xy(void)819 void plotutils_xy(void)
820 {
821 	Global->PlotGlobal->graph_type = GRAPH_XY;
822 	io_info_msg("Graph type is now XY chart");
823 }
824 
plotutils_pie(void)825 void plotutils_pie(void)
826 {
827 	Global->PlotGlobal->graph_type = GRAPH_PIE;
828 	io_info_msg("Graph type is now PIE chart");
829 }
830 
plotutils_bar(void)831 void plotutils_bar(void)
832 {
833 	Global->PlotGlobal->graph_type = GRAPH_BAR;
834 	io_info_msg("Graph type is now BAR chart");
835 }
836 
plotutils_set_graph_type(enum graph_type gt)837 void plotutils_set_graph_type(enum graph_type gt)
838 {
839 	Global->PlotGlobal->graph_type = gt;
840 }
841