javascript - d3.js 强制定向问题, "d"的意义?

标签 javascript d3.js force-layout

我在获取与 D3.js 一起使用的东西时遇到了一些麻烦。也就是说,我正在尝试使用 http://bl.ocks.org/mbostock/1021953 中的基本代码来制作一棵节点树。 .

enter image description here

我将其切换为内联加载数据,而不是从文件加载,因为我将它与 Rails 应用程序一起使用,并且不希望有重复的信息。我切换了线路,以便您可以看到我的数据的格式。

无论如何,这是我的大部分代码:

<%= javascript_tag do %>
  var nodes = [{"title":"Duncan's Death","id":"265"},{"title":"Nature Thrown Off","id":"266"},{"title":"Cows Dead","id":"267"},{"title":"Weather Bad","id":"268"},{"title":"Lighting kills man","id":"269"},{"title":"Macbeth's Rise","id":"270"}];
  var links = [{"source":"265","target":"266","weight":"1"},{"source":"266","target":"267","weight":"1"},{"source":"266","target":"268","weight":"1"},{"source":"268","target":"269","weight":"1"}];

  var firstelement = +links[0].source;

  links.forEach(function(l) {
    l.source = +l.source;
    l.source = l.source-firstelement;
    l.target = +l.target
    l.target = l.target-firstelement;
    });

  var width = 960,
      height = 500;

  var color = d3.scale.category20();

  var force = d3.layout.force()
      .charge(-1000)
      .linkDistance(300)
      .size([width, height]);

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

  force
      .nodes(nodes)
      .links(links)
      .start();

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

  var node = svg.selectAll(".node")
      .data(nodes)
    .enter().append("g")
      .attr("class", "node")
      .call(force.drag);

  node.append("circle")
      .attr("class", "circle_node")
      .attr("r", 50)
      .style("fill", function(d) { return color(d.id); })

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

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

  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("x", function(a) { return a.x; })
        .attr("y", function(a) { return a.y; }); 
  });

<% end %>

这似乎对我有用,但我似乎可以管理它。链接有效,但节点全部保留在左上角。我尝试直接输入圆圈并将文本附加到其中(靠近我上面列出的源代码),但是虽然圆圈行为正常,但它不显示文本。我希望标题位于节点的中心。

更一般地说,我对它的工作原理感到有点困惑。像这样的行中的“d”指什么

function(d) { return d.source.x; }

它似乎是在声明一个函数并同时调用它。我知道它不一定是特定的字符“d”(例如,将“d”切换为“a”似乎没有什么区别,只要它在声明中和函数内完成即可。 )但是它指的是什么?输入到正在修改的对象中的数据?例如,如果我想打印出来(在属性之外)我该怎么做?

抱歉,我是 D3 的新手(而且总体来说对 JavaScript 相当陌生),所以我感觉答案是显而易见的,但我一直在查找它并通过教程,但我仍然迷失方向。提前致谢。

最佳答案

首先,您的代码存在一个简单的问题,导致所有节点都停留在左上角。您尝试使用以下代码定位每个节点:

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

但是,节点g的选择,它不采用xy属性。。相反,您可以使用平移变换来移动每个节点,例如

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

进行此更改应该允许节点四处移动。


接下来,转向关于“d”的问题,我认为您需要了解的第一件事是您可以使用 D3 中的一系列元素来做什么。来自 the docs :选择(例如节点)“是从当前文档中提取的元素数组”。选择元素后,您可以应用运算符来更改元素的属性或样式。您还可以将数据绑定(bind)到每个元素。

在您的情况下,您将数据绑定(bind)到选择的g(节点):

var node = svg.selectAll(".node")
  .data(nodes)
  .enter().append("g")

您现在正在使用 attr改变每个节点的位置。但是,您不是将每个元素的 xy 属性设置为相同的值,而是传递 attr anonymous function这将为每个节点返回一个(可能不同的)位置:

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

attr 的文档中也解释了此行为:

Attribute values and such are specified as either constants or functions; the latter are evaluated for each element.

因此,d 表示节点 中的单个元素(对象)。

所以回到你的代码,在每个刻度上都会发生两件事:

  1. 每个节点(数据)的位置正在通过force重新计算。
  2. 然后,您传递给 force.on 的匿名函数会将每个相应元素移动到新位置。

关于javascript - d3.js 强制定向问题, "d"的意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20295700/

相关文章:

javascript - d3力布局中心节点定位

javascript - 添加动态按钮而不是替换

javascript - 颜色插值

javascript - 根据过滤器下拉列表在 d3 中的力图中添加和删除节点和链接

javascript - 堆叠条形图的 X Y 坐标

javascript - dc js - 使用 dc js 的直方图

javascript - 无法可视化 d3 力布局中的节点

javascript - PHP,服务器发送事件 - date_default_timezone_get() 在远程文件中无法正常工作

javascript - 如果在我的保持登录功能中刷新浏览器,如何保留电子邮件和密码?

javascript - 如何使用 javascript 将日期和时间加粗