【问题标题】:D3: data, enter, append pattern adds data to outer blockD3: data, enter, append 模式将数据添加到外部块
【发布时间】:2012-11-19 19:53:36
【问题描述】:

我正在使用 D3 javascript 库来呈现一些基本的网络图表。我想将三个 <path> 元素添加到 <svg> 块,但 D3 将元素添加到 <html> 块的末尾。这是完整的 html 源代码:

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="d3.v2.js"></script>
<script>
var chartData = [ 1, 2, 3 ];
d3.select("html").select("body").append("svg")
  .data(chartData, function(d) { console.log("data d:", d); return d; })
  .enter()
    .append("path")
      .attr("d", function(d) { return d; });
</script>
</body>

Chrome 的开发者控制台显示生成的 html 为:

<html><head><meta charset="utf-8">
<style type="text/css"></style></head><body>
<script src="d3.v2.js"></script>
<script>
var chartData = [ 1, 2, 3 ];
d3.select("html").select("body").append("svg")
  .data(chartData, function(d) { console.log("data d:", d); return d; })
  .enter()
    .append("path")
      .attr("d", function(d) { return d; });
</script><svg></svg>
</body><path d="1"></path><path d="2"></path><path d="3"></path></html>

&lt;svg&gt; 块已创建,但由于某种原因,&lt;path&gt; 块位于其外部。如何更正此错误,并将它们放在它们所属的 &lt;svg&gt; 中?

【问题讨论】:

    标签: javascript d3.js append enter


    【解决方案1】:

    首先,您应该有一个仅引用 svg 的高级变量。其次,您应该在创建 SVG 时指定它的高度和宽度。您不需要指定html 的选择,所以:

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

    现在您可以使用svg 变量来附加路径。建议您将路径组合在一起(因此首先附加了 "g")。而且您还应该为路径执行selectAll,因为您希望将要添加的数据绑定到路径元素。所以:

    svg.append("g").selectAll("path")
        .data(chartData)
      .enter().append("path")
        .attr("d", function(d) { return d; });
    

    我在这里推荐 D3 教程:http://alignedleft.com/tutorials/d3/

    【讨论】:

    • 谢谢!原来.selectAll("path")是缺失的关键部分。
    【解决方案2】:

    对于有类似问题的未来访问者:

    看来selectselectAll 在这种情况下(和其他类似情况)的行为差异取决于selectAll 创建了一个新组这一事实。

    D3 的选择对象是一个具有一些附加特殊属性的数组。每个数组对应一组对象。该组的一个属性是parentNode,它是执行初始selectAll 的节点。

    当最外层的选择是select 时,根隐含地是文档的根节点——在本例中为html

    由于selectAll 为每个匹配项(或条目)在选择中创建了一个新组,因此每个组都被指定为其派生节点的父节点。使用select,由于没有创建新组,因此每个组的原始parentNode 被保留,即使它不再准确地表示组内节点的父节点

    parentNode 也似乎(根据经验)是enter selections 的appended 节点所附加的节点。

    这就是为什么select 产生了观察到的行为,而selectAll 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多