使用d3生成标记但不操纵DOM?

时间:2016-10-21 21:37:25

标签: javascript d3.js

鉴于以下代码,我可以将svg圈添加到body标签。

d3.select("body")
  .append("svg")
  .append("circle")
    .attr("cx", 30)
    .attr("cy", 30)
    .attr("r", 20);

但是说我想用d3来生成标记:

<svg><circle cx="30" cy="30" r="20"/></svg>

并将其分配给javascript变量,最终在页面上呈现。在这种情况下,我不希望d3直接操作DOM,但我想用它的魔法来生成我的标记。

我该如何解决这个问题。

1 个答案:

答案 0 :(得分:2)

您可以使用轻量级DocumentFragment来创建内存中的树,该树不是实际DOM树的一部分。由于DocumentFragment接口继承自Node接口,因此您可以轻松地将其包装在D3选择中,并从新的虚拟根开始执行正常的D3操作。完成后,可以从根节点的outerHTML属性获取所需的源字符串,即附加的<svg>

&#13;
&#13;
// Create a document fragment in memory and wrap a D3 selection around it.
var doc = d3.select(document.createDocumentFragment());

// Do your normal D3 stuff.
var svg = doc.append("svg")
svg.append("circle")
  .attr("cx", 30)
  .attr("cy", 30)
  .attr("r", 20);

// 1. Obtain your source string from the outerHTML property.
var svgString = svg.node().outerHTML;
console.dir(svgString);

// 2. You can run a normal selection on the root
// This variant does not even require keeping a
// reference to the appended elements.
svgString = doc.select("svg").node().outerHTML;
console.dir(svgString);
&#13;
<script src="https://d3js.org/d3.v4.js"></script>
&#13;
&#13;
&#13;

注意:正如我刚刚意识到的那样,有一个缺点,因为IE仍然不支持SVG内容的innerHTMLouterHTML属性。因此,如果您需要支持IE,这种方法是不可行的解决方案。