Javascript / D3.js /带标签的强制有向图

乔1314

我正在尝试通过使用D3创建一个强制有向图。我已经创建了一个没有标签的图形,但是一旦我尝试在图形上放置标签,就会弄乱整个代码,甚至该图形也不会出现。我在检查了几个文档后编写了代码,但是我不知道该在哪里修复它。如果您可以让我知道这段代码的哪一部分出错,那么熟悉D3的任何人都将不胜感激。

<html>

<head>
  <meta charset="utf-8">
  <title>D3 v5 force simulation</title>
  <style>
    text {
      font-family: sans-serif;
      font-size: 10px;
    }

  </style>
</head>

<body>
  <svg width="500" height="600"></svg>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script>
 
  var nodesData = [
    {id:"Korea", "group": 1, "value": 10},
    {id:"USA", "group": 1, "value": 5},
    {id:"France", "group": 1, "value": 5},
    {id:"UK", "group": 1, "value": 5},
    {id:"Japan", "group": 1, "value": 20},
    {id:"Turkey", "group": 1, "value": 5},

  ]

  var linksData = [
    { "source": 'Korea', "target": 'USA'},
    { "source": 'UK', "target": 'USA' },
    { "source": 'France', "target": 'Turkey' },
    { "source": 'Korea', "target": 'UK' },
    { "source": 'Japan', "target": 'Turkey' },
    { "source": 'Japan', "target": 'Korea' }
  ]

<---added---->
 var svg = d3.select("svg"),
     width =  +svg.attr("width"),
     height = +svg.attr("height");

 <---changed---->
  var link = svg.append("g")
    .selectAll("line")
    .data(linksData)
    .enter()
    .append("line")
    .attr("stroke-width", 1)
    .attr("stroke", "black");


  <---changed---->
  var node = svg.append("g")
    .selectAll("g")
    .data(nodesData)
    .enter()
    .append("g")
    
<---changed---->
 var circles = node.append("circle")
    .data(nodesData)
    .attr("r", d => d.value)
    .attr("fill", "LightSalmon")
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

<---added---->
var labels = node.append("text")
    .text(function(d){return d.id;});
    



  var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(200, 150));

  simulation
    .nodes(nodesData)
    .on("tick", ticked);

  simulation.force("link")
    .links(linksData);


  function ticked() {
    link
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });
    node
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
  }


  function dragstarted(d) {
    if(!d3.event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function dragged(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
  }

  function dragended(d) {
    if(!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }
  </script>
</body>

</html>

<原始代码-不带标签的强制有向图>要放置标签,我只更改了几点。最初,节点和链接是分开设置的,但是将它们分组在一起放置标签。

 <!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>D3 v5 force simulation</title>
</head>

<body>
  <svg width="400" height="300"></svg>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script>
  // 1. Data
  var nodesData = [
    {id:"Korea", "group": 1, "value":10},
    {id:"USA", "group": 1,"value":5},
    {id:"France", "group": 1,"value":5},
    {id:"UK", "group": 1,"value":5},
    {id:"Japan", "group": 1,"value":20},
    {id:"Turkey", "group": 1,"value":5},

  ]

  var linksData = [
    { "source": 'Korea', "target": 'USA'},
    { "source": 'UK', "target": 'USA' },
    { "source": 'France', "target": 'Turkey' },
    { "source": 'Korea', "target": 'UK' },
    { "source": 'Japan', "target": 'Turkey' },
    { "source": 'Japan', "target": 'Korea' }
  ]

  // 2. svg
  var link = d3.select("svg")
    .selectAll("line")
    .data(linksData)
    .enter()
    .append("line")
    .attr("stroke-width", 1)
    .attr("stroke", "black");

  var node = d3.select("svg")
    .selectAll("circle")
    .data(nodesData)
    .enter()
    .append("circle")
    .attr("r", d=> d.value)
    .attr("fill", "LightSalmon")
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

  // 3. forceSimulation
  var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(200, 150));

  simulation
    .nodes(nodesData)
    .on("tick", ticked);

  simulation.force("link")
    .links(linksData);

  // 4. forceSimulation 
  function ticked() {
    link
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });
    node
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
  }

  // 5. drag event
  function dragstarted(d) {
    if(!d3.event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function dragged(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
  }

  function dragended(d) {
    if(!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }
  </script>
</body>

</html>
雨果·埃哈伊·拉森(Hugo Elhaj-Lahsen)

由于节点是g元素,因此需要使用该transform属性来移动它们。我们使用translate(x,y)移动它变换。

  function ticked() {
    link
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });
    node
      .attr("transform", function(d) { return `translate(${d.x},${d.y})` });
  }

现在g我们正在翻译元素,因此直接对它们调用拖动处理程序:

  var node = svg.append("g")
    .selectAll("g")
    .data(nodesData)
    .enter()
    .append("g")
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

<head>
  <meta charset="utf-8">
  <title>D3 v5 force simulation</title>
  <style>
    text {
      font-family: sans-serif;
      font-size: 10px;
    }

  </style>
</head>

<body>
  <svg width="500" height="600"></svg>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script>
 
  var nodesData = [
    {id:"Korea", "group": 1, "value": 10},
    {id:"USA", "group": 1, "value": 5},
    {id:"France", "group": 1, "value": 5},
    {id:"UK", "group": 1, "value": 5},
    {id:"Japan", "group": 1, "value": 20},
    {id:"Turkey", "group": 1, "value": 5},

  ]

  var linksData = [
    { "source": 'Korea', "target": 'USA'},
    { "source": 'UK', "target": 'USA' },
    { "source": 'France', "target": 'Turkey' },
    { "source": 'Korea', "target": 'UK' },
    { "source": 'Japan', "target": 'Turkey' },
    { "source": 'Japan', "target": 'Korea' }
  ]

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

  var link = svg.append("g")
    .selectAll("line")
    .data(linksData)
    .enter()
    .append("line")
    .attr("stroke-width", 1)
    .attr("stroke", "black");


  var node = svg.append("g")
    .selectAll("g")
    .data(nodesData)
    .enter()
    .append("g")
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));
    
 var circles = node.append("circle")
    .data(nodesData)
    .attr("r", d => d.value)
    .attr("fill", "LightSalmon")

var labels = node.append("text")
    .text(function(d){return d.id;});
    



  var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(200, 150));

  simulation
    .nodes(nodesData)
    .on("tick", ticked);

  simulation.force("link")
    .links(linksData);


  function ticked() {
    link
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });
    node
      .attr("transform", function(d) { return `translate(${d.x},${d.y})` });
  }


  function dragstarted(d) {
    if(!d3.event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function dragged(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
  }

  function dragended(d) {
    if(!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }
  </script>
</body>

</html> 

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用dagre d3.js(javascript库)向有向图添加click事件?

来自分类Dev

如何使用dagre d3.js(javascript库)向有向图添加click事件?

来自分类Dev

d3强制有向图删除文本光标

来自分类Dev

d3强制有向图不选择文本

来自分类Dev

D3强制有向图ajax更新

来自分类Dev

参数化的D3js强制有向图节点定位

来自分类Dev

将节点动态添加到d3.js强制有向图

来自分类Dev

D3.js强制有向图,每组颜色不同吗?

来自分类Dev

将节点动态添加到d3.js强制有向图

来自分类Dev

d3.js 强制有向图:如何使节点大小取决于链接的值?

来自分类Dev

使用d3 js的水平条形图

来自分类Dev

在JavaScript / html中水平镜像d3图

来自分类Dev

JavaScript,D3条形图错误

来自分类Dev

中心d3.js JavaScript图

来自分类Dev

在力图D3 JS上添加标签

来自分类Dev

如何从JSON文件向D3 js森伯斯特图添加颜色?

来自分类Dev

为什么D3 js之间没有缝隙

来自分类Dev

如何仅将新节点添加到d3强制有向图?

来自分类Dev

带滑块的 D3 图也需要添加标签

来自分类Dev

d3.js中的有向无环图

来自分类Dev

d3 js中带有数据数组的堆积图

来自分类Dev

无法使用D3.js在强制标签布局中向标签添加鱼眼效果

来自分类Dev

带链接的D3树图

来自分类Dev

javascript / D3怪癖?

来自分类Dev

d3力有向图,未绘制链接

来自分类Dev

动态过滤D3有向图的节点

来自分类Dev

D3带标签的量规表

来自分类Dev

D3力向图方向

来自分类Dev

d3 强制有向图节点在过滤后停留在固定位置