最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Creating and appending detached elements with d3.create - Stack Overflow

programmeradmin1浏览0评论

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

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

<head>
  <script src=".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>

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>

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).

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>

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

Any ideas how to fix this?

Share Improve this question edited Apr 25, 2018 at 0:27 Gerardo Furtado 102k9 gold badges128 silver badges176 bronze badges asked Apr 24, 2018 at 10:23 NiborNibor 6791 gold badge8 silver badges18 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 21

Just namespace it:

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>

Explanation

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")

We normally just do:

selection.append("rect") 

So, why do you need a namespace here?

Internally, d3.create uses d3.creator calling it with document.documentElement:

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

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.

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

发布评论

评论列表(0)

  1. 暂无评论