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 ierr = PetscDrawIsNull(axis->win,&isnull);CHKERRQ(ierr); 208 if (isnull) PetscFunctionReturn(0); 209 210 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)axis),&rank);CHKERRQ(ierr); 211 if (rank) PetscFunctionReturn(0); 212 213 draw = axis->win; 214 ac = axis->ac; tc = axis->tc; cc = axis->cc; 215 if (axis->xlow == axis->xhigh) {axis->xlow -= .5; axis->xhigh += .5;} 216 if (axis->ylow == axis->yhigh) {axis->ylow -= .5; axis->yhigh += .5;} 217 xl = axis->xlow; xr = axis->xhigh; yl = axis->ylow; yr = axis->yhigh; 218 219 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 220 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 221 numx = (int)(.15*(xr-xl)/tw); if (numx > 6) numx = 6;if (numx< 2) numx = 2; 222 numy = (int)(.50*(yr-yl)/th); if (numy > 6) numy = 6;if (numy< 2) numy = 2; 223 xl -= 11*tw; xr += 2*tw; yl -= 2.5*th; yr += 2*th; 224 if (axis->xlabel) yl -= 2*th; 225 if (axis->ylabel) xl -= 2*tw; 226 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 227 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 228 229 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xhigh,axis->ylow,ac);CHKERRQ(ierr); 230 ierr = PetscDrawLine(draw,axis->xlow,axis->ylow,axis->xlow,axis->yhigh,ac);CHKERRQ(ierr); 231 232 if (axis->toplabel) { 233 h = axis->yhigh; 234 ierr = PetscDrawStringCentered(draw,.5*(xl+xr),axis->yhigh,cc,axis->toplabel);CHKERRQ(ierr); 235 } 236 237 /* PetscDraw the ticks and labels */ 238 if (axis->xticks) { 239 ierr = (*axis->xticks)(axis->xlow,axis->xhigh,numx,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 240 /* PetscDraw in tick marks */ 241 for (i=0; i<ntick; i++) { 242 ierr = PetscDrawLine(draw,tickloc[i],axis->ylow-.5*th,tickloc[i],axis->ylow+.5*th,tc);CHKERRQ(ierr); 243 } 244 /* label ticks */ 245 for (i=0; i<ntick; i++) { 246 if (axis->xlabelstr) { 247 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 248 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 249 else sep = 0.0; 250 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 251 ierr = PetscDrawStringCentered(draw,tickloc[i],axis->ylow-1.2*th,cc,p);CHKERRQ(ierr); 252 } 253 } 254 } 255 if (axis->xlabel) { 256 h = axis->ylow - 2.5*th; 257 ierr = PetscDrawStringCentered(draw,.5*(xl + xr),h,cc,axis->xlabel);CHKERRQ(ierr); 258 } 259 if (axis->yticks) { 260 ierr = (*axis->yticks)(axis->ylow,axis->yhigh,numy,&ntick,tickloc,MAXSEGS);CHKERRQ(ierr); 261 /* PetscDraw in tick marks */ 262 for (i=0; i<ntick; i++) { 263 ierr = PetscDrawLine(draw,axis->xlow -.5*tw,tickloc[i],axis->xlow+.5*tw,tickloc[i],tc);CHKERRQ(ierr); 264 } 265 /* label ticks */ 266 for (i=0; i<ntick; i++) { 267 if (axis->ylabelstr) { 268 if (i < ntick - 1) sep = tickloc[i+1] - tickloc[i]; 269 else if (i > 0) sep = tickloc[i] - tickloc[i-1]; 270 else sep = 0.0; 271 ierr = (*axis->xlabelstr)(tickloc[i],sep,&p);CHKERRQ(ierr); 272 ierr = PetscStrlen(p,&len);CHKERRQ(ierr); 273 w = axis->xlow - len * tw - 1.2*tw; 274 ierr = PetscDrawString(draw,w,tickloc[i]-.5*th,cc,p);CHKERRQ(ierr); 275 } 276 } 277 } 278 if (axis->ylabel) { 279 ierr = PetscStrlen(axis->ylabel,&len);CHKERRQ(ierr); 280 h = yl + .5*(yr - yl) + .5*len*th; 281 w = xl + 1.5*tw; 282 ierr = PetscDrawStringVertical(draw,w,h,cc,axis->ylabel);CHKERRQ(ierr); 283 } 284 PetscFunctionReturn(0); 285 } 286 287 #undef __FUNCT__ 288 #define __FUNCT__ "PetscStripe0" 289 /* 290 Removes all zeros but one from .0000 291 */ 292 PetscErrorCode PetscStripe0(char *buf) 293 { 294 PetscErrorCode ierr; 295 size_t n; 296 PetscBool flg; 297 char *str; 298 299 PetscFunctionBegin; 300 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 301 ierr = PetscStrendswith(buf,"e00",&flg);CHKERRQ(ierr); 302 if (flg) buf[n-3] = 0; 303 ierr = PetscStrstr(buf,"e0",&str);CHKERRQ(ierr); 304 if (str) { 305 buf[n-2] = buf[n-1]; 306 buf[n-1] = 0; 307 } 308 ierr = PetscStrstr(buf,"e-0",&str);CHKERRQ(ierr); 309 if (str) { 310 buf[n-2] = buf[n-1]; 311 buf[n-1] = 0; 312 } 313 PetscFunctionReturn(0); 314 } 315 316 #undef __FUNCT__ 317 #define __FUNCT__ "PetscStripAllZeros" 318 /* 319 Removes all zeros but one from .0000 320 */ 321 PetscErrorCode PetscStripAllZeros(char *buf) 322 { 323 PetscErrorCode ierr; 324 size_t i,n; 325 326 PetscFunctionBegin; 327 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 328 if (buf[0] != '.') PetscFunctionReturn(0); 329 for (i=1; i<n; i++) { 330 if (buf[i] != '0') PetscFunctionReturn(0); 331 } 332 buf[0] = '0'; 333 buf[1] = 0; 334 PetscFunctionReturn(0); 335 } 336 337 #undef __FUNCT__ 338 #define __FUNCT__ "PetscStripTrailingZeros" 339 /* 340 Removes trailing zeros 341 */ 342 PetscErrorCode PetscStripTrailingZeros(char *buf) 343 { 344 PetscErrorCode ierr; 345 char *found; 346 size_t i,n,m = PETSC_MAX_INT; 347 348 PetscFunctionBegin; 349 /* if there is an e in string DO NOT strip trailing zeros */ 350 ierr = PetscStrchr(buf,'e',&found);CHKERRQ(ierr); 351 if (found) PetscFunctionReturn(0); 352 353 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 354 /* locate decimal point */ 355 for (i=0; i<n; i++) { 356 if (buf[i] == '.') {m = i; break;} 357 } 358 /* if not decimal point then no zeros to remove */ 359 if (m == PETSC_MAX_INT) PetscFunctionReturn(0); 360 /* start at right end of string removing 0s */ 361 for (i=n-1; i>m; i++) { 362 if (buf[i] != '0') PetscFunctionReturn(0); 363 buf[i] = 0; 364 } 365 PetscFunctionReturn(0); 366 } 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "PetscStripInitialZero" 370 /* 371 Removes leading 0 from 0.22 or -0.22 372 */ 373 PetscErrorCode PetscStripInitialZero(char *buf) 374 { 375 PetscErrorCode ierr; 376 size_t i,n; 377 378 PetscFunctionBegin; 379 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 380 if (buf[0] == '0') { 381 for (i=0; i<n; i++) buf[i] = buf[i+1]; 382 } else if (buf[0] == '-' && buf[1] == '0') { 383 for (i=1; i<n; i++) buf[i] = buf[i+1]; 384 } 385 PetscFunctionReturn(0); 386 } 387 388 #undef __FUNCT__ 389 #define __FUNCT__ "PetscStripZeros" 390 /* 391 Removes the extraneous zeros in numbers like 1.10000e6 392 */ 393 PetscErrorCode PetscStripZeros(char *buf) 394 { 395 PetscErrorCode ierr; 396 size_t i,j,n; 397 398 PetscFunctionBegin; 399 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 400 if (n<5) PetscFunctionReturn(0); 401 for (i=1; i<n-1; i++) { 402 if (buf[i] == 'e' && buf[i-1] == '0') { 403 for (j=i; j<n+1; j++) buf[j-1] = buf[j]; 404 ierr = PetscStripZeros(buf);CHKERRQ(ierr); 405 PetscFunctionReturn(0); 406 } 407 } 408 PetscFunctionReturn(0); 409 } 410 411 #undef __FUNCT__ 412 #define __FUNCT__ "PetscStripZerosPlus" 413 /* 414 Removes the plus in something like 1.1e+2 or 1.1e+02 415 */ 416 PetscErrorCode PetscStripZerosPlus(char *buf) 417 { 418 PetscErrorCode ierr; 419 size_t i,j,n; 420 421 PetscFunctionBegin; 422 ierr = PetscStrlen(buf,&n);CHKERRQ(ierr); 423 if (n<5) PetscFunctionReturn(0); 424 for (i=1; i<n-2; i++) { 425 if (buf[i] == '+') { 426 if (buf[i+1] == '0') { 427 for (j=i+1; j<n; j++) buf[j-1] = buf[j+1]; 428 PetscFunctionReturn(0); 429 } else { 430 for (j=i+1; j<n+1; j++) buf[j-1] = buf[j]; 431 PetscFunctionReturn(0); 432 } 433 } else if (buf[i] == '-') { 434 if (buf[i+1] == '0') { 435 for (j=i+1; j<n; j++) buf[j] = buf[j+1]; 436 PetscFunctionReturn(0); 437 } 438 } 439 } 440 PetscFunctionReturn(0); 441 } 442