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