Actual source code: axisc.c

petsc-3.7.7 2017-09-25
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 on 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;


 30:   PetscHeaderCreate(ad,PETSC_DRAWAXIS_CLASSID,"DrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)draw),PetscDrawAxisDestroy,NULL);
 31:   PetscLogObjectParent((PetscObject)draw,(PetscObject)ad);

 33:   PetscObjectReference((PetscObject)draw);
 34:   ad->win = draw;

 36:   ad->xticks    = PetscADefTicks;
 37:   ad->yticks    = PetscADefTicks;
 38:   ad->xlabelstr = PetscADefLabel;
 39:   ad->ylabelstr = PetscADefLabel;
 40:   ad->ac        = PETSC_DRAW_BLACK;
 41:   ad->tc        = PETSC_DRAW_BLACK;
 42:   ad->cc        = PETSC_DRAW_BLACK;
 43:   ad->xlabel    = NULL;
 44:   ad->ylabel    = NULL;
 45:   ad->toplabel  = NULL;

 47:   *axis = ad;
 48:   return(0);
 49: }

 53: /*@
 54:     PetscDrawAxisDestroy - Frees the space used by an axis structure.

 56:     Collective on PetscDrawAxis

 58:     Input Parameters:
 59: .   axis - the axis context

 61:     Level: advanced

 63: @*/
 64: PetscErrorCode  PetscDrawAxisDestroy(PetscDrawAxis *axis)
 65: {

 69:   if (!*axis) return(0);
 71:   if (--((PetscObject)(*axis))->refct > 0) {*axis = NULL; return(0);}

 73:   PetscFree((*axis)->toplabel);
 74:   PetscFree((*axis)->xlabel);
 75:   PetscFree((*axis)->ylabel);
 76:   PetscDrawDestroy(&(*axis)->win);
 77:   PetscHeaderDestroy(axis);
 78:   return(0);
 79: }

 83: /*@
 84:     PetscDrawAxisSetColors -  Sets the colors to be used for the axis,
 85:                          tickmarks, and text.

 87:     Logically Collective on PetscDrawAxis

 89:     Input Parameters:
 90: +   axis - the axis
 91: .   ac - the color of the axis lines
 92: .   tc - the color of the tick marks
 93: -   cc - the color of the text strings

 95:     Level: advanced

 97: @*/
 98: PetscErrorCode  PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
 99: {
105:   axis->ac = ac; axis->tc = tc; axis->cc = cc;
106:   return(0);
107: }

111: /*@C
112:     PetscDrawAxisSetLabels -  Sets the x and y axis labels.

114:     Logically Collective on PetscDrawAxis

116:     Input Parameters:
117: +   axis - the axis
118: .   top - the label at the top of the image
119: -   xlabel,ylabel - the labes for the x and y axis

121:     Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
122:            There should be no newlines in the arguments

124:     Level: advanced

126: @*/
127: PetscErrorCode  PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
128: {

133:   PetscFree(axis->xlabel);
134:   PetscFree(axis->ylabel);
135:   PetscFree(axis->toplabel);
136:   PetscStrallocpy(xlabel,&axis->xlabel);
137:   PetscStrallocpy(ylabel,&axis->ylabel);
138:   PetscStrallocpy(top,&axis->toplabel);
139:   return(0);
140: }

144: /*@
145:     PetscDrawAxisSetLimits -  Sets the limits (in user coords) of the axis

147:     Logically Collective on PetscDrawAxis

149:     Input Parameters:
150: +   axis - the axis
151: .   xmin,xmax - limits in x
152: -   ymin,ymax - limits in y

154:     Options Database:
155: .   -drawaxis_hold - hold the initial set of axis limits for future plotting

157:     Level: advanced

159: .seealso:  PetscDrawAxisSetHoldLimits()

161: @*/
162: PetscErrorCode  PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)
163: {

168:   if (axis->hold) return(0);
169:   axis->xlow = xmin;
170:   axis->xhigh= xmax;
171:   axis->ylow = ymin;
172:   axis->yhigh= ymax;
173:   PetscOptionsHasName(((PetscObject)axis)->options,((PetscObject)axis)->prefix,"-drawaxis_hold",&axis->hold);
174:   return(0);
175: }

179: /*@
180:     PetscDrawAxisGetLimits -  Gets the limits (in user coords) of the axis

182:     Not Collective

184:     Input Parameters:
185: +   axis - the axis
186: .   xmin,xmax - limits in x
187: -   ymin,ymax - limits in y

189:     Level: advanced

191: .seealso:  PetscDrawAxisSetLimits()

193: @*/
194: PetscErrorCode  PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax)
195: {
198:   *xmin = axis->xlow;
199:   *xmax = axis->xhigh;
200:   *ymin = axis->ylow;
201:   *ymax = axis->yhigh;
202:   return(0);
203: }

207: /*@
208:     PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
209:         again

211:     Logically Collective on PetscDrawAxis

213:     Input Parameters:
214: +   axis - the axis
215: -   hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed

217:     Level: advanced

219:     Notes:
220:         Once this has been called with PETSC_TRUE the limits will not change if you call
221:      PetscDrawAxisSetLimits() until you call this with PETSC_FALSE

223: .seealso:  PetscDrawAxisSetLimits()

225: @*/
226: PetscErrorCode  PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
227: {
231:   axis->hold = hold;
232:   return(0);
233: }

237: /*@
238:     PetscDrawAxisDraw - PetscDraws an axis.

240:     Collective on PetscDrawAxis

242:     Input Parameter:
243: .   axis - Axis structure

245:     Level: advanced

247:     Note:
248:     This draws the actual axis.  The limits etc have already been set.
249:     By picking special routines for the ticks and labels, special
250:     effects may be generated.  These routines are part of the Axis
251:     structure (axis).
252: @*/
253: PetscErrorCode  PetscDrawAxisDraw(PetscDrawAxis axis)
254: {
255:   int            i,ntick,numx,numy,ac,tc,cc;
256:   PetscMPIInt    rank;
257:   size_t         len,ytlen=0;
258:   PetscReal      coors[4],tickloc[MAXSEGS],sep,tw,th;
259:   PetscReal      xl,xr,yl,yr,dxl=0,dyl=0,dxr=0,dyr=0;
260:   char           *p;
261:   PetscDraw      draw;
262:   PetscBool      isnull;

267:   PetscDrawIsNull(axis->win,&isnull);
268:   if (isnull) return(0);
269:   MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);

271:   draw = axis->win;

273:   ac = axis->ac; tc = axis->tc; cc = axis->cc;
274:   if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
275:   if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}

277:   PetscDrawCollectiveBegin(draw);
278:   if (rank) goto finally;

280:   /* get cannonical string size */
281:   PetscDrawSetCoordinates(draw,0,0,1,1);
282:   PetscDrawStringGetSize(draw,&tw,&th);
283:   /* lower spacing */
284:   if (axis->xlabelstr) dyl += 1.5*th;
285:   if (axis->xlabel)    dyl += 1.5*th;
286:   /* left spacing */
287:   if (axis->ylabelstr) dxl += 7.5*tw;
288:   if (axis->ylabel)    dxl += 2.0*tw;
289:   /* right and top spacing */
290:   if (axis->xlabelstr) dxr = 2.5*tw;
291:   if (axis->ylabelstr) dyr = 0.5*th;
292:   if (axis->toplabel)  dyr = 1.5*th;
293:   /* extra spacing */
294:   dxl += 0.7*tw; dxr += 0.5*tw;
295:   dyl += 0.2*th; dyr += 0.2*th;
296:   /* determine coordinates */
297:   xl = (dxl*axis->xhigh + dxr*axis->xlow - axis->xlow)  / (dxl + dxr - 1);
298:   xr = (dxl*axis->xhigh + dxr*axis->xlow - axis->xhigh) / (dxl + dxr - 1);
299:   yl = (dyl*axis->yhigh + dyr*axis->ylow - axis->ylow)  / (dyl + dyr - 1);
300:   yr = (dyl*axis->yhigh + dyr*axis->ylow - axis->yhigh) / (dyl + dyr - 1);
301:   PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
302:   PetscDrawStringGetSize(draw,&tw,&th);

304:   /* PetscDraw the axis lines */
305:   PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);
306:   PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);
307:   PetscDrawLine(draw,axis->xlow,axis->yhigh,axis->xhigh,axis->yhigh,ac);
308:   PetscDrawLine(draw,axis->xhigh,axis->ylow,axis->xhigh,axis->yhigh,ac);

310:   /* PetscDraw the top label */
311:   if (axis->toplabel) {
312:     PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->yhigh + 0.5*th;
313:     PetscDrawStringCentered(draw,x,y,cc,axis->toplabel);
314:   }

316:   /* PetscDraw the X ticks and labels */
317:   if (axis->xticks) {
318:     numx = (int)(.15*(axis->xhigh-axis->xlow)/tw); numx = PetscClipInterval(numx,2,6);
319:     (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);
320:     /* PetscDraw in tick marks */
321:     for (i=0; i<ntick; i++) {
322:       PetscDrawLine(draw,tickloc[i],axis->ylow,tickloc[i],axis->ylow+.5*th,tc);
323:       PetscDrawLine(draw,tickloc[i],axis->yhigh,tickloc[i],axis->yhigh-.5*th,tc);
324:     }
325:     /* label ticks */
326:     if (axis->xlabelstr) {
327:       for (i=0; i<ntick; i++) {
328:         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
329:         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
330:         else               sep = 0.0;
331:         (*axis->xlabelstr)(tickloc[i],sep,&p);
332:         PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.5*th,cc,p);
333:       }
334:     }
335:   }
336:   if (axis->xlabel) {
337:     PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->ylow - 1.5*th;
338:     if (axis->xlabelstr) y -= 1.5*th;
339:     PetscDrawStringCentered(draw,x,y,cc,axis->xlabel);
340:   }

342:   /* PetscDraw the Y ticks and labels */
343:   if (axis->yticks) {
344:     numy = (int)(.50*(axis->yhigh-axis->ylow)/th); numy = PetscClipInterval(numy,2,6);
345:     (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);
346:     /* PetscDraw in tick marks */
347:     for (i=0; i<ntick; i++) {
348:       PetscDrawLine(draw,axis->xlow,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);
349:       PetscDrawLine(draw,axis->xhigh,tickloc[i],axis->xhigh-.5*tw,tickloc[i],tc);
350:     }
351:     /* label ticks */
352:     if (axis->ylabelstr) {
353:       for (i=0; i<ntick; i++) {
354:         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
355:         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
356:         else               sep = 0.0;
357:         (*axis->ylabelstr)(tickloc[i],sep,&p);
358:         PetscStrlen(p,&len); ytlen = PetscMax(ytlen,len);
359:         PetscDrawString(draw,axis->xlow-(len+.5)*tw,tickloc[i]-.5*th,cc,p);
360:       }
361:     }
362:   }
363:   if (axis->ylabel) {
364:     PetscReal x = axis->xlow - 2.0*tw, y = (axis->ylow + axis->yhigh)/2;
365:     if (axis->ylabelstr) x -= (ytlen+.5)*tw;
366:     PetscStrlen(axis->ylabel,&len);
367:     PetscDrawStringVertical(draw,x,y+len*th/2,cc,axis->ylabel);
368:   }

370:   PetscDrawGetCoordinates(draw,&coors[0],&coors[1],&coors[2],&coors[3]);
371: finally:
372:   PetscDrawCollectiveEnd(draw);
373:   MPI_Bcast(coors,4,MPIU_REAL,0,PetscObjectComm((PetscObject)draw));
374:   PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);
375:   return(0);
376: }

380: /*
381:     Removes all zeros but one from .0000
382: */
383: PetscErrorCode PetscStripe0(char *buf)
384: {
386:   size_t         n;
387:   PetscBool      flg;
388:   char           *str;

391:   PetscStrlen(buf,&n);
392:   PetscStrendswith(buf,"e00",&flg);
393:   if (flg) buf[n-3] = 0;
394:   PetscStrstr(buf,"e0",&str);
395:   if (str) {
396:     buf[n-2] = buf[n-1];
397:     buf[n-1] = 0;
398:   }
399:   PetscStrstr(buf,"e-0",&str);
400:   if (str) {
401:     buf[n-2] = buf[n-1];
402:     buf[n-1] = 0;
403:   }
404:   return(0);
405: }

409: /*
410:     Removes all zeros but one from .0000
411: */
412: PetscErrorCode PetscStripAllZeros(char *buf)
413: {
415:   size_t         i,n;

418:   PetscStrlen(buf,&n);
419:   if (buf[0] != '.') return(0);
420:   for (i=1; i<n; i++) {
421:     if (buf[i] != '0') return(0);
422:   }
423:   buf[0] = '0';
424:   buf[1] = 0;
425:   return(0);
426: }

430: /*
431:     Removes trailing zeros
432: */
433: PetscErrorCode PetscStripTrailingZeros(char *buf)
434: {
436:   char           *found;
437:   size_t         i,n,m = PETSC_MAX_INT;

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

444:   PetscStrlen(buf,&n);
445:   /* locate decimal point */
446:   for (i=0; i<n; i++) {
447:     if (buf[i] == '.') {m = i; break;}
448:   }
449:   /* if not decimal point then no zeros to remove */
450:   if (m == PETSC_MAX_INT) return(0);
451:   /* start at right end of string removing 0s */
452:   for (i=n-1; i>m; i++) {
453:     if (buf[i] != '0') return(0);
454:     buf[i] = 0;
455:   }
456:   return(0);
457: }

461: /*
462:     Removes leading 0 from 0.22 or -0.22
463: */
464: PetscErrorCode PetscStripInitialZero(char *buf)
465: {
467:   size_t         i,n;

470:   PetscStrlen(buf,&n);
471:   if (buf[0] == '0') {
472:     for (i=0; i<n; i++) buf[i] = buf[i+1];
473:   } else if (buf[0] == '-' && buf[1] == '0') {
474:     for (i=1; i<n; i++) buf[i] = buf[i+1];
475:   }
476:   return(0);
477: }

481: /*
482:      Removes the extraneous zeros in numbers like 1.10000e6
483: */
484: PetscErrorCode PetscStripZeros(char *buf)
485: {
487:   size_t         i,j,n;

490:   PetscStrlen(buf,&n);
491:   if (n<5) return(0);
492:   for (i=1; i<n-1; i++) {
493:     if (buf[i] == 'e' && buf[i-1] == '0') {
494:       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
495:       PetscStripZeros(buf);
496:       return(0);
497:     }
498:   }
499:   return(0);
500: }

504: /*
505:       Removes the plus in something like 1.1e+2 or 1.1e+02
506: */
507: PetscErrorCode PetscStripZerosPlus(char *buf)
508: {
510:   size_t         i,j,n;

513:   PetscStrlen(buf,&n);
514:   if (n<5) return(0);
515:   for (i=1; i<n-2; i++) {
516:     if (buf[i] == '+') {
517:       if (buf[i+1] == '0') {
518:         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
519:         return(0);
520:       } else {
521:         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
522:         return(0);
523:       }
524:     } else if (buf[i] == '-') {
525:       if (buf[i+1] == '0') {
526:         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
527:         return(0);
528:       }
529:     }
530:   }
531:   return(0);
532: }