Попытка отобразить два дерева, используя d3.js. После добавления второго дерева событие масштабирования или щелчка не работает на первом SVG. Я добавил масштабирование и событие, указав определенное имя класса SVG. Тем не менее это не работает. Любая помощь, пожалуйста
<script src="http://d3js.org/d3.v3.min.js"></script>
// ************** Generate the tree diagram *****************
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
},
width = 900 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var i = 0,
duration = 750,
root;
var nodeWidth = 150;
var nodeHeight = 30;
var tree1 = d3.layout.tree()
.size([height, width])
.nodeSize([nodeWidth, nodeHeight])
.separation(function(a, b) {
return ((a.parent == root) && (b.parent == root)) ? 0.2 : 0.3;
});
var tree2 = d3.layout.tree()
.size([height, width])
.nodeSize([nodeWidth, nodeHeight])
.separation(function(a, b) {
return ((a.parent == root) && (b.parent == root)) ? 0.2 : 0.3;
});
var treeDict = {};
treeDict["_lhs"] = tree1;
treeDict["_rhs"] = tree2;
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.y, d.x];
})
.source(function(d) {
return {
x: d.source.x,
y: d.source.y
};
})
.target(function(d) {
return {
x: d.target.x,
y: d.target.y
};
});
var posCSS;
var pos_CSS;
/*
.call(d3.behavior.zoom().on("zoom", function () { d3.select(posCSS).select(".svg_1").select(".svg_2").attr("transform", d3.event.transform) }))
*/
var ret = drawTree(".lhs", tree1);
function drawTree(cssPos, treeData) {
posCSS = cssPos
pos_CSS = cssPos.replace(/[&\/\\#, +()$~%.'":*?<>{}]/g, '_');
var svg = d3.select("body").select(posCSS).append("svg:svg")
.attr("class", "svg_1" + pos_CSS)
.attr("width", width)
.attr("height", height)
.style("background-color", "#EEEEEE")
.style("overflow", "scroll")
.call(d3.behavior.zoom().scaleExtent([0.5, 5]).on("zoom", zoom))
.append("svg:g")
.attr("class", "svg_2")
.append("svg:g")
.attr("class", "svg_3")
.attr("transform", "translate(" + (margin.left) + "," + (margin.top + height / 2) + ")");
//without svg_3 when we select the graph first time, it moves to top left and then we need to drag..so leave it
/*
d3.select(posCSS).select(".svg_1")
.call(d3.behavior.zoom()
.scaleExtent([0.5, 5])
.on("zoom", zoom));
*/
root = treeData[0];
root.x0 = height / 2;
root.y0 = 0;
update(root);
}
function update(source) {
//var nodeHeight = 50, nodeWidth = 100;
// Compute the new tree layout.
var nodes = treeDict[pos_CSS].nodes(root).reverse(),
links = treeDict[pos_CSS].links(nodes);
// Normalize for fixed-depth.
//For Right to Left
//nodes.forEach(function(d) { d.y = width - (d.depth * 180); });
//For Left to Right
nodes.forEach(function(d) {
d.y = d.depth * 180;
});
// Update the nodes
//var node = svg.selectAll("g.node")
var node = d3.select("div" + posCSS).select("svg.svg_1" + pos_CSS).select("g.svg_2").select("g.svg_3").selectAll("g.node")
.data(nodes, function(d) {
return d.id || (d.id = ++i);
});
//var arrow = svg.append("svg:defs").selectAll("marker")
var arrow = d3.select(posCSS).select(".svg_1" + pos_CSS).select(".svg_2").select(".svg_3").append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 0)
.attr("refY", 0)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.attr("class", "arrow")
.append("svg:path")
.attr('d', 'M10,-5L0,0L10,5');
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + source.x0 + "," + source.y0 + ")";
})
//.on("click", click);
// Toggle children on click.
.on("click", function(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
});
nodeEnter.append("rect")
.attr("width", nodeWidth)
.attr("height", nodeHeight)
.attr("stroke", "black")
.attr("fill", "blue")
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("foreignObject")
.attr('x', -5)
.attr('y', -10)
.append("xhtml:body")
.append("xhtml:div")
.style({
width: nodeWidth + 'px',
height: nodeHeight + 'px',
"font-size": "10px",
"background-color": "white"
}).html(function(d) {
return '<b>' + d.funcName + '<br>' + '<A HREF="http://127.0.0.1:5000" target="_blank" >' + d.modName + '</A></b>'
});;
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
if (d.parent == "null") {
d.y = 700;
//d.x = 10;
}
return "translate(" + d.y + "," + d.x + ")";
});
nodeUpdate.select("rect")
.attr("r", 10)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("circle")
//nodeExit.select("rect")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links
var link = d3.select(posCSS).select(".svg_1" + pos_CSS).select(".svg_2").select(".svg_3").selectAll("path.link")
.data(links, function(d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("marker-end", "url(#end)")
.attr("class", "link")
.attr("d", function(d) {
var valX = 15,
valY = 10
var o = {
x: source.x0 + valX,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", function(d) {
var valX = 15,
valY = 10
var s = {
x: d.source.x + valX,
y: d.source.y + nodeWidth + valY - 5
},
t = {
x: d.target.x + valX,
y: d.target.y - valY
}
return diagonal({
source: s,
target: t
});
});
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var valX = 15,
valY = 10
var o = {
x: source.x + valX,
y: source.y + nodeWidth + valY
};
return diagonal({
source: o,
target: o
});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
node.on("mouseover", function(p) {
var nodes = [];
nodes.push(p);
while (p.parent) {
p = p.parent;
nodes.push(p);
}
//color the links
link.filter(function(d) {
if (nodes.indexOf(d.target) !== -1) return true;
}).style("stroke", "orange");
//color the nodes
node.filter(function(d) {
if (nodes.indexOf(d) !== -1) return true;
}).style("fill", "steelblue");
});
node.on("mouseout", function(p) {
var nodes = [];
nodes.push(p);
while (p.parent) {
p = p.parent;
nodes.push(p);
}
//color the links
link.filter(function(d) {
if (nodes.indexOf(d.target) !== -1) return true;
}).style("stroke", "#ccc");
//color the nodes
node.filter(function(d) {
if (nodes.indexOf(d) !== -1) return true;
}).style("fill", "#ccc");
});
}
function zoom() {
var realWidth = window.innerWidth - 80;
var realHeight = window.innerHeight - 480;
var scale = d3.event.scale,
translation = d3.event.translate,
tbound = -height * scale,
bbound = height * scale,
lbound = (-width + 240) * scale,
rbound = (width - 240) * scale;
translation = [
Math.max(Math.min(translation[0], rbound), lbound),
Math.max(Math.min(translation[1], bbound), tbound)
];
d3.select(posCSS).select(".svg_1" + pos_CSS).select(".svg_2")
.attr("transform", "translate(" + translation + ")" +
" scale(" + scale + ")");
}
</script>
<div class="lhs">
<script>
var tree2 = [{
"children": [{
"children": [{
"count": 1,
"funcName": "main",
"modName": "bash-5.0/array.c"
}, {
"count": 1,
"funcName": "print_array_assignment",
"modName": "bash-5.0/arrayfunc.c"
}, {
"count": 1,
"funcName": "array_var_assignment",
"modName": "bash-5.0/subst.c"
}, {
"count": 1,
"funcName": "make_env_array_from_var_list",
"modName": "bash-5.0/variables.c"
}],
"count": 1,
"funcName": "array_to_assign",
"modName": "bash-5.0/array.c"
}, {
"children": [{
"count": 1,
"funcName": "print_assoc_assignment",
"modName": "bash-5.0/arrayfunc.c"
}, {
"count": 1,
"funcName": "array_var_assignment",
"modName": "bash-5.0/subst.c"
}, {
"count": 1,
"funcName": "make_env_array_from_var_list",
"modName": "bash-5.0/variables.c"
}],
"count": 2,
"funcName": "assoc_to_assign",
"modName": "bash-5.0/assoc.c"
}, {
"children": [{
"count": 1,
"funcName": "execute_disk_command",
"modName": "bash-5.0/execute_cmd.c"
}],
"count": 1,
"funcName": "printable_filename",
"modName": "bash-5.0/general.c"
}, {
"children": [{
"count": 1,
"funcName": "string_var_assignment",
"modName": "bash-5.0/subst.c"
}, {
"count": 1,
"funcName": "string_transform",
"modName": "bash-5.0/subst.c"
}],
"count": 1,
"funcName": "sh_quote_reusable",
"modName": "bash-5.0/lib/sh/shquote.c"
}, {
"children": [{
"count": 1,
"funcName": "do_assignment_internal",
"modName": "bash-5.0/subst.c"
}, {
"count": 1,
"funcName": "assign_in_env",
"modName": "bash-5.0/variables.c"
}],
"count": 1,
"funcName": "xtrace_print_assignment",
"modName": "bash-5.0/print_cmd.c"
}, {
"children": [{
"count": 2,
"funcName": "execute_simple_command",
"modName": "bash-5.0/execute_cmd.c"
}, {
"count": 1,
"funcName": "xtrace_print_for_command_head",
"modName": "bash-5.0/print_cmd.c"
}, {
"count": 1,
"funcName": "xtrace_print_select_command_head",
"modName": "bash-5.0/print_cmd.c"
}],
"count": 1,
"funcName": "xtrace_print_word_list",
"modName": "bash-5.0/print_cmd.c"
}, {
"children": [{
"count": 1,
"funcName": "print_heredocs",
"modName": "bash-5.0/print_cmd.c"
}, {
"count": 2,
"funcName": "print_redirection_list",
"modName": "bash-5.0/print_cmd.c"
}],
"count": 1,
"funcName": "print_redirection",
"modName": "bash-5.0/print_cmd.c"
}, {
"children": [{
"count": 1,
"funcName": "printenv_builtin",
"modName": "bash-5.0/examples/loadables/printenv.c"
}, {
"count": 1,
"funcName": "print_assignment",
"modName": "bash-5.0/variables.c"
}],
"count": 1,
"funcName": "print_var_value",
"modName": "bash-5.0/variables.c"
}, {
"children": [{
"count": 1,
"funcName": "push_heredoc",
"modName": "bash-5.0/y.tab.c"
}, {
"count": 1,
"funcName": "yyerror",
"modName": "bash-5.0/y.tab.c"
}],
"count": 1,
"funcName": "report_syntax_error",
"modName": "bash-5.0/y.tab.c"
}],
"count": 1,
"funcName": "ansic_quote",
"modName": "FileName.c"
}];
var ret = drawTree(".lhs", tree2);
</script>
</div>
<div class="rhs">
<script>
var ret = drawTree(".rhs", tree2);
</script>
.node {
cursor: pointer;
}
.link {
fill: none;
stroke: #aaa;
stroke-width: 2px;
}
.lhs {
position: fixed;
top: 0;
left: 0px;
border: 3px solid #73AD21;
}
.rhs {
position: fixed;
top: 0;
right: 0px;
border: 3px solid #73AD21;
}
<html>
<body>
<div class="lhs">
<script>
var ret = drawTree(".lhs", treeData);
</script>
</div>
<div class="rhs">
<script>
var ret = drawTree(".rhs", treeData);
</script>
</div>
<body>
Попытка отобразить два дерева с помощью d3.js. После добавления второго дерева событие масштабирования или щелчка не работает на первом SVG. Я добавил масштабирование и событие, указав определенное имя класса SVG. Тем не менее это не работает. Любая помощь, пожалуйста