BearCakes100
BearCakes100

Reputation: 117

Why isn' t this selecting and changing the attributes in D3?

I have a simple data object called data that contains some radii , co-ordinates and colours I wish to use for my circles. However I want to now make them all orange but the last line of code does not seem to run ?

const myCircles = svg.selectAll()
.data(data);

myCircles.enter().append('circle')
    .attr('cx' , (d) => d.x)
    .attr('cy' , (d) => d.y)
    .attr('r' , (d) => d.radius )
    .attr('fill' , (d) => d.color )

myCircles.attr('fill' , 'orange');

Other things I tried that did not work

I tried the line

d3.selectAll(myCircles).attr('fill' , 'orange');

And I tried

svg.selectAll(myCircles).attr('fill' , 'orange');

But both times recive the error: d3.v7.min.js:2 Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Element': '[object Object]' is not a valid selector.

What does work but I do not want it

d3.selectAll('circle').attr('fill' , 'orange')

Because I would like to select the circles by the variable myCircles and not using the d3 tag "circle" as I intend on making more circles later.

Upvotes: 0

Views: 601

Answers (1)

Rodrigo Divino
Rodrigo Divino

Reputation: 1931

The myCircles variable is empty because it is only the update selection, and not the enter selection that appended the circles. If you need a variable to hold the appended circles, you can assign the enter selection to it:


const myCircles = svg.selectAll()
.data(data);

const myOrangeCircles = myCircles.enter().append('circle')
    .attr('cx' , (d) => d.x)
    .attr('cy' , (d) => d.y)
    .attr('r' , (d) => d.radius )
    .attr('fill' , (d) => d.color )

myOrangeCircles.attr('fill' , 'orange');

A good resource I recommend to learn more about those details is the official General Update Pattern Tutorial


To complement:

Instead of variables, you can also use classes to differentiate between objects. For example, if you append the circles with a class, you can later use selectAll to retrieve only the circles that match the class:

myCircles.enter().append('circle')
    .attr('cx' , (d) => d.x)
    .attr('cy' , (d) => d.y)
    .attr('r' , (d) => d.radius )
    .attr('fill' , (d) => d.color )
    .classed('myOrangeCircle', true)

svg.selectAll('circle.myOrangeCircle').attr('fill' , 'orange');

Upvotes: 1

Related Questions