为了账号安全,请及时绑定邮箱和手机立即绑定

D3.js 发送节点/图像后面的路径/链接

D3.js 发送节点/图像后面的路径/链接

ibeautiful 2023-09-07 16:03:41
我希望能够发送中心图像后面的路径/链接/边缘(示例中的 Marvel 符号)。我正在使用这个例子:http ://bl.ocks.org/eesur/be2abfb3155a38be4de4启动时,一切都像它应该的那样,但是当您单击 Marvel 符号,然后再次单击时,路径/链接会在图像前面打开。我很确定问题出在点击功能上,但不知道从哪里开始。@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>
查看完整描述

1 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

  1. d3.selection.raise()在版本 3中似乎还不存在;

  2. 如果它确实存在,您应该将其应用于父级,而不是图像。SVG 结构是svg > g.node > img,但是更改内部图像的位置g.node不会执行任何操作 - 它是独生子。将其应用到g.node.

  3. 我在答案中提出的另一个选择是使用两个容器,一个用于路径,一个用于节点。那么,顺序并不重要。我在下面实现了这个。

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 variables

var tcBlack = "#130C0E";


// rest of vars

var 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 path

var 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>


查看完整回答
反对 回复 2023-09-07
  • 1 回答
  • 0 关注
  • 58 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信