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 -= 11*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__ "PetscStripe0" 284 /* 285 Removes all zeros but one from .0000 286 */ 287 PetscErrorCode PetscStripe0(char *buf) 288 { 289 PetscErrorCode ierr; 290 size_t n; 291 PetscBool flg; 292 char *str; 293 294 PetscFunctionBegin; 295 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 296 ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr); 297 if (flg) { 298 buf[n-3] = 0; 299 } 300 ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr); 301 if (str) { 302 buf[n-2] = buf[n-1]; 303 buf[n-1] = 0; 304 } 305 ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr); 306 if (str) { 307 buf[n-2] = buf[n-1]; 308 buf[n-1] = 0; 309 } 310 PetscFunctionReturn(0); 311 } 312 313 #undef __FUNCT__ 314 #define __FUNCT__ "PetscStripAllZeros" 315 /* 316 Removes all zeros but one from .0000 317 */ 318 PetscErrorCode PetscStripAllZeros(char *buf) 319 { 320 PetscErrorCode ierr; 321 size_t i,n; 322 323 PetscFunctionBegin; 324 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 325 if (buf[0] != '.') PetscFunctionReturn(0); 326 for (i=1; i<n; i++) { 327 if (buf[i] != '0') PetscFunctionReturn(0); 328 } 329 buf[0] = '0'; 330 buf[1] = 0; 331 PetscFunctionReturn(0); 332 } 333 334 #undef __FUNCT__ 335 #define __FUNCT__ "PetscStripTrailingZeros" 336 /* 337 Removes trailing zeros 338 */ 339 PetscErrorCode PetscStripTrailingZeros(char *buf) 340 { 341 PetscErrorCode ierr; 342 char *found; 343 size_t i,n,m = PETSC_MAX_INT; 344 345 PetscFunctionBegin; 346 /* if there is an e in string DO NOT strip trailing zeros */ 347 ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr); 348 if (found) PetscFunctionReturn(0); 349 350 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 351 /* locate decimal point */ 352 for (i=0; i<n; i++) { 353 if (buf[i] == '.') {m = i; break;} 354 } 355 /* if not decimal point then no zeros to remove */ 356 if (m == PETSC_MAX_INT) PetscFunctionReturn(0); 357 /* start at right end of string removing 0s */ 358 for (i=n-1; i>m; i++) { 359 if (buf[i] != '0') PetscFunctionReturn(0); 360 buf[i] = 0; 361 } 362 PetscFunctionReturn(0); 363 } 364 365 #undef __FUNCT__ 366 #define __FUNCT__ "PetscStripInitialZero" 367 /* 368 Removes leading 0 from 0.22 or -0.22 369 */ 370 PetscErrorCode PetscStripInitialZero(char *buf) 371 { 372 PetscErrorCode ierr; 373 size_t i,n; 374 375 PetscFunctionBegin; 376 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 377 if (buf[0] == '0') { 378 for (i=0; i<n; i++) { 379 buf[i] = buf[i+1]; 380 } 381 } else if (buf[0] == '-' && buf[1] == '0') { 382 for (i=1; i<n; i++) { 383 buf[i] = buf[i+1]; 384 } 385 } 386 PetscFunctionReturn(0); 387 } 388 389 #undef __FUNCT__ 390 #define __FUNCT__ "PetscStripZeros" 391 /* 392 Removes the extraneous zeros in numbers like 1.10000e6 393 */ 394 PetscErrorCode PetscStripZeros(char *buf) 395 { 396 PetscErrorCode ierr; 397 size_t i,j,n; 398 399 PetscFunctionBegin; 400 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 401 if (n<5) PetscFunctionReturn(0); 402 for (i=1; i<n-1; i++) { 403 if (buf[i] == 'e' && buf[i-1] == '0') { 404 for (j=i; j<n+1; j++) buf[j-1] = buf[j]; 405 ierr = PetscStripZeros(buf);CHKERRQ(ierr); 406 PetscFunctionReturn(0); 407 } 408 } 409 PetscFunctionReturn(0); 410 } 411 412 #undef __FUNCT__ 413 #define __FUNCT__ "PetscStripZerosPlus" 414 /* 415 Removes the plus in something like 1.1e+2 or 1.1e+02 416 */ 417 PetscErrorCode PetscStripZerosPlus(char *buf) 418 { 419 PetscErrorCode ierr; 420 size_t i,j,n; 421 422 PetscFunctionBegin; 423 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 424 if (n<5) PetscFunctionReturn(0); 425 for (i=1; i<n-2; i++) { 426 if (buf[i] == '+') { 427 if (buf[i+1] == '0') { 428 for (j=i+1; j<n; j++) buf[j-1] = buf[j+1]; 429 PetscFunctionReturn(0); 430 } else { 431 for (j=i+1; j<n+1; j++) buf[j-1] = buf[j]; 432 PetscFunctionReturn(0); 433 } 434 } else if (buf[i] == '-') { 435 if (buf[i+1] == '0') { 436 for (j=i+1; j<n; j++) buf[j] = buf[j+1]; 437 PetscFunctionReturn(0); 438 } 439 } 440 } 441 PetscFunctionReturn(0); 442 } 443 444 445 446 447 448 449 450