Actual source code: axisc.c
petsc-3.6.4 2016-04-12
1: #include <../src/sys/classes/draw/utils/axisimpl.h> /*I "petscdraw.h" I*/
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(PetscObjectComm((PetscObject)obj),(PetscDraw*)axis);
35: (*axis)->win = draw;
36: return(0);
37: }
38: PetscHeaderCreate(ad,PETSC_DRAWAXIS_CLASSID,"PetscDrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)draw),PetscDrawAxisDestroy,NULL);
39: PetscLogObjectParent((PetscObject)draw,(PetscObject)ad);
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;
53: *axis = ad;
54: return(0);
55: }
59: /*@
60: PetscDrawAxisDestroy - Frees the space used by an axis structure.
62: Collective over PetscDrawAxis
64: Input Parameters:
65: . axis - the axis context
67: Level: advanced
69: @*/
70: PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis)
71: {
75: if (!*axis) return(0);
76: if (--((PetscObject)(*axis))->refct > 0) return(0);
78: PetscFree((*axis)->toplabel);
79: PetscFree((*axis)->xlabel);
80: PetscFree((*axis)->ylabel);
81: PetscHeaderDestroy(axis);
82: return(0);
83: }
87: /*@
88: PetscDrawAxisSetColors - Sets the colors to be used for the axis,
89: tickmarks, and text.
91: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
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
99: Level: advanced
101: @*/
102: PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
103: {
105: if (!axis) return(0);
106: axis->ac = ac; axis->tc = tc; axis->cc = cc;
107: return(0);
108: }
112: /*@C
113: PetscDrawAxisSetLabels - Sets the x and y axis labels.
115: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
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
122: Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
123: There should be no newlines in the arguments
125: Level: advanced
127: @*/
128: PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
129: {
133: if (!axis) return(0);
134: PetscFree(axis->xlabel);
135: PetscFree(axis->ylabel);
136: PetscFree(axis->toplabel);
137: PetscStrallocpy(xlabel,&axis->xlabel);
138: PetscStrallocpy(ylabel,&axis->ylabel);
139: PetscStrallocpy(top,&axis->toplabel);
140: return(0);
141: }
145: /*@
146: PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called
147: again
149: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
151: Input Parameters:
152: + axis - the axis
153: - hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
155: Level: advanced
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
161: .seealso: PetscDrawAxisSetLimits()
163: @*/
164: PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
165: {
167: if (!axis) return(0);
168: axis->hold = hold;
169: return(0);
170: }
174: /*@
175: PetscDrawAxisDraw - PetscDraws an axis.
177: Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)
179: Input Parameter:
180: . axis - Axis structure
182: Level: advanced
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;
200: if (!axis) return(0);
201: MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);
202: if (rank) return(0);
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;}
211: xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh;
212: PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
213: PetscDrawStringGetSize(draw,&tw,&th);
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: PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
220: PetscDrawStringGetSize(draw,&tw,&th);
222: PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);
223: PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);
225: if (axis->toplabel) {
226: h = axis->yhigh;
227: PetscDrawStringCentered(draw,.5*(xl+xr),axis->yhigh,cc,axis->toplabel);
228: }
230: /* PetscDraw the ticks and labels */
231: if (axis->xticks) {
232: (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);
233: /* PetscDraw in tick marks */
234: for (i=0; i<ntick; i++) {
235: PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);
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: (*axis->xlabelstr)(tickloc[i],sep,&p);
244: PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.2*th,cc,p);
245: }
246: }
247: }
248: if (axis->xlabel) {
249: h = axis->ylow - 2.5*th;
250: PetscDrawStringCentered(draw,.5*(xl + xr),h,cc,axis->xlabel);
251: }
252: if (axis->yticks) {
253: (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);
254: /* PetscDraw in tick marks */
255: for (i=0; i<ntick; i++) {
256: PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);
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: (*axis->xlabelstr)(tickloc[i],sep,&p);
265: PetscStrlen(p,&len);
266: w = axis->xlow - len * tw - 1.2*tw;
267: PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);
268: }
269: }
270: }
271: if (axis->ylabel) {
272: PetscStrlen(axis->ylabel,&len);
273: h = yl + .5*(yr - yl) + .5*len*th;
274: w = xl + 1.5*tw;
275: PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);
276: }
277: return(0);
278: }
282: /*
283: Removes all zeros but one from .0000
284: */
285: PetscErrorCode PetscStripe0(char *buf)
286: {
288: size_t n;
289: PetscBool flg;
290: char *str;
293: PetscStrlen(buf,&n);
294: PetscStrendswith(buf,"e00",&flg);
295: if (flg) buf[n-3] = 0;
296: PetscStrstr(buf,"e0",&str);
297: if (str) {
298: buf[n-2] = buf[n-1];
299: buf[n-1] = 0;
300: }
301: PetscStrstr(buf,"e-0",&str);
302: if (str) {
303: buf[n-2] = buf[n-1];
304: buf[n-1] = 0;
305: }
306: return(0);
307: }
311: /*
312: Removes all zeros but one from .0000
313: */
314: PetscErrorCode PetscStripAllZeros(char *buf)
315: {
317: size_t i,n;
320: PetscStrlen(buf,&n);
321: if (buf[0] != '.') return(0);
322: for (i=1; i<n; i++) {
323: if (buf[i] != '0') return(0);
324: }
325: buf[0] = '0';
326: buf[1] = 0;
327: return(0);
328: }
332: /*
333: Removes trailing zeros
334: */
335: PetscErrorCode PetscStripTrailingZeros(char *buf)
336: {
338: char *found;
339: size_t i,n,m = PETSC_MAX_INT;
342: /* if there is an e in string DO NOT strip trailing zeros */
343: PetscStrchr(buf,'e',&found);
344: if (found) return(0);
346: PetscStrlen(buf,&n);
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) return(0);
353: /* start at right end of string removing 0s */
354: for (i=n-1; i>m; i++) {
355: if (buf[i] != '0') return(0);
356: buf[i] = 0;
357: }
358: return(0);
359: }
363: /*
364: Removes leading 0 from 0.22 or -0.22
365: */
366: PetscErrorCode PetscStripInitialZero(char *buf)
367: {
369: size_t i,n;
372: PetscStrlen(buf,&n);
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: return(0);
379: }
383: /*
384: Removes the extraneous zeros in numbers like 1.10000e6
385: */
386: PetscErrorCode PetscStripZeros(char *buf)
387: {
389: size_t i,j,n;
392: PetscStrlen(buf,&n);
393: if (n<5) return(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: PetscStripZeros(buf);
398: return(0);
399: }
400: }
401: return(0);
402: }
406: /*
407: Removes the plus in something like 1.1e+2 or 1.1e+02
408: */
409: PetscErrorCode PetscStripZerosPlus(char *buf)
410: {
412: size_t i,j,n;
415: PetscStrlen(buf,&n);
416: if (n<5) return(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: return(0);
422: } else {
423: for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
424: return(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: return(0);
430: }
431: }
432: }
433: return(0);
434: }