javascript - D3 按节点名称链接圈

标签 javascript d3.js

刚刚开始使用 D3。我目前正在做网络交易项目,需要我将节点与其他节点连接起来,这取决于json文件。

我的 json 文件如下所示。

{
    "nodes": [
        {  
           "id": "site01",
           "x": 317.5,
           "y": 282.5
        },
        {
          "id": "site02",
          "x": 112,
          "y": 47
       },
       {
          "id": "site03",
          "x": 69.5,
          "y": 287
       },
   ]
   "links": [
       {  
          "node01": "site01", 
          "node02": "site02", 
          "amount": 170
       },
       {  
          "node01": "site01", 
          "node02": "site03", 
          "amount": 100
       },
       {  
          "node01": "site02", 
          "node02": "site03", 
          "amount": 70
       },
   ]
}

我现在能做的就是绘制节点中所有站点的位置。

这是我的代码。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <script src="https://d3js.org/d3.v4.min.js"></script>
  </head>
  <body>
    <script type="text/javascript">
      var w = 1200;
      var h = 800;
      var svg = d3.select("body").append("svg").attr("width",w).attr("height", h);
      var lines = svg.attr("class", "line")
      d3.json("data.json", function(error, data) {
        console.log(data);
        var circles = svg.selectAll("foo")
          .data(data.nodes)
          .enter()
          .append("circle")
          .attr("cx", function(d) {return d.x;})
          .attr("cy", function(d) {return d.y;})
          .attr("r", 20)
          .append("title") // For hover effect
          .text(function(d) { return "The site is " + d.id; });
        var lines = svg.selectAll("foo")
          .data(data.links)
          .enter()
          .append("line")
          .attr("x1", function(d) {
              return circles.filter(function(e) {
                  return e.id === d.node01
              }).attr("cx")
          })
          .attr("x2", function(d) {
              return circles.filter(function(e) {
                  return e.id === d.node02
              }).attr("cx")
          })
          .attr("y1", function(d) {
              return circles.filter(function(e) {
                  return e.id === d.node01
              }).attr("cy")
          })
          .attr("y2", function(d) {
              return circles.filter(function(e) {
                  return e.id === d.node02
              }).attr("cy")
          })
          .attr("stroke", "gray");
        circles.raise();
      });
    </script>
  </body>
</html>

我的问题是如何在 json 文件中的“链接”中描述的两个站点之间画一条线。另外,如何根据“链接”中描述的数量更改圆的半径。例如,如果 site01 和 site02 有链接,则这 2 个节点的半径将相同。

编辑 - 更改为当前版本

谢谢,

最佳答案

当我第一次读到你的问题标题时,我想“好吧,OP 想要一个力导向图表”,这就是我询问 D3 v4.x in the comments 的原因。 ...

但是,在我看来,您并不希望有一种力量来引导:您已经有了圆圈的位置。您只想链接它们。

既然如此,您可以过滤圆圈的选择以获取线条的 x1x2y1 y2:

var lines = svg.selectAll("foo")
    .data(data.links)
    .enter()
    .append("line")
    .attr("x1", function(d) {
        return circles.filter(function(e) {
            return e.id === d.node01
        }).attr("cx")
    })
    .attr("x2", function(d) {
        return circles.filter(function(e) {
            return e.id === d.node02
        }).attr("cx")
    })
    .attr("y1", function(d) {
        return circles.filter(function(e) {
            return e.id === d.node01
        }).attr("cy")
    })
    .attr("y2", function(d) {
        return circles.filter(function(e) {
            return e.id === d.node02
        }).attr("cy")
    })
    .attr("stroke", "gray");

这是使用您的代码和行选择的演示:

var data = {
  "nodes": [{
    "id": "site01",
    "x": 317.5,
    "y": 282.5
  }, {
    "id": "site02",
    "x": 112,
    "y": 47
  }, {
    "id": "site03",
    "x": 69.5,
    "y": 287
  }],
  "links": [{
    "node01": "site01",
    "node02": "site02",
    "amount": 170
  }, {
    "node01": "site01",
    "node02": "site03",
    "amount": 100
  }, {
    "node01": "site02",
    "node02": "site03",
    "amount": 70
  }]
};

var w = 400;
var h = 320;
var svg = d3.select("body").append("svg").attr("width", w).attr("height", h);
var lines = svg.attr("class", "line")

var circles = svg.selectAll("foo")
  .data(data.nodes)
  .enter()
  .append("circle")
  .attr("cx", function(d) {
    return d.x;
  })
  .attr("cy", function(d) {
    return d.y;
  })
  .attr("r", 20);

circles.append("title")
  .text(function(d) {
    return "The site is " + d.id;
  });

var lines = svg.selectAll("foo")
  .data(data.links)
  .enter()
  .append("line")
  .attr("x1", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node01
    }).attr("cx")
  })
  .attr("x2", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node02
    }).attr("cx")
  })
  .attr("y1", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node01
    }).attr("cy")
  })
  .attr("y2", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node02
    }).attr("cy")
  })
  .attr("stroke", "gray");
<script src="https://d3js.org/d3.v4.min.js"></script>

这里是相同的代码,但圆圈后面有线条:

var data = {
  "nodes": [{
    "id": "site01",
    "x": 317.5,
    "y": 282.5
  }, {
    "id": "site02",
    "x": 112,
    "y": 47
  }, {
    "id": "site03",
    "x": 69.5,
    "y": 287
  }],
  "links": [{
    "node01": "site01",
    "node02": "site02",
    "amount": 170
  }, {
    "node01": "site01",
    "node02": "site03",
    "amount": 100
  }, {
    "node01": "site02",
    "node02": "site03",
    "amount": 70
  }]
};

var w = 400;
var h = 320;
var svg = d3.select("body").append("svg").attr("width", w).attr("height", h);
var lines = svg.attr("class", "line")

var circles = svg.selectAll("foo")
  .data(data.nodes)
  .enter()
  .append("circle")
  .attr("cx", function(d) {
    return d.x;
  })
  .attr("cy", function(d) {
    return d.y;
  })
  .attr("r", 20);

circles.append("title")
  .text(function(d) {
    return "The site is " + d.id;
  });

var lines = svg.selectAll("foo")
  .data(data.links)
  .enter()
  .append("line")
  .attr("x1", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node01
    }).attr("cx")
  })
  .attr("x2", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node02
    }).attr("cx")
  })
  .attr("y1", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node01
    }).attr("cy")
  })
  .attr("y2", function(d) {
    return circles.filter(function(e) {
      return e.id === d.node02
    }).attr("cy")
  })
  .attr("stroke", "gray");
  
circles.raise();
<script src="https://d3js.org/d3.v4.min.js"></script>

关于javascript - D3 按节点名称链接圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43913436/

相关文章:

javascript - 如何使轮播中的内容垂直居中?

javascript - <g> 元素不适应 Firefox 上的 <svg>

javascript - 将 svg 元素替换为 icon

javascript - 反转 D3 中的 Y 轴

javascript - 堆叠三元运算符在 Angularjs 表达式中不起作用

javascript - 限制使用 Meteor blaze 输出的文本数量

javascript - Aframe 使用 Three.js 更改对象位置

Javascript window.location.replace 只是重新加载此页面

reactjs - mousemove事件,访问此上下文

javascript - 解释 Mike Bostock 节点解析循环