xref: /petsc/src/sys/classes/draw/utils/axisc.c (revision 22d28d0898e9654d85ab75d133853ba201e99be3) !
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*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow));
205     axis->yhigh += 1.e-5*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow));
206    } */
207   if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}
208 
209   xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh;
210   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
211   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
212   numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6; if (numx< 2) numx = 2;
213   numy = (int)(.5*(yr-yl)/th); if (numy > 6) numy = 6; if (numy< 2) numy = 2;
214   xl -= 11*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th;
215   if (axis->xlabel) yl -= 2*th;
216   if (axis->ylabel) xl -= 2*tw;
217   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
218   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
219 
220   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr);
221   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr);
222 
223   if (axis->toplabel) {
224     ierr =  PetscStrlen(axis->toplabel,&len);CHKERRQ(ierr);
225     w    = xl + .5*(xr - xl) - .5*len*tw;
226     h    = axis->yhigh;
227     ierr = PetscDrawString(draw,w,h,cc,axis->toplabel);CHKERRQ(ierr);
228   }
229 
230   /* PetscDraw the ticks and labels */
231   if (axis->xticks) {
232     ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
233     /* PetscDraw in tick marks */
234     for (i=0; i<ntick; i++) {
235       ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr);
236     }
237     /* label ticks */
238     for (i=0; i<ntick; i++) {
239       if (axis->xlabelstr) {
240         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
241         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
242         else               sep = 0.0;
243         ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
244         ierr = PetscStrlen(p,&len);CHKERRQ(ierr);
245         w    = .5*len*tw;
246         ierr = PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);CHKERRQ(ierr);
247       }
248     }
249   }
250   if (axis->xlabel) {
251     ierr = PetscStrlen(axis->xlabel,&len);CHKERRQ(ierr);
252     w    = xl + .5*(xr - xl) - .5*len*tw;
253     h    = axis->ylow - 2.5*th;
254     ierr = PetscDrawString(draw,w,h,cc,axis->xlabel);CHKERRQ(ierr);
255   }
256   if (axis->yticks) {
257     ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
258     /* PetscDraw in tick marks */
259     for (i=0; i<ntick; i++) {
260       ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr);
261     }
262     /* label ticks */
263     for (i=0; i<ntick; i++) {
264       if (axis->ylabelstr) {
265         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
266         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
267         else               sep = 0.0;
268         ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
269         ierr = PetscStrlen(p,&len);CHKERRQ(ierr);
270         w    = axis->xlow - len * tw - 1.2*tw;
271         ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr);
272       }
273     }
274   }
275   if (axis->ylabel) {
276     ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr);
277     h    = yl + .5*(yr - yl) + .5*len*th;
278     w    = xl + .5*tw;
279     ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr);
280   }
281   PetscFunctionReturn(0);
282 }
283 
284 #undef __FUNCT__
285 #define __FUNCT__ "PetscStripe0"
286 /*
287     Removes all zeros but one from .0000
288 */
289 PetscErrorCode PetscStripe0(char *buf)
290 {
291   PetscErrorCode ierr;
292   size_t         n;
293   PetscBool      flg;
294   char           *str;
295 
296   PetscFunctionBegin;
297   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
298   ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr);
299   if (flg) {
300     buf[n-3] = 0;
301   }
302   ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr);
303   if (str) {
304     buf[n-2] = buf[n-1];
305     buf[n-1] = 0;
306   }
307   ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr);
308   if (str) {
309     buf[n-2] = buf[n-1];
310     buf[n-1] = 0;
311   }
312   PetscFunctionReturn(0);
313 }
314 
315 #undef __FUNCT__
316 #define __FUNCT__ "PetscStripAllZeros"
317 /*
318     Removes all zeros but one from .0000
319 */
320 PetscErrorCode PetscStripAllZeros(char *buf)
321 {
322   PetscErrorCode ierr;
323   size_t         i,n;
324 
325   PetscFunctionBegin;
326   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
327   if (buf[0] != '.') PetscFunctionReturn(0);
328   for (i=1; i<n; i++) {
329     if (buf[i] != '0') PetscFunctionReturn(0);
330   }
331   buf[0] = '0';
332   buf[1] = 0;
333   PetscFunctionReturn(0);
334 }
335 
336 #undef __FUNCT__
337 #define __FUNCT__ "PetscStripTrailingZeros"
338 /*
339     Removes trailing zeros
340 */
341 PetscErrorCode PetscStripTrailingZeros(char *buf)
342 {
343   PetscErrorCode ierr;
344   char           *found;
345   size_t         i,n,m = PETSC_MAX_INT;
346 
347   PetscFunctionBegin;
348   /* if there is an e in string DO NOT strip trailing zeros */
349   ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr);
350   if (found) PetscFunctionReturn(0);
351 
352   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
353   /* locate decimal point */
354   for (i=0; i<n; i++) {
355     if (buf[i] == '.') {m = i; break;}
356   }
357   /* if not decimal point then no zeros to remove */
358   if (m == PETSC_MAX_INT) PetscFunctionReturn(0);
359   /* start at right end of string removing 0s */
360   for (i=n-1; i>m; i++) {
361     if (buf[i] != '0') PetscFunctionReturn(0);
362     buf[i] = 0;
363   }
364   PetscFunctionReturn(0);
365 }
366 
367 #undef __FUNCT__
368 #define __FUNCT__ "PetscStripInitialZero"
369 /*
370     Removes leading 0 from 0.22 or -0.22
371 */
372 PetscErrorCode PetscStripInitialZero(char *buf)
373 {
374   PetscErrorCode ierr;
375   size_t         i,n;
376 
377   PetscFunctionBegin;
378   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
379   if (buf[0] == '0') {
380     for (i=0; i<n; i++) {
381       buf[i] = buf[i+1];
382     }
383   } else if (buf[0] == '-' && buf[1] == '0') {
384     for (i=1; i<n; i++) {
385       buf[i] = buf[i+1];
386     }
387   }
388   PetscFunctionReturn(0);
389 }
390 
391 #undef __FUNCT__
392 #define __FUNCT__ "PetscStripZeros"
393 /*
394      Removes the extraneous zeros in numbers like 1.10000e6
395 */
396 PetscErrorCode PetscStripZeros(char *buf)
397 {
398   PetscErrorCode ierr;
399   size_t         i,j,n;
400 
401   PetscFunctionBegin;
402   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
403   if (n<5) PetscFunctionReturn(0);
404   for (i=1; i<n-1; i++) {
405     if (buf[i] == 'e' && buf[i-1] == '0') {
406       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
407       ierr = PetscStripZeros(buf);CHKERRQ(ierr);
408       PetscFunctionReturn(0);
409     }
410   }
411   PetscFunctionReturn(0);
412 }
413 
414 #undef __FUNCT__
415 #define __FUNCT__ "PetscStripZerosPlus"
416 /*
417       Removes the plus in something like 1.1e+2 or 1.1e+02
418 */
419 PetscErrorCode PetscStripZerosPlus(char *buf)
420 {
421   PetscErrorCode ierr;
422   size_t         i,j,n;
423 
424   PetscFunctionBegin;
425   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
426   if (n<5) PetscFunctionReturn(0);
427   for (i=1; i<n-2; i++) {
428     if (buf[i] == '+') {
429       if (buf[i+1] == '0') {
430         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
431         PetscFunctionReturn(0);
432       } else {
433         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
434         PetscFunctionReturn(0);
435       }
436     } else if (buf[i] == '-') {
437       if (buf[i+1] == '0') {
438         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
439         PetscFunctionReturn(0);
440       }
441     }
442   }
443   PetscFunctionReturn(0);
444 }
445 
446 
447 
448 
449 
450 
451 
452