Reputation: 2673
D3.js is simply quite awesome, but I'm stuck on what should be very simple.
I have two group divs (#RFL & #RFR) containing two divs each (#RFLL, #RFLR, #RFRL, #RFRR, respectively). I want to put a select dropdown beneath each 'sub-DIV' – all of which is to be populated by a two dimensional array.
The trick is, the dropdowns for each 'group' div should be identical.
i.e. in the code below,
RFLL and RFLR should be 1, 2, 3, and RFRL and RFRR should be A, B, C
I've fiddled with this for a long time. I get every combination of arrangement except the one I want... the version below gives me two select boxes for each ".RFSubPane" - one too many... I've seen the section in the documentation as well as http://christopheviau.com/d3_tutorial/
All help / pointers greatly appreciated!
<script>
var l1 = ["1", "2", "3"];
var l2 = ["A", "B", "C"];
var labels = [l1, l2];
function d3test()
{
d3.selectAll(".RFSubPane")
.selectAll(".RFPane")
.data(labels)
.enter()
.append("select")
.selectAll("option")
.data(function (d) {return d;})
.enter()
.append("option")
.text(String);
}
</script>
<div class="RFPane" id="RFL" style="float: left; background: green;">
RFL
<div class="RFSubPane" id="RFLL" style="float: left; background: blue;"></div>
<div class="RFSubPane" id="RFLR" style="float: right; background: gray;"></div>
</div>
<div class="RFPane" id="RFR" style="float: right; background: red;">
RFR
<div class="RFSubPane" id="RFRL" style="float: left; background: blue;"></div>
<div class="RFSubPane" id="RFRR" style="float: right; background: gray;"></div>
</div>
Upvotes: 2
Views: 5031
Reputation: 51819
Cross-post with answer. In its entirety:
You've almost got it. The weird thing is that your selectors appear to be inverted: RFSubPane is inside RFPane, so you should select the panes first. There are two panes, so you can join them to your two-element labels array:
var pane = d3.selectAll(".RFPane")
.data(labels);
Now, if I understand correctly, you want to add a select element to each subpane, using the options from the pane's datum. Since you're using selectAll (there are multiple elements), the subpanes will not automatically inherit the data from the pane. If you know that there are always two subpanes per pane, you can duplicate the data:
var subpane = pane.selectAll(".RFSubPane")
.data(function(d) { return [d, d]; });
Now you can create the select element, and by expanding the data array, the child options:
subpane.append("select").selectAll("option")
.data(function(d) { return d; })
.enter().append("option")
.text(function(d) { return d; ]);
Mike
P.S. If there are a variable number of subpanes, you could use pane.each to create a context where you can access the parent data, maybe like this:
pane.each(function(d, i) {
var subpane = d3.select(this).selectAll(".RFSubPane");
});
In this case, you don't actually need to bind data to the subpanes,
and you can say selectAll("option").data(d)
rather than using a
function.
Upvotes: 5