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