尝试使用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 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> <div class="lhs"> <script> var ret = drawTree(".lhs", treeData); </script>