Javascript 如何使用d3.js向现有svg添加外部组?
假设我用d3.js创建了一个svg,如下所示:Javascript 如何使用d3.js向现有svg添加外部组?,javascript,d3.js,svg,Javascript,D3.js,Svg,假设我用d3.js创建了一个svg,如下所示: svg = d3.select('.svgContainer').append("svg") .attr("width", '100%') .attr("height", '100%') .call(d3.zoom().on("zoom", function () { svg.attr("transform", d3.event.transform) })) .append("g"); 现在我想动态
svg = d3.select('.svgContainer').append("svg")
.attr("width", '100%')
.attr("height", '100%')
.call(d3.zoom().on("zoom", function () {
svg.attr("transform", d3.event.transform)
}))
.append("g");
现在我想动态地从不同的文件中添加不同的组。例如:
<svg>
<g id="myGroup">
<rect width="100" height="100" fill="blue" />
</g>
</svg>
但是,这会产生以下DOM:
svg
-svg
--myGroup
但是因为我需要根据主svg转换我的组,所以我需要以下DOM结构:
svg
-myGroup
--(eventually more dynamically added groups)
我尝试了以下方法并获得了正确的DOM,但该组未显示在我的svg中:
d3.xml("test.svg").then(function(xml) {
var svgGroup = xml.getElementById("myGroup");
svg.node().append(svgGroup);
});
编辑:我发现,这应该已经起作用了,问题是我的SVG中有几个关键的部分,例如渐变。当我只添加组时,我丢失了它们。最后,我把工作包起来,一切都很好。你就快到了。我已经说明了添加元素的两种方法。第一种方法的问题是svgNode不是节点,而是节点列表。可以使用循环将列表中的每个节点添加到列表中,如代码所示:
...
var toAdd = svgNode.childNodes;
for (var i = 0; i < svgNode.childElementCount; i++){
svg.node().appendChild(toAdd[i]);
}
...
关于第二种办法,我不能说有什么不对。我从另一个svg文件导入了一个路径,它显示在下半部分。我更改的唯一细节是显式设置svg元素的大小,而不是100%。是否可能因为它位于可见部分之外而未渲染?只是作为对的补充:如果您想要纯D3解决方案,可以使用selection.append和函数。就你而言:
d3.xml(svgfile).then(function(xml) {
var svgNode = d3.select(xml).select("#MyGroup");
svg.append(() => svgNode.node()) ;
});
甚至更短:
d3.xml(svgfile).then(function(xml) {
svg.append(() => d3.select(xml).select("#MyGroup").node()) ;
});
下面是使用另一个答案中链接的Wikipedia SVG的演示:
var svgfile=https://simple.wikipedia.org/static/images/mobile/copyright/wikipedia-wordmark-en.svg;
var svg=d3。选择“主体”。追加svg
.宽度,'120'
.高度为“20”;
d3.xmlsvgfile.thenfunctionxml{
var svgNode=d3.selectxml.selectWikipedia;
svg.append=>svgNode.node;
};
嗯,这很奇怪。当我使用你的文件时,它确实工作得很好。然而,当我使用我的文件时,它并没有。啊哈,我明白了。一旦我从您的文件中复制了svg定义xmlns、viewbox等,我的文件也可以使用。
d3.xml(svgfile).then(function(xml) {
svg.append(() => d3.select(xml).select("#MyGroup").node()) ;
});