Actual source code: axisc.c
petsc-3.3-p7 2013-05-11
1: #include <../src/sys/draw/utils/axisimpl.h>
3: PetscClassId PETSC_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: PetscObjectTypeCompare(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_PetscDrawAxis,int,PETSC_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: PetscFree(axis->xlabel);
133: PetscFree(axis->ylabel);
134: PetscFree(axis->toplabel);
135: PetscStrallocpy(xlabel,&axis->xlabel);
136: PetscStrallocpy(ylabel,&axis->ylabel);
137: PetscStrallocpy(top,&axis->toplabel);
138: return(0);
139: }
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)
149: Input Parameters:
150: + axis - the axis
151: - hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
153: Level: advanced
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()
161: @*/
162: PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
163: {
165: if (!axis) return(0);
166: axis->hold = hold;
167: return(0);
168: }
172: /*@
173: PetscDrawAxisDraw - PetscDraws an axis.
175: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
177: Input Parameter:
178: . axis - Axis structure
180: Level: advanced
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;
198: if (!axis) return(0);
199: MPI_Comm_rank(((PetscObject)axis)->comm,&rank);
200: if (rank) return(0);
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: PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
206: PetscDrawStringGetSize(draw,&tw,&th);
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: PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
213: PetscDrawStringGetSize(draw,&tw,&th);
215: PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);
216: PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);
218: if (axis->toplabel) {
219: PetscStrlen(axis->toplabel,&len);
220: w = xl + .5*(xr - xl) - .5*len*tw;
221: h = axis->yhigh;
222: PetscDrawString(draw,w,h,cc,axis->toplabel);
223: }
225: /* PetscDraw the ticks and labels */
226: if (axis->xticks) {
227: (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);
228: /* PetscDraw in tick marks */
229: for (i=0; i<ntick; i++) {
230: PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);
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: (*axis->xlabelstr)(tickloc[i],sep,&p);
239: PetscStrlen(p,&len);
240: w = .5*len*tw;
241: PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);
242: }
243: }
244: }
245: if (axis->xlabel) {
246: PetscStrlen(axis->xlabel,&len);
247: w = xl + .5*(xr - xl) - .5*len*tw;
248: h = axis->ylow - 2.5*th;
249: PetscDrawString(draw,w,h,cc,axis->xlabel);
250: }
251: if (axis->yticks) {
252: (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);
253: /* PetscDraw in tick marks */
254: for (i=0; i<ntick; i++) {
255: PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);
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: (*axis->xlabelstr)(tickloc[i],sep,&p);
264: PetscStrlen(p,&len);
265: w = axis->xlow - len * tw - 1.2*tw;
266: PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);
267: }
268: }
269: }
270: if (axis->ylabel) {
271: PetscStrlen(axis->ylabel,&len);
272: h = yl + .5*(yr - yl) + .5*len*th;
273: w = xl + .5*tw;
274: PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);
275: }
276: return(0);
277: }
281: /*
282: Removes all zeros but one from .0000
283: */
284: PetscErrorCode PetscStripAllZeros(char *buf)
285: {
287: size_t i,n;
290: PetscStrlen(buf,&n);
291: if (buf[0] != '.') return(0);
292: for (i=1; i<n; i++) {
293: if (buf[i] != '0') return(0);
294: }
295: buf[0] = '0';
296: buf[1] = 0;
297: return(0);
298: }
302: /*
303: Removes trailing zeros
304: */
305: PetscErrorCode PetscStripTrailingZeros(char *buf)
306: {
308: char *found;
309: size_t i,n,m = PETSC_MAX_INT;
312: /* if there is an e in string DO NOT strip trailing zeros */
313: PetscStrchr(buf,'e',&found);
314: if (found) return(0);
316: PetscStrlen(buf,&n);
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) return(0);
323: /* start at right end of string removing 0s */
324: for (i=n-1; i>m; i++) {
325: if (buf[i] != '0') return(0);
326: buf[i] = 0;
327: }
328: return(0);
329: }
333: /*
334: Removes leading 0 from 0.22 or -0.22
335: */
336: PetscErrorCode PetscStripInitialZero(char *buf)
337: {
339: size_t i,n;
342: PetscStrlen(buf,&n);
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: return(0);
353: }
357: /*
358: Removes the extraneous zeros in numbers like 1.10000e6
359: */
360: PetscErrorCode PetscStripZeros(char *buf)
361: {
363: size_t i,j,n;
366: PetscStrlen(buf,&n);
367: if (n<5) return(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: PetscStripZeros(buf);
372: return(0);
373: }
374: }
375: return(0);
376: }
380: /*
381: Removes the plus in something like 1.1e+2
382: */
383: PetscErrorCode PetscStripZerosPlus(char *buf)
384: {
386: size_t i,j,n;
389: PetscStrlen(buf,&n);
390: if (n<5) return(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+1; j++) buf[j-1] = buf[j+1];
395: return(0);
396: } else {
397: for (j=i+1; j<n+1; j++) buf[j] = buf[j+1];
398: return(0);
399: }
400: } else if (buf[i] == '-') {
401: if (buf[i+1] == '0') {
402: for (j=i+1; j<n+1; j++) buf[j] = buf[j+1];
403: return(0);
404: }
405: }
406: }
407: return(0);
408: }