慕容708150
d3.selection.raise()在版本 3中似乎还不存在;如果它确实存在,您应该将其应用于父级,而不是图像。SVG 结构是svg > g.node > img,但是更改内部图像的位置g.node不会执行任何操作 - 它是独生子。将其应用到g.node.我在答案中提出的另一个选择是使用两个容器,一个用于路径,一个用于节点。那么,顺序并不重要。我在下面实现了这个。var json = { "name": "marvel", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/marvel.png", "children": [{ "name": "Heroes", "children": [{ "hero": "Spider-Man", "name": "Peter Benjamin Parker", "link": "http://marvel.com/characters/54/spider-man", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_spiderman.png", "size": 40000 }, { "hero": "CAPTAIN MARVEL", "name": "Carol Danvers", "link": "http://marvel.com/characters/9/captain_marvel", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_captainmarvel.png", "size": 40000 }, { "hero": "HULK", "name": "Robert Bruce Banner", "link": "http://marvel.com/characters/25/hulk", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_hulk.png", "size": 40000 }, { "hero": "Black Widow", "name": "Natalia 'Natasha' Alianovna Romanova", "link": "http://marvel.com/characters/6/black_widow", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_blackwidow.png", "size": 40000 }, { "hero": "Daredevil", "name": "Matthew Michael Murdock", "link": "http://marvel.com/characters/11/daredevil", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_daredevil.png", "size": 40000 }, { "hero": "Wolverine", "name": "James Howlett", "link": "http://marvel.com/characters/66/wolverine", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_wolverine.png", "size": 40000 }, { "hero": "Captain America", "name": "Steven Rogers", "link": "http://marvel.com/characters/8/captain_america", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_captainamerica.png", "size": 40000 }, { "hero": "Iron Man", "name": "Anthony Edward 'Tony' Stark", "link": "http://marvel.com/characters/29/iron_man", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_ironman.png", "size": 40000 }, { "hero": "THOR", "name": "Thor Odinson", "link": "http://marvel.com/characters/60/thor", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/top_thor.png", "size": 40000 } ] }, { "name": "Villains", "children": [{ "hero": "Dr. Doom", "name": "Victor von Doom", "link": "http://marvel.com/characters/13/dr_doom", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/drdoom.png", "size": 40000 }, { "hero": "Mystique", "name": "Unrevealed", "link": "http://marvel.com/characters/1552/mystique", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/mystique.png", "size": 40000 }, { "hero": "Red Skull", "name": "Johann Shmidt", "link": "http://marvel.com/characters/1901/red_skull", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/redskull.png", "size": 40000 }, { "hero": "Ronan", "name": "Ronan", "link": "http://marvel.com/characters/49/ronan", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/ronan.png", "size": 40000 }, { "hero": "Magneto", "name": "Max Eisenhardt", "link": "http://marvel.com/characters/35/magneto", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/magneto.png", "size": 40000 }, { "hero": "Thanos", "name": "Thanos", "link": "http://marvel.com/characters/58/thanos", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/thanos.png", "size": 40000 }, { "hero": "Black Cat", "name": "Felicia Hardy", "link": "http://marvel.com/characters/271/black_cat", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/blackcat.png", "size": 40000 } ] }, { "name": "Teams", "children": [{ "hero": "Avengers", "name": "", "link": "http://marvel.com/characters/68/avengers", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/avengers.png", "size": 40000 }, { "hero": "Guardians of the Galaxy", "name": "", "link": "http://marvel.com/characters/70/guardians_of_the_galaxy", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/gofgalaxy.png", "size": 40000 }, { "hero": "Defenders", "name": "", "link": "http://marvel.com/characters/534/defenders", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/defenders.png", "size": 40000 }, { "hero": "X-Men", "name": "", "link": "http://marvel.com/characters/71/x-men", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/xmen.png", "size": 40000 }, { "hero": "Fantastic Four", "name": "", "link": "http://marvel.com/characters/69/fantastic_four", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/fantasticfour.png", "size": 40000 }, { "hero": "Inhumans", "name": "", "link": "http://marvel.com/characters/1040/inhumans", "img": "http://marvel-force-chart.surge.sh/marvel_force_chart_img/inhumans.png", "size": 40000 } ] } ]};// some colour variablesvar tcBlack = "#130C0E";// rest of varsvar w = 960, h = 800, maxNodeSize = 50, x_browser = 20, y_browser = 25, root;var vis;var force = d3.layout.force();vis = d3.select("#vis").append("svg").attr("width", w).attr("height", h);var pathContainer = vis.append("g").attr("class", "paths");var nodeContainer = vis.append("g").attr("class", "nodes");root = json;root.fixed = true;root.x = w / 2;root.y = h / 4;// Build the pathvar defs = vis.insert("svg:defs") .data(["end"]);defs.enter().append("svg:path") .attr("d", "M0,-5L10,0L0,5");update();function update() { var nodes = flatten(root), links = d3.layout.tree().links(nodes); // Restart the force layout. force.nodes(nodes) .links(links) .gravity(0.05) .charge(-1500) .linkDistance(100) .friction(0.5) .linkStrength(function(l, i) { return 1; }) .size([w, h]) .on("tick", tick) .start(); var path = pathContainer.selectAll("path.link") .data(links, function(d) { return d.target.id; }); path.enter().insert("svg:path") .attr("class", "link") // .attr("marker-end", "url(#end)") .style("stroke", "#eee"); // Exit any old paths. path.exit().remove(); // Update the nodes… var node = nodeContainer.selectAll("g.node") .data(nodes, function(d) { return d.id; }); // Enter any new nodes. var nodeEnter = node.enter().append("svg:g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .on("click", click) .call(force.drag); // Append a circle nodeEnter.append("svg:circle") .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; }) .style("fill", "#eee"); // Append images var images = nodeEnter.append("svg:image") .attr("xlink:href", function(d) { return d.img; }) .attr("x", function(d) { return -25; }) .attr("y", function(d) { return -25; }) .attr("height", 50) .attr("width", 50); // make the image grow a little on mouse over and add the text details on click var setEvents = images // Append hero text .on('click', function(d) { d3.select("h1").html(d.hero); d3.select("h2").html(d.name); d3.select("h3").html("Take me to " + "<a href='" + d.link + "' >" + d.hero + " web page ⇢" + "</a>"); }) .on('mouseenter', function() { // select element in current context d3.select(this) .transition() .attr("x", function(d) { return -60; }) .attr("y", function(d) { return -60; }) .attr("height", 100) .attr("width", 100); }) // set back .on('mouseleave', function() { d3.select(this) .transition() .attr("x", function(d) { return -25; }) .attr("y", function(d) { return -25; }) .attr("height", 50) .attr("width", 50); }); // Append hero name on roll over next to the node as well nodeEnter.append("text") .attr("class", "nodetext") .attr("x", x_browser) .attr("y", y_browser + 15) .attr("fill", tcBlack) .text(function(d) { return d.hero; }); // Exit any old nodes. node.exit().remove(); // Re-select for update. path = pathContainer.selectAll("path.link"); node = nodeContainer.selectAll("g.node"); function tick() { path.attr("d", function(d) { var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math.sqrt(dx * dx + dy * dy); return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; }); node.attr("transform", nodeTransform); }}/** * Gives the coordinates of the border for keeping the nodes inside a frame * http://bl.ocks.org/mbostock/1129492 */function nodeTransform(d) { d.x = Math.max(maxNodeSize, Math.min(w - (d.imgwidth / 2 || 16), d.x)); d.y = Math.max(maxNodeSize, Math.min(h - (d.imgheight / 2 || 16), d.y)); return "translate(" + d.x + "," + d.y + ")";}/** * Toggle children on click. */function click(d) { if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } update();}/** * Returns a list of all nodes under the root. */function flatten(root) { var nodes = []; var i = 0; function recurse(node) { if (node.children) node.children.forEach(recurse); if (!node.id) node.id = ++i; nodes.push(node); } recurse(root); return nodes;}@import url(http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600);body { font-family: "Source Code Pro", Consolas, monaco, monospace; line-height: 160%; font-size: 16px; margin: 0;}path.link { fill: none; stroke-width: 2px;}.node:not(:hover) .nodetext { display: none;}h1 { font-size: 36px; margin: 10px 0; text-transform: uppercase; font-weight: normal;}h2,h3 { font-size: 18px; margin: 5px 0; font-weight: normal;}header { padding: 20px; position: absolute; top: 0; left: 0;}a:link { color: #EE3124; text-decoration: none;}a:visited { color: #EE3124;}a:hover { color: #A4CD39; text-decoration: underline;}a:active { color: #EE3124;}<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script><section id="vis"></section>