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>
It looks like you're trying to add a different image for each node, instead of the one image added here:
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:or, if you had image URLs in the node data itself: