1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
|
# copyright (C) 1997-2005 Jean-Luc Fontaine (mailto:jfontain@free.fr)
# this program is free software: please read the COPYRIGHT file enclosed in this package or use the Help Copyright menu
# $Id: databar.tcl,v 2.39 2005/02/05 21:22:39 jfontain Exp $
class dataBarChart {
set (plotBackground) $widget::option(button,background)
set (list) {}
proc dataBarChart {this parentPath noMinimum args} composite {[new frame $parentPath] $args} blt2DViewer {
$widget::($this,path) [blt::barchart $widget::($this,path).bar -title {} -bottommargin 6 -plotbackground $(plotBackground)]
0 $noMinimum
} {
if {$noMinimum} {set ($this,noMinimum) {}}
set path $widget::($this,path).bar
$path grid off ;# grid is on by default
$path xaxis configure -hide 1; $path yaxis configure -hide 1
set ($this,path) $path
composite::complete $this
lappend (list) $this ;# remember bar charts in order to be able to globally set some options
# display help message after object is completely constructed for the message virtual procedure to work:
after idle "dataBarChart::updateMessage $this"
}
proc ~dataBarChart {this} {
ldelete (list) $this
if {[string length $composite::($this,-deletecommand)]>0} {
uplevel #0 $composite::($this,-deletecommand) ;# always invoke command at global level
}
}
proc options {this} {
# force size values
return [list\
[list -cellcolors {} {}]\
[list -deletecommand {} {}]\
[list -draggable 0 0]\
[list -height $global::viewerHeight]\
[list -labelsposition right]\
[list -mode normal normal]\
[list -width $global::viewerWidth]\
[list -ymaximum {} {}]\
[list -ymaximumcell {} {}]\
[list -yminimum $global::graphMinimumY]\
[list -yminimumcell {} {}]\
]
}
proc set-cellcolors {this value} { ;# colors of soon to be created cells when initializing from file
if {$composite::($this,complete)} {
error {option -cellcolors cannot be set dynamically}
}
blt2DViewer::setCellColors $this $value
}
proc set-deletecommand {this value} {}
foreach option {-height -width} {
proc set$option {this value} "\$widget::(\$this,path) configure $option \$value"
}
proc set-draggable {this value} {
if {$composite::($this,complete)} {
error {option -draggable cannot be set dynamically}
}
if {$value} {
blt2DViewer::allowDrag $this
}
}
proc set-mode {this value} {
$($this,path) configure -barmode $value
}
proc set-labelsposition {this value} {
blt2DViewer::updateLayout $this
}
proc set-ymaximum {this value} {
blt2DViewer::setLimit $this maximum $value
}
proc set-ymaximumcell {this value} {
blt2DViewer::setLimitCell $this maximum $value
}
proc set-yminimum {this value} {
if {[info exists ($this,noMinimum)]} return ;# minimum limits useless when fixed 0 minimum
blt2DViewer::setLimit $this minimum $value
}
proc set-yminimumcell {this value} {
if {[info exists ($this,noMinimum)]} return ;# minimum limits useless when fixed 0 minimum
blt2DViewer::setLimitCell $this minimum $value
}
proc newElement {this path args} { ;# invoked from 2D viewer base class
return [eval new element $path $args]
}
virtual proc updateElement {this element seconds value} { ;# value is either a valid number or the ? character
if {[string equal $value ?]} { ;# handle void value
element::update $element 0
} else {
element::update $element $value
}
}
proc modified {this monitored} { ;# number of monitored cells
$($this,path) yaxis configure -hide [expr {$monitored == 0}] ;# hide if no elements to display
updateMessage $this
}
proc updateMessage {this} {
# viewer may have been immediately deleted after construction when a cell of an invalid type was dropped:
if {[catch {classof $this}]} return
if {[llength [blt2DViewer::cells $this]] == 0} {
centerMessage $widget::($this,path) [message $this] $(plotBackground) $global::viewerMessageColor
} else {
centerMessage $widget::($this,path) {}
}
}
virtual proc message {this}
proc initializationConfiguration {this} {
if {[info exists ($this,noMinimum)]} { ;# minimum limits useless when fixed 0 minimum
set list {}
} else {
set list [list -yminimum $composite::($this,-yminimum) -yminimumcell $composite::($this,-yminimumcell)]
}
return [concat\
[list\
-ymaximum $composite::($this,-ymaximum) -ymaximumcell $composite::($this,-ymaximumcell)\
-labelsposition $composite::($this,-labelsposition)\
] $list [blt2DViewer::_initializationConfiguration $this]\
]
}
}
class dataBarChart {
class element {
proc element {this path args} switched {$args} {
$path element create $this -label {} -borderwidth 1 -xdata 0 ;# use object identifier as element identifier
set ($this,path) $path
switched::complete $this
}
proc ~element {this} {
$($this,path) element delete $this
if {[string length $switched::($this,-deletecommand)]>0} {
uplevel #0 $switched::($this,-deletecommand) ;# always invoke command at global level
}
}
proc options {this} {
return [list\
[list -color black black]\
[list -deletecommand {} {}]\
]
}
proc set-color {this value} {
$($this,path) element configure $this -foreground $value
}
proc set-deletecommand {this value} {} ;# data is stored at switched level
proc update {this y} { ;# y is either a valid number or the ? character
$($this,path) element configure $this -ydata $y
}
}
}
class dataSideBarChart {
proc dataSideBarChart {this parentPath args} dataBarChart {$parentPath 0 $args} {
composite::configure $this -mode aligned
}
proc ~dataSideBarChart {this} {}
proc iconData {} {
return {
R0lGODdhJAAkAMYAAPj4+Hh4ePj8+DBgGHh8eKDweAAAAJjscJjkcJDgaJDcaIjYaIjUYIDMYIDEWHjAWHi8WHBIAHC4UOjUSHC0UODMQGisSNjEQNjASGCk
SNC4SGCgQMiwSFiYQMioSFiYOMCgSFiQOLiYSFCMOLiQSICEgFCIMLCMSBBgeIiQiEiEMKiESMDQ2JCYkEiAKKh8SKjA0KCkoEB4KKB0SJC0wKisqJhsSLi8
uEBwIJhkSHiouMDEwDhsIJBcSGCYsMjQyNDY0ODk4Ojs6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAJAAkAAAH/oAAgoOCAYSHhoeDiYWKhIyKkIiPhAIDl5iZk44AkIkBAQQDBaSlpAMG
oKqrrK2ggpYHsrOyAwSUnJ6VAwi9vr22uI66g5YJx8jHwYucnbigogrS09KorteusAML3N3cy425wgCWDObn5uDO4szFAw3w8fDqkuOfoe/y8dbY/a/kAxwI
HCiQXjNi2h4oXKhQHQEB7MJpg0CxIsUBETJq3LgpHLQBEkKKDIlxgsmTJiOk8qeNgsuXLjFWmElzZoRb7SQCtMCzJ0+MF4IKDXoTok5Ilnz6xIihqdOmRXOu
+5ihqtWqGDVo3apVJQGWADeIHSsWI4ezaM/etLerg9u3/m4xephLd+5aqUgHfNjLdy9GEIADA456VJCBwwNCKF6sGKOIx5AfqzxMuTJlApgHjNjMeTNGEqBD
g76JubTp0iVSDzDBujVrjCdiy44dAYXt27hTl0jBe4CK38B/Y1xBvDjx2iySK0+OggDvFtAHuJhOfTrGF9izY68No7v37s2hxxg/QIb58+YxzljPfn1tGvDj
w28+vob98ujPY7TBvz//9/LF15x9NxQ4AA4IJoggRjk06GCDtekg4YQSNlfgDhgOwMOGHG6IUQ8ghghibT6UaGKJzWH4w4qZtIjRRjDiJmNzKwJhIxCn5ajj
jqbZGMSPQAYp5JBEFinEkUgmB6nkkkw2GQgAOw==
}
}
proc message {this} {
return [mc "side bar chart:\ndrop data cell(s)"]
}
}
class dataStackedBarChart {
proc dataStackedBarChart {this parentPath args} dataBarChart {$parentPath 1 $args} {
composite::configure $this -mode stacked
}
proc ~dataStackedBarChart {this} {}
proc iconData {} {
return {
R0lGODdhJAAkAKUAAPj4+Hh4eHh8eDBgGPj8+KjweAAAAJjkcJDYaIjMYIDAWDg4OHi0UGioSGCgQFiUOHBIAPDYSOjMQODESNi4SNCwSMioSMCcSLiUSLCI
SBBgeLDY6KDQ4ICEgJDE2IiQiIi80JCYkHi0yKCkoHCswKisqGCguLi8uFiYsMDEwEiQqMjQyNDY0ODk4Ojs6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAJAAkAAAG/kCAcCgMEI/G4zBZVBKZSiiSKFAOrtisdrsFEKqAgFgwKJjP6LQaPTAIBOIhYXCo2+/4/H0g
+B7nCIGCg4SFg3x+RHMJjI2Oj5COAwFfBGFjAwqam5ydnpwDC29wcgMMp6ipqqupk5WKAw2ys7S1trSufbAOvL2+v8C+uZZiAWQPyMnKy8zKoaNMBBDT1NXW
19eUunIQEd7f4OHi4BDaltwS6err7O3r5a/FAhAT9fb3+Pn3EKJv0RAUAgocSLDgQHjbhEirwLChw4cQHSI8pxCChYsYM2rcmHHipTcQLogcSbKkSZL8oHHD
wLKly5cwXXrklqGmzZs4c96cqVCDv8+fQIMKFWoOgIGjBjRsWMq0qdOnTTUgPTpKgAYOWLNq3cpVq4aqAjqI7aDBg9mzaNOqRft1bIcPcD9oAEG3rt27eO1+
jfshhN8QGkQIHky4sGHCX/+GGMF4hAYSkCNLnkxZ8tfGI0poLqHBhOfPoEOLBv11c4kTqE9oQMG6tevXsF1/TX0ihe0UGlTo3s27t2/eX2+nWEF8xdDjyH8K
KL6ChXPnYKNLny7gOYsW2LNr3869u3cX4MOLH0++vPkgADs=
}
}
proc updateElement {this element seconds value} { ;# value is either a valid number or the ? character
if {[string equal $value ?]} { ;# handle void value
dataBarChart::element::update $element 0
} else {
dataBarChart::element::update $element [expr {abs($value)}] ;# negative values make no sense
}
}
proc message {this} {
return [mc "stacked bar chart:\ndrop data cell(s)"]
}
}
class dataOverlapBarChart {
proc dataOverlapBarChart {this parentPath args} dataBarChart {$parentPath 0 $args} {
composite::configure $this -mode overlap
}
proc ~dataOverlapBarChart {this} {}
proc iconData {} {
return {
R0lGODdhJAAkAMYAAPj4+Hh4ePj8+DBgIHh8eKDweAAAAJjscJjocJDgcJDgaIjYaIjUaIDQYIDMYIDIYHjEWHjAWHBIAHC8WOjQQHC0UODIQGiwUNjEQNi8
QGCoSNC0QGCkSMisQFigQMikQFicQMCgQFiYQLiYQFCQOLiQQICEgLCIQBBgeIiQiEiMOKiAQLjI0JCYkEiEMKh8QKCkoECAMKB0QKC4yKisqEB8MJhsQIio
uLi8uEB4KJhkQMDEwDh0KJBcQHCgsMjQyODk4NDY0Ojs6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAJAAkAAAH/oAAgoOCAYSHhoeDiYWKhIyKkIiPhAIDl5iZmQCSlIuFAQQDBaSlpqQD
BgGrrK2urIKWB7O0tbMDBJ2fu7EDCL/Awb+4uo28AJYJysvMygOrjsbGq6IK1tfY1qm5r92wyAML4uPk4s/FnJ69DOzt7uzn0enHlg329/j28dGQidQDDgIK
HBhwm7eDvR4oXMhQ4T5H/SoNgECxokWKDyOpAxeho0cJIEOKFLnRX6gBE1KqlEChpcuXLSWoOpjIUoWbOCVY2Mmz504JBI5BsnShqFEJGJIqXZoUqFCJRo9m
mEq16lQJAQRIm/dPg9evEjaIHUtWrExu3npxWMtWQoe3/nDjvsWqdd5WSx7y6pXwoa/fv33pbh06AIThwxJCKF7MWLFgu/MMSB4gorJlCSMya96cWabkz6Al
Exg9gITp0xJKqF7NWjXQ0bBjjzZBu/Rp0xJO6N6tG4Xv38CB0zaRovgAFciTS1jBvDlzFCyiS58eHQWB4i2yD3DBvbuEF+DDg4dOvbz17DDSD4jBvr0EGfDj
w0cxo779+/Wtp6fBf0CN/wBKYMOABA6Iwg0IJqgggtbxh8ODA+Qg4YQS6GDhhRYeuOCG1j24w4cD8CDiiBL0YOKJJqLgw4ostriidR/+IKMml4wkUnA4/kaA
jED0CIRsQAYpZGxBBOHjkUgmEKnkkj4K4eSTUEYp5ZRUBgIAOw==
}
}
proc updateElement {this element seconds value} { ;# value is either a valid number or the ? character
dataBarChart::_updateElement $this $element $seconds $value ;# update as usual
set path $dataBarChart::($this,path)
set list {} ;# now update elements display so that none hides the others (ordered with largest values in the back)
foreach name [$path element show] {
set value [$path element cget $name -ydata]
if {![string is double -strict $value]} {set value 0} ;# may be undefined
lappend list [list $name $value]
}
set names {}
foreach list [lsort -real -index end -decreasing $list] {
foreach {name value} $list {}
lappend names $name
}
$path element show $names
}
proc message {this} {
return [mc "overlap bar chart:\ndrop data cell(s)"]
}
}
|