source: trunk/Jgraph/process.c@ 419

Last change on this file since 419 was 418, checked in by Nicholas Riley, 16 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.