使用d3.create创建和附加分离的元素 [英] Creating and appending detached elements with d3.create

查看:130
本文介绍了使用d3.create创建和附加分离的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's say I create a simple graphic like this:

<!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>,而是可以随意附加它(例如,它可以从一个函数返回),而不仅仅是附加它.

But instead of just appending to it, I want to create a detached <g> which can then be appended at will (e.g. it could be returned from a function).

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

With d3 V5 there is a d3.create() function which creates a detached element.

<!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看起来一样,它也不会出现在浏览器中.

But it doesn't appear in the browser, even though the DOM looks the same.

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

Any ideas how to fix this?

推荐答案

仅对其命名空间:

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

以下是具有此更改的代码:

Here is the code with that change:

<!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.).因此,代替:

When appending SVG elements with the append() method, 98.47% of D3 programmers don't use namespaces (source: Fakedata Inc.). Therefore, instead of:

selection.append("svg:rect")

我们通常只是这样做:

selection.append("rect") 

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

So, why do you need a namespace here?

在内部, d3.create 使用d3.creatordocument.documentElement调用它:

export default function(name) {
    return select(creator(name).call(document.documentElement));
}

这将更改this方法的this.在使用append(内部使用d3.creator)创建SVG元素时,通常不使用名称空间,因为:

That changes the this for the d3.creator method. We normally don't use namespaces when we create SVG elements using append (which internally uses d3.creator), since:

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

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

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

However, because of the use of document.documentElement as this, the namespace becomes necessary in this case.

这篇关于使用d3.create创建和附加分离的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆