xref: /petsc/src/sys/classes/draw/utils/axisc.c (revision 36c9bc0d608efe1a596e7d8b972c2154d3f5669d)
1 #include <../src/sys/classes/draw/utils/axisimpl.h>
2 
3 PetscClassId PETSC_DRAWAXIS_CLASSID = 0;
4 
5 #undef __FUNCT__
6 #define __FUNCT__ "PetscDrawAxisCreate"
7 /*@
8    PetscDrawAxisCreate - Generate the axis data structure.
9 
10    Collective over PetscDraw
11 
12    Input Parameters:
13 .  win - PetscDraw object where axis to to be made
14 
15    Ouput Parameters:
16 .  axis - the axis datastructure
17 
18    Level: advanced
19 
20 @*/
21 PetscErrorCode  PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis *axis)
22 {
23   PetscDrawAxis  ad;
24   PetscObject    obj = (PetscObject)draw;
25   PetscErrorCode ierr;
26   PetscBool      isnull;
27 
28   PetscFunctionBegin;
29   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
30   PetscValidPointer(axis,2);
31   ierr = PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);CHKERRQ(ierr);
32   if (isnull) {
33     ierr = PetscDrawOpenNull(((PetscObject)obj)->comm,(PetscDraw*)axis);CHKERRQ(ierr);
34     (*axis)->win = draw;
35     PetscFunctionReturn(0);
36   }
37   ierr = PetscHeaderCreate(ad,_p_PetscDrawAxis,int,PETSC_DRAWAXIS_CLASSID,0,"PetscDrawAxis","Draw Axis","Draw",((PetscObject)obj)->comm,PetscDrawAxisDestroy,0);CHKERRQ(ierr);
38   ierr = PetscLogObjectParent(draw,ad);CHKERRQ(ierr);
39   ad->xticks    = PetscADefTicks;
40   ad->yticks    = PetscADefTicks;
41   ad->xlabelstr = PetscADefLabel;
42   ad->ylabelstr = PetscADefLabel;
43   ad->win       = draw;
44   ad->ac        = PETSC_DRAW_BLACK;
45   ad->tc        = PETSC_DRAW_BLACK;
46   ad->cc        = PETSC_DRAW_BLACK;
47   ad->xlabel    = 0;
48   ad->ylabel    = 0;
49   ad->toplabel  = 0;
50 
51   *axis = ad;
52   PetscFunctionReturn(0);
53 }
54 
55 #undef __FUNCT__
56 #define __FUNCT__ "PetscDrawAxisDestroy"
57 /*@
58     PetscDrawAxisDestroy - Frees the space used by an axis structure.
59 
60     Collective over PetscDrawAxis
61 
62     Input Parameters:
63 .   axis - the axis context
64 
65     Level: advanced
66 
67 @*/
68 PetscErrorCode  PetscDrawAxisDestroy(PetscDrawAxis *axis)
69 {
70   PetscErrorCode ierr;
71 
72   PetscFunctionBegin;
73   if (!*axis) PetscFunctionReturn(0);
74   if (--((PetscObject)(*axis))->refct > 0) PetscFunctionReturn(0);
75 
76   ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr);
77   ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr);
78   ierr = PetscFree((*axis)->ylabel);CHKERRQ(ierr);
79   ierr = PetscHeaderDestroy(axis);CHKERRQ(ierr);
80   PetscFunctionReturn(0);
81 }
82 
83 #undef __FUNCT__
84 #define __FUNCT__ "PetscDrawAxisSetColors"
85 /*@
86     PetscDrawAxisSetColors -  Sets the colors to be used for the axis,
87                          tickmarks, and text.
88 
89     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
90 
91     Input Parameters:
92 +   axis - the axis
93 .   ac - the color of the axis lines
94 .   tc - the color of the tick marks
95 -   cc - the color of the text strings
96 
97     Level: advanced
98 
99 @*/
100 PetscErrorCode  PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
101 {
102   PetscFunctionBegin;
103   if (!axis) PetscFunctionReturn(0);
104   axis->ac = ac; axis->tc = tc; axis->cc = cc;
105   PetscFunctionReturn(0);
106 }
107 
108 #undef __FUNCT__
109 #define __FUNCT__ "PetscDrawAxisSetLabels"
110 /*@C
111     PetscDrawAxisSetLabels -  Sets the x and y axis labels.
112 
113     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
114 
115     Input Parameters:
116 +   axis - the axis
117 .   top - the label at the top of the image
118 -   xlabel,ylabel - the labes for the x and y axis
119 
120     Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
121            There should be no newlines in the arguments
122 
123     Level: advanced
124 
125 @*/
126 PetscErrorCode  PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
127 {
128   PetscErrorCode ierr;
129 
130   PetscFunctionBegin;
131   if (!axis) PetscFunctionReturn(0);
132   ierr = PetscFree(axis->xlabel);CHKERRQ(ierr);
133   ierr = PetscFree(axis->ylabel);CHKERRQ(ierr);
134   ierr = PetscFree(axis->toplabel);CHKERRQ(ierr);
135   ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr);
136   ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr);
137   ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr);
138   PetscFunctionReturn(0);
139 }
140 
141 #undef __FUNCT__
142 #define __FUNCT__ "PetscDrawAxisSetHoldLimits"
143 /*@
144     PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
145         again
146 
147     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
148 
149     Input Parameters:
150 +   axis - the axis
151 -   hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
152 
153     Level: advanced
154 
155     Notes:
156         Once this has been called with PETSC_TRUE the limits will not change if you call
157      PetscDrawAxisSetLimits() until you call this with PETSC_FALSE
158 
159 .seealso:  PetscDrawAxisSetLimits()
160 
161 @*/
162 PetscErrorCode  PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool  hold)
163 {
164   PetscFunctionBegin;
165   if (!axis) PetscFunctionReturn(0);
166   axis->hold = hold;
167   PetscFunctionReturn(0);
168 }
169 
170 #undef __FUNCT__
171 #define __FUNCT__ "PetscDrawAxisDraw"
172 /*@
173     PetscDrawAxisDraw - PetscDraws an axis.
174 
175     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
176 
177     Input Parameter:
178 .   axis - Axis structure
179 
180     Level: advanced
181 
182     Note:
183     This draws the actual axis.  The limits etc have already been set.
184     By picking special routines for the ticks and labels, special
185     effects may be generated.  These routines are part of the Axis
186     structure (axis).
187 @*/
188 PetscErrorCode  PetscDrawAxisDraw(PetscDrawAxis axis)
189 {
190   int            i,ntick,numx,numy,ac = axis->ac,tc = axis->tc,cc = axis->cc,rank;
191   size_t         len;
192   PetscReal      tickloc[MAXSEGS],sep,h,w,tw,th,xl,xr,yl,yr;
193   char           *p;
194   PetscDraw      draw = axis->win;
195   PetscErrorCode ierr;
196 
197   PetscFunctionBegin;
198   if (!axis) PetscFunctionReturn(0);
199   ierr = MPI_Comm_rank(((PetscObject)axis)->comm,&rank);CHKERRQ(ierr);
200   if (rank) PetscFunctionReturn(0);
201 
202   if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
203   if ((axis->yhigh - axis->ylow) <= 1.e-5*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow))) {
204     axis->ylow -= 1.e-5; axis->yhigh += 1.e-5;
205   }
206 
207   xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh;
208   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
209   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
210   numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6; if (numx< 2) numx = 2;
211   numy = (int)(.5*(yr-yl)/th); if (numy > 6) numy = 6; if (numy< 2) numy = 2;
212   xl -= 11*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th;
213   if (axis->xlabel) yl -= 2*th;
214   if (axis->ylabel) xl -= 2*tw;
215   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
216   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
217 
218   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr);
219   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr);
220 
221   if (axis->toplabel) {
222     ierr =  PetscStrlen(axis->toplabel,&len);CHKERRQ(ierr);
223     w    = xl + .5*(xr - xl) - .5*len*tw;
224     h    = axis->yhigh;
225     ierr = PetscDrawString(draw,w,h,cc,axis->toplabel);CHKERRQ(ierr);
226   }
227 
228   /* PetscDraw the ticks and labels */
229   if (axis->xticks) {
230     ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
231     /* PetscDraw in tick marks */
232     for (i=0; i<ntick; i++) {
233       ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr);
234     }
235     /* label ticks */
236     for (i=0; i<ntick; i++) {
237 	if (axis->xlabelstr) {
238 	    if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
239 	    else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
240 	    else               sep = 0.0;
241 	    ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
242             ierr = PetscStrlen(p,&len);CHKERRQ(ierr);
243 	    w    = .5*len*tw;
244 	    ierr = PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);CHKERRQ(ierr);
245         }
246     }
247   }
248   if (axis->xlabel) {
249     ierr = PetscStrlen(axis->xlabel,&len);CHKERRQ(ierr);
250     w    = xl + .5*(xr - xl) - .5*len*tw;
251     h    = axis->ylow - 2.5*th;
252     ierr = PetscDrawString(draw,w,h,cc,axis->xlabel);CHKERRQ(ierr);
253   }
254   if (axis->yticks) {
255     ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
256     /* PetscDraw in tick marks */
257     for (i=0; i<ntick; i++) {
258       ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr);
259     }
260     /* label ticks */
261     for (i=0; i<ntick; i++) {
262 	if (axis->ylabelstr) {
263 	    if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
264 	    else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
265 	    else               sep = 0.0;
266 	    ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
267             ierr = PetscStrlen(p,&len);CHKERRQ(ierr);
268 	    w    = axis->xlow - len * tw - 1.2*tw;
269 	    ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr);
270         }
271     }
272   }
273   if (axis->ylabel) {
274     ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr);
275     h    = yl + .5*(yr - yl) + .5*len*th;
276     w    = xl + .5*tw;
277     ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr);
278   }
279   PetscFunctionReturn(0);
280 }
281 
282 #undef __FUNCT__
283 #define __FUNCT__ "PetscStripe0"
284 /*
285     Removes all zeros but one from .0000
286 */
287 PetscErrorCode PetscStripe0(char *buf)
288 {
289   PetscErrorCode ierr;
290   size_t         n;
291   PetscBool      flg;
292   char           *str;
293 
294   PetscFunctionBegin;
295   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
296   ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr);
297   if (flg) {
298     buf[n-3] = 0;
299   }
300   ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr);
301   if (str) {
302     buf[n-2] = buf[n-1];
303     buf[n-1] = 0;
304   }
305   ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr);
306   if (str) {
307     buf[n-2] = buf[n-1];
308     buf[n-1] = 0;
309   }
310   PetscFunctionReturn(0);
311 }
312 
313 #undef __FUNCT__
314 #define __FUNCT__ "PetscStripAllZeros"
315 /*
316     Removes all zeros but one from .0000
317 */
318 PetscErrorCode PetscStripAllZeros(char *buf)
319 {
320   PetscErrorCode ierr;
321   size_t         i,n;
322 
323   PetscFunctionBegin;
324   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
325   if (buf[0] != '.') PetscFunctionReturn(0);
326   for (i=1; i<n; i++) {
327     if (buf[i] != '0') PetscFunctionReturn(0);
328   }
329   buf[0] = '0';
330   buf[1] = 0;
331   PetscFunctionReturn(0);
332 }
333 
334 #undef __FUNCT__
335 #define __FUNCT__ "PetscStripTrailingZeros"
336 /*
337     Removes trailing zeros
338 */
339 PetscErrorCode PetscStripTrailingZeros(char *buf)
340 {
341   PetscErrorCode ierr;
342   char           *found;
343   size_t         i,n,m = PETSC_MAX_INT;
344 
345   PetscFunctionBegin;
346   /* if there is an e in string DO NOT strip trailing zeros */
347   ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr);
348   if (found) PetscFunctionReturn(0);
349 
350   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
351   /* locate decimal point */
352   for (i=0; i<n; i++) {
353     if (buf[i] == '.') {m = i; break;}
354   }
355   /* if not decimal point then no zeros to remove */
356   if (m == PETSC_MAX_INT) PetscFunctionReturn(0);
357   /* start at right end of string removing 0s */
358   for (i=n-1; i>m; i++) {
359     if (buf[i] != '0') PetscFunctionReturn(0);
360     buf[i] = 0;
361   }
362   PetscFunctionReturn(0);
363 }
364 
365 #undef __FUNCT__
366 #define __FUNCT__ "PetscStripInitialZero"
367 /*
368     Removes leading 0 from 0.22 or -0.22
369 */
370 PetscErrorCode PetscStripInitialZero(char *buf)
371 {
372   PetscErrorCode ierr;
373   size_t         i,n;
374 
375   PetscFunctionBegin;
376   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
377   if (buf[0] == '0') {
378     for (i=0; i<n; i++) {
379       buf[i] = buf[i+1];
380     }
381   } else if (buf[0] == '-' && buf[1] == '0') {
382     for (i=1; i<n; i++) {
383       buf[i] = buf[i+1];
384     }
385   }
386   PetscFunctionReturn(0);
387 }
388 
389 #undef __FUNCT__
390 #define __FUNCT__ "PetscStripZeros"
391 /*
392      Removes the extraneous zeros in numbers like 1.10000e6
393 */
394 PetscErrorCode PetscStripZeros(char *buf)
395 {
396   PetscErrorCode ierr;
397   size_t         i,j,n;
398 
399   PetscFunctionBegin;
400   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
401   if (n<5) PetscFunctionReturn(0);
402   for (i=1; i<n-1; i++) {
403     if (buf[i] == 'e' && buf[i-1] == '0') {
404       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
405       ierr = PetscStripZeros(buf);CHKERRQ(ierr);
406       PetscFunctionReturn(0);
407     }
408   }
409   PetscFunctionReturn(0);
410 }
411 
412 #undef __FUNCT__
413 #define __FUNCT__ "PetscStripZerosPlus"
414 /*
415       Removes the plus in something like 1.1e+2 or 1.1e+02
416 */
417 PetscErrorCode PetscStripZerosPlus(char *buf)
418 {
419   PetscErrorCode ierr;
420   size_t         i,j,n;
421 
422   PetscFunctionBegin;
423   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
424   if (n<5) PetscFunctionReturn(0);
425   for (i=1; i<n-2; i++) {
426     if (buf[i] == '+') {
427       if (buf[i+1] == '0') {
428         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
429         PetscFunctionReturn(0);
430       } else {
431         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
432         PetscFunctionReturn(0);
433       }
434     } else if (buf[i] == '-') {
435       if (buf[i+1] == '0') {
436         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
437         PetscFunctionReturn(0);
438       }
439     }
440   }
441   PetscFunctionReturn(0);
442 }
443 
444 
445 
446 
447 
448 
449 
450