D3 使用文本而不是节点的力导向图

发布于 2024-12-17 05:01:32 字数 2062 浏览 0 评论 0原文

原文: http://mbostock.github.com/d3/ex/force.html

在他的示例中正如上面的链接中所提供的,我只是尝试用它们的名称替换圆形节点。我对 D3 和 js/jquery 不太了解,但我试图弄清楚它是如何工作的。

我能够用 svg:text 替换节点,但是当我这样做时,它们只是在它们开始的地方“生成”,并且不会产生动画。

我不知道是否应该在这里使用组。如果我这样做,请教我如何做。

到目前为止,这是我修改后的代码:

<div id="chart">
</div>

<script type="text/javascript">
<!--

var w = 960,
    h = 500,
    fill = d3.scale.category20();

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

d3.json("http://fourthdraft.com/ext/dataviz/miserables.json", function(json) {
  var force = d3.layout.force()
      .charge(-120)
      .linkDistance(70)
      .nodes(json.nodes)
      .links(json.links)
      .size([w, h])
      .start();

  var link = vis.selectAll("line.link")
      .data(json.links)
    .enter().append("svg:line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); })
      .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; });

  var node = vis.selectAll("circle.node")
      .data(json.nodes) 
    .enter().append("svg:text")
      .attr("class", "node")
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; })
      .text(function(d) { return d.name; })
      .style("fill", function(d) { return fill(d.group); })
      .call(force.drag);

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

  force.on("tick", function() {
    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; });
  });
});

//-->
</script>

Original: http://mbostock.github.com/d3/ex/force.html

In his example as provided in the above link, I'm simply trying to replace the circle nodes with their names instead. I don't know much about D3 nor js/jquery but I'm trying to figure how it works.

I was able to replace the nodes with svg:text but when I do, they just "spawn" wherever they start and they don't animate.

I don't know if I should use groups here. If I do, teach me how.

So far, this is my modified code:

<div id="chart">
</div>

<script type="text/javascript">
<!--

var w = 960,
    h = 500,
    fill = d3.scale.category20();

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

d3.json("http://fourthdraft.com/ext/dataviz/miserables.json", function(json) {
  var force = d3.layout.force()
      .charge(-120)
      .linkDistance(70)
      .nodes(json.nodes)
      .links(json.links)
      .size([w, h])
      .start();

  var link = vis.selectAll("line.link")
      .data(json.links)
    .enter().append("svg:line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); })
      .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; });

  var node = vis.selectAll("circle.node")
      .data(json.nodes) 
    .enter().append("svg:text")
      .attr("class", "node")
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; })
      .text(function(d) { return d.name; })
      .style("fill", function(d) { return fill(d.group); })
      .call(force.drag);

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

  force.on("tick", function() {
    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; });
  });
});

//-->
</script>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

说不完的你爱 2024-12-24 05:01:32

请参阅此小提琴: http://jsfiddle.net/nrabinowitz/QMKm3/6/

主要上面代码的问题是您正确地将 cxcy 属性(特定于 svg:circle 元素)更改为xy 在您附加 svg:text 元素的部分,但您没有在 tick< 中更改它们/code> 处理程序,这是迭代布局更新发生的地方:

force.on("tick", function() {
    // snip

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

您还应该将选择和附加从 更改为

var node = vis.selectAll("circle.node")
  .data(json.nodes)
.enter().append("svg:text")

即使

var node = vis.selectAll("text.node")
  .data(json.nodes)
.enter().append("svg:text")

我认为这在此代码的上下文中没有任何区别,但它最终会让您陷入困境- 在 D3 中,如此处所述,通常使用模式“使用选择器进行选择,添加与此选择器匹配的缺失节点” ,删除与此选择器匹配的额外节点”。在您的代码中,选择器和您添加的节点不匹配,这是一个概念问题,即使它对您编写的代码没有任何影响。 (我应该指出,我仍然发现这种模式有点令人困惑和奇怪。但至少,遵循它将使您的代码对其他开发人员来说更容易理解。)

See this fiddle: http://jsfiddle.net/nrabinowitz/QMKm3/6/

The main issue with your code above is that you correctly changed the cx and cy attributes (which are specific to the svg:circle element) to x and y in the part where you appended the svg:text elements, but you didn't change them in the tick handler, which is where the iterative layout update happens:

force.on("tick", function() {
    // snip

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

You also should change the selection-and-appending from

var node = vis.selectAll("circle.node")
  .data(json.nodes)
.enter().append("svg:text")

to

var node = vis.selectAll("text.node")
  .data(json.nodes)
.enter().append("svg:text")

Even though I don't think this makes any difference in the context of this code, it will eventually trip you up - in D3, as explained here, you generally use the pattern "select with a selector, add missing nodes that match this selector, remove extra nodes that match this selector". In your code, the selector and the nodes you add don't match, which is a conceptual issue even if it doesn't have any ramifications for your code as written. (I should note that I still find this pattern a bit confusing and weird. But at a minimum, following it will make your code more legible to other developers.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文