且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在 D3.js 中使用嵌套数据

更新时间:2023-08-25 20:02:58

这里有几个问题.

首先,您将一个 svg:path 元素附加到一个 svg:text 元素.在我看来,您正在尝试使用类rule"创建一个 svg:g 元素,但是您的代码将选择 rules 定义为一组 svg:text 元素.首先创建 svg:g 元素,然后附加 svg:text 元素:

First, you’re appending an svg:path element to an svg:text element. It seems to me like you’re trying to create an svg:g element with the class "rule", but your code defines the selection rules as a set of svg:text elements. Create the svg:g elements first, and then append svg:text elements:

var rules = vis.selectAll("g.rule")
    .data(data)
  .enter().append("svg:g")
    .attr("class", "rule");

rules.append("svg:text")
    …

第二个问题是数据运算符每组计算一次,而不是每个元素一次.有关更多详细信息,请参阅 API 参考中的在选择上操作"部分.你在 vis 中有一个 svg:svg 元素,所以你在 rules 中有一个组,所以你的数据函数只被调用一次:

The second problem is that the data operator is evaluated once per group, rather than once per element. See the section "Operating on Selections" in the API reference for more details. You have one svg:svg element in vis, so you have one group in rules, and so your data function is only called once:

function(d, i) {
  return d.data;
}

然后,生成的数据元素被映射到 rules selection... 已经定义了之前 selectAll 中的数据,并在创建时追加.

Then, the resulting data elements are mapped to the rules selection… which already have defined data from the previous selectAll and append when they were created.

简单的解决方法是使用 map 运算符而不是数据运算符,后者是每个元素评估一次,而不是每组评估一次.

The simple fix is to use the map operator rather than the data operator, which is evaluated once per element rather than once per group.

rules.append("svg:path")
    .map(function(d) { return d.data; })
    .attr("d", d3.svg.line()
    …

或者,您可以将数据直接传递给行生成器,但这需要您提前声明行生成器而不是内联它:

Alternatively, you could pass the data directly to the line generator, but that requires you declaring the line generator ahead of time rather than inlining it:

var line = d3.svg.line()
    .x(function(d) { return x(d[0]); })
    .y(function(d) { return y(d[1]); });

rules.append("svg:path")
    .attr("d", function(d) { return line(d.data); })
    …

希望这有帮助!