Reputation: 556
Wondering if you can help. I have tried different stylings and different d3js examples but they all fail to show the text on the node. Any ideas this would be?
The task is quite simple really. Show the text on top of a node. I really have no idea why this is not working so your help is much appreciated.
Many thanks for your help in advance.
Below is the code, but for convenience here is the fiddle http://jsfiddle.net/rg5pmrz1/
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Force Layout Example 1</title>
<style>
.node {
fill: #ccc;
stroke: #fff;
stroke-width: 2px;
}
.link {
stroke: #777;
stroke-width: 2px;
}
.node text {
font: 10px sans-serif;
pointer-events: none;
}
text {
font: 10px sans-serif;
pointer-events: none;
}
</style>
</head>
<body>
<script src='http://d3js.org/d3.v3.min.js'></script>
<script>
// Define the dimensions of the visualization. We're using
// a size that's convenient for displaying the graphic on
// http://jsDataV.is
var width = window.innerWidth - 20,
height = innerHeight - 20;
var color = d3.scale.category10();
var force = d3.layout.force()
.charge(-300)
.linkDistance(function (l) { return l.value; })
.gravity(0.03)
.friction(0.9)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var graph = getData();
var nodeMap = {};
graph.nodes.forEach(function(d) {
nodeMap[d.name] = d;
//centering first element
if(d.main == true)
{
graph.nodes[0].x = width / 2;
graph.nodes[0].y = height / 2;
}
});
graph.links.forEach(function(l) {
l.source = nodeMap[l.source];
l.target = nodeMap[l.target];
l.distance = l.value;
l.size = l.value;
})
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 1 / (d.value / 1000);
});
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 30)
.style("fill", function(d) { return color(d.group); })
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.call(force.drag);
node.append("title")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) { return d.name});
node.append("text")
.attr("x", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name;console.log("name: " + 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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
function mouseover() {
console.log("mouse over");
d3.select(this).transition()
.duration(250)
.attr("r", 60);
}
function mouseout() {
console.log("mouse out");
d3.select(this).transition()
.duration(250)
.attr("r", 30);
}
function click() {
console.log("clicky clicky");
d3.select(this).transition()
.duration(250)
.attr("r", 60);
}
function getData() {
return {
"nodes":[
{"name":"John","group":1, "value": 1, "main": true},
{"name":"Mike","group":2, "value": 2},
{"name":"Ian","group":1, "value": 3},
{"name":"James","group":2, "value": 4},
{"name":"Sarah","group":2,"value": 5}
],
"links":[
{"source":"John","target":"Mike","value":100},
{"source":"Ian","target":"John","value":200},
{"source":"John","target":"James","value":100},
{"source":"Sarah","target":"John","value":300},
] };
}
</script>
</body>
</html>
Upvotes: 2
Views: 1176
Reputation: 556
This seems to reduce the flickering. Replace the var node = etc. with the following:
var node = svg.selectAll(".node")
.data(graph.connections)
.enter().append("g") //this appends the G to enable the text
.attr("class", "node")
.call(force.drag);
node.append("circle") //then we add the circle
.attr("class", "node")
.attr("r", function (d) {
if (d.main == true)
{
return 45;
}
else
{
return 30;
}
})
.style("fill", function(d) { return color(d.group); })
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.call(force.drag);
Upvotes: 0
Reputation: 1511
From the answers to duplicate questions here and here, it is because:
You can't add svg text to a svg circle. You should first create an svg g object (g stands for group) for each node, and than add a circle and a text for each g element, like in this code:
jsFiddle. Note the additional code in the tick function.
var width = window.innerWidth - 20,
height = innerHeight - 20;
var color = d3.scale.category10();
var force = d3.layout.force()
.charge(-300)
.linkDistance(function (l) { return l.value; })
.gravity(0.03)
.friction(0.9)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var graph = getData();
var nodeMap = {};
graph.nodes.forEach(function(d) {
nodeMap[d.name] = d;
//centering first element
if(d.main == true)
{
graph.nodes[0].x = width / 2;
graph.nodes[0].y = height / 2;
}
});
graph.links.forEach(function(l) {
l.source = nodeMap[l.source];
l.target = nodeMap[l.target];
l.distance = l.value;
l.size = l.value;
})
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 1 / (d.value / 1000);
});
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g");
var circle = node.append("circle")
.attr("class", "node")
.attr("id", function (d) { return d.name; })
.attr("r", 30)
.style("fill", function (d) {
return color(d.group);
})
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.call(force.drag);
var label = node.append("svg:text")
.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("transform", function(d) {
console.log(d);
return 'translate(' + [d.x, d.y] + ')';
});
});
function mouseover() {
console.log("mouse over");
d3.select(this).transition()
.duration(250)
.attr("r", 60);
}
function mouseout() {
console.log("mouse out");
d3.select(this).transition()
.duration(250)
.attr("r", 30);
}
function click() {
console.log("clicky clicky");
d3.select(this).transition()
.duration(250)
.attr("r", 60);
}
function getData() {
return {
"nodes":[
{"name":"John","group":1, "value": 1, "main": true},
{"name":"Mike","group":2, "value": 2},
{"name":"Ian","group":1, "value": 3},
{"name":"James","group":2, "value": 4},
{"name":"Sarah","group":2,"value": 5}
],
"links":[
{"source":"John","target":"Mike","value":100},
{"source":"Ian","target":"John","value":200},
{"source":"John","target":"James","value":100},
{"source":"Sarah","target":"John","value":300},
] };
}
Upvotes: 3