使用JavaScript和JSON构建内联SVG图

Constructing an inline SVG diagram using JavaScript with JSON

本文关键字:SVG 构建 JavaScript JSON 使用      更新时间:2023-09-26

我目前正在进行一个涉及构建动态图的项目,并正在考虑为此使用SVG。

基于此,我想看看我所追求的SVG是否真的可行。

1) 使用JavaScript和json,是否可以基于我的json数据在HTML页面中动态构建SVG图?

基本上,我想在页面中构建一个矩形框,在那里我可以有1到10行svg作为输入到左侧的矩形框中。要确定实际出现的行数,将来自我的json对象。

如上所述,这可能吗?如果可能,如何设置来绘制这个内联svg图?

2) 同样,使用JavaScript,是否可以在这些svg行上放置超链接标签,同样基于json对象中的信息?

我开始玩静态内联SVG,但不确定如何使用javascript来构建它,以掩盖我上面的两点,即:

<body>
  <h1>My SVG Test</h1><hr/>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text x="465" y="90" fill="red">Heading One</text>
    <image x="100" y="110" width="50%" height="50%"
       xlink:href="http://my-image.com/myimg.jpg" />
    <line x1="25" y1="80" x2="350" y2="80" style="stroke: #000000; stroke-width: 2;"/>
  </svg>
</body> 

您可以使用Snap轻松创建您想要的内容。在下面的片段中,我添加了元素的所有必需属性和类型,并使用.el()创建了svg元素

el的语法为

Paper.el(name,attr)

Name是要创建的元素,例如线、圆、路径等,attr是要添加的属性。在下面的数据中,我通过指定它们的属性创建了两条线和一个圆。我还添加了填充和笔划

var data = [
{
  type:"line",
  attrs:{
    x1:0,
    x2:0,
    y1:0,
    y2:100,
    stroke:"black",
    "stroke-width":"5"
  }
},
{
  type:"line",
  attrs:{
    x1:100,
    x2:100,
    y1:0,
    y2:100,
    stroke:"black",
    "stroke-width":"5"
  }
},
{
  type:"circle",
  attrs:{
    cx:50,
    cy:50,
    r:40,
    fill:"orange", 
  }
} 
]
var s = Snap("svg");
for(var x=0;x<data.length;x++){
  s.el(data[x].type).attr(data[x].attrs);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<svg width="500" height="500" viewbox="0 0 100 100"></svg>

添加链接有点困难和复杂,因为必须将子text元素附加到a。所以我对代码做了一些更改。

在下面的代码片段中,我为json数据添加了一个名为parent的新键。然后将parent:true设置为那些具有子元素的元素,并运行另一个循环将子元素附加到父

var data = [{
  type: "line",
  parent: false, //is false because it has no child elements
  attrs: {
    x1: 0,
    x2: 0,
    y1: 0,
    y2: 100,
    stroke: "black",
    "stroke-width": "5"
  }
}, {
  type: "line",
  parent: false,
  attrs: {
    x1: 100,
    x2: 100,
    y1: 0,
    y2: 100,
    stroke: "black",
    "stroke-width": "5"
  }
}, {
  type: "circle",
  parent: false,
  attrs: {
    cx: 50,
    cy: 50,
    r: 40,
    fill: "orange",
  }
}, {
  type: "a",
  parent: true, // Is true because this has child elements
  attrs: {
    x: 10,
    y: 50,
    "xlink:href": "http://snapsvg.io/docs/"
  },
  childs: [{
    type: "text",
    attrs: {
      x: 10,
      y: 50,
      text: "Snap is Cool",
    }
  }]
}, {
  type: "image",
  parent: false,
  attrs: {
    "xlink:href": "http://i.imgur.com/5NK0H1e.jpg",
    x: 0,
    y: 0,
    width: 50,
    height: 50
  }
}]
var s = Snap("svg");
for (var x = 0; x < data.length; x++) {
  var p = s.el(data[x].type).attr(data[x].attrs);
  if (data[x].parent) { //check if it is true
    for (var y = 0; y < data[x].childs.length; y++) {
      var c = s.el(data[x].childs[y].type).attr(data[x].childs[y].attrs);
      p.append(c);
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js?wmode=transparent"></script>
<svg width="500" height="500" viewbox="0 0 100 100"></svg>

要添加更多子元素,应使用以下代码

var data = [{
  type: "g"
}, {
  type: "image",
  appendTo: 0,
  attrs: {
    "xlink:href": "http://lorempixel.com/500/500/",
    x: 0,
    y: 0,
    width: 50,
    height: 50
  }
}, {
  appendTo: 0,
  type: "a",
  parent: true,
  attrs: {
    x: 5,
    y: 5,
    target: "_blank",
    "xlink:href": "http://snapsvg.io/docs/"
  }
}, {
  appendTo: 2,
  type: "circle",
  attrs: {
    cx: 5,
    cy: 5,
    r: 2.5,
    fill: "orange"
  }
}]
var s = Snap("svg");
var elems = [];
for (var x = 0; x < data.length; x++) {
  var e = s.el(data[x].type).attr(data[x].attrs);
  if (data[x]["appendTo"] !== undefined) {
    var p = elems[data[x].appendTo];
    p.append(e);
  }
  elems.push(e);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<div class="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100"></svg>
</div>