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