javascript - D3 力导向图方向

标签 javascript d3.js svg

我是 D3 新手,正在尝试制作类似于此的图表 example但有几件事让我感到困惑。我不确定该示例何时指的是 D3 内置的内容,或者只是指他们正在使用的数据集。

就像这里一样,我不确定 idd.id.因为示例的数据看起来像这样,这让我认为 id 来自数据。或者它代表一个索引值?

"nodes": [
    {"id": "Myriel", "group": 1},
    {"id": "Napoleon", "group": 1}
         ],
            // etc
"links": [
    {"source": "Napoleon", "target": "Myriel", "value": 1},
    {"source": "Mlle.Baptistine", "target": "Myriel", "value": 8},
    {"source": "Mme.Magloire", "target": "Myriel", "value": 10},
          //etc

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; })) <-- where is this from?
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));
所以!在我的代码中,我收到重复数千次的错误,“ Uncaught Error :丢失:X”,其中 X 是链接数组中第一个源的值。我可以 console.log 我的数据,它看起来很好,并且元素正在渲染到 DOM,但全部聚集在 SVG 的左上角。我不知道出了什么问题。我想我有两个问题。

  1. 有人可以澄清一下示例 id 的事情吗?

  2. 我的错误意味着什么?

如有任何帮助,我们将不胜感激。

我的代码;

var graph

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


d3.json("./mock.json", function(json) {
  var graph = json
      console.log(graph);
      console.log(graph.nodes);

      var simulation = d3.forceSimulation()
      .force("link", d3.forceLink(graph.links))
      .force("charge", d3.forceManyBody())
      .force("center", d3.forceCenter(width/2, height/2));

  var link = svg.append("g")
    .attr("class", "links")
    .selectAll("line")
    .data(graph.links)
    .enter().append("line")
    //.attr("stroke-width", function(d) {return Math.sqrt(d.value); });

  var node = svg.append("g")
    .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", 5)
      //.attr("fill", function(d) { return color(d.id); })
      .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));

    node.append("title")
      .text(function(d) {return d.text });

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

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

})

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;
}

});

数据:

{
 "nodes":[
         {"reference":5, "year": 0, "text":"The amount of time spent on video gaming is related negatively to academic achievement", "tags":["Academic disturbance"]},
         {"reference":5, "year": 0, "text":"Digital addiction ranges from <1% and 38%", "tags":["Addiction"]},
         {"reference":58, "year": 0, "text":"Patological video game play impacts negativelly academic achievement", "tags":["Addiction"]},
         {"reference":77, "year": 2009, "text":"74% of adults have Internet access at home", "tags":["Adults"]},
         {"reference":64, "year": 0, "text":"Apathetic users spend short times on web pages, follow no logical order, and make random selections", "tags":["Apathetic hypertext users3"]},
         {"reference":8, "year": 0, "text":"49.8% of sessions are shorter than 5 seconds", "tags":["App usage"]}
       ],
 "links": [
       {"source":0,"target":2},
       {"source":0,"target":6},
       {"source":1,"target":6},
       {"source":1,"target":3},
       {"source":1,"target":2}

 ]
 }

最佳答案

您的代码有两个问题:

  1. links 数组中看到的 6 索引在 nodes 数组中不可用。 nodes 的长度为 6,这意味着最大索引为 5。即使代码正确,这也会导致错误。我在下面的工作示例中将 6 更改为 5,我相信这就是您想要的。

  2. 由于链接是基于索引的,因此您可以简单地返回索引而不是 ID,即 d3.forceLink().id(function(d,i) { return i; }.

这是功能证明示例:

var graph

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

var json = {
  "nodes": [{
    "reference": 5,
    "year": 0,
    "text": "The amount of time spent on video gaming is related negatively to academic achievement",
    "tags": ["Academic disturbance"]
  }, {
    "reference": 5,
    "year": 0,
    "text": "Digital addiction ranges from <1% and 38%",
    "tags": ["Addiction"]
  }, {
    "reference": 58,
    "year": 0,
    "text": "Patological video game play impacts negativelly academic achievement",
    "tags": ["Addiction"]
  }, {
    "reference": 77,
    "year": 2009,
    "text": "74% of adults have Internet access at home",
    "tags": ["Adults"]
  }, {
    "reference": 64,
    "year": 0,
    "text": "Apathetic users spend short times on web pages, follow no logical order, and make random selections",
    "tags": ["Apathetic hypertext users3"]
  }, {
    "reference": 8,
    "year": 0,
    "text": "49.8% of sessions are shorter than 5 seconds",
    "tags": ["App usage"]
  }],
  "links": [{
      "source": 0,
      "target": 2
    }, {
      "source": 0,
      "target": 5
    }, {
      "source": 1,
      "target": 5
    }, {
      "source": 1,
      "target": 3
    }, {
      "source": 1,
      "target": 2
    }

  ]
};

var graph = json;

var simulation = d3.forceSimulation()
  .force("link", d3.forceLink().id(function(d, i) {
    return i;
  }))
  .force("charge", d3.forceManyBody())
  .force("center", d3.forceCenter(width / 2, height / 2));

var link = svg.append("g")
  .attr("class", "links")
  .selectAll("line")
  .data(graph.links)
  .enter().append("line")
  //.attr("stroke-width", function(d) {return Math.sqrt(d.value); });

var node = svg.append("g")
  .attr("class", "nodes")
  .selectAll("circle")
  .data(graph.nodes)
  .enter().append("circle")
  .attr("r", 5)
  //.attr("fill", function(d) { return color(d.id); })
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

node.append("title")
  .text(function(d) {
    return d.text
  });

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

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


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;
}
.links line {
  stroke: #aaa;
}

.nodes circle {
  pointer-events: all;
  stroke: none;
  stroke-width: 40px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.8/d3.min.js"></script>
<svg width="500" height="200"></svg>

关于javascript - D3 力导向图方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40230859/

相关文章:

javascript - 将鼠标悬停在链接上时显示文本

java - 在Java中读取SVG路径

javascript - TensorFlow.js 中的成本函数正则化

javascript - 如何使放置在 IFRAME 内的链接在父窗口中打开

javascript - 将 CORS + SOAP + WCF 用于 HTTPS 服务

javascript - 使用 D3.JS 为 Nest 树状图着色

javascript - 运行 D3.js 示例

html - 如何将内联 SVG 移动到 css

css - 你如何使用 css 设置外部 svg 的样式

javascript - React 下拉菜单一次打开所有下拉菜单