【问题标题】:Some clarification on reusable charts关于可重用图表的一些说明
【发布时间】:2013-02-02 19:48:15
【问题描述】:

在“Towards Reusable Charts”中,Mike 在末尾列出了一个示例 time-series chart。在里面,他有这样一行:

// Select the svg element, if it exists.
var svg = d3.select(this).selectAll("svg").data([data]);

这发生在可重用图表对象的定义中。我很难理解这句话。

  1. 首先,为什么要使用select(this)this 上下文是图表对象的当前实例吗?如果是这样,何必呢,为什么不直接选择页面上的 svg 元素呢?

  2. 为什么是selectAll?不是每个图表对象都对应一个图表吗?

  3. 为什么要[data],而不仅仅是data,就像我见过的大多数其他例子一样?此外,为什么我们将数据绑定到 svg 元素,而不是(比如说)路径元素?

如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 数据似乎绑定到svg,因此可以在同一个函数中创建和更新 svg 元素。这是正确的吗?

标签: d3.js


【解决方案1】:

文章中定义的可重用图表可用于将图表插入到任何 DOM 元素,可能在同一页面上多次插入,尽管data 不同。此外,由于您指出的声明,它可用于更新 DOM 元素中已经存在的图形。它的使用方式是(来自article):

var formatDate = d3.time.format("%b %Y");

var chart = timeSeriesChart()
             .x(function(d) { return formatDate.parse(d.date); })
             .y(function(d) { return +d.price; });

// Put the chart _inside_ #example1
d3.select("#example1")
  .datum(data1)
  .call(chart);

// Put the same chart _inside_ #example2
d3.select("#example2")
  .datum(data1)
  .call(chart);

// Update the data for #example1, without appending another <svg> element
setInterval(function () {
    d3.select("#example1")
      .datum(data2)
      .call(chart);
}, 5000);

现在解决您对它如何这样做的担忧:

  1. 首先请注意,此代码在 selection.each(...) 内运行。根据 API 参考,.each 中的 this 上下文是 DOM 元素。 API 参考进一步说:

    每个运算符可用于递归处理选择,通过在回调函数中使用 d3.select(this)。

    所以d3.select(this) 只返回一个d3.selection 只包含当前的DOM 元素,其中可能包含也可能不包含&lt;svg&gt; 元素。在页面上选择一个/每个&lt;svg&gt; 元素不会产生一个非常可重用的图表,因为它会弄乱整个页面,而不仅仅是您希望图表出现在其中的 DOM 元素。

  2. 使用selectAll 创建一个新的元素分组供D3 处理,与保留原始分组的select 相反。有关嵌套选择如何工作的更多详细信息,请参阅此article。而且,是的,你是对的,这里的 selectAll 组将仅用于创建或更新一个 &lt;svg&gt; 元素,这将我们带到下一点。

  3. D3 背后的基本概念之一是data-joins,其中一个数组 数据加入 中的一组DOM 元素一对一的时尚。在这种情况下,我们有兴趣将一些 data 追加/更新到恰好一个 &lt;svg&gt; 元素。使用[data] 为我们提供了一个可以绑定到一个&lt;svg&gt; 元素的单元素数组。或者,这可以写成:

  var svg = d3.select(this).selectAll("svg").data([1]); // No `data`

   // Update the area path.
   g.select(".area")
      .data(data)    // Specifying data explicitly
      .attr("d", area.y0(yScale.range()[0]));

   // Update the line path.
   g.select(".line")
      .data(data)   // Specifying data explicitly
      .attr("d", line);

但是,通过将数据绑定到&lt;svg&gt; 元素,让数据已经可供子选择使用会更高兴

【讨论】:

  • 谢谢!那肯定把事情弄清楚了。一个快速跟进:绑定到 svg 的数据是否自动可供其所有子节点使用?我试图用它来绘制两条孙子路径(svg>g>path),但它似乎没有用。我不得不将数据重新绑定到那些特定的路径。但是有一种方法可以使用 svg 数据,对吧?
  • 这取决于您是使用selectAll 添加孩子,然后是连接还是普通append。您能否发布您的代码(可能作为单独的问题或在原始问题中)以供审核?
  • @musially_ut 新问题:stackoverflow.com/questions/14675237/…
【解决方案2】:

可重复使用的图表只是图表应该已经创建,我们可以简单地从图表中受益。我们不需要花时间从头开始创建图表。

致谢:Reusabe Charts for d3

【讨论】:

    猜你喜欢
    • 2011-02-04
    • 2015-06-22
    • 2011-06-17
    • 2019-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    相关资源
    最近更新 更多