-
我试图让D3.js生成矩形元素d3.create()。
-
首先,我创建了一个rectangle()函数,它返回一个元素:
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 }
-
然后创建一个SVG选择,并在其中添加一个rectangle()的实例。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() } )
-
但是在我的浏览器(Google Chrome)中没有可视输出。
-
然而,当我看到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>
-
实际上,如果我复制上面的代码并将其不加修改地放在HTML文件的其他地方,浏览器中将出现一个矩形。
-
为什么SVG对浏览器DOM的修改没有显示/工作,但它生成的代码是正确的,并且在手动复制/粘贴到HTML中时会显示出来?
创建文档:
此方法假定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
因此,创建矩形的函数应该使用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:rect
在DOM上有相同的名称,它们引用不同的规范,并且唯一对浏览器有意义的是svg:rect
。