Reputation: 188
I'm building svg with D3. I want to use clipping for the path element, but I have problem appending the defs
section for the clipPath.
Here is my code:
function build_svg(div,width,height) {
var margin={left: 10, top: 20};
return div.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.append("defs")
.append("clipPath")
.append("rect")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width)
.attr("height", height)
.insert("g","defs")
.attr("transform", "translate("+margin.left+","+margin.top+")");
}
I'm getting this:
<svg width="100%" height="100%">
<defs>
<clipPath>
<rect x="40" y="10" width="651" height="214">
<g transform="translate(40,10)">
.....
</g>
</rect>
</clipPath>
</defs>
</svg>
But I want this:
<svg width="100%" height="100%">
<defs>
<clipPath>
<rect x="40" y="10" width="651" height="214"></rect>
</clipPath>
</defs>
<g transform="translate(40,10)">
.......
</g>
</svg>
Where is my mistake?
Upvotes: 2
Views: 63
Reputation: 102218
Right now you have a single chain, and therefore the structure you're getting is the expected one.
So, instead of that, break your chain. First, name the SVG selection:
const svg = div.append("svg")
.attr("width", "100%")
.attr("height", "100%");
And then:
svg.append("defs")
.append("clipPath")
.append("rect")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width)
.attr("height", height);
svg.append("g", "defs")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
Pay attention to the fact that you want to append
the group, not insert
it.
Here is the demo, run it and inspect the SVG:
function build_svg(div, width, height) {
var margin = {
left: 10,
top: 20
};
const svg = div.append("svg")
.attr("width", "100%")
.attr("height", "100%");
svg.append("defs")
.append("clipPath")
.append("rect")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width)
.attr("height", height);
svg.append("g", "defs")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
};
const div = d3.select("#myDiv");
build_svg(div, 200, 200)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="myDiv"></div>
You'll see this structure:
<svg width="100%" height="100%">
<defs>
<clipPath>
<rect x="10" y="20" width="200" height="200"></rect>
</clipPath>
</defs>
<g transform="translate(10,20)"></g>
</svg>
Upvotes: 4