I have svg like this:
<svg id="mySvg">
<path></path>
<path></path>
<path></path>
</svg>
But I would like to group all paths in this svg inside the g tag, so it would look like that:
<svg id="mySvg">
<g>
<path></path>
<path></path>
<path></path>
</g>
</svg>
How should I do it?
d3.select("#mySvg").append("g") // -> and move all paths inside g
CodePudding user response:
You can remove elements with selection.remove()
. This method will return a selection of the removed elements.
You can also use selection.append()
to append those elements. However, selection.append only takes a function or a string. If you supply a function it should return a (single) element/node. We can access the element/node of a selection of one element with selection.node()
This gives us the pattern:
let svg = d3.select('svg')
let path = svg.selectAll('path').remove();
svg.append('g').append(()=>path.node());
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<svg>
<path d="M 30 30 C 60 30 50 50 80 50" stroke="black" stroke-width="1" fill="none"></path>
</svg>
However, append() is intended for a single element. If you have many elements, instead you could use selection.each()
to add each selected element to a parent g
:
let svg = d3.select('svg')
let path = svg.selectAll('path').remove();
let g = svg.append('g');
path.each(function() {
g.append(()=>this);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<svg>
<path d="M 30 30 C 60 30 50 50 80 50" stroke="black" stroke-width="1" fill="none"></path>
<path d="M 30 130 C 60 130 50 150 80 150" stroke="black" stroke-width="1" fill="none"></path>
</svg>
The use of function() and fat arrow notation is intended to ensure the correct this
, which is the element we want to add to the parent g
This second snippet will work regardless of whether one or more nodes are selected.