在D3图形的svg图像中添加边框

时间:2018-07-26 20:14:53

标签: javascript d3.js svg

我已经使用D3 Javascript库创建了一个图形。它是一个以图像为节点的有向图。我一直在尝试在图像节点周围添加粗边框,但没有成功。

这是我的带有嵌入式d3 JS脚本的html:

var json = {
  "nodes": [
    {"x": 50, "y": 50, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 150, "y": 50, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 250, "y": 50, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 350, "y": 150, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 450, "y": 150, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 50, "y": 250, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 150, "y": 250, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 250, "y": 250, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"}
  ],
  "links": [
    {"source":  0, "target":  1},
    {"source":  1, "target":  2},
    {"source":  2, "target":  3},
    {"source":  3, "target":  4},
    {"source":  5, "target":  6},
    {"source":  6, "target":  7},
    {"source":  7, "target":  3}
  ]
};

  // setting up the canvas size :)
  var width = 900,
    height = 500;

  // initialization
  var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);

  // build the arrow.
  svg.append("svg:defs").selectAll("marker")
  .data(["end"])      // Different link/path types can be defined here
  .enter().append("svg:marker")    // This section adds in the arrows
  .attr("id", String)
  .attr("viewBox", "0 -5 15 15")
  .attr("refX", 12)
  .attr("refY", 0)
  .attr("markerWidth", 25)
  .attr("markerHeight", 25)
  .attr("orient", "auto")
  .append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");

  var force = d3.layout.force()
  .gravity(0) // atom's cohesiveness / elasticity of imgs :)
  .charge(-50) // meta state transition excitement
  .linkDistance(140)
  .size([width, height]); // degree of freedom to the canvas

  // exception handling
  // d3.json("graph.json", function(error, json) {
  //   if (error) throw error;

    // Restart the force layout
    force
    .nodes(json.nodes)
    .links(json.links)
    .start();

    // Build the link
    var link = svg.selectAll(".links")
    .data(json.links)
    .enter().append("line")
    .attr("class", "link")
    .attr("marker-end", "url(#end)"); // add the arrow with and identify it wiht the tag "end" :)

    var node = svg.selectAll(".nodes")
    .data(json.nodes)
    .enter().append("g")
    .attr("class", "node")
    .call(force.drag);

    // Append custom images
    node.append("svg:image")
      .attr("xlink:href",  function(d) { return d.img;}) // update the node with the image
      .attr("x", function(d) { return -5;}) // how far is the image from the link??
      .attr("y", function(d) { return -19;}) // --- same ---
      .attr("height", 35) // size
      .attr("width", 35)
      .style("stroke", "red") //------ DOESNT WORK
      .style("fill", "auto") //------ DOESNT WORK
      .style("stroke-width", 5) //------ DOESNT WORK
    ;

    force.on("tick", function() {
      link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

      node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

      force.stop();
    });

  // });
.link {
  stroke: black;
}
.node text {
  pointer-events: none;
   font: 10px sans-serif;
}
.node:not(:hover) .nodetext {
  display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="style.css">
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
</body>
</html>

我正在尝试向图像节点添加边框。我正在使用

.style("stroke", "red") 
.style("fill", "auto") 
.style("stroke-width", 5)

在我的节点上,但似乎不起作用。请帮助我知道我要去哪里错了。

1 个答案:

答案 0 :(得分:1)

我认为您不能使用svg图像的边框,但是如果所有图像都是圆形,则可以在每个节点上附加一个可以模拟图像边框的圆形:

node.append("circle")
  .attr("cx", 12.5)
  .attr("cy", 0)
  .attr("r", 17.5)
  .style("fill", "transparent")
  .style("stroke", "black")
  .style("stroke-width", "2px");

var json = {
  "nodes": [
    {"x": 50, "y": 50, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 150, "y": 50, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 250, "y": 50, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 350, "y": 150, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 450, "y": 150, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 50, "y": 250, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 150, "y": 250, "label": "lol", "todoinfo": "Info here", "img": "https://cdn1.iconfinder.com/data/icons/flat-round-system/512/android-128.png"},
    {"x": 250, "y": 250, "label": "lol", "todoinfo": "Info here", "img": "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png"}
  ],
  "links": [
    {"source":  0, "target":  1},
    {"source":  1, "target":  2},
    {"source":  2, "target":  3},
    {"source":  3, "target":  4},
    {"source":  5, "target":  6},
    {"source":  6, "target":  7},
    {"source":  7, "target":  3}
  ]
};

  // setting up the canvas size :)
  var width = 900,
    height = 500;

  // initialization
  var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);

  // build the arrow.
  svg.append("svg:defs").selectAll("marker")
  .data(["end"])      // Different link/path types can be defined here
  .enter().append("svg:marker")    // This section adds in the arrows
  .attr("id", String)
  .attr("viewBox", "0 -5 15 15")
  .attr("refX", 12)
  .attr("refY", 0)
  .attr("markerWidth", 25)
  .attr("markerHeight", 25)
  .attr("orient", "auto")
  .append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");

  var force = d3.layout.force()
  .gravity(0) // atom's cohesiveness / elasticity of imgs :)
  .charge(-50) // meta state transition excitement
  .linkDistance(140)
  .size([width, height]); // degree of freedom to the canvas

  // exception handling
  // d3.json("graph.json", function(error, json) {
  //   if (error) throw error;

    // Restart the force layout
    force
    .nodes(json.nodes)
    .links(json.links)
    .start();

    // Build the link
    var link = svg.selectAll(".links")
    .data(json.links)
    .enter().append("line")
    .attr("class", "link")
    .attr("marker-end", "url(#end)"); // add the arrow with and identify it wiht the tag "end" :)

    var node = svg.selectAll(".nodes")
    .data(json.nodes)
    .enter().append("g")
    .attr("class", "node")
    .call(force.drag);

    // Append custom images
    node.append("svg:image")
      .attr("xlink:href",  function(d) { return d.img;}) // update the node with the image
      .attr("x", function(d) { return -5;}) // how far is the image from the link??
      .attr("y", function(d) { return -19;}) // --- same ---
      .attr("height", 35) // size
      .attr("width", 35)
      .style("stroke", "red") //------ DOESNT WORK
      .style("fill", "auto") //------ DOESNT WORK
      .style("stroke-width", 5) //------ DOESNT WORK
    ;

    node.append("circle")
      .attr("cx", 12.5)
      .attr("cy", 0)
      .attr("r", 17.5)
      .style("fill", "transparent")
      .style("stroke", "black")
      .style("stroke-width", "2px");

    force.on("tick", function() {
      link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

      node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

      force.stop();
    });

  // });
.link {
  stroke: black;
}
.node text {
  pointer-events: none;
   font: 10px sans-serif;
}
.node:not(:hover) .nodetext {
  display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="style.css">
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
</body>
</html>