Reputation: 140
I have multiple groups inside another group and i want to reorder them in a specific order.
<svg>
<g id="wrapper">
<g id="b">...</g>
<g id="a">...</g>
<g id="c">...</g>
<g id="e">...</g>
<g id="d">...</g>
</g>
</svg>
Each groups inside the wrapper group has an id, right now the order of the ids are b, a, c, e, d. Say i want to order it with an array [3, 1, 4, 5, 2]
then the corresponding order will be c, b, e, d, a.
Resulting in,
<svg>
<g id="wrapper">
<g id="c">...</g>
<g id="b">...</g>
<g id="e">...</g>
<g id="d">...</g>
<g id="a">...</g>
</g>
</svg>
Upvotes: 0
Views: 616
Reputation: 102174
D3 has a very handy method, named sort(). Unfortunately, for this method to work, you have to compare the data bound to each element, and they have none right now. If you don't want to bind a bogus data you can always use pure JavaScript for this.
So, for using selection.sort()
, we'll first bind the data based on your index array (pay attention to the fact that the indices in your array are not zero based):
const order = [3, 1, 4, 5, 2];
const groups = d3.selectAll("#wrapper g");
groups.each(function(_, i) {
d3.select(this).datum({
position: i + 1
})
});
Or just:
const order = [3, 1, 4, 5, 2];
const groups = d3.selectAll("#wrapper g");
groups.datum(function(_, i) {
return {
position: i + 1
}
});
After that, it's just a matter of:
groups.sort(function(a, b) {
return order.indexOf(a.position) - order.indexOf(b.position)
});
Here is the demo:
const order = [3, 1, 4, 5, 2];
const groups = d3.selectAll("#wrapper g");
groups.datum(function(_, i) {
return {
position: i + 1
}
});
groups.sort(function(a, b) {
return order.indexOf(a.position) - order.indexOf(b.position)
});
console.log((new XMLSerializer()).serializeToString(d3.select("svg").node()))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<g id="wrapper">
<g id="b"></g>
<g id="a"></g>
<g id="c"></g>
<g id="e"></g>
<g id="d"></g>
</g>
</svg>
And this is the result, if you inspect the SVG:
<svg>
<g id="wrapper">
<g id="c"></g>
<g id="b"></g>
<g id="e"></g>
<g id="d"></g>
<g id="a"></g>
</g>
</svg>
Upvotes: 2