xref: /petsc/src/sys/classes/draw/utils/axisc.c (revision 999739cf12618b36ac48ee4250964a76f927d80d)
1*999739cfSJacob Faibussowitsch #include <petsc/private/drawimpl.h>  /*I   "petscdraw.h"  I*/
25c6c1daeSBarry Smith 
3*999739cfSJacob Faibussowitsch #define PETSC_DRAW_AXIS_MAX_SEGMENTS 20
45c6c1daeSBarry Smith PetscClassId PETSC_DRAWAXIS_CLASSID = 0;
55c6c1daeSBarry Smith 
65c6c1daeSBarry Smith /*@
75c6c1daeSBarry Smith    PetscDrawAxisCreate - Generate the axis data structure.
85c6c1daeSBarry Smith 
95b399a63SLisandro Dalcin    Collective on PetscDraw
105c6c1daeSBarry Smith 
115c6c1daeSBarry Smith    Input Parameters:
125c6c1daeSBarry Smith .  win - PetscDraw object where axis to to be made
135c6c1daeSBarry Smith 
1401d2d390SJose E. Roman    Output Parameter:
155c6c1daeSBarry Smith .  axis - the axis datastructure
165c6c1daeSBarry Smith 
1795452b02SPatrick Sanan    Notes:
1895452b02SPatrick Sanan     the MPI communicator that owns the underlying draw object owns the PetscDrawAxis object, but calls to set PetscDrawAxis options are ignored by all processes
197e25d57eSBarry Smith           except the first MPI process in the communicator
207e25d57eSBarry Smith 
215c6c1daeSBarry Smith    Level: advanced
225c6c1daeSBarry Smith 
230afdd333SBarry Smith .seealso: PetscDrawLGCreate(), PetscDrawLG, PetscDrawSPCreate(), PetscDrawSP, PetscDrawHGCreate(), PetscDrawHG, PetscDrawBarCreate(), PetscDrawBar, PetscDrawLGGetAxis(), PetscDrawSPGetAxis(),
240afdd333SBarry Smith           PetscDrawHGGetAxis(), PetscDrawBarGetAxis(), PetscDrawAxis, PetscDrawAxisDestroy(), PetscDrawAxisSetColors(), PetscDrawAxisSetLabels(), PetscDrawAxisSetLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetHoldLimits(),
250afdd333SBarry Smith           PetscDrawAxisDraw()
265c6c1daeSBarry Smith @*/
275c6c1daeSBarry Smith PetscErrorCode  PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis *axis)
285c6c1daeSBarry Smith {
29e118a51fSLisandro Dalcin   PetscDrawAxis  ad;
30e118a51fSLisandro Dalcin   PetscErrorCode ierr;
315c6c1daeSBarry Smith 
325c6c1daeSBarry Smith   PetscFunctionBegin;
335c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
345c6c1daeSBarry Smith   PetscValidPointer(axis,2);
35e118a51fSLisandro Dalcin 
3671917b75SLisandro Dalcin   ierr = PetscHeaderCreate(ad,PETSC_DRAWAXIS_CLASSID,"DrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)draw),PetscDrawAxisDestroy,NULL);CHKERRQ(ierr);
373bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)ad);CHKERRQ(ierr);
38a297a907SKarl Rupp 
39e118a51fSLisandro Dalcin   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
40e118a51fSLisandro Dalcin   ad->win = draw;
41e118a51fSLisandro Dalcin 
425c6c1daeSBarry Smith   ad->xticks    = PetscADefTicks;
435c6c1daeSBarry Smith   ad->yticks    = PetscADefTicks;
445c6c1daeSBarry Smith   ad->xlabelstr = PetscADefLabel;
455c6c1daeSBarry Smith   ad->ylabelstr = PetscADefLabel;
465c6c1daeSBarry Smith   ad->ac        = PETSC_DRAW_BLACK;
475c6c1daeSBarry Smith   ad->tc        = PETSC_DRAW_BLACK;
485c6c1daeSBarry Smith   ad->cc        = PETSC_DRAW_BLACK;
49e5ab1681SLisandro Dalcin   ad->xlabel    = NULL;
50e5ab1681SLisandro Dalcin   ad->ylabel    = NULL;
51e5ab1681SLisandro Dalcin   ad->toplabel  = NULL;
525c6c1daeSBarry Smith 
535c6c1daeSBarry Smith   *axis = ad;
545c6c1daeSBarry Smith   PetscFunctionReturn(0);
555c6c1daeSBarry Smith }
565c6c1daeSBarry Smith 
575c6c1daeSBarry Smith /*@
585c6c1daeSBarry Smith     PetscDrawAxisDestroy - Frees the space used by an axis structure.
595c6c1daeSBarry Smith 
605b399a63SLisandro Dalcin     Collective on PetscDrawAxis
615c6c1daeSBarry Smith 
625c6c1daeSBarry Smith     Input Parameters:
635c6c1daeSBarry Smith .   axis - the axis context
645c6c1daeSBarry Smith 
655c6c1daeSBarry Smith     Level: advanced
665c6c1daeSBarry Smith 
670afdd333SBarry Smith .seealso: PetscDrawAxisCreate(), PetscDrawAxis
685c6c1daeSBarry Smith @*/
695c6c1daeSBarry Smith PetscErrorCode  PetscDrawAxisDestroy(PetscDrawAxis *axis)
705c6c1daeSBarry Smith {
715c6c1daeSBarry Smith   PetscErrorCode ierr;
725c6c1daeSBarry Smith 
735c6c1daeSBarry Smith   PetscFunctionBegin;
745c6c1daeSBarry Smith   if (!*axis) PetscFunctionReturn(0);
75e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*axis,PETSC_DRAWAXIS_CLASSID,1);
76e118a51fSLisandro Dalcin   if (--((PetscObject)(*axis))->refct > 0) {*axis = NULL; PetscFunctionReturn(0);}
775c6c1daeSBarry Smith 
785c6c1daeSBarry Smith   ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr);
795c6c1daeSBarry Smith   ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr);
805c6c1daeSBarry Smith   ierr = PetscFree((*axis)->ylabel);CHKERRQ(ierr);
81e118a51fSLisandro Dalcin   ierr = PetscDrawDestroy(&(*axis)->win);CHKERRQ(ierr);
825c6c1daeSBarry Smith   ierr = PetscHeaderDestroy(axis);CHKERRQ(ierr);
835c6c1daeSBarry Smith   PetscFunctionReturn(0);
845c6c1daeSBarry Smith }
855c6c1daeSBarry Smith 
865c6c1daeSBarry Smith /*@
875c6c1daeSBarry Smith     PetscDrawAxisSetColors -  Sets the colors to be used for the axis,
885c6c1daeSBarry Smith                          tickmarks, and text.
895c6c1daeSBarry Smith 
905b399a63SLisandro Dalcin     Logically Collective on PetscDrawAxis
915c6c1daeSBarry Smith 
925c6c1daeSBarry Smith     Input Parameters:
935c6c1daeSBarry Smith +   axis - the axis
945c6c1daeSBarry Smith .   ac - the color of the axis lines
955c6c1daeSBarry Smith .   tc - the color of the tick marks
965c6c1daeSBarry Smith -   cc - the color of the text strings
975c6c1daeSBarry Smith 
985c6c1daeSBarry Smith     Level: advanced
995c6c1daeSBarry Smith 
1000afdd333SBarry Smith .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetLabels(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
1015c6c1daeSBarry Smith @*/
1025c6c1daeSBarry Smith PetscErrorCode  PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)
1035c6c1daeSBarry Smith {
1045c6c1daeSBarry Smith   PetscFunctionBegin;
105e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
1065b399a63SLisandro Dalcin   PetscValidLogicalCollectiveInt(axis,ac,2);
1075b399a63SLisandro Dalcin   PetscValidLogicalCollectiveInt(axis,tc,3);
1085b399a63SLisandro Dalcin   PetscValidLogicalCollectiveInt(axis,cc,4);
1095c6c1daeSBarry Smith   axis->ac = ac; axis->tc = tc; axis->cc = cc;
1105c6c1daeSBarry Smith   PetscFunctionReturn(0);
1115c6c1daeSBarry Smith }
1125c6c1daeSBarry Smith 
1135c6c1daeSBarry Smith /*@C
1145c6c1daeSBarry Smith     PetscDrawAxisSetLabels -  Sets the x and y axis labels.
1155c6c1daeSBarry Smith 
1165b399a63SLisandro Dalcin     Logically Collective on PetscDrawAxis
1175c6c1daeSBarry Smith 
1185c6c1daeSBarry Smith     Input Parameters:
1195c6c1daeSBarry Smith +   axis - the axis
1205c6c1daeSBarry Smith .   top - the label at the top of the image
1215c6c1daeSBarry Smith -   xlabel,ylabel - the labes for the x and y axis
1225c6c1daeSBarry Smith 
12395452b02SPatrick Sanan     Notes:
12495452b02SPatrick Sanan     Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw()
1255c6c1daeSBarry Smith            There should be no newlines in the arguments
1265c6c1daeSBarry Smith 
1275c6c1daeSBarry Smith     Level: advanced
1285c6c1daeSBarry Smith 
1290afdd333SBarry Smith .seealso: PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetColors(), PetscDrawAxisDraw(), PetscDrawAxisSetLimits()
1305c6c1daeSBarry Smith @*/
1315c6c1daeSBarry Smith PetscErrorCode  PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])
1325c6c1daeSBarry Smith {
1335c6c1daeSBarry Smith   PetscErrorCode ierr;
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith   PetscFunctionBegin;
136e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
1375c6c1daeSBarry Smith   ierr = PetscFree(axis->xlabel);CHKERRQ(ierr);
1385c6c1daeSBarry Smith   ierr = PetscFree(axis->ylabel);CHKERRQ(ierr);
1395c6c1daeSBarry Smith   ierr = PetscFree(axis->toplabel);CHKERRQ(ierr);
1405c6c1daeSBarry Smith   ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr);
1415c6c1daeSBarry Smith   ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr);
1425c6c1daeSBarry Smith   ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr);
1435c6c1daeSBarry Smith   PetscFunctionReturn(0);
1445c6c1daeSBarry Smith }
1455c6c1daeSBarry Smith 
14671917b75SLisandro Dalcin /*@
14771917b75SLisandro Dalcin     PetscDrawAxisSetLimits -  Sets the limits (in user coords) of the axis
14871917b75SLisandro Dalcin 
14971917b75SLisandro Dalcin     Logically Collective on PetscDrawAxis
15071917b75SLisandro Dalcin 
15171917b75SLisandro Dalcin     Input Parameters:
15271917b75SLisandro Dalcin +   axis - the axis
15371917b75SLisandro Dalcin .   xmin,xmax - limits in x
15471917b75SLisandro Dalcin -   ymin,ymax - limits in y
15571917b75SLisandro Dalcin 
15671917b75SLisandro Dalcin     Options Database:
15771917b75SLisandro Dalcin .   -drawaxis_hold - hold the initial set of axis limits for future plotting
15871917b75SLisandro Dalcin 
15971917b75SLisandro Dalcin     Level: advanced
16071917b75SLisandro Dalcin 
1610afdd333SBarry Smith .seealso:  PetscDrawAxisSetHoldLimits(), PetscDrawAxisGetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
16271917b75SLisandro Dalcin 
16371917b75SLisandro Dalcin @*/
16471917b75SLisandro Dalcin PetscErrorCode  PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)
16571917b75SLisandro Dalcin {
16671917b75SLisandro Dalcin   PetscErrorCode ierr;
16771917b75SLisandro Dalcin 
16871917b75SLisandro Dalcin   PetscFunctionBegin;
16971917b75SLisandro Dalcin   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
17071917b75SLisandro Dalcin   if (axis->hold) PetscFunctionReturn(0);
17171917b75SLisandro Dalcin   axis->xlow = xmin;
17271917b75SLisandro Dalcin   axis->xhigh= xmax;
17371917b75SLisandro Dalcin   axis->ylow = ymin;
17471917b75SLisandro Dalcin   axis->yhigh= ymax;
17571917b75SLisandro Dalcin   ierr = PetscOptionsHasName(((PetscObject)axis)->options,((PetscObject)axis)->prefix,"-drawaxis_hold",&axis->hold);CHKERRQ(ierr);
17671917b75SLisandro Dalcin   PetscFunctionReturn(0);
17771917b75SLisandro Dalcin }
17871917b75SLisandro Dalcin 
17971917b75SLisandro Dalcin /*@
18071917b75SLisandro Dalcin     PetscDrawAxisGetLimits -  Gets the limits (in user coords) of the axis
18171917b75SLisandro Dalcin 
18271917b75SLisandro Dalcin     Not Collective
18371917b75SLisandro Dalcin 
18471917b75SLisandro Dalcin     Input Parameters:
18571917b75SLisandro Dalcin +   axis - the axis
18671917b75SLisandro Dalcin .   xmin,xmax - limits in x
18771917b75SLisandro Dalcin -   ymin,ymax - limits in y
18871917b75SLisandro Dalcin 
18971917b75SLisandro Dalcin     Level: advanced
19071917b75SLisandro Dalcin 
1910afdd333SBarry Smith .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisSetHoldLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
19271917b75SLisandro Dalcin 
19371917b75SLisandro Dalcin @*/
19471917b75SLisandro Dalcin PetscErrorCode  PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax)
19571917b75SLisandro Dalcin {
19671917b75SLisandro Dalcin   PetscFunctionBegin;
19771917b75SLisandro Dalcin   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
198bb046f40SHong Zhang   if (xmin) *xmin = axis->xlow;
199bb046f40SHong Zhang   if (xmax) *xmax = axis->xhigh;
200bb046f40SHong Zhang   if (ymin) *ymin = axis->ylow;
201bb046f40SHong Zhang   if (ymax) *ymax = axis->yhigh;
20271917b75SLisandro Dalcin   PetscFunctionReturn(0);
20371917b75SLisandro Dalcin }
20471917b75SLisandro Dalcin 
2055c6c1daeSBarry Smith /*@
2065c6c1daeSBarry Smith     PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
2075c6c1daeSBarry Smith         again
2085c6c1daeSBarry Smith 
2095b399a63SLisandro Dalcin     Logically Collective on PetscDrawAxis
2105c6c1daeSBarry Smith 
2115c6c1daeSBarry Smith     Input Parameters:
2125c6c1daeSBarry Smith +   axis - the axis
2135c6c1daeSBarry Smith -   hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed
2145c6c1daeSBarry Smith 
2155c6c1daeSBarry Smith     Level: advanced
2165c6c1daeSBarry Smith 
2175c6c1daeSBarry Smith     Notes:
2185c6c1daeSBarry Smith         Once this has been called with PETSC_TRUE the limits will not change if you call
2195c6c1daeSBarry Smith      PetscDrawAxisSetLimits() until you call this with PETSC_FALSE
2205c6c1daeSBarry Smith 
2210afdd333SBarry Smith .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
2225c6c1daeSBarry Smith 
2235c6c1daeSBarry Smith @*/
2245c6c1daeSBarry Smith PetscErrorCode  PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)
2255c6c1daeSBarry Smith {
2265c6c1daeSBarry Smith   PetscFunctionBegin;
227e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
2285b399a63SLisandro Dalcin   PetscValidLogicalCollectiveBool(axis,hold,2);
2295c6c1daeSBarry Smith   axis->hold = hold;
2305c6c1daeSBarry Smith   PetscFunctionReturn(0);
2315c6c1daeSBarry Smith }
2325c6c1daeSBarry Smith 
2335c6c1daeSBarry Smith /*@
2345c6c1daeSBarry Smith     PetscDrawAxisDraw - PetscDraws an axis.
2355c6c1daeSBarry Smith 
2365b399a63SLisandro Dalcin     Collective on PetscDrawAxis
2375c6c1daeSBarry Smith 
2385c6c1daeSBarry Smith     Input Parameter:
2395c6c1daeSBarry Smith .   axis - Axis structure
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith     Level: advanced
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith     Note:
2445c6c1daeSBarry Smith     This draws the actual axis.  The limits etc have already been set.
2455c6c1daeSBarry Smith     By picking special routines for the ticks and labels, special
2465c6c1daeSBarry Smith     effects may be generated.  These routines are part of the Axis
2475c6c1daeSBarry Smith     structure (axis).
2480afdd333SBarry Smith 
2490afdd333SBarry Smith .seealso:  PetscDrawAxisCreate(), PetscDrawAxis, PetscDrawAxisGetLimits(), PetscDrawAxisSetLimits(), PetscDrawAxisSetLabels(), PetscDrawAxisSetColors()
2500afdd333SBarry Smith 
2515c6c1daeSBarry Smith @*/
2525c6c1daeSBarry Smith PetscErrorCode  PetscDrawAxisDraw(PetscDrawAxis axis)
2535c6c1daeSBarry Smith {
254e118a51fSLisandro Dalcin   int            i,ntick,numx,numy,ac,tc,cc;
255e118a51fSLisandro Dalcin   PetscMPIInt    rank;
25671917b75SLisandro Dalcin   size_t         len,ytlen=0;
257*999739cfSJacob Faibussowitsch   PetscReal      coors[4],tickloc[PETSC_DRAW_AXIS_MAX_SEGMENTS],sep,tw,th;
25871917b75SLisandro Dalcin   PetscReal      xl,xr,yl,yr,dxl=0,dyl=0,dxr=0,dyr=0;
2595c6c1daeSBarry Smith   char           *p;
260e118a51fSLisandro Dalcin   PetscDraw      draw;
261e118a51fSLisandro Dalcin   PetscBool      isnull;
2625c6c1daeSBarry Smith   PetscErrorCode ierr;
2635c6c1daeSBarry Smith 
2645c6c1daeSBarry Smith   PetscFunctionBegin;
265e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1);
2668f69470aSLisandro Dalcin   ierr = PetscDrawIsNull(axis->win,&isnull);CHKERRQ(ierr);
267e118a51fSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
268ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);CHKERRMPI(ierr);
2695c6c1daeSBarry Smith 
2708f69470aSLisandro Dalcin   draw = axis->win;
2715b399a63SLisandro Dalcin 
272e118a51fSLisandro Dalcin   ac = axis->ac; tc = axis->tc; cc = axis->cc;
2735c6c1daeSBarry Smith   if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;}
2747b8d257dSBarry Smith   if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;}
275e118a51fSLisandro Dalcin 
27671917b75SLisandro Dalcin   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
27771917b75SLisandro Dalcin   if (rank) goto finally;
27871917b75SLisandro Dalcin 
27971917b75SLisandro Dalcin   /* get cannonical string size */
28071917b75SLisandro Dalcin   ierr = PetscDrawSetCoordinates(draw,0,0,1,1);CHKERRQ(ierr);
2815c6c1daeSBarry Smith   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
28271917b75SLisandro Dalcin   /* lower spacing */
28371917b75SLisandro Dalcin   if (axis->xlabelstr) dyl += 1.5*th;
28471917b75SLisandro Dalcin   if (axis->xlabel)    dyl += 1.5*th;
28571917b75SLisandro Dalcin   /* left spacing */
28671917b75SLisandro Dalcin   if (axis->ylabelstr) dxl += 7.5*tw;
28771917b75SLisandro Dalcin   if (axis->ylabel)    dxl += 2.0*tw;
28871917b75SLisandro Dalcin   /* right and top spacing */
28971917b75SLisandro Dalcin   if (axis->xlabelstr) dxr = 2.5*tw;
29071917b75SLisandro Dalcin   if (axis->ylabelstr) dyr = 0.5*th;
29171917b75SLisandro Dalcin   if (axis->toplabel)  dyr = 1.5*th;
29271917b75SLisandro Dalcin   /* extra spacing */
29371917b75SLisandro Dalcin   dxl += 0.7*tw; dxr += 0.5*tw;
29471917b75SLisandro Dalcin   dyl += 0.2*th; dyr += 0.2*th;
29571917b75SLisandro Dalcin   /* determine coordinates */
29671917b75SLisandro Dalcin   xl = (dxl*axis->xhigh + dxr*axis->xlow - axis->xlow)  / (dxl + dxr - 1);
29771917b75SLisandro Dalcin   xr = (dxl*axis->xhigh + dxr*axis->xlow - axis->xhigh) / (dxl + dxr - 1);
29871917b75SLisandro Dalcin   yl = (dyl*axis->yhigh + dyr*axis->ylow - axis->ylow)  / (dyl + dyr - 1);
29971917b75SLisandro Dalcin   yr = (dyl*axis->yhigh + dyr*axis->ylow - axis->yhigh) / (dyl + dyr - 1);
3005c6c1daeSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
3015c6c1daeSBarry Smith   ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
3025c6c1daeSBarry Smith 
30371917b75SLisandro Dalcin   /* PetscDraw the axis lines */
3045c6c1daeSBarry Smith   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr);
3055c6c1daeSBarry Smith   ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr);
30671917b75SLisandro Dalcin   ierr = PetscDrawLine(draw,axis->xlow,axis->yhigh,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr);
30771917b75SLisandro Dalcin   ierr = PetscDrawLine(draw,axis->xhigh,axis->ylow,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr);
3085c6c1daeSBarry Smith 
30971917b75SLisandro Dalcin   /* PetscDraw the top label */
3105c6c1daeSBarry Smith   if (axis->toplabel) {
31171917b75SLisandro Dalcin     PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->yhigh + 0.5*th;
31271917b75SLisandro Dalcin     ierr = PetscDrawStringCentered(draw,x,y,cc,axis->toplabel);CHKERRQ(ierr);
3135c6c1daeSBarry Smith   }
3145c6c1daeSBarry Smith 
31571917b75SLisandro Dalcin   /* PetscDraw the X ticks and labels */
3165c6c1daeSBarry Smith   if (axis->xticks) {
31771917b75SLisandro Dalcin     numx = (int)(.15*(axis->xhigh-axis->xlow)/tw); numx = PetscClipInterval(numx,2,6);
318*999739cfSJacob Faibussowitsch     ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,PETSC_DRAW_AXIS_MAX_SEGMENTS);CHKERRQ(ierr);
3195c6c1daeSBarry Smith     /* PetscDraw in tick marks */
3205c6c1daeSBarry Smith     for (i=0; i<ntick; i++) {
32171917b75SLisandro Dalcin       ierr = PetscDrawLine(draw,tickloc[i],axis->ylow,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr);
32271917b75SLisandro Dalcin       ierr = PetscDrawLine(draw,tickloc[i],axis->yhigh,tickloc[i],axis->yhigh-.5*th,tc);CHKERRQ(ierr);
3235c6c1daeSBarry Smith     }
3245c6c1daeSBarry Smith     /* label ticks */
3255c6c1daeSBarry Smith     if (axis->xlabelstr) {
32671917b75SLisandro Dalcin       for (i=0; i<ntick; i++) {
3275c6c1daeSBarry Smith         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
3285c6c1daeSBarry Smith         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
3295c6c1daeSBarry Smith         else               sep = 0.0;
3305c6c1daeSBarry Smith         ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
33171917b75SLisandro Dalcin         ierr = PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.5*th,cc,p);CHKERRQ(ierr);
3325c6c1daeSBarry Smith       }
3335c6c1daeSBarry Smith     }
3345c6c1daeSBarry Smith   }
3355c6c1daeSBarry Smith   if (axis->xlabel) {
33671917b75SLisandro Dalcin     PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->ylow - 1.5*th;
33771917b75SLisandro Dalcin     if (axis->xlabelstr) y -= 1.5*th;
33871917b75SLisandro Dalcin     ierr = PetscDrawStringCentered(draw,x,y,cc,axis->xlabel);CHKERRQ(ierr);
3395c6c1daeSBarry Smith   }
34071917b75SLisandro Dalcin 
34171917b75SLisandro Dalcin   /* PetscDraw the Y ticks and labels */
3425c6c1daeSBarry Smith   if (axis->yticks) {
34371917b75SLisandro Dalcin     numy = (int)(.50*(axis->yhigh-axis->ylow)/th); numy = PetscClipInterval(numy,2,6);
344*999739cfSJacob Faibussowitsch     ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,PETSC_DRAW_AXIS_MAX_SEGMENTS);CHKERRQ(ierr);
3455c6c1daeSBarry Smith     /* PetscDraw in tick marks */
3465c6c1daeSBarry Smith     for (i=0; i<ntick; i++) {
34771917b75SLisandro Dalcin       ierr = PetscDrawLine(draw,axis->xlow,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr);
34871917b75SLisandro Dalcin       ierr = PetscDrawLine(draw,axis->xhigh,tickloc[i],axis->xhigh-.5*tw,tickloc[i],tc);CHKERRQ(ierr);
3495c6c1daeSBarry Smith     }
3505c6c1daeSBarry Smith     /* label ticks */
3515c6c1daeSBarry Smith     if (axis->ylabelstr) {
35271917b75SLisandro Dalcin       for (i=0; i<ntick; i++) {
3535c6c1daeSBarry Smith         if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i];
3545c6c1daeSBarry Smith         else if (i > 0)    sep = tickloc[i]   - tickloc[i-1];
3555c6c1daeSBarry Smith         else               sep = 0.0;
35671917b75SLisandro Dalcin         ierr = (*axis->ylabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr);
35771917b75SLisandro Dalcin         ierr = PetscStrlen(p,&len);CHKERRQ(ierr); ytlen = PetscMax(ytlen,len);
35871917b75SLisandro Dalcin         ierr = PetscDrawString(draw,axis->xlow-(len+.5)*tw,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr);
3595c6c1daeSBarry Smith       }
3605c6c1daeSBarry Smith     }
3615c6c1daeSBarry Smith   }
3625c6c1daeSBarry Smith   if (axis->ylabel) {
36371917b75SLisandro Dalcin     PetscReal x = axis->xlow - 2.0*tw, y = (axis->ylow + axis->yhigh)/2;
36471917b75SLisandro Dalcin     if (axis->ylabelstr) x -= (ytlen+.5)*tw;
3655c6c1daeSBarry Smith     ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr);
36671917b75SLisandro Dalcin     ierr = PetscDrawStringVertical(draw,x,y+len*th/2,cc,axis->ylabel);CHKERRQ(ierr);
3675c6c1daeSBarry Smith   }
3685b399a63SLisandro Dalcin 
3695b399a63SLisandro Dalcin   ierr = PetscDrawGetCoordinates(draw,&coors[0],&coors[1],&coors[2],&coors[3]);CHKERRQ(ierr);
3705b399a63SLisandro Dalcin finally:
3715b399a63SLisandro Dalcin   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
372ffc4695bSBarry Smith   ierr = MPI_Bcast(coors,4,MPIU_REAL,0,PetscObjectComm((PetscObject)draw));CHKERRMPI(ierr);
3735b399a63SLisandro Dalcin   ierr = PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);CHKERRQ(ierr);
3745c6c1daeSBarry Smith   PetscFunctionReturn(0);
3755c6c1daeSBarry Smith }
3765c6c1daeSBarry Smith 
37736c9bc0dSBarry Smith /*
37836c9bc0dSBarry Smith     Removes all zeros but one from .0000
37936c9bc0dSBarry Smith */
38036c9bc0dSBarry Smith PetscErrorCode PetscStripe0(char *buf)
38136c9bc0dSBarry Smith {
38236c9bc0dSBarry Smith   PetscErrorCode ierr;
38336c9bc0dSBarry Smith   size_t         n;
38436c9bc0dSBarry Smith   PetscBool      flg;
38536c9bc0dSBarry Smith   char           *str;
38636c9bc0dSBarry Smith 
38736c9bc0dSBarry Smith   PetscFunctionBegin;
38836c9bc0dSBarry Smith   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
38936c9bc0dSBarry Smith   ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr);
390a297a907SKarl Rupp   if (flg) buf[n-3] = 0;
39136c9bc0dSBarry Smith   ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr);
39236c9bc0dSBarry Smith   if (str) {
39336c9bc0dSBarry Smith     buf[n-2] = buf[n-1];
39436c9bc0dSBarry Smith     buf[n-1] = 0;
39536c9bc0dSBarry Smith   }
39636c9bc0dSBarry Smith   ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr);
39736c9bc0dSBarry Smith   if (str) {
39836c9bc0dSBarry Smith     buf[n-2] = buf[n-1];
39936c9bc0dSBarry Smith     buf[n-1] = 0;
40036c9bc0dSBarry Smith   }
40136c9bc0dSBarry Smith   PetscFunctionReturn(0);
40236c9bc0dSBarry Smith }
40336c9bc0dSBarry Smith 
4045c6c1daeSBarry Smith /*
4055c6c1daeSBarry Smith     Removes all zeros but one from .0000
4065c6c1daeSBarry Smith */
4075c6c1daeSBarry Smith PetscErrorCode PetscStripAllZeros(char *buf)
4085c6c1daeSBarry Smith {
4095c6c1daeSBarry Smith   PetscErrorCode ierr;
4105c6c1daeSBarry Smith   size_t         i,n;
4115c6c1daeSBarry Smith 
4125c6c1daeSBarry Smith   PetscFunctionBegin;
4135c6c1daeSBarry Smith   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
4145c6c1daeSBarry Smith   if (buf[0] != '.') PetscFunctionReturn(0);
4155c6c1daeSBarry Smith   for (i=1; i<n; i++) {
4165c6c1daeSBarry Smith     if (buf[i] != '0') PetscFunctionReturn(0);
4175c6c1daeSBarry Smith   }
4185c6c1daeSBarry Smith   buf[0] = '0';
4195c6c1daeSBarry Smith   buf[1] = 0;
4205c6c1daeSBarry Smith   PetscFunctionReturn(0);
4215c6c1daeSBarry Smith }
4225c6c1daeSBarry Smith 
4235c6c1daeSBarry Smith /*
4245c6c1daeSBarry Smith     Removes trailing zeros
4255c6c1daeSBarry Smith */
4265c6c1daeSBarry Smith PetscErrorCode PetscStripTrailingZeros(char *buf)
4275c6c1daeSBarry Smith {
4285c6c1daeSBarry Smith   PetscErrorCode ierr;
4295c6c1daeSBarry Smith   char           *found;
4305c6c1daeSBarry Smith   size_t         i,n,m = PETSC_MAX_INT;
4315c6c1daeSBarry Smith 
4325c6c1daeSBarry Smith   PetscFunctionBegin;
4335c6c1daeSBarry Smith   /* if there is an e in string DO NOT strip trailing zeros */
4345c6c1daeSBarry Smith   ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr);
4355c6c1daeSBarry Smith   if (found) PetscFunctionReturn(0);
4365c6c1daeSBarry Smith 
4375c6c1daeSBarry Smith   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
4385c6c1daeSBarry Smith   /* locate decimal point */
4395c6c1daeSBarry Smith   for (i=0; i<n; i++) {
4405c6c1daeSBarry Smith     if (buf[i] == '.') {m = i; break;}
4415c6c1daeSBarry Smith   }
4425c6c1daeSBarry Smith   /* if not decimal point then no zeros to remove */
4435c6c1daeSBarry Smith   if (m == PETSC_MAX_INT) PetscFunctionReturn(0);
4445c6c1daeSBarry Smith   /* start at right end of string removing 0s */
4455c6c1daeSBarry Smith   for (i=n-1; i>m; i++) {
4465c6c1daeSBarry Smith     if (buf[i] != '0') PetscFunctionReturn(0);
4475c6c1daeSBarry Smith     buf[i] = 0;
4485c6c1daeSBarry Smith   }
4495c6c1daeSBarry Smith   PetscFunctionReturn(0);
4505c6c1daeSBarry Smith }
4515c6c1daeSBarry Smith 
4525c6c1daeSBarry Smith /*
4535c6c1daeSBarry Smith     Removes leading 0 from 0.22 or -0.22
4545c6c1daeSBarry Smith */
4555c6c1daeSBarry Smith PetscErrorCode PetscStripInitialZero(char *buf)
4565c6c1daeSBarry Smith {
4575c6c1daeSBarry Smith   PetscErrorCode ierr;
4585c6c1daeSBarry Smith   size_t         i,n;
4595c6c1daeSBarry Smith 
4605c6c1daeSBarry Smith   PetscFunctionBegin;
4615c6c1daeSBarry Smith   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
4625c6c1daeSBarry Smith   if (buf[0] == '0') {
463a297a907SKarl Rupp     for (i=0; i<n; i++) buf[i] = buf[i+1];
4645c6c1daeSBarry Smith   } else if (buf[0] == '-' && buf[1] == '0') {
465a297a907SKarl Rupp     for (i=1; i<n; i++) buf[i] = buf[i+1];
4665c6c1daeSBarry Smith   }
4675c6c1daeSBarry Smith   PetscFunctionReturn(0);
4685c6c1daeSBarry Smith }
4695c6c1daeSBarry Smith 
4705c6c1daeSBarry Smith /*
4715c6c1daeSBarry Smith      Removes the extraneous zeros in numbers like 1.10000e6
4725c6c1daeSBarry Smith */
4735c6c1daeSBarry Smith PetscErrorCode PetscStripZeros(char *buf)
4745c6c1daeSBarry Smith {
4755c6c1daeSBarry Smith   PetscErrorCode ierr;
4765c6c1daeSBarry Smith   size_t         i,j,n;
4775c6c1daeSBarry Smith 
4785c6c1daeSBarry Smith   PetscFunctionBegin;
4795c6c1daeSBarry Smith   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
4805c6c1daeSBarry Smith   if (n<5) PetscFunctionReturn(0);
4815c6c1daeSBarry Smith   for (i=1; i<n-1; i++) {
4825c6c1daeSBarry Smith     if (buf[i] == 'e' && buf[i-1] == '0') {
4835c6c1daeSBarry Smith       for (j=i; j<n+1; j++) buf[j-1] = buf[j];
4845c6c1daeSBarry Smith       ierr = PetscStripZeros(buf);CHKERRQ(ierr);
4855c6c1daeSBarry Smith       PetscFunctionReturn(0);
4865c6c1daeSBarry Smith     }
4875c6c1daeSBarry Smith   }
4885c6c1daeSBarry Smith   PetscFunctionReturn(0);
4895c6c1daeSBarry Smith }
4905c6c1daeSBarry Smith 
4915c6c1daeSBarry Smith /*
4925c6c1daeSBarry Smith       Removes the plus in something like 1.1e+2 or 1.1e+02
4935c6c1daeSBarry Smith */
4945c6c1daeSBarry Smith PetscErrorCode PetscStripZerosPlus(char *buf)
4955c6c1daeSBarry Smith {
4965c6c1daeSBarry Smith   PetscErrorCode ierr;
4975c6c1daeSBarry Smith   size_t         i,j,n;
4985c6c1daeSBarry Smith 
4995c6c1daeSBarry Smith   PetscFunctionBegin;
5005c6c1daeSBarry Smith   ierr = PetscStrlen(buf,&n);CHKERRQ(ierr);
5015c6c1daeSBarry Smith   if (n<5) PetscFunctionReturn(0);
5025c6c1daeSBarry Smith   for (i=1; i<n-2; i++) {
5035c6c1daeSBarry Smith     if (buf[i] == '+') {
5045c6c1daeSBarry Smith       if (buf[i+1] == '0') {
5055c6c1daeSBarry Smith         for (j=i+1; j<n; j++) buf[j-1] = buf[j+1];
5065c6c1daeSBarry Smith         PetscFunctionReturn(0);
5075c6c1daeSBarry Smith       } else {
5085c6c1daeSBarry Smith         for (j=i+1; j<n+1; j++) buf[j-1] = buf[j];
5095c6c1daeSBarry Smith         PetscFunctionReturn(0);
5105c6c1daeSBarry Smith       }
5115c6c1daeSBarry Smith     } else if (buf[i] == '-') {
5125c6c1daeSBarry Smith       if (buf[i+1] == '0') {
5135c6c1daeSBarry Smith         for (j=i+1; j<n; j++) buf[j] = buf[j+1];
5145c6c1daeSBarry Smith         PetscFunctionReturn(0);
5155c6c1daeSBarry Smith       }
5165c6c1daeSBarry Smith     }
5175c6c1daeSBarry Smith   }
5185c6c1daeSBarry Smith   PetscFunctionReturn(0);
5195c6c1daeSBarry Smith }
520