2 * Grace - GRaphing, Advanced Computation and Exploration of data
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7 * Copyright (c) 1996-2004 Grace Development Team
9 * Maintained by Evgeny Stambulchik
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 * Draw axis bars, axis labels, ticks and tick labels
40 #include "core_utils.h"
44 static void drawgrid(Canvas
*canvas
, Quark
*q
)
53 WPoint wp_grid_start
, wp_grid_stop
;
54 VPoint vp_grid_start
, vp_grid_stop
;
56 double phi_start
, phi_stop
, rho
;
57 double wc_start
, wc_stop
; /* world coordinates */
58 int ittype_loop
, itick
;
65 gr
= get_parent_graph(q
);
67 setclipping(canvas
, TRUE
);
69 /* TODO: add Pen to ticks and remove the following */
70 setpattern(canvas
, 1);
72 graph_get_viewport(gr
, &v
);
73 graph_get_world(gr
, &w
);
75 /* graph center; for polar plots */
76 vpc
.x
= (v
.xv1
+ v
.xv2
)/2.0;
77 vpc
.y
= (v
.yv1
+ v
.yv2
)/2.0;
79 if (axis_is_x(q
)) { /* an X-axis */
82 wp_grid_start
.y
= w
.yg1
;
83 wp_grid_stop
.y
= w
.yg2
;
84 } else { /* a Y-axis */
87 wp_grid_start
.x
= w
.xg1
;
88 wp_grid_stop
.x
= w
.xg2
;
91 for (ittype_loop
= 0; ittype_loop
< 2; ittype_loop
++) {
92 if (ittype_loop
== 0) { /* minor ticks */
93 ttype
= TICK_TYPE_MINOR
;
95 } else { /* major ticks */
96 ttype
= TICK_TYPE_MAJOR
;
99 if (tprops
.gridflag
== 0) {
103 setcolor(canvas
, tprops
.color
);
104 setlinewidth(canvas
, tprops
.linew
);
105 setlinestyle(canvas
, tprops
.lines
);
107 for (itick
= 0; itick
< t
->nticks
; itick
++) {
108 if (t
->tloc
[itick
].type
!= ttype
) {
112 wtpos
= t
->tloc
[itick
].wtpos
;
114 if ((wtpos
< wc_start
) || (wtpos
> wc_stop
)) {
118 if (axis_is_x(q
)) { /* an X-axis */
119 wp_grid_start
.x
= wtpos
;
120 wp_grid_stop
.x
= wtpos
;
121 } else { /* a Y-axis */
122 wp_grid_start
.y
= wtpos
;
123 wp_grid_stop
.y
= wtpos
;
126 Wpoint2Vpoint(gr
, &wp_grid_start
, &vp_grid_start
);
127 Wpoint2Vpoint(gr
, &wp_grid_stop
, &vp_grid_stop
);
130 if (!axis_is_x(q
) && graph_get_type(gr
) == GRAPH_POLAR
) {
131 xy2polar(vp_grid_start
.x
- vpc
.x
, vp_grid_start
.y
- vpc
.y
,
133 xy2polar(vp_grid_stop
.x
- vpc
.x
, vp_grid_stop
.y
- vpc
.y
,
139 if (graph_is_xinvert(gr
) == TRUE
) {
140 fswap(&phi_start
, &phi_stop
);
142 if (phi_stop
< phi_start
) {
145 DrawArc(canvas
, &vp1
, &vp2
, 180.0/M_PI
*phi_start
,
146 180.0/M_PI
*(phi_stop
- phi_start
));
148 DrawLine(canvas
, &vp_grid_start
, &vp_grid_stop
);
154 static void drawaxis(Canvas
*canvas
, Quark
*q
)
161 double vbase1
, vbase2
, vbase1_start
, vbase1_stop
, vbase2_start
, vbase2_stop
;
162 double vbase_tlabel
, vbase_tlabel1
, vbase_tlabel2
;
163 double tsize
, tlsize
, wtpos
, vtpos
;
164 double tl_offset
, tl_trans
;
165 WPoint wp1_start
, wp1_stop
, wp2_start
, wp2_stop
;
166 VPoint vp1_start
, vp1_stop
, vp2_start
, vp2_stop
;
167 VPoint vp_tick1_start
, vp_tick1_stop
, vp_tick2_start
, vp_tick2_stop
;
168 VPoint vp_tlabel
, vp_label
, vp_label_offset1
, vp_label_offset2
;
169 VPoint vpc
, vp1
, vp2
;
170 double phi_start
, phi_stop
, rho
;
171 VVector ort_para
, ort_perp
;
172 double wc_start
, wc_stop
, wc_start_labels
, wc_stop_labels
; /* world
174 int ittype_loop
, itick
, itcur
;
176 char tlabel
[MAX_STRING_LENGTH
];
177 int tlabel1_just
, tlabel2_just
, label1_just
, label2_just
;
182 double (*coord_conv
) (const Quark
*gr
, double wx
);
184 t
= axis_get_data(q
);
189 setclipping(canvas
, FALSE
);
191 /* TODO: add Pen to ticks and remove the following */
192 setpattern(canvas
, 1);
194 gr
= get_parent_graph(q
);
196 graph_get_viewport(gr
, &v
);
197 graph_get_world(gr
, &w
);
199 /* graph center; for polar plots */
200 vpc
.x
= (v
.xv1
+ v
.xv2
)/2.0;
201 vpc
.y
= (v
.yv1
+ v
.yv2
)/2.0;
204 if (t
->zero
== FALSE
) {
210 if (axis_is_x(q
)) { /* an X-axis */
216 coord_conv
= xy_xconv
;
225 if (t
->zero
== TRUE
) {
226 if (w
.yg1
<= 0.0 && w
.yg2
>= 0.0) {
241 Wpoint2Vpoint(gr
, &wp1_start
, &vp1_start
);
242 Wpoint2Vpoint(gr
, &wp1_stop
, &vp1_stop
);
243 Wpoint2Vpoint(gr
, &wp2_start
, &vp2_start
);
244 Wpoint2Vpoint(gr
, &wp2_stop
, &vp2_stop
);
246 if (graph_is_yinvert(gr
) == TRUE
) {
247 vpswap(&vp1_start
, &vp2_start
);
248 vpswap(&vp1_stop
, &vp2_stop
);
251 /* TODO axis offset for polar plots */
252 if (graph_get_type(gr
) != GRAPH_POLAR
) {
253 vp1_start
.y
-= t
->offsx
;
254 vp1_stop
.y
-= t
->offsx
;
255 vp2_start
.y
+= t
->offsy
;
256 vp2_stop
.y
+= t
->offsy
;
259 vbase1
= vp1_start
.y
;
260 vbase2
= vp2_start
.y
;
262 tlabel1_just
= JUST_CENTER
|JUST_TOP
;
263 tlabel2_just
= JUST_CENTER
|JUST_BOTTOM
;
265 switch (t
->label_layout
) {
266 case LAYOUT_PARALLEL
:
269 case LAYOUT_PERPENDICULAR
:
273 errmsg("Internal error in drawaxis()");
276 } else { /* a Y-axis */
282 coord_conv
= xy_yconv
;
292 if (t
->zero
== TRUE
) {
293 if (w
.xg1
<= 0.0 && w
.xg2
>= 0.0) {
308 Wpoint2Vpoint(gr
, &wp1_start
, &vp1_start
);
309 Wpoint2Vpoint(gr
, &wp1_stop
, &vp1_stop
);
310 Wpoint2Vpoint(gr
, &wp2_start
, &vp2_start
);
311 Wpoint2Vpoint(gr
, &wp2_stop
, &vp2_stop
);
313 if (graph_is_xinvert(gr
) == TRUE
) {
314 vpswap(&vp1_start
, &vp2_start
);
315 vpswap(&vp1_stop
, &vp2_stop
);
318 if (graph_get_type(gr
) != GRAPH_POLAR
) {
319 vp1_start
.x
-= t
->offsx
;
320 vp1_stop
.x
-= t
->offsx
;
321 vp2_start
.x
+= t
->offsy
;
322 vp2_stop
.x
+= t
->offsy
;
325 vbase1
= vp1_start
.x
;
326 vbase2
= vp2_start
.x
;
328 tlabel1_just
= JUST_RIGHT
|JUST_MIDDLE
;
329 tlabel2_just
= JUST_LEFT
|JUST_MIDDLE
;
331 switch (t
->label_layout
) {
332 case LAYOUT_PARALLEL
:
335 case LAYOUT_PERPENDICULAR
:
339 errmsg("Internal error in drawaxis()");
344 /* Begin axis bar stuff */
346 setcolor(canvas
, t
->t_drawbarcolor
);
347 setlinewidth(canvas
, t
->t_drawbarlinew
);
348 setlinestyle(canvas
, t
->t_drawbarlines
);
349 if (t
->t_op
== PLACEMENT_NORMAL
|| t
->t_op
== PLACEMENT_BOTH
) {
350 if (axis_is_x(q
) && graph_get_type(gr
) == GRAPH_POLAR
) {
351 xy2polar(vp1_start
.x
- vpc
.x
, vp1_start
.y
- vpc
.y
,
353 xy2polar(vp1_stop
.x
- vpc
.x
, vp1_stop
.y
- vpc
.y
,
359 if (graph_is_xinvert(gr
) == TRUE
) {
360 fswap(&phi_start
, &phi_stop
);
362 if (phi_stop
< phi_start
) {
365 DrawArc(canvas
, &vp1
, &vp2
, 180.0/M_PI
*phi_start
,
366 180.0/M_PI
*(phi_stop
- phi_start
));
368 DrawLine(canvas
, &vp1_start
, &vp1_stop
);
371 if (t
->t_op
== PLACEMENT_OPPOSITE
|| t
->t_op
== PLACEMENT_BOTH
) {
372 if (axis_is_x(q
) && graph_get_type(gr
) == GRAPH_POLAR
) {
373 xy2polar(vp2_start
.x
- vpc
.x
, vp2_start
.y
- vpc
.y
,
375 xy2polar(vp2_stop
.x
- vpc
.x
, vp2_stop
.y
- vpc
.y
,
381 if (graph_is_xinvert(gr
) == TRUE
) {
382 fswap(&phi_start
, &phi_stop
);
384 if (phi_stop
< phi_start
) {
387 DrawArc(canvas
, &vp1
, &vp2
, 180.0/M_PI
*phi_start
,
388 180.0/M_PI
*(phi_stop
- phi_start
));
390 DrawLine(canvas
, &vp2_start
, &vp2_stop
);
394 /* End axis bar stuff*/
397 /* TODO ticks, labels and axis labels for polar plots */
398 if (graph_get_type(gr
) == GRAPH_POLAR
) {
402 activate_bbox(canvas
, BBOX_TYPE_TEMP
, TRUE
);
403 reset_bbox(canvas
, BBOX_TYPE_TEMP
);
405 /* Begin axis tick stuff */
407 for (ittype_loop
= 0; ittype_loop
< 2; ittype_loop
++) {
409 if (ittype_loop
== 0) { /* minor ticks */
410 ttype
= TICK_TYPE_MINOR
;
412 } else { /* major ticks */
413 ttype
= TICK_TYPE_MAJOR
;
416 tsize
= 0.02 * tprops
.size
;
418 switch (tprops
.inout
) {
420 vbase1_start
= vbase1
;
421 vbase1_stop
= vbase1
+ tick_dir_sign
*tsize
;
422 vbase2_start
= vbase2
;
423 vbase2_stop
= vbase2
- tick_dir_sign
*tsize
;
426 vbase1_start
= vbase1
;
427 vbase1_stop
= vbase1
- tick_dir_sign
*tsize
;
428 vbase2_start
= vbase2
;
429 vbase2_stop
= vbase2
+ tick_dir_sign
*tsize
;
432 vbase1_start
= vbase1
- tsize
;
433 vbase1_stop
= vbase1
+ tsize
;
434 vbase2_start
= vbase2
+ tsize
;
435 vbase2_stop
= vbase2
- tsize
;
438 errmsg("Internal error in drawaxis()");
442 setcolor(canvas
, tprops
.color
);
443 setlinewidth(canvas
, tprops
.linew
);
444 setlinestyle(canvas
, tprops
.lines
);
447 for (itick
= 0; itick
< t
->nticks
; itick
++) {
448 if (t
->tloc
[itick
].type
!= ttype
) {
452 wtpos
= t
->tloc
[itick
].wtpos
;
454 if ((wtpos
< wc_start
) || (wtpos
> wc_stop
)) {
458 vtpos
= coord_conv(gr
, wtpos
);
459 if (t
->t_op
== PLACEMENT_NORMAL
||
460 t
->t_op
== PLACEMENT_BOTH
) {
461 vp_tick1_start
.x
= vtpos
*ort_para
.x
+ vbase1_start
*ort_perp
.x
;
462 vp_tick1_start
.y
= vtpos
*ort_para
.y
+ vbase1_start
*ort_perp
.y
;
463 vp_tick1_stop
.x
= vtpos
*ort_para
.x
+ vbase1_stop
*ort_perp
.x
;
464 vp_tick1_stop
.y
= vtpos
*ort_para
.y
+ vbase1_stop
*ort_perp
.y
;
465 DrawLine(canvas
, &vp_tick1_start
, &vp_tick1_stop
);
467 if (t
->t_op
== PLACEMENT_OPPOSITE
||
468 t
->t_op
== PLACEMENT_BOTH
) {
469 vp_tick2_start
.x
= vtpos
*ort_para
.x
+ vbase2_start
*ort_perp
.x
;
470 vp_tick2_start
.y
= vtpos
*ort_para
.y
+ vbase2_start
*ort_perp
.y
;
471 vp_tick2_stop
.x
= vtpos
*ort_para
.x
+ vbase2_stop
*ort_perp
.x
;
472 vp_tick2_stop
.y
= vtpos
*ort_para
.y
+ vbase2_stop
*ort_perp
.y
;
473 DrawLine(canvas
, &vp_tick2_start
, &vp_tick2_stop
);
479 /* End axis ticks stuff */
481 /* Make sure we don't end up with an empty BBox if no ticks have
487 update_bbox(canvas
, BBOX_TYPE_TEMP
, &vp1
);
488 update_bbox(canvas
, BBOX_TYPE_TEMP
, &vp2
);
490 /* Begin tick label stuff */
492 if(t
->tl_gaptype
==TYPE_AUTO
) {
493 /* hard coded offsets for autoplacement of tick labels */
494 tl_trans
=0.0; /* parallel */
495 tl_offset
=0.01; /* perpendicular */
497 tl_trans
= t
->tl_gap
.x
;
498 tl_offset
= t
->tl_gap
.y
;
502 if (t
->tl_starttype
== TYPE_SPEC
) {
503 wc_start_labels
= t
->tl_start
;
505 wc_start_labels
= wc_start
;
508 if (t
->tl_stoptype
== TYPE_SPEC
) {
509 wc_stop_labels
= t
->tl_stop
;
511 wc_stop_labels
= wc_stop
;
514 tlsize
= 0.02*t
->tl_tprops
.charsize
;
516 tsize
= 0.02*t
->props
.size
;
518 switch (t
->props
.inout
) {
520 vbase_tlabel1
= vbase1
- (1 - tick_dir_sign
)/2*tsize
- tl_offset
;
521 vbase_tlabel2
= vbase2
+ (1 - tick_dir_sign
)/2*tsize
+ tl_offset
;
524 vbase_tlabel1
= vbase1
- (1 + tick_dir_sign
)/2*tsize
- tl_offset
;
525 vbase_tlabel2
= vbase2
+ (1 + tick_dir_sign
)/2*tsize
+ tl_offset
;
528 vbase_tlabel1
= vbase1
- tsize
- tl_offset
;
529 vbase_tlabel2
= vbase2
+ tsize
+ tl_offset
;
532 errmsg("Internal error in drawaxis()");
537 for (itick
= 0; itick
< t
->nticks
; itick
++) {
538 if (t
->tloc
[itick
].type
!= TICK_TYPE_MAJOR
) {
542 wtpos
= t
->tloc
[itick
].wtpos
;
544 if ((wtpos
< wc_start_labels
) || (wtpos
> wc_stop_labels
)) {
548 if (t
->tl_prestr
[0]) {
549 strcpy(tlabel
, t
->tl_prestr
);
553 if (t
->tloc
[itick
].label
!= NULL
) {
554 strcat(tlabel
, t
->tloc
[itick
].label
);
556 if (t
->tl_appstr
[0]) {
557 strcat(tlabel
, t
->tl_appstr
);
560 vtpos
= coord_conv(gr
, wtpos
);
562 if (itcur
% (t
->tl_skip
+ 1) == 0) {
563 TextProps tprops
= t
->tl_tprops
;
564 /* Tick labels on normal side */
565 if (t
->tl_op
== PLACEMENT_NORMAL
||
566 t
->tl_op
== PLACEMENT_BOTH
) {
567 vbase_tlabel
= vbase_tlabel1
- (tl_offset
+ tlsize
)*
568 (itcur
% (t
->tl_staggered
+ 1));
569 vp_tlabel
.x
= (vtpos
+ tl_trans
)*ort_para
.x
+
570 vbase_tlabel
*ort_perp
.x
;
571 vp_tlabel
.y
= (vtpos
+ tl_trans
)*ort_para
.y
+
572 vbase_tlabel
*ort_perp
.y
;
573 tprops
.just
= tlabel1_just
;
574 drawtext(canvas
, &vp_tlabel
, &tprops
, tlabel
);
576 /* Tick labels on opposite side */
577 if (t
->tl_op
== PLACEMENT_OPPOSITE
||
578 t
->tl_op
== PLACEMENT_BOTH
) {
579 vbase_tlabel
= vbase_tlabel2
+ (tl_offset
+ tlsize
)*
580 (itcur
% (t
->tl_staggered
+ 1));
581 vp_tlabel
.x
= (vtpos
+ tl_trans
)*ort_para
.x
+
582 vbase_tlabel
*ort_perp
.x
;
583 vp_tlabel
.y
= (vtpos
+ tl_trans
)*ort_para
.y
+
584 vbase_tlabel
*ort_perp
.y
;
585 tprops
.just
= tlabel2_just
;
586 drawtext(canvas
, &vp_tlabel
, &tprops
, tlabel
);
593 /* End tick label stuff */
595 get_bbox(canvas
, BBOX_TYPE_TEMP
, &bb
);
597 /* Begin axis label stuff */
599 if (t
->label_place
== TYPE_SPEC
) {
600 vp_label_offset1
= t
->label_offset
;
601 vp_label_offset2
= t
->label_offset
;
603 /* These settings are for backward compatibility */
604 label1_just
= JUST_CENTER
|JUST_MIDDLE
;
605 label2_just
= JUST_CENTER
|JUST_MIDDLE
;
607 /* parallel is trivial ;-) */
608 vp_label_offset1
.x
= 0.00;
609 vp_label_offset2
.x
= 0.00;
613 vp_label_offset1
.y
= vbase1
- bb
.yv1
;
614 vp_label_offset2
.y
= bb
.yv2
- vbase2
;
616 vp_label_offset1
.y
= vbase1
- bb
.xv1
;
617 vp_label_offset2
.y
= bb
.xv2
- vbase2
;
620 vp_label_offset1
.y
+= tl_offset
;
621 vp_label_offset2
.y
+= tl_offset
;
623 label1_just
= tlabel1_just
;
624 label2_just
= tlabel2_just
;
627 if (!is_empty_string(t
->label
)) {
629 setcharsize(canvas
, t
->label_tprops
.charsize
);
630 setfont(canvas
, t
->label_tprops
.font
);
631 setcolor(canvas
, t
->label_tprops
.color
);
633 /* Axis label on normal side */
634 if (t
->label_op
== PLACEMENT_NORMAL
||
635 t
->label_op
== PLACEMENT_BOTH
) {
637 vp_label
.x
= (vp1_start
.x
+ vp1_stop
.x
)/2
638 + vp_label_offset1
.x
*ort_para
.x
639 - vp_label_offset1
.y
*ort_perp
.x
;
640 vp_label
.y
= (vp1_start
.y
+ vp1_stop
.y
)/2
641 + vp_label_offset1
.x
*ort_para
.y
642 - vp_label_offset1
.y
*ort_perp
.y
;
644 WriteString(canvas
, &vp_label
, (double) langle
, label1_just
, t
->label
);
647 /* Axis label on opposite side */
648 if (t
->label_op
== PLACEMENT_OPPOSITE
||
649 t
->label_op
== PLACEMENT_BOTH
) {
651 vp_label
.x
= (vp2_start
.x
+ vp2_stop
.x
)/2
652 + vp_label_offset2
.x
*ort_para
.x
653 + vp_label_offset2
.y
*ort_perp
.x
;
654 vp_label
.y
= (vp2_start
.y
+ vp2_stop
.y
)/2
655 + vp_label_offset2
.x
*ort_para
.y
656 + vp_label_offset2
.y
*ort_perp
.y
;
658 WriteString(canvas
, &vp_label
, (double) langle
, label2_just
, t
->label
);
662 /* End axis label stuff */
665 static void calculate_tickgrid(Quark
*q
)
668 int itick
, imtick
, itmaj
;
670 double swc_start
, swc_stop
, stmajor
;
679 t
= axis_get_data(q
);
685 gr
= get_parent_graph(q
);
687 graph_get_world(gr
, &w
);
690 if (t
->t_spec
== TICKS_SPEC_NONE
) {
692 scale
= graph_get_xscale(gr
);
693 if (scale
== SCALE_LOG
) {
694 swc_start
= fscale(w
.xg1
, scale
);
695 swc_stop
= fscale(w
.xg2
, scale
);
701 scale
= graph_get_yscale(gr
);
702 if (scale
== SCALE_LOG
) {
703 swc_start
= fscale(w
.yg1
, scale
);
704 swc_stop
= fscale(w
.yg2
, scale
);
710 if (scale
== SCALE_LOG
) {
711 stmajor
= fscale(t
->tmajor
, scale
);
716 if (stmajor
<= 0.0) {
717 errmsg("Invalid major tick spacing, autoticking");
722 if (t
->t_round
== TRUE
) {
723 swc_start
= floor(swc_start
/stmajor
)*stmajor
;
726 nmajor
= (int) ceil((swc_stop
- swc_start
) / stmajor
+ 1);
727 t
->nticks
= (nmajor
- 1)*(t
->nminor
+ 1) + 1;
729 if (t
->nticks
> MAX_TICKS
) {
730 errmsg("Too many ticks ( > MAX_TICKS ), autoticking");
736 * if (t->nticks > MAX_TICKS) {
737 * t->nticks = MAX_TICKS;
743 while (itick
< t
->nticks
) {
744 if (scale
== SCALE_LOG
) {
745 wtmaj
= ifscale(swc_start
+ itmaj
*stmajor
, scale
);
747 wtmaj
= swc_start
+ itmaj
*stmajor
;
748 if (t
->tl_format
== FORMAT_GENERAL
&& fabs(wtmaj
) < 1.0e-6*stmajor
) {
752 t
->tloc
[itick
].wtpos
= wtmaj
;
753 t
->tloc
[itick
].type
= TICK_TYPE_MAJOR
;
756 for (imtick
= 0; imtick
< t
->nminor
&& itick
< t
->nticks
; imtick
++) {
757 if (scale
== SCALE_LOG
) {
758 t
->tloc
[itick
].wtpos
= wtmaj
* (imtick
+ 2);
760 t
->tloc
[itick
].wtpos
= wtmaj
+ (imtick
+ 1)*stmajor
/(t
->nminor
+ 1);
762 t
->tloc
[itick
].type
= TICK_TYPE_MINOR
;
763 XCFREE(t
->tloc
[itick
].label
);
770 if (t
->t_spec
!= TICKS_SPEC_BOTH
) {
772 for (itick
= 0; itick
< t
->nticks
; itick
++) {
773 if (t
->tloc
[itick
].type
== TICK_TYPE_MAJOR
) {
777 if (!is_empty_string(t
->tl_formula
)) {
779 tvar
= get_parser_arr_by_name("$t");
781 tvar
= define_parser_arr("$t");
783 errmsg("Internal error");
788 if (tvar
->length
!= 0) {
792 tvar
->data
= xmalloc(nmajor
*SIZEOF_DOUBLE
);
793 if (tvar
->data
== NULL
) {
796 tvar
->length
= nmajor
;
799 for (itick
= 0; itick
< t
->nticks
; itick
++) {
800 if (t
->tloc
[itick
].type
== TICK_TYPE_MAJOR
) {
801 tvar
->data
[itmaj
] = t
->tloc
[itick
].wtpos
;
806 res
= v_scanner(t
->tl_formula
, &len
, &tt
);
809 if (res
!= RETURN_SUCCESS
|| len
!= nmajor
) {
810 errmsg("Error in tick transformation formula");
815 for (itick
= 0; itick
< t
->nticks
; itick
++) {
816 if (t
->tloc
[itick
].type
== TICK_TYPE_MAJOR
) {
817 t
->tloc
[itick
].label
= copy_string(t
->tloc
[itick
].label
,
818 create_fstring(get_parent_project(q
),
819 t
->tl_format
, t
->tl_prec
,
820 tt
[itmaj
], LFORMAT_TYPE_EXTENDED
));
826 for (itick
= 0; itick
< t
->nticks
; itick
++) {
827 if (t
->tloc
[itick
].type
== TICK_TYPE_MAJOR
) {
828 t
->tloc
[itick
].label
= copy_string(t
->tloc
[itick
].label
,
829 create_fstring(get_parent_project(q
),
830 t
->tl_format
, t
->tl_prec
,
831 t
->tloc
[itick
].wtpos
, LFORMAT_TYPE_EXTENDED
));
838 void draw_axis(Canvas
*canvas
, Quark
*q
)
840 tickmarks
*t
= axis_get_data(q
);
841 if (t
&& graph_get_type(get_parent_graph(q
)) != GRAPH_PIE
) {
842 /* calculate tick mark positions */
843 calculate_tickgrid(q
);
845 /* draw grid lines */