D3, SVG, and Javascript : Need to assign unique images to dynamically created nodes

感情迁移 提交于 2019-12-09 22:43:50

问题


I'm playing with the following Javascript + SVG + D3 code.
http://bl.ocks.org/1095795

The code is here:
https://gist.github.com/1095727

In short, I need unique images for each node (instead of the duplicated smiley face image as it's pulling now), but I'm not savvy enough to make it happen. Any help would be appreciated.

<!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>

回答1:


It looks like you're trying to add a different image for each node, instead of the one image added here:

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

This adds the image at node creation time, which sounds like it would be sufficient for your purposes. All you need to do is supply a function instead of a string for the relevant .attr() call. If you had an array of image URLs to use, you could get them in sequence like this:

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];
    })

or, if you had image URLs in the node data itself:

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;
    })


来源:https://stackoverflow.com/questions/12847783/d3-svg-and-javascript-need-to-assign-unique-images-to-dynamically-created-no

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!