I'm trying to plot some directed links with a label in a force graph using D3 using this code:
// Per-type markers, as they don't inherit styles.
var svg = d3.select("body").select("svg");
svg.append("svg:defs").selectAll("marker")
.data(["end"])
.enter().append("svg:marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -0.8)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
// add the links and the arrows
var path = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
.attr("class", "link")
.attr("marker-mid", "url(#arrow)");
var marker = vis.selectAll("marker")
.data(force.links());
marker.append("text")
.attr("text-anchor", "middle")
.attr("font-family", "Arial, Helvetica, sans-serif")
.attr("fill", "Black")
.style("font", "normal 12px Arial")
.attr("transform", function(d) {
return "translate(" +
((d.source.y + d.target.y)/2) + "," +
((d.source.x + d.target.x)/2) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d){return d.type;});
It looks like a LOT of code for me given that the task is reasonably simple. But that's the only way I've managed to do it and even then, the text is not showing.
I find interesting that if i change.text(function(d){return d.type;});
for: .text(function(d){console.log(d.type);});
The info is logged into the console.
I would like to know why my text is not being presented and if there's a simpler way to do what I'm trying to do.
Thanks.
Instead of doing .data(force.links()); twice, create a g element for each group and place the text and path in that:
var pg = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("g");
var path = pg.append("path")
.attr("class", "link")
.attr("marker-end", "url(#end)");
var text = pg.append("text")
.text("text")
.style("fill", "black");
Then in your tick function update the position of the text:
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
text.attr("transform", function(d) {
return "translate(" + ((d.source.x + d.target.x)/2) + "," + ((d.source.y + d.target.y)/2) + ")"; });
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
}
Since you seem to be working off of this example, here's a modification of it:
<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.js"></script>
<style>
path.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
circle {
fill: #ccc;
stroke: #fff;
stroke-width: 1.5px;
}
text {
fill: #000;
font: 10px sans-serif;
pointer-events: none;
}
</style>
<body>
<script>
// get the data
//d3.csv("force.csv", function(error, links) {
var links = [{"source":"Harry","target":"Sally","value":"1.2"},{"source":"Harry","target":"Mario","value":"1.3"},{"source":"Sarah","target":"Alice","value":"0.2"},{"source":"Eveie","target":"Alice","value":"0.5"},{"source":"Peter","target":"Alice","value":"1.6"},{"source":"Mario","target":"Alice","value":"0.4"},{"source":"James","target":"Alice","value":"0.6"},{"source":"Harry","target":"Carol","value":"0.7"},{"source":"Harry","target":"Nicky","value":"0.8"},{"source":"Bobby","target":"Frank","value":"0.8"},{"source":"Alice","target":"Mario","value":"0.7"},{"source":"Harry","target":"Lynne","value":"0.5"},{"source":"Sarah","target":"James","value":"1.9"},{"source":"Roger","target":"James","value":"1.1"},{"source":"Maddy","target":"James","value":"0.3"},{"source":"Sonny","target":"Roger","value":"0.5"},{"source":"James","target":"Roger","value":"1.5"},{"source":"Alice","target":"Peter","value":"1.1"},{"source":"Johan","target":"Peter","value":"1.6"},{"source":"Alice","target":"Eveie","value":"0.5"},{"source":"Harry","target":"Eveie","value":"0.1"},{"source":"Eveie","target":"Harry","value":"2.0"},{"source":"Henry","target":"Mikey","value":"0.4"},{"source":"Elric","target":"Mikey","value":"0.6"},{"source":"James","target":"Sarah","value":"1.5"},{"source":"Alice","target":"Sarah","value":"0.6"},{"source":"James","target":"Maddy","value":"0.5"},{"source":"Peter","target":"Johan","value":"0.7"}];
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target});
link.value = +link.value;
});
var width = 960,
height = 500;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(60)
.charge(-300)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// build the arrow.
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
// add the links and the arrows
var pg = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("g");
var path = pg.append("path")
.attr("class", "link")
.attr("marker-end", "url(#end)");
var text = pg.append("text")
.text("My Awesome Text!!")
.style("fill", "black");
// define the nodes
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.call(force.drag);
// add the nodes
node.append("circle")
.attr("r", 5);
// add the text
node.append("text")
.attr("x", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
// add the curvy lines
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
text.attr("transform", function(d) {
return "translate(" + ((d.source.x + d.target.x)/2) + "," + ((d.source.y + d.target.y)/2) + ")"; });
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
}
//});
</script>
</body>
</html>
Related
I'm new to d3.js and JavaScript as well. Here is my code to the force directed graph in d3 with the CSV file data.
Before getting to it, here is the snippet of the code that i want to make the similar http://bl.ocks.org/eesur/be2abfb3155a38be4de4
Everything about the graph is fine but the onclick event doesn't seem to work.
The click funtion supposed to apply the click event to all the nodes in the csv data (which is 16 nodes) but my graph only has 9 nodes.
I have tried to put the click data to these specific nodes but failed instead. Also here is the CSV data that i want to draw the graph
https://github.com/hohadang1999/Authorship-Network-Graph/blob/master/publications.csv
d3.csv("publications.csv", function(error, links) {
var nodes = {};
links.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target});
});
var width = 1500,
height = 500;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(180)
.charge(-300)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("svg:defs").selectAll("marker")
.data(["end"])
.enter().append("svg:marker")
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
var path = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
.attr("class", "link")
.attr("marker-end", "url(#end)")
.style("stroke","#eee")
.on("click", click);
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.on("click", click)
.call(force.drag);
node.append("circle")
.attr("r", 15)
.style("fill","lightcoral")
.style("stroke","red");
node.append("text")
.attr("x",20)
.attr("dy", ".65em")
.text(function(d) { return d.name; });
node.on("click", function )
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
}
function click() {
d3.select(this).select("circle").transition()
.duration(750)
.attr("r",6)
.style("fill", "#ccc");
}
});
What i want to achieve is the click event on these nodes as the graph shown
There might be other issues (I didn't run your script), but one problem I can see clearly is the line "node.on("click", function ) which isn't mapping the click event to the click() function you wrote. You should change that to node.on("click", click).
I am very new to D3 and I am trying to replicate the behavior for text like is done with the circle elements here with the mouseover,mouseout behavior. Basically, to show text when hovered and hidden when not. Do I need to create a node var as I have with circle and text or is it possible with the current implementation:
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, value: link.type});
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target, value: link.type});
});
var width = 1000,
height = 900;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(90)
.charge(-125)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// Per-type markers, as they don't inherit styles.
svg.append("defs").selectAll("marker")
.data(["suit", "licensing", "resolved"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; })
.style("stroke", function(d){
if (d.type >= 0.4) {
return '#000066'
}
if (d.type >= 0.25) {
return '#ccccff'
}
if (d.type >= 0.01) {
return 'e8f4f8'
}
else {
return '#FFFFFF'
}
});
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 6)
.on("dblclick", dblclick)
.on('mouseover', function(d){
var nodeSelection = d3.select(this).style({opacity:'0.5'});
nodeSelection.select("text").style({opacity:'1.0'});
})
.on('mouseout', function(d){
var nodeSelection = d3.select(this).style({opacity:'0.0'});
nodeSelection.select("text").style({opacity:'0.0'});
})
.call(force.drag);
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d){
if (d.value >= 0.35){
return d.name
}
});
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", linkArc);
circle.attr("transform", transform);
text.attr("transform", transform);
}
function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}
var drag = force.drag()
.on("dragstart", dragstart);
function dblclick(d) {
d3.select(this).classed("fixed", d.fixed = false);
}
function dragstart(d) {
d3.select(this).classed("fixed", d.fixed = true);
}
Add opacity attribute to your text that defaults to 0. It appears you already have text to show and hide it on mouseover/mouseout. I posted a different way to do it as well if your method is not working for you.
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 8)
.attr("y", ".31em")
.attr("opacity", 1)
.text(function(d){
if (d.value >= 0.35){
return d.name
}
});
function mouseout(d) { text.style("opacity", 0); }
function mouseover(d) { text.style("opacity", 1);
I have a problem when there is two graph on same page, the first graph has a normal size but the second which is populated by fixed data is anormaly large. The two graph are superimposed. Strange thing, if I use the code of the second graph, it works on my local website test.
This is the code of the second graph :
// http://blog.thomsonreuters.com/index.php/mobile-patent-suits-graphic-of-the-day/
var links = [
{"source":"TEST111","target":"TEST222","level":"1","life":"1","test":"1","type":"licensing"},
{"source":"TEST222","target":"TEST3333","level":"2","life":"2","test":"2","type":"licensing"},
{"source":"TEST3333","target":"TEST4444","level":"3","life":"3","test":"3","type":"licensing"}
];
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, level:link.level, life:link.life});
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target, level:link.level, life:link.life});
});
var width = 960,
height = 500;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(200)
.charge(-400)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// Per-type markers, as they don't inherit styles.
svg.append("defs").selectAll("marker")
.data(["suit", "licensing", "resolved"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 20)
.attr("markerHeight", 20)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 20)
.call(force.drag)
.style("fill","red")
.on("click", click);
function click(d){
}
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return d.name; });
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", linkArc);
circle.attr("transform", transform);
text.attr("transform", transform)
}
function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}
Also, on the Pluker, the two graph are bunk but it's not the problem (It works in local). You can delete the data load if you want (line 34). This is an online Plunker to see the problem : https://plnkr.co/edit/ewoi6wao97tXAKr1QxIm?p=preview
Thanks.
Basically your problem was you were filling the path rather than just giving it a stroke.
So when you create the path just add the following :
.style("fill","none").style("stroke","red")
So now it looks like :
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.style("fill","none").style("stroke","red")
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
Updated plnkr : https://plnkr.co/edit/JgHwC4zyolj0hsg8ib4w?p=preview
I would like to label multiple edges between two nodes in a d3 force diagram. By modifying this example (http://jsfiddle.net/7HZcR/3/) I have two edges displayed separately but the labels associated to the edges overlapping on one edge rather than sitting on their own line. I can't work out why that would be. Any ideas how I could fix this? Here is the relevant part of my code:
d3.csv("GHT_1_A.csv", function(error, links) {
//sort links by source, then target
links.sort(function(a,b) {
if (a.source > b.source) {return 1;}
else if (a.source < b.source) {return -1;}
else {
if (a.target > b.target) {return 1;}
if (a.target < b.target) {return -1;}
else {return 0;}
}
});
//any links with duplicate source and target get an incremented 'linknum'
for (var i=0; i<links.length; i++) {
if (i != 0 &&
links[i].source == links[i-1].source &&
links[i].target == links[i-1].target) {
links[i].linknum = links[i-1].linknum + 1;
}
else {links[i].linknum = 1;};
};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target});
});
force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(200)
.charge(-1000)
.on("tick", tick)
.start();
svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// build the arrow.
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
var link = svg.append("svg:g").selectAll("g.link")
.data(force.links())
.enter().append('g')
var linkPath = link.append("svg:path")
.attr('class', 'link')
.attr("marker-end", "url(#end)");
var textPath = link.append("svg:path")
.attr("id", function(d) { return d.source.index + "_" + d.target.index; })
.attr("class", "textpath");
var path_label = svg.append("svg:g").selectAll(".path_label")
.data(force.links())
.enter().append("svg:text")
.attr("class", "path_label")
.append("svg:textPath")
.attr("startOffset", "50%")
.attr("text-anchor", "middle")
.attr("xlink:href", function(d) { return "#" + d.source.index + "_" + d.target.index; })
.style("fill", "#000")
.style("font-family", "Arial")
.text(function(d) { return d.linkQ; });
function arcPath(leftHand, d) {
var start = leftHand ? d.source : d.target,
end = leftHand ? d.target : d.source,
dx = end.x - start.x,
dy = end.y - start.y,
dr = 100/d.linknum;
//dr = Math.sqrt(dx * dx + dy * dy),
sweep = leftHand ? 0 : 1;
return "M" + start.x + "," + start.y + "A" + dr + "," + dr + " 0 0," + sweep + " " + end.x + "," + end.y;
}
var circle = svg.append("svg:g").selectAll("circle")
.data(force.nodes())
.enter().append("svg:circle")
.attr("r", 6)
.call(force.drag);
var text = svg.append("svg:g").selectAll("g")
.data(force.nodes())
.enter().append("svg:g");
// A copy of the text with a thick white stroke for legibility.
text.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.attr("class", "shadow")
.text(function(d) { return d.name; });
text.append("svg:text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return d.name; });
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
linkPath.attr("d", function(d) {
return arcPath(false, d);
});
textPath.attr("d", function(d) {
return arcPath(d.source.x < d.target.x, d);
});
circle.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
text.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
};
});
I am creating a navigation flow diagram using D3.js. Basically, it looks alright so far, however, when I change things to include a title/tooltip on link between nodes (to reflect how many people clicked from one page to another), I am unable to do it -
var data = [{"value":"1","target":"SearchActivity","source":"CommonFriendActivity"},{"value":"1","target":"SearchActivity","source":"InviteActivity"},{"value":"1","target":"SearchActivity","source":"LikeDetailActivity"},{"value":"1","target":"Exit","source":"LoginScreenActivity"},{"value":"1","target":"InviteActivity","source":"LoginScreenActivity"},{"value":"1.5","target":"SearchActivity","source":"LoginScreenActivity"},{"value":"1","target":"Exit","source":"SearchActivity"},{"value":"1","target":"InviteActivity","source":"SearchActivity"},{"value":"1","target":"PictureActivity","source":"SearchActivity"},{"value":"1","target":"UserDetailActivity","source":"SearchActivity"},{"value":"1","target":"CommonFriendActivity","source":"UserDetailActivity"},{"value":"1","target":"Exit","source":"UserDetailActivity"},{"value":"1","target":"LikeDetailActivity","source":"UserDetailActivity"},{"value":"1","target":"SearchActivity","source":"UserDetailActivity"}];
var nodes = {};
// Compute the distinct nodes from the links.
data.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source, tooltip: link.value});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target, tooltip: link.value});
link.value = +link.value;
});
var width = 600,
height = 500;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(data)
.size([width, height])
.linkDistance(200)
.charge(-300)
.on("tick", tick)
.start();
// Set the range
var v = d3.scale.linear().range([0, 100]);
// Scale the range of the data
v.domain([0, d3.max(data, function(d) { return d.value; })]);
// asign a type per value to encode opacity
data.forEach(function(link) {
if (v(link.value) <= 25) {
link.type = "twofive";
} else if (v(link.value) <= 50 && v(link.value) > 25) {
link.type = "fivezero";
} else if (v(link.value) <= 75 && v(link.value) > 50) {
link.type = "sevenfive";
} else if (v(link.value) <= 100 && v(link.value) > 75) {
link.type = "onezerozero";
}
});
var svg = d3.select("#phone_layout").append("svg")
.attr("width", width)
.attr("height", height);
// build the arrow.
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
// add the links and the arrows
var path = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", "url(#end)");
// define the nodes
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.on("click", click)
.on("dblclick", dblclick)
.call(force.drag);
// add the nodes
node.append("circle")
.attr("r", 10)
.style("fill", "steelblue")
.style("stroke", "lightsteelblue")
.style("stroke-width", ".5px")
.style("font", "20px sans-serif");
// add the text
node.append("text")
.attr("x", 15)
.attr("dy", ".9em")
.text(function(d) { return d.name; });
// add the curvy lines
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
}
Here is the jsfiddle - http://jsfiddle.net/uMceL/7/
PS: Links are also not looking properly but they seem fine on webpage when I use same code.
Any help/pointer will be greatly appreciated