Filter data in d3 to draw either circle or square

d3.js

Solution

The problem is that after you `.enter()` you are returning a nested array, hence your error:

Uncaught TypeError: Object [object Array] has no method 'append'

To use `.filter()`, you need to apply it after the `.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);

Using the code above (also in this fiddle), I get the following output:

Note that you can also achieve the same effect using Array's filter method, e.g.

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);

Problem

I'm having a bit of trouble understand selections and filtering in d3. Let's say I have a simple array: ``` data = [1, 2, 6, 3, 4] ``` I want to draw circles if the value < 5 and squares if it's >= 5. My code right now only draws circles and looks like this: ``` var svg = d3.select("body").append("svg") svg.selectAll("shapes") .data(data) .enter() .append("circle") ``` and other attributes for circles. I need to use the `.filter()` method, but I don't know where to put it. I tried doing something like: ``` var svg = d3.select("body").append("svg") svg.selectAll("shapes") .data(data) .enter() .filter(function(d){if (d>5){console.log('working');}) .append("circle") ``` but then I get an error with the `append` method. Can someone point me in the right direction on how I'd accomplish this?

Original source