Actual source code: axisc.c
1: #include <../src/sys/draw/utils/axisimpl.h>
3: PetscClassId DRAWAXIS_CLASSID = 0;
7: /*@
8: PetscDrawAxisCreate - Generate the axis data structure.
10: Collective over PetscDraw
12: Input Parameters:
13: . win - PetscDraw object where axis to to be made
15: Ouput Parameters:
16: . axis - the axis datastructure
18: Level: advanced
20: @*/
21: PetscErrorCode PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis *axis)
22: {
23: PetscDrawAxis ad;
24: PetscObject obj = (PetscObject)draw;
26: PetscBool isnull;
31: PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
32: if (isnull) {
33: PetscDrawOpenNull(((PetscObject)obj)->comm,(PetscDraw*)axis);
34: (*axis)->win = draw;
35: return(0);
36: }
37: PetscHeaderCreate(ad,_p_DrawAxis,int,DRAWAXIS_CLASSID,0,"PetscDrawAxis","Draw Axis","Draw",((PetscObject)obj)->comm,PetscDrawAxisDestroy,0);
38: PetscLogObjectParent(draw,ad);
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;
51: *axis = ad;
52: return(0);
53: }
57: /*@
58: PetscDrawAxisDestroy - Frees the space used by an axis structure.
60: Collective over PetscDrawAxis
62: Input Parameters:
63: . axis - the axis context
64:
65: Level: advanced
67: @*/
68: PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis)
69: {
73: if (!*axis) return(0);
74: if (--((PetscObject)(*axis))->refct > 0) return(0);
76: PetscFree((*axis)->toplabel);
77: PetscFree((*axis)->xlabel);
78: PetscFree((*axis)->ylabel);
79: PetscHeaderDestroy(axis);
80: return(0);
81: }
85: /*@
86: PetscDrawAxisSetColors - Sets the colors to be used for the axis,
87: tickmarks, and text.
89: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
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
97: Level: advanced
99: @*/
100: PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
101: {
103: if (!axis) return(0);
104: axis->ac = ac; axis->tc = tc; axis->cc = cc;
105: return(0);
106: }
110: /*@C
111: PetscDrawAxisSetLabels - Sets the x and y axis labels.
113: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
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
120: Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
121: There should be no newlines in the arguments
123: Level: advanced
125: @*/
126: PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
127: {
131: if (!axis) return(0);
132: PetscStrallocpy(xlabel,&axis->xlabel);
133: PetscStrallocpy(ylabel,&axis->ylabel);
134: PetscStrallocpy(top,&axis->toplabel);
135: return(0);
136: }
140: /*@
141: PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called
142: again
143:
144: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
146: Input Parameters:
147: + axis - the axis
148: - hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
150: Level: advanced
152: Notes:
153: Once this has been called with PETSC_TRUE the limits will not change if you call
154: PetscDrawAxisSetLimits() until you call this with PETSC_FALSE
155:
156: .seealso: PetscDrawAxisSetLimits()
158: @*/
159: PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
160: {
162: if (!axis) return(0);
163: axis->hold = hold;
164: return(0);
165: }
169: /*@
170: PetscDrawAxisDraw - PetscDraws an axis.
172: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
174: Input Parameter:
175: . axis - Axis structure
177: Level: advanced
179: Note:
180: This draws the actual axis. The limits etc have already been set.
181: By picking special routines for the ticks and labels, special
182: effects may be generated. These routines are part of the Axis
183: structure (axis).
184: @*/
185: PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis)
186: {
187: int i,ntick,numx,numy,ac = axis->ac,tc = axis->tc,cc = axis->cc,rank;
188: size_t len;
189: PetscReal tickloc[MAXSEGS],sep,h,w,tw,th,xl,xr,yl,yr;
190: char *p;
191: PetscDraw draw = axis->win;
195: if (!axis) return(0);
196: MPI_Comm_rank(((PetscObject)axis)->comm,&rank);
197: if (rank) return(0);
199: if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
200: if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}
201: xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh;
202: PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
203: PetscDrawStringGetSize(draw,&tw,&th);
204: numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6; if (numx< 2) numx = 2;
205: numy = (int)(.5*(yr-yl)/th); if (numy > 6) numy = 6; if (numy< 2) numy = 2;
206: xl -= 8*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th;
207: if (axis->xlabel) yl -= 2*th;
208: if (axis->ylabel) xl -= 2*tw;
209: PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
210: PetscDrawStringGetSize(draw,&tw,&th);
212: PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);
213: PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);
215: if (axis->toplabel) {
216: PetscStrlen(axis->toplabel,&len);
217: w = xl + .5*(xr - xl) - .5*len*tw;
218: h = axis->yhigh;
219: PetscDrawString(draw,w,h,cc,axis->toplabel);
220: }
222: /* PetscDraw the ticks and labels */
223: if (axis->xticks) {
224: (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);
225: /* PetscDraw in tick marks */
226: for (i=0; i<ntick; i++) {
227: PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);
228: }
229: /* label ticks */
230: for (i=0; i<ntick; i++) {
231: if (axis->xlabelstr) {
232: if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
233: else if (i > 0) sep = tickloc[i] - tickloc[i-1];
234: else sep = 0.0;
235: (*axis->xlabelstr)(tickloc[i],sep,&p);
236: PetscStrlen(p,&len);
237: w = .5*len*tw;
238: PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);
239: }
240: }
241: }
242: if (axis->xlabel) {
243: PetscStrlen(axis->xlabel,&len);
244: w = xl + .5*(xr - xl) - .5*len*tw;
245: h = axis->ylow - 2.5*th;
246: PetscDrawString(draw,w,h,cc,axis->xlabel);
247: }
248: if (axis->yticks) {
249: (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);
250: /* PetscDraw in tick marks */
251: for (i=0; i<ntick; i++) {
252: PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);
253: }
254: /* label ticks */
255: for (i=0; i<ntick; i++) {
256: if (axis->ylabelstr) {
257: if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
258: else if (i > 0) sep = tickloc[i] - tickloc[i-1];
259: else sep = 0.0;
260: (*axis->xlabelstr)(tickloc[i],sep,&p);
261: PetscStrlen(p,&len);
262: w = axis->xlow - len * tw - 1.2*tw;
263: PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);
264: }
265: }
266: }
267: if (axis->ylabel) {
268: PetscStrlen(axis->ylabel,&len);
269: h = yl + .5*(yr - yl) + .5*len*th;
270: w = xl + .5*tw;
271: PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);
272: }
273: return(0);
274: }
278: /*
279: Removes all zeros but one from .0000
280: */
281: PetscErrorCode PetscStripAllZeros(char *buf)
282: {
284: size_t i,n;
287: PetscStrlen(buf,&n);
288: if (buf[0] != '.') return(0);
289: for (i=1; i<n; i++) {
290: if (buf[i] != '0') return(0);
291: }
292: buf[0] = '0';
293: buf[1] = 0;
294: return(0);
295: }
299: /*
300: Removes trailing zeros
301: */
302: PetscErrorCode PetscStripTrailingZeros(char *buf)
303: {
305: char *found;
306: size_t i,n,m = PETSC_MAX_INT;
309: /* if there is an e in string DO NOT strip trailing zeros */
310: PetscStrchr(buf,'e',&found);
311: if (found) return(0);
313: PetscStrlen(buf,&n);
314: /* locate decimal point */
315: for (i=0; i<n; i++) {
316: if (buf[i] == '.') {m = i; break;}
317: }
318: /* if not decimal point then no zeros to remove */
319: if (m == PETSC_MAX_INT) return(0);
320: /* start at right end of string removing 0s */
321: for (i=n-1; i>m; i++) {
322: if (buf[i] != '0') return(0);
323: buf[i] = 0;
324: }
325: return(0);
326: }
330: /*
331: Removes leading 0 from 0.22 or -0.22
332: */
333: PetscErrorCode PetscStripInitialZero(char *buf)
334: {
336: size_t i,n;
339: PetscStrlen(buf,&n);
340: if (buf[0] == '0') {
341: for (i=0; i<n; i++) {
342: buf[i] = buf[i+1];
343: }
344: } else if (buf[0] == '-' && buf[1] == '0') {
345: for (i=1; i<n; i++) {
346: buf[i] = buf[i+1];
347: }
348: }
349: return(0);
350: }
354: /*
355: Removes the extraneous zeros in numbers like 1.10000e6
356: */
357: PetscErrorCode PetscStripZeros(char *buf)
358: {
360: size_t i,j,n;
363: PetscStrlen(buf,&n);
364: if (n<5) return(0);
365: for (i=1; i<n-1; i++) {
366: if (buf[i] == 'e' && buf[i-1] == '0') {
367: for (j=i; j<n+1; j++) buf[j-1] = buf[j];
368: PetscStripZeros(buf);
369: return(0);
370: }
371: }
372: return(0);
373: }
377: /*
378: Removes the plus in something like 1.1e+2
379: */
380: PetscErrorCode PetscStripZerosPlus(char *buf)
381: {
383: size_t i,j,n;
386: PetscStrlen(buf,&n);
387: if (n<5) return(0);
388: for (i=1; i<n-2; i++) {
389: if (buf[i] == '+') {
390: if (buf[i+1] == '0') {
391: for (j=i+1; j<n+1; j++) buf[j-1] = buf[j+1];
392: return(0);
393: } else {
394: for (j=i+1; j<n+1; j++) buf[j] = buf[j+1];
395: return(0);
396: }
397: } else if (buf[i] == '-') {
398: if (buf[i+1] == '0') {
399: for (j=i+1; j<n+1; j++) buf[j] = buf[j+1];
400: return(0);
401: }
402: }
403: }
404: return(0);
405: }