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

标签 javascript d3.js svg

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

<!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 看起来一样。

有什么办法解决这个问题吗?

最佳答案

只是命名空间:

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 Inc.)。因此,而不是:

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(内部使用 d3.creator)创建 SVG 元素时,我们通常不使用命名空间,因为:

If no namespace is specified, the namespace will be inherited from the parent element.

但是,由于将 document.documentElement 用作 this,因此在这种情况下命名空间变得必要。

关于javascript - 使用 d3.create 创建和附加分离元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59142143/

相关文章:

html - d3.js 图形输出到高分辨率打印质量文件?

javascript - D3 + React Native - X 位置更改时数据点值不更新

html - 在 IE Edge 中不考虑 SVG 转换属性

用于具有特定功能的折线图的 JavaScript Canvas 图表库

javascript - 使用 PreventDefault 禁用鼠标滚轮但无法启用它?

javascript - 通过 $parent.$index 和 $index 更新对象 $scope 项

javascript - 为什么我获取不到这个 d3.js 文本的 Bounding Box?

html - 在不知道高度宽度的情况下用背景图像填充 SVG 路径

javascript - 了解已解决 promise 的后续 then() 处理程序的执行顺序

javascript - 分别拖动每个元素