source: trunk/Jgraph/process.c @ 418

Last change on this file since 418 was 418, checked in by Nicholas Riley, 12 years ago

Jgraph 8.3 from http://www.cs.utk.edu/~plank/plank/jgraph/jgraph.tar.gz

File size: 23.3 KB
Line 
1/*
2 * $Source: /tmp_mnt/n/fs/grad1/jsp/src/jgraph/RCS/process.c,v $
3 * $Revision: 8.3 $
4 * $Date: 92/11/30 11:42:35 $
5 * $Author: jsp $
6 */
7
8#include <stdio.h>
9#include <math.h>
10
11#include "jgraph.h"
12
13#define ABS(a) ((a > 0.0) ? (a) : (-a))
14#define MAX(a, b) ((a > b) ? (a) : (b))
15#define MIN(a, b) ((a < b) ? (a) : (b))
16#define AXIS_CHAR(a) ((a->is_x) ? 'x' : 'y')
17#define HASH_DIR(a) ((a->hash_scale > 0.0) ? 1 : -1)
18
19static double Pi;
20
21process_title(g)
22Graph g;
23{
24
25  float ytitleloc;
26
27  if (g->title->x == FSIG) g->title->x = g->x_axis->psize / 2.0;
28    else g->title->x = ctop(g->title->x, g->x_axis);
29  if (g->title->y != FSIG) g->title->y = ctop(g->title->y, g->y_axis);
30  else {
31    ytitleloc = 0.0;
32    if (g->x_axis->draw_axis_label && g->x_axis->label->label != CNULL) 
33      ytitleloc = MIN(ytitleloc, g->x_axis->label->ymin); 
34    if (g->x_axis->draw_hash_labels)
35      ytitleloc = MIN(ytitleloc, g->x_axis->hl->ymin);
36    if (g->x_axis->draw_hash_marks)
37      ytitleloc = MIN(ytitleloc, g->x_axis->draw_hash_marks_at - HASH_SIZE);
38    if (g->legend->type == 'u')
39      ytitleloc = MIN(ytitleloc, g->legend->l->ymin);
40   
41    g->title->y = ytitleloc - 10.0;
42  }
43  process_label(g->title, g, 0);
44}
45
46process_legend(g)
47Graph g;
48{
49  Legend l;
50  int anything;
51  float height, hdist, y, x, width, maxmark, maxmarky;
52  Curve c;
53  char *s;
54
55  l = g->legend;
56  if (l->type == 'n') return;
57  if (l->l->linesep == FSIG) l->l->linesep = l->l->fontsize;
58  l->anylines = 0;
59  maxmark = 0.0;
60  maxmarky = 0.0;
61  anything = 0;
62  for (c = first(g->curves); c != nil(g->curves); c = next(c)) {
63    if (c->l->label != CNULL) {
64      anything = 1;
65      if (c->marktype == 'l') {
66         maxmark = MAX(maxmark, c->lmark->xmax - c->lmark->xmin); 
67         maxmarky = MAX(maxmarky, c->lmark->ymax - c->lmark->ymin); 
68      } else if (c->marktype != 'n') {
69        maxmark = MAX(maxmark, ABS(c->marksize[0]));
70        maxmarky = MAX(maxmarky, ABS(c->marksize[1]));
71      }
72      if (c->linetype != '0') l->anylines = 1;
73    }
74  }
75  if (l->linelength == FSIG)
76    l->linelength = (l->anylines) ? (MAX(maxmark + 6.0, 24.0)) : 0.0;
77    else l->linelength = disttop(l->linelength, g->x_axis);
78  if (l->midspace == FSIG)
79    l->midspace = (l->anylines) ? 4.0 : (maxmark / 2.0) + 4.0;
80    else l->midspace = disttop(l->midspace, g->x_axis);
81  if (l->linebreak == FSIG)
82    l->linebreak = MAX(l->l->linesep * FCPI / FPPI, maxmarky);
83    else l->linebreak = disttop(l->linebreak, g->y_axis);
84
85  if (l->type == 'c') {
86    for (c = first(g->curves); c != nil(g->curves); c = next(c)) {
87      if (c->l->label != CNULL) process_label(c->l, g, 1);
88    }
89    return;
90  }
91
92  if (!anything) {
93    l->anylines = -1; 
94    return;
95  }
96
97  width = 0.0;
98  height = -l->linebreak;
99  for (c = first(g->curves); c != nil(g->curves); c = next(c)) {
100    if (c->l->label != CNULL) {
101      s = c->l->label;
102      copy_label(c->l, l->l);
103      c->l->x = 0.0;
104      c->l->y = 0.0;
105      c->l->rotate = 0.0;
106      c->l->hj = 'l';
107      c->l->vj = 'b';
108      c->l->label = s;
109      process_label(c->l, g, 0);
110      height += c->l->ymax + l->linebreak;
111      width = MAX(width, c->l->xmax);
112    }
113  }
114  hdist = (l->anylines) ? l->midspace + l->linelength : l->midspace;
115  width += hdist;
116
117  if (l->l->x == FSIG) {
118    if (l->l->hj == 'c') {
119      l->l->x = g->x_axis->psize / 2;
120    } else if (l->l->hj == 'l') {
121      if (l->l->vj == 'c') {
122        l->l->x = g->x_axis->psize;
123        if (g->y_axis->draw_axis_label) 
124          l->l->x = MAX(l->l->x, g->y_axis->label->xmax);
125        if (g->y_axis->draw_hash_labels) 
126          l->l->x = MAX(l->l->x, g->y_axis->hl->xmax);
127        if (g->y_axis->draw_hash_marks) {
128          l->l->x = MAX(l->l->x, g->y_axis->draw_hash_marks_at);
129          l->l->x = MAX(l->l->x, g->y_axis->draw_hash_marks_at + 
130                                 HASH_DIR(g->y_axis) * HASH_SIZE);
131        }
132        l->l->x += 15.0;
133      } else {
134        l->l->x = 0.0;
135      }
136    } else {
137      if (l->l->vj == 'c') {
138        l->l->x = 0.0;
139        if (g->y_axis->draw_axis_label) 
140          l->l->x = MIN(l->l->x, g->y_axis->label->xmin);
141        if (g->y_axis->draw_hash_labels) 
142          l->l->x = MIN(l->l->x, g->y_axis->hl->xmin);
143        if (g->y_axis->draw_hash_marks) {
144          l->l->x = MIN(l->l->x, g->y_axis->draw_hash_marks_at);
145          l->l->x = MIN(l->l->x, g->y_axis->draw_hash_marks_at + 
146                                 HASH_DIR(g->y_axis) * HASH_SIZE);
147        }
148        l->l->x = l->l->x - 15.0;
149      } else {
150        l->l->x = g->x_axis->psize;
151      }
152    }
153  } else {
154    l->l->x = ctop(l->l->x, g->x_axis);
155  }
156  if (l->l->y == FSIG) {
157    if (l->l->vj == 'c') {
158      l->l->y = g->y_axis->psize / 2.0;
159    } else if (l->l->vj == 'b') {
160      l->l->y = g->y_axis->psize;
161      if (g->x_axis->draw_axis_label) 
162        l->l->y = MAX(l->l->y, g->x_axis->label->ymax);
163      if (g->x_axis->draw_hash_labels) 
164        l->l->y = MAX(l->l->y, g->x_axis->hl->ymax);
165      if (g->x_axis->draw_hash_marks) {
166        l->l->y = MAX(l->l->y, g->x_axis->draw_hash_marks_at);
167        l->l->y = MAX(l->l->y, g->x_axis->draw_hash_marks_at + 
168                               HASH_DIR(g->x_axis) * HASH_SIZE);
169      }
170      l->l->y += 15.0;
171    } else {
172      l->l->y = 0.0;
173      if (g->x_axis->draw_axis_label) 
174        l->l->y = MIN(l->l->y, g->x_axis->label->ymin);
175      if (g->x_axis->draw_hash_labels) 
176        l->l->y = MIN(l->l->y, g->x_axis->hl->ymin);
177      if (g->x_axis->draw_hash_marks) {
178        l->l->y = MIN(l->l->y, g->x_axis->draw_hash_marks_at);
179        l->l->y = MIN(l->l->y, g->x_axis->draw_hash_marks_at + 
180                               HASH_DIR(g->x_axis) * HASH_SIZE);
181      }
182      l->l->y -= 15.0;
183    }
184  } else {
185    l->l->y = ctop(l->l->y, g->y_axis);
186  }
187
188  if (l->l->hj == 'l') x = 0.0;
189  else if (l->l->hj == 'c') x = - width/2.0;
190  else x = -width;
191
192  if (l->l->vj == 't') y = 0.0;
193  else if (l->l->vj == 'c') y = height / 2.0;
194  else y = height;
195
196  for (c = first(g->curves); c != nil(g->curves); c = next(c)) {
197    if (c->l->label != CNULL) {
198      c->l->x = hdist + x;
199      c->l->y = y;
200      c->l->vj = 't';
201      c->l->hj = 'l';
202      c->l->rotate = 0.0;
203      process_label(c->l, g, 0);
204      y = c->l->ymin - l->linebreak;
205    }
206  }
207 
208  process_label_max_n_mins(l->l, width, height);
209}
210
211float find_reasonable_hash_interval(a) 
212Axis a;
213{
214  float s, d;
215
216  if (a->is_lg) return 0.0;
217  s = a->max - a->min;
218  d = 1.0;
219  if (s > 5.0) {
220    while(1) {
221      if (s / d < 6.0) return d;
222      d *= 2.0;
223      if (s / d < 6.0) return d;
224      d *= 2.5;
225      if (s / d < 6.0) return d;
226      d *= 2.0;
227    }
228  } else {
229    while(1) {
230      if (s / d > 2.0) return d;
231      d /= 2.0;
232      if (s / d > 2.0) return d;
233      d /= 2.5;
234      if (s / d > 2.0) return d;
235      d /= 2.0;
236    }
237  }
238}
239
240float find_reasonable_hash_start(a)
241Axis a;
242{
243  int i;
244 
245  if (a->is_lg) return 0.0;
246  if (a->max > 0.0 && a->min < 0.0) return 0.0;
247  i = ((int) (a->min / a->hash_interval));
248  return ((float) i) * a->hash_interval;
249}
250
251int find_reasonable_precision(a)
252Axis a;
253{
254  int i, b, b2, done;
255  float x, x2, tolerance;
256
257  if (a->hash_format == 'g' || a->hash_format == 'G') return 6;
258  if (a->hash_format == 'e' || a->hash_format == 'E') return 0;
259  if (a->is_lg) return 0;
260
261  tolerance = 0.000001;
262  b = 0;
263  x = a->hash_interval;
264
265  done = 0;
266  while(b < 6 && !done) {
267    i = (int) (x + 0.4);
268    x2 = i;
269    if (x2 - x < tolerance && x - x2 < tolerance) done = 1;
270    else {
271      b++;
272      x *= 10.0;
273      tolerance *= 10.0;
274    }
275  }
276
277  tolerance = 0.000001;
278  b2 = 0;
279  x = a->hash_start;
280
281  done = 0;
282  while(b2 < 6 && !done) {
283    i = (int) (x + 0.4);
284    x2 = i;
285    if (x2 - x < tolerance && x - x2 < tolerance) done = 1;
286    else {
287      b2++;
288      x *= 10.0;
289      tolerance *= 10.0;
290    }
291  }
292  return MAX(b, b2);
293}
294
295int find_reasonable_minor_hashes(a)
296Axis a;
297{
298  float d; 
299  int i;
300 
301  if (a->is_lg) {
302    d = a->log_base;
303    while(d > 10.0) d /= 10.0;
304    while(d <= 1.0) d *= 10.0;
305    i = (int) d;
306    return MAX((i - 2), 0);
307  } else {
308    d = a->hash_interval;
309    if (d == 0.0) return 0;
310    while(d > 10.0) d /= 10.0;
311    while(d <= 1.0) d *= 10.0;
312    i = (int) d;
313    if (((float) i) != d) return 0;
314    return i-1;
315  }
316}
317
318process_axis1(a, g)
319Axis a;
320Graph g;
321{
322  float tmp;
323  int i;
324
325  if (a->min == FSIG) {
326    if (a->pmin == FSIG) {
327      error_header();
328      fprintf(stderr, 
329              "Graph %d: %c axis has no minimum, and cannot derive one\n",
330              g->num, AXIS_CHAR(a));
331      fprintf(stderr, "  Use %caxis min\n", AXIS_CHAR(a));
332      exit(1);
333    } else if (a->pmin <= 0.0 && a->is_lg) {
334      error_header();
335      fprintf(stderr, "Trying to derive %c axis\n", AXIS_CHAR(a));
336      fprintf(stderr, 
337        "        Minimum value %f will be -infinity with log axes\n", a->pmin);
338      exit(1);
339    } else a->min = a->pmin;
340  }
341  if (a->max == FSIG) {
342    if (a->pmax == FSIG) {
343      error_header();
344      fprintf(stderr, 
345              "Graph %d: %c axis has no maximum, and cannot derive one\n",
346              g->num, AXIS_CHAR(a));
347      fprintf(stderr, "  Use %caxis max\n", AXIS_CHAR(a));
348      exit(1);
349    } else if (a->pmax <= 0.0 && a->is_lg) {
350      error_header();
351      fprintf(stderr, "Trying to derive %c axis\n", AXIS_CHAR(a));
352      fprintf(stderr, 
353        "        Maximum value %f will be -infinity with log axes\n", a->pmax);
354      exit(1);
355    } else a->max = a->pmax;
356  }
357  if (a->max < a->min) {
358    tmp = a->max;  a->max = a->min;  a->min = tmp;
359  } else if (a->max == a->min) {
360    if (!a->is_lg) a->min -= 1;
361    a->max += 1;
362  }
363  a->psize = intop(a->size);
364  if (a->is_lg) {
365    if (a->min <= 0.0) {
366      error_header();
367      fprintf(stderr, 
368        "Graph %d, %c axis: Min value = %f.  This is -infinity with logrhythmic axes\n", 
369        g->num, (a->is_x) ? 'x' : 'y', a->min);
370      exit(1);
371    }
372    a->logfactor = log(a->log_base);
373    a->logmin = log(a->min) / a->logfactor;
374    a->factor = a->psize / (log(a->max) / a->logfactor - a->logmin);
375  } else {
376    a->factor = a->psize / (a->max - a->min);
377  }
378  if (a->gr_graytype == '0') {
379    a->gr_graytype = a->graytype;
380    for (i = 0; i < 3; i++) a->gr_gray[i] = a->gray[i];
381  }
382  if (a->mgr_graytype == '0') {
383    a->mgr_graytype = a->gr_graytype;
384    for (i = 0; i < 3; i++) a->mgr_gray[i] = a->gr_gray[i];
385  }
386}
387
388process_axis2(a, g)
389Axis a;
390Graph g;
391{
392  float t1, t2, t3, minor_hashes, hloc, tmp;
393  float ymin, ymax, xmin, xmax;
394  int prec, i1;
395  Hash h;
396  String s;
397  Axis other;
398
399  other = (a->is_x) ? g->y_axis : g->x_axis;
400  if (a->draw_at == FSIG) 
401    a->draw_at = (HASH_DIR(a) == -1) ? 0.0 : other->psize;
402  else a->draw_at = ctop(a->draw_at, other);
403
404  if (a->hash_interval < 0.0) {
405    a->hash_interval = find_reasonable_hash_interval(a);
406    if (!a->start_given)
407      a->hash_start = find_reasonable_hash_start(a);
408  } else if (!a->start_given) a->hash_start = a->min;
409  if (a->minor_hashes < 0) {
410    a->minor_hashes = find_reasonable_minor_hashes(a);
411  }
412  if (a->precision < 0) a->precision = find_reasonable_precision(a);
413
414  for (h = first(a->hash_lines) ; h != nil(a->hash_lines); h = next(h)) {
415    h->loc = ctop(h->loc, a);
416  }
417 
418  for (s = first(a->hash_labels); s != nil(a->hash_labels); s = next(s)) {
419    s->s->x = ctop(s->s->x, a);
420    s->s->y = ctop(s->s->y, a);
421  }
422
423  if (((a->hash_interval != 0.0 && !a->is_lg) || a->is_lg) && a->auto_hash_marks) {
424    if (a->is_lg) {
425      for (t1 = 1.0; t1 > a->min; t1 /= a->log_base) ;
426      t2 = t1 * a->log_base - t1;
427    } else {
428      for (t1 = a->hash_start; t1 > a->min; t1 -= a->hash_interval) ;
429      t2 = a->hash_interval;
430    }
431    while (t1 <= a->max) {
432      hloc = ctop(t1, a);
433      if (hloc > -.05 && hloc < a->psize + .05) {
434        h = (Hash) get_node(a->hash_lines);
435        h->loc = hloc;
436        h->size = HASH_SIZE;
437        h->major = 1;
438        insert(h, a->hash_lines);
439        if (a->auto_hash_labels) {
440          s = (String) get_node (a->hash_labels);
441          s->s = new_label();
442          s->s->x = hloc;
443          s->s->y = hloc;
444          s->s->label = (char *) malloc (80);
445          if (a->precision >= 0) {
446            prec = a->precision;
447          } else {
448            if (ABS(t1) >= 1.0 || t1 == 0.0) prec = 0;
449            else {
450              tmp = ABS(t1);
451              prec = -1;
452              while(tmp < 1.0) {tmp *= 10.0; prec++;}
453            }
454          }
455          switch(a->hash_format) {
456            case 'G': sprintf(s->s->label, "%.*G", prec, t1); break;
457            case 'g': sprintf(s->s->label, "%.*g", prec, t1); break;
458            case 'E': sprintf(s->s->label, "%.*E", prec, t1); break;
459            case 'e': sprintf(s->s->label, "%.*e", prec, t1); break;
460            case 'f': sprintf(s->s->label, "%.*f", prec, t1); break;
461            default: fprintf(stderr, "Internal jgraph error: hl_st\n");
462                     exit(1);
463          }
464          insert(s, a->hash_labels);
465        }
466      }
467      minor_hashes = t2 / ((float) (a->minor_hashes + 1));
468      t3 = t1;
469      for (i1 = 1; i1 <= a->minor_hashes; i1++) {
470        t3 += minor_hashes;
471        hloc = ctop(t3, a);
472        if (hloc > -.05 && hloc < a->psize + .05) {
473          h = (Hash) get_node(a->hash_lines);
474          h->loc = hloc;
475          h->size = MHASH_SIZE;
476          h->major = 0;
477          insert(h, a->hash_lines);
478        }
479      }
480      if (a->is_lg) {
481        t1 *= a->log_base;
482        t2 = t1 * a->log_base - t1;
483      } else t1 += t2;
484    }
485  }
486
487  if (a->draw_hash_marks_at == FSIG)
488    a->draw_hash_marks_at = a->draw_at;
489  else a->draw_hash_marks_at = ctop(a->draw_hash_marks_at, other);
490  if (a->draw_hash_labels_at == FSIG)
491    a->draw_hash_labels_at = a->draw_hash_marks_at +
492      a->hash_scale * HASH_SIZE + HASH_DIR(a) * 3.0;
493  else a->draw_hash_labels_at = ctop(a->draw_hash_labels_at, other);
494
495  if (a->is_x) {
496    a->hl->y = a->draw_hash_labels_at; 
497    if (a->hl->hj == '0')
498      a->hl->hj = 'c';
499    if (a->hl->vj == '0')
500      a->hl->vj = (HASH_DIR(a) == -1) ? 't' : 'b';
501  } else {
502    a->hl->x = a->draw_hash_labels_at;
503    if (a->hl->vj == '0') a->hl->vj = 'c';
504    if (a->hl->hj == '0')
505      a->hl->hj = (HASH_DIR(a) == -1) ? 'r' : 'l';
506  }
507
508  ymin = (a->is_x) ? a->hl->y : 0;
509  ymax = (a->is_x) ? a->hl->y : a->psize;
510  xmin = (!a->is_x) ? a->hl->x : 0;
511  xmax = (!a->is_x) ? a->hl->x : a->psize;
512
513  for (s = first(a->hash_labels); s != nil(a->hash_labels); s = next(s)) {
514    if (a->is_x) a->hl->x = s->s->x; else a->hl->y = s->s->y;
515    a->hl->label = s->s->label;
516    process_label(a->hl, g, 0);
517    xmin = MIN(a->hl->xmin, xmin);
518    ymin = MIN(a->hl->ymin, ymin);
519    xmax = MAX(a->hl->xmax, xmax);
520    ymax = MAX(a->hl->ymax, ymax);
521  }
522  a->hl->xmin = xmin;
523  a->hl->ymin = ymin;
524  a->hl->xmax = xmax;
525  a->hl->ymax = ymax;
526
527  /* HERE -- now either test or continue */
528
529  if (a->is_x) {
530    if (a->label->x == FSIG) 
531      a->label->x = a->psize / 2.0;
532      else a->label->x = ctop(a->label->x, g->x_axis);
533    if (a->label->y == FSIG) {
534      ymin = 0.0;
535      ymax = other->psize;
536      if (a->draw_hash_labels) {
537        ymin = MIN(ymin, a->hl->ymin); 
538        ymax = MAX(ymax, a->hl->ymax); 
539      } 
540      if (a->draw_hash_marks) {
541        ymin = MIN(ymin, a->draw_hash_marks_at);
542        ymin = MIN(ymin, a->draw_hash_marks_at + a->hash_scale * HASH_SIZE);
543        ymax = MAX(ymax, a->draw_hash_marks_at);
544        ymax = MAX(ymax, a->draw_hash_marks_at + a->hash_scale * HASH_SIZE);
545      } 
546      a->label->y = (HASH_DIR(a) == -1) ? ymin - 8.0 : ymax + 8.0 ;
547    } else a->label->y = ctop(a->label->y, g->y_axis);
548    if (a->label->hj == '0') a->label->hj = 'c';
549    if (a->label->vj == '0') a->label->vj = (HASH_DIR(a) == -1) ? 't' : 'b' ;
550    if (a->label->rotate == FSIG) a->label->rotate = 0.0;
551  } else {
552    if (a->label->y == FSIG) 
553      a->label->y = a->psize / 2.0;
554      else a->label->y = ctop(a->label->y, g->y_axis);
555    if (a->label->x == FSIG) {
556      xmin = 0.0;
557      xmax = other->psize;
558      if (a->draw_hash_labels) {
559        xmin = MIN(xmin, a->hl->xmin); 
560        xmax = MAX(xmax, a->hl->xmax); 
561      } 
562      if (a->draw_hash_marks) {
563        xmin = MIN(xmin, a->draw_hash_marks_at);
564        xmin = MIN(xmin, a->draw_hash_marks_at + a->hash_scale * HASH_SIZE);
565        xmax = MAX(xmax, a->draw_hash_marks_at);
566        xmax = MAX(xmax, a->draw_hash_marks_at + a->hash_scale * HASH_SIZE);
567      } 
568      a->label->x = (HASH_DIR(a) == -1) ? xmin - 8.0 : xmax + 8.0 ;
569    } else a->label->x = ctop(a->label->x, g->x_axis);
570    if (a->label->hj == '0') a->label->hj = 'c';
571    if (a->label->vj == '0') a->label->vj = 'b';
572    if (a->label->rotate == FSIG) 
573      a->label->rotate = (HASH_DIR(a) == -1) ? 90.0 : -90.0;
574  }
575  process_label (a->label, g, 0);
576}
577
578process_label(l, g, adjust)
579Label l;
580Graph g;
581int adjust;
582{
583  float len, height;
584  int f, i;
585  float fnl, tmp;
586  char *s;
587
588  if (l->label == CNULL) return;
589
590  if (adjust) {
591    l->x = ctop(l->x, g->x_axis);
592    l->y = ctop(l->y, g->y_axis);
593  }
594  if (l->linesep == FSIG) l->linesep = l->fontsize;
595
596  l->nlines = 0;
597  for (i = 0; l->label[i] != '\0'; i++) {
598    if (l->label[i] == '\n') {
599      l->label[i] = '\0';
600      l->nlines++;
601    }
602  }
603  fnl = (float) l->nlines;
604
605  len = 0.0;
606  s = l->label;
607  for (i = 0; i <= l->nlines; i++) {
608    tmp = l->fontsize * FCPI / FPPI * strlen(s) * 0.8;
609    len = MAX(len, tmp);
610    if (i != l->nlines) {
611      f = strlen(s);
612      s[f] = '\n';
613      s = &(s[f+1]);
614    }
615  }
616  height = (l->fontsize * (fnl+1) + l->linesep * fnl) * FCPI / FPPI;
617  process_label_max_n_mins(l, len, height);
618}
619   
620process_label_max_n_mins(l, len, height)
621Label l;
622float len;
623float height;
624{
625  float xlen, ylen, xheight, yheight;
626  float x, y;
627
628  xlen = len * cos(l->rotate * Pi / 180.00);
629  ylen = height * cos((l->rotate + 90.0) * Pi / 180.00);
630  xheight = len * sin(l->rotate * Pi / 180.00);
631  yheight = height * sin((l->rotate + 90.0) * Pi / 180.00);
632 
633  x = l->x;
634  y = l->y;
635
636  if (l->hj == 'c') {
637    x -= xlen / 2.0;
638    y -= xheight / 2.0;
639  } else if (l->hj == 'r') {
640    x -= xlen;
641    y -= xheight;
642  }
643  if (l->vj == 'c') {
644    x -= ylen / 2.0;
645    y -= yheight / 2.0;
646  } else if (l->vj == 't') {
647    x -= ylen;
648    y -= yheight;
649  }
650
651  l->xmin = MIN(x, x + xlen);
652  l->xmin = MIN(l->xmin, x + xlen + ylen);
653  l->xmin = MIN(l->xmin, x + ylen);
654
655  l->ymin = MIN(y, y + xheight);
656  l->ymin = MIN(l->ymin, y + yheight);
657  l->ymin = MIN(l->ymin, y + xheight + yheight);
658
659  l->xmax = MAX(x, x + xlen);
660  l->xmax = MAX(l->xmax, x + xlen + ylen);
661  l->xmax = MAX(l->xmax, x + ylen);
662
663  l->ymax = MAX(y, y + xheight);
664  l->ymax = MAX(l->ymax, y + yheight);
665  l->ymax = MAX(l->ymax, y + xheight + yheight);
666
667}
668
669process_strings(g)
670Graph g;
671{
672  String s;
673
674  for(s = first(g->strings); s != nil(g->strings); s = next(s)) {
675    process_label(s->s, g, 1);
676  }
677}
678
679process_curve(c, g)
680Curve c;
681Graph g;
682{
683  if (c->bezier && (c->npts < 4 || (c->npts % 3 != 1))) {
684    error_header();
685    fprintf(stderr, "  Graph %d Curve %d:\n", g->num, c->num);
686    fprintf(stderr, "  Curve has %d points\n", c->npts);
687    fprintf(stderr, "  Bezier must have 3n + 1 points (n > 0)\n");
688    exit(1);
689  }
690  c->marksize[0] = (c->marksize[0] == FSIG) ? 
691                   4.0 : disttop(c->marksize[0], g->x_axis);
692  c->marksize[1] = (c->marksize[1] == FSIG) ? 
693                   4.0 : disttop(c->marksize[1], g->y_axis);
694  if (c->marktype == 'o') c->marksize[1] = c->marksize[0];
695  c->asize[0] = (c->asize[0] == FSIG) ? 
696                   6.0 : disttop(c->asize[0], g->x_axis);
697  c->asize[1] = (c->asize[1] == FSIG) ? 
698                   2.0 : disttop(c->asize[1], g->y_axis) / 2.0;
699  c->lmark->x = disttop(c->lmark->x, g->x_axis);
700  c->lmark->y = disttop(c->lmark->y, g->y_axis);
701  process_label(c->lmark, g, 0);
702  if (c->parg == FSIG) c->parg = 0.0;
703  if (c->aparg == FSIG) c->aparg = 0.0;
704  if (c->pparg == FSIG) c->pparg = 0.0;
705}
706
707process_curves(g)
708Graph g;
709{
710  Curve c;
711  for(c = first(g->curves); c != nil(g->curves); c = next(c)) {
712    process_curve(c, g);
713  }
714}
715 
716process_extrema(g)  /* This finds all the minval/maxvals for bbox calc */
717Graph g;
718{
719  Curve c;
720  String s;
721  Axis xa, ya;
722
723  xa = g->x_axis;
724  ya = g->y_axis;
725
726  g->xminval = 0.0;
727  g->yminval = 0.0;
728  g->xmaxval = xa->psize;
729  g->ymaxval = ya->psize;
730 
731  if (xa->draw_axis_label) process_label_extrema(xa->label, g);
732  if (ya->draw_axis_label) process_label_extrema(ya->label, g);
733  if (xa->draw_hash_labels) process_label_extrema(xa->hl, g);
734  if (ya->draw_hash_labels) process_label_extrema(ya->hl, g);
735
736  if (xa->draw_hash_marks) {
737      g->yminval = MIN(g->yminval, xa->draw_hash_marks_at);
738      g->yminval = MIN(g->yminval, 
739                       xa->draw_hash_marks_at + HASH_DIR(xa) * HASH_SIZE);
740      g->ymaxval = MAX(g->ymaxval, xa->draw_hash_marks_at);
741      g->ymaxval = MAX(g->ymaxval, 
742                       xa->draw_hash_marks_at + HASH_DIR(xa) * HASH_SIZE);
743  }
744  if (ya->draw_hash_marks) {
745      g->xminval = MIN(g->xminval, ya->draw_hash_marks_at);
746      g->xminval = MIN(g->xminval, 
747                       ya->draw_hash_marks_at + HASH_DIR(ya) * HASH_SIZE);
748      g->xmaxval = MAX(g->xmaxval, ya->draw_hash_marks_at);
749      g->xmaxval = MAX(g->xmaxval, 
750                       ya->draw_hash_marks_at + HASH_DIR(ya) * HASH_SIZE);
751  }
752  process_label_extrema(g->title, g); 
753
754  if (g->legend->type == 'c') {
755    for (c = first(g->curves); c != nil(g->curves); c = next(c)) {
756      process_label_extrema(c->l, g);
757    }
758  } else if (g->legend->type == 'u' && g->legend->anylines >= 0) {
759    process_label_extrema(g->legend->l, g);
760  }
761  for(s = first(g->strings); s != nil(g->strings); s = next(s)) {
762    process_label_extrema(s->s, g);
763  }
764}
765
766process_label_extrema(l, g)
767Label l;
768Graph g;
769{
770  if (l->label == CNULL) return;
771  g->yminval = MIN(g->yminval, l->ymin);
772  g->ymaxval = MAX(g->ymaxval, l->ymax);
773  g->xminval = MIN(g->xminval, l->xmin);
774  g->xmaxval = MAX(g->xmaxval, l->xmax);
775}
776
777process_graph(g)
778Graph g;
779{
780  g->x_translate = intop(g->x_translate);
781  g->y_translate = intop(g->y_translate);
782  process_axis1(g->x_axis, g);
783  process_axis1(g->y_axis, g);
784  process_axis2(g->x_axis, g);
785  process_axis2(g->y_axis, g);
786  process_curves(g);
787  process_legend(g);
788  process_strings(g);
789  process_title(g);
790  process_extrema(g);
791}
792
793process_graphs(gs)
794Graphs gs;
795{
796  Graphs the_g;
797  Graph g;
798  float diff, max_y, min_y, max_x, min_x;
799  int do_bb, i;
800
801  Pi = acos(-1.0);
802  for (the_g = first(gs); the_g != nil(gs); the_g = next(the_g)) {
803    for (g = first(the_g->g); g != nil(the_g->g); g = next(g)) process_graph(g);
804    max_x = 0.0;
805    min_x = 0.0;
806    max_y = 0.0;
807    min_y = 0.0;
808    for (g = first(the_g->g); g != nil(the_g->g); g = next(g)) {
809      max_y = MAX(max_y, g->y_translate + g->ymaxval);
810      min_y = MIN(min_y, g->y_translate + g->yminval);
811      max_x = MAX(max_x, g->x_translate + g->xmaxval);
812      min_x = MIN(min_x, g->x_translate + g->xminval);
813    }
814
815    if (the_g->height >= 0.00) {
816      the_g->height *= FCPI;
817      if (the_g->height > max_y - min_y) {
818        diff = (the_g->height - max_y + min_y) / 2.0;
819        max_y += diff;
820        min_y -= diff;
821      } else {
822        the_g->height = max_y - min_y;
823      }
824    } else {
825      the_g->height = max_y - min_y;
826    }
827    if (the_g->width >= 0.00) {
828      the_g->width *= FCPI;
829      if (the_g->width > max_x - min_x) {
830        diff = (the_g->width - max_x + min_x) / 2.0;
831        max_x += diff;
832        min_x -= diff;
833      } else {
834        the_g->width = max_x - min_x;
835      }
836    } else {
837      the_g->width = max_x - min_x;
838    }
839
840    do_bb = 1;
841    for (i = 0; i < 4; i++) do_bb = (do_bb && the_g->bb[i] == ISIG);
842    if (do_bb) {
843      the_g->bb[0] = (int) (min_x - 1.0);
844      the_g->bb[1] = (int) (min_y - 1.0);
845      the_g->bb[2] = (int) (max_x + 1.0);
846      the_g->bb[3] = (int) (max_y + 1.0);
847    } 
848  }
849}
Note: See TracBrowser for help on using the repository browser.