Прямо сейчас у вас есть одна цепочка, и поэтому структура, которую вы получаете, является ожидаемой.
Так что вместо этого разорвите вашу цепочку.Сначала назовите SVG-выбор:
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 + ")");
Обратите внимание на то, что вы хотите append
группу, а не insert
it.
Вот демо, запустите его и осмотрите 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>
Вы увидите эту структуру:
<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>