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