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*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow)); 205 axis->yhigh += 1.e-5*PetscMax(PetscAbsReal(axis->yhigh),PetscAbsReal(axis->ylow)); 206 } */ 207 if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;} 208 209 xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh; 210 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 211 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 212 numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6; if (numx< 2) numx = 2; 213 numy = (int)(.5*(yr-yl)/th); if (numy > 6) numy = 6; if (numy< 2) numy = 2; 214 xl -= 11*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th; 215 if (axis->xlabel) yl -= 2*th; 216 if (axis->ylabel) xl -= 2*tw; 217 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 218 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 219 220 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr); 221 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr); 222 223 if (axis->toplabel) { 224 ierr = PetscStrlen(axis->toplabel,&len);CHKERRQ(ierr); 225 w = xl + .5*(xr - xl) - .5*len*tw; 226 h = axis->yhigh; 227 ierr = PetscDrawString(draw,w,h,cc,axis->toplabel);CHKERRQ(ierr); 228 } 229 230 /* PetscDraw the ticks and labels */ 231 if (axis->xticks) { 232 ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 233 /* PetscDraw in tick marks */ 234 for (i=0; i<ntick; i++) { 235 ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr); 236 } 237 /* label ticks */ 238 for (i=0; i<ntick; i++) { 239 if (axis->xlabelstr) { 240 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 241 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 242 else sep = 0.0; 243 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 244 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 245 w = .5*len*tw; 246 ierr = PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);CHKERRQ(ierr); 247 } 248 } 249 } 250 if (axis->xlabel) { 251 ierr = PetscStrlen(axis->xlabel,&len);CHKERRQ(ierr); 252 w = xl + .5*(xr - xl) - .5*len*tw; 253 h = axis->ylow - 2.5*th; 254 ierr = PetscDrawString(draw,w,h,cc,axis->xlabel);CHKERRQ(ierr); 255 } 256 if (axis->yticks) { 257 ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 258 /* PetscDraw in tick marks */ 259 for (i=0; i<ntick; i++) { 260 ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr); 261 } 262 /* label ticks */ 263 for (i=0; i<ntick; i++) { 264 if (axis->ylabelstr) { 265 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 266 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 267 else sep = 0.0; 268 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 269 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 270 w = axis->xlow - len * tw - 1.2*tw; 271 ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr); 272 } 273 } 274 } 275 if (axis->ylabel) { 276 ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr); 277 h = yl + .5*(yr - yl) + .5*len*th; 278 w = xl + .5*tw; 279 ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr); 280 } 281 PetscFunctionReturn(0); 282 } 283 284 #undef __FUNCT__ 285 #define __FUNCT__ "PetscStripe0" 286 /* 287 Removes all zeros but one from .0000 288 */ 289 PetscErrorCode PetscStripe0(char *buf) 290 { 291 PetscErrorCode ierr; 292 size_t n; 293 PetscBool flg; 294 char *str; 295 296 PetscFunctionBegin; 297 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 298 ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr); 299 if (flg) { 300 buf[n-3] = 0; 301 } 302 ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr); 303 if (str) { 304 buf[n-2] = buf[n-1]; 305 buf[n-1] = 0; 306 } 307 ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr); 308 if (str) { 309 buf[n-2] = buf[n-1]; 310 buf[n-1] = 0; 311 } 312 PetscFunctionReturn(0); 313 } 314 315 #undef __FUNCT__ 316 #define __FUNCT__ "PetscStripAllZeros" 317 /* 318 Removes all zeros but one from .0000 319 */ 320 PetscErrorCode PetscStripAllZeros(char *buf) 321 { 322 PetscErrorCode ierr; 323 size_t i,n; 324 325 PetscFunctionBegin; 326 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 327 if (buf[0] != '.') PetscFunctionReturn(0); 328 for (i=1; i<n; i++) { 329 if (buf[i] != '0') PetscFunctionReturn(0); 330 } 331 buf[0] = '0'; 332 buf[1] = 0; 333 PetscFunctionReturn(0); 334 } 335 336 #undef __FUNCT__ 337 #define __FUNCT__ "PetscStripTrailingZeros" 338 /* 339 Removes trailing zeros 340 */ 341 PetscErrorCode PetscStripTrailingZeros(char *buf) 342 { 343 PetscErrorCode ierr; 344 char *found; 345 size_t i,n,m = PETSC_MAX_INT; 346 347 PetscFunctionBegin; 348 /* if there is an e in string DO NOT strip trailing zeros */ 349 ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr); 350 if (found) PetscFunctionReturn(0); 351 352 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 353 /* locate decimal point */ 354 for (i=0; i<n; i++) { 355 if (buf[i] == '.') {m = i; break;} 356 } 357 /* if not decimal point then no zeros to remove */ 358 if (m == PETSC_MAX_INT) PetscFunctionReturn(0); 359 /* start at right end of string removing 0s */ 360 for (i=n-1; i>m; i++) { 361 if (buf[i] != '0') PetscFunctionReturn(0); 362 buf[i] = 0; 363 } 364 PetscFunctionReturn(0); 365 } 366 367 #undef __FUNCT__ 368 #define __FUNCT__ "PetscStripInitialZero" 369 /* 370 Removes leading 0 from 0.22 or -0.22 371 */ 372 PetscErrorCode PetscStripInitialZero(char *buf) 373 { 374 PetscErrorCode ierr; 375 size_t i,n; 376 377 PetscFunctionBegin; 378 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 379 if (buf[0] == '0') { 380 for (i=0; i<n; i++) { 381 buf[i] = buf[i+1]; 382 } 383 } else if (buf[0] == '-' && buf[1] == '0') { 384 for (i=1; i<n; i++) { 385 buf[i] = buf[i+1]; 386 } 387 } 388 PetscFunctionReturn(0); 389 } 390 391 #undef __FUNCT__ 392 #define __FUNCT__ "PetscStripZeros" 393 /* 394 Removes the extraneous zeros in numbers like 1.10000e6 395 */ 396 PetscErrorCode PetscStripZeros(char *buf) 397 { 398 PetscErrorCode ierr; 399 size_t i,j,n; 400 401 PetscFunctionBegin; 402 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 403 if (n<5) PetscFunctionReturn(0); 404 for (i=1; i<n-1; i++) { 405 if (buf[i] == 'e' && buf[i-1] == '0') { 406 for (j=i; j<n+1; j++) buf[j-1] = buf[j]; 407 ierr = PetscStripZeros(buf);CHKERRQ(ierr); 408 PetscFunctionReturn(0); 409 } 410 } 411 PetscFunctionReturn(0); 412 } 413 414 #undef __FUNCT__ 415 #define __FUNCT__ "PetscStripZerosPlus" 416 /* 417 Removes the plus in something like 1.1e+2 or 1.1e+02 418 */ 419 PetscErrorCode PetscStripZerosPlus(char *buf) 420 { 421 PetscErrorCode ierr; 422 size_t i,j,n; 423 424 PetscFunctionBegin; 425 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 426 if (n<5) PetscFunctionReturn(0); 427 for (i=1; i<n-2; i++) { 428 if (buf[i] == '+') { 429 if (buf[i+1] == '0') { 430 for (j=i+1; j<n; j++) buf[j-1] = buf[j+1]; 431 PetscFunctionReturn(0); 432 } else { 433 for (j=i+1; j<n+1; j++) buf[j-1] = buf[j]; 434 PetscFunctionReturn(0); 435 } 436 } else if (buf[i] == '-') { 437 if (buf[i+1] == '0') { 438 for (j=i+1; j<n; j++) buf[j] = buf[j+1]; 439 PetscFunctionReturn(0); 440 } 441 } 442 } 443 PetscFunctionReturn(0); 444 } 445 446 447 448 449 450 451 452