d3-将元素添加到外部SVG文件

4

我有一张图形想要加载到我的d3可视化中作为背景(或仅仅是一个svg文件,我可以在其上添加circle元素)。该插图以svg格式呈现。我尝试将其加载到我的html文件中,使我能够向svg文件(或包含它的div)后添加元素(如圆形)。我尝试了两种方法:

<script>

d3.xml("bal.svg", "image/svg+xml", function(xml) {
  document.body.appendChild(xml.documentElement);
});

var circle = svg.append("circle")
                .attr("cx", 100)
                .attr("cy", 100)
                .attr("r", 20)
                .style("fill", "red");

</script>
< p > SVG图片显示正常,但没有圆形出现。在Firefox中,外部SVG文件的HTML显示为:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
width="250px" height="250px" viewBox="0 0 250 250" 
enable-background="new 0 0 250 250" xml:space="preserve">

我也尝试过:

<div id="htmlEmbed"></div>

<script>

d3.select("#htmlEmbed")
.append("object")
.attr("data", "tba2.svg")
.attr("width", 500)
.attr("height", 500)
.attr("type", "image/svg");

d3.select("#htmlEmbed")
.append("circle")
.attr("cx", 600)
.attr("cy", 600)
.attr("r", 20)
.style("fill", "red"); 

再次,SVG图像看起来完好无损,但是没有圆形显示出来。在这种情况下,浏览器中显示的HTML代码为:

<object width="500" height="500" data="tba2.svg" type="image/svg">
#document
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
width="500px" height="500px" viewBox="0 0 250 250" 
enable-background="new 0 0 250 250" xml:space="preserve"></svg>
</object>

我觉得这应该很简单,但我不确定。任何帮助都将不胜感激。

在你的第一个例子中,你没有告诉我们svg是如何定义的。请注意,您可能需要将SVG命名空间添加到任何要附加的元素中(即.append("svg:circle"))。 - Lars Kotthoff
感谢您的回复。在第一个示例中,我没有明确定义svg。我的假设是通过执行svg.append("circle"),代码将选择图像的svg元素(由于前面的行而出现在html中)。如何告诉它使用图像的svg?顺便说一句,如果我在文本编辑器中打开svg文件并简单地添加带有cx、cy属性的<circle>标记,并在浏览器中打开它,圆圈看起来完美无缺。肯定有一种方法让d3附加这些元素,但我不知道如何让它识别图像的svg。 - whistler
D3 不会根据页面上的内容自动分配变量。请尝试使用 d3.select("svg"),而不是 svg - Lars Kotthoff
我刚刚尝试了d3.select("svg").append("circle"),但它没有起作用。在HTML中没有出现圆形元素。 - whistler
你确定已经正确选择了 svg 元素吗?如果你能提供一个完整的可工作示例,那将会很有帮助。 - Lars Kotthoff
我刚刚在http://jsfiddle.net/Jw2f8/5/上设置了一个小工具。链接的SVG图像不是我想要使用的,但我不知道如何添加本地SVG文件。我将两种方法都放进去了,但注释掉了其中一种。 - whistler
1个回答

11

你尝试的代码有两个问题。首先,你需要正确定义svg,其次,在SVG加载后执行修改SVG的代码。由于d3.xml的异步性质,这并不是这种情况。

因此,你需要运行的代码是这样的。

d3.xml("http://openvz.org/images/1/17/Warning.svg", function(xml) {
  document.body.appendChild(xml.documentElement);

  var circle = d3.select("svg").append("circle")
            .attr("cx", 100)
            .attr("cy", 100)
            .attr("r", 20)
            .style("fill", "red");
});

工作的代码演示(除了安全限制外)在此


哇!感谢你解决了这个问题!如果StackOverflow上有天才徽章,你应该得到它! - whistler
有没有办法将外部SVG加载为普通对象,以便在d3.xml函数之外进行选择和操作? - Amyunimus
已经是这种情况了,问题在于,正如我所说,d3.xml 是异步的。在它完成加载后,您可以对 SVG 进行任何操作。 - Lars Kotthoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接