2013-06-23 99 views
4

是否可以选择和更改在Adobe Illustrator中创建的嵌入式(外部)SVG中的元素?D3:选择并更改外部SVG?

HTML:

<object data="circles.svg" type="image/svg+xml" id="circles"></object> 

circles.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px" > 
    <circle id="c_red" fill="#A00" stroke="#000" cx="40" cy="40" r="40"/> 
    <circle id="c_grn" fill="#0A0" stroke="#000" cx="60" cy="60" r="40"/> 
</svg> 

D3代码:

<script> 
    var my_circles = d3.select("#circles svg").selectAll("circles"); 
    my_circles.attr("fill", "black"); 
</script> 

否则,我愿意这样做的其他方式。例如,这样的事情可能会奏效选择(它确实找到SVG):

var svg = document.getElementById('circles'); 

但是,如何在解析和改变D3?奖金问题:调试D3选择器的最佳方式是什么?

回答

6

这实际上是一个讨厌的情况,因为您不能直接在嵌入式文档上使用DOM选择器。原则上,您需要的选择器是"#circles > circle",但在这种情况下这不起作用。所以你需要一些相当丑陋的东西,比如

var my_circles = d3.select(document.getElementById("circles").contentDocument) 
        .selectAll("circle"); 

我发现Javascript控制台对调试选择器非常有用。只要输入你想测试的东西,看看你想要的东西是否被返回。

问题是,上述代码只有在对象被加载后才有效。即使使用诸如JQuery的.ready()之类的东西也不足以确保这一点。一个快速和肮脏的解决办法是反复检查元素是否存在,直到它们分别是:

function changeColor() { 
    var sel = d3.select(document.getElementById("circles").contentDocument) 
       .selectAll("circle"); 
    if(sel.empty()) { 
    setTimeout(changeColor, 100); 
    } else { 
    sel.attr("fill", "black"); 
    } 
} 
changeColor(); 

完整的示例here

+0

我试过你的代码,但我仍然在我的Javascript控制台中获得“0:Array [0]”,我解释为返回零元素,对吧?这个阵列中不应该有两个'圆圈'吗?那么中间的“svg”元素呢? – allanberry

+0

您应该能够选择圆圈而不明确指定中间SVG。你能在某个地方发布一个完整的例子吗? –

+0

我基本上只包含了这个例子中的内容:https://gist.github.com/allanberry/5864358 – allanberry