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

11

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

<!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>

但是我不仅想要将元素附加到其中,而是想创建一个独立的<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>

但是它不会在浏览器中显示,尽管DOM看起来相同。

有什么解决方法吗?

1个回答

20

只需使用命名空间:

const detachedG = d3.create('svg:g');

这是带有该更改的代码:

<!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('svg: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>

解释

使用append()方法添加SVG元素时,98.47%的D3程序员不使用命名空间(来源:Fakedata公司)。因此,不是:

selection.append("svg:rect")

我们通常只做:

selection.append("rect") 

所以,在这里为什么需要一个命名空间?
在内部,d3.create 使用 d3.creator 并使用 document.documentElement 调用它:
export default function(name) {
    return select(creator(name).call(document.documentElement));
}

那会改变d3.creator方法中的this。通常我们使用append创建SVG元素时不使用命名空间(它内部使用d3.creator),因为:

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

然而,由于使用document.documentElement作为this,在这种情况下需要使用命名空间。

你会用哪个命名空间来创建一个未附加的 div?d3.create("div:div") 可以吗?谢谢。 - user2728841
1
在这种情况下,不需要命名空间,因为div是HTML元素。 - Gerardo Furtado

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