d3.create() 返回带有 .node() 的元素,但不显示在浏览器中

ano*_*oir 3 javascript svg d3.js

  1. 我试图让 D3.js 使用d3.create()生成矩形元素。它不工作/不显示。

  2. 首先,我创建一个矩形()函数,它返回一个元素:

    function rectangle() {
    
        _el = d3.create("rect")
            .attr("stroke", "black")
            .attr("fill", "black")
            .attr("stroke-width", "10px")
            .attr("x", 0)
            .attr("y", 0)
            .attr("width", 300)
            .attr("height", 200);
    
        return _el
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后,我创建一个 SVG 选择,并在其中附加矩形().node()的实例:

    
    const SVG_WIDTH = 1000;
    const SVG_HEIGHT = 1000;
    
    svg = d3.select("body").append("svg")
        .attr("width", SVG_WIDTH)
        .attr("height", SVG_HEIGHT)
        .attr("id", "generated")
    
    svg.append(
        // () => rectangle().node()
        function () { return rectangle().node() }
    )
    
    Run Code Online (Sandbox Code Playgroud)
  4. 然而我的浏览器(Google Chrome)中没有任何视觉输出。

  5. 然而,当我查看 DOM(通过 Chrome 的“元素”选项卡)时,D3 生成了正确的 SVG/矩形代码:

    <svg width="1000" height="1000" id="generated">
        <rect stroke="black" fill="black" stroke-width="10px" x="0" y="0" width="300" height="200" rx="10" ry="10"></rect>
    </svg>
    
    Run Code Online (Sandbox Code Playgroud)
  6. 事实上,如果我复制上述代码并将其放置在 HTML 文件中的任何其他位置而不进行修改,我的浏览器中就会出现一个矩形。

  7. 为什么 SVG 对浏览器 DOM 的修改无法显示/工作,但它生成的代码是正确的,并且在手动复制/粘贴到 HTML 中时会显示?

Rod*_*ino 7

来自d3.create 文档:

此方法假定 HTML 命名空间,因此您必须在创建 SVG 或其他非 HTML 元素时显式指定命名空间 [...]

    d3.create("svg") // equivalent to svg:svg  
    d3.create("svg:svg") // more explicitly  
    d3.create("svg:g") // an SVG G element  
    d3.create("g") // an HTML G (unknown) element  
Run Code Online (Sandbox Code Playgroud)

因此,创建矩形的函数应该使用svg:rect. 否则它将创建一个“HTML 矩形”而不是“SVG 矩形”。

该d3.create方法默认在 HTML 命名空间中创建元素。当您使用时,d3.create('rect')您不是创建一个 SVG 矩形,而是创建一个 HTML 矩形(HTML 规范中不存在该矩形)。该元素出现在 DOM 上,但浏览器不知道如何渲染它(它具有 SVG 元素的名称,但不是 SVG 元素),因此它不会出现在屏幕上。

每个 HTML 元素都有一个隐式xhtml:前缀,SVG 中的每个 SVG 元素都隐式有一个svg:前缀。通常您不需要担心它,因为名称空间通常足够明显,可以由库处理。然而,d3.create无法说出你想要哪一个,因为它是一个独立的元素;所以它默认为 HTML。

因此,尽管 和svg:rect在xhtml:rectDOM 上具有相同的名称,但它们引用不同的规范,而唯一对浏览器有意义的是svg:rect.

  • @xax 我编辑了答案来详细说明 HTML 矩形和 SVG 矩形之间的差异。 (2认同)