Actual source code: axisc.c

petsc-3.4.5 2014-06-29
  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,_p_PetscDrawAxis,int,PETSC_DRAWAXIS_CLASSID,"PetscDrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)obj),PetscDrawAxisDestroy,0);
 39:   PetscLogObjectParent(draw,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:      PetscStrlen(axis->toplabel,&len);
227:     w    = xl + .5*(xr - xl) - .5*len*tw;
228:     h    = axis->yhigh;
229:     PetscDrawString(draw,w,h,cc,axis->toplabel);
230:   }

232:   /* PetscDraw the ticks and labels */
233:   if (axis->xticks) {
234:     (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);
235:     /* PetscDraw in tick marks */
236:     for (i=0; i<ntick; i++) {
237:       PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);
238:     }
239:     /* label ticks */
240:     for (i=0; i<ntick; i++) {
241:       if (axis->xlabelstr) {
242:         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
243:         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
244:         else               sep = 0.0;
245:         (*axis->xlabelstr)(tickloc[i],sep,&p);
246:         PetscStrlen(p,&len);
247:         w    = .5*len*tw;
248:         PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);
249:       }
250:     }
251:   }
252:   if (axis->xlabel) {
253:     PetscStrlen(axis->xlabel,&len);
254:     w    = xl + .5*(xr - xl) - .5*len*tw;
255:     h    = axis->ylow - 2.5*th;
256:     PetscDrawString(draw,w,h,cc,axis->xlabel);
257:   }
258:   if (axis->yticks) {
259:     (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);
260:     /* PetscDraw in tick marks */
261:     for (i=0; i<ntick; i++) {
262:       PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);
263:     }
264:     /* label ticks */
265:     for (i=0; i<ntick; i++) {
266:       if (axis->ylabelstr) {
267:         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
268:         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
269:         else               sep = 0.0;
270:         (*axis->xlabelstr)(tickloc[i],sep,&p);
271:         PetscStrlen(p,&len);
272:         w    = axis->xlow - len * tw - 1.2*tw;
273:         PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);
274:       }
275:     }
276:   }
277:   if (axis->ylabel) {
278:     PetscStrlen(axis->ylabel,&len);
279:     h    = yl + .5*(yr - yl) + .5*len*th;
280:     w    = xl + 1.5*tw;
281:     PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);
282:   }
283:   return(0);
284: }

288: /*
289:     Removes all zeros but one from .0000
290: */
291: PetscErrorCode PetscStripe0(char *buf)
292: {
294:   size_t         n;
295:   PetscBool      flg;
296:   char           *str;

299:   PetscStrlen(buf,&n);
300:   PetscStrendswith(buf,"e00",&flg);
301:   if (flg) buf[n-3] = 0;
302:   PetscStrstr(buf,"e0",&str);
303:   if (str) {
304:     buf[n-2] = buf[n-1];
305:     buf[n-1] = 0;
306:   }
307:   PetscStrstr(buf,"e-0",&str);
308:   if (str) {
309:     buf[n-2] = buf[n-1];
310:     buf[n-1] = 0;
311:   }
312:   return(0);
313: }

317: /*
318:     Removes all zeros but one from .0000
319: */
320: PetscErrorCode PetscStripAllZeros(char *buf)
321: {
323:   size_t         i,n;

326:   PetscStrlen(buf,&n);
327:   if (buf[0] != '.') return(0);
328:   for (i=1; i<n; i++) {
329:     if (buf[i] != '0') return(0);
330:   }
331:   buf[0] = '0';
332:   buf[1] = 0;
333:   return(0);
334: }

338: /*
339:     Removes trailing zeros
340: */
341: PetscErrorCode PetscStripTrailingZeros(char *buf)
342: {
344:   char           *found;
345:   size_t         i,n,m = PETSC_MAX_INT;

348:   /* if there is an e in string DO NOT strip trailing zeros */
349:   PetscStrchr(buf,'e',&found);
350:   if (found) return(0);

352:   PetscStrlen(buf,&n);
353:   /* locate decimal point */
354:   for (i=0; i<n; i++) {
355:     if (buf[i] == '.') {m = i; break;}
356:   }
357:   /* if not decimal point then no zeros to remove */
358:   if (m == PETSC_MAX_INT) return(0);
359:   /* start at right end of string removing 0s */
360:   for (i=n-1; i>m; i++) {
361:     if (buf[i] != '0') return(0);
362:     buf[i] = 0;
363:   }
364:   return(0);
365: }

369: /*
370:     Removes leading 0 from 0.22 or -0.22
371: */
372: PetscErrorCode PetscStripInitialZero(char *buf)
373: {
375:   size_t         i,n;

378:   PetscStrlen(buf,&n);
379:   if (buf[0] == '0') {
380:     for (i=0; i<n; i++) buf[i] = buf[i+1];
381:   } else if (buf[0] == '-' && buf[1] == '0') {
382:     for (i=1; i<n; i++) buf[i] = buf[i+1];
383:   }
384:   return(0);
385: }

389: /*
390:      Removes the extraneous zeros in numbers like 1.10000e6
391: */
392: PetscErrorCode PetscStripZeros(char *buf)
393: {
395:   size_t         i,j,n;

398:   PetscStrlen(buf,&n);
399:   if (n<5) return(0);
400:   for (i=1; i<n-1; i++) {
401:     if (buf[i] == 'e' && buf[i-1] == '0') {
402:       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
403:       PetscStripZeros(buf);
404:       return(0);
405:     }
406:   }
407:   return(0);
408: }

412: /*
413:       Removes the plus in something like 1.1e+2 or 1.1e+02
414: */
415: PetscErrorCode PetscStripZerosPlus(char *buf)
416: {
418:   size_t         i,j,n;

421:   PetscStrlen(buf,&n);
422:   if (n<5) return(0);
423:   for (i=1; i<n-2; i++) {
424:     if (buf[i] == '+') {
425:       if (buf[i+1] == '0') {
426:         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
427:         return(0);
428:       } else {
429:         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
430:         return(0);
431:       }
432:     } else if (buf[i] == '-') {
433:       if (buf[i+1] == '0') {
434:         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
435:         return(0);
436:       }
437:     }
438:   }
439:   return(0);
440: }