TPCCLIB
Loading...
Searching...
No Matches
axis.c File Reference

Axis for XY plots. More...

#include "libtpcsvg.h"

Go to the source code of this file.

Functions

int axis_tick_positions (const double begin, const double end, double *ticks, int *tick_nr, double *scale_factor, int *tick_decimals, int verbose)
void axis_check_range (double *begin, double *end, int verbose)
void strRmExpZeroes (char *str)

Detailed Description

Axis for XY plots.

Author
Vesa Oikonen

Definition in file axis.c.

Function Documentation

◆ axis_check_range()

void axis_check_range ( double * begin,
double * end,
int verbose )

Check and if necessary correct axis range: min must be smaller than max. Also, if the range is close to zero, then make it larger. Also, if the range is relatively large, then change it to start from zero.

See also
axis_tick_positions, svg_calculate_axes
Parameters
beginaxis range minimum
endaxis range maximum
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 116 of file axis.c.

123 {
124 double temp;
125
126 if(verbose>0) printf("axis_check_range(%g, %g, %d)\n", *begin, *end, verbose);
127
128 if(*begin<*end) {
129 // fine now
130 } else if(*begin>*end) {
131 temp=*end; *end=*begin; *begin=temp;
132 } else { // this means that begin==end
133 if(*begin==0.0) {
134 *begin=-1.0; *end=1.0;
135 } else if(*begin<0.0) {
136 *begin*=2.0; *end=0.0;
137 } else {
138 *begin=0.0; *end*=2.0;
139 }
140 if(verbose>2) {
141 printf(" new begin := %g\n", *begin);
142 printf(" new end := %g\n", *end);
143 }
144 return;
145 }
146 /* If range is very small */
147 if((*end-*begin)<1.0e-98) {
148 if(*begin>=1.0e-98 || *begin<0.0) *begin-=1.0e-98;
149 else if(*begin>=0.0) *begin=0.0;
150 if(*end<=-1.0e-98 || *end>0.0) *end+=1.0e-98;
151 else if(*end<0.0) *end=0.0;
152 if(verbose>2) {
153 printf(" new begin := %g\n", *begin);
154 printf(" new end := %g\n", *end);
155 }
156 return;
157 }
158 /* If range is relatively large */
159 if(*begin>0.0 && *end>0.0) {
160 if((*end-*begin)>3.3*(*begin)) *begin=0.0;
161 } else if(*begin<0.0 && *end<0.0) {
162 if((*end-*begin)>3.3*(-*end)) *end=0.0;
163 }
164 /* If data range is relatively small (compared to level) */
165 temp=(*end-*begin)*2.0/(fabs(*end)+fabs(*begin));
166 if(temp<0.01) {
167 temp=0.5*(*end-*begin)*0.01/temp;
168 if(*begin<0.0 || *begin>temp) *begin-=temp; else *begin=0.0;
169 if(*end>0.0 || *end<-temp) *end+=temp; else *end=0.0;
170 }
171
172 return;
173}

Referenced by svg_calculate_axes().

◆ axis_tick_positions()

int axis_tick_positions ( const double begin,
const double end,
double * ticks,
int * tick_nr,
double * scale_factor,
int * tick_decimals,
int verbose )

Define suitable tick positions for XY plot.

Returns
Returns 0 if successful, <>0 in case of error.
See also
axis_check_range, svg_calculate_axes
Parameters
beginaxis range minimum.
endaxis range maximum.
ticksPointer to array where tick values will be written. Length must be at least tick_nr.
tick_nrInput: Max allowed nr of ticks; Output: actual nr of ticks.
scale_factorOutput: Suggested scale factor (x10^sf). NULL, if not needed.
tick_decimalsOutput: tick value precision (nr of decimals). NULL, if not needed.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 14 of file axis.c.

29 {
30 int ti;
31 double step, scale;
32
33 if(verbose>0)
34 printf("axis_tick_positions(%.10E, %.10E, ticks, %d, sf, td, %d)\n",
35 begin, end, *tick_nr, verbose);
36
37 /* Check input */
38 if(ticks==NULL || *tick_nr<1) return(1);
39 //if(verbose>1) printf(" begin:=%.10E\n end:=%.10E\n", begin, end);
40 if(end<=begin) {
41 *tick_nr=0;
42 if(scale_factor!=NULL) *scale_factor=1.0;
43 if(tick_decimals!=NULL) *tick_decimals=0;
44 return(0);
45 }
46 /* Calculate the initial tick step size */
47 step=(end-begin)/(double)(*tick_nr);
48 if(verbose>1) printf(" tick_nr:=%d\n step:=%20.10E\n", *tick_nr, step);
49
50 /* Calculate a feasible step size and scale */
51 scale=1.0;
52 while(step<=0.5) {step*=10.0; scale/=10.0;}
53 while(step>5.0) {step/=10.0; scale*=10.0;}
54 if(verbose>1) printf(" scaled_step:=%.10E\n scale:=%E\n", step, scale);
55 if (step<1.0) {step=1.0;}
56 else if(step<2.0) {step=2.0;}
57 else {step=5.0;}
58 if(verbose>1) {
59 printf(" feasible step:=%g\n", step);
60 }
61 ti=0; ticks[ti]=step*scale*ceil(begin/(step*scale));
62 while(ticks[ti]<=(end+(end-begin)*0.00001) && ti<*tick_nr) {
63 ti++; ticks[ti]=ticks[0]+step*scale*(double)ti;
64 }
65 *tick_nr=ti;
66
67 if(verbose>1) {
68 printf(" final tick_nr := %d\n", *tick_nr);
69 printf(" ticks: %.10E", ticks[0]);
70 for(ti=1; ti<*tick_nr; ti++) printf(", %.10E", ticks[ti]);
71 printf("\n");
72 }
73
74 /* Quit, if user did not like scales etc */
75 if(scale_factor==NULL && tick_decimals==NULL) return(0);
76
77 /* Calculate step scale */
78 double step_scale=log10(scale);
79 if(verbose>1) printf(" step_scale=%g\n", step_scale);
80
81 /* Find the highest tick label */
82 double tick_high;
83 int tick_scale, scale_dif;
84 if(fabs(ticks[0])>fabs(ticks[*tick_nr-1])) tick_high=ticks[0];
85 else tick_high=ticks[*tick_nr-1];
86 if(verbose>1) printf(" tick_high := %.10E\n", tick_high);
87 tick_scale=0;
88 while(fabs(tick_high)<1.0) {tick_high*=10.0; tick_scale--;}
89 while(fabs(tick_high)>=10.0) {tick_high/=10.0; tick_scale++;}
90 if(verbose>1) printf(" scaled_tick_high := %g\n tick_scale := %d\n", tick_high, tick_scale);
91
92 /* Calculate the difference between tick and step scales */
93 scale_dif=tick_scale-step_scale;
94 if(verbose>1) printf(" scale_dif := %d\n", scale_dif);
95 /* That determines the tick number precision */
96 if(tick_decimals!=NULL) {
97 *tick_decimals=1+scale_dif;
98 if(verbose>1) printf(" tick_decimals := %d\n", *tick_decimals);
99 }
100
101 /* Calculate the preferred tick scale factor, or quit, if it is not needed */
102 if(scale_factor==NULL) return(0);
103 *scale_factor=tick_scale;
104 if(verbose>1) printf(" scale_factor := %g\n", *scale_factor);
105
106 return(0);
107}

Referenced by svg_calculate_axes().

◆ strRmExpZeroes()

void strRmExpZeroes ( char * str)

Remove initial exponential zeroes from the exponential part of string representation of values, for example, '1.01E-010' -> '1.01E-10'.

Definition at line 179 of file axis.c.

180{
181 char *p, *r;
182 int i, n;
183
184 if(str==NULL || strlen(str)<3) return;
185 // search the exp E
186 p=strrchr(str, 'E'); if(p==NULL) p=strrchr(str, 'e'); if(p==NULL) return;
187 // if only +,- and 0 after it, then remove also E
188 r=p+1; if(strspn(r, "0+-")==strlen(r)) {*p=(char)0; return;}
189 // remove next '+' or jump over '-'
190 p++;
191 if(*p=='+') {r=p; while(1) {*r=*(r+1); if(*r==(char)0) break; r++;}}
192 else if(*p=='-') p++;
193 // count initial zeroes
194 n=strspn(p, "0"); if(n==0) return;
195 // copy the rest of the string over zeroes
196 r=p+n; n=strlen(r);
197 for(i=0; i<=n; i++) {*p=*r; p++; r++;}
198 return;
199}

Referenced by svg_calculate_axes().