1# plotchart.tcl -- 2# Facilities to draw simple plots in a dedicated canvas 3# 4# Note: 5# This source file contains the public functions. 6# The private functions are contained in the files "sourced" 7# at the end. 8# 9package require Tcl 8.4 10package require Tk 11 12# Plotchart -- 13# Namespace to hold the procedures and the private data 14# 15namespace eval ::Plotchart { 16 variable settings 17 variable legend 18 variable scaling 19 variable methodProc 20 variable data_series 21 22 namespace export worldCoordinates viewPort coordsToPixel \ 23 polarCoordinates setZoomPan \ 24 world3DCoordinates coordsToPixel \ 25 coords3DToPixel polarToPixel \ 26 pixelToCoords pixelToIndex \ 27 determineScale determineScaleFromList \ 28 createXYPlot createPolarplot createPiechart \ 29 createBarchart createHorizontalBarchart \ 30 createTimechart createStripchart \ 31 createIsometricPlot create3DPlot \ 32 createGanttChart createHistogram colorMap \ 33 create3DBars createRadialchart \ 34 createTXPlot createRightAxis \ 35 create3DRibbonChart create3DRibbonPlot \ 36 createXLogYPlot createLogXYPlot createLogXLogYPlot \ 37 createWindrose createTargetDiagram createPerformanceProfile \ 38 plotconfig plotpack plotmethod 39 40 # 41 # Array linking procedures with methods 42 # 43 set methodProc(xyplot,title) DrawTitle 44 set methodProc(xyplot,xtext) DrawXtext 45 set methodProc(xyplot,ytext) DrawYtext 46 set methodProc(xyplot,vtext) DrawVtext 47 set methodProc(xyplot,plot) DrawData 48 set methodProc(xyplot,dot) DrawDot 49 set methodProc(xyplot,dotconfig) DotConfigure 50 set methodProc(xyplot,interval) DrawInterval 51 set methodProc(xyplot,trend) DrawTrendLine 52 set methodProc(xyplot,vector) DrawVector 53 set methodProc(xyplot,vectorconfig) VectorConfigure 54 set methodProc(xyplot,rchart) DrawRchart 55 set methodProc(xyplot,grid) DrawGrid 56 set methodProc(xyplot,contourlines) DrawIsolines 57 set methodProc(xyplot,contourfill) DrawShades 58 set methodProc(xyplot,contourbox) DrawBox 59 set methodProc(xyplot,saveplot) SavePlot 60 set methodProc(xyplot,dataconfig) DataConfig 61 set methodProc(xyplot,xconfig) XConfig 62 set methodProc(xyplot,yconfig) YConfig 63 set methodProc(xyplot,xticklines) DrawXTicklines 64 set methodProc(xyplot,yticklines) DrawYTicklines 65 set methodProc(xyplot,background) BackgroundColour 66 set methodProc(xyplot,legendconfig) LegendConfigure 67 set methodProc(xyplot,legend) DrawLegend 68 set methodProc(xyplot,balloon) DrawBalloon 69 set methodProc(xyplot,balloonconfig) ConfigBalloon 70 set methodProc(xyplot,plaintext) DrawPlainText 71 set methodProc(xyplot,plaintextconfig) ConfigPlainText 72 set methodProc(xyplot,bindvar) BindVar 73 set methodProc(xyplot,bindcmd) BindCmd 74 set methodProc(xyplot,rescale) RescalePlot 75 set methodProc(xyplot,box-and-whiskers) DrawBoxWhiskers 76 set methodProc(xyplot,xband) DrawXband 77 set methodProc(xyplot,yband) DrawYband 78 set methodProc(xyplot,labeldot) DrawLabelDot 79 set methodProc(xyplot,bindplot) BindPlot 80 set methodProc(xyplot,bindlast) BindLast 81 set methodProc(xyplot,contourlinesfunctionvalues) DrawIsolinesFunctionValues 82 set methodProc(xyplot,contourlinesfunctionpoints) DrawIsolinesFunctionPoints 83 set methodProc(xyplot,plotfunc) DrawFunction 84 set methodProc(xlogyplot,title) DrawTitle 85 set methodProc(xlogyplot,xtext) DrawXtext 86 set methodProc(xlogyplot,ytext) DrawYtext 87 set methodProc(xlogyplot,vtext) DrawVtext 88 set methodProc(xlogyplot,plot) DrawLogYData 89 set methodProc(xlogyplot,dot) DrawLogDot 90 set methodProc(xlogyplot,dotconfig) DotConfigure 91 set methodProc(xlogyplot,interval) DrawLogInterval 92 set methodProc(xlogyplot,trend) DrawLogTrendLine 93 set methodProc(xlogyplot,saveplot) SavePlot 94 set methodProc(xlogyplot,dataconfig) DataConfig 95 set methodProc(xlogyplot,xconfig) XConfig 96 set methodProc(xlogyplot,yconfig) YConfig 97 set methodProc(xlogyplot,xticklines) DrawXTicklines 98 set methodProc(xlogyplot,yticklines) DrawYTicklines 99 set methodProc(xlogyplot,background) BackgroundColour 100 set methodProc(xlogyplot,legendconfig) LegendConfigure 101 set methodProc(xlogyplot,legend) DrawLegend 102 set methodProc(xlogyplot,balloon) DrawBalloon 103 set methodProc(xlogyplot,balloonconfig) ConfigBalloon 104 set methodProc(xlogyplot,plaintext) DrawPlainText 105 set methodProc(xlogyplot,plaintextconfig) ConfigPlainText 106 set methodProc(logxyplot,title) DrawTitle 107 set methodProc(logxyplot,xtext) DrawXtext 108 set methodProc(logxyplot,ytext) DrawYtext 109 set methodProc(logxyplot,vtext) DrawVtext 110 set methodProc(logxyplot,plot) DrawLogXData 111 set methodProc(logxyplot,dot) DrawLogDot 112 set methodProc(logxyplot,dotconfig) DotConfigure 113 set methodProc(logxyplot,interval) DrawLogInterval 114 set methodProc(logxyplot,trend) DrawLogTrendLine 115 set methodProc(logxyplot,saveplot) SavePlot 116 set methodProc(logxyplot,dataconfig) DataConfig 117 set methodProc(logxyplot,xconfig) XConfig 118 set methodProc(logxyplot,yconfig) YConfig 119 set methodProc(logxyplot,xticklines) DrawXTicklines 120 set methodProc(logxyplot,yticklines) DrawYTicklines 121 set methodProc(logxyplot,background) BackgroundColour 122 set methodProc(logxyplot,legendconfig) LegendConfigure 123 set methodProc(logxyplot,legend) DrawLegend 124 set methodProc(logxyplot,balloon) DrawBalloon 125 set methodProc(logxyplot,balloonconfig) ConfigBalloon 126 set methodProc(logxyplot,plaintext) DrawPlainText 127 set methodProc(logxyplot,plaintextconfig) ConfigPlainText 128 set methodProc(logxlogyplot,title) DrawTitle 129 set methodProc(logxlogyplot,xtext) DrawXtext 130 set methodProc(logxlogyplot,ytext) DrawYtext 131 set methodProc(logxlogyplot,vtext) DrawVtext 132 set methodProc(logxlogyplot,plot) DrawLogXLogYData 133 set methodProc(logxlogyplot,dot) DrawLogDot 134 set methodProc(logxlogyplot,dotconfig) DotConfigure 135 set methodProc(logxlogyplot,interval) DrawLogInterval 136 set methodProc(logxlogyplot,trend) DrawLogTrendLine 137 set methodProc(logxlogyplot,saveplot) SavePlot 138 set methodProc(logxlogyplot,dataconfig) DataConfig 139 set methodProc(logxlogyplot,xconfig) XConfig 140 set methodProc(logxlogyplot,yconfig) YConfig 141 set methodProc(logxlogyplot,xticklines) DrawXTicklines 142 set methodProc(logxlogyplot,yticklines) DrawYTicklines 143 set methodProc(logxlogyplot,background) BackgroundColour 144 set methodProc(logxlogyplot,legendconfig) LegendConfigure 145 set methodProc(logxlogyplot,legend) DrawLegend 146 set methodProc(logxlogyplot,balloon) DrawBalloon 147 set methodProc(logxlogyplot,balloonconfig) ConfigBalloon 148 set methodProc(logxlogyplot,plaintext) DrawPlainText 149 set methodProc(logxlogyplot,plaintextconfig) ConfigPlainText 150 set methodProc(piechart,title) DrawTitle 151 set methodProc(piechart,plot) DrawPie 152 set methodProc(piechart,saveplot) SavePlot 153 set methodProc(piechart,balloon) DrawBalloon 154 set methodProc(piechart,balloonconfig) ConfigBalloon 155 set methodProc(piechart,explode) PieExplodeSegment 156 set methodProc(piechart,plaintext) DrawPlainText 157 set methodProc(piechart,plaintextconfig) ConfigPlainText 158 set methodProc(polarplot,title) DrawTitle 159 set methodProc(polarplot,plot) DrawPolarData 160 set methodProc(polarplot,saveplot) SavePlot 161 set methodProc(polarplot,dataconfig) DataConfig 162 set methodProc(polarplot,background) BackgroundColour 163 set methodProc(polarplot,legendconfig) LegendConfigure 164 set methodProc(polarplot,legend) DrawLegend 165 set methodProc(polarplot,balloon) DrawBalloon 166 set methodProc(polarplot,balloonconfig) ConfigBalloon 167 set methodProc(polarplot,plaintext) DrawPlainText 168 set methodProc(polarplot,plaintextconfig) ConfigPlainText 169 set methodProc(polarplot,labeldot) DrawLabelDotPolar 170 set methodProc(histogram,title) DrawTitle 171 set methodProc(histogram,xtext) DrawXtext 172 set methodProc(histogram,ytext) DrawYtext 173 set methodProc(histogram,vtext) DrawVtext 174 set methodProc(histogram,plot) DrawHistogramData 175 set methodProc(histogram,saveplot) SavePlot 176 set methodProc(histogram,dataconfig) DataConfig 177 set methodProc(histogram,xconfig) XConfig 178 set methodProc(histogram,yconfig) YConfig 179 set methodProc(histogram,yticklines) DrawYTicklines 180 set methodProc(histogram,background) BackgroundColour 181 set methodProc(histogram,legendconfig) LegendConfigure 182 set methodProc(histogram,legend) DrawLegend 183 set methodProc(histogram,balloon) DrawBalloon 184 set methodProc(histogram,balloonconfig) ConfigBalloon 185 set methodProc(histogram,plaintext) DrawPlainText 186 set methodProc(histogram,plaintextconfig) ConfigPlainText 187 set methodProc(horizbars,title) DrawTitle 188 set methodProc(horizbars,xtext) DrawXtext 189 set methodProc(horizbars,ytext) DrawYtext 190 set methodProc(horizbars,vtext) DrawVtext 191 set methodProc(horizbars,plot) DrawHorizBarData 192 set methodProc(horizbars,xticklines) DrawXTicklines 193 set methodProc(horizbars,background) BackgroundColour 194 set methodProc(horizbars,saveplot) SavePlot 195 set methodProc(horizbars,colours) SetColours 196 set methodProc(horizbars,colors) SetColours 197 set methodProc(horizbars,xconfig) XConfig 198 set methodProc(horizbars,config) ConfigBar 199 set methodProc(horizbars,legendconfig) LegendConfigure 200 set methodProc(horizbars,legend) DrawLegend 201 set methodProc(horizbars,balloon) DrawBalloon 202 set methodProc(horizbars,balloonconfig) ConfigBalloon 203 set methodProc(horizbars,plaintext) DrawPlainText 204 set methodProc(horizbars,plaintextconfig) ConfigPlainText 205 set methodProc(vertbars,title) DrawTitle 206 set methodProc(vertbars,xtext) DrawXtext 207 set methodProc(vertbars,ytext) DrawYtext 208 set methodProc(vertbars,vtext) DrawVtext 209 set methodProc(vertbars,plot) DrawVertBarData 210 set methodProc(vertbars,background) BackgroundColour 211 set methodProc(vertbars,yticklines) DrawYTicklines 212 set methodProc(vertbars,saveplot) SavePlot 213 set methodProc(vertbars,colours) SetColours 214 set methodProc(vertbars,colors) SetColours 215 set methodProc(vertbars,yconfig) YConfig 216 set methodProc(vertbars,config) ConfigBar 217 set methodProc(vertbars,legendconfig) LegendConfigure 218 set methodProc(vertbars,legend) DrawLegend 219 set methodProc(vertbars,balloon) DrawBalloon 220 set methodProc(vertbars,balloonconfig) ConfigBalloon 221 set methodProc(vertbars,plaintext) DrawPlainText 222 set methodProc(vertbars,plaintextconfig) ConfigPlainText 223 set methodProc(timechart,title) DrawTitle 224 set methodProc(timechart,period) DrawTimePeriod 225 set methodProc(timechart,milestone) DrawTimeMilestone 226 set methodProc(timechart,vertline) DrawTimeVertLine 227 set methodProc(timechart,saveplot) SavePlot 228 set methodProc(timechart,background) BackgroundColour 229 set methodProc(timechart,balloon) DrawBalloon 230 set methodProc(timechart,balloonconfig) ConfigBalloon 231 set methodProc(timechart,plaintext) DrawPlainText 232 set methodProc(timechart,plaintextconfig) ConfigPlainText 233 set methodProc(timechart,hscroll) ConnectHorizScrollbar 234 set methodProc(timechart,vscroll) ConnectVertScrollbar 235 set methodProc(ganttchart,title) DrawTitle 236 set methodProc(ganttchart,period) DrawGanttPeriod 237 set methodProc(ganttchart,task) DrawGanttPeriod 238 set methodProc(ganttchart,milestone) DrawGanttMilestone 239 set methodProc(ganttchart,vertline) DrawGanttVertLine 240 set methodProc(ganttchart,saveplot) SavePlot 241 set methodProc(ganttchart,color) GanttColor 242 set methodProc(ganttchart,colour) GanttColor 243 set methodProc(ganttchart,font) GanttFont 244 set methodProc(ganttchart,connect) DrawGanttConnect 245 set methodProc(ganttchart,summary) DrawGanttSummary 246 set methodProc(ganttchart,background) BackgroundColour 247 set methodProc(ganttchart,balloon) DrawBalloon 248 set methodProc(ganttchart,balloonconfig) ConfigBalloon 249 set methodProc(ganttchart,plaintext) DrawPlainText 250 set methodProc(ganttchart,plaintextconfig) ConfigPlainText 251 set methodProc(ganttchart,hscroll) ConnectHorizScrollbar 252 set methodProc(ganttchart,vscroll) ConnectVertScrollbar 253 set methodProc(stripchart,title) DrawTitle 254 set methodProc(stripchart,xtext) DrawXtext 255 set methodProc(stripchart,ytext) DrawYtext 256 set methodProc(stripchart,vtext) DrawVtext 257 set methodProc(stripchart,plot) DrawStripData 258 set methodProc(stripchart,saveplot) SavePlot 259 set methodProc(stripchart,dataconfig) DataConfig 260 set methodProc(stripchart,xconfig) XConfig 261 set methodProc(stripchart,yconfig) YConfig 262 set methodProc(stripchart,yticklines) DrawYTicklines 263 set methodProc(stripchart,background) BackgroundColour 264 set methodProc(stripchart,legendconfig) LegendConfigure 265 set methodProc(stripchart,legend) DrawLegend 266 set methodProc(stripchart,balloon) DrawBalloon 267 set methodProc(stripchart,balloonconfig) ConfigBalloon 268 set methodProc(stripchart,plaintext) DrawPlainText 269 set methodProc(stripchart,plaintextconfig) ConfigPlainText 270 set methodProc(isometric,title) DrawTitle 271 set methodProc(isometric,xtext) DrawXtext 272 set methodProc(isometric,ytext) DrawYtext 273 set methodProc(isometric,vtext) DrawVtext 274 set methodProc(isometric,plot) DrawIsometricData 275 set methodProc(isometric,saveplot) SavePlot 276 set methodProc(isometric,background) BackgroundColour 277 set methodProc(isometric,balloon) DrawBalloon 278 set methodProc(isometric,balloonconfig) ConfigBalloon 279 set methodProc(isometric,plaintext) DrawPlainText 280 set methodProc(isometric,plaintextconfig) ConfigPlainText 281 set methodProc(3dplot,title) DrawTitle 282 set methodProc(3dplot,plotfunc) Draw3DFunction 283 set methodProc(3dplot,plotdata) Draw3DData 284 set methodProc(3dplot,plotline) Draw3DLineFrom3Dcoordinates 285 set methodProc(3dplot,gridsize) GridSize3D 286 set methodProc(3dplot,ribbon) Draw3DRibbon 287 set methodProc(3dplot,saveplot) SavePlot 288 set methodProc(3dplot,colour) SetColours 289 set methodProc(3dplot,color) SetColours 290 set methodProc(3dplot,xconfig) XConfig 291 set methodProc(3dplot,yconfig) YConfig 292 set methodProc(3dplot,zconfig) ZConfig 293 set methodProc(3dplot,plotfuncont) Draw3DFunctionContour 294 set methodProc(3dplot,background) BackgroundColour 295 set methodProc(3dbars,title) DrawTitle 296 set methodProc(3dbars,plot) Draw3DBar 297 set methodProc(3dbars,yconfig) YConfig 298 set methodProc(3dbars,saveplot) SavePlot 299 set methodProc(3dbars,config) Config3DBar 300 set methodProc(3dbars,balloon) DrawBalloon 301 set methodProc(3dbars,balloonconfig) ConfigBalloon 302 set methodProc(3dbars,plaintext) DrawPlainText 303 set methodProc(3dbars,plaintextconfig) ConfigPlainText 304 set methodProc(radialchart,title) DrawTitle 305 set methodProc(radialchart,plot) DrawRadial 306 set methodProc(radialchart,saveplot) SavePlot 307 set methodProc(radialchart,balloon) DrawBalloon 308 set methodProc(radialchart,plaintext) DrawPlainText 309 set methodProc(radialchart,plaintextconfig) ConfigPlainText 310 set methodProc(txplot,title) DrawTitle 311 set methodProc(txplot,xtext) DrawXtext 312 set methodProc(txplot,ytext) DrawYtext 313 set methodProc(txplot,vtext) DrawVtext 314 set methodProc(txplot,plot) DrawTimeData 315 set methodProc(txplot,interval) DrawInterval 316 set methodProc(txplot,saveplot) SavePlot 317 set methodProc(txplot,dataconfig) DataConfig 318 set methodProc(txplot,xconfig) XConfig 319 set methodProc(txplot,yconfig) YConfig 320 set methodProc(txplot,xticklines) DrawXTicklines 321 set methodProc(txplot,yticklines) DrawYTicklines 322 set methodProc(txplot,background) BackgroundColour 323 set methodProc(txplot,legendconfig) LegendConfigure 324 set methodProc(txplot,legend) DrawLegend 325 set methodProc(txplot,balloon) DrawBalloon 326 set methodProc(txplot,balloonconfig) ConfigBalloon 327 set methodProc(txplot,plaintext) DrawPlainText 328 set methodProc(txplot,plaintextconfig) ConfigPlainText 329 set methodProc(3dribbon,title) DrawTitle 330 set methodProc(3dribbon,saveplot) SavePlot 331 set methodProc(3dribbon,line) Draw3DLine 332 set methodProc(3dribbon,area) Draw3DArea 333 set methodProc(3dribbon,background) BackgroundColour 334 set methodProc(boxplot,title) DrawTitle 335 set methodProc(boxplot,xtext) DrawXtext 336 set methodProc(boxplot,ytext) DrawYtext 337 set methodProc(boxplot,vtext) DrawVtext 338 set methodProc(boxplot,plot) DrawBoxData 339 set methodProc(boxplot,saveplot) SavePlot 340 set methodProc(boxplot,dataconfig) DataConfig 341 set methodProc(boxplot,xconfig) XConfig 342 set methodProc(boxplot,yconfig) YConfig 343 set methodProc(boxplot,xticklines) DrawXTicklines 344 set methodProc(boxplot,yticklines) DrawYTicklines 345 set methodProc(boxplot,background) BackgroundColour 346 set methodProc(boxplot,legendconfig) LegendConfigure 347 set methodProc(boxplot,legend) DrawLegend 348 set methodProc(boxplot,balloon) DrawBalloon 349 set methodProc(boxplot,balloonconfig) ConfigBalloon 350 set methodProc(boxplot,plaintext) DrawPlainText 351 set methodProc(boxplot,plaintextconfig) ConfigPlainText 352 set methodProc(windrose,plot) DrawWindRoseData 353 set methodProc(windrose,saveplot) SavePlot 354 set methodProc(windrose,title) DrawTitle 355 set methodProc(targetdiagram,title) DrawTitle 356 set methodProc(targetdiagram,xtext) DrawXtext 357 set methodProc(targetdiagram,ytext) DrawYtext 358 set methodProc(targetdiagram,vtext) DrawVtext 359 set methodProc(targetdiagram,plot) DrawTargetData 360 set methodProc(targetdiagram,saveplot) SavePlot 361 set methodProc(targetdiagram,background) BackgroundColour 362 set methodProc(targetdiagram,legendconfig) LegendConfigure 363 set methodProc(targetdiagram,legend) DrawLegend 364 set methodProc(targetdiagram,balloon) DrawBalloon 365 set methodProc(targetdiagram,balloonconfig) ConfigBalloon 366 set methodProc(targetdiagram,plaintext) DrawPlainText 367 set methodProc(targetdiagram,plaintextconfig) ConfigPlainText 368 set methodProc(targetdiagram,dataconfig) DataConfig 369 set methodProc(3dribbonplot,title) DrawTitle 370 set methodProc(3dribbonplot,plot) Draw3DRibbon 371 set methodProc(3dribbonplot,saveplot) SavePlot 372 set methodProc(3dribbonplot,xconfig) XConfig 373 set methodProc(3dribbonplot,yconfig) YConfig 374 set methodProc(3dribbonplot,zconfig) ZConfig 375 set methodProc(3dribbonplot,background) BackgroundColour 376 set methodProc(performance,title) DrawTitle 377 set methodProc(performance,xtext) DrawXtext 378 set methodProc(performance,ytext) DrawYtext 379 set methodProc(performance,vtext) DrawVtext 380 set methodProc(performance,plot) DrawPerformanceData 381 set methodProc(performance,dot) DrawDot 382 set methodProc(performance,saveplot) SavePlot 383 set methodProc(performance,dataconfig) DataConfig 384 set methodProc(performance,xconfig) XConfig 385 set methodProc(performance,yconfig) YConfig 386 set methodProc(performance,xticklines) DrawXTicklines 387 set methodProc(performance,yticklines) DrawYTicklines 388 set methodProc(performance,background) BackgroundColour 389 set methodProc(performance,legendconfig) LegendConfigure 390 set methodProc(performance,legend) DrawLegend 391 set methodProc(performance,balloon) DrawBalloon 392 set methodProc(performance,balloonconfig) ConfigBalloon 393 set methodProc(performance,plaintext) DrawPlainText 394 set methodProc(performance,plaintextconfig) ConfigPlainText 395 396 # 397 # Auxiliary parameters 398 # 399 variable torad 400 set torad [expr {3.1415926/180.0}] 401 402 variable options 403 variable option_keys 404 variable option_values 405 set options {-colour -color -symbol -type -filled -fillcolour -boxwidth -width} 406 set option_keys {-colour -colour -symbol -type -filled -fillcolour -boxwidth -width} 407 set option_values {-colour {...} 408 -symbol {plus cross circle up down dot upfilled downfilled} 409 -type {line symbol both} 410 -filled {no up down} 411 -fillcolour {...} 412 -boxwidth {...} 413 -width {...} 414 } 415 416 variable axis_options 417 variable axis_option_clear 418 variable axis_option_values 419 set axis_options {-format -ticklength -ticklines -scale -minorticks -labeloffset -axisoffset} 420 set axis_option_clear { 0 0 0 1 0 0 0 } 421 set axis_option_config { 0 1 0 0 1 1 1 } 422 set axis_option_values {-format {...} 423 -ticklength {...} 424 -ticklines {0 1} 425 -scale {...} 426 -minorticks {...} 427 -labeloffset {...} 428 -axisoffset {...} 429 } 430 variable contour_options 431} 432 433# setZoomPan -- 434# Set up the bindings for zooming and panning 435# Arguments: 436# w Name of the canvas window 437# Result: 438# None 439# Side effect: 440# Bindings set up 441# 442proc ::Plotchart::setZoomPan { w } { 443 set sqrt2 [expr {sqrt(2.0)}] 444 set sqrt05 [expr {sqrt(0.5)}] 445 446 bind $w <Control-Button-1> [list ::Plotchart::ScaleItems $w %x %y $sqrt2] 447 bind $w <Control-Prior> [list ::Plotchart::ScaleItems $w %x %y $sqrt2] 448 bind $w <Control-Button-2> [list ::Plotchart::ScaleItems $w %x %y $sqrt05] 449 bind $w <Control-Button-3> [list ::Plotchart::ScaleItems $w %x %y $sqrt05] 450 bind $w <Control-Next> [list ::Plotchart::ScaleItems $w %x %y $sqrt05] 451 bind $w <Control-Up> [list ::Plotchart::MoveItems $w 0 -40] 452 bind $w <Control-Down> [list ::Plotchart::MoveItems $w 0 40] 453 bind $w <Control-Left> [list ::Plotchart::MoveItems $w -40 0] 454 bind $w <Control-Right> [list ::Plotchart::MoveItems $w 40 0] 455 focus $w 456} 457 458# viewPort -- 459# Set the pixel extremes for the graph 460# Arguments: 461# w Name of the canvas window 462# pxmin Minimum X-coordinate 463# pymin Minimum Y-coordinate 464# pxmax Maximum X-coordinate 465# pymax Maximum Y-coordinate 466# Result: 467# None 468# Side effect: 469# Array scaling filled 470# 471proc ::Plotchart::viewPort { w pxmin pymin pxmax pymax } { 472 variable scaling 473 474 if { $pxmin >= $pxmax || $pymin >= $pymax } { 475 return -code error "Inconsistent bounds for viewport - increase canvas size or decrease margins" 476 } 477 478 set scaling($w,pxmin) $pxmin 479 set scaling($w,pymin) $pymin 480 set scaling($w,pxmax) $pxmax 481 set scaling($w,pymax) $pymax 482 set scaling($w,new) 1 483} 484 485# worldCoordinates -- 486# Set the extremes for the world coordinates 487# Arguments: 488# w Name of the canvas window 489# xmin Minimum X-coordinate 490# ymin Minimum Y-coordinate 491# xmax Maximum X-coordinate 492# ymax Maximum Y-coordinate 493# Result: 494# None 495# Side effect: 496# Array scaling filled 497# 498proc ::Plotchart::worldCoordinates { w xmin ymin xmax ymax } { 499 variable scaling 500 501 if { $xmin == $xmax || $ymin == $ymax } { 502 return -code error "Minimum and maximum must differ for world coordinates" 503 } 504 505 set scaling($w,xmin) [expr {double($xmin)}] 506 set scaling($w,ymin) [expr {double($ymin)}] 507 set scaling($w,xmax) [expr {double($xmax)}] 508 set scaling($w,ymax) [expr {double($ymax)}] 509 510 set scaling($w,new) 1 511} 512 513# polarCoordinates -- 514# Set the extremes for the polar coordinates 515# Arguments: 516# w Name of the canvas window 517# radmax Maximum radius 518# Result: 519# None 520# Side effect: 521# Array scaling filled 522# 523proc ::Plotchart::polarCoordinates { w radmax } { 524 variable scaling 525 526 if { $radmax <= 0.0 } { 527 return -code error "Maximum radius must be positive" 528 } 529 530 set scaling($w,xmin) [expr {-double($radmax)}] 531 set scaling($w,ymin) [expr {-double($radmax)}] 532 set scaling($w,xmax) [expr {double($radmax)}] 533 set scaling($w,ymax) [expr {double($radmax)}] 534 535 set scaling($w,new) 1 536} 537 538# world3DCoordinates -- 539# Set the extremes for the world coordinates in 3D plots 540# Arguments: 541# w Name of the canvas window 542# xmin Minimum X-coordinate 543# ymin Minimum Y-coordinate 544# zmin Minimum Z-coordinate 545# xmax Maximum X-coordinate 546# ymax Maximum Y-coordinate 547# zmax Maximum Z-coordinate 548# Result: 549# None 550# Side effect: 551# Array scaling filled 552# 553proc ::Plotchart::world3DCoordinates { w xmin ymin zmin xmax ymax zmax } { 554 variable scaling 555 556 if { $xmin == $xmax || $ymin == $ymax || $zmin == $zmax } { 557 return -code error "Minimum and maximum must differ for world coordinates" 558 } 559 560 set scaling($w,xmin) [expr {double($xmin)}] 561 set scaling($w,ymin) [expr {double($ymin)}] 562 set scaling($w,zmin) [expr {double($zmin)}] 563 set scaling($w,xmax) [expr {double($xmax)}] 564 set scaling($w,ymax) [expr {double($ymax)}] 565 set scaling($w,zmax) [expr {double($zmax)}] 566 567 set scaling($w,new) 1 568} 569 570# coordsToPixel -- 571# Convert world coordinates to pixel coordinates 572# Arguments: 573# w Name of the canvas 574# xcrd X-coordinate 575# ycrd Y-coordinate 576# Result: 577# List of two elements, x- and y-coordinates in pixels 578# 579proc ::Plotchart::coordsToPixel { w xcrd ycrd } { 580 variable scaling 581 582 if { $scaling($w,new) == 1 } { 583 set scaling($w,new) 0 584 set width [expr {$scaling($w,pxmax)-$scaling($w,pxmin)}] 585 set height [expr {$scaling($w,pymax)-$scaling($w,pymin)}] 586 587 set dx [expr {$scaling($w,xmax)-$scaling($w,xmin)}] 588 set dy [expr {$scaling($w,ymax)-$scaling($w,ymin)}] 589 set scaling($w,xfactor) [expr {$width/$dx}] 590 set scaling($w,yfactor) [expr {$height/$dy}] 591 } 592 593 set xpix [expr {$scaling($w,pxmin)+($xcrd-$scaling($w,xmin))*$scaling($w,xfactor)}] 594 set ypix [expr {$scaling($w,pymin)+($scaling($w,ymax)-$ycrd)*$scaling($w,yfactor)}] 595 return [list $xpix $ypix] 596} 597 598# coords3DToPixel -- 599# Convert world coordinates to pixel coordinates (3D plots) 600# Arguments: 601# w Name of the canvas 602# xcrd X-coordinate 603# ycrd Y-coordinate 604# zcrd Z-coordinate 605# Result: 606# List of two elements, x- and y-coordinates in pixels 607# 608proc ::Plotchart::coords3DToPixel { w xcrd ycrd zcrd } { 609 variable scaling 610 611 if { $scaling($w,new) == 1 } { 612 set scaling($w,new) 0 613 set width [expr {$scaling($w,pxmax)-$scaling($w,pxmin)}] 614 set height [expr {$scaling($w,pymax)-$scaling($w,pymin)}] 615 616 set dx [expr {$scaling($w,xmax)-$scaling($w,xmin)}] 617 set dy [expr {$scaling($w,ymax)-$scaling($w,ymin)}] 618 set dz [expr {$scaling($w,zmax)-$scaling($w,zmin)}] 619 set scaling($w,xyfactor) [expr {$scaling($w,yfract)*$width/$dx}] 620 set scaling($w,xzfactor) [expr {$scaling($w,zfract)*$height/$dx}] 621 set scaling($w,yfactor) [expr {$width/$dy}] 622 set scaling($w,zfactor) [expr {$height/$dz}] 623 } 624 625 # 626 # The values for xcrd = xmax 627 # 628 set xpix [expr {$scaling($w,pxmin)+($ycrd-$scaling($w,ymin))*$scaling($w,yfactor)}] 629 set ypix [expr {$scaling($w,pymin)+($scaling($w,zmax)-$zcrd)*$scaling($w,zfactor)}] 630 631 # 632 # Add the shift due to xcrd-xmax 633 # 634 set xpix [expr {$xpix + $scaling($w,xyfactor)*($xcrd-$scaling($w,xmax))}] 635 set ypix [expr {$ypix - $scaling($w,xzfactor)*($xcrd-$scaling($w,xmax))}] 636 637 return [list $xpix $ypix] 638} 639 640# pixelToCoords -- 641# Convert pixel coordinates to world coordinates 642# Arguments: 643# w Name of the canvas 644# xpix X-coordinate (pixel) 645# ypix Y-coordinate (pixel) 646# Result: 647# List of two elements, x- and y-coordinates in world coordinate system 648# 649proc ::Plotchart::pixelToCoords { w xpix ypix } { 650 variable scaling 651 652 if { $scaling($w,new) == 1 } { 653 set scaling($w,new) 0 654 set width [expr {$scaling($w,pxmax)-$scaling($w,pxmin)}] 655 set height [expr {$scaling($w,pymax)-$scaling($w,pymin)}] 656 657 set dx [expr {$scaling($w,xmax)-$scaling($w,xmin)}] 658 set dy [expr {$scaling($w,ymax)-$scaling($w,ymin)}] 659 set scaling($w,xfactor) [expr {$width/$dx}] 660 set scaling($w,yfactor) [expr {$height/$dy}] 661 } 662 663 set xcrd [expr {$scaling($w,xmin)+($xpix-$scaling($w,pxmin))/$scaling($w,xfactor)}] 664 set ycrd [expr {$scaling($w,ymax)-($ypix-$scaling($w,pymin))/$scaling($w,yfactor)}] 665 return [list $xcrd $ycrd] 666} 667 668# pixelToIndex -- 669# Convert pixel coordinates to elements list index 670# Arguments: 671# w Name of the canvas 672# xpix X-coordinate (pixel) 673# ypix Y-coordinate (pixel) 674# Result: 675# Elements list index 676# 677proc ::Plotchart::pixelToIndex { w xpix ypix } { 678 variable scaling 679 variable torad 680 681 set idx -1 682 set radius [expr {($scaling(${w},pxmax) - $scaling(${w},pxmin)) / 2}] 683 set xrel [expr {${xpix} - $scaling(${w},pxmin) - ${radius}}] 684 set yrel [expr {-${ypix} + $scaling(${w},pymin) + ${radius}}] 685 if {[expr {pow(${radius},2) < (pow(${xrel},2) + pow(${yrel},2))}]} { 686 # do nothing out of pie chart 687 } elseif {[info exists scaling(${w},angles)]} { 688 set xy_angle [expr {(360 + round(atan2(${yrel},${xrel})/${torad})) % 360}] 689 foreach angle $scaling(${w},angles) { 690 if {${xy_angle} <= ${angle}} { 691 break 692 } 693 incr idx 694 } 695 } 696 return ${idx} 697} 698 699# polarToPixel -- 700# Convert polar coordinates to pixel coordinates 701# Arguments: 702# w Name of the canvas 703# rad Radius of the point 704# phi Angle of the point (degrees) 705# Result: 706# List of two elements, x- and y-coordinates in pixels 707# 708proc ::Plotchart::polarToPixel { w rad phi } { 709 variable torad 710 711 set xcrd [expr {$rad*cos($phi*$torad)}] 712 set ycrd [expr {$rad*sin($phi*$torad)}] 713 714 coordsToPixel $w $xcrd $ycrd 715} 716 717# createXYPlot -- 718# Create a command for drawing an XY plot 719# Arguments: 720# w Name of the canvas 721# xscale Minimum, maximum and step for x-axis (initial) 722# yscale Minimum, maximum and step for y-axis 723# args Options (currently: "-xlabels list" and "-ylabels list") 724# Result: 725# Name of a new command 726# Note: 727# The entire canvas will be dedicated to the XY plot. 728# The plot will be drawn with axes 729# 730proc ::Plotchart::createXYPlot { w xscale yscale args} { 731 variable scaling 732 variable data_series 733 734 foreach s [array names data_series "$w,*"] { 735 unset data_series($s) 736 } 737 738 set newchart "xyplot_$w" 739 interp alias {} $newchart {} ::Plotchart::PlotHandler xyplot $w 740 CopyConfig xyplot $w 741 set scaling($w,eventobj) "" 742 743 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 744 745 foreach {xmin xmax xdelt} $xscale {break} 746 foreach {ymin ymax ydelt} $yscale {break} 747 748 if { $xdelt == 0.0 || $ydelt == 0.0 } { 749 return -code error "Step size can not be zero" 750 } 751 752 if { $xdelt ne {} && ($xmax-$xmin)*$xdelt < 0.0 } { 753 set xdelt [expr {-$xdelt}] 754 } 755 if { $ydelt ne {} && ($ymax-$ymin)*$ydelt < 0.0 } { 756 set ydelt [expr {-$ydelt}] 757 } 758 759 viewPort $w $pxmin $pymin $pxmax $pymax 760 worldCoordinates $w $xmin $ymin $xmax $ymax 761 762 if { $xdelt eq {} } { 763 foreach {arg val} $args { 764 switch -exact -- $arg { 765 -xlabels { 766 DrawXaxis $w $xmin $xmax $xdelt $arg $val 767 } 768 -ylabels { 769 # Ignore 770 } 771 default { 772 error "Argument $arg not recognized" 773 } 774 } 775 } 776 } else { 777 DrawXaxis $w $xmin $xmax $xdelt 778 } 779 if { $ydelt eq {} } { 780 foreach {arg val} $args { 781 switch -exact -- $arg { 782 -ylabels { 783 DrawYaxis $w $ymin $ymax $ydelt $arg $val 784 } 785 -xlabels { 786 # Ignore 787 } 788 default { 789 error "Argument $arg not recognized" 790 } 791 } 792 } 793 } else { 794 DrawYaxis $w $ymin $ymax $ydelt 795 } 796 DrawMask $w 797 DefaultLegend $w 798 DefaultBalloon $w 799 800 $newchart dataconfig labeldot -colour red -type symbol -symbol dot 801 802 return $newchart 803} 804 805# createStripchart -- 806# Create a command for drawing a strip chart 807# Arguments: 808# w Name of the canvas 809# xscale Minimum, maximum and step for x-axis (initial) 810# yscale Minimum, maximum and step for y-axis 811# Result: 812# Name of a new command 813# Note: 814# The entire canvas will be dedicated to the stripchart. 815# The stripchart will be drawn with axes 816# 817proc ::Plotchart::createStripchart { w xscale yscale } { 818 variable data_series 819 820 set newchart [createXYPlot $w $xscale $yscale] 821 822 interp alias {} $newchart {} 823 824 set newchart "stripchart_$w" 825 interp alias {} $newchart {} ::Plotchart::PlotHandler stripchart $w 826 CopyConfig stripchart $w 827 828 return $newchart 829} 830 831# createIsometricPlot -- 832# Create a command for drawing an "isometric" plot 833# Arguments: 834# w Name of the canvas 835# xscale Minimum and maximum for x-axis 836# yscale Minimum and maximum for y-axis 837# stepsize Step size for numbers on the axes or "noaxes" 838# Result: 839# Name of a new command 840# Note: 841# The entire canvas will be dedicated to the plot 842# The plot will be drawn with or without axes 843# 844proc ::Plotchart::createIsometricPlot { w xscale yscale stepsize } { 845 variable data_series 846 847 foreach s [array names data_series "$w,*"] { 848 unset data_series($s) 849 } 850 851 set newchart "isometric_$w" 852 interp alias {} $newchart {} ::Plotchart::PlotHandler isometric $w 853 CopyConfig isometric $w 854 855 if { $stepsize != "noaxes" } { 856 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 857 } else { 858 set pxmin 0 859 set pymin 0 860 #set pxmax [$w cget -width] 861 #set pymax [$w cget -height] 862 set pxmax [WidthCanvas $w] 863 set pymax [HeightCanvas $w] 864 } 865 866 foreach {xmin xmax xdelt} $xscale {break} 867 foreach {ymin ymax ydelt} $yscale {break} 868 869 if { $xmin == $xmax || $ymin == $ymax } { 870 return -code error "Extremes for axes must be different" 871 } 872 873 viewPort $w $pxmin $pymin $pxmax $pymax 874 ScaleIsometric $w $xmin $ymin $xmax $ymax 875 876 if { $stepsize != "noaxes" } { 877 DrawYaxis $w $ymin $ymax $stepsize 878 DrawXaxis $w $xmin $xmax $stepsize 879 DrawMask $w 880 } 881 DefaultLegend $w 882 DefaultBalloon $w 883 884 return $newchart 885} 886 887# createXLogYPlot -- 888# Create a command for drawing an XY plot (with a vertical logarithmic axis) 889# Arguments: 890# w Name of the canvas 891# xscale Minimum, maximum and step for x-axis (initial) 892# yscale Minimum, maximum and step for y-axis (step is ignored!) 893# Result: 894# Name of a new command 895# Note: 896# The entire canvas will be dedicated to the XY plot. 897# The plot will be drawn with axes 898# 899proc ::Plotchart::createXLogYPlot { w xscale yscale } { 900 variable data_series 901 902 foreach s [array names data_series "$w,*"] { 903 unset data_series($s) 904 } 905 906 set newchart "xlogyplot_$w" 907 interp alias {} $newchart {} ::Plotchart::PlotHandler xlogyplot $w 908 CopyConfig xlogyplot $w 909 910 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 911 912 foreach {xmin xmax xdelt} $xscale {break} 913 foreach {ymin ymax ydelt} $yscale {break} 914 915 if { $xdelt == 0.0 || $ydelt == 0.0 } { 916 return -code error "Step size can not be zero" 917 } 918 919 if { $ymin <= 0.0 || $ymax <= 0.0 } { 920 return -code error "Minimum and maximum for y-axis must be positive" 921 } 922 923 # 924 # TODO: reversed log plot 925 # 926 927 viewPort $w $pxmin $pymin $pxmax $pymax 928 worldCoordinates $w $xmin [expr {log10($ymin)}] $xmax [expr {log10($ymax)}] 929 930 DrawLogYaxis $w $ymin $ymax $ydelt 931 DrawXaxis $w $xmin $xmax $xdelt 932 DrawMask $w 933 DefaultLegend $w 934 DefaultBalloon $w 935 936 return $newchart 937} 938 939# createLogXYPlot -- 940# Create a command for drawing an XY plot (with a horizontal logarithmic axis) 941# Arguments: 942# w Name of the canvas 943# xscale Minimum, maximum and step for x-axis (step is ignored!) 944# yscale Minimum, maximum and step for y-axis (initial) 945# Result: 946# Name of a new command 947# Note: 948# The entire canvas will be dedicated to the XY plot. 949# The plot will be drawn with axes 950# 951proc ::Plotchart::createLogXYPlot { w xscale yscale } { 952 variable data_series 953 954 foreach s [array names data_series "$w,*"] { 955 unset data_series($s) 956 } 957 958 set newchart "logxyplot_$w" 959 interp alias {} $newchart {} ::Plotchart::PlotHandler logxyplot $w 960 CopyConfig logxyplot $w 961 962 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 963 964 foreach {xmin xmax xdelt} $xscale {break} 965 foreach {ymin ymax ydelt} $yscale {break} 966 967 if { $xmin <= 0.0 || $xmax <= 0.0 } { 968 return -code error "Minimum and maximum for x-axis must be positive" 969 } 970 971 if { $ydelt == 0.0 } { 972 return -code error "Step size can not be zero" 973 } 974 975 # 976 # TODO: reversed log plot 977 # 978 979 viewPort $w $pxmin $pymin $pxmax $pymax 980 worldCoordinates $w [expr {log10($xmin)}] $ymin [expr {log10($xmax)}] $ymax 981 DrawYaxis $w $ymin $ymax $ydelt 982 DrawLogXaxis $w $xmin $xmax $xdelt 983 DrawMask $w 984 DefaultLegend $w 985 DefaultBalloon $w 986 987 return $newchart 988} 989 990# createLogXLogYPlot -- 991# Create a command for drawing an XY plot (with a both logarithmic axis) 992# Arguments: 993# w Name of the canvas 994# xscale Minimum, maximum and step for x-axis (step is ignored!) 995# yscale Minimum, maximum and step for y-axis (step is ignored!) 996# Result: 997# Name of a new command 998# Note: 999# The entire canvas will be dedicated to the XY plot. 1000# The plot will be drawn with axes 1001# 1002proc ::Plotchart::createLogXLogYPlot { w xscale yscale } { 1003 variable data_series 1004 1005 foreach s [array names data_series "$w,*"] { 1006 unset data_series($s) 1007 } 1008 1009 set newchart "logxlogyplot_$w" 1010 interp alias {} $newchart {} ::Plotchart::PlotHandler logxlogyplot $w 1011 CopyConfig logxlogyplot $w 1012 1013 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 1014 1015 foreach {xmin xmax xdelt} $xscale {break} 1016 foreach {ymin ymax ydelt} $yscale {break} 1017 1018 if { $xmin <= 0.0 || $xmax <= 0.0 } { 1019 return -code error "Minimum and maximum for x-axis must be positive" 1020 } 1021 1022 if { $ymin <= 0.0 || $ymax <= 0.0 } { 1023 return -code error "Minimum and maximum for y-axis must be positive" 1024 } 1025 1026 # 1027 # TODO: reversed log plot 1028 # 1029 1030 viewPort $w $pxmin $pymin $pxmax $pymax 1031 worldCoordinates $w [expr {log10($xmin)}] [expr {log10($ymin)}] [expr {log10($xmax)}] [expr {log10($ymax)}] 1032 DrawLogYaxis $w $ymin $ymax $ydelt 1033 DrawLogXaxis $w $xmin $xmax $xdelt 1034 DrawMask $w 1035 DefaultLegend $w 1036 DefaultBalloon $w 1037 1038 return $newchart 1039} 1040 1041# createHistogram -- 1042# Create a command for drawing a histogram 1043# Arguments: 1044# w Name of the canvas 1045# xscale Minimum, maximum and step for x-axis (initial) 1046# yscale Minimum, maximum and step for y-axis 1047# Result: 1048# Name of a new command 1049# Note: 1050# The entire canvas will be dedicated to the histogram. 1051# The plot will be drawn with axes 1052# This is almost the same code as for an XY plot 1053# 1054proc ::Plotchart::createHistogram { w xscale yscale } { 1055 variable data_series 1056 1057 foreach s [array names data_series "$w,*"] { 1058 unset data_series($s) 1059 } 1060 1061 set newchart "histogram_$w" 1062 interp alias {} $newchart {} ::Plotchart::PlotHandler histogram $w 1063 CopyConfig histogram $w 1064 1065 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 1066 1067 foreach {xmin xmax xdelt} $xscale {break} 1068 foreach {ymin ymax ydelt} $yscale {break} 1069 1070 if { $xdelt == 0.0 || $ydelt == 0.0 } { 1071 return -code error "Step size can not be zero" 1072 } 1073 1074 if { ($xmax-$xmin)*$xdelt < 0.0 } { 1075 set xdelt [expr {-$xdelt}] 1076 } 1077 if { ($ymax-$ymin)*$ydelt < 0.0 } { 1078 set ydelt [expr {-$ydelt}] 1079 } 1080 1081 viewPort $w $pxmin $pymin $pxmax $pymax 1082 worldCoordinates $w $xmin $ymin $xmax $ymax 1083 1084 DrawYaxis $w $ymin $ymax $ydelt 1085 DrawXaxis $w $xmin $xmax $xdelt 1086 DrawMask $w 1087 DefaultLegend $w 1088 DefaultBalloon $w 1089 1090 return $newchart 1091} 1092 1093# createPiechart -- 1094# Create a command for drawing a pie chart 1095# Arguments: 1096# w Name of the canvas 1097# Result: 1098# Name of a new command 1099# Note: 1100# The entire canvas will be dedicated to the pie chart. 1101# 1102proc ::Plotchart::createPiechart { w } { 1103 variable data_series 1104 variable scaling 1105 1106 foreach s [array names data_series "$w,*"] { 1107 unset data_series($s) 1108 } 1109 1110 set newchart "piechart_$w" 1111 interp alias {} $newchart {} ::Plotchart::PlotHandler piechart $w 1112 CopyConfig piechart $w 1113 1114 foreach {pxmin pymin pxmax pymax} [MarginsCircle $w] {break} 1115 1116 viewPort $w $pxmin $pymin $pxmax $pymax 1117 #$w create oval $pxmin $pymin $pxmax $pymax 1118 1119 SetColours $w blue lightblue green yellow orange red magenta brown 1120 DefaultLegend $w 1121 DefaultBalloon $w 1122 1123 set scaling($w,auto) 0 1124 set scaling($w,exploded) -1 1125 1126 return $newchart 1127} 1128 1129# createPolarplot -- 1130# Create a command for drawing a polar plot 1131# Arguments: 1132# w Name of the canvas 1133# radius_data Maximum radius and step 1134# Result: 1135# Name of a new command 1136# Note: 1137# The entire canvas will be dedicated to the polar plot 1138# Possible additional arguments (optional): nautical/mathematical 1139# step in phi 1140# 1141proc ::Plotchart::createPolarplot { w radius_data } { 1142 variable data_series 1143 1144 foreach s [array names data_series "$w,*"] { 1145 unset data_series($s) 1146 } 1147 1148 set newchart "polarplot_$w" 1149 interp alias {} $newchart {} ::Plotchart::PlotHandler polarplot $w 1150 CopyConfig polarplot $w 1151 1152 set rad_max [lindex $radius_data 0] 1153 set rad_step [lindex $radius_data 1] 1154 1155 if { $rad_step <= 0.0 } { 1156 return -code error "Step size can not be zero or negative" 1157 } 1158 if { $rad_max <= 0.0 } { 1159 return -code error "Maximum radius can not be zero or negative" 1160 } 1161 1162 foreach {pxmin pymin pxmax pymax} [MarginsCircle $w] {break} 1163 1164 viewPort $w $pxmin $pymin $pxmax $pymax 1165 polarCoordinates $w $rad_max 1166 DrawPolarAxes $w $rad_max $rad_step 1167 DefaultLegend $w 1168 DefaultBalloon $w 1169 1170 $newchart dataconfig labeldot -colour red -type symbol -symbol dot 1171 1172 return $newchart 1173} 1174 1175# createBarchart -- 1176# Create a command for drawing a barchart with vertical bars 1177# Arguments: 1178# w Name of the canvas 1179# xlabels List of labels for x-axis 1180# yscale Minimum, maximum and step for y-axis 1181# noseries Number of series or the keyword "stacked" 1182# Result: 1183# Name of a new command 1184# Note: 1185# The entire canvas will be dedicated to the barchart. 1186# 1187proc ::Plotchart::createBarchart { w xlabels yscale noseries } { 1188 variable data_series 1189 variable settings 1190 1191 foreach s [array names data_series "$w,*"] { 1192 unset data_series($s) 1193 } 1194 1195 set newchart "barchart_$w" 1196 interp alias {} $newchart {} ::Plotchart::PlotHandler vertbars $w 1197 CopyConfig vertbars $w 1198 1199 set settings($w,showvalues) 0 1200 set settings($w,valuefont) "" 1201 set settings($w,valuecolour) black 1202 set settings($w,valueformat) %s 1203 1204 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 1205 1206 set xmin 0.0 1207 set xmax [expr {[llength $xlabels] + 0.1}] 1208 1209 foreach {ymin ymax ydelt} $yscale {break} 1210 1211 if { $ydelt == 0.0 } { 1212 return -code error "Step size can not be zero" 1213 } 1214 1215 if { ($ymax-$ymin)*$ydelt < 0.0 } { 1216 set ydelt [expr {-$ydelt}] 1217 } 1218 1219 viewPort $w $pxmin $pymin $pxmax $pymax 1220 worldCoordinates $w $xmin $ymin $xmax $ymax 1221 1222 DrawYaxis $w $ymin $ymax $ydelt 1223 DrawXlabels $w $xlabels $noseries 1224 DrawMask $w 1225 DefaultLegend $w 1226 set data_series($w,legendtype) "rectangle" 1227 DefaultBalloon $w 1228 1229 SetColours $w blue lightblue green yellow orange red magenta brown 1230 1231 return $newchart 1232} 1233 1234# createHorizontalBarchart -- 1235# Create a command for drawing a barchart with horizontal bars 1236# Arguments: 1237# w Name of the canvas 1238# xscale Minimum, maximum and step for x-axis 1239# ylabels List of labels for y-axis 1240# noseries Number of series or the keyword "stacked" 1241# Result: 1242# Name of a new command 1243# Note: 1244# The entire canvas will be dedicated to the barchart. 1245# 1246proc ::Plotchart::createHorizontalBarchart { w xscale ylabels noseries } { 1247 variable data_series 1248 variable config 1249 variable settings 1250 1251 foreach s [array names data_series "$w,*"] { 1252 unset data_series($s) 1253 } 1254 1255 set newchart "hbarchart_$w" 1256 interp alias {} $newchart {} ::Plotchart::PlotHandler horizbars $w 1257 CopyConfig horizbars $w 1258 1259 set settings($w,showvalues) 0 1260 set settings($w,valuefont) "" 1261 set settings($w,valuecolour) black 1262 set settings($w,valueformat) %s 1263 1264 set font $config($w,leftaxis,font) 1265 set xspacemax 0 1266 foreach ylabel $ylabels { 1267 set xspace [font measure $font $ylabel] 1268 if { $xspace > $xspacemax } { 1269 set xspacemax $xspace 1270 } 1271 } 1272 set config($w,margin,left) [expr {$xspacemax+5}] ;# Slightly more space required! 1273 1274 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 1275 1276 set ymin 0.0 1277 set ymax [expr {[llength $ylabels] + 0.1}] 1278 1279 foreach {xmin xmax xdelt} $xscale {break} 1280 1281 if { $xdelt == 0.0 } { 1282 return -code error "Step size can not be zero" 1283 } 1284 1285 if { ($xmax-$xmin)*$xdelt < 0.0 } { 1286 set xdelt [expr {-$xdelt}] 1287 } 1288 1289 viewPort $w $pxmin $pymin $pxmax $pymax 1290 worldCoordinates $w $xmin $ymin $xmax $ymax 1291 1292 DrawXaxis $w $xmin $xmax $xdelt 1293 DrawYlabels $w $ylabels $noseries 1294 DrawMask $w 1295 DefaultLegend $w 1296 set data_series($w,legendtype) "rectangle" 1297 DefaultBalloon $w 1298 1299 SetColours $w blue lightblue green yellow orange red magenta brown 1300 1301 return $newchart 1302} 1303 1304# createBoxplot -- 1305# Create a command for drawing a plot with box-and-whiskers 1306# Arguments: 1307# w Name of the canvas 1308# xscale Minimum, maximum and step for x-axis 1309# ylabels List of labels for y-axis 1310# Result: 1311# Name of a new command 1312# Note: 1313# The entire canvas will be dedicated to the boxplot. 1314# 1315proc ::Plotchart::createBoxplot { w xscale ylabels } { 1316 variable data_series 1317 variable config 1318 1319 foreach s [array names data_series "$w,*"] { 1320 unset data_series($s) 1321 } 1322 1323 set newchart "boxplot_$w" 1324 interp alias {} $newchart {} ::Plotchart::PlotHandler boxplot $w 1325 CopyConfig boxplot $w 1326 1327 set font $config($w,leftaxis,font) 1328 set xspacemax 0 1329 foreach ylabel $ylabels { 1330 set xspace [font measure $font $ylabel] 1331 if { $xspace > $xspacemax } { 1332 set xspacemax $xspace 1333 } 1334 } 1335 set config($w,margin,left) [expr {$xspacemax+5}] ;# Slightly more space required! 1336 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 1337 1338 set ymin 0.0 1339 set ymax [expr {[llength $ylabels] + 0.1}] 1340 1341 foreach {xmin xmax xdelt} $xscale {break} 1342 1343 if { $xdelt == 0.0 } { 1344 return -code error "Step size can not be zero" 1345 } 1346 1347 if { ($xmax-$xmin)*$xdelt < 0.0 } { 1348 set xdelt [expr {-$xdelt}] 1349 } 1350 1351 viewPort $w $pxmin $pymin $pxmax $pymax 1352 worldCoordinates $w $xmin $ymin $xmax $ymax 1353 1354 DrawXaxis $w $xmin $xmax $xdelt 1355 DrawYlabels $w $ylabels 1 1356 DrawMask $w 1357 DefaultLegend $w 1358 set data_series($w,legendtype) "rectangle" 1359 DefaultBalloon $w 1360 1361 set config($w,axisnames) $ylabels 1362 1363 return $newchart 1364} 1365 1366# createTimechart -- 1367# Create a command for drawing a simple timechart 1368# Arguments: 1369# w Name of the canvas 1370# time_begin Start time (in the form of a date/time) 1371# time_end End time (in the form of a date/time) 1372# args Number of items to be shown (determines spacing) 1373# or one or more options (-barheight pixels, -ylabelwidth pixels) 1374# Result: 1375# Name of a new command 1376# Note: 1377# The entire canvas will be dedicated to the timechart. 1378# 1379proc ::Plotchart::createTimechart { w time_begin time_end args} { 1380 variable data_series 1381 variable scaling 1382 1383 foreach s [array names data_series "$w,*"] { 1384 unset data_series($s) 1385 } 1386 1387 set newchart "timechart_$w" 1388 interp alias {} $newchart {} ::Plotchart::PlotHandler timechart $w 1389 CopyConfig timechart $w 1390 1391 # 1392 # Handle the arguments 1393 # 1394 set barheight 0 1395 set noitems [lindex $args 0] 1396 set ylabelwidth 8 1397 1398 if { [string is integer -strict $noitems] } { 1399 set args [lrange $args 1 end] 1400 } 1401 foreach {keyword value} $args { 1402 switch -- $keyword { 1403 "-barheight" { 1404 set barheight $value 1405 } 1406 "-ylabelwidth" { 1407 set ylabelwidth [expr {$value/10.0}] ;# Pixels to characters 1408 } 1409 default { 1410 # Ignore 1411 } 1412 } 1413 } 1414 1415 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w 3 $ylabelwidth] {break} 1416 1417 if { $barheight != 0 } { 1418 set noitems [expr {($pxmax-$pxmin)/double($barheight)}] 1419 } 1420 set scaling($w,barheight) $barheight 1421 1422 set ymin 0.0 1423 set ymax $noitems 1424 1425 set xmin [expr {1.0*[clock scan $time_begin]}] 1426 set xmax [expr {1.0*[clock scan $time_end]}] 1427 1428 viewPort $w $pxmin $pymin $pxmax $pymax 1429 worldCoordinates $w $xmin $ymin $xmax $ymax 1430 1431 set scaling($w,current) $ymax 1432 set scaling($w,dy) -0.7 1433 1434 DrawScrollMask $w 1435 set scaling($w,curpos) 0 1436 set scaling($w,curhpos) 0 1437 1438 return $newchart 1439} 1440 1441# createGanttchart -- 1442# Create a command for drawing a Gantt (planning) chart 1443# Arguments: 1444# w Name of the canvas 1445# time_begin Start time (in the form of a date/time) 1446# time_end End time (in the form of a date/time) 1447# args (First integer) Number of items to be shown (determines spacing) 1448# (Second integer) Estimated maximum length of text (default: 20) 1449# Or keyword-value pairs 1450# Result: 1451# Name of a new command 1452# Note: 1453# The entire canvas will be dedicated to the Gantt chart. 1454# Most commands taken from time charts. 1455# 1456proc ::Plotchart::createGanttchart { w time_begin time_end args} { 1457 1458 variable data_series 1459 variable scaling 1460 1461 foreach s [array names data_series "$w,*"] { 1462 unset data_series($s) 1463 } 1464 1465 set newchart "ganttchart_$w" 1466 interp alias {} $newchart {} ::Plotchart::PlotHandler ganttchart $w 1467 CopyConfig ganttchart $w 1468 1469 # 1470 # Handle the arguments 1471 # 1472 set barheight 0 1473 set noitems [lindex $args 0] 1474 1475 if { [string is integer -strict $noitems] } { 1476 set args [lrange $args 1 end] 1477 set ylabelwidth [lindex $args 0] 1478 if { [string is integer -strict $ylabelwidth] } { 1479 set args [lrange $args 1 end] 1480 } else { 1481 set ylabelwidth 20 1482 } 1483 } else { 1484 set ylabelwidth 20 1485 } 1486 1487 foreach {keyword value} $args { 1488 switch -- $keyword { 1489 "-barheight" { 1490 set barheight $value 1491 } 1492 "-ylabelwidth" { 1493 set ylabelwidth [expr {$value/10.0}] ;# Pixels to characters 1494 } 1495 default { 1496 # Ignore 1497 } 1498 } 1499 } 1500 1501 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w 3 $ylabelwidth] {break} 1502 1503 if { $barheight != 0 } { 1504 set noitems [expr {($pxmax-$pxmin)/double($barheight)}] 1505 } 1506 set scaling($w,barheight) $barheight 1507 1508 set ymin 0.0 1509 set ymax $noitems 1510 1511 set xmin [expr {1.0*[clock scan $time_begin]}] 1512 set xmax [expr {1.0*[clock scan $time_end]}] 1513 1514 viewPort $w $pxmin $pymin $pxmax $pymax 1515 worldCoordinates $w $xmin $ymin $xmax $ymax 1516 1517 set scaling($w,current) $ymax 1518 set scaling($w,dy) -0.7 1519 1520 # 1521 # Draw the backgrounds (both in the text part and the 1522 # graphical part; the text part has the "special" tag 1523 # "Edit" to enable a GUI to change things) 1524 # 1525 set yend 0.0 1526 for { set i 0 } { $i < $noitems } { incr i } { 1527 set ybegin $yend 1528 set yend [expr {$ybegin+1.0}] 1529 foreach {x1 y1} [coordsToPixel $w $xmin $ybegin] {break} 1530 foreach {x2 y2} [coordsToPixel $w $xmax $yend ] {break} 1531 1532 if { $i%2 == 0 } { 1533 set tag odd 1534 } else { 1535 set tag even 1536 } 1537 $w create rectangle 0 $y1 $x1 $y2 -fill white \ 1538 -tag {Edit vertscroll lowest} -outline white 1539 $w create rectangle $x1 $y1 $x2 $y2 -fill white \ 1540 -tag [list $tag vertscroll lowest] -outline white 1541 } 1542 1543 # 1544 # Default colours and fonts 1545 # 1546 GanttColor $w description black 1547 GanttColor $w completed lightblue 1548 GanttColor $w left white 1549 GanttColor $w odd white 1550 GanttColor $w even lightgrey 1551 GanttColor $w summary black 1552 GanttColor $w summarybar black 1553 GanttFont $w description "times 10" 1554 GanttFont $w summary "times 10 bold" 1555 GanttFont $w scale "times 7" 1556 DefaultBalloon $w 1557 1558 DrawScrollMask $w 1559 set scaling($w,curpos) 0 1560 set scaling($w,curhpos) 0 1561 1562 return $newchart 1563} 1564 1565# create3DPlot -- 1566# Create a simple 3D plot 1567# Arguments: 1568# w Name of the canvas 1569# xscale Minimum, maximum and step for x-axis (initial) 1570# yscale Minimum, maximum and step for y-axis 1571# zscale Minimum, maximum and step for z-axis 1572# Result: 1573# Name of a new command 1574# Note: 1575# The entire canvas will be dedicated to the 3D plot 1576# 1577proc ::Plotchart::create3DPlot { w xscale yscale zscale } { 1578 variable data_series 1579 1580 foreach s [array names data_series "$w,*"] { 1581 unset data_series($s) 1582 } 1583 1584 set newchart "3dplot_$w" 1585 interp alias {} $newchart {} ::Plotchart::PlotHandler 3dplot $w 1586 CopyConfig 3dplot $w 1587 1588 foreach {pxmin pymin pxmax pymax} [Margins3DPlot $w] {break} 1589 1590 foreach {xmin xmax xstep} $xscale {break} 1591 foreach {ymin ymax ystep} $yscale {break} 1592 foreach {zmin zmax zstep} $zscale {break} 1593 1594 viewPort $w $pxmin $pymin $pxmax $pymax 1595 world3DCoordinates $w $xmin $ymin $zmin $xmax $ymax $zmax 1596 1597 Draw3DAxes $w $xmin $ymin $zmin $xmax $ymax $zmax \ 1598 $xstep $ystep $zstep 1599 DefaultLegend $w 1600 DefaultBalloon $w 1601 1602 SetColours $w grey black 1603 1604 return $newchart 1605} 1606 1607# create3DRibbonPlot -- 1608# Create a simple 3D plot that allows for ribbons 1609# Arguments: 1610# w Name of the canvas 1611# yscale Minimum, maximum and step for y-axis 1612# zscale Minimum, maximum and step for z-axis 1613# Result: 1614# Name of a new command 1615# Note: 1616# The entire canvas will be dedicated to the 3D plot 1617# 1618proc ::Plotchart::create3DRibbonPlot { w yscale zscale } { 1619 variable data_series 1620 1621 foreach s [array names data_series "$w,*"] { 1622 unset data_series($s) 1623 } 1624 1625 set newchart "3dribbonplot_$w" 1626 interp alias {} $newchart {} ::Plotchart::PlotHandler 3dribbonplot $w 1627 CopyConfig 3dplot $w 1628 1629 foreach {pxmin pymin pxmax pymax} [Margins3DPlot $w] {break} 1630 1631 foreach {xmin xmax xstep} {0.0 1.0 0.0} {break} 1632 foreach {ymin ymax ystep} $yscale {break} 1633 foreach {zmin zmax zstep} $zscale {break} 1634 1635 viewPort $w $pxmin $pymin $pxmax $pymax 1636 world3DCoordinates $w $xmin $ymin $zmin $xmax $ymax $zmax 1637 1638 Draw3DAxes $w $xmin $ymin $zmin $xmin $ymax $zmax \ 1639 $xstep $ystep $zstep 1640 DefaultLegend $w 1641 DefaultBalloon $w 1642 1643 SetColours $w grey black 1644 1645 return $newchart 1646} 1647 1648# create3DBarchart -- 1649# Create a command for drawing a barchart with vertical 3D bars 1650# Arguments: 1651# w Name of the canvas 1652# yscale Minimum, maximum and step for y-axis 1653# nobars Number of bars to be drawn 1654# Result: 1655# Name of a new command 1656# Note: 1657# The entire canvas will be dedicated to the barchart. 1658# 1659proc ::Plotchart::create3DBarchart { w yscale nobars } { 1660 variable data_series 1661 1662 foreach s [array names data_series "$w,*"] { 1663 unset data_series($s) 1664 } 1665 1666 set newchart "3dbarchart_$w" 1667 interp alias {} $newchart {} ::Plotchart::PlotHandler 3dbars $w 1668 CopyConfig 3dbars $w 1669 1670 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w 4] {break} 1671 1672 set xmin 0.0 1673 set xmax [expr {$nobars + 0.1}] 1674 1675 foreach {ymin ymax ydelt} $yscale {break} 1676 1677 if { $ydelt == 0.0 } { 1678 return -code error "Step size can not be zero" 1679 } 1680 1681 if { ($ymax-$ymin)*$ydelt < 0.0 } { 1682 set ydelt [expr {-$ydelt}] 1683 } 1684 1685 viewPort $w $pxmin $pymin $pxmax $pymax 1686 worldCoordinates $w $xmin $ymin $xmax $ymax 1687 1688 DrawYaxis $w $ymin $ymax $ydelt 1689 #DrawMask $w -- none! 1690 Draw3DBarchart $w $yscale $nobars 1691 DefaultLegend $w 1692 DefaultBalloon $w 1693 1694 return $newchart 1695} 1696 1697# createRadialchart -- 1698# Create a command for drawing a radial chart 1699# Arguments: 1700# w Name of the canvas 1701# names Names of the spokes 1702# scale Scale factor for the data 1703# style (Optional) style of the chart (lines, cumulative or filled) 1704# Result: 1705# Name of a new command 1706# Note: 1707# The entire canvas will be dedicated to the radial chart. 1708# 1709proc ::Plotchart::createRadialchart { w names scale {style lines} } { 1710 variable settings 1711 variable data_series 1712 1713 foreach s [array names data_series "$w,*"] { 1714 unset data_series($s) 1715 } 1716 1717 set newchart "radialchart_$w" 1718 interp alias {} $newchart {} ::Plotchart::PlotHandler radialchart $w 1719 CopyConfig radialchart $w 1720 1721 foreach {pxmin pymin pxmax pymax} [MarginsCircle $w] {break} 1722 1723 viewPort $w $pxmin $pymin $pxmax $pymax 1724 $w create oval $pxmin $pymin $pxmax $pymax 1725 1726 set settings($w,scale) [expr {double($scale)}] 1727 set settings($w,style) $style 1728 set settings($w,number) [llength $names] 1729 1730 DrawRadialSpokes $w $names 1731 DefaultLegend $w 1732 DefaultBalloon $w 1733 1734 return $newchart 1735} 1736 1737# createTXPlot -- 1738# Create a command for drawing a TX plot (x versus date/time) 1739# Arguments: 1740# w Name of the canvas 1741# tscale Minimum, maximum and step for date/time-axis (initial) 1742# (values must be valid dates and the step is in days) 1743# xscale Minimum, maximum and step for vertical axis 1744# Result: 1745# Name of a new command 1746# Note: 1747# The entire canvas will be dedicated to the TX plot. 1748# The plot will be drawn with axes 1749# 1750proc ::Plotchart::createTXPlot { w tscale xscale } { 1751 variable data_series 1752 1753 foreach s [array names data_series "$w,*"] { 1754 unset data_series($s) 1755 } 1756 1757 set newchart "txplot_$w" 1758 interp alias {} $newchart {} ::Plotchart::PlotHandler txplot $w 1759 CopyConfig txplot $w 1760 1761 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 1762 1763 foreach {tmin tmax tdelt} $tscale {break} 1764 1765 set xmin [clock scan $tmin] 1766 set xmax [clock scan $tmax] 1767 set xdelt [expr {86400*$tdelt}] 1768 1769 foreach {ymin ymax ydelt} $xscale {break} 1770 1771 if { $xdelt == 0.0 || $ydelt == 0.0 } { 1772 return -code error "Step size can not be zero" 1773 } 1774 1775 if { ($xmax-$xmin)*$xdelt < 0.0 } { 1776 set xdelt [expr {-$xdelt}] 1777 } 1778 if { ($ymax-$ymin)*$ydelt < 0.0 } { 1779 set ydelt [expr {-$ydelt}] 1780 } 1781 1782 viewPort $w $pxmin $pymin $pxmax $pymax 1783 worldCoordinates $w $xmin $ymin $xmax $ymax 1784 1785 DrawYaxis $w $ymin $ymax $ydelt 1786 DrawTimeaxis $w $tmin $tmax $tdelt 1787 DrawMask $w 1788 DefaultLegend $w 1789 DefaultBalloon $w 1790 1791 return $newchart 1792} 1793 1794# createRightAxis -- 1795# Create a command for drawing a plot with a right axis 1796# Arguments: 1797# w Name of the canvas 1798# yscale Minimum, maximum and step for vertical axis 1799# Result: 1800# Name of a new command 1801# Note: 1802# This command requires that another plot command has been 1803# created prior to this one. Some of the properties from that 1804# command serve for this one too. 1805# 1806proc ::Plotchart::createRightAxis { w yscale } { 1807 variable data_series 1808 variable scaling 1809 variable config 1810 1811 set newchart "right_$w" 1812 1813 # 1814 # Check if there is an appropriate plot already defined - there 1815 # should be only one! 1816 # 1817 if { [llength [info command "*_$w" ]] == 0 } { 1818 return -code error "There should be a plot with a left axis already defined" 1819 } 1820 if { [llength [info command "*_$w" ]] >= 2 } { 1821 if { [llength [info command "right_$w"]] == 0 } { 1822 return -code error "There should be only one plot command for this widget ($w)" 1823 } else { 1824 catch { 1825 interp alias {} $newchart {} 1826 } 1827 } 1828 } 1829 1830 foreach s [array names data_series "r$w,*"] { 1831 unset data_series($s) 1832 } 1833 1834 set type [lindex [interp alias {} [info command "*_$w"]] 1] 1835 1836 interp alias {} $newchart {} ::Plotchart::PlotHandler $type r$w 1837 interp alias {} r$w {} $w 1838 CopyConfig $type r$w 1839 1840 set config(r$w,font,char_width) $config($w,font,char_width) 1841 set config(r$w,font,char_height) $config($w,font,char_height) 1842 1843 set xmin $scaling($w,xmin) 1844 set xmax $scaling($w,xmax) 1845 1846 set pxmin $scaling($w,pxmin) 1847 set pxmax $scaling($w,pxmax) 1848 set pymin $scaling($w,pymin) 1849 set pymax $scaling($w,pymax) 1850 1851 foreach {ymin ymax ydelt} $yscale {break} 1852 1853 if { $ydelt == 0.0 } { 1854 return -code error "Step size can not be zero" 1855 } 1856 1857 if { ($ymax-$ymin)*$ydelt < 0.0 } { 1858 set ydelt [expr {-$ydelt}] 1859 } 1860 1861 viewPort r$w $pxmin $pymin $pxmax $pymax 1862 worldCoordinates r$w $xmin $ymin $xmax $ymax 1863 1864 DrawRightaxis r$w $ymin $ymax $ydelt 1865 1866 #DefaultLegend r$w 1867 #DefaultBalloon r$w 1868 1869 return $newchart 1870} 1871 1872# create3DRibbonChart -- 1873# Create a chart that can display 3D lines and areas 1874# Arguments: 1875# w Name of the canvas 1876# names Labels along the x-axis 1877# yscale Minimum, maximum and step for y-axis 1878# zscale Minimum, maximum and step for z-axis 1879# Result: 1880# Name of a new command 1881# Note: 1882# The entire canvas will be dedicated to the 3D chart 1883# 1884proc ::Plotchart::create3DRibbonChart { w names yscale zscale } { 1885 variable data_series 1886 1887 foreach s [array names data_series "$w,*"] { 1888 unset data_series($s) 1889 } 1890 1891 set newchart "3dribbon_$w" 1892 interp alias {} $newchart {} ::Plotchart::PlotHandler 3dribbon $w 1893 CopyConfig 3dribbon $w 1894 1895 foreach {pxmin pymin pxmax pymax} [Margins3DPlot $w] {break} 1896 1897 foreach {xmin xmax xstep} {0.0 1.0 0.0} {break} 1898 foreach {ymin ymax ystep} $yscale {break} 1899 foreach {zmin zmax zstep} $zscale {break} 1900 1901 set xstep [expr {1.0/[llength $names]}] 1902 set data_series($w,xbase) [expr {1.0-0.15*$xstep}] 1903 set data_series($w,xstep) $xstep 1904 set data_series($w,xwidth) [expr {0.7*$xstep}] 1905 1906 viewPort $w $pxmin $pymin $pxmax $pymax 1907 world3DCoordinates $w $xmin $ymin $zmin $xmax $ymax $zmax 1908 1909 Draw3DAxes $w $xmin $ymin $zmin $xmax $ymax $zmax \ 1910 $xstep $ystep $zstep $names 1911 DefaultLegend $w 1912 DefaultBalloon $w 1913 1914 SetColours $w grey black 1915 1916 return $newchart 1917} 1918 1919# createWindRose -- 1920# Create a new command for plotting a windrose 1921# 1922# Arguments: 1923# w Name of the canvas 1924# radius_data Maximum radius and step 1925# sectors Number of sectors (default: 16) 1926# Result: 1927# Name of a new command 1928# Note: 1929# The entire canvas will be dedicated to the windrose 1930# Possible additional arguments (optional): nautical/mathematical 1931# step in phi 1932# 1933proc ::Plotchart::createWindRose { w radius_data {sectors 16}} { 1934 variable data_series 1935 1936 foreach s [array names data_series "$w,*"] { 1937 unset data_series($s) 1938 } 1939 1940 set newchart "windrose_$w" 1941 interp alias {} $newchart {} ::Plotchart::PlotHandler windrose $w 1942 CopyConfig windrose $w 1943 1944 set rad_max [lindex $radius_data 0] 1945 set rad_step [lindex $radius_data 1] 1946 1947 if { $rad_step <= 0.0 } { 1948 return -code error "Step size can not be zero or negative" 1949 } 1950 if { $rad_max <= 0.0 } { 1951 return -code error "Maximum radius can not be zero or negative" 1952 } 1953 1954 foreach {pxmin pymin pxmax pymax} [MarginsCircle $w] {break} 1955 1956 viewPort $w $pxmin $pymin $pxmax $pymax 1957 polarCoordinates $w $rad_max 1958 DrawRoseAxes $w $rad_max $rad_step 1959 1960 1961 set data_series($w,radius) {} 1962 for { set i 0 } { $i < $sectors } { incr i } { 1963 lappend data_series($w,cumulative_radius) 0.0 1964 } 1965 1966 set data_series($w,start_angle) [expr {90.0 - 360.0/(4.0*$sectors)}] 1967 set data_series($w,d_angle) [expr {360.0/(2.0*$sectors)}] 1968 set data_series($w,increment_angle) [expr {360.0/$sectors}] 1969 set data_series($w,count_data) 0 1970 1971 1972 return $newchart 1973} 1974 1975# createTargetDiagram -- 1976# Create a command for drawing a target diagram 1977# Arguments: 1978# w Name of the canvas 1979# bounds List of radii to indicate bounds for the skill 1980# scale Scale of the axes - defaults to 1 1981# Result: 1982# Name of a new command 1983# Note: 1984# The entire canvas will be dedicated to the XY plot. 1985# The plot will be drawn with axes 1986# 1987proc ::Plotchart::createTargetDiagram { w bounds {scale 1.0}} { 1988 variable scaling 1989 variable data_series 1990 variable config 1991 1992 foreach s [array names data_series "$w,*"] { 1993 unset data_series($s) 1994 } 1995 1996 set newchart "targetdiagram_$w" 1997 interp alias {} $newchart {} ::Plotchart::PlotHandler targetdiagram $w 1998 CopyConfig targetdiagram $w 1999 2000 foreach {pxmin pymin pxmax pymax} [MarginsSquare $w] {break} 2001 2002 set extremes [determineScale [expr {-$scale}] $scale] 2003 foreach {xmin xmax xdelt} $extremes {break} 2004 foreach {ymin ymax ydelt} $extremes {break} 2005 2006 if { $xdelt == 0.0 || $ydelt == 0.0 } { 2007 return -code error "Step size can not be zero" 2008 } 2009 2010 if { $xdelt ne {} && ($xmax-$xmin)*$xdelt < 0.0 } { 2011 set xdelt [expr {-$xdelt}] 2012 } 2013 if { ($ymax-$ymin)*$ydelt < 0.0 } { 2014 set ydelt [expr {-$ydelt}] 2015 } 2016 2017 viewPort $w $pxmin $pymin $pxmax $pymax 2018 worldCoordinates $w $xmin $ymin $xmax $ymax 2019 2020 DrawYaxis $w $ymin $ymax $ydelt 2021 DrawXaxis $w $xmin $xmax $xdelt 2022 2023 DrawMask $w 2024 DefaultLegend $w 2025 DefaultBalloon $w 2026 2027 foreach {pxcent pycent} [coordsToPixel $w 0.0 0.0] {break} 2028 2029 $w create line $pxmin $pycent $pxmax $pycent -fill $config($w,limits,color) -tag limits 2030 $w create line $pxcent $pymin $pxcent $pymax -fill $config($w,limits,color) -tag limits 2031 2032 foreach r $bounds { 2033 foreach {pxmin pymin} [coordsToPixel $w [expr {-$r}] [expr {-$r}]] {break} 2034 foreach {pxmax pymax} [coordsToPixel $w $r $r] {break} 2035 2036 $w create oval $pxmin $pymin $pxmax $pymax -outline $config($w,limits,color) -tag limits 2037 } 2038 2039 2040 return $newchart 2041} 2042 2043# createPerformanceProfile -- 2044# Create a command for drawing a performance profile 2045# Arguments: 2046# w Name of the canvas 2047# scale Maximum value for the x-axis 2048# Result: 2049# Name of a new command 2050# Note: 2051# The entire canvas will be dedicated to the XY plot. 2052# The plot will be drawn with axes 2053# 2054proc ::Plotchart::createPerformanceProfile { w scale } { 2055 variable scaling 2056 variable data_series 2057 2058 foreach s [array names data_series "$w,*"] { 2059 unset data_series($s) 2060 } 2061 2062 set newchart "performance_$w" 2063 interp alias {} $newchart {} ::Plotchart::PlotHandler performance $w 2064 CopyConfig performance $w 2065 set scaling($w,eventobj) "" 2066 2067 foreach {pxmin pymin pxmax pymax} [MarginsRectangle $w] {break} 2068 2069 foreach {xmin xmax xdelt} [determineScale 1.0 $scale] {break} 2070 foreach {ymin ymax ydelt} {0.0 1.1 0.25} {break} 2071 2072 viewPort $w $pxmin $pymin $pxmax $pymax 2073 worldCoordinates $w $xmin $ymin $xmax $ymax 2074 2075 DrawYaxis $w $ymin $ymax $ydelt 2076 DrawXaxis $w $xmin $xmax $xdelt 2077 2078 DrawMask $w 2079 DefaultLegend $w 2080 LegendConfigure $w -position bottom-right 2081 DefaultBalloon $w 2082 2083 2084 return $newchart 2085} 2086 2087# Load the private procedures 2088# 2089source [file join [file dirname [info script]] "plotpriv.tcl"] 2090source [file join [file dirname [info script]] "plotaxis.tcl"] 2091source [file join [file dirname [info script]] "plot3d.tcl"] 2092source [file join [file dirname [info script]] "scaling.tcl"] 2093source [file join [file dirname [info script]] "plotcontour.tcl"] 2094source [file join [file dirname [info script]] "plotgantt.tcl"] 2095source [file join [file dirname [info script]] "plotbusiness.tcl"] 2096source [file join [file dirname [info script]] "plotannot.tcl"] 2097source [file join [file dirname [info script]] "plotconfig.tcl"] 2098source [file join [file dirname [info script]] "plotpack.tcl"] 2099source [file join [file dirname [info script]] "plotbind.tcl"] 2100source [file join [file dirname [info script]] "plotspecial.tcl"] 2101 2102# Announce our presence 2103# 2104package provide Plotchart 1.9.2 2105