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,_p_PetscDrawAxis,int,PETSC_DRAWAXIS_CLASSID,"PetscDrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)obj),PetscDrawAxisDestroy,0);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 ierr = PetscStrlen(axis->toplabel,&len);CHKERRQ(ierr); 227 w = xl + .5*(xr - xl) - .5*len*tw; 228 h = axis->yhigh; 229 ierr = PetscDrawString(draw,w,h,cc,axis->toplabel);CHKERRQ(ierr); 230 } 231 232 /* PetscDraw the ticks and labels */ 233 if (axis->xticks) { 234 ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 235 /* PetscDraw in tick marks */ 236 for (i=0; i<ntick; i++) { 237 ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr); 238 } 239 /* label ticks */ 240 for (i=0; i<ntick; i++) { 241 if (axis->xlabelstr) { 242 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 243 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 244 else sep = 0.0; 245 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 246 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 247 w = .5*len*tw; 248 ierr = PetscDrawString(draw,tickloc[i]-w,axis->ylow-1.2*th,cc,p);CHKERRQ(ierr); 249 } 250 } 251 } 252 if (axis->xlabel) { 253 ierr = PetscStrlen(axis->xlabel,&len);CHKERRQ(ierr); 254 w = xl + .5*(xr - xl) - .5*len*tw; 255 h = axis->ylow - 2.5*th; 256 ierr = PetscDrawString(draw,w,h,cc,axis->xlabel);CHKERRQ(ierr); 257 } 258 if (axis->yticks) { 259 ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 260 /* PetscDraw in tick marks */ 261 for (i=0; i<ntick; i++) { 262 ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr); 263 } 264 /* label ticks */ 265 for (i=0; i<ntick; i++) { 266 if (axis->ylabelstr) { 267 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 268 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 269 else sep = 0.0; 270 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 271 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 272 w = axis->xlow - len * tw - 1.2*tw; 273 ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr); 274 } 275 } 276 } 277 if (axis->ylabel) { 278 ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr); 279 h = yl + .5*(yr - yl) + .5*len*th; 280 w = xl + 1.5*tw; 281 ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr); 282 } 283 PetscFunctionReturn(0); 284 } 285 286 #undef __FUNCT__ 287 #define __FUNCT__ "PetscStripe0" 288 /* 289 Removes all zeros but one from .0000 290 */ 291 PetscErrorCode PetscStripe0(char *buf) 292 { 293 PetscErrorCode ierr; 294 size_t n; 295 PetscBool flg; 296 char *str; 297 298 PetscFunctionBegin; 299 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 300 ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr); 301 if (flg) buf[n-3] = 0; 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++) buf[i] = buf[i+1]; 381 } else if (buf[0] == '-' && buf[1] == '0') { 382 for (i=1; i<n; i++) buf[i] = buf[i+1]; 383 } 384 PetscFunctionReturn(0); 385 } 386 387 #undef __FUNCT__ 388 #define __FUNCT__ "PetscStripZeros" 389 /* 390 Removes the extraneous zeros in numbers like 1.10000e6 391 */ 392 PetscErrorCode PetscStripZeros(char *buf) 393 { 394 PetscErrorCode ierr; 395 size_t i,j,n; 396 397 PetscFunctionBegin; 398 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 399 if (n<5) PetscFunctionReturn(0); 400 for (i=1; i<n-1; i++) { 401 if (buf[i] == 'e' && buf[i-1] == '0') { 402 for (j=i; j<n+1; j++) buf[j-1] = buf[j]; 403 ierr = PetscStripZeros(buf);CHKERRQ(ierr); 404 PetscFunctionReturn(0); 405 } 406 } 407 PetscFunctionReturn(0); 408 } 409 410 #undef __FUNCT__ 411 #define __FUNCT__ "PetscStripZerosPlus" 412 /* 413 Removes the plus in something like 1.1e+2 or 1.1e+02 414 */ 415 PetscErrorCode PetscStripZerosPlus(char *buf) 416 { 417 PetscErrorCode ierr; 418 size_t i,j,n; 419 420 PetscFunctionBegin; 421 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 422 if (n<5) PetscFunctionReturn(0); 423 for (i=1; i<n-2; i++) { 424 if (buf[i] == '+') { 425 if (buf[i+1] == '0') { 426 for (j=i+1; j<n; j++) buf[j-1] = buf[j+1]; 427 PetscFunctionReturn(0); 428 } else { 429 for (j=i+1; j<n+1; j++) buf[j-1] = buf[j]; 430 PetscFunctionReturn(0); 431 } 432 } else if (buf[i] == '-') { 433 if (buf[i+1] == '0') { 434 for (j=i+1; j<n; j++) buf[j] = buf[j+1]; 435 PetscFunctionReturn(0); 436 } 437 } 438 } 439 PetscFunctionReturn(0); 440 } 441 442 443 444 445 446 447 448