1 #include <../src/sys/classes/draw/utils/axisimpl.h> 2 3 PetscClassId PETSC_DRAWAXIS_CLASSID = 0; 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "PetscDrawAxisCreate" 7 /*@ 8 PetscDrawAxisCreate - Generate the axis data structure. 9 10 Collective over PetscDraw 11 12 Input Parameters: 13 . win - PetscDraw object where axis to to be made 14 15 Ouput Parameters: 16 . axis - the axis datastructure 17 18 Level: advanced 19 20 @*/ 21 PetscErrorCode PetscDrawAxisCreate(PetscDraw draw,PetscDrawAxis *axis) 22 { 23 PetscDrawAxis ad; 24 PetscObject obj = (PetscObject)draw; 25 PetscErrorCode ierr; 26 PetscBool isnull; 27 28 PetscFunctionBegin; 29 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 30 PetscValidPointer(axis,2); 31 ierr = PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);CHKERRQ(ierr); 32 if (isnull) { 33 ierr = PetscDrawOpenNull(((PetscObject)obj)->comm,(PetscDraw*)axis);CHKERRQ(ierr); 34 (*axis)->win = draw; 35 PetscFunctionReturn(0); 36 } 37 ierr = PetscHeaderCreate(ad,_p_PetscDrawAxis,int,PETSC_DRAWAXIS_CLASSID,0,"PetscDrawAxis","Draw Axis","Draw",((PetscObject)obj)->comm,PetscDrawAxisDestroy,0);CHKERRQ(ierr); 38 ierr = PetscLogObjectParent(draw,ad);CHKERRQ(ierr); 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; 50 51 *axis = ad; 52 PetscFunctionReturn(0); 53 } 54 55 #undef __FUNCT__ 56 #define __FUNCT__ "PetscDrawAxisDestroy" 57 /*@ 58 PetscDrawAxisDestroy - Frees the space used by an axis structure. 59 60 Collective over PetscDrawAxis 61 62 Input Parameters: 63 . axis - the axis context 64 65 Level: advanced 66 67 @*/ 68 PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis) 69 { 70 PetscErrorCode ierr; 71 72 PetscFunctionBegin; 73 if (!*axis) PetscFunctionReturn(0); 74 if (--((PetscObject)(*axis))->refct > 0) PetscFunctionReturn(0); 75 76 ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr); 77 ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr); 78 ierr = PetscFree((*axis)->ylabel);CHKERRQ(ierr); 79 ierr = PetscHeaderDestroy(axis);CHKERRQ(ierr); 80 PetscFunctionReturn(0); 81 } 82 83 #undef __FUNCT__ 84 #define __FUNCT__ "PetscDrawAxisSetColors" 85 /*@ 86 PetscDrawAxisSetColors - Sets the colors to be used for the axis, 87 tickmarks, and text. 88 89 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 90 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 96 97 Level: advanced 98 99 @*/ 100 PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc) 101 { 102 PetscFunctionBegin; 103 if (!axis) PetscFunctionReturn(0); 104 axis->ac = ac; axis->tc = tc; axis->cc = cc; 105 PetscFunctionReturn(0); 106 } 107 108 #undef __FUNCT__ 109 #define __FUNCT__ "PetscDrawAxisSetLabels" 110 /*@C 111 PetscDrawAxisSetLabels - Sets the x and y axis labels. 112 113 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 114 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 119 120 Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw() 121 There should be no newlines in the arguments 122 123 Level: advanced 124 125 @*/ 126 PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[]) 127 { 128 PetscErrorCode ierr; 129 130 PetscFunctionBegin; 131 if (!axis) PetscFunctionReturn(0); 132 ierr = PetscFree(axis->xlabel);CHKERRQ(ierr); 133 ierr = PetscFree(axis->ylabel);CHKERRQ(ierr); 134 ierr = PetscFree(axis->toplabel);CHKERRQ(ierr); 135 ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr); 136 ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr); 137 ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr); 138 PetscFunctionReturn(0); 139 } 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "PetscDrawAxisSetHoldLimits" 143 /*@ 144 PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called 145 again 146 147 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 148 149 Input Parameters: 150 + axis - the axis 151 - hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed 152 153 Level: advanced 154 155 Notes: 156 Once this has been called with PETSC_TRUE the limits will not change if you call 157 PetscDrawAxisSetLimits() until you call this with PETSC_FALSE 158 159 .seealso: PetscDrawAxisSetLimits() 160 161 @*/ 162 PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold) 163 { 164 PetscFunctionBegin; 165 if (!axis) PetscFunctionReturn(0); 166 axis->hold = hold; 167 PetscFunctionReturn(0); 168 } 169 170 #undef __FUNCT__ 171 #define __FUNCT__ "PetscDrawAxisDraw" 172 /*@ 173 PetscDrawAxisDraw - PetscDraws an axis. 174 175 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 176 177 Input Parameter: 178 . axis - Axis structure 179 180 Level: advanced 181 182 Note: 183 This draws the actual axis. The limits etc have already been set. 184 By picking special routines for the ticks and labels, special 185 effects may be generated. These routines are part of the Axis 186 structure (axis). 187 @*/ 188 PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis) 189 { 190 int i,ntick,numx,numy,ac = axis->ac,tc = axis->tc,cc = axis->cc,rank; 191 size_t len; 192 PetscReal tickloc[MAXSEGS],sep,h,w,tw,th,xl,xr,yl,yr; 193 char *p; 194 PetscDraw draw = axis->win; 195 PetscErrorCode ierr; 196 197 PetscFunctionBegin; 198 if (!axis) PetscFunctionReturn(0); 199 ierr = MPI_Comm_rank(((PetscObject)axis)->comm,&rank);CHKERRQ(ierr); 200 if (rank) PetscFunctionReturn(0); 201 202 if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;} 203 if ((axis->yhigh - axis->ylow) <= 1.e-5*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow))) { 204 axis->ylow -= 1.e-5; axis->yhigh += 1.e-5; 205 } 206 207 xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh; 208 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 209 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 210 numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6; if (numx< 2) numx = 2; 211 numy = (int)(.5*(yr-yl)/th); if (numy > 6) numy = 6; if (numy< 2) numy = 2; 212 xl -= 8*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th; 213 if (axis->xlabel) yl -= 2*th; 214 if (axis->ylabel) xl -= 2*tw; 215 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 216 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 217 218 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr); 219 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr); 220 221 if (axis->toplabel) { 222 ierr = PetscStrlen(axis->toplabel,&len);CHKERRQ(ierr); 223 w = xl + .5*(xr - xl) - .5*len*tw; 224 h = axis->yhigh; 225 ierr = PetscDrawString(draw,w,h,cc,axis->toplabel);CHKERRQ(ierr); 226 } 227 228 /* PetscDraw the ticks and labels */ 229 if (axis->xticks) { 230 ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 231 /* PetscDraw in tick marks */ 232 for (i=0; i<ntick; i++) { 233 ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr); 234 } 235 /* label ticks */ 236 for (i=0; i<ntick; i++) { 237 if (axis->xlabelstr) { 238 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 239 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 240 else sep = 0.0; 241 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 242 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 243 w = .5*len*tw; 244 ierr = PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);CHKERRQ(ierr); 245 } 246 } 247 } 248 if (axis->xlabel) { 249 ierr = PetscStrlen(axis->xlabel,&len);CHKERRQ(ierr); 250 w = xl + .5*(xr - xl) - .5*len*tw; 251 h = axis->ylow - 2.5*th; 252 ierr = PetscDrawString(draw,w,h,cc,axis->xlabel);CHKERRQ(ierr); 253 } 254 if (axis->yticks) { 255 ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 256 /* PetscDraw in tick marks */ 257 for (i=0; i<ntick; i++) { 258 ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr); 259 } 260 /* label ticks */ 261 for (i=0; i<ntick; i++) { 262 if (axis->ylabelstr) { 263 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 264 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 265 else sep = 0.0; 266 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 267 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 268 w = axis->xlow - len * tw - 1.2*tw; 269 ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr); 270 } 271 } 272 } 273 if (axis->ylabel) { 274 ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr); 275 h = yl + .5*(yr - yl) + .5*len*th; 276 w = xl + .5*tw; 277 ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr); 278 } 279 PetscFunctionReturn(0); 280 } 281 282 #undef __FUNCT__ 283 #define __FUNCT__ "PetscStripAllZeros" 284 /* 285 Removes all zeros but one from .0000 286 */ 287 PetscErrorCode PetscStripAllZeros(char *buf) 288 { 289 PetscErrorCode ierr; 290 size_t i,n; 291 292 PetscFunctionBegin; 293 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 294 if (buf[0] != '.') PetscFunctionReturn(0); 295 for (i=1; i<n; i++) { 296 if (buf[i] != '0') PetscFunctionReturn(0); 297 } 298 buf[0] = '0'; 299 buf[1] = 0; 300 PetscFunctionReturn(0); 301 } 302 303 #undef __FUNCT__ 304 #define __FUNCT__ "PetscStripTrailingZeros" 305 /* 306 Removes trailing zeros 307 */ 308 PetscErrorCode PetscStripTrailingZeros(char *buf) 309 { 310 PetscErrorCode ierr; 311 char *found; 312 size_t i,n,m = PETSC_MAX_INT; 313 314 PetscFunctionBegin; 315 /* if there is an e in string DO NOT strip trailing zeros */ 316 ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr); 317 if (found) PetscFunctionReturn(0); 318 319 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 320 /* locate decimal point */ 321 for (i=0; i<n; i++) { 322 if (buf[i] == '.') {m = i; break;} 323 } 324 /* if not decimal point then no zeros to remove */ 325 if (m == PETSC_MAX_INT) PetscFunctionReturn(0); 326 /* start at right end of string removing 0s */ 327 for (i=n-1; i>m; i++) { 328 if (buf[i] != '0') PetscFunctionReturn(0); 329 buf[i] = 0; 330 } 331 PetscFunctionReturn(0); 332 } 333 334 #undef __FUNCT__ 335 #define __FUNCT__ "PetscStripInitialZero" 336 /* 337 Removes leading 0 from 0.22 or -0.22 338 */ 339 PetscErrorCode PetscStripInitialZero(char *buf) 340 { 341 PetscErrorCode ierr; 342 size_t i,n; 343 344 PetscFunctionBegin; 345 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 346 if (buf[0] == '0') { 347 for (i=0; i<n; i++) { 348 buf[i] = buf[i+1]; 349 } 350 } else if (buf[0] == '-' && buf[1] == '0') { 351 for (i=1; i<n; i++) { 352 buf[i] = buf[i+1]; 353 } 354 } 355 PetscFunctionReturn(0); 356 } 357 358 #undef __FUNCT__ 359 #define __FUNCT__ "PetscStripZeros" 360 /* 361 Removes the extraneous zeros in numbers like 1.10000e6 362 */ 363 PetscErrorCode PetscStripZeros(char *buf) 364 { 365 PetscErrorCode ierr; 366 size_t i,j,n; 367 368 PetscFunctionBegin; 369 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 370 if (n<5) PetscFunctionReturn(0); 371 for (i=1; i<n-1; i++) { 372 if (buf[i] == 'e' && buf[i-1] == '0') { 373 for (j=i; j<n+1; j++) buf[j-1] = buf[j]; 374 ierr = PetscStripZeros(buf);CHKERRQ(ierr); 375 PetscFunctionReturn(0); 376 } 377 } 378 PetscFunctionReturn(0); 379 } 380 381 #undef __FUNCT__ 382 #define __FUNCT__ "PetscStripZerosPlus" 383 /* 384 Removes the plus in something like 1.1e+2 or 1.1e+02 385 */ 386 PetscErrorCode PetscStripZerosPlus(char *buf) 387 { 388 PetscErrorCode ierr; 389 size_t i,j,n; 390 391 PetscFunctionBegin; 392 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 393 if (n<5) PetscFunctionReturn(0); 394 for (i=1; i<n-2; i++) { 395 if (buf[i] == '+') { 396 if (buf[i+1] == '0') { 397 for (j=i+1; j<n; j++) buf[j-1] = buf[j+1]; 398 PetscFunctionReturn(0); 399 } else { 400 for (j=i+1; j<n+1; j++) buf[j-1] = buf[j]; 401 PetscFunctionReturn(0); 402 } 403 } else if (buf[i] == '-') { 404 if (buf[i+1] == '0') { 405 for (j=i+1; j<n; j++) buf[j] = buf[j+1]; 406 PetscFunctionReturn(0); 407 } 408 } 409 } 410 PetscFunctionReturn(0); 411 } 412 413 414 415 416 417 418 419