在嵌套结构

时间:2016-09-22 05:38:03

标签: javascript html css d3.js svg

我使用以下内容使用HTML ul和li来实现JSON模式的树结构。 JSFiddle

我希望在HTML SVG上实现相同的目标(因为之后会有可绘制的东西),我用SVG替换了ul和li:g

有没有办法在ul / li中添加边框到g?我可以使用SVG线来获得适当的结构,但有更好的方法吗?

var data = {
  "title": "person",
  "type": "object",
  "properties": {
    "first name": {
      "type": "string"
    },
    "last name": {
      "type": "string"
    },
    "age": {
      "type": "number"
    },
    "birthday": {
      "type": "string",
      "format": "date-time"
    },
    "address": {
      "type": "object",
      "properties": {
        "street address": {
          "type": "object",
          "properties": {
            "house number": {
              "type": "number"
            },
            "lane": {
              "type": "string"
            }
          }
        },
        "city": {
          "type": "string"
        },
        "state": {
          "type": "string"
        },
        "country": {
          "type": "string"
        }
      }
    },
    "phone number": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string"
          },
          "code": {
            "type": "number"
          }
        },
        "required": [
          "location",
          "code"
        ]
      }
    },
    "children": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "nickname": {
      "type": "string"
    }
  }
};

var title = data.title || "Root"; 
var result1 = d3.select("#input-structure");
traverseJSONSchema1(data, title, result1 );





function traverseJSONSchema1(root, rootname, resultpane ) {

  if (root.type === "object") {
    var listitem = resultpane.append("li");
    if (rootname !== "") {
      listitem.text(rootname + ":" + root.type  ); 
    }
    var newlist = listitem.append("ul");
    var items = root.properties; //select PROPERTIES
    for (var i = 0; i < Object.keys(items).length; i++) { //traverse through each PROPERTY of the object
      var itemname = Object.keys(items)[i];
      var item = items[itemname];
      traverseJSONSchema1(item, itemname, newlist );
    }

  } else if (root.type === "array") {
    var items = root.items; //select ITEMS
    var listitem = resultpane.append("li");
    if (rootname !== "") {
      listitem.text(rootname + ":" + root.type + "[" + items.type + "]" ); 
    }

    traverseJSONSchema1(items, "", listitem ); //recurse through the items of array
  } else if (["string", "integer", "number", "boolean"].indexOf(root.type) > -1) { //when the type is a primitive
    var listitem = resultpane.append("li");
    if (rootname !== "") {
      listitem.text(rootname + ":" + root.type   ); 
    }
  }

}
  .structure,
   .structure ul {
     list-style-type: none;
     text-indent: 5px;
   }
   
   li {
     border-bottom: 1px solid #c9c9c9;
     border-left: 1px solid #c9c9c9;
     width: max-content;
   }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div style="display:inline-block;">
  <ul id="input-structure" class="structure">
  </ul>
</div>

1 个答案:

答案 0 :(得分:3)

您无法向SVG <g>元素添加样式,但是您为<g>元素提供的样式将应用于其子元素。

您可以在组元素中添加边框,方法是在其中创建与每个组元素具有相同尺寸的<rect>元素。

这是一个例子。

d3.select("svg").selectAll("g")
  .each(function() {
    var bbox = d3.select(this).node().getBBox();    
    d3.select(this)
      .append("rect")
      .attr("width", bbox.width)
      .attr("height", bbox.height)
      .attr("x", bbox.x)
      .attr("y", bbox.y)
      .style("fill", "transparent")
      .style("stroke", "black");
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg height=500 width=500>
  <g>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="326.3864923262564" cy="386.95554145281227">
      <title>Myriel</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="301.18316897593957" cy="420.628099778895">
      <title>Napoleon</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="373.5296290951024" cy="350.31992689845373">
      <title>Mlle.Baptistine</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="383.028688690342" cy="370.21780005972573">
      <title>Mme.Magloire</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="291.2095525200062" cy="404.52807449846455">
      <title>CountessdeLo</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="284.3663860468869" cy="385.80285560875626">
      <title>Geborand</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="312.5026917750641" cy="425.9760979428693">
      <title>Champtercier</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="282.3287327273353" cy="397.57426542045806">
      <title>Cravatte</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="287.68354521150735" cy="373.4553102756052">
      <title>Count</title>
    </circle>
    <circle r="5" fill="#1f77b4" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="290.796739411191" cy="415.5793195443388">
      <title>OldMan</title>
    </circle>
    <circle r="5" fill="#aec7e8" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="475.09793964155534" cy="353.2189171085851">
      <title>Labarre</title>
    </circle>
    <circle r="5" fill="#aec7e8" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="456.0195362306761" cy="320.7461480714901">
      <title>Valjean</title>
    </circle>
    <circle r="5" fill="#ff7f0e" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="417.6709517148946" cy="241.9725833398076">
      <title>Marguerite</title>
    </circle>
    <circle r="5" fill="#aec7e8" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" cx="461.5929705608288" cy="358.92350523233586">
      <title>Mme.deR</title>
    </circle>
  </g>
  <svg>