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