代码之家  ›  专栏  ›  技术社区  ›  Nibor

使用d3创建并附加分离的元素。创造

  •  8
  • Nibor  · 技术社区  · 7 年前

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

    <!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 回复  |  直到 7 年前
        1
  •  15
  •   Gerardo Furtado    5 年前

    仅为其命名名称空间:

    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>

    解释

    添加SVG元素时 append() 方法,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));
    }
    

    这改变了 this 对于 d3。创建者 方法在使用创建SVG元素时,通常不使用名称空间 append (内部使用 d3。创建者 ),自:

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

    但是,由于使用 文件文档元素 ,在这种情况下,名称空间是必需的。