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

uke*_*joe 20 d3.js

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

data = [1, 2, 6, 3, 4]
Run Code Online (Sandbox Code Playgroud)

如果值<5则绘制圆圈,如果> = 5则绘制正方形.我的代码现在只绘制圆圈​​,如下所示:

var svg = d3.select("body").append("svg")
svg.selectAll("shapes")
    .data(data)
    .enter()
    .append("circle")
Run Code Online (Sandbox Code Playgroud)

圈子的其他属性.我需要使用该.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")
Run Code Online (Sandbox Code Playgroud)

但后来我得到了该append方法的错误.有人能指出我如何实现这个目标吗?

mdm*_*dml 23

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

未捕获的TypeError:对象[对象数组]没有方法'追加'

要使用.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);
Run Code Online (Sandbox Code Playgroud)

使用上面的代码(也在这个小提琴中),我得到以下输出:

在此输入图像描述

请注意,您也可以使用Array的滤镜方法实现相同的效果,例如

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);
Run Code Online (Sandbox Code Playgroud)

  • @mdml:您使用 `selection.filter()` 的原始答案留下了一堆空的圆圈和方块。另一种选择是过滤你_不_想要的项目,然后`.remove()`它们:http://jsfiddle.net/LGJNF/1/ (2认同)

小智 6

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

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

比如这样

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);
Run Code Online (Sandbox Code Playgroud)