xref: /petsc/src/sys/classes/draw/utils/axisc.c (revision 9895aa37ac365bac650f6bd8bf977519f7222510)
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   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(PetscObjectComm((PetscObject)obj),(PetscDraw*)axis);CHKERRQ(ierr);
34 
35     (*axis)->win = draw;
36     PetscFunctionReturn(0);
37   }
38   ierr = PetscHeaderCreate(ad,_p_PetscDrawAxis,int,PETSC_DRAWAXIS_CLASSID,"PetscDrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)obj),PetscDrawAxisDestroy,0);CHKERRQ(ierr);
39   ierr = PetscLogObjectParent(draw,ad);CHKERRQ(ierr);
40 
41   ad->xticks    = PetscADefTicks;
42   ad->yticks    = PetscADefTicks;
43   ad->xlabelstr = PetscADefLabel;
44   ad->ylabelstr = PetscADefLabel;
45   ad->win       = draw;
46   ad->ac        = PETSC_DRAW_BLACK;
47   ad->tc        = PETSC_DRAW_BLACK;
48   ad->cc        = PETSC_DRAW_BLACK;
49   ad->xlabel    = 0;
50   ad->ylabel    = 0;
51   ad->toplabel  = 0;
52 
53   *axis = ad;
54   PetscFunctionReturn(0);
55 }
56 
57 #undef __FUNCT__
58 #define __FUNCT__ "PetscDrawAxisDestroy"
59 /*@
60     PetscDrawAxisDestroy - Frees the space used by an axis structure.
61 
62     Collective over PetscDrawAxis
63 
64     Input Parameters:
65 .   axis - the axis context
66 
67     Level: advanced
68 
69 @*/
70 PetscErrorCode  PetscDrawAxisDestroy(PetscDrawAxis *axis)
71 {
72   PetscErrorCode ierr;
73 
74   PetscFunctionBegin;
75   if (!*axis) PetscFunctionReturn(0);
76   if (--((PetscObject)(*axis))->refct > 0) PetscFunctionReturn(0);
77 
78   ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr);
79   ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr);
80   ierr = PetscFree((*axis)->ylabel);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   axis->ac = ac; axis->tc = tc; axis->cc = cc;
107   PetscFunctionReturn(0);
108 }
109 
110 #undef __FUNCT__
111 #define __FUNCT__ "PetscDrawAxisSetLabels"
112 /*@C
113     PetscDrawAxisSetLabels -  Sets the x and y axis labels.
114 
115     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
116 
117     Input Parameters:
118 +   axis - the axis
119 .   top - the label at the top of the image
120 -   xlabel,ylabel - the labes for the x and y axis
121 
122     Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
123            There should be no newlines in the arguments
124 
125     Level: advanced
126 
127 @*/
128 PetscErrorCode  PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
129 {
130   PetscErrorCode ierr;
131 
132   PetscFunctionBegin;
133   if (!axis) PetscFunctionReturn(0);
134   ierr = PetscFree(axis->xlabel);CHKERRQ(ierr);
135   ierr = PetscFree(axis->ylabel);CHKERRQ(ierr);
136   ierr = PetscFree(axis->toplabel);CHKERRQ(ierr);
137   ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr);
138   ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr);
139   ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr);
140   PetscFunctionReturn(0);
141 }
142 
143 #undef __FUNCT__
144 #define __FUNCT__ "PetscDrawAxisSetHoldLimits"
145 /*@
146     PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
147         again
148 
149     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
150 
151     Input Parameters:
152 +   axis - the axis
153 -   hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
154 
155     Level: advanced
156 
157     Notes:
158         Once this has been called with PETSC_TRUE the limits will not change if you call
159      PetscDrawAxisSetLimits() until you call this with PETSC_FALSE
160 
161 .seealso:  PetscDrawAxisSetLimits()
162 
163 @*/
164 PetscErrorCode  PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
165 {
166   PetscFunctionBegin;
167   if (!axis) PetscFunctionReturn(0);
168   axis->hold = hold;
169   PetscFunctionReturn(0);
170 }
171 
172 #undef __FUNCT__
173 #define __FUNCT__ "PetscDrawAxisDraw"
174 /*@
175     PetscDrawAxisDraw - PetscDraws an axis.
176 
177     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
178 
179     Input Parameter:
180 .   axis - Axis structure
181 
182     Level: advanced
183 
184     Note:
185     This draws the actual axis.  The limits etc have already been set.
186     By picking special routines for the ticks and labels, special
187     effects may be generated.  These routines are part of the Axis
188     structure (axis).
189 @*/
190 PetscErrorCode  PetscDrawAxisDraw(PetscDrawAxis axis)
191 {
192   int            i,ntick,numx,numy,ac = axis->ac,tc = axis->tc,cc = axis->cc,rank;
193   size_t         len;
194   PetscReal      tickloc[MAXSEGS],sep,h,w,tw,th,xl,xr,yl,yr;
195   char           *p;
196   PetscDraw      draw = axis->win;
197   PetscErrorCode ierr;
198 
199   PetscFunctionBegin;
200   if (!axis) PetscFunctionReturn(0);
201   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);CHKERRQ(ierr);
202   if (rank) PetscFunctionReturn(0);
203 
204   if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
205   /*  if ((axis->yhigh - axis->ylow) <= 1.e-5*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow))) {
206     axis->ylow  -= 1.e-5*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow));
207     axis->yhigh += 1.e-5*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow));
208    } */
209   if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}
210 
211   xl   = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh;
212   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
213   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
214   numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6;if (numx< 2) numx = 2;
215   numy = (int)(.50*(yr-yl)/th); if (numy > 6) numy = 6;if (numy< 2) numy = 2;
216   xl  -= 11*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th;
217   if (axis->xlabel) yl -= 2*th;
218   if (axis->ylabel) xl -= 2*tw;
219   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
220   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
221 
222   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr);
223   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr);
224 
225   if (axis->toplabel) {
226     ierr =  PetscStrlen(axis->toplabel,&len);CHKERRQ(ierr);
227     w    = xl + .5*(xr - xl) - .5*len*tw;
228     h    = axis->yhigh;
229     ierr = PetscDrawString(draw,w,h,cc,axis->toplabel);CHKERRQ(ierr);
230   }
231 
232   /* PetscDraw the ticks and labels */
233   if (axis->xticks) {
234     ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
235     /* PetscDraw in tick marks */
236     for (i=0; i<ntick; i++) {
237       ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr);
238     }
239     /* label ticks */
240     for (i=0; i<ntick; i++) {
241       if (axis->xlabelstr) {
242         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
243         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
244         else               sep = 0.0;
245         ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
246         ierr = PetscStrlen(p,&len);CHKERRQ(ierr);
247         w    = .5*len*tw;
248         ierr = PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);CHKERRQ(ierr);
249       }
250     }
251   }
252   if (axis->xlabel) {
253     ierr = PetscStrlen(axis->xlabel,&len);CHKERRQ(ierr);
254     w    = xl + .5*(xr - xl) - .5*len*tw;
255     h    = axis->ylow - 2.5*th;
256     ierr = PetscDrawString(draw,w,h,cc,axis->xlabel);CHKERRQ(ierr);
257   }
258   if (axis->yticks) {
259     ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr);
260     /* PetscDraw in tick marks */
261     for (i=0; i<ntick; i++) {
262       ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr);
263     }
264     /* label ticks */
265     for (i=0; i<ntick; i++) {
266       if (axis->ylabelstr) {
267         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
268         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
269         else               sep = 0.0;
270         ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
271         ierr = PetscStrlen(p,&len);CHKERRQ(ierr);
272         w    = axis->xlow - len * tw - 1.2*tw;
273         ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr);
274       }
275     }
276   }
277   if (axis->ylabel) {
278     ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr);
279     h    = yl + .5*(yr - yl) + .5*len*th;
280     w    = xl + .5*tw;
281     ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr);
282   }
283   PetscFunctionReturn(0);
284 }
285 
286 #undef __FUNCT__
287 #define __FUNCT__ "PetscStripe0"
288 /*
289     Removes all zeros but one from .0000
290 */
291 PetscErrorCode PetscStripe0(char *buf)
292 {
293   PetscErrorCode ierr;
294   size_t         n;
295   PetscBool      flg;
296   char           *str;
297 
298   PetscFunctionBegin;
299   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
300   ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr);
301   if (flg) buf[n-3] = 0;
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++) buf[i] = buf[i+1];
381   } else if (buf[0] == '-' && buf[1] == '0') {
382     for (i=1; i<n; i++) buf[i] = buf[i+1];
383   }
384   PetscFunctionReturn(0);
385 }
386 
387 #undef __FUNCT__
388 #define __FUNCT__ "PetscStripZeros"
389 /*
390      Removes the extraneous zeros in numbers like 1.10000e6
391 */
392 PetscErrorCode PetscStripZeros(char *buf)
393 {
394   PetscErrorCode ierr;
395   size_t         i,j,n;
396 
397   PetscFunctionBegin;
398   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
399   if (n<5) PetscFunctionReturn(0);
400   for (i=1; i<n-1; i++) {
401     if (buf[i] == 'e' && buf[i-1] == '0') {
402       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
403       ierr = PetscStripZeros(buf);CHKERRQ(ierr);
404       PetscFunctionReturn(0);
405     }
406   }
407   PetscFunctionReturn(0);
408 }
409 
410 #undef __FUNCT__
411 #define __FUNCT__ "PetscStripZerosPlus"
412 /*
413       Removes the plus in something like 1.1e+2 or 1.1e+02
414 */
415 PetscErrorCode PetscStripZerosPlus(char *buf)
416 {
417   PetscErrorCode ierr;
418   size_t         i,j,n;
419 
420   PetscFunctionBegin;
421   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
422   if (n<5) PetscFunctionReturn(0);
423   for (i=1; i<n-2; i++) {
424     if (buf[i] == '+') {
425       if (buf[i+1] == '0') {
426         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
427         PetscFunctionReturn(0);
428       } else {
429         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
430         PetscFunctionReturn(0);
431       }
432     } else if (buf[i] == '-') {
433       if (buf[i+1] == '0') {
434         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
435         PetscFunctionReturn(0);
436       }
437     }
438   }
439   PetscFunctionReturn(0);
440 }
441 
442 
443 
444 
445 
446 
447 
448