为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 d3.js 将外部组添加到现有的 svg?

如何使用 d3.js 将外部组添加到现有的 svg?

九州编程 2021-09-30 10:50:46
假设我用 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>    <g id="myGroup">        <rect width="100" height="100" fill="blue" />    </g></svg>我知道,我可以像这样添加整个 svg(假设文件名为 test.svg):d3.xml("test.svg").then(function(xml) {     var svgNode = xml.getElementsByTagName("svg")[0];    svg.node().appendChild(svgNode);  });但是,这会产生以下 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);  });编辑:我发现,这应该已经可以工作了,问题是我<defs>的 SVG 内部有几个关键(例如渐变)。当我只添加组时,我丢失了它们。我结束了,把我的<g>周围包裹起来,<defs>现在一切正常。
查看完整描述

2 回答

?
holdtom

TA贡献1805条经验 获得超10个赞

作为对已接受答案的补充:如果您想要纯 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()) ;       

});

这是使用其他答案中链接的维基百科 SVG 的演示:

var svgfile = "https://simple.wikipedia.org/static/images/mobile/copyright/wikipedia-wordmark-en.svg";


var svg = d3.select('body').append("svg")

  .attr("width", '120')

  .attr("height", '20');


d3.xml(svgfile).then(function(xml) {

  var svgNode = d3.select(xml).select("#Wikipedia");

  svg.append(() => svgNode.node());

});

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


查看完整回答
反对 回复 2021-09-30
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

你快到了。我已经说明了在这个 codepen 中添加元素的两种方法。第一种方法的问题在于svgNode它不是 a node,而是 a nodeList。您可以使用循环添加列表中的每个节点,如代码所示:


...

var toAdd = svgNode.childNodes;

for (var i = 0; i < svgNode.childElementCount; i++){     

  svg.node().appendChild(toAdd[i]);

}

...

关于第二种方法,我不能说有什么问题。我从不同的 svg 文件导入了一个路径,它显示在下部。我更改的唯一细节是我明确设置了 svg 元素的大小,而不是100%. 是否有可能因为它在可见部分之外而没有被渲染?


查看完整回答
反对 回复 2021-09-30
  • 2 回答
  • 0 关注
  • 430 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信