【问题标题】:d3 filter selection not working?d3 过滤器选择不起作用?
【发布时间】:2014-08-16 21:33:24
【问题描述】:

要么我没有正确使用 d3 的 selection.filter,要么它有问题。我可以将问题提炼为几行。我在加载了 d3 的 Chrome 调试器中。让我们从一个空选择开始

d3.selectAll("nonexistant").empty()
> true

并将一些数据绑定到它。

d3.selectAll("nonexistant").data([1,2,3,4])
> [Array[4]]

很好,所以它有四号。让我们检查selection.size

d3.selectAll("nonexistant").data([1,2,3,4]).size()
> 0

嗯,我猜那是因为还没有 DOM 元素更新选择是空的,因为没有以前的元素。所以让我们make访问回车选择。

d3.selectAll("nonexistant").data([1,2,3,4]).enter()
> [Array[4]]
d3.selectAll("nonexistant").data([1,2,3,4]).enter().size()
> TypeError: undefined is not a function
d3.selectAll("nonexistant").data([1,2,3,4]).enter().append("p").size()
> 4

不确定为什么输入选择会导致错误,(更新:已在 v3.4.12 中修复)但无论如何,如果我们尝试使用文档中的示例函数进行过滤,

function odds(d, i) { return i & 1; }
d3.selectAll("nonexistant").data([1,2,3,4]).filter(odds);
> [Array[0]]
d3.selectAll("nonexistant").data([1,2,3,4]).enter().filter(odds);
> []
d3.selectAll("nonexistant").data([1,2,3,4]).enter().append("p").filter(odds)
> [Array[2]]

为什么当没有绑定 DOM 元素时它会默默地过滤掉所有元素?当我已经拥有 DOM 元素时,它似乎确实有效。但这感觉毫无用处,因为我不想为要丢弃的数据创建元素。也许我早点把过滤器放在?

d3.selectAll("nonexistant").data([1,2,3,4]).filter(odds).enter().append("p").size()
> TypeError: undefined is not a function
d3.selectAll("nonexistant").data([1,2,3,4]).enter().filter(odds).append("p").size()
> TypeError: undefined is not a function

不。似乎要走的路是在数组上使用 JS 的原生 filter

d3.selectAll("nonexistant").data([1,2,3,4].filter(odds)).enter().append("p").size()
> 2

d3 文档似乎没有区分绑定了 DOM 元素的选择和没有绑定的选择。看来我应该能够将filter 粘贴在我的方法链中的任何位置(并在任何选择上调用size),并在没有类型错误的情况下获得正确的结果。当然,filter 也支持需要 DOM 元素的 CSS 选择器,但我在这里没有使用它们。

我想知道的: d3 所做的与我期望的不匹配。我在多大程度上对选择以及对它们有效的操作存在误解?文件在多大程度上不清楚?这种行为是否属于错误?

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    来自.enter()方法的the documentation

    ...进入选择只定义appendinsertselectcall运算符;在修改任何内容之前,您必须使用这些运算符来实例化输入节点。 (输入选择也支持empty检查是否为空。)

    调用其他任何东西都不会产生有用的结果。这是否是错误、副作用或功能可能是值得商榷的。在几乎所有情况下,它都不会创建任何障碍,除非您可能需要知道此选择的 size() 以找出您传递给 data() 的数组中有多少基准尚未创建元素。

    不过,一旦您在输入选择中调用append(),它的行为就会很好,就像任何正常选择一样。其实append()是返回一个新的选择,所以!==enter()的返回值。

    那时您还可以检查此选择的size(),因此实际上只有在您需要在调用append() 之前知道大小时才算作问题。

    如果您甚至不需要在 odds(d) == false 处附加元素,则使用本机数组 filter 是正确的解决方案。

    当您已经创建了绑定到 [1,2,3,4] 的 DOM 节点(例如 <p>s),并且(例如,在事件处理程序中,当用户单击“突出显示所有可能性”按钮时)您打电话

    d3.selectAll('p').filter(odds).css('color', 'red')
    

    顺便说一句,这是一个写得很好的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 2017-09-12
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多