在方向力布局中与图像重叠的链接 [英] Links overlapping with the image in directional force layout

查看:63
本文介绍了在方向力布局中与图像重叠的链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的定向力布局 codepen 我使用的是图标而不是圆圈;目前,链接与图像/图标重叠。我希望链接在图像之前结束。但是我在 d3noob的示例中看到链接在圆圈后开始/结束,它与圆圈。

In my directional force layout codepen I am using icons rather than circles; currently, the links are overlapping with the image/icon. I want the links to end just before the image. However I see in d3noob's example the link starts/end after the circle, it does not overlap with the circle.

我调整了以下的返回声明,但无法正确修复它。

I tweaked the following return statement but not able to fix it properly.

function tick() {
 link.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", function(d) {
    return "translate(" + d.x + "," + d.y + ")";
 });
}


推荐答案

避免这种情况的数学方法,不使用元素的顺序,计算偏移量,所以链接在节点的边缘开始和结束。

The mathematical way to avoid this, without playing with the elements' order, is computing an offset, so the links start and end at the nodes' edges.

在你的情况下,我们首先得到角度在两个节点之间:

In your case, we first get the angle between the two nodes:

var angle = Math.atan2(dx, dy);

然后我们计算偏移量:

var offsetX = radius * Math.cos(angle);
var offsetY = radius * Math.sin(angle);

最后在 d 中使用该值属性:

And finally use that value in the d attribute:

return ("M" + (d.source.x + offsetX) + "," + (d.source.y + offsetY) +
  "A" + dr + "," + dr + " 0 0,1 " + (d.target.x - offsetX) +
  "," + (d.target.y - offsetY)
);

以下是更改的代码:

var width = 500,
  height = 400,
    radius = 8;

var fill = d3.scale.category20();
var links = [{ source:  "FH", target: "TP" }];
var nodes = [
    { id: "FH", x: 100, y: 110 },
    { id: "TP", x: 200, y: 110 },
    { id: "GW", x: 200, y: 110 },
    { id: "DB", x: 100, y: 110 }
  ]

var map = {}
nodes.forEach(function(d,i){
  map[d.id] = i;
})

links.forEach(function(d) {
  d.source = map[d.source];
  d.target = map[d.target];
})

var force = d3.layout
  .force()
  .size([width, height])
  .nodes(nodes)
  .links(links)
  .linkDistance(150)
  .charge(-500)
  .on("tick", tick);

var svg = d3
  .select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var arrows = svg
  .append("svg:defs")
  .selectAll("marker")
  .data(["arrow"])
  .enter()
  .append("marker")
  .attr("id", String)
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 10)
  .attr("refY", 0)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", "auto")
  .append("path")
  .attr("d", "M0,-5L10,0L0,5");

svg
  .append("rect")
  .attr("width", width)
  .attr("height", height);

var nodes = force.nodes(),
  links = force.links(),
  node = svg.selectAll(".node"),
  link = svg.selectAll(".link");

restart();





function tick() {
  link.attr("d", function(d) {
    var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y;
    var angle = Math.atan2(dy, dx);
    var offsetX = radius * Math.cos(angle);
    var offsetY = radius * Math.sin(angle);
      dr = Math.sqrt(dx * dx + dy * dy);
    return (
      "M" +
      (d.source.x + offsetX) +
      "," +
      (d.source.y + offsetY) +
      "A" +
      dr +
      "," +
      dr +
      " 0 0,1 " +
      (d.target.x - offsetX) +
      "," +
      (d.target.y - offsetY)
    );
  });

  node.attr("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")";
  });
}

function restart() {
   link = link.data(links);
  link
    .enter()
    .append("path")
    .attr("class", "link")
    .attr("marker-end", "url(#arrow)");
  link.exit().remove();
  
  node = node.data(nodes);
  node
    .enter()
    .insert("g")
    .attr("class", "node")
    .call(force.drag);
  node
    .append("image")
    .attr("xlink:href", "https://github.com/favicon.ico")
    .attr("x", -8)
    .attr("y", -8)
    .attr("width", 16)
    .attr("height", 16);
  node
    .append("text")
    .attr("dx", 12)
    .attr("dy", ".35em")
    .text(function(d) {
      return d.id;
    });
  node.exit().remove();

   force.start();
}

#nodeConsole {
  width: 80%;
  height: 1px;
  font-family: courier new;
  padding: 1px;
  border: 3px solid gray;
  margin-top: 1px;
  overflow: autao;
}

#linkedNodes {
  width: 80%;
  font-family: courier new;
  padding: 10px;
}

#srcNodes {
  width: 40%;
  font-family: courier new;
  padding: 8px;
}

#targetNodes {
  width: 40%;
  font-family: courier new;
  padding: 8px;
}

rect {
  fill: none;
  pointer-events: all;
}

.node {
  fill: #000;
}

.cursor {
  fill: none;
  stroke: brown;
  pointer-events: none;
}

.link {
  stroke: #999;
}
.node text {
  pointer-events: none;
  font: 10px sans-serif;
}

path.link {
  fill: none;
  stroke: #666;
  stroke-width: 1.5px;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

这篇关于在方向力布局中与图像重叠的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆