使用d3.create创建和附加分离的元素

Nib*_*bor 3 javascript svg d3.js

假设我创建了一个像这样的简单图形:

<!doctype html>
<html lang="en">

<head>
  <script src="https://d3js.org/d3.v5.min.js"></script>
</head>

<body>
  <svg></svg>
  <script>
    const svg = d3.select('svg');
    const g = svg.append('g');

    g.append('g')
      .selectAll('g')
      .data([5, 10, 20, 40])
      .enter()
      .append('rect')
      .attr('fill', 'green')
      .attr('x', d => d)
      .attr('y', d => d)
      .attr('height', d => d)
      .attr('width', d => d);
  </script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

但是我不只是要附加它,还想创建一个独立的对象<g>,然后可以随意附加它(例如,可以从函数中返回它)。

对于d3 V5,有一个d3.create()函数可以创建一个分离的元素。

<!doctype html>
<html lang="en">

<head>
  <script src="https://d3js.org/d3.v5.min.js"></script>
</head>

<body>
  <svg></svg>
  <script>
    const svg = d3.select('svg');
    const g = svg.append('g');

    const detachedG = d3.create('g');
    detachedG.selectAll('g')
      .data([5, 10, 20, 40])
      .enter()
      .append('rect')
      .attr('fill', 'green')
      .attr('x', d => d)
      .attr('y', d => d)
      .attr('height', d => d)
      .attr('width', d => d);

    g.append(() => detachedG.node());
  </script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

但是,即使DOM看起来相同,它也不会出现在浏览器中。

任何想法如何解决这一问题?

Ger*_*ado 7

只是命名空间:

const detachedG = d3.create('svg:g');
Run Code Online (Sandbox Code Playgroud)

这是具有此更改的代码:

const detachedG = d3.create('svg:g');
Run Code Online (Sandbox Code Playgroud)

说明

当用该append()方法附加SVG元素时,98.47%的D3程序员不使用名称空间(来源:Fakedata Inc.)。因此,代替:

selection.append("svg:rect")
Run Code Online (Sandbox Code Playgroud)

我们只是做:

selection.append("rect") 
Run Code Online (Sandbox Code Playgroud)

那么,为什么在这里需要命名空间?

在内部,d3.create使用d3.creator调用它document.documentElement

export default function(name) {
    return select(creator(name).call(document.documentElement));
}
Run Code Online (Sandbox Code Playgroud)

这改变thisd3.creator方法。当我们使用append(内部使用d3.creator)创建SVG元素时,通常不使用名称空间,因为:

如果未指定名称空间,则名称空间将从父元素继承。

但是,由于使用document.documentElementas this,因此在这种情况下必须使用名称空间。