D3在一个调用中绘制不同的SVG形状,没有可见性

D3 draw different SVG shapes in one call, no visiblity

本文关键字:SVG 形状 可见性 绘制 调用 一个 D3      更新时间:2023-09-26

我有一个对象来存储svg形状的信息。它具有以下结构:

  Shapes = {
        id: <Shape ID>,
        objType: <Tag Name of Shape e.g ellipse or line>,
        Coordinates: < Object Containing relevant data for drawing >,
        Style:  <Object Containing relevant data for styling>,
 }
Examples for Coordinates and Style could be:
 Shapes.Coordinates = {
     x1: 10, // for Lines
     y1: 10,
     x2: 100,
     y2: 100,
 }
 Shapes.Coordinates = {
     cx: 10 ,// for Circles
     cy: 10,
     r: 10,
 }
 Shapes.Style = {
    fill: "black",
    stroke: "red",
    "stroke-width": 10
 }

现在我想要一个D3调用来利用给定的数据,根据对象数据绘制不同的形状。到目前为止,我最好的想法是以下代码:

首先,我创建了每个没有属性的形状,只有ID和Events。

    let objectsRender = svg.selectAll("line") 
                       .data(data)
                       .enter()
                       .append(function(d) {
                         return document.createElement(d.objType);
                       })
                       .attr("id", function(d){ return prefix +d._id;})
                       .attr("class", "no-attr")
                       .on("click",(d)=>{this.modeClick(d);});

然后,我在第二个调用中添加属性,通过使用for循环来找到正确的id,我认为这不是一个好的解决方案。我可以通过查找no-attr 类的任何标签来找到"空"的svg标签

let objectsAttributes=  svg.selectAll(".no-attr").each(function(){
    let id= d3.select(this).attr("id");
    let d = null;
    d = data[0];
    for(i = 0;i < props.data.length; i++){
      if(id == prefix +props.data[i]._id){
        d = props.data[i];
        break;
      }
    }
    if( d !== null){
    d3.select(this)
      .attr(d.coordinates)
      .attr(d.style)
      .attr("class", null);
    }

到目前为止,这个临时解决方案创建了具有相关属性的所有形状。但是这些形状是不可见的,这与append调用有关。

                       .append(function(d) {
                         return document.createElement(d.objType);
                       })

有人能提出一个更好的解决方案吗?或者告诉我,为什么我的svg在我的浏览器窗口上不可见,而是通过开发工具可见?

SVG元素不能用document.createElement创建,该方法只能创建html元素。

SVG元素必须通过document.createElementNS('http://www.w3.org/2000/svg',<元素名称>)所以我想在你的情况下,你会想要

.append(function(d) {
      return document.createElementNS('http://www.w3.org/2000/svg', d.objType);
})

浏览器工具显示您已经创建了与您真正想要的SVG元素名称相同的html元素,但由于它们是html元素,因此不起作用。