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
|
#!/usr/bin/env tclsh
## -*- tcl -*-
package require Tk
# editgraph.tcl --
# Widget to edit data series graphically
#
# Note:
# Not as elegant as could be with bindings via Plotchart itself
#
package require Plotchart
namespace eval ::Editgraph {
variable graph
variable endedit
}
# editSeries --
# Procedure to edit a series of data graphically
#
# Arguments:
# xrange Range for the x values
# yrange Range for the y values
# number Number of data points
#
# Result:
# List of x,y values representing the data series
#
# Note:
# The widget allows setting new y values for given x values only
#
proc ::Editgraph::editSeries {xrange yrange number} {
variable graph
variable endedit
toplevel .graph
wm title .graph "Editing series"
canvas .graph.c -width 400 -height 300
button .graph.ok -text OK -width 10 -command {::Editgraph::SaveSeries}
button .graph.cancel -text Cancel -width 10 -command {::Editgraph::CancelSeries}
grid .graph.c -
grid .graph.ok .graph.cancel
#
# Initialise the series
#
foreach {xmin xmax} $xrange {break}
foreach {ymin ymax} $yrange {break}
if { $ymin <= 0.0 && $ymax >= 0.0 } {
set y 0.0
} else {
set y $ymin
}
set delx [expr {($xmax-$xmin)/double($number-1)}]
set graph(xy) {}
set x $xmin
while { $x < $xmax+0.5*$delx } {
lappend graph(xy) $x $y
set x [expr {$x + $delx}]
if { abs($x) < 0.5 *$delx } {
set x 0.0
}
}
set graph(xmin) $xmin
set graph(xmax) $xmax
set graph(delx) $delx
set graph(number) $number
set graph(plot) [::Plotchart::createXYPlot .graph.c \
[::Plotchart::determineScale $xmin $xmax] \
[::Plotchart::determineScale $ymin $ymax]]
$graph(plot) dataconfig data -colour blue
set graph(widget) .graph.c
foreach {x y} $graph(xy) {
$graph(plot) plot data $x $y
}
#
# Set the bindings
#
bind .graph.c <Button-1> {::Editgraph::EditPoint %W %x %y}
vwait ::Editgraph::endedit
puts "$endedit"
if { $endedit == 1 } {
return $graph(xy)
} else {
return {}
}
}
# SaveSeries, CancelSeries --
# Callback procedure for the widget
#
# Arguments:
# None
#
# Result:
# None
#
# Side effects:
# The widget is closed
#
proc ::Editgraph::SaveSeries {} {
set ::Editgraph::endedit 1
destroy .graph
}
proc ::Editgraph::CancelSeries {} {
set ::Editgraph::endedit 0
destroy .graph
}
# EditPoint --
# Callback procedure for setting the new data point
#
# Arguments:
# w Widget
# x X-coordinate of selected point (pixel)
# y Y-coordinate of selected point (pixel)
#
# Result:
# None
#
# Side effects:
# The data points are updated and the graph redrawn
#
proc ::Editgraph::EditPoint {w x y} {
variable graph
foreach {xc yc} [::Plotchart::pixelToCoords $graph(widget) $x $y] {break}
set xp [expr {int(0.5+($xc-$graph(xmin))/$graph(delx))}]
if { $xp < 0 } { set xp 0 }
if { $xp > $graph(number) } { set xp $graph(number) }
lset graph(xy) [expr {2*$xp+1}] $yc
#
# Reset the plotted data
#
$graph(widget) delete data
$graph(plot) plot data "" ""
#
# Redraw the data
#
foreach {x y} $graph(xy) {
$graph(plot) plot data $x $y
}
}
# main --
# Make it all work
catch {
console show
}
set xyseries [::Editgraph::editSeries {0 100} {-50 50} 10]
puts "Series:"
foreach {x y} $xyseries {
puts [format "%10.4f %10.4f" $x $y]
}
|