Actual source code: axisc.c

  1: #include <../src/sys/draw/utils/axisimpl.h>

  3: PetscClassId 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:   PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
 32:   if (isnull) {
 33:     PetscDrawOpenNull(((PetscObject)obj)->comm,(PetscDraw*)axis);
 34:     (*axis)->win = draw;
 35:     return(0);
 36:   }
 37:   PetscHeaderCreate(ad,_p_DrawAxis,int,DRAWAXIS_CLASSID,0,"PetscDrawAxis","Draw Axis","Draw",((PetscObject)obj)->comm,PetscDrawAxisDestroy,0);
 38:   PetscLogObjectParent(draw,ad);
 39:   ad->xticks    = PetscADefTicks;
 40:   ad->yticks    = PetscADefTicks;
 41:   ad->xlabelstr = PetscADefLabel;
 42:   ad->ylabelstr = PetscADefLabel;
 43:   ad->win       = draw;
 44:   ad->ac        = PETSC_DRAW_BLACK;
 45:   ad->tc        = PETSC_DRAW_BLACK;
 46:   ad->cc        = PETSC_DRAW_BLACK;
 47:   ad->xlabel    = 0;
 48:   ad->ylabel    = 0;
 49:   ad->toplabel  = 0;

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

 57: /*@
 58:     PetscDrawAxisDestroy - Frees the space used by an axis structure.

 60:     Collective over PetscDrawAxis

 62:     Input Parameters:
 63: .   axis - the axis context
 64:  
 65:     Level: advanced

 67: @*/
 68: PetscErrorCode  PetscDrawAxisDestroy(PetscDrawAxis *axis)
 69: {

 73:   if (!*axis) return(0);
 74:   if (--((PetscObject)(*axis))->refct > 0) return(0);

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

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

 89:     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)

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

 97:     Level: advanced

 99: @*/
100: PetscErrorCode  PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
101: {
103:   if (!axis) return(0);
104:   axis->ac = ac; axis->tc = tc; axis->cc = cc;
105:   return(0);
106: }

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

113:     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)

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

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

123:     Level: advanced

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

131:   if (!axis) return(0);
132:   PetscStrallocpy(xlabel,&axis->xlabel);
133:   PetscStrallocpy(ylabel,&axis->ylabel);
134:   PetscStrallocpy(top,&axis->toplabel);
135:   return(0);
136: }

140: /*@
141:     PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
142:         again
143:     
144:     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)

146:     Input Parameters:
147: +   axis - the axis
148: -   hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed

150:     Level: advanced

152:     Notes:
153:         Once this has been called with PETSC_TRUE the limits will not change if you call
154:      PetscDrawAxisSetLimits() until you call this with PETSC_FALSE
155:  
156: .seealso:  PetscDrawAxisSetLimits()

158: @*/
159: PetscErrorCode  PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool  hold)
160: {
162:   if (!axis) return(0);
163:   axis->hold = hold;
164:   return(0);
165: }

169: /*@
170:     PetscDrawAxisDraw - PetscDraws an axis.

172:     Not Collective (ignored on all processors except processor 0 of PetscDrawAxis)

174:     Input Parameter:
175: .   axis - Axis structure

177:     Level: advanced

179:     Note:
180:     This draws the actual axis.  The limits etc have already been set.
181:     By picking special routines for the ticks and labels, special
182:     effects may be generated.  These routines are part of the Axis
183:     structure (axis).
184: @*/
185: PetscErrorCode  PetscDrawAxisDraw(PetscDrawAxis axis)
186: {
187:   int            i,ntick,numx,numy,ac = axis->ac,tc = axis->tc,cc = axis->cc,rank;
188:   size_t         len;
189:   PetscReal      tickloc[MAXSEGS],sep,h,w,tw,th,xl,xr,yl,yr;
190:   char           *p;
191:   PetscDraw      draw = axis->win;

195:   if (!axis) return(0);
196:   MPI_Comm_rank(((PetscObject)axis)->comm,&rank);
197:   if (rank) return(0);

199:   if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
200:   if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}
201:   xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh;
202:   PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
203:   PetscDrawStringGetSize(draw,&tw,&th);
204:   numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6; if (numx< 2) numx = 2;
205:   numy = (int)(.5*(yr-yl)/th); if (numy > 6) numy = 6; if (numy< 2) numy = 2;
206:   xl -= 8*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th;
207:   if (axis->xlabel) yl -= 2*th;
208:   if (axis->ylabel) xl -= 2*tw;
209:   PetscDrawSetCoordinates(draw,xl,yl,xr,yr);
210:   PetscDrawStringGetSize(draw,&tw,&th);

212:   PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);
213:   PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);

215:   if (axis->toplabel) {
216:      PetscStrlen(axis->toplabel,&len);
217:     w    = xl + .5*(xr - xl) - .5*len*tw;
218:     h    = axis->yhigh;
219:     PetscDrawString(draw,w,h,cc,axis->toplabel);
220:   }

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

278: /*
279:     Removes all zeros but one from .0000 
280: */
281: PetscErrorCode PetscStripAllZeros(char *buf)
282: {
284:   size_t         i,n;

287:   PetscStrlen(buf,&n);
288:   if (buf[0] != '.') return(0);
289:   for (i=1; i<n; i++) {
290:     if (buf[i] != '0') return(0);
291:   }
292:   buf[0] = '0';
293:   buf[1] = 0;
294:   return(0);
295: }

299: /*
300:     Removes trailing zeros
301: */
302: PetscErrorCode PetscStripTrailingZeros(char *buf)
303: {
305:   char           *found;
306:   size_t         i,n,m = PETSC_MAX_INT;

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

313:   PetscStrlen(buf,&n);
314:   /* locate decimal point */
315:   for (i=0; i<n; i++) {
316:     if (buf[i] == '.') {m = i; break;}
317:   }
318:   /* if not decimal point then no zeros to remove */
319:   if (m == PETSC_MAX_INT) return(0);
320:   /* start at right end of string removing 0s */
321:   for (i=n-1; i>m; i++) {
322:     if (buf[i] != '0') return(0);
323:     buf[i] = 0;
324:   }
325:   return(0);
326: }

330: /*
331:     Removes leading 0 from 0.22 or -0.22
332: */
333: PetscErrorCode PetscStripInitialZero(char *buf)
334: {
336:   size_t         i,n;

339:   PetscStrlen(buf,&n);
340:   if (buf[0] == '0') {
341:     for (i=0; i<n; i++) {
342:       buf[i] = buf[i+1];
343:     }
344:   } else if (buf[0] == '-' && buf[1] == '0') {
345:     for (i=1; i<n; i++) {
346:       buf[i] = buf[i+1];
347:     }
348:   }
349:   return(0);
350: }

354: /*
355:      Removes the extraneous zeros in numbers like 1.10000e6
356: */
357: PetscErrorCode PetscStripZeros(char *buf)
358: {
360:   size_t         i,j,n;

363:   PetscStrlen(buf,&n);
364:   if (n<5) return(0);
365:   for (i=1; i<n-1; i++) {
366:     if (buf[i] == 'e' && buf[i-1] == '0') {
367:       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
368:       PetscStripZeros(buf);
369:       return(0);
370:     }
371:   }
372:   return(0);
373: }

377: /*
378:       Removes the plus in something like 1.1e+2
379: */
380: PetscErrorCode PetscStripZerosPlus(char *buf)
381: {
383:   size_t         i,j,n;

386:   PetscStrlen(buf,&n);
387:   if (n<5) return(0);
388:   for (i=1; i<n-2; i++) {
389:     if (buf[i] == '+') {
390:       if (buf[i+1] == '0') {
391:         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j+1];
392:         return(0);
393:       } else {
394:         for (j=i+1; j<n+1; j++) buf[j] = buf[j+1];
395:         return(0);
396:       }
397:     } else if (buf[i] == '-') {
398:       if (buf[i+1] == '0') {
399:         for (j=i+1; j<n+1; j++) buf[j] = buf[j+1];
400:         return(0);
401:       }
402:     }
403:   }
404:   return(0);
405: }