agn
agn

Reputation: 29

Add a Circle for Every nth Data Element d3.js

I am creating a grouped line graph in d3.js. I would like to add circles with tooltips for the data. However, doing this for every point becomes too crowded. Therefore, I would like to add circles to every third data point on the line.

I tried to do this with the following code:

svg2.selectAll("dot")

        .data(data)
        .enter().append("circle")
        .attr("r", 10)
        .attr('fill', "red")
        .attr("cx", function (d,i) {
            if (i%3 === 0 && i>0) {
                return xAxisScale(d.date);
            }
            else {
                return null;
            }
        })
        .attr("cy", function (d,i) {
            if (i%3 === 0 && i >0 ) {

                return yAxisScale(d.count);
            }
            else {
                return null;
            }

        })

However, for some reason, there seems to be an extraneous point.

enter image description here

I am not sure why this is occurring or how to get rid of this. Any help would be greatly appreciated!

Upvotes: 1

Views: 2488

Answers (1)

Andrew Reid
Andrew Reid

Reputation: 38211

You are adding a circle for every data point, just positioning every third one. The circles are already added when you use .attr("cx", the enter().append() portion has already appended the circles. So when you use i to position every third circle, every other circle is given null as cx and cy attributes, so that wayward circle is actually many circles overlaid on top of each other.

Instead, filter your data array: you have an empty selection (selectAll('dot'), shouldn't select any elements, so the enter selection will create an element for every item in the data array). This way we'll only create circles for the data points we want:

svg2.selectAll("dot")
    .data(data.filter(function(d,i) { return i%3 == 0})
    .enter().append("circle")
    .attr("r", 10)
    .attr('fill', "red")
    .attr("cx", function (d,i) {
       return xAxisScale(d.date);
    })
    .attr("cy", function (d,i) {
        return yAxisScale(d.count);
    })

By filtering the data we create a selection of only the circles we want.

Upvotes: 3

Related Questions