1 #include <../src/sys/classes/draw/utils/axisimpl.h> /*I "petscdraw.h" I*/ 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 on 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 PetscErrorCode ierr; 25 26 PetscFunctionBegin; 27 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 28 PetscValidPointer(axis,2); 29 30 ierr = PetscHeaderCreate(ad,PETSC_DRAWAXIS_CLASSID,"DrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)draw),PetscDrawAxisDestroy,NULL);CHKERRQ(ierr); 31 ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)ad);CHKERRQ(ierr); 32 33 ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr); 34 ad->win = draw; 35 36 ad->xticks = PetscADefTicks; 37 ad->yticks = PetscADefTicks; 38 ad->xlabelstr = PetscADefLabel; 39 ad->ylabelstr = PetscADefLabel; 40 ad->ac = PETSC_DRAW_BLACK; 41 ad->tc = PETSC_DRAW_BLACK; 42 ad->cc = PETSC_DRAW_BLACK; 43 ad->xlabel = NULL; 44 ad->ylabel = NULL; 45 ad->toplabel = NULL; 46 47 *axis = ad; 48 PetscFunctionReturn(0); 49 } 50 51 #undef __FUNCT__ 52 #define __FUNCT__ "PetscDrawAxisDestroy" 53 /*@ 54 PetscDrawAxisDestroy - Frees the space used by an axis structure. 55 56 Collective on PetscDrawAxis 57 58 Input Parameters: 59 . axis - the axis context 60 61 Level: advanced 62 63 @*/ 64 PetscErrorCode PetscDrawAxisDestroy(PetscDrawAxis *axis) 65 { 66 PetscErrorCode ierr; 67 68 PetscFunctionBegin; 69 if (!*axis) PetscFunctionReturn(0); 70 PetscValidHeaderSpecific(*axis,PETSC_DRAWAXIS_CLASSID,1); 71 if (--((PetscObject)(*axis))->refct > 0) {*axis = NULL; PetscFunctionReturn(0);} 72 73 ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr); 74 ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr); 75 ierr = PetscFree((*axis)->ylabel);CHKERRQ(ierr); 76 ierr = PetscDrawDestroy(&(*axis)->win);CHKERRQ(ierr); 77 ierr = PetscHeaderDestroy(axis);CHKERRQ(ierr); 78 PetscFunctionReturn(0); 79 } 80 81 #undef __FUNCT__ 82 #define __FUNCT__ "PetscDrawAxisSetColors" 83 /*@ 84 PetscDrawAxisSetColors - Sets the colors to be used for the axis, 85 tickmarks, and text. 86 87 Logically Collective on PetscDrawAxis 88 89 Input Parameters: 90 + axis - the axis 91 . ac - the color of the axis lines 92 . tc - the color of the tick marks 93 - cc - the color of the text strings 94 95 Level: advanced 96 97 @*/ 98 PetscErrorCode PetscDrawAxisSetColors(PetscDrawAxis axis,int ac,int tc,int cc) 99 { 100 PetscFunctionBegin; 101 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 102 PetscValidLogicalCollectiveInt(axis,ac,2); 103 PetscValidLogicalCollectiveInt(axis,tc,3); 104 PetscValidLogicalCollectiveInt(axis,cc,4); 105 axis->ac = ac; axis->tc = tc; axis->cc = cc; 106 PetscFunctionReturn(0); 107 } 108 109 #undef __FUNCT__ 110 #define __FUNCT__ "PetscDrawAxisSetLabels" 111 /*@C 112 PetscDrawAxisSetLabels - Sets the x and y axis labels. 113 114 Logically Collective on PetscDrawAxis 115 116 Input Parameters: 117 + axis - the axis 118 . top - the label at the top of the image 119 - xlabel,ylabel - the labes for the x and y axis 120 121 Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw() 122 There should be no newlines in the arguments 123 124 Level: advanced 125 126 @*/ 127 PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[]) 128 { 129 PetscErrorCode ierr; 130 131 PetscFunctionBegin; 132 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 133 ierr = PetscFree(axis->xlabel);CHKERRQ(ierr); 134 ierr = PetscFree(axis->ylabel);CHKERRQ(ierr); 135 ierr = PetscFree(axis->toplabel);CHKERRQ(ierr); 136 ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr); 137 ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr); 138 ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr); 139 PetscFunctionReturn(0); 140 } 141 142 #undef __FUNCT__ 143 #define __FUNCT__ "PetscDrawAxisSetLimits" 144 /*@ 145 PetscDrawAxisSetLimits - Sets the limits (in user coords) of the axis 146 147 Logically Collective on PetscDrawAxis 148 149 Input Parameters: 150 + axis - the axis 151 . xmin,xmax - limits in x 152 - ymin,ymax - limits in y 153 154 Options Database: 155 . -drawaxis_hold - hold the initial set of axis limits for future plotting 156 157 Level: advanced 158 159 .seealso: PetscDrawAxisSetHoldLimits() 160 161 @*/ 162 PetscErrorCode PetscDrawAxisSetLimits(PetscDrawAxis axis,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax) 163 { 164 PetscErrorCode ierr; 165 166 PetscFunctionBegin; 167 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 168 if (axis->hold) PetscFunctionReturn(0); 169 axis->xlow = xmin; 170 axis->xhigh= xmax; 171 axis->ylow = ymin; 172 axis->yhigh= ymax; 173 ierr = PetscOptionsHasName(((PetscObject)axis)->options,((PetscObject)axis)->prefix,"-drawaxis_hold",&axis->hold);CHKERRQ(ierr); 174 PetscFunctionReturn(0); 175 } 176 177 #undef __FUNCT__ 178 #define __FUNCT__ "PetscDrawAxisGetLimits" 179 /*@ 180 PetscDrawAxisGetLimits - Gets the limits (in user coords) of the axis 181 182 Not Collective 183 184 Input Parameters: 185 + axis - the axis 186 . xmin,xmax - limits in x 187 - ymin,ymax - limits in y 188 189 Level: advanced 190 191 .seealso: PetscDrawAxisSetLimits() 192 193 @*/ 194 PetscErrorCode PetscDrawAxisGetLimits(PetscDrawAxis axis,PetscReal *xmin,PetscReal *xmax,PetscReal *ymin,PetscReal *ymax) 195 { 196 PetscFunctionBegin; 197 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 198 *xmin = axis->xlow; 199 *xmax = axis->xhigh; 200 *ymin = axis->ylow; 201 *ymax = axis->yhigh; 202 PetscFunctionReturn(0); 203 } 204 205 #undef __FUNCT__ 206 #define __FUNCT__ "PetscDrawAxisSetHoldLimits" 207 /*@ 208 PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called 209 again 210 211 Logically Collective on PetscDrawAxis 212 213 Input Parameters: 214 + axis - the axis 215 - hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed 216 217 Level: advanced 218 219 Notes: 220 Once this has been called with PETSC_TRUE the limits will not change if you call 221 PetscDrawAxisSetLimits() until you call this with PETSC_FALSE 222 223 .seealso: PetscDrawAxisSetLimits() 224 225 @*/ 226 PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold) 227 { 228 PetscFunctionBegin; 229 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 230 PetscValidLogicalCollectiveBool(axis,hold,2); 231 axis->hold = hold; 232 PetscFunctionReturn(0); 233 } 234 235 #undef __FUNCT__ 236 #define __FUNCT__ "PetscDrawAxisDraw" 237 /*@ 238 PetscDrawAxisDraw - PetscDraws an axis. 239 240 Collective on PetscDrawAxis 241 242 Input Parameter: 243 . axis - Axis structure 244 245 Level: advanced 246 247 Note: 248 This draws the actual axis. The limits etc have already been set. 249 By picking special routines for the ticks and labels, special 250 effects may be generated. These routines are part of the Axis 251 structure (axis). 252 @*/ 253 PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis) 254 { 255 int i,ntick,numx,numy,ac,tc,cc; 256 PetscMPIInt rank; 257 size_t len,ytlen=0; 258 PetscReal coors[4],tickloc[MAXSEGS],sep,tw,th; 259 PetscReal xl,xr,yl,yr,dxl=0,dyl=0,dxr=0,dyr=0; 260 char *p; 261 PetscDraw draw; 262 PetscBool isnull; 263 PetscErrorCode ierr; 264 265 PetscFunctionBegin; 266 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 267 ierr = PetscDrawIsNull(axis->win,&isnull);CHKERRQ(ierr); 268 if (isnull) PetscFunctionReturn(0); 269 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);CHKERRQ(ierr); 270 271 draw = axis->win; 272 273 ac = axis->ac; tc = axis->tc; cc = axis->cc; 274 if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;} 275 if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;} 276 277 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 278 if (rank) goto finally; 279 280 /* get cannonical string size */ 281 ierr = PetscDrawSetCoordinates(draw,0,0,1,1);CHKERRQ(ierr); 282 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 283 /* lower spacing */ 284 //if (axis->xlabelstr || axis->xlabel) dyl = 0.5*th; 285 if (axis->xlabelstr) dyl += 1.5*th; 286 if (axis->xlabel) dyl += 1.5*th; 287 /* left spacing */ 288 if (axis->ylabelstr) dxl += 7.5*tw; 289 if (axis->ylabel) dxl += 2.0*tw; 290 /* right and top spacing */ 291 if (axis->xlabelstr) dxr = 2.5*tw; 292 if (axis->ylabelstr) dyr = 0.5*th; 293 if (axis->toplabel) dyr = 1.5*th; 294 /* extra spacing */ 295 dxl += 0.7*tw; dxr += 0.5*tw; 296 dyl += 0.2*th; dyr += 0.2*th; 297 /* determine coordinates */ 298 xl = (dxl*axis->xhigh + dxr*axis->xlow - axis->xlow) / (dxl + dxr - 1); 299 xr = (dxl*axis->xhigh + dxr*axis->xlow - axis->xhigh) / (dxl + dxr - 1); 300 yl = (dyl*axis->yhigh + dyr*axis->ylow - axis->ylow) / (dyl + dyr - 1); 301 yr = (dyl*axis->yhigh + dyr*axis->ylow - axis->yhigh) / (dyl + dyr - 1); 302 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 303 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 304 305 /* PetscDraw the axis lines */ 306 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr); 307 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr); 308 ierr = PetscDrawLine(draw,axis->xlow,axis->yhigh,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr); 309 ierr = PetscDrawLine(draw,axis->xhigh,axis->ylow,axis->xhigh,axis->yhigh,ac);CHKERRQ(ierr); 310 311 /* PetscDraw the top label */ 312 if (axis->toplabel) { 313 PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->yhigh + 0.5*th; 314 ierr = PetscDrawStringCentered(draw,x,y,cc,axis->toplabel);CHKERRQ(ierr); 315 } 316 317 /* PetscDraw the X ticks and labels */ 318 if (axis->xticks) { 319 numx = (int)(.15*(axis->xhigh-axis->xlow)/tw); numx = PetscClipInterval(numx,2,6); 320 ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 321 /* PetscDraw in tick marks */ 322 for (i=0; i<ntick; i++) { 323 ierr = PetscDrawLine(draw,tickloc[i],axis->ylow,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr); 324 ierr = PetscDrawLine(draw,tickloc[i],axis->yhigh,tickloc[i],axis->yhigh-.5*th,tc);CHKERRQ(ierr); 325 } 326 /* label ticks */ 327 if (axis->xlabelstr) { 328 for (i=0; i<ntick; i++) { 329 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 330 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 331 else sep = 0.0; 332 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 333 ierr = PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.5*th,cc,p);CHKERRQ(ierr); 334 } 335 } 336 } 337 if (axis->xlabel) { 338 PetscReal x = (axis->xlow + axis->xhigh)/2, y = axis->ylow - 1.5*th; 339 if (axis->xlabelstr) y -= 1.5*th; 340 ierr = PetscDrawStringCentered(draw,x,y,cc,axis->xlabel);CHKERRQ(ierr); 341 } 342 343 /* PetscDraw the Y ticks and labels */ 344 if (axis->yticks) { 345 numy = (int)(.50*(axis->yhigh-axis->ylow)/th); numy = PetscClipInterval(numy,2,6); 346 ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 347 /* PetscDraw in tick marks */ 348 for (i=0; i<ntick; i++) { 349 ierr = PetscDrawLine(draw,axis->xlow,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr); 350 ierr = PetscDrawLine(draw,axis->xhigh,tickloc[i],axis->xhigh-.5*tw,tickloc[i],tc);CHKERRQ(ierr); 351 } 352 /* label ticks */ 353 if (axis->ylabelstr) { 354 for (i=0; i<ntick; i++) { 355 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 356 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 357 else sep = 0.0; 358 ierr = (*axis->ylabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 359 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); ytlen = PetscMax(ytlen,len); 360 ierr = PetscDrawString(draw,axis->xlow-(len+.5)*tw,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr); 361 } 362 } 363 } 364 if (axis->ylabel) { 365 PetscReal x = axis->xlow - 2.0*tw, y = (axis->ylow + axis->yhigh)/2; 366 if (axis->ylabelstr) x -= (ytlen+.5)*tw; 367 ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr); 368 ierr = PetscDrawStringVertical(draw,x,y+len*th/2,cc,axis->ylabel);CHKERRQ(ierr); 369 } 370 371 ierr = PetscDrawGetCoordinates(draw,&coors[0],&coors[1],&coors[2],&coors[3]);CHKERRQ(ierr); 372 finally: 373 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 374 ierr = MPI_Bcast(coors,4,MPIU_REAL,0,PetscObjectComm((PetscObject)draw));CHKERRQ(ierr); 375 ierr = PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);CHKERRQ(ierr); 376 PetscFunctionReturn(0); 377 } 378 379 #undef __FUNCT__ 380 #define __FUNCT__ "PetscStripe0" 381 /* 382 Removes all zeros but one from .0000 383 */ 384 PetscErrorCode PetscStripe0(char *buf) 385 { 386 PetscErrorCode ierr; 387 size_t n; 388 PetscBool flg; 389 char *str; 390 391 PetscFunctionBegin; 392 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 393 ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr); 394 if (flg) buf[n-3] = 0; 395 ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr); 396 if (str) { 397 buf[n-2] = buf[n-1]; 398 buf[n-1] = 0; 399 } 400 ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr); 401 if (str) { 402 buf[n-2] = buf[n-1]; 403 buf[n-1] = 0; 404 } 405 PetscFunctionReturn(0); 406 } 407 408 #undef __FUNCT__ 409 #define __FUNCT__ "PetscStripAllZeros" 410 /* 411 Removes all zeros but one from .0000 412 */ 413 PetscErrorCode PetscStripAllZeros(char *buf) 414 { 415 PetscErrorCode ierr; 416 size_t i,n; 417 418 PetscFunctionBegin; 419 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 420 if (buf[0] != '.') PetscFunctionReturn(0); 421 for (i=1; i<n; i++) { 422 if (buf[i] != '0') PetscFunctionReturn(0); 423 } 424 buf[0] = '0'; 425 buf[1] = 0; 426 PetscFunctionReturn(0); 427 } 428 429 #undef __FUNCT__ 430 #define __FUNCT__ "PetscStripTrailingZeros" 431 /* 432 Removes trailing zeros 433 */ 434 PetscErrorCode PetscStripTrailingZeros(char *buf) 435 { 436 PetscErrorCode ierr; 437 char *found; 438 size_t i,n,m = PETSC_MAX_INT; 439 440 PetscFunctionBegin; 441 /* if there is an e in string DO NOT strip trailing zeros */ 442 ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr); 443 if (found) PetscFunctionReturn(0); 444 445 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 446 /* locate decimal point */ 447 for (i=0; i<n; i++) { 448 if (buf[i] == '.') {m = i; break;} 449 } 450 /* if not decimal point then no zeros to remove */ 451 if (m == PETSC_MAX_INT) PetscFunctionReturn(0); 452 /* start at right end of string removing 0s */ 453 for (i=n-1; i>m; i++) { 454 if (buf[i] != '0') PetscFunctionReturn(0); 455 buf[i] = 0; 456 } 457 PetscFunctionReturn(0); 458 } 459 460 #undef __FUNCT__ 461 #define __FUNCT__ "PetscStripInitialZero" 462 /* 463 Removes leading 0 from 0.22 or -0.22 464 */ 465 PetscErrorCode PetscStripInitialZero(char *buf) 466 { 467 PetscErrorCode ierr; 468 size_t i,n; 469 470 PetscFunctionBegin; 471 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 472 if (buf[0] == '0') { 473 for (i=0; i<n; i++) buf[i] = buf[i+1]; 474 } else if (buf[0] == '-' && buf[1] == '0') { 475 for (i=1; i<n; i++) buf[i] = buf[i+1]; 476 } 477 PetscFunctionReturn(0); 478 } 479 480 #undef __FUNCT__ 481 #define __FUNCT__ "PetscStripZeros" 482 /* 483 Removes the extraneous zeros in numbers like 1.10000e6 484 */ 485 PetscErrorCode PetscStripZeros(char *buf) 486 { 487 PetscErrorCode ierr; 488 size_t i,j,n; 489 490 PetscFunctionBegin; 491 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 492 if (n<5) PetscFunctionReturn(0); 493 for (i=1; i<n-1; i++) { 494 if (buf[i] == 'e' && buf[i-1] == '0') { 495 for (j=i; j<n+1; j++) buf[j-1] = buf[j]; 496 ierr = PetscStripZeros(buf);CHKERRQ(ierr); 497 PetscFunctionReturn(0); 498 } 499 } 500 PetscFunctionReturn(0); 501 } 502 503 #undef __FUNCT__ 504 #define __FUNCT__ "PetscStripZerosPlus" 505 /* 506 Removes the plus in something like 1.1e+2 or 1.1e+02 507 */ 508 PetscErrorCode PetscStripZerosPlus(char *buf) 509 { 510 PetscErrorCode ierr; 511 size_t i,j,n; 512 513 PetscFunctionBegin; 514 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 515 if (n<5) PetscFunctionReturn(0); 516 for (i=1; i<n-2; i++) { 517 if (buf[i] == '+') { 518 if (buf[i+1] == '0') { 519 for (j=i+1; j<n; j++) buf[j-1] = buf[j+1]; 520 PetscFunctionReturn(0); 521 } else { 522 for (j=i+1; j<n+1; j++) buf[j-1] = buf[j]; 523 PetscFunctionReturn(0); 524 } 525 } else if (buf[i] == '-') { 526 if (buf[i+1] == '0') { 527 for (j=i+1; j<n; j++) buf[j] = buf[j+1]; 528 PetscFunctionReturn(0); 529 } 530 } 531 } 532 PetscFunctionReturn(0); 533 } 534