1# -*-Mode:Tcl-*- 2 3catch {tk_getOpenFile -junk} 4 5namespace eval dataplot_v1 { 6 variable dataplot 7 8 set dataplot(fmtstr) "0:red" 9 set dataplot(max) 0 10 set dataplot(min) 0 11 set dataplot(ybase) [expr $::v(waveh) + $::v(spegh)] 12 set dataplot(height) $::v(spegh) 13 set dataplot(frametime) 0.01 14 set dataplot(offset) 0.0 15 set dataplot(skip) 0 16 set dataplot(lockmax) 0 17 set dataplot(lockmin) 0 18 19 lappend ::v(plugins) ::dataplot_v1 20 snack::menuCommand Tools {Plot Data} ::dataplot_v1::PlotDataWin 21 22 proc Describe {} { 23 return "This plug-in adds the capability to plot numerical ASCII data. It is also possible to modify the plot and save the changes." 24 } 25 26 proc Unload {} { 27 snack::menuDelete Tools {Plot Data} 28 } 29 30 proc Redraw y { 31 global c f v 32 variable dataplot 33 34 set max -1000000 35 set min 1000000 36 if ![info exist dataplot(check)] { return 0 } 37 if {$dataplot(check) != $f(sndfile)} { return 0 } 38 $c delete plot 39 40 foreach def [split $dataplot(fmtstr)] { 41 scan $def "%d:%s" column color 42 set plot($column) $color 43 } 44 45 foreach column [array names plot] { 46 if {!$dataplot(lockmax)} { 47 for {set i 0} {$i < $dataplot(rows)} {incr i} { 48 set val $dataplot($i.$column) 49 if {$val > $max} { set max $val } 50 } 51 set dataplot(max) $max 52 } else { 53 set max $dataplot(max) 54 } 55 if {!$dataplot(lockmin)} { 56 for {set i 0} {$i < $dataplot(rows)} {incr i} { 57 set val $dataplot($i.$column) 58 if {$val < $min} { set min $val } 59 } 60 set dataplot(min) $min 61 } else { 62 set min $dataplot(min) 63 } 64 set range [expr $max - $min] 65 set data [ComputeCoords 0 [expr $dataplot(rows)-1] $column $range $min] 66 eval $c create line $data -tags {[list col$column $column plot]} -fill $plot($column) 67 set dataplot(data$column) $data 68 } 69 70 $c bind plot <B1-Motion> "::dataplot_v1::EditPlot %W %x %y draw" 71 $c bind plot <ButtonPress-1> "::dataplot_v1::EditPlot %W %x %y set" 72 73 set dataplot(min) $min 74 set dataplot(range) $range 75 return 0 76 } 77 78 proc Putmark m { 79 } 80 81 proc ComputeCoords {start end column range min} { 82 global v 83 variable dataplot 84 85 set t 0 86 set toff [expr $dataplot(offset) - double($v(startsmp))/$v(rate)] 87 for {set i $start} {$i <= $end} {incr i} { 88 set val $dataplot($i.$column) 89 set yplot [expr $dataplot(ybase) - (($val - $min) * $dataplot(height) / $range)] 90 set t [expr ($i * $dataplot(frametime) + $toff) * $v(pps)] 91 lappend data $t $yplot 92 } 93 return $data 94 } 95 96 proc PlotDataWin {} { 97 global v 98 variable dataplot 99 100 set w .plot 101 catch {destroy $w} 102 toplevel $w 103 wm title $w "Plot data" 104 wm geometry $w [xsGetGeometry] 105 106 pack [ label $w.lFmt -text "Format example: 1:green 3:red"] 107 pack [ entry $w.eFmt -textvar ::dataplot_v1::dataplot(fmtstr) -wi 34] 108 109 pack [ frame $w.f1] 110 pack [ label $w.f1.lFrameTime -text "Frame spacing (s):" -wi 26] -side left 111 pack [ entry $w.f1.eFrameTime -textvar ::dataplot_v1::dataplot(frametime) -wi 8] -side left 112 113 pack [ frame $w.f11] 114 pack [ label $w.f11.lStartOffset -text "Start offset (s):" -wi 20] -side left 115 pack [ entry $w.f11.eStartOffset -textvar ::dataplot_v1::dataplot(offset) -wi 8] -side left 116 117 pack [ frame $w.f2] 118 pack [ label $w.f2.lmax -text "Plot value at top:" -wi 26] -side left 119 pack [ entry $w.f2.emax -textvar ::dataplot_v1::dataplot(max) -wi 8] -side left 120 pack [ checkbutton $w.f2.rLock -text Lock -var ::dataplot_v1::dataplot(lockmax)] 121 122 pack [ frame $w.f21] 123 pack [ label $w.f21.lmin -text "Plot value at bottom:" -wi 26] -side left 124 pack [ entry $w.f21.emin -textvar ::dataplot_v1::dataplot(min) -wi 8] -side left 125 pack [ checkbutton $w.f21.rLock -text Lock -var ::dataplot_v1::dataplot(lockmin)] 126 127 pack [ frame $w.f3] 128 pack [ label $w.f3.lYBase -text "Plot baseline at (pixels):" -wi 26] -side left 129 pack [ entry $w.f3.eYBase -textvar ::dataplot_v1::dataplot(ybase) -wi 8] 130 131 pack [ frame $w.f4] 132 pack [ label $w.f4.lHeight -text "Plot height (pixels):" -wi 26] -side left 133 pack [ entry $w.f4.eHeight -textvar ::dataplot_v1::dataplot(height) -wi 8] 134 135 pack [ frame $w.f5] 136 pack [ label $w.f5.lSkipHeader -text "Skip header (lines):" -wi 26] -side left 137 pack [ entry $w.f5.eSkipHeader -textvar ::dataplot_v1::dataplot(skip) -wi 8] 138 139 pack [ frame $w.fb] 140 pack [ button $w.fb.bLoad -text Load -command ::dataplot_v1::PlotGetFile] -side left 141 pack [ button $w.fb.bSave -text Save -command ::dataplot_v1::SaveFile] -side left 142 pack [ button $w.fb.bPlot -text Plot -command ::Redraw] -side left 143 pack [ frame $w.f] -side bottom -fill x 144 label $w.f.lab -text "" -width 1 -relief sunken -bd 1 -anchor w 145 pack $w.f.lab -side left -expand yes -fill x 146 pack [ button $w.f.bExit -text Close -command "destroy $w"] -side left 147 bind $w <Key-Return> ::Redraw 148 } 149 150 proc PlotGetFile {} { 151 global f v 152 variable dataplot 153 154 set file [tk_getOpenFile -title "Open data file" -initialfile [file rootname $f(sndfile)]] 155 if {$file == ""} return 156 if {[PlotReadFile $file] == -1} return 157 158 set strip_fn [lindex [file split [file rootname $file]] end] 159 set ext [file extension $f(sndfile)] 160 161 if {[string compare $strip_fn$ext $f(sndfile)] != 0} { 162 ::OpenFiles $f(spath)$strip_fn$ext 163 } 164 165 set dataplot(frametime) [expr [snd length -units seconds]/$dataplot(rows)] 166 set dataplot(check) $f(sndfile) 167 set v(msg) "Plotting data file: $file" 168 ::Redraw 169 } 170 171 proc PlotReadFile file { 172 global f v 173 variable dataplot 174 175 set dataplot(file) $file 176 if {$file != ""} { 177 if [catch {open $file} in] { 178 SetMsg $in 179 return -1 180 } else { 181 set row 0 182 for {set i 0} {$i < $dataplot(skip)} {incr i} { 183 gets $in line 184 } 185 gets $in line 186 while ![eof $in] { 187 set column 0 188 foreach item [split $line] { 189 if {$item == ""} continue 190 if [catch {scan $item "%s" val} res] { 191 SetMsg "Failed reading data at row: $row, col: $column" 192 return 193 } 194 set dataplot($row.$column) $val 195 incr column 196 } 197 incr row 198 gets $in line 199 } 200 close $in 201 } 202 set dataplot(rows) $row 203 set dataplot(cols) $column 204 } 205 } 206 207 proc SaveFile {} { 208 variable dataplot 209 210 file copy -force $dataplot(file) $dataplot(file)~ 211 if [catch {open $dataplot(file) w} out] { 212 SetMsg $out 213 } else { 214 for {set i 0} {$i < $dataplot(rows)} {incr i} { 215 set row "" 216 for {set j 0} {$j < $dataplot(cols)} {incr j} { 217 if $j { append row " " } 218 append row $dataplot($i.$j) 219 } 220 puts $out $row 221 } 222 } 223 close $out 224 } 225 226 227 proc EditPlot {w x y flag} { 228 global c v 229 variable dataplot 230 231 set xc [$c canvasx $x] 232 set yc [$c canvasy $y] 233 set tag [lindex [$c gettags current] 0] 234 set col [lindex [$c gettags current] 1] 235 set i [expr int(($v(startsmp)/$v(rate)+$xc*1.0/$v(pps)-$dataplot(offset)) / $dataplot(frametime))] 236 237 if {$i < 0 || $i >= $dataplot(rows)} return 238 if {$flag == "set"} { 239 set dataplot(orow) $i 240 return 241 } 242 if {$yc > $dataplot(ybase)} { 243 set yc $dataplot(ybase) 244 } 245 if {$yc < $dataplot(ybase) - $dataplot(height)} { 246 set yc [expr $dataplot(ybase) - $dataplot(height)] 247 } 248 set val [expr -$dataplot(range) * ($yc - $dataplot(ybase)) / $dataplot(height) + $dataplot(min)] 249 set inc 0 250 if {$i > $dataplot(orow)} { 251 set inc 1 252 } 253 if {$i < $dataplot(orow)} { 254 set inc -1 255 } 256 set start [expr $dataplot(orow) + $inc] 257 for {set j $start} {$j != $i} {incr j $inc} { 258 set dataplot($j.$col) $val 259 } 260 set dataplot($i.$col) $val 261 SetMsg "Row: $i, Value: $val" 262 if {$start <= $i} { 263 set end $i 264 } else { 265 set end $start 266 set start $i 267 } 268 set chgd [ComputeCoords $start $end $col $dataplot(range) $dataplot(min)] 269 set dataplot(data$col) [eval lreplace {$dataplot(data$col)} [expr 2*$start] [expr 2*$end+1] $chgd] 270 271 eval $c coords $tag $dataplot(data$col) 272 set dataplot(orow) $i 273 } 274 275}