I'm in the process of finally learning D3, and I stumbled upon a problem that I haven't been able to find an answer to. I'm not certain if my question is because I'm not thinking idiomatically with the library, or if it is because of a procedure that I am currently unaware of. I should also mention that I've only started doing web-related things in June, so I'm fairly new to javascript.
Say that we're building a tool that gives a user a list of foods with respective images. And lets add on the additional constraint that each list item needs to be labeled by a unique ID so that it can be linked to another view. My first intuition to solve this is to create a list of <div>
's each with their own ID, where each div
has its own <p>
and <img>
. The resulting HTML would look something like:
<div id="chocolate">
<p>Chocolate Cookie</p>
<img src="chocolate.jpg" />
</div>
<div id="sugar">
<p>Sugar Cookie</p>
<img src="sugar.jpg" />
</div>
The data for this tool is in a JSON array, where an individual JSON looks like:
{ "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }
Is there a way to do generate the HTML in one fell swoop? Starting with a base case of adding a div, the code might look something like:
d3.select(containerId).selectAll('div')
.data(food)
.enter().append('div')
.attr('id', function(d) { return d.label; });
Now, what about adding a <div>
with a <p>
in it? My original thought was to do something like:
d3.select(containerId).selectAll('div')
.data(food)
.enter().append('div')
.attr('id', function(d) { return d.label; })
.append('p').text('somethingHere');
But, I see two problems with this: (1) how do you get the data from the div
element, and (2) how can you append multiple children to the same parent in one declarative chain? I can't think of a way to make the third step where I would append on the img
.
I found mention of nested selection on another post, which pointed to http://bost.ocks.org/mike/nest/. But is nested selection, and therefore breaking apart the appends into three chunks, appropriate/idiomatic for this situation? Or is there actually a well-constructed way to form this structure in one chain of declarations? It seems like there might be a way with subselections mentioned on https://github.com/mbostock/d3/wiki/Selections, but I'm not familiar enough with the language to test that hypothesis.
From a conceptual level, these three objects (div
, p
, and img
) are treated more like one group rather than separate entities, and it would be nice if the code reflected that as well.
See Question&Answers more detail:
os