Creating and appending detached elements with d3.create

后端 未结 1 1697
隐瞒了意图╮
隐瞒了意图╮ 2020-11-29 12:24

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

相关标签:
1条回答
  • 2020-11-29 12:59

    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 讨论(0)
提交回复
热议问题