if (name_declared("pkgversions") != 4 ) { execute("strdef pkgversions") }
sprint(pkgversions,"%sTreePlot = $Revision: 1.14 $, ",pkgversions)
load_file("RPlot.hoc")
begintemplate TreePlot
public plot, lines, marks, errorbars
public view, size, family, erase_all
public getline, line_info, view_info
public getmarks
public graph
public rprintfile, rp
public set_xlab, get_xlab
public set_ylab, get_ylab
public view_equal_plot, auto_limits_on, set_limits, get_limit
objref graph, xvec, yvec, diamvec, parentsvec, errorvec
objref tmpxvec, tmpyvec
objref xmarklist, ymarklist
strdef xlab, ylab
objref rp
objref this
double manual_limits[4]
double auto_limits[4]
double auto_flag[4]
double limits[4]
proc init() { local i
// Allow not to map, similar to Graph object
if (numarg()== 1) {
graph = new Graph($1)
} else {
graph = new Graph()
}
tmpxvec = new Vector(2)
tmpyvec = new Vector(2)
xmarklist = new List()
ymarklist = new List()
colour = 1
lines(1) // Show lines
marks(0) // Don't show marks
errorbars(1) // Show errorbars
family_flag = 0 // Whether to keep lines
for i=0,3 { auto_flag[i] = 1 }
xlab = ""
ylab = ""
rp = new RPlot()
}
proc plot() { local i, s
xvec = $o1
yvec = $o2
parentsvec = $o3
if (numarg() >= 4) { errorvec = $o4 }
// Clear graph if required
if (!family_flag) {
erase_all()
colour = 1
}
// So that crosshair_action works, do invisible line
yvec.line(graph,xvec,0,1)
if (lines_flag) {
for i=0, xvec.size()-1 {
tmpxvec.x(0) = xvec.x(i)
tmpxvec.x(1) = xvec.x(parentsvec.x(i))
tmpyvec.x(0) = yvec.x(i)
tmpyvec.x(1) = yvec.x(parentsvec.x(i))
tmpyvec.line(graph,tmpxvec,colour,1)
}
}
if (marks_flag) {
yvec.mark(graph,xvec,"o",6,colour)
xmarklist.append(xvec)
ymarklist.append(yvec)
}
if ((numarg() >= 4) && (errorbars_flag == 1)) {
for i=0, errorvec.size()-1 {
tmpxvec.x(0) = xvec.x(i)
tmpxvec.x(1) = xvec.x(i)
tmpyvec.x(0) = yvec.x(i)-errorvec.x(i)
tmpyvec.x(1) = yvec.x(i)+errorvec.x(i)
tmpyvec.line(graph,tmpxvec,colour,1)
}
}
colour += 1
if (colour == 10) colour=1
}
proc erase_all() {
graph.erase_all()
s = xmarklist.remove_all()
s = ymarklist.remove_all()
}
// turn lines on or off
proc lines() { lines_flag = $1 }
// turn marks on or off
proc marks() { marks_flag = $1 }
// turn errorbars on or off
proc errorbars() { errorbars_flag = $1 }
// mleft, mbottom, mwidth, mheight, wleft, wtop, wwidth, wheight
proc view() { graph.view($1,$2,$3,$4,$5,$6,$7,$8) }
// Clone of Graph.size()
proc size() { graph.size($1,$2,$3,$4) }
// Part of functionality of Graph.family()
proc family() { family_flag = $1 }
// Clone of Graph.getline()
func getline() { return graph.getline($1,$o2,$o3) }
// Analogue of getline() for marks
func getmarks() { local i
i = $1
i += 1
if (i <= (xmarklist.count()-1)) {
$o2 = xmarklist.object(i).cl
$o3 = ymarklist.object(i).cl
} else {
i = -1
}
return i
}
// Clone of Graph.view_info()
func view_info() {
if (numarg() == 0 ) { return graph.view_info() }
if (numarg() == 2 ) { return graph.view_info($1,$2) }
return -1
}
// Clone of Graph.line_info()
func line_info() {
return graph.line_info($1,$o2)
}
// Set manual limits which will be respected by view_equal_plot() in
// directions for which auto_limits = 0
proc set_limits() { local i
for i=1,4 { manual_limits[i-1] = $i }
}
// turn on automatic setting of limit when argument corresponding to
// argument in size() is 1
proc auto_limits_on() { local i
for i=1,4 { auto_flag[i-1] = $i }
}
// Fit graph to plot (apart from manually-set limits)
proc view_equal_plot() { local i
graph.size(&auto_limits)
for i=0,3 {
if (auto_flag[i]) {
limits[i] = auto_limits[i]
} else {
limits[i] = manual_limits[i]
}
}
size(limits[0], limits[1], limits[2], limits[3])
}
func get_limit() {
return limits[$1-1]
}
proc set_xlab() { xlab = $s1 }
proc get_xlab() { $s1 = xlab }
proc set_ylab() { ylab = $s1 }
proc get_ylab() { $s1 = ylab }
// rprintfile(String epsfilename, Double SaveFile)
proc rprintfile() { local i, j
if (numarg() == 1) { rp.create_rfile() }
if (numarg() == 2) {
if ($2 != 0) { rp.create_rfile($s1) }
}
rp.start_plot($s1)
rp.add_graph(this)
rp.end_plot()
rp.run()
}
endtemplate TreePlot