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