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 9*811af0c4SBarry Smith Collective on draw 105c6c1daeSBarry Smith 115c6c1daeSBarry Smith Input Parameters: 12*811af0c4SBarry 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 17*811af0c4SBarry Smith Note: 18*811af0c4SBarry Smith The MPI communicator that owns the underlying draw object owns the `PetscDrawAxis` object, but calls to set `PetscDrawAxis` options are 19*811af0c4SBarry 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 @*/ 279371c9d4SSatish Balay PetscErrorCode PetscDrawAxisCreate(PetscDraw draw, PetscDrawAxis *axis) { 28e118a51fSLisandro Dalcin PetscDrawAxis ad; 295c6c1daeSBarry Smith 305c6c1daeSBarry Smith PetscFunctionBegin; 315c6c1daeSBarry Smith PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 325c6c1daeSBarry Smith PetscValidPointer(axis, 2); 33e118a51fSLisandro Dalcin 349566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(ad, PETSC_DRAWAXIS_CLASSID, "DrawAxis", "Draw Axis", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawAxisDestroy, NULL)); 359566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)draw, (PetscObject)ad)); 36a297a907SKarl Rupp 379566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)draw)); 38e118a51fSLisandro Dalcin ad->win = draw; 39e118a51fSLisandro Dalcin 405c6c1daeSBarry Smith ad->xticks = PetscADefTicks; 415c6c1daeSBarry Smith ad->yticks = PetscADefTicks; 425c6c1daeSBarry Smith ad->xlabelstr = PetscADefLabel; 435c6c1daeSBarry Smith ad->ylabelstr = PetscADefLabel; 445c6c1daeSBarry Smith ad->ac = PETSC_DRAW_BLACK; 455c6c1daeSBarry Smith ad->tc = PETSC_DRAW_BLACK; 465c6c1daeSBarry Smith ad->cc = PETSC_DRAW_BLACK; 47e5ab1681SLisandro Dalcin ad->xlabel = NULL; 48e5ab1681SLisandro Dalcin ad->ylabel = NULL; 49e5ab1681SLisandro Dalcin ad->toplabel = NULL; 505c6c1daeSBarry Smith 515c6c1daeSBarry Smith *axis = ad; 525c6c1daeSBarry Smith PetscFunctionReturn(0); 535c6c1daeSBarry Smith } 545c6c1daeSBarry Smith 555c6c1daeSBarry Smith /*@ 565c6c1daeSBarry Smith PetscDrawAxisDestroy - Frees the space used by an axis structure. 575c6c1daeSBarry Smith 58*811af0c4SBarry Smith Collective on axis 595c6c1daeSBarry Smith 605c6c1daeSBarry Smith Input Parameters: 615c6c1daeSBarry Smith . axis - the axis context 625c6c1daeSBarry Smith 635c6c1daeSBarry Smith Level: advanced 645c6c1daeSBarry Smith 65*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis` 665c6c1daeSBarry Smith @*/ 679371c9d4SSatish Balay PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis) { 685c6c1daeSBarry Smith PetscFunctionBegin; 695c6c1daeSBarry Smith if (!*axis) PetscFunctionReturn(0); 70e118a51fSLisandro Dalcin PetscValidHeaderSpecific(*axis, PETSC_DRAWAXIS_CLASSID, 1); 719371c9d4SSatish Balay if (--((PetscObject)(*axis))->refct > 0) { 729371c9d4SSatish Balay *axis = NULL; 739371c9d4SSatish Balay PetscFunctionReturn(0); 749371c9d4SSatish Balay } 755c6c1daeSBarry Smith 769566063dSJacob Faibussowitsch PetscCall(PetscFree((*axis)->toplabel)); 779566063dSJacob Faibussowitsch PetscCall(PetscFree((*axis)->xlabel)); 789566063dSJacob Faibussowitsch PetscCall(PetscFree((*axis)->ylabel)); 799566063dSJacob Faibussowitsch PetscCall(PetscDrawDestroy(&(*axis)->win)); 809566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(axis)); 815c6c1daeSBarry Smith PetscFunctionReturn(0); 825c6c1daeSBarry Smith } 835c6c1daeSBarry Smith 845c6c1daeSBarry Smith /*@ 855c6c1daeSBarry Smith PetscDrawAxisSetColors - Sets the colors to be used for the axis, 865c6c1daeSBarry Smith tickmarks, and text. 875c6c1daeSBarry Smith 88*811af0c4SBarry Smith Logically Collective on axis 895c6c1daeSBarry Smith 905c6c1daeSBarry Smith Input Parameters: 915c6c1daeSBarry Smith + axis - the axis 925c6c1daeSBarry Smith . ac - the color of the axis lines 935c6c1daeSBarry Smith . tc - the color of the tick marks 945c6c1daeSBarry Smith - cc - the color of the text strings 955c6c1daeSBarry Smith 965c6c1daeSBarry Smith Level: advanced 975c6c1daeSBarry Smith 98*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisDraw()`, `PetscDrawAxisSetLimits()` 995c6c1daeSBarry Smith @*/ 1009371c9d4SSatish Balay PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis, int ac, int tc, int cc) { 1015c6c1daeSBarry Smith PetscFunctionBegin; 102e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1); 1035b399a63SLisandro Dalcin PetscValidLogicalCollectiveInt(axis, ac, 2); 1045b399a63SLisandro Dalcin PetscValidLogicalCollectiveInt(axis, tc, 3); 1055b399a63SLisandro Dalcin PetscValidLogicalCollectiveInt(axis, cc, 4); 1069371c9d4SSatish Balay axis->ac = ac; 1079371c9d4SSatish Balay axis->tc = tc; 1089371c9d4SSatish Balay axis->cc = cc; 1095c6c1daeSBarry Smith PetscFunctionReturn(0); 1105c6c1daeSBarry Smith } 1115c6c1daeSBarry Smith 1125c6c1daeSBarry Smith /*@C 1135c6c1daeSBarry Smith PetscDrawAxisSetLabels - Sets the x and y axis labels. 1145c6c1daeSBarry Smith 115*811af0c4SBarry Smith Logically Collective on axis 1165c6c1daeSBarry Smith 1175c6c1daeSBarry Smith Input Parameters: 1185c6c1daeSBarry Smith + axis - the axis 1195c6c1daeSBarry Smith . top - the label at the top of the image 1205c6c1daeSBarry Smith - xlabel,ylabel - the labes for the x and y axis 1215c6c1daeSBarry Smith 12295452b02SPatrick Sanan Notes: 123*811af0c4SBarry Smith Must be called before `PetscDrawAxisDraw()` or `PetscDrawLGDraw()` 124*811af0c4SBarry Smith 1255c6c1daeSBarry Smith There should be no newlines in the arguments 1265c6c1daeSBarry Smith 1275c6c1daeSBarry Smith Level: advanced 1285c6c1daeSBarry Smith 129*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisDraw()`, `PetscDrawAxisSetLimits()` 1305c6c1daeSBarry Smith @*/ 1319371c9d4SSatish Balay PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis, const char top[], const char xlabel[], const char ylabel[]) { 1325c6c1daeSBarry Smith PetscFunctionBegin; 133e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1); 1349566063dSJacob Faibussowitsch PetscCall(PetscFree(axis->xlabel)); 1359566063dSJacob Faibussowitsch PetscCall(PetscFree(axis->ylabel)); 1369566063dSJacob Faibussowitsch PetscCall(PetscFree(axis->toplabel)); 1379566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(xlabel, &axis->xlabel)); 1389566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(ylabel, &axis->ylabel)); 1399566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(top, &axis->toplabel)); 1405c6c1daeSBarry Smith PetscFunctionReturn(0); 1415c6c1daeSBarry Smith } 1425c6c1daeSBarry Smith 14371917b75SLisandro Dalcin /*@ 14471917b75SLisandro Dalcin PetscDrawAxisSetLimits - Sets the limits (in user coords) of the axis 14571917b75SLisandro Dalcin 146*811af0c4SBarry Smith Logically Collective on axis 14771917b75SLisandro Dalcin 14871917b75SLisandro Dalcin Input Parameters: 14971917b75SLisandro Dalcin + axis - the axis 15071917b75SLisandro Dalcin . xmin,xmax - limits in x 15171917b75SLisandro Dalcin - ymin,ymax - limits in y 15271917b75SLisandro Dalcin 153*811af0c4SBarry Smith Options Database Key: 15471917b75SLisandro Dalcin . -drawaxis_hold - hold the initial set of axis limits for future plotting 15571917b75SLisandro Dalcin 15671917b75SLisandro Dalcin Level: advanced 15771917b75SLisandro Dalcin 158db781477SPatrick Sanan .seealso: `PetscDrawAxisSetHoldLimits()`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()` 15971917b75SLisandro Dalcin @*/ 1609371c9d4SSatish Balay PetscErrorCode PetscDrawAxisSetLimits(PetscDrawAxis axis, PetscReal xmin, PetscReal xmax, PetscReal ymin, PetscReal ymax) { 16171917b75SLisandro Dalcin PetscFunctionBegin; 16271917b75SLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1); 16371917b75SLisandro Dalcin if (axis->hold) PetscFunctionReturn(0); 16471917b75SLisandro Dalcin axis->xlow = xmin; 16571917b75SLisandro Dalcin axis->xhigh = xmax; 16671917b75SLisandro Dalcin axis->ylow = ymin; 16771917b75SLisandro Dalcin axis->yhigh = ymax; 1689566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)axis)->options, ((PetscObject)axis)->prefix, "-drawaxis_hold", &axis->hold)); 16971917b75SLisandro Dalcin PetscFunctionReturn(0); 17071917b75SLisandro Dalcin } 17171917b75SLisandro Dalcin 17271917b75SLisandro Dalcin /*@ 17371917b75SLisandro Dalcin PetscDrawAxisGetLimits - Gets the limits (in user coords) of the axis 17471917b75SLisandro Dalcin 17571917b75SLisandro Dalcin Not Collective 17671917b75SLisandro Dalcin 17771917b75SLisandro Dalcin Input Parameters: 17871917b75SLisandro Dalcin + axis - the axis 17971917b75SLisandro Dalcin . xmin,xmax - limits in x 18071917b75SLisandro Dalcin - ymin,ymax - limits in y 18171917b75SLisandro Dalcin 18271917b75SLisandro Dalcin Level: advanced 18371917b75SLisandro Dalcin 184db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisSetHoldLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()` 18571917b75SLisandro Dalcin @*/ 1869371c9d4SSatish Balay PetscErrorCode PetscDrawAxisGetLimits(PetscDrawAxis axis, PetscReal *xmin, PetscReal *xmax, PetscReal *ymin, PetscReal *ymax) { 18771917b75SLisandro Dalcin PetscFunctionBegin; 18871917b75SLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1); 189bb046f40SHong Zhang if (xmin) *xmin = axis->xlow; 190bb046f40SHong Zhang if (xmax) *xmax = axis->xhigh; 191bb046f40SHong Zhang if (ymin) *ymin = axis->ylow; 192bb046f40SHong Zhang if (ymax) *ymax = axis->yhigh; 19371917b75SLisandro Dalcin PetscFunctionReturn(0); 19471917b75SLisandro Dalcin } 19571917b75SLisandro Dalcin 1965c6c1daeSBarry Smith /*@ 1975c6c1daeSBarry Smith PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called 1985c6c1daeSBarry Smith again 1995c6c1daeSBarry Smith 200*811af0c4SBarry Smith Logically Collective on axis 2015c6c1daeSBarry Smith 2025c6c1daeSBarry Smith Input Parameters: 2035c6c1daeSBarry Smith + axis - the axis 204*811af0c4SBarry Smith - hold - `PETSC_TRUE` - hold current limits, `PETSC_FALSE` allow limits to be changed 2055c6c1daeSBarry Smith 2065c6c1daeSBarry Smith Level: advanced 2075c6c1daeSBarry Smith 208*811af0c4SBarry Smith Note: 209*811af0c4SBarry Smith Once this has been called with `PETSC_TRUE` the limits will not change if you call 210*811af0c4SBarry Smith `PetscDrawAxisSetLimits()` until you call this with `PETSC_FALSE` 2115c6c1daeSBarry Smith 212db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()` 2135c6c1daeSBarry Smith @*/ 2149371c9d4SSatish Balay PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis, PetscBool hold) { 2155c6c1daeSBarry Smith PetscFunctionBegin; 216e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1); 2175b399a63SLisandro Dalcin PetscValidLogicalCollectiveBool(axis, hold, 2); 2185c6c1daeSBarry Smith axis->hold = hold; 2195c6c1daeSBarry Smith PetscFunctionReturn(0); 2205c6c1daeSBarry Smith } 2215c6c1daeSBarry Smith 2225c6c1daeSBarry Smith /*@ 223*811af0c4SBarry Smith PetscDrawAxisDraw - draws an axis. 2245c6c1daeSBarry Smith 225*811af0c4SBarry Smith Collective on axis 2265c6c1daeSBarry Smith 2275c6c1daeSBarry Smith Input Parameter: 228*811af0c4SBarry Smith . axis - `PetscDrawAxis` structure 2295c6c1daeSBarry Smith 2305c6c1daeSBarry Smith Level: advanced 2315c6c1daeSBarry Smith 2325c6c1daeSBarry Smith Note: 2335c6c1daeSBarry Smith This draws the actual axis. The limits etc have already been set. 2345c6c1daeSBarry Smith By picking special routines for the ticks and labels, special 2355c6c1daeSBarry Smith effects may be generated. These routines are part of the Axis 2365c6c1daeSBarry Smith structure (axis). 2370afdd333SBarry Smith 238db781477SPatrick Sanan .seealso: `PetscDrawAxisCreate()`, `PetscDrawAxis`, `PetscDrawAxisGetLimits()`, `PetscDrawAxisSetLimits()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetColors()` 2395c6c1daeSBarry Smith @*/ 2409371c9d4SSatish Balay PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis) { 241e118a51fSLisandro Dalcin int i, ntick, numx, numy, ac, tc, cc; 242e118a51fSLisandro Dalcin PetscMPIInt rank; 24371917b75SLisandro Dalcin size_t len, ytlen = 0; 244999739cfSJacob Faibussowitsch PetscReal coors[4], tickloc[PETSC_DRAW_AXIS_MAX_SEGMENTS], sep, tw, th; 24571917b75SLisandro Dalcin PetscReal xl, xr, yl, yr, dxl = 0, dyl = 0, dxr = 0, dyr = 0; 2465c6c1daeSBarry Smith char *p; 247e118a51fSLisandro Dalcin PetscDraw draw; 248e118a51fSLisandro Dalcin PetscBool isnull; 2495c6c1daeSBarry Smith 2505c6c1daeSBarry Smith PetscFunctionBegin; 251e118a51fSLisandro Dalcin PetscValidHeaderSpecific(axis, PETSC_DRAWAXIS_CLASSID, 1); 2529566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(axis->win, &isnull)); 253e118a51fSLisandro Dalcin if (isnull) PetscFunctionReturn(0); 2549566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)axis), &rank)); 2555c6c1daeSBarry Smith 2568f69470aSLisandro Dalcin draw = axis->win; 2575b399a63SLisandro Dalcin 2589371c9d4SSatish Balay ac = axis->ac; 2599371c9d4SSatish Balay tc = axis->tc; 2609371c9d4SSatish Balay cc = axis->cc; 2619371c9d4SSatish Balay if (axis->xlow == axis->xhigh) { 2629371c9d4SSatish Balay axis->xlow -= .5; 2639371c9d4SSatish Balay axis->xhigh += .5; 2649371c9d4SSatish Balay } 2659371c9d4SSatish Balay if (axis->ylow == axis->yhigh) { 2669371c9d4SSatish Balay axis->ylow -= .5; 2679371c9d4SSatish Balay axis->yhigh += .5; 2689371c9d4SSatish Balay } 269e118a51fSLisandro Dalcin 270d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 27171917b75SLisandro Dalcin if (rank) goto finally; 27271917b75SLisandro Dalcin 27371917b75SLisandro Dalcin /* get cannonical string size */ 2749566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, 0, 0, 1, 1)); 2759566063dSJacob Faibussowitsch PetscCall(PetscDrawStringGetSize(draw, &tw, &th)); 27671917b75SLisandro Dalcin /* lower spacing */ 27771917b75SLisandro Dalcin if (axis->xlabelstr) dyl += 1.5 * th; 27871917b75SLisandro Dalcin if (axis->xlabel) dyl += 1.5 * th; 27971917b75SLisandro Dalcin /* left spacing */ 28071917b75SLisandro Dalcin if (axis->ylabelstr) dxl += 7.5 * tw; 28171917b75SLisandro Dalcin if (axis->ylabel) dxl += 2.0 * tw; 28271917b75SLisandro Dalcin /* right and top spacing */ 28371917b75SLisandro Dalcin if (axis->xlabelstr) dxr = 2.5 * tw; 28471917b75SLisandro Dalcin if (axis->ylabelstr) dyr = 0.5 * th; 28571917b75SLisandro Dalcin if (axis->toplabel) dyr = 1.5 * th; 28671917b75SLisandro Dalcin /* extra spacing */ 2879371c9d4SSatish Balay dxl += 0.7 * tw; 2889371c9d4SSatish Balay dxr += 0.5 * tw; 2899371c9d4SSatish Balay dyl += 0.2 * th; 2909371c9d4SSatish Balay dyr += 0.2 * th; 29171917b75SLisandro Dalcin /* determine coordinates */ 29271917b75SLisandro Dalcin xl = (dxl * axis->xhigh + dxr * axis->xlow - axis->xlow) / (dxl + dxr - 1); 29371917b75SLisandro Dalcin xr = (dxl * axis->xhigh + dxr * axis->xlow - axis->xhigh) / (dxl + dxr - 1); 29471917b75SLisandro Dalcin yl = (dyl * axis->yhigh + dyr * axis->ylow - axis->ylow) / (dyl + dyr - 1); 29571917b75SLisandro Dalcin yr = (dyl * axis->yhigh + dyr * axis->ylow - axis->yhigh) / (dyl + dyr - 1); 2969566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 2979566063dSJacob Faibussowitsch PetscCall(PetscDrawStringGetSize(draw, &tw, &th)); 2985c6c1daeSBarry Smith 29971917b75SLisandro Dalcin /* PetscDraw the axis lines */ 3009566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, axis->ylow, axis->xhigh, axis->ylow, ac)); 3019566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, axis->ylow, axis->xlow, axis->yhigh, ac)); 3029566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, axis->yhigh, axis->xhigh, axis->yhigh, ac)); 3039566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xhigh, axis->ylow, axis->xhigh, axis->yhigh, ac)); 3045c6c1daeSBarry Smith 30571917b75SLisandro Dalcin /* PetscDraw the top label */ 3065c6c1daeSBarry Smith if (axis->toplabel) { 30771917b75SLisandro Dalcin PetscReal x = (axis->xlow + axis->xhigh) / 2, y = axis->yhigh + 0.5 * th; 3089566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, x, y, cc, axis->toplabel)); 3095c6c1daeSBarry Smith } 3105c6c1daeSBarry Smith 31171917b75SLisandro Dalcin /* PetscDraw the X ticks and labels */ 3125c6c1daeSBarry Smith if (axis->xticks) { 3139371c9d4SSatish Balay numx = (int)(.15 * (axis->xhigh - axis->xlow) / tw); 3149371c9d4SSatish Balay numx = PetscClipInterval(numx, 2, 6); 3159566063dSJacob Faibussowitsch PetscCall((*axis->xticks)(axis->xlow, axis->xhigh, numx, &ntick, tickloc, PETSC_DRAW_AXIS_MAX_SEGMENTS)); 3165c6c1daeSBarry Smith /* PetscDraw in tick marks */ 3175c6c1daeSBarry Smith for (i = 0; i < ntick; i++) { 3189566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, tickloc[i], axis->ylow, tickloc[i], axis->ylow + .5 * th, tc)); 3199566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, tickloc[i], axis->yhigh, tickloc[i], axis->yhigh - .5 * th, tc)); 3205c6c1daeSBarry Smith } 3215c6c1daeSBarry Smith /* label ticks */ 3225c6c1daeSBarry Smith if (axis->xlabelstr) { 32371917b75SLisandro Dalcin for (i = 0; i < ntick; i++) { 3245c6c1daeSBarry Smith if (i < ntick - 1) sep = tickloc[i + 1] - tickloc[i]; 3255c6c1daeSBarry Smith else if (i > 0) sep = tickloc[i] - tickloc[i - 1]; 3265c6c1daeSBarry Smith else sep = 0.0; 3279566063dSJacob Faibussowitsch PetscCall((*axis->xlabelstr)(tickloc[i], sep, &p)); 3289566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, tickloc[i], axis->ylow - 1.5 * th, cc, p)); 3295c6c1daeSBarry Smith } 3305c6c1daeSBarry Smith } 3315c6c1daeSBarry Smith } 3325c6c1daeSBarry Smith if (axis->xlabel) { 33371917b75SLisandro Dalcin PetscReal x = (axis->xlow + axis->xhigh) / 2, y = axis->ylow - 1.5 * th; 33471917b75SLisandro Dalcin if (axis->xlabelstr) y -= 1.5 * th; 3359566063dSJacob Faibussowitsch PetscCall(PetscDrawStringCentered(draw, x, y, cc, axis->xlabel)); 3365c6c1daeSBarry Smith } 33771917b75SLisandro Dalcin 33871917b75SLisandro Dalcin /* PetscDraw the Y ticks and labels */ 3395c6c1daeSBarry Smith if (axis->yticks) { 3409371c9d4SSatish Balay numy = (int)(.50 * (axis->yhigh - axis->ylow) / th); 3419371c9d4SSatish Balay numy = PetscClipInterval(numy, 2, 6); 3429566063dSJacob Faibussowitsch PetscCall((*axis->yticks)(axis->ylow, axis->yhigh, numy, &ntick, tickloc, PETSC_DRAW_AXIS_MAX_SEGMENTS)); 3435c6c1daeSBarry Smith /* PetscDraw in tick marks */ 3445c6c1daeSBarry Smith for (i = 0; i < ntick; i++) { 3459566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xlow, tickloc[i], axis->xlow + .5 * tw, tickloc[i], tc)); 3469566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, axis->xhigh, tickloc[i], axis->xhigh - .5 * tw, tickloc[i], tc)); 3475c6c1daeSBarry Smith } 3485c6c1daeSBarry Smith /* label ticks */ 3495c6c1daeSBarry Smith if (axis->ylabelstr) { 35071917b75SLisandro Dalcin for (i = 0; i < ntick; i++) { 3515c6c1daeSBarry Smith if (i < ntick - 1) sep = tickloc[i + 1] - tickloc[i]; 3525c6c1daeSBarry Smith else if (i > 0) sep = tickloc[i] - tickloc[i - 1]; 3535c6c1daeSBarry Smith else sep = 0.0; 3549566063dSJacob Faibussowitsch PetscCall((*axis->ylabelstr)(tickloc[i], sep, &p)); 3559371c9d4SSatish Balay PetscCall(PetscStrlen(p, &len)); 3569371c9d4SSatish Balay ytlen = PetscMax(ytlen, len); 3579566063dSJacob Faibussowitsch PetscCall(PetscDrawString(draw, axis->xlow - (len + .5) * tw, tickloc[i] - .5 * th, cc, p)); 3585c6c1daeSBarry Smith } 3595c6c1daeSBarry Smith } 3605c6c1daeSBarry Smith } 3615c6c1daeSBarry Smith if (axis->ylabel) { 36271917b75SLisandro Dalcin PetscReal x = axis->xlow - 2.0 * tw, y = (axis->ylow + axis->yhigh) / 2; 36371917b75SLisandro Dalcin if (axis->ylabelstr) x -= (ytlen + .5) * tw; 3649566063dSJacob Faibussowitsch PetscCall(PetscStrlen(axis->ylabel, &len)); 3659566063dSJacob Faibussowitsch PetscCall(PetscDrawStringVertical(draw, x, y + len * th / 2, cc, axis->ylabel)); 3665c6c1daeSBarry Smith } 3675b399a63SLisandro Dalcin 3689566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &coors[0], &coors[1], &coors[2], &coors[3])); 3695b399a63SLisandro Dalcin finally: 370d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 3719566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(coors, 4, MPIU_REAL, 0, PetscObjectComm((PetscObject)draw))); 3729566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, coors[0], coors[1], coors[2], coors[3])); 3735c6c1daeSBarry Smith PetscFunctionReturn(0); 3745c6c1daeSBarry Smith } 3755c6c1daeSBarry Smith 37636c9bc0dSBarry Smith /* 37736c9bc0dSBarry Smith Removes all zeros but one from .0000 37836c9bc0dSBarry Smith */ 3799371c9d4SSatish Balay PetscErrorCode PetscStripe0(char *buf) { 38036c9bc0dSBarry Smith size_t n; 38136c9bc0dSBarry Smith PetscBool flg; 38236c9bc0dSBarry Smith char *str; 38336c9bc0dSBarry Smith 38436c9bc0dSBarry Smith PetscFunctionBegin; 3859566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n)); 3869566063dSJacob Faibussowitsch PetscCall(PetscStrendswith(buf, "e00", &flg)); 387a297a907SKarl Rupp if (flg) buf[n - 3] = 0; 3889566063dSJacob Faibussowitsch PetscCall(PetscStrstr(buf, "e0", &str)); 38936c9bc0dSBarry Smith if (str) { 39036c9bc0dSBarry Smith buf[n - 2] = buf[n - 1]; 39136c9bc0dSBarry Smith buf[n - 1] = 0; 39236c9bc0dSBarry Smith } 3939566063dSJacob Faibussowitsch PetscCall(PetscStrstr(buf, "e-0", &str)); 39436c9bc0dSBarry Smith if (str) { 39536c9bc0dSBarry Smith buf[n - 2] = buf[n - 1]; 39636c9bc0dSBarry Smith buf[n - 1] = 0; 39736c9bc0dSBarry Smith } 39836c9bc0dSBarry Smith PetscFunctionReturn(0); 39936c9bc0dSBarry Smith } 40036c9bc0dSBarry Smith 4015c6c1daeSBarry Smith /* 4025c6c1daeSBarry Smith Removes all zeros but one from .0000 4035c6c1daeSBarry Smith */ 4049371c9d4SSatish Balay PetscErrorCode PetscStripAllZeros(char *buf) { 4055c6c1daeSBarry Smith size_t i, n; 4065c6c1daeSBarry Smith 4075c6c1daeSBarry Smith PetscFunctionBegin; 4089566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n)); 4095c6c1daeSBarry Smith if (buf[0] != '.') PetscFunctionReturn(0); 4105c6c1daeSBarry Smith for (i = 1; i < n; i++) { 4115c6c1daeSBarry Smith if (buf[i] != '0') PetscFunctionReturn(0); 4125c6c1daeSBarry Smith } 4135c6c1daeSBarry Smith buf[0] = '0'; 4145c6c1daeSBarry Smith buf[1] = 0; 4155c6c1daeSBarry Smith PetscFunctionReturn(0); 4165c6c1daeSBarry Smith } 4175c6c1daeSBarry Smith 4185c6c1daeSBarry Smith /* 4195c6c1daeSBarry Smith Removes trailing zeros 4205c6c1daeSBarry Smith */ 4219371c9d4SSatish Balay PetscErrorCode PetscStripTrailingZeros(char *buf) { 4225c6c1daeSBarry Smith char *found; 4235c6c1daeSBarry Smith size_t i, n, m = PETSC_MAX_INT; 4245c6c1daeSBarry Smith 4255c6c1daeSBarry Smith PetscFunctionBegin; 4265c6c1daeSBarry Smith /* if there is an e in string DO NOT strip trailing zeros */ 4279566063dSJacob Faibussowitsch PetscCall(PetscStrchr(buf, 'e', &found)); 4285c6c1daeSBarry Smith if (found) PetscFunctionReturn(0); 4295c6c1daeSBarry Smith 4309566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n)); 4315c6c1daeSBarry Smith /* locate decimal point */ 4325c6c1daeSBarry Smith for (i = 0; i < n; i++) { 4339371c9d4SSatish Balay if (buf[i] == '.') { 4349371c9d4SSatish Balay m = i; 4359371c9d4SSatish Balay break; 4369371c9d4SSatish Balay } 4375c6c1daeSBarry Smith } 4385c6c1daeSBarry Smith /* if not decimal point then no zeros to remove */ 4395c6c1daeSBarry Smith if (m == PETSC_MAX_INT) PetscFunctionReturn(0); 4405c6c1daeSBarry Smith /* start at right end of string removing 0s */ 4415c6c1daeSBarry Smith for (i = n - 1; i > m; i++) { 4425c6c1daeSBarry Smith if (buf[i] != '0') PetscFunctionReturn(0); 4435c6c1daeSBarry Smith buf[i] = 0; 4445c6c1daeSBarry Smith } 4455c6c1daeSBarry Smith PetscFunctionReturn(0); 4465c6c1daeSBarry Smith } 4475c6c1daeSBarry Smith 4485c6c1daeSBarry Smith /* 4495c6c1daeSBarry Smith Removes leading 0 from 0.22 or -0.22 4505c6c1daeSBarry Smith */ 4519371c9d4SSatish Balay PetscErrorCode PetscStripInitialZero(char *buf) { 4525c6c1daeSBarry Smith size_t i, n; 4535c6c1daeSBarry Smith 4545c6c1daeSBarry Smith PetscFunctionBegin; 4559566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n)); 4565c6c1daeSBarry Smith if (buf[0] == '0') { 457a297a907SKarl Rupp for (i = 0; i < n; i++) buf[i] = buf[i + 1]; 4585c6c1daeSBarry Smith } else if (buf[0] == '-' && buf[1] == '0') { 459a297a907SKarl Rupp for (i = 1; i < n; i++) buf[i] = buf[i + 1]; 4605c6c1daeSBarry Smith } 4615c6c1daeSBarry Smith PetscFunctionReturn(0); 4625c6c1daeSBarry Smith } 4635c6c1daeSBarry Smith 4645c6c1daeSBarry Smith /* 4655c6c1daeSBarry Smith Removes the extraneous zeros in numbers like 1.10000e6 4665c6c1daeSBarry Smith */ 4679371c9d4SSatish Balay PetscErrorCode PetscStripZeros(char *buf) { 4685c6c1daeSBarry Smith size_t i, j, n; 4695c6c1daeSBarry Smith 4705c6c1daeSBarry Smith PetscFunctionBegin; 4719566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n)); 4725c6c1daeSBarry Smith if (n < 5) PetscFunctionReturn(0); 4735c6c1daeSBarry Smith for (i = 1; i < n - 1; i++) { 4745c6c1daeSBarry Smith if (buf[i] == 'e' && buf[i - 1] == '0') { 4755c6c1daeSBarry Smith for (j = i; j < n + 1; j++) buf[j - 1] = buf[j]; 4769566063dSJacob Faibussowitsch PetscCall(PetscStripZeros(buf)); 4775c6c1daeSBarry Smith PetscFunctionReturn(0); 4785c6c1daeSBarry Smith } 4795c6c1daeSBarry Smith } 4805c6c1daeSBarry Smith PetscFunctionReturn(0); 4815c6c1daeSBarry Smith } 4825c6c1daeSBarry Smith 4835c6c1daeSBarry Smith /* 4845c6c1daeSBarry Smith Removes the plus in something like 1.1e+2 or 1.1e+02 4855c6c1daeSBarry Smith */ 4869371c9d4SSatish Balay PetscErrorCode PetscStripZerosPlus(char *buf) { 4875c6c1daeSBarry Smith size_t i, j, n; 4885c6c1daeSBarry Smith 4895c6c1daeSBarry Smith PetscFunctionBegin; 4909566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buf, &n)); 4915c6c1daeSBarry Smith if (n < 5) PetscFunctionReturn(0); 4925c6c1daeSBarry Smith for (i = 1; i < n - 2; i++) { 4935c6c1daeSBarry Smith if (buf[i] == '+') { 4945c6c1daeSBarry Smith if (buf[i + 1] == '0') { 4955c6c1daeSBarry Smith for (j = i + 1; j < n; j++) buf[j - 1] = buf[j + 1]; 4965c6c1daeSBarry Smith PetscFunctionReturn(0); 4975c6c1daeSBarry Smith } else { 4985c6c1daeSBarry Smith for (j = i + 1; j < n + 1; j++) buf[j - 1] = buf[j]; 4995c6c1daeSBarry Smith PetscFunctionReturn(0); 5005c6c1daeSBarry Smith } 5015c6c1daeSBarry Smith } else if (buf[i] == '-') { 5025c6c1daeSBarry Smith if (buf[i + 1] == '0') { 5035c6c1daeSBarry Smith for (j = i + 1; j < n; j++) buf[j] = buf[j + 1]; 5045c6c1daeSBarry Smith PetscFunctionReturn(0); 5055c6c1daeSBarry Smith } 5065c6c1daeSBarry Smith } 5075c6c1daeSBarry Smith } 5085c6c1daeSBarry Smith PetscFunctionReturn(0); 5095c6c1daeSBarry Smith } 510