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