Javascript d3.js武力指导问题,“的重要性”;d";?

Javascript d3.js武力指导问题,“的重要性”;d";?,javascript,d3.js,force-layout,Javascript,D3.js,Force Layout,我在使用D3.js时遇到了一些问题。也就是说,我正在尝试使用中的基本代码创建一个节点树 我将其切换为内联加载数据,而不是从文件加载,因为我将其用于Rails应用程序,不希望有重复的信息。我切换了线路,以便您可以看到我的数据格式 总之,我的大部分代码如下: <%= javascript_tag do %> var nodes = [{"title":"Duncan's Death","id":"265"},{"title":"Nature Thrown Off","id":"26

我在使用D3.js时遇到了一些问题。也就是说,我正在尝试使用中的基本代码创建一个节点树

我将其切换为内联加载数据,而不是从文件加载,因为我将其用于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”(例如,将“d”切换为“a”似乎没有什么区别,只要在声明和函数中都这样做了。)但它指的是什么?输入到正在修改的对象中的数据?例如,如果我想打印出来,(在属性之外),我该怎么做


对不起,我是D3新手(一般来说对JavaScript也是相当陌生的),所以我觉得答案是显而易见的,但我一直在查找和阅读教程,我还是迷路了。提前感谢。

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

node.attr("x", function(a) { return a.x; })
    .attr("y", function(a) { return a.y; }); 
但是,
节点
是一个选择的
g
s,它不具有
x
y
属性。相反,您可以使用translate transform移动每个
节点
,例如

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
进行此更改应允许节点四处移动


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

在本例中,您将数据绑定到所选的
g
s(节点):

然后使用更改每个节点的位置。但是,不是将每个元素的
x
y
属性设置为相同的值,而是传递
attr
an,该属性将为每个节点返回一个(可能不同的)位置:

node.attr("x", function(a) { return a.x; })
    .attr("y", function(a) { return a.y; }); 
attr
的文档中也解释了这种行为:

属性值等被指定为常量或 功能;后者针对每个元素进行评估

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

因此,回到您的代码,在每个勾号上都会发生两件事:

  • 通过
    force
    重新计算每个节点(数据)的位置
  • 然后,通过传递给
    force.on
    的匿名函数,将每个对应元素移动到其新位置

  • 如果有助于澄清;我的印象是,
    d
    应该代表
    datum
    ,就像在您的数据集的单个部分中一样。谢谢,这非常有帮助。看来我应该多学习SVG。就我的第二个问题而言,它基本上假设我选择的任何变量(通常是
    d
    ,因为这似乎很标准)都是我正在处理的集合的一个元素(例如,当我调用
    .attr
    时,
    node
    )我在那里调用函数而不是只调用
    .attr(“x”,d.x)
    的唯一原因是,如果没有函数,它会尝试将
    d.x
    作为常量计算,因此不会对每个元素单独进行计算?@user3043447:是的,
    attr(“x”,d.x)
    将为选择中的每个元素计算相同的值。要明确的是,这对于任何值都是正确的,例如
    attr(“x”,20)
    (我不确定在您的示例中
    d
    来自哪里)。
    var node = svg.selectAll(".node")
      .data(nodes)
      .enter().append("g")
    
    node.attr("x", function(a) { return a.x; })
        .attr("y", function(a) { return a.y; });