D3:选择并更改外部SVG?

all*_*rry 5 graphics svg adobe-illustrator inkscape d3.js

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

HTML:

<object data="circles.svg" type="image/svg+xml" id="circles"></object>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

d3代码:

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

否则,我会采取其他方式来做到这一点.例如,像这样的东西可能会选择(确实找到了SVG):

var svg = document.getElementById('circles');
Run Code Online (Sandbox Code Playgroud)

但是如何在D3中解析和修改?红利问题:调试D3选择器的最佳方法是什么?

Lar*_*off 7

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

var my_circles = d3.select(document.getElementById("circles").contentDocument)
                   .selectAll("circle");
Run Code Online (Sandbox Code Playgroud)

我发现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();
Run Code Online (Sandbox Code Playgroud)

完整的例子在这里.

  • 仅供参考,我已经发布了一个问题来澄清加载问题 - http://stackoverflow.com/questions/17347533/run-javascript-function-when-object-content-has-been-loaded (2认同)