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 PetscBool isnull; 24 PetscDrawAxis ad; 25 PetscErrorCode ierr; 26 27 PetscFunctionBegin; 28 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 29 PetscValidPointer(axis,2); 30 31 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 32 if (isnull) {*axis = NULL; PetscFunctionReturn(0);} 33 34 ierr = PetscHeaderCreate(ad,PETSC_DRAWAXIS_CLASSID,"PetscDrawAxis","Draw Axis","Draw",PetscObjectComm((PetscObject)draw),PetscDrawAxisDestroy,NULL);CHKERRQ(ierr); 35 ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)ad);CHKERRQ(ierr); 36 37 ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr); 38 ad->win = draw; 39 40 ad->xticks = PetscADefTicks; 41 ad->yticks = PetscADefTicks; 42 ad->xlabelstr = PetscADefLabel; 43 ad->ylabelstr = PetscADefLabel; 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 PetscValidHeaderSpecific(*axis,PETSC_DRAWAXIS_CLASSID,1); 75 if (--((PetscObject)(*axis))->refct > 0) {*axis = NULL; PetscFunctionReturn(0);} 76 77 ierr = PetscFree((*axis)->toplabel);CHKERRQ(ierr); 78 ierr = PetscFree((*axis)->xlabel);CHKERRQ(ierr); 79 ierr = PetscFree((*axis)->ylabel);CHKERRQ(ierr); 80 ierr = PetscDrawDestroy(&(*axis)->win);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 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 107 axis->ac = ac; axis->tc = tc; axis->cc = cc; 108 PetscFunctionReturn(0); 109 } 110 111 #undef __FUNCT__ 112 #define __FUNCT__ "PetscDrawAxisSetLabels" 113 /*@C 114 PetscDrawAxisSetLabels - Sets the x and y axis labels. 115 116 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 117 118 Input Parameters: 119 + axis - the axis 120 . top - the label at the top of the image 121 - xlabel,ylabel - the labes for the x and y axis 122 123 Notes: Must be called before PetscDrawAxisDraw() or PetscDrawLGDraw() 124 There should be no newlines in the arguments 125 126 Level: advanced 127 128 @*/ 129 PetscErrorCode PetscDrawAxisSetLabels(PetscDrawAxis axis,const char top[],const char xlabel[],const char ylabel[]) 130 { 131 PetscErrorCode ierr; 132 133 PetscFunctionBegin; 134 if (!axis) PetscFunctionReturn(0); 135 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 136 ierr = PetscFree(axis->xlabel);CHKERRQ(ierr); 137 ierr = PetscFree(axis->ylabel);CHKERRQ(ierr); 138 ierr = PetscFree(axis->toplabel);CHKERRQ(ierr); 139 ierr = PetscStrallocpy(xlabel,&axis->xlabel);CHKERRQ(ierr); 140 ierr = PetscStrallocpy(ylabel,&axis->ylabel);CHKERRQ(ierr); 141 ierr = PetscStrallocpy(top,&axis->toplabel);CHKERRQ(ierr); 142 PetscFunctionReturn(0); 143 } 144 145 #undef __FUNCT__ 146 #define __FUNCT__ "PetscDrawAxisSetHoldLimits" 147 /*@ 148 PetscDrawAxisSetHoldLimits - Causes an axis to keep the same limits until this is called 149 again 150 151 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 152 153 Input Parameters: 154 + axis - the axis 155 - hold - PETSC_TRUE - hold current limits, PETSC_FALSE allow limits to be changed 156 157 Level: advanced 158 159 Notes: 160 Once this has been called with PETSC_TRUE the limits will not change if you call 161 PetscDrawAxisSetLimits() until you call this with PETSC_FALSE 162 163 .seealso: PetscDrawAxisSetLimits() 164 165 @*/ 166 PetscErrorCode PetscDrawAxisSetHoldLimits(PetscDrawAxis axis,PetscBool hold) 167 { 168 PetscFunctionBegin; 169 if (!axis) PetscFunctionReturn(0); 170 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 171 axis->hold = hold; 172 PetscFunctionReturn(0); 173 } 174 175 #undef __FUNCT__ 176 #define __FUNCT__ "PetscDrawAxisDraw" 177 /*@ 178 PetscDrawAxisDraw - PetscDraws an axis. 179 180 Not Collective (ignored on all processors except processor 0 of PetscDrawAxis) 181 182 Input Parameter: 183 . axis - Axis structure 184 185 Level: advanced 186 187 Note: 188 This draws the actual axis. The limits etc have already been set. 189 By picking special routines for the ticks and labels, special 190 effects may be generated. These routines are part of the Axis 191 structure (axis). 192 @*/ 193 PetscErrorCode PetscDrawAxisDraw(PetscDrawAxis axis) 194 { 195 int i,ntick,numx,numy,ac,tc,cc; 196 PetscMPIInt rank; 197 size_t len; 198 PetscReal tickloc[MAXSEGS],sep,h,w,tw,th,xl,xr,yl,yr; 199 char *p; 200 PetscDraw draw; 201 PetscBool isnull; 202 PetscErrorCode ierr; 203 204 PetscFunctionBegin; 205 if (!axis) PetscFunctionReturn(0); 206 PetscValidHeaderSpecific(axis,PETSC_DRAWAXIS_CLASSID,1); 207 208 draw = axis->win; 209 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 210 if (isnull) PetscFunctionReturn(0); 211 212 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);CHKERRQ(ierr); 213 if (rank) PetscFunctionReturn(0); 214 215 ac = axis->ac; tc = axis->tc; cc = axis->cc; 216 if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;} 217 if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;} 218 xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh; 219 220 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 221 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 222 numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6;if (numx< 2) numx = 2; 223 numy = (int)(.50*(yr-yl)/th); if (numy > 6) numy = 6;if (numy< 2) numy = 2; 224 xl -= 11*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th; 225 if (axis->xlabel) yl -= 2*th; 226 if (axis->ylabel) xl -= 2*tw; 227 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 228 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 229 230 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr); 231 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr); 232 233 if (axis->toplabel) { 234 h = axis->yhigh; 235 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),axis->yhigh,cc,axis->toplabel);CHKERRQ(ierr); 236 } 237 238 /* PetscDraw the ticks and labels */ 239 if (axis->xticks) { 240 ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 241 /* PetscDraw in tick marks */ 242 for (i=0; i<ntick; i++) { 243 ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr); 244 } 245 /* label ticks */ 246 for (i=0; i<ntick; i++) { 247 if (axis->xlabelstr) { 248 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 249 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 250 else sep = 0.0; 251 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 252 ierr = PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.2*th,cc,p);CHKERRQ(ierr); 253 } 254 } 255 } 256 if (axis->xlabel) { 257 h = axis->ylow - 2.5*th; 258 ierr = PetscDrawStringCentered(draw,.5*(xl + xr),h,cc,axis->xlabel);CHKERRQ(ierr); 259 } 260 if (axis->yticks) { 261 ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 262 /* PetscDraw in tick marks */ 263 for (i=0; i<ntick; i++) { 264 ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr); 265 } 266 /* label ticks */ 267 for (i=0; i<ntick; i++) { 268 if (axis->ylabelstr) { 269 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 270 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 271 else sep = 0.0; 272 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 273 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 274 w = axis->xlow - len * tw - 1.2*tw; 275 ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr); 276 } 277 } 278 } 279 if (axis->ylabel) { 280 ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr); 281 h = yl + .5*(yr - yl) + .5*len*th; 282 w = xl + 1.5*tw; 283 ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr); 284 } 285 PetscFunctionReturn(0); 286 } 287 288 #undef __FUNCT__ 289 #define __FUNCT__ "PetscStripe0" 290 /* 291 Removes all zeros but one from .0000 292 */ 293 PetscErrorCode PetscStripe0(char *buf) 294 { 295 PetscErrorCode ierr; 296 size_t n; 297 PetscBool flg; 298 char *str; 299 300 PetscFunctionBegin; 301 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 302 ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr); 303 if (flg) buf[n-3] = 0; 304 ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr); 305 if (str) { 306 buf[n-2] = buf[n-1]; 307 buf[n-1] = 0; 308 } 309 ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr); 310 if (str) { 311 buf[n-2] = buf[n-1]; 312 buf[n-1] = 0; 313 } 314 PetscFunctionReturn(0); 315 } 316 317 #undef __FUNCT__ 318 #define __FUNCT__ "PetscStripAllZeros" 319 /* 320 Removes all zeros but one from .0000 321 */ 322 PetscErrorCode PetscStripAllZeros(char *buf) 323 { 324 PetscErrorCode ierr; 325 size_t i,n; 326 327 PetscFunctionBegin; 328 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 329 if (buf[0] != '.') PetscFunctionReturn(0); 330 for (i=1; i<n; i++) { 331 if (buf[i] != '0') PetscFunctionReturn(0); 332 } 333 buf[0] = '0'; 334 buf[1] = 0; 335 PetscFunctionReturn(0); 336 } 337 338 #undef __FUNCT__ 339 #define __FUNCT__ "PetscStripTrailingZeros" 340 /* 341 Removes trailing zeros 342 */ 343 PetscErrorCode PetscStripTrailingZeros(char *buf) 344 { 345 PetscErrorCode ierr; 346 char *found; 347 size_t i,n,m = PETSC_MAX_INT; 348 349 PetscFunctionBegin; 350 /* if there is an e in string DO NOT strip trailing zeros */ 351 ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr); 352 if (found) PetscFunctionReturn(0); 353 354 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 355 /* locate decimal point */ 356 for (i=0; i<n; i++) { 357 if (buf[i] == '.') {m = i; break;} 358 } 359 /* if not decimal point then no zeros to remove */ 360 if (m == PETSC_MAX_INT) PetscFunctionReturn(0); 361 /* start at right end of string removing 0s */ 362 for (i=n-1; i>m; i++) { 363 if (buf[i] != '0') PetscFunctionReturn(0); 364 buf[i] = 0; 365 } 366 PetscFunctionReturn(0); 367 } 368 369 #undef __FUNCT__ 370 #define __FUNCT__ "PetscStripInitialZero" 371 /* 372 Removes leading 0 from 0.22 or -0.22 373 */ 374 PetscErrorCode PetscStripInitialZero(char *buf) 375 { 376 PetscErrorCode ierr; 377 size_t i,n; 378 379 PetscFunctionBegin; 380 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 381 if (buf[0] == '0') { 382 for (i=0; i<n; i++) buf[i] = buf[i+1]; 383 } else if (buf[0] == '-' && buf[1] == '0') { 384 for (i=1; i<n; i++) buf[i] = buf[i+1]; 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