Actual source code: axisc.c

petsc-3.8.4 2018-03-24
Report Typos and Errors
  1:  #include <../src/sys/classes/draw/utils/axisimpl.h>

  3: PetscClassId PETSC_DRAWAXIS_CLASSID = 0;

  5: /*@
  6:    PetscDrawAxisCreate - Generate the axis data structure.

  8:    Collective on PetscDraw

 10:    Input Parameters:
 11: .  win - PetscDraw object where axis to to be made

 13:    Ouput Parameters:
 14: .  axis - the axis datastructure

 16:    Notes: the MPI communicator that owns the underlying draw object owns the PetscDrawAxis object, but calls to set PetscDrawAxis options are ignored by all processes
 17:           except the first MPI process in the communicator

 19:    Level: advanced

 21: .seealso: PetscDrawLGCreate(), PetscDrawLG, PetscDrawSPCreate(), PetscDrawSP, PetscDrawHGCreate(), PetscDrawHG, PetscDrawBarCreate(), PetscDrawBar, PetscDrawLGGetAxis(), PetscDrawSPGetAxis(),
 22:           PetscDrawHGGetAxis(), PetscDrawBarGetAxis(), PetscDrawAxis, PetscDrawAxisDestroy(), PetscDrawAxisSetColors(), PetscDrawAxisSetLabels(), PetscDrawAxisSetLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetHoldLimits(),
 23:           PetscDrawAxisDraw()
 24: @*/
 25: PetscErrorCode  PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis *axis)
 26: {
 27:   PetscDrawAxis  ad;


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

 37:   PetscObjectReference((PetscObject)draw);
 38:   ad->win = draw;

 40:   ad->xticks    = PetscADefTicks;
 41:   ad->yticks    = PetscADefTicks;
 42:   ad->xlabelstr = PetscADefLabel;
 43:   ad->ylabelstr = PetscADefLabel;
 44:   ad->ac        = PETSC_DRAW_BLACK;
 45:   ad->tc        = PETSC_DRAW_BLACK;
 46:   ad->cc        = PETSC_DRAW_BLACK;
 47:   ad->xlabel    = NULL;
 48:   ad->ylabel    = NULL;
 49:   ad->toplabel  = NULL;

 51:   *axis = ad;
 52:   return(0);
 53: }

 55: /*@
 56:     PetscDrawAxisDestroy - Frees the space used by an axis structure.

 58:     Collective on PetscDrawAxis

 60:     Input Parameters:
 61: .   axis - the axis context

 63:     Level: advanced

 65: .seealso: PetscDrawAxisCreate(), PetscDrawAxis
 66: @*/
 67: PetscErrorCode  PetscDrawAxisDestroy(PetscDrawAxis *axis)
 68: {

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

 76:   PetscFree((*axis)->toplabel);
 77:   PetscFree((*axis)->xlabel);
 78:   PetscFree((*axis)->ylabel);
 79:   PetscDrawDestroy(&(*axis)->win);
 80:   PetscHeaderDestroy(axis);
 81:   return(0);
 82: }

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

 88:     Logically Collective on PetscDrawAxis

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

 96:     Level: advanced

 98: .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetLabels(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
 99: @*/
100: PetscErrorCode  PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
101: {
107:   axis->ac = ac; axis->tc = tc; axis->cc = cc;
108:   return(0);
109: }

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: .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetColors(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
127: @*/
128: PetscErrorCode  PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
129: {

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: }

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

146:     Logically Collective on PetscDrawAxis

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

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

156:     Level: advanced

158: .seealso:  PetscDrawAxisSetHoldLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()

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

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

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

179:     Not Collective

181:     Input Parameters:
182: +   axis - the axis
183: .   xmin,xmax - limits in x
184: -   ymin,ymax - limits in y

186:     Level: advanced

188: .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetHoldLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()

190: @*/
191: PetscErrorCode  PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax)
192: {
195:   *xmin = axis->xlow;
196:   *xmax = axis->xhigh;
197:   *ymin = axis->ylow;
198:   *ymax = axis->yhigh;
199:   return(0);
200: }

202: /*@
203:     PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
204:         again

206:     Logically Collective on PetscDrawAxis

208:     Input Parameters:
209: +   axis - the axis
210: -   hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed

212:     Level: advanced

214:     Notes:
215:         Once this has been called with PETSC_TRUE the limits will not change if you call
216:      PetscDrawAxisSetLimits() until you call this with PETSC_FALSE

218: .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()

220: @*/
221: PetscErrorCode  PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
222: {
226:   axis->hold = hold;
227:   return(0);
228: }

230: /*@
231:     PetscDrawAxisDraw - PetscDraws an axis.

233:     Collective on PetscDrawAxis

235:     Input Parameter:
236: .   axis - Axis structure

238:     Level: advanced

240:     Note:
241:     This draws the actual axis.  The limits etc have already been set.
242:     By picking special routines for the ticks and labels, special
243:     effects may be generated.  These routines are part of the Axis
244:     structure (axis).

246: .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()

248: @*/
249: PetscErrorCode  PetscDrawAxisDraw(PetscDrawAxis axis)
250: {
251:   int            i,ntick,numx,numy,ac,tc,cc;
252:   PetscMPIInt    rank;
253:   size_t         len,ytlen=0;
254:   PetscReal      coors[4],tickloc[MAXSEGS],sep,tw,th;
255:   PetscReal      xl,xr,yl,yr,dxl=0,dyl=0,dxr=0,dyr=0;
256:   char           *p;
257:   PetscDraw      draw;
258:   PetscBool      isnull;

263:   PetscDrawIsNull(axis->win,&isnull);
264:   if (isnull) return(0);
265:   MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);

267:   draw = axis->win;

269:   ac = axis->ac; tc = axis->tc; cc = axis->cc;
270:   if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
271:   if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}

273:   PetscDrawCollectiveBegin(draw);
274:   if (rank) goto finally;

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

300:   /* PetscDraw the axis lines */
301:   PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);
302:   PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);
303:   PetscDrawLine(draw,axis->xlow,axis->yhigh,axis->xhigh,axis->yhigh,ac);
304:   PetscDrawLine(draw,axis->xhigh,axis->ylow,axis->xhigh,axis->yhigh,ac);

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

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

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

366:   PetscDrawGetCoordinates(draw,&coors[0],&coors[1],&coors[2],&coors[3]);
367: finally:
368:   PetscDrawCollectiveEnd(draw);
369:   MPI_Bcast(coors,4,MPIU_REAL,0,PetscObjectComm((PetscObject)draw));
370:   PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);
371:   return(0);
372: }

374: /*
375:     Removes all zeros but one from .0000
376: */
377: PetscErrorCode PetscStripe0(char *buf)
378: {
380:   size_t         n;
381:   PetscBool      flg;
382:   char           *str;

385:   PetscStrlen(buf,&n);
386:   PetscStrendswith(buf,"e00",&flg);
387:   if (flg) buf[n-3] = 0;
388:   PetscStrstr(buf,"e0",&str);
389:   if (str) {
390:     buf[n-2] = buf[n-1];
391:     buf[n-1] = 0;
392:   }
393:   PetscStrstr(buf,"e-0",&str);
394:   if (str) {
395:     buf[n-2] = buf[n-1];
396:     buf[n-1] = 0;
397:   }
398:   return(0);
399: }

401: /*
402:     Removes all zeros but one from .0000
403: */
404: PetscErrorCode PetscStripAllZeros(char *buf)
405: {
407:   size_t         i,n;

410:   PetscStrlen(buf,&n);
411:   if (buf[0] != '.') return(0);
412:   for (i=1; i<n; i++) {
413:     if (buf[i] != '0') return(0);
414:   }
415:   buf[0] = '0';
416:   buf[1] = 0;
417:   return(0);
418: }

420: /*
421:     Removes trailing zeros
422: */
423: PetscErrorCode PetscStripTrailingZeros(char *buf)
424: {
426:   char           *found;
427:   size_t         i,n,m = PETSC_MAX_INT;

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

434:   PetscStrlen(buf,&n);
435:   /* locate decimal point */
436:   for (i=0; i<n; i++) {
437:     if (buf[i] == '.') {m = i; break;}
438:   }
439:   /* if not decimal point then no zeros to remove */
440:   if (m == PETSC_MAX_INT) return(0);
441:   /* start at right end of string removing 0s */
442:   for (i=n-1; i>m; i++) {
443:     if (buf[i] != '0') return(0);
444:     buf[i] = 0;
445:   }
446:   return(0);
447: }

449: /*
450:     Removes leading 0 from 0.22 or -0.22
451: */
452: PetscErrorCode PetscStripInitialZero(char *buf)
453: {
455:   size_t         i,n;

458:   PetscStrlen(buf,&n);
459:   if (buf[0] == '0') {
460:     for (i=0; i<n; i++) buf[i] = buf[i+1];
461:   } else if (buf[0] == '-' && buf[1] == '0') {
462:     for (i=1; i<n; i++) buf[i] = buf[i+1];
463:   }
464:   return(0);
465: }

467: /*
468:      Removes the extraneous zeros in numbers like 1.10000e6
469: */
470: PetscErrorCode PetscStripZeros(char *buf)
471: {
473:   size_t         i,j,n;

476:   PetscStrlen(buf,&n);
477:   if (n<5) return(0);
478:   for (i=1; i<n-1; i++) {
479:     if (buf[i] == 'e' && buf[i-1] == '0') {
480:       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
481:       PetscStripZeros(buf);
482:       return(0);
483:     }
484:   }
485:   return(0);
486: }

488: /*
489:       Removes the plus in something like 1.1e+2 or 1.1e+02
490: */
491: PetscErrorCode PetscStripZerosPlus(char *buf)
492: {
494:   size_t         i,j,n;

497:   PetscStrlen(buf,&n);
498:   if (n<5) return(0);
499:   for (i=1; i<n-2; i++) {
500:     if (buf[i] == '+') {
501:       if (buf[i+1] == '0') {
502:         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
503:         return(0);
504:       } else {
505:         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
506:         return(0);
507:       }
508:     } else if (buf[i] == '-') {
509:       if (buf[i+1] == '0') {
510:         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
511:         return(0);
512:       }
513:     }
514:   }
515:   return(0);
516: }