Add id from Array/Object to svg circle

Hello i have the following aray :
Capture d’écran 05-07-2023 13.17.46
That i use to add circle with the following code :

lines.selectAll("circle")
    .data(function(d) {return d.values})
    .enter()
    .append("circle")
	.attr("cx", function(d) { return xScale(d.date); })
	.attr("cy", function(d) { return yScale(d.measurement); })
	.attr("r", 10)
	.attr("fill", "#3498db")
    .attr("stroke", "#fff")
    .attr("stroke-width", "1.5px")
    .attr("fill", "#CCE5F6")
    .style("opacity", 0)	
	.on('mousemove', function(e, d) {	 
			d3.select(this)
			.on("mouseover", (event, d) => logMeasurement(event, d))

Now i would like to attach to each circle the coresponding id from the array. I have tried thing like this :

.attr('id','key.id')

but i didn’t get any results.
Thanks

Hi Daniel. Your last line there, .attr('id','key.id'), will set the id attribute of every circle element to be the same thing, the literal string “key.id”. For it to be dynamic (different for every circle, based on an id property in the bound data object), you’d have to pass a function as the second argument of attr, like:

.attr("id", function(d) { return d.id; })

or, equivalently:

.attr("id", (d) => d.id)

The next question is, what’s “d” there? In your case I think it’d be one of the elements of the “values” array. I can’t see what those objects are like, though it looks like they at least have “date” and “measurement” properties. If those objects have the “id” you’d want to use, I think you should be all set.

But if the id you want to use is up in that parent array (TemperatureExterieure, TemperatureBallon, Humidite, etc.), you won’t have access to it in that “d” object, and D3 doesn’t pass it in. (This common issue is discussed here.) So you have a few options:

1 — Access the bound data of the parent. It looks like your circles are appended to a selection called “lines” (which may be <G> elements?); I think the id should be attached to the elements of that selection:

.attr("id", function(d) {
  return d3.select(this.parentNode).datum().id;
})

2 — Rewrite the code to keep a reference to the parent’s data. For example:

lines.each(function(parentData) {
  d3.select(this)
    .selectAll("circle")
      .data(parentData.values)
    .enter()
      .append("circle")
      .attr("id", parentData.id)
})

3 — Transform the data to be more “tidy”, so each element of values also has the id:

data = data.map(({id, values}) => ({id, values: values.map(d => ({...d, id}))}))

Let me know if that works. If you post an example notebook, we may be able to give more specific advice.

1 Like

Hi @tophtucker great so first point is i almost read everywhere about notebook but i don’t know what is this and will be nice if you can give me a link to understand how to do it.
Yes this is the point that i want to use the parent array ( TemperatureExterieure, TemperatureBallon, Humidite, etc.)
So now I get more clarification about how my data are treated with the notion of parent.
I was actually working with the answer on point 3 and i suceed to have the id attached. But i like your option 2. Do you think that in term of time treatement one solution is better than other between 2 and 3 ?

Just to give you more info about this is an array of objects, which contains an array of objects and it looks like this :


So in this Slices there is the id : “TemperatureExterieure” but if i understood well this is not possible to get access to this id ?
or maybe i should change this line somehow ?:

.data(function(d) {return d.values})

And so in fact it look like what you mentioned with point 1
So after test option 1 and 3 are working and i cant go forward. Solution 2 should also work so i just wondering if there is one better than other ? Many thanks

I don’t think there’s a big difference between the different options. Any should work.

i almost read everywhere about notebook but i don’t know what is this and will be nice if you can give me a link to understand how to do it.

A notebook is an Observable thing. Observable is a company and a web platform for coding and data analysis, and this is the help forum for it. Observable was cofounded by the D3 founder and hosts a lot of D3 examples and so a lot of people come here with D3 questions. (And we’re happy to help when we can, but it is mainly meant as an Observable forum!)

A “notebook” is just a document / page / file in Observable. E.g. here’s an Observable notebook making a D3 bar chart. You can change the code right on the page; to save your work you can click “Fork” in the upper right:

I work for them lol but I loved it before I worked here! It makes it easy to share examples so people can help with your code. Like in this case if I could see your notebook I could (sometimes, hopefully!) fix the code for you and send it to you as a suggestion.

1 Like

Hi thank you , ok i didn’t know this possibility and thanks for your answer.Maybe can be a good point to start to improve my code.

1 Like

It’s my mistake to say that this forum is officially just for Observable questions; that used to be true, but we now officially recommend this forum on Community 🏠 | D3 by Observable, too (since Observable supports D3 development). My bad!! In any case, glad you’re here!