javascript - D3、SVG 和 JavaScript : Need to assign unique images to dynamically created nodes

标签 javascript svg d3.js nodes force-layout

我正在使用以下 Javascript + SVG + D3 代码。
http://bl.ocks.org/1095795

代码在这里:
https://gist.github.com/1095727

简而言之,我需要为每个节点提供唯一的图像(而不是现在拉动的重复的笑脸图像),但我不够精明,无法实现这一点。任何帮助将不胜感激。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js"></script>
<style type="text/css">
.link { stroke: #ccc; }
.nodetext { pointer-events: none; font: 10px sans-serif; }
</style>
</head>
<body>
<script type="text/javascript">

var w = 960,
    h = 500

var nodes = [],
    links = [];

var vis = d3.select("body").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

var force = self.force = d3.layout.force()
    .nodes(nodes)
    .links(links)
    .gravity(.05)
    .distance(100)
    .charge(-100)
    .size([w, h]);

force.on("tick", function() {
    var node = vis.selectAll("g.node")
        .data(nodes, function(d) { return d.id;} )
    var link = vis.selectAll("line.link")
        .data(links, function(d) { return d.source.id + ',' + d.target.id})
  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 + ")"; });
});

function recalc() {
    var link = vis.selectAll("line.link")
                  .data(links, function(l) { return l.source.id + '-' + l.target.id; });

    link.enter().append("svg:line")
                .attr("class", "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; });

    link.exit().remove();

    var node = vis.selectAll("g.node")
              .data(nodes, function(d) { return d.dpid;}).call(force.drag);

      var nodeEnter = node.enter().append("svg:g")
        .attr("class", "node")
        .call(force.drag);

    nodeEnter.append("svg:image")
        .attr("class", "circle")
        .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png")
        .attr("x", "-8px")
        .attr("y", "-8px")
        .attr("width", "16px")
        .attr("height", "16px");

    nodeEnter.append("svg:text")
        .attr("class", "nodetext")
        .attr("dx", 12)
        .attr("dy", ".35em")
        .text(function(d) { return d.id });

    node.exit().remove();

    force.start();

}


/* Scenario */

/* step 1: add three nodes and three links */
function step1() {
    var nA = {id: 'aaa'};
    var nB = {id: 'bbb'};
    var nC = {id: 'ccc'};
    nodes.push(nA);
    nodes.push(nB);
    nodes.push(nC);

    var lAB = {source: nA, target: nB};
    var lAC = {source: nA, target: nC};
    var lBC = {source: nB, target: nC};
    links.push(lAB );
    links.push(lAC);
    links.push(lBC);

    recalc();
}

/* step 2: node B disappears with links */
function step2() {
    nodes = nodes.filter(function(n) { return n.id !== 'bbb'; });
    links = links.filter(function(l) { return (l.source.id !== 'bbb' && l.target.id !== 'bbb'); });

    recalc();
}

/* step 3: node B reappears with links */
function step3() {
    var nB = {id: 'bbb'};

    nodes.push(nB);

    /* find exiting nodes for links */
    var nA = nodes.filter(function(n) { return n.id === 'aaa'; })[0];
    var nC = nodes.filter(function(n) { return n.id === 'ccc'; })[0];

    var lAB = {source: nA, target: nB};
    var lBC = {source: nB, target: nC};
    links.push(lAB);
    links.push(lBC);

    recalc();
}

window.setTimeout(step1, 2000);
window.setTimeout(step2, 4000);
window.setTimeout(step3, 6000);

force.start();
recalc();

</script>
</body>
</html>

最佳答案

看起来您正在尝试为每个节点添加不同的图像,而不是此处添加的一个图像:

nodeEnter.append("svg:image")
    .attr("class", "circle")
    .attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png")

这会在节点创建时添加图像,这听起来足以满足您的目的。您所需要做的就是为相关的 .attr() 调用提供一个函数而不是字符串。如果您有一组图像 URL 可供使用,您可以按如下顺序获取它们:

nodeEnter.append("svg:image")
    .attr("class", "circle")
    .attr("xlink:href", function(d, i) {
        // d is the node data, i is the index of the node
        return myImages[i];
    })

或者,如果节点数据本身中有图像 URL:

nodeEnter.append("svg:image")
    .attr("class", "circle")
    .attr("xlink:href", function(d, i) {
        // d is the node data, i is the index of the node
        return d.nodeImageUrl;
    })

关于javascript - D3、SVG 和 JavaScript : Need to assign unique images to dynamically created nodes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12847783/

相关文章:

javascript - D3v4 堆积条形图工具提示

javascript - D3.js csv 文件中的列顺序错误

javascript - 无法使用 d3 选择 svg 元素

javascript - jQuery 激活器不适用于多个 DIV

javascript - 评估和提示并发症

javascript - 如何将属性 `preserveAspectRatio` 添加到 Highchart svg

java - 如何使用 iText7 将 SVG 添加到 PDF

javascript - React/Router/MemoryRouter - 如何传递历史属性并在子组件中使用 push()?

javascript - Am 图表 v4 工具提示问题

svg - 定位 svg :polygon 的更好方法