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