Actual source code: axisc.c

petsc-3.6.1 2015-07-22
Report Typos and Errors
  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: }