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