【问题标题】:d3 NaN when using javascript Filter (data.filter) on stacked Bar Chart在堆积条形图上使用javascript过滤器(data.filter)时的d3 NaN
【发布时间】:2015-10-22 22:43:28
【问题描述】:

我在 d3 中有一个堆积条形图。每个堆栈由 4 个 svg 矩形组成。我想在图表中的每个堆栈上方创建一个带有堆栈总数的文本框。

堆栈 data[i][3] 中的最后一个矩形包含元素 x、y 和 y0。 i 代表堆栈 0 到 3。

这是一个控制台输出:

            .data(data.filter(function(d,i){
                     console.log("This is i: " + i);
                     console.dir(d[3]);
                     return d[3];
            }))

这是我:0 x: 0 y: 0.46 y0:2.4

我的想法是,我将能够为每个堆栈的最后一个矩形创建一个数据集,然后通过为该矩形添加 y 和 y0 来找到文本框的 y 位置。

我可以使用 d3 .filter(":last-child") 选项来做到这一点,但它会创建我不想要的空矩形元素。当我尝试使用 javaScript 过滤器时,我得到 d.x 和 d.y 值的 NaN 结果。有什么建议吗?

            stack.selectAll('.stackTotalBox')
            .data(data.filter(function(d,i){
                     console.log("This is i: " + i);
                     console.dir(d[3]);
                     return d[3];
            }))
            .enter()
            .append("rect")
           // .filter(":last-child")  -- this works but generates empty rect 
            .attr("class","stackTotalBox")
            .attr("x", function (d) {
                console.dir(d);
                return xScale(d.x) + 170/2 - 39.12;  // + width of stack/2 - width of text box/2
            })
            .attr("y", function (d) {
                    return yScale(d.y0 + d.y) - 40; // height of stack + room for text box
            })
            .attr("width", 78.24)      // width of text box
            .attr("height", 19.347)    // height of text box
            .attr("rx", 8)             // rounded corners
            .attr("ry", 8)             // rounded corners
            .attr("fill", "#BBBDBF");

更新数据的数据结构

数据包含4个数组(每个堆栈一个数组),每个数组有4个对象(矩形),每个对象包含一个矩形的坐标。

这是它在控制台中的外观,第一个堆栈/数组已展开:

数组[4]
--> 0: Array[4] (这代表一个堆叠条)
----> 0:对象
----> 1:对象
----> 2:对象
----> 3:对象(这表示堆叠栏中的最后一个矩形)
--------> x: 0(第一个数组有 x = 0,第二个数组有 x = 1)
--------> y: 0.4(矩形的高度)
--------> y0: 2.13(前面矩形的高度,起始 Y 坐标)

--> 1: 数组[4]
--> 2: 数组[4]
--> 3: 数组[4]

【问题讨论】:

  • 对“data”的数据结构不是很了解,可以分享一下吗?
  • 以上已更新,谢谢

标签: javascript d3.js


【解决方案1】:

我明白了。您应该使用Array.prototype.map 而不是Array.prototype.filter。如果你使用filter,那么只要闭包返回true,你的输出就会被包含在内。 因此,在您的情况下,由于d[3] 是一个对象并且它始终是正确的,因此您基本上没有过滤任何内容,因此d 仍然是一个二维数组,而d.x 是未定义的。

试试这个过滤你的数据:

stack.selectAll('.stackTotalBox')
    .data(data.map(function(item){            
        return item[3];
    }))

【讨论】:

  • 您的解决方案奏效了!感谢您的精彩解释。 (没有足够的 Rep 投票)
猜你喜欢
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 2019-06-19
  • 2013-12-22
  • 1970-01-01
相关资源
最近更新 更多