Actual source code: axisc.c
petsc-3.7.1 2016-05-15
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: }