在d3中过滤数据以绘制圆形或方形

时间:2013-12-02 18:20:46

标签: d3.js

我在d3中理解选择和过滤时遇到了一些麻烦。假设我有一个简单的数组:

data = [1, 2, 6, 3, 4]

如果值<我想绘制圆圈。 5和正方形如果它是> = 5.我的代码现在只绘制圆圈​​,看起来像这样:

var svg = d3.select("body").append("svg")
svg.selectAll("shapes")
    .data(data)
    .enter()
    .append("circle")

和圈子的其他属性。我需要使用.filter()方法,但我不知道放在哪里。我尝试过这样的事情:

var svg = d3.select("body").append("svg")
svg.selectAll("shapes")
    .data(data)
    .enter()
    .filter(function(d){if (d>5){console.log('working');})
    .append("circle")

然后我使用append方法出错。有人能指出我如何实现这个目标吗?

2 个答案:

答案 0 :(得分:23)

问题是在.enter()之后你返回一个嵌套数组,因此你的错误是:

  

未捕获TypeError:对象[object Array]没有方法'追加'

要使用.filter(),您需要在 .append()

之后应用它
var data = d3.range(10);
var svg = d3.select("body").append("svg");

var shapes = svg.selectAll(".shapes")
    .data(data).enter();

shapes.append("circle")
    .filter(function(d){ return d < 5; })
    .attr("cx", function(d, i){ return (i+1) * 25; })
    .attr("cy", 10)
    .attr("r", 10);

shapes.append("rect")
    .filter(function(d){ return d >= 5; })
    .attr("x", function(d, i){ return (i+1) * 25; })
    .attr("y", 25)
    .attr("width", 10)
    .attr("height", 10);

使用上面的代码(也在this fiddle中),我得到以下输出:

enter image description here

请注意,使用Array's filter method也可以达到相同的效果,例如

var shapes = svg.selectAll(".shapes")
    .data(data.filter(function(d){ return d < 5; })).enter()
    .append("circle")
    .attr("cx", function(d, i){ return (i+1) * 25; })
    .attr("cy", 10)
    .attr("r", 10);

答案 1 :(得分:6)

通过为append function提供函数参数,也可以使用数据有条件地创建圆形或矩形

    .append(function(d, i){
        if (something to do with d) {
            ... return an SVG circle element
        } else {
            ... return an SVG rectangle element
        }
    })

e.g。像这样

var data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var svg = d3.select("body").append("svg");

function createSvgEl(name) {
    return document.createElementNS('http://www.w3.org/2000/svg', name);
}

svg
    .selectAll(".shapes")
    .data(data)
    .enter()
    .append(function(d, i){
        if (d <= 4) {
            return createSvgEl("circle");
        } else {
            return createSvgEl("rect");
        }
    });

svg.selectAll("circle")
        .attr("cx", function(d, i){ return (i+1) * 25; })
        .attr("cy", 10)
        .attr("r", 10);

svg.selectAll("rect")
        .attr("x", function(d, i){ return (i+1) * 25; })
        .attr("y", 25)
        .attr("width", 10)
        .attr("height", 10);