I'm trying to modify Mike's Force-Directed Graph example to use rectangles instead of circles as nodes. Also, I want text inside the rectangle.
I have rectangles showing up with text correctly, however they're not attached to the links, and they do not move.
Here's a codepen link: http://codepen.io/anon/pen/gpgWaz
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
.call(force.drag);
node.append("rect")
.attr("class", "node")
.attr("width", 100)
.attr("height", 35)
.style("fill", function(d) {
return color(d.group);
})
.style("stroke", "black")
.style("stroke-width", "1px");
node.append("text")
.text(function(d) {
return d.name;
})
.style("font-size", "12px")
.attr("dy", "1em");
node.append("title")
.text(function(d) {
return d.name;
});
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("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
});
});
Update
Thanks to Lars 's comment, and his codepen it works now.
Updates I made to my code:
Here my new codepen: http://codepen.io/anon/pen/bdgREd
var width = window.innerWidth,
height = window.innerHeight,
nodeWidth = 100,
nodeHeight = 35;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-1500)
.linkDistance(100)
.friction(0.5)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
.call(force.drag);
node.append("rect")
.attr("class", "node")
.attr("width", nodeWidth)
.attr("height", nodeHeight)
.attr("rx", 5)
.attr("ry", 5)
.style("fill", function(d) {
return color(d.group);
})
.style("stroke", "black")
.style("stroke-width", "1px");
node.append("text")
.attr("x", 5)
.attr("y", 2)
.text(function(d) {
return d.name;
})
.style("font-size", "12px")
.attr("dy", "1em");
node.append("title")
.text(function(d) {
return d.name;
});
force.on("tick", function() {
link.attr("x1", function(d) {
return d.source.x + (nodeWidth / 2);
})
.attr("y1", function(d) {
return d.source.y + (nodeHeight / 2);
})
.attr("x2", function(d) {
return d.target.x + (nodeWidth / 2);
})
.attr("y2", function(d) {
return d.target.y + (nodeHeight / 2);
});
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
You're setting the x
and y
attributes on the g
elements to change their positions -- this won't do anything. You need to set the transform
attribute instead, like you're doing when adding the g
elements. So your tick
handler function would contain
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
instead of
node.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
});
Complete demo here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.