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