xref: /petsc/src/sys/classes/draw/utils/axisc.c (revision d8e47b638cf8f604a99e9678e1df24f82d959cd7)
1999739cfSJacob Faibussowitsch #include <petsc/private/drawimpl.h> /*I   "petscdraw.h"  I*/
25c6c1daeSBarry Smith 
3999739cfSJacob 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 
9c3339decSBarry Smith   Collective
105c6c1daeSBarry Smith 
112fe279fdSBarry Smith   Input Parameter:
1215229ffcSPierre Jolivet . draw - `PetscDraw` object where axis to be made
135c6c1daeSBarry Smith 
1401d2d390SJose E. Roman   Output Parameter:
155c6c1daeSBarry Smith . axis - the axis datastructure
165c6c1daeSBarry Smith 
17811af0c4SBarry Smith   Note:
18811af0c4SBarry Smith   The MPI communicator that owns the underlying draw object owns the `PetscDrawAxis` object, but calls to set `PetscDrawAxis` options are
19811af0c4SBarry Smith   ignored by all processes except the first MPI rank in the communicator
207e25d57eSBarry Smith 
215c6c1daeSBarry Smith   Level: advanced
225c6c1daeSBarry Smith 
23db781477SPatrick Sanan .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawSPCreate()`, `PetscDrawSP`, `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawLGGetAxis()`, `PetscDrawSPGetAxis()`,
24db781477SPatrick Sanan           `PetscDrawHGGetAxis()`, `PetscDrawBarGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisDestroy()`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetHoldLimits()`,
25db781477SPatrick Sanan           `PetscDrawAxisDraw()`
265c6c1daeSBarry Smith @*/
PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis * axis)27d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisCreate(PetscDraw draw, PetscDrawAxis *axis)
28d71ae5a4SJacob Faibussowitsch {
29e118a51fSLisandro Dalcin   PetscDrawAxis ad;
305c6c1daeSBarry Smith 
315c6c1daeSBarry Smith   PetscFunctionBegin;
325c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
334f572ea9SToby Isaac   PetscAssertPointer(axis, 2);
34e118a51fSLisandro Dalcin 
359566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(ad, PETSC_DRAWAXIS_CLASSID, "DrawAxis", "Draw Axis", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawAxisDestroy, NULL));
369566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)draw));
37e118a51fSLisandro Dalcin   ad->win       = draw;
385c6c1daeSBarry Smith   ad->xticks    = PetscADefTicks;
395c6c1daeSBarry Smith   ad->yticks    = PetscADefTicks;
405c6c1daeSBarry Smith   ad->xlabelstr = PetscADefLabel;
415c6c1daeSBarry Smith   ad->ylabelstr = PetscADefLabel;
425c6c1daeSBarry Smith   ad->ac        = PETSC_DRAW_BLACK;
435c6c1daeSBarry Smith   ad->tc        = PETSC_DRAW_BLACK;
445c6c1daeSBarry Smith   ad->cc        = PETSC_DRAW_BLACK;
45e5ab1681SLisandro Dalcin   ad->xlabel    = NULL;
46e5ab1681SLisandro Dalcin   ad->ylabel    = NULL;
47e5ab1681SLisandro Dalcin   ad->toplabel  = NULL;
485c6c1daeSBarry Smith   *axis         = ad;
493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
505c6c1daeSBarry Smith }
515c6c1daeSBarry Smith 
525c6c1daeSBarry Smith /*@
535c6c1daeSBarry Smith   PetscDrawAxisDestroy - Frees the space used by an axis structure.
545c6c1daeSBarry Smith 
55c3339decSBarry Smith   Collective
565c6c1daeSBarry Smith 
572fe279fdSBarry Smith   Input Parameter:
585c6c1daeSBarry Smith . axis - the axis context
595c6c1daeSBarry Smith 
605c6c1daeSBarry Smith   Level: advanced
615c6c1daeSBarry Smith 
62811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`
635c6c1daeSBarry Smith @*/
PetscDrawAxisDestroy(PetscDrawAxis * axis)64d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis)
65d71ae5a4SJacob Faibussowitsch {
665c6c1daeSBarry Smith   PetscFunctionBegin;
673ba16761SJacob Faibussowitsch   if (!*axis) PetscFunctionReturn(PETSC_SUCCESS);
68e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*axis, PETSC_DRAWAXIS_CLASSID, 1);
69f4f49eeaSPierre Jolivet   if (--((PetscObject)*axis)->refct > 0) {
709371c9d4SSatish Balay     *axis = NULL;
713ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
729371c9d4SSatish Balay   }
735c6c1daeSBarry Smith 
749566063dSJacob Faibussowitsch   PetscCall(PetscFree((*axis)->toplabel));
759566063dSJacob Faibussowitsch   PetscCall(PetscFree((*axis)->xlabel));
769566063dSJacob Faibussowitsch   PetscCall(PetscFree((*axis)->ylabel));
779566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*axis)->win));
789566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(axis));
793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
805c6c1daeSBarry Smith }
815c6c1daeSBarry Smith 
825c6c1daeSBarry Smith /*@
835c6c1daeSBarry Smith   PetscDrawAxisSetColors -  Sets the colors to be used for the axis,
845c6c1daeSBarry Smith   tickmarks, and text.
855c6c1daeSBarry Smith 
86c3339decSBarry Smith   Logically Collective
875c6c1daeSBarry Smith 
885c6c1daeSBarry Smith   Input Parameters:
895c6c1daeSBarry Smith + axis - the axis
905c6c1daeSBarry Smith . ac   - the color of the axis lines
915c6c1daeSBarry Smith . tc   - the color of the tick marks
925c6c1daeSBarry Smith - cc   - the color of the text strings
935c6c1daeSBarry Smith 
945c6c1daeSBarry Smith   Level: advanced
955c6c1daeSBarry Smith 
96811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisDraw()`, `PetscDrawAxisSetLimits()`
975c6c1daeSBarry Smith @*/
PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc)98d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis, int ac, int tc, int cc)
99d71ae5a4SJacob Faibussowitsch {
1005c6c1daeSBarry Smith   PetscFunctionBegin;
101e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
1025b399a63SLisandro Dalcin   PetscValidLogicalCollectiveInt(axis, ac, 2);
1035b399a63SLisandro Dalcin   PetscValidLogicalCollectiveInt(axis, tc, 3);
1045b399a63SLisandro Dalcin   PetscValidLogicalCollectiveInt(axis, cc, 4);
1059371c9d4SSatish Balay   axis->ac = ac;
1069371c9d4SSatish Balay   axis->tc = tc;
1079371c9d4SSatish Balay   axis->cc = cc;
1083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1095c6c1daeSBarry Smith }
1105c6c1daeSBarry Smith 
111cc4c1da9SBarry Smith /*@
1125c6c1daeSBarry Smith   PetscDrawAxisSetLabels -  Sets the x and y axis labels.
1135c6c1daeSBarry Smith 
114c3339decSBarry Smith   Logically Collective
1155c6c1daeSBarry Smith 
1165c6c1daeSBarry Smith   Input Parameters:
1175c6c1daeSBarry Smith + axis   - the axis
1185c6c1daeSBarry Smith . top    - the label at the top of the image
11910450e9eSJacob Faibussowitsch . xlabel - the x axis label
12010450e9eSJacob Faibussowitsch - ylabel - the y axis label
1215c6c1daeSBarry Smith 
1222fe279fdSBarry Smith   Level: advanced
1232fe279fdSBarry Smith 
12495452b02SPatrick Sanan   Notes:
125811af0c4SBarry Smith   Must be called before `PetscDrawAxisDraw()` or `PetscDrawLGDraw()`
126811af0c4SBarry Smith 
1275c6c1daeSBarry Smith   There should be no newlines in the arguments
1285c6c1daeSBarry Smith 
129811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisDraw()`, `PetscDrawAxisSetLimits()`
1305c6c1daeSBarry Smith @*/
PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[])131d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis, const char top[], const char xlabel[], const char ylabel[])
132d71ae5a4SJacob Faibussowitsch {
1335c6c1daeSBarry Smith   PetscFunctionBegin;
134e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
1359566063dSJacob Faibussowitsch   PetscCall(PetscFree(axis->xlabel));
1369566063dSJacob Faibussowitsch   PetscCall(PetscFree(axis->ylabel));
1379566063dSJacob Faibussowitsch   PetscCall(PetscFree(axis->toplabel));
1389566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(xlabel, &axis->xlabel));
1399566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(ylabel, &axis->ylabel));
1409566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(top, &axis->toplabel));
1413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1425c6c1daeSBarry Smith }
1435c6c1daeSBarry Smith 
14471917b75SLisandro Dalcin /*@
14571917b75SLisandro Dalcin   PetscDrawAxisSetLimits -  Sets the limits (in user coords) of the axis
14671917b75SLisandro Dalcin 
147c3339decSBarry Smith   Logically Collective
14871917b75SLisandro Dalcin 
14971917b75SLisandro Dalcin   Input Parameters:
15071917b75SLisandro Dalcin + axis - the axis
15110450e9eSJacob Faibussowitsch . xmin - the lower x limit
15210450e9eSJacob Faibussowitsch . xmax - the upper x limit
15310450e9eSJacob Faibussowitsch . ymin - the lower y limit
15410450e9eSJacob Faibussowitsch - ymax - the upper y limit
15571917b75SLisandro Dalcin 
156811af0c4SBarry Smith   Options Database Key:
15771917b75SLisandro Dalcin . -drawaxis_hold - hold the initial set of axis limits for future plotting
15871917b75SLisandro Dalcin 
15971917b75SLisandro Dalcin   Level: advanced
16071917b75SLisandro Dalcin 
161db781477SPatrick Sanan .seealso: `PetscDrawAxisSetHoldLimits()`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
16271917b75SLisandro Dalcin @*/
PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax)163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetLimits(PetscDrawAxis axis, PetscReal xmin, PetscReal xmax, PetscReal ymin, PetscReal ymax)
164d71ae5a4SJacob Faibussowitsch {
16571917b75SLisandro Dalcin   PetscFunctionBegin;
16671917b75SLisandro Dalcin   PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
1673ba16761SJacob Faibussowitsch   if (axis->hold) PetscFunctionReturn(PETSC_SUCCESS);
16871917b75SLisandro Dalcin   axis->xlow  = xmin;
16971917b75SLisandro Dalcin   axis->xhigh = xmax;
17071917b75SLisandro Dalcin   axis->ylow  = ymin;
17171917b75SLisandro Dalcin   axis->yhigh = ymax;
1729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(((PetscObject)axis)->options, ((PetscObject)axis)->prefix, "-drawaxis_hold", &axis->hold));
1733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17471917b75SLisandro Dalcin }
17571917b75SLisandro Dalcin 
17671917b75SLisandro Dalcin /*@
17771917b75SLisandro Dalcin   PetscDrawAxisGetLimits -  Gets the limits (in user coords) of the axis
17871917b75SLisandro Dalcin 
17971917b75SLisandro Dalcin   Not Collective
18071917b75SLisandro Dalcin 
18171917b75SLisandro Dalcin   Input Parameters:
18271917b75SLisandro Dalcin + axis - the axis
18310450e9eSJacob Faibussowitsch . xmin - the lower x limit
18410450e9eSJacob Faibussowitsch . xmax - the upper x limit
18510450e9eSJacob Faibussowitsch . ymin - the lower y limit
18610450e9eSJacob Faibussowitsch - ymax - the upper y limit
18771917b75SLisandro Dalcin 
18871917b75SLisandro Dalcin   Level: advanced
18971917b75SLisandro Dalcin 
190db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetHoldLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
19171917b75SLisandro Dalcin @*/
PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal * xmin,PetscReal * xmax,PetscReal * ymin,PetscReal * ymax)192d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisGetLimits(PetscDrawAxis axis, PetscReal *xmin, PetscReal *xmax, PetscReal *ymin, PetscReal *ymax)
193d71ae5a4SJacob Faibussowitsch {
19471917b75SLisandro Dalcin   PetscFunctionBegin;
19571917b75SLisandro Dalcin   PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
196bb046f40SHong Zhang   if (xmin) *xmin = axis->xlow;
197bb046f40SHong Zhang   if (xmax) *xmax = axis->xhigh;
198bb046f40SHong Zhang   if (ymin) *ymin = axis->ylow;
199bb046f40SHong Zhang   if (ymax) *ymax = axis->yhigh;
2003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20171917b75SLisandro Dalcin }
20271917b75SLisandro Dalcin 
2035c6c1daeSBarry Smith /*@
2045c6c1daeSBarry Smith   PetscDrawAxisSetHoldLimits -  Causes an axis to keep the same limits until this is called
2055c6c1daeSBarry Smith   again
2065c6c1daeSBarry Smith 
207c3339decSBarry Smith   Logically Collective
2085c6c1daeSBarry Smith 
2095c6c1daeSBarry Smith   Input Parameters:
2105c6c1daeSBarry Smith + axis - the axis
211811af0c4SBarry Smith - hold - `PETSC_TRUE` - hold current limits, `PETSC_FALSE` allow limits to be changed
2125c6c1daeSBarry Smith 
2135c6c1daeSBarry Smith   Level: advanced
2145c6c1daeSBarry Smith 
215811af0c4SBarry Smith   Note:
216811af0c4SBarry Smith   Once this has been called with `PETSC_TRUE` the limits will not change if you call
217811af0c4SBarry Smith   `PetscDrawAxisSetLimits()` until you call this with `PETSC_FALSE`
2185c6c1daeSBarry Smith 
219db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
2205c6c1daeSBarry Smith @*/
PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold)221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis, PetscBool hold)
222d71ae5a4SJacob Faibussowitsch {
2235c6c1daeSBarry Smith   PetscFunctionBegin;
224e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
2255b399a63SLisandro Dalcin   PetscValidLogicalCollectiveBool(axis, hold, 2);
2265c6c1daeSBarry Smith   axis->hold = hold;
2273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2285c6c1daeSBarry Smith }
2295c6c1daeSBarry Smith 
2305c6c1daeSBarry Smith /*@
231811af0c4SBarry Smith   PetscDrawAxisDraw - draws an axis.
2325c6c1daeSBarry Smith 
233c3339decSBarry Smith   Collective
2345c6c1daeSBarry Smith 
2355c6c1daeSBarry Smith   Input Parameter:
236811af0c4SBarry Smith . axis - `PetscDrawAxis` structure
2375c6c1daeSBarry Smith 
2385c6c1daeSBarry Smith   Level: advanced
2395c6c1daeSBarry Smith 
2405c6c1daeSBarry Smith   Note:
2415c6c1daeSBarry Smith   This draws the actual axis.  The limits etc have already been set.
2425c6c1daeSBarry Smith   By picking special routines for the ticks and labels, special
2435c6c1daeSBarry Smith   effects may be generated.  These routines are part of the Axis
2445c6c1daeSBarry Smith   structure (axis).
2450afdd333SBarry Smith 
246db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()`
2475c6c1daeSBarry Smith @*/
PetscDrawAxisDraw(PetscDrawAxis axis)248d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis)
249d71ae5a4SJacob Faibussowitsch {
250e118a51fSLisandro Dalcin   int         i, ntick, numx, numy, ac, tc, cc;
251e118a51fSLisandro Dalcin   PetscMPIInt rank;
25271917b75SLisandro Dalcin   size_t      len, ytlen = 0;
253*dd460d27SBarry Smith   PetscReal   coors[4] = {0, 0, 0, 0}, tickloc[PETSC_DRAW_AXIS_MAX_SEGMENTS], sep, tw, th;
25471917b75SLisandro Dalcin   PetscReal   xl, xr, yl, yr, dxl = 0, dyl = 0, dxr = 0, dyr = 0;
2555c6c1daeSBarry Smith   char       *p;
256e118a51fSLisandro Dalcin   PetscDraw   draw;
257e118a51fSLisandro Dalcin   PetscBool   isnull;
2585c6c1daeSBarry Smith 
2595c6c1daeSBarry Smith   PetscFunctionBegin;
260e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1);
2619566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(axis->win, &isnull));
2623ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
2639566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)axis), &rank));
2645c6c1daeSBarry Smith 
2658f69470aSLisandro Dalcin   draw = axis->win;
2665b399a63SLisandro Dalcin 
2679371c9d4SSatish Balay   ac = axis->ac;
2689371c9d4SSatish Balay   tc = axis->tc;
2699371c9d4SSatish Balay   cc = axis->cc;
2709371c9d4SSatish Balay   if (axis->xlow == axis->xhigh) {
2719371c9d4SSatish Balay     axis->xlow -= .5;
2729371c9d4SSatish Balay     axis->xhigh += .5;
2739371c9d4SSatish Balay   }
2749371c9d4SSatish Balay   if (axis->ylow == axis->yhigh) {
2759371c9d4SSatish Balay     axis->ylow -= .5;
2769371c9d4SSatish Balay     axis->yhigh += .5;
2779371c9d4SSatish Balay   }
278e118a51fSLisandro Dalcin 
279d0609cedSBarry Smith   PetscDrawCollectiveBegin(draw);
28071917b75SLisandro Dalcin   if (rank) goto finally;
28171917b75SLisandro Dalcin 
282da81f932SPierre Jolivet   /* get canonical string size */
2839566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, 0, 0, 1, 1));
2849566063dSJacob Faibussowitsch   PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
28571917b75SLisandro Dalcin   /* lower spacing */
28671917b75SLisandro Dalcin   if (axis->xlabelstr) dyl += 1.5 * th;
28771917b75SLisandro Dalcin   if (axis->xlabel) dyl += 1.5 * th;
28871917b75SLisandro Dalcin   /* left spacing */
28971917b75SLisandro Dalcin   if (axis->ylabelstr) dxl += 7.5 * tw;
29071917b75SLisandro Dalcin   if (axis->ylabel) dxl += 2.0 * tw;
29171917b75SLisandro Dalcin   /* right and top spacing */
29271917b75SLisandro Dalcin   if (axis->xlabelstr) dxr = 2.5 * tw;
29371917b75SLisandro Dalcin   if (axis->ylabelstr) dyr = 0.5 * th;
29471917b75SLisandro Dalcin   if (axis->toplabel) dyr = 1.5 * th;
29571917b75SLisandro Dalcin   /* extra spacing */
2969371c9d4SSatish Balay   dxl += 0.7 * tw;
2979371c9d4SSatish Balay   dxr += 0.5 * tw;
2989371c9d4SSatish Balay   dyl += 0.2 * th;
2999371c9d4SSatish Balay   dyr += 0.2 * th;
30071917b75SLisandro Dalcin   /* determine coordinates */
30171917b75SLisandro Dalcin   xl = (dxl * axis->xhigh + dxr * axis->xlow - axis->xlow) / (dxl + dxr - 1);
30271917b75SLisandro Dalcin   xr = (dxl * axis->xhigh + dxr * axis->xlow - axis->xhigh) / (dxl + dxr - 1);
30371917b75SLisandro Dalcin   yl = (dyl * axis->yhigh + dyr * axis->ylow - axis->ylow) / (dyl + dyr - 1);
30471917b75SLisandro Dalcin   yr = (dyl * axis->yhigh + dyr * axis->ylow - axis->yhigh) / (dyl + dyr - 1);
3059566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
3069566063dSJacob Faibussowitsch   PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
3075c6c1daeSBarry Smith 
30871917b75SLisandro Dalcin   /* PetscDraw the axis lines */
3099566063dSJacob Faibussowitsch   PetscCall(PetscDrawLine(draw, axis->xlow, axis->ylow, axis->xhigh, axis->ylow, ac));
3109566063dSJacob Faibussowitsch   PetscCall(PetscDrawLine(draw, axis->xlow, axis->ylow, axis->xlow, axis->yhigh, ac));
3119566063dSJacob Faibussowitsch   PetscCall(PetscDrawLine(draw, axis->xlow, axis->yhigh, axis->xhigh, axis->yhigh, ac));
3129566063dSJacob Faibussowitsch   PetscCall(PetscDrawLine(draw, axis->xhigh, axis->ylow, axis->xhigh, axis->yhigh, ac));
3135c6c1daeSBarry Smith 
31471917b75SLisandro Dalcin   /* PetscDraw the top label */
3155c6c1daeSBarry Smith   if (axis->toplabel) {
31671917b75SLisandro Dalcin     PetscReal x = (axis->xlow + axis->xhigh) / 2, y = axis->yhigh + 0.5 * th;
3176497c311SBarry Smith 
3189566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, x, y, cc, axis->toplabel));
3195c6c1daeSBarry Smith   }
3205c6c1daeSBarry Smith 
32171917b75SLisandro Dalcin   /* PetscDraw the X ticks and labels */
3225c6c1daeSBarry Smith   if (axis->xticks) {
3239371c9d4SSatish Balay     numx = (int)(.15 * (axis->xhigh - axis->xlow) / tw);
3249371c9d4SSatish Balay     numx = PetscClipInterval(numx, 2, 6);
3259566063dSJacob Faibussowitsch     PetscCall((*axis->xticks)(axis->xlow, axis->xhigh, numx, &ntick, tickloc, PETSC_DRAW_AXIS_MAX_SEGMENTS));
3265c6c1daeSBarry Smith     /* PetscDraw in tick marks */
3275c6c1daeSBarry Smith     for (i = 0; i < ntick; i++) {
3289566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, tickloc[i], axis->ylow, tickloc[i], axis->ylow + .5 * th, tc));
3299566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, tickloc[i], axis->yhigh, tickloc[i], axis->yhigh - .5 * th, tc));
3305c6c1daeSBarry Smith     }
3315c6c1daeSBarry Smith     /* label ticks */
3325c6c1daeSBarry Smith     if (axis->xlabelstr) {
33371917b75SLisandro Dalcin       for (i = 0; i < ntick; i++) {
3345c6c1daeSBarry Smith         if (i < ntick - 1) sep = tickloc[i + 1] - tickloc[i];
3355c6c1daeSBarry Smith         else if (i > 0) sep = tickloc[i] - tickloc[i - 1];
3365c6c1daeSBarry Smith         else sep = 0.0;
3379566063dSJacob Faibussowitsch         PetscCall((*axis->xlabelstr)(tickloc[i], sep, &p));
3389566063dSJacob Faibussowitsch         PetscCall(PetscDrawStringCentered(draw, tickloc[i], axis->ylow - 1.5 * th, cc, p));
3395c6c1daeSBarry Smith       }
3405c6c1daeSBarry Smith     }
3415c6c1daeSBarry Smith   }
3425c6c1daeSBarry Smith   if (axis->xlabel) {
34371917b75SLisandro Dalcin     PetscReal x = (axis->xlow + axis->xhigh) / 2, y = axis->ylow - 1.5 * th;
3446497c311SBarry Smith 
34571917b75SLisandro Dalcin     if (axis->xlabelstr) y -= 1.5 * th;
3469566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringCentered(draw, x, y, cc, axis->xlabel));
3475c6c1daeSBarry Smith   }
34871917b75SLisandro Dalcin 
34971917b75SLisandro Dalcin   /* PetscDraw the Y ticks and labels */
3505c6c1daeSBarry Smith   if (axis->yticks) {
3519371c9d4SSatish Balay     numy = (int)(.50 * (axis->yhigh - axis->ylow) / th);
3529371c9d4SSatish Balay     numy = PetscClipInterval(numy, 2, 6);
3539566063dSJacob Faibussowitsch     PetscCall((*axis->yticks)(axis->ylow, axis->yhigh, numy, &ntick, tickloc, PETSC_DRAW_AXIS_MAX_SEGMENTS));
3545c6c1daeSBarry Smith     /* PetscDraw in tick marks */
3555c6c1daeSBarry Smith     for (i = 0; i < ntick; i++) {
3569566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, axis->xlow, tickloc[i], axis->xlow + .5 * tw, tickloc[i], tc));
3579566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, axis->xhigh, tickloc[i], axis->xhigh - .5 * tw, tickloc[i], tc));
3585c6c1daeSBarry Smith     }
3595c6c1daeSBarry Smith     /* label ticks */
3605c6c1daeSBarry Smith     if (axis->ylabelstr) {
36171917b75SLisandro Dalcin       for (i = 0; i < ntick; i++) {
3625c6c1daeSBarry Smith         if (i < ntick - 1) sep = tickloc[i + 1] - tickloc[i];
3635c6c1daeSBarry Smith         else if (i > 0) sep = tickloc[i] - tickloc[i - 1];
3645c6c1daeSBarry Smith         else sep = 0.0;
3659566063dSJacob Faibussowitsch         PetscCall((*axis->ylabelstr)(tickloc[i], sep, &p));
3669371c9d4SSatish Balay         PetscCall(PetscStrlen(p, &len));
3679371c9d4SSatish Balay         ytlen = PetscMax(ytlen, len);
3686497c311SBarry Smith         PetscCall(PetscDrawString(draw, axis->xlow - ((PetscReal)len + .5) * tw, tickloc[i] - .5 * th, cc, p));
3695c6c1daeSBarry Smith       }
3705c6c1daeSBarry Smith     }
3715c6c1daeSBarry Smith   }
3725c6c1daeSBarry Smith   if (axis->ylabel) {
37371917b75SLisandro Dalcin     PetscReal x = axis->xlow - 2.0 * tw, y = (axis->ylow + axis->yhigh) / 2;
3746497c311SBarry Smith 
3756497c311SBarry Smith     if (axis->ylabelstr) x -= ((PetscReal)ytlen + .5) * tw;
3769566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(axis->ylabel, &len));
3776497c311SBarry Smith     PetscCall(PetscDrawStringVertical(draw, x, y + ((PetscReal)len) * th / 2, cc, axis->ylabel));
3785c6c1daeSBarry Smith   }
3795b399a63SLisandro Dalcin 
3809566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &coors[0], &coors[1], &coors[2], &coors[3]));
3815b399a63SLisandro Dalcin finally:
382d0609cedSBarry Smith   PetscDrawCollectiveEnd(draw);
3839566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(coors, 4, MPIU_REAL, 0, PetscObjectComm((PetscObject)draw)));
3849566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, coors[0], coors[1], coors[2], coors[3]));
3853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3865c6c1daeSBarry Smith }
3875c6c1daeSBarry Smith 
38836c9bc0dSBarry Smith /*
38936c9bc0dSBarry Smith     Removes all zeros but one from .0000
39036c9bc0dSBarry Smith */
PetscStripe0(char * buf)391d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripe0(char *buf)
392d71ae5a4SJacob Faibussowitsch {
39336c9bc0dSBarry Smith   size_t    n;
39436c9bc0dSBarry Smith   PetscBool flg;
395bbcf679cSJacob Faibussowitsch   char     *str = NULL;
39636c9bc0dSBarry Smith 
39736c9bc0dSBarry Smith   PetscFunctionBegin;
3989566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(buf, &n));
3999566063dSJacob Faibussowitsch   PetscCall(PetscStrendswith(buf, "e00", &flg));
400a297a907SKarl Rupp   if (flg) buf[n - 3] = 0;
4019566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(buf, "e0", &str));
40236c9bc0dSBarry Smith   if (str) {
40336c9bc0dSBarry Smith     buf[n - 2] = buf[n - 1];
40436c9bc0dSBarry Smith     buf[n - 1] = 0;
40536c9bc0dSBarry Smith   }
4069566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(buf, "e-0", &str));
40736c9bc0dSBarry Smith   if (str) {
40836c9bc0dSBarry Smith     buf[n - 2] = buf[n - 1];
40936c9bc0dSBarry Smith     buf[n - 1] = 0;
41036c9bc0dSBarry Smith   }
4113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41236c9bc0dSBarry Smith }
41336c9bc0dSBarry Smith 
4145c6c1daeSBarry Smith /*
4155c6c1daeSBarry Smith     Removes all zeros but one from .0000
4165c6c1daeSBarry Smith */
PetscStripAllZeros(char * buf)417d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripAllZeros(char *buf)
418d71ae5a4SJacob Faibussowitsch {
4195c6c1daeSBarry Smith   size_t i, n;
4205c6c1daeSBarry Smith 
4215c6c1daeSBarry Smith   PetscFunctionBegin;
4229566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(buf, &n));
4233ba16761SJacob Faibussowitsch   if (buf[0] != '.') PetscFunctionReturn(PETSC_SUCCESS);
4245c6c1daeSBarry Smith   for (i = 1; i < n; i++) {
4253ba16761SJacob Faibussowitsch     if (buf[i] != '0') PetscFunctionReturn(PETSC_SUCCESS);
4265c6c1daeSBarry Smith   }
4275c6c1daeSBarry Smith   buf[0] = '0';
4285c6c1daeSBarry Smith   buf[1] = 0;
4293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4305c6c1daeSBarry Smith }
4315c6c1daeSBarry Smith 
4325c6c1daeSBarry Smith /*
4335c6c1daeSBarry Smith     Removes trailing zeros
4345c6c1daeSBarry Smith */
4354279555eSSatish Balay #if (PETSC_SIZEOF_SIZE_T == 8)
4364279555eSSatish Balay   #define MAX_SIZE_T PETSC_INT64_MAX
4374279555eSSatish Balay #else
4384279555eSSatish Balay   #define MAX_SIZE_T INT_MAX
4394279555eSSatish Balay #endif
PetscStripTrailingZeros(char * buf)440d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripTrailingZeros(char *buf)
441d71ae5a4SJacob Faibussowitsch {
442bbcf679cSJacob Faibussowitsch   char  *found = NULL;
4434279555eSSatish Balay   size_t i, n, m = MAX_SIZE_T;
4445c6c1daeSBarry Smith 
4455c6c1daeSBarry Smith   PetscFunctionBegin;
4465c6c1daeSBarry Smith   /* if there is an e in string DO NOT strip trailing zeros */
4479566063dSJacob Faibussowitsch   PetscCall(PetscStrchr(buf, 'e', &found));
4483ba16761SJacob Faibussowitsch   if (found) PetscFunctionReturn(PETSC_SUCCESS);
4495c6c1daeSBarry Smith 
4509566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(buf, &n));
4515c6c1daeSBarry Smith   /* locate decimal point */
4525c6c1daeSBarry Smith   for (i = 0; i < n; i++) {
4539371c9d4SSatish Balay     if (buf[i] == '.') {
4549371c9d4SSatish Balay       m = i;
4559371c9d4SSatish Balay       break;
4569371c9d4SSatish Balay     }
4575c6c1daeSBarry Smith   }
4585c6c1daeSBarry Smith   /* if not decimal point then no zeros to remove */
4594279555eSSatish Balay   if (m == MAX_SIZE_T) PetscFunctionReturn(PETSC_SUCCESS);
4605c6c1daeSBarry Smith   /* start at right end of string removing 0s */
4615c6c1daeSBarry Smith   for (i = n - 1; i > m; i++) {
4623ba16761SJacob Faibussowitsch     if (buf[i] != '0') PetscFunctionReturn(PETSC_SUCCESS);
4635c6c1daeSBarry Smith     buf[i] = 0;
4645c6c1daeSBarry Smith   }
4653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4665c6c1daeSBarry Smith }
4675c6c1daeSBarry Smith 
4685c6c1daeSBarry Smith /*
4695c6c1daeSBarry Smith     Removes leading 0 from 0.22 or -0.22
4705c6c1daeSBarry Smith */
PetscStripInitialZero(char * buf)471d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripInitialZero(char *buf)
472d71ae5a4SJacob Faibussowitsch {
4735c6c1daeSBarry Smith   size_t i, n;
4745c6c1daeSBarry Smith 
4755c6c1daeSBarry Smith   PetscFunctionBegin;
4769566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(buf, &n));
4775c6c1daeSBarry Smith   if (buf[0] == '0') {
478a297a907SKarl Rupp     for (i = 0; i < n; i++) buf[i] = buf[i + 1];
4795c6c1daeSBarry Smith   } else if (buf[0] == '-' && buf[1] == '0') {
480a297a907SKarl Rupp     for (i = 1; i < n; i++) buf[i] = buf[i + 1];
4815c6c1daeSBarry Smith   }
4823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4835c6c1daeSBarry Smith }
4845c6c1daeSBarry Smith 
4855c6c1daeSBarry Smith /*
4865c6c1daeSBarry Smith      Removes the extraneous zeros in numbers like 1.10000e6
4875c6c1daeSBarry Smith */
PetscStripZeros(char * buf)488d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripZeros(char *buf)
489d71ae5a4SJacob Faibussowitsch {
4905c6c1daeSBarry Smith   size_t i, j, n;
4915c6c1daeSBarry Smith 
4925c6c1daeSBarry Smith   PetscFunctionBegin;
4939566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(buf, &n));
4943ba16761SJacob Faibussowitsch   if (n < 5) PetscFunctionReturn(PETSC_SUCCESS);
4955c6c1daeSBarry Smith   for (i = 1; i < n - 1; i++) {
4965c6c1daeSBarry Smith     if (buf[i] == 'e' && buf[i - 1] == '0') {
4975c6c1daeSBarry Smith       for (j = i; j < n + 1; j++) buf[j - 1] = buf[j];
4989566063dSJacob Faibussowitsch       PetscCall(PetscStripZeros(buf));
4993ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
5005c6c1daeSBarry Smith     }
5015c6c1daeSBarry Smith   }
5023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5035c6c1daeSBarry Smith }
5045c6c1daeSBarry Smith 
5055c6c1daeSBarry Smith /*
5065c6c1daeSBarry Smith       Removes the plus in something like 1.1e+2 or 1.1e+02
5075c6c1daeSBarry Smith */
PetscStripZerosPlus(char * buf)508d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStripZerosPlus(char *buf)
509d71ae5a4SJacob Faibussowitsch {
5105c6c1daeSBarry Smith   size_t i, j, n;
5115c6c1daeSBarry Smith 
5125c6c1daeSBarry Smith   PetscFunctionBegin;
5139566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(buf, &n));
5143ba16761SJacob Faibussowitsch   if (n < 5) PetscFunctionReturn(PETSC_SUCCESS);
5155c6c1daeSBarry Smith   for (i = 1; i < n - 2; i++) {
5165c6c1daeSBarry Smith     if (buf[i] == '+') {
5175c6c1daeSBarry Smith       if (buf[i + 1] == '0') {
5185c6c1daeSBarry Smith         for (j = i + 1; j < n; j++) buf[j - 1] = buf[j + 1];
5193ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
5205c6c1daeSBarry Smith       } else {
5215c6c1daeSBarry Smith         for (j = i + 1; j < n + 1; j++) buf[j - 1] = buf[j];
5223ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
5235c6c1daeSBarry Smith       }
5245c6c1daeSBarry Smith     } else if (buf[i] == '-') {
5255c6c1daeSBarry Smith       if (buf[i + 1] == '0') {
5265c6c1daeSBarry Smith         for (j = i + 1; j < n; j++) buf[j] = buf[j + 1];
5273ba16761SJacob Faibussowitsch         PetscFunctionReturn(PETSC_SUCCESS);
5285c6c1daeSBarry Smith       }
5295c6c1daeSBarry Smith     }
5305c6c1daeSBarry Smith   }
5313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5325c6c1daeSBarry Smith }
533