Create radial network diagram with non-hierarchical data in D3.js - javascript
I am trying to create a diagram similar to this one in D3.js:
http://mbostock.github.io/d3/talk/20111116/bundle.html
This example uses hierarchical edge bundling. However, my data is not hierarchical in nature and I want to represent a relatively simple network structure. I have a bunch of nodes divided into groups, and connected through a simple connectivity matrix. I am able to generate a force-directed network diagram in D3.js similar to this:
http://bl.ocks.org/mbostock/4062045
var width = 500,
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);
var graph = getData();
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("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag);
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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
function getData() {
return {
"nodes":[
{"name":"Myriel","group":1},
{"name":"Napoleon","group":1},
{"name":"Mlle.Baptistine","group":1},
{"name":"Mme.Magloire","group":1},
{"name":"CountessdeLo","group":1},
{"name":"Geborand","group":1},
{"name":"Champtercier","group":1},
{"name":"Cravatte","group":1},
{"name":"Count","group":1},
{"name":"OldMan","group":1},
{"name":"Labarre","group":2},
{"name":"Valjean","group":2},
{"name":"Marguerite","group":3},
{"name":"Mme.deR","group":2},
{"name":"Isabeau","group":2},
{"name":"Gervais","group":2},
{"name":"Tholomyes","group":3},
{"name":"Listolier","group":3},
{"name":"Fameuil","group":3},
{"name":"Blacheville","group":3},
{"name":"Favourite","group":3},
{"name":"Dahlia","group":3},
{"name":"Zephine","group":3},
{"name":"Fantine","group":3},
{"name":"Mme.Thenardier","group":4},
{"name":"Thenardier","group":4},
{"name":"Cosette","group":5},
{"name":"Javert","group":4},
{"name":"Fauchelevent","group":0},
{"name":"Bamatabois","group":2},
{"name":"Perpetue","group":3},
{"name":"Simplice","group":2},
{"name":"Scaufflaire","group":2},
{"name":"Woman1","group":2},
{"name":"Judge","group":2},
{"name":"Champmathieu","group":2},
{"name":"Brevet","group":2},
{"name":"Chenildieu","group":2},
{"name":"Cochepaille","group":2},
{"name":"Pontmercy","group":4},
{"name":"Boulatruelle","group":6},
{"name":"Eponine","group":4},
{"name":"Anzelma","group":4},
{"name":"Woman2","group":5},
{"name":"MotherInnocent","group":0},
{"name":"Gribier","group":0},
{"name":"Jondrette","group":7},
{"name":"Mme.Burgon","group":7},
{"name":"Gavroche","group":8},
{"name":"Gillenormand","group":5},
{"name":"Magnon","group":5},
{"name":"Mlle.Gillenormand","group":5},
{"name":"Mme.Pontmercy","group":5},
{"name":"Mlle.Vaubois","group":5},
{"name":"Lt.Gillenormand","group":5},
{"name":"Marius","group":8},
{"name":"BaronessT","group":5},
{"name":"Mabeuf","group":8},
{"name":"Enjolras","group":8},
{"name":"Combeferre","group":8},
{"name":"Prouvaire","group":8},
{"name":"Feuilly","group":8},
{"name":"Courfeyrac","group":8},
{"name":"Bahorel","group":8},
{"name":"Bossuet","group":8},
{"name":"Joly","group":8},
{"name":"Grantaire","group":8},
{"name":"MotherPlutarch","group":9},
{"name":"Gueulemer","group":4},
{"name":"Babet","group":4},
{"name":"Claquesous","group":4},
{"name":"Montparnasse","group":4},
{"name":"Toussaint","group":5},
{"name":"Child1","group":10},
{"name":"Child2","group":10},
{"name":"Brujon","group":4},
{"name":"Mme.Hucheloup","group":8}
],
"links":[
{"source":1,"target":0,"value":1},
{"source":2,"target":0,"value":8},
{"source":3,"target":0,"value":10},
{"source":3,"target":2,"value":6},
{"source":4,"target":0,"value":1},
{"source":5,"target":0,"value":1},
{"source":6,"target":0,"value":1},
{"source":7,"target":0,"value":1},
{"source":8,"target":0,"value":2},
{"source":9,"target":0,"value":1},
{"source":11,"target":10,"value":1},
{"source":11,"target":3,"value":3},
{"source":11,"target":2,"value":3},
{"source":11,"target":0,"value":5},
{"source":12,"target":11,"value":1},
{"source":13,"target":11,"value":1},
{"source":14,"target":11,"value":1},
{"source":15,"target":11,"value":1},
{"source":17,"target":16,"value":4},
{"source":18,"target":16,"value":4},
{"source":18,"target":17,"value":4},
{"source":19,"target":16,"value":4},
{"source":19,"target":17,"value":4},
{"source":19,"target":18,"value":4},
{"source":20,"target":16,"value":3},
{"source":20,"target":17,"value":3},
{"source":20,"target":18,"value":3},
{"source":20,"target":19,"value":4},
{"source":21,"target":16,"value":3},
{"source":21,"target":17,"value":3},
{"source":21,"target":18,"value":3},
{"source":21,"target":19,"value":3},
{"source":21,"target":20,"value":5},
{"source":22,"target":16,"value":3},
{"source":22,"target":17,"value":3},
{"source":22,"target":18,"value":3},
{"source":22,"target":19,"value":3},
{"source":22,"target":20,"value":4},
{"source":22,"target":21,"value":4},
{"source":23,"target":16,"value":3},
{"source":23,"target":17,"value":3},
{"source":23,"target":18,"value":3},
{"source":23,"target":19,"value":3},
{"source":23,"target":20,"value":4},
{"source":23,"target":21,"value":4},
{"source":23,"target":22,"value":4},
{"source":23,"target":12,"value":2},
{"source":23,"target":11,"value":9},
{"source":24,"target":23,"value":2},
{"source":24,"target":11,"value":7},
{"source":25,"target":24,"value":13},
{"source":25,"target":23,"value":1},
{"source":25,"target":11,"value":12},
{"source":26,"target":24,"value":4},
{"source":26,"target":11,"value":31},
{"source":26,"target":16,"value":1},
{"source":26,"target":25,"value":1},
{"source":27,"target":11,"value":17},
{"source":27,"target":23,"value":5},
{"source":27,"target":25,"value":5},
{"source":27,"target":24,"value":1},
{"source":27,"target":26,"value":1},
{"source":28,"target":11,"value":8},
{"source":28,"target":27,"value":1},
{"source":29,"target":23,"value":1},
{"source":29,"target":27,"value":1},
{"source":29,"target":11,"value":2},
{"source":30,"target":23,"value":1},
{"source":31,"target":30,"value":2},
{"source":31,"target":11,"value":3},
{"source":31,"target":23,"value":2},
{"source":31,"target":27,"value":1},
{"source":32,"target":11,"value":1},
{"source":33,"target":11,"value":2},
{"source":33,"target":27,"value":1},
{"source":34,"target":11,"value":3},
{"source":34,"target":29,"value":2},
{"source":35,"target":11,"value":3},
{"source":35,"target":34,"value":3},
{"source":35,"target":29,"value":2},
{"source":36,"target":34,"value":2},
{"source":36,"target":35,"value":2},
{"source":36,"target":11,"value":2},
{"source":36,"target":29,"value":1},
{"source":37,"target":34,"value":2},
{"source":37,"target":35,"value":2},
{"source":37,"target":36,"value":2},
{"source":37,"target":11,"value":2},
{"source":37,"target":29,"value":1},
{"source":38,"target":34,"value":2},
{"source":38,"target":35,"value":2},
{"source":38,"target":36,"value":2},
{"source":38,"target":37,"value":2},
{"source":38,"target":11,"value":2},
{"source":38,"target":29,"value":1},
{"source":39,"target":25,"value":1},
{"source":40,"target":25,"value":1},
{"source":41,"target":24,"value":2},
{"source":41,"target":25,"value":3},
{"source":42,"target":41,"value":2},
{"source":42,"target":25,"value":2},
{"source":42,"target":24,"value":1},
{"source":43,"target":11,"value":3},
{"source":43,"target":26,"value":1},
{"source":43,"target":27,"value":1},
{"source":44,"target":28,"value":3},
{"source":44,"target":11,"value":1},
{"source":45,"target":28,"value":2},
{"source":47,"target":46,"value":1},
{"source":48,"target":47,"value":2},
{"source":48,"target":25,"value":1},
{"source":48,"target":27,"value":1},
{"source":48,"target":11,"value":1},
{"source":49,"target":26,"value":3},
{"source":49,"target":11,"value":2},
{"source":50,"target":49,"value":1},
{"source":50,"target":24,"value":1},
{"source":51,"target":49,"value":9},
{"source":51,"target":26,"value":2},
{"source":51,"target":11,"value":2},
{"source":52,"target":51,"value":1},
{"source":52,"target":39,"value":1},
{"source":53,"target":51,"value":1},
{"source":54,"target":51,"value":2},
{"source":54,"target":49,"value":1},
{"source":54,"target":26,"value":1},
{"source":55,"target":51,"value":6},
{"source":55,"target":49,"value":12},
{"source":55,"target":39,"value":1},
{"source":55,"target":54,"value":1},
{"source":55,"target":26,"value":21},
{"source":55,"target":11,"value":19},
{"source":55,"target":16,"value":1},
{"source":55,"target":25,"value":2},
{"source":55,"target":41,"value":5},
{"source":55,"target":48,"value":4},
{"source":56,"target":49,"value":1},
{"source":56,"target":55,"value":1},
{"source":57,"target":55,"value":1},
{"source":57,"target":41,"value":1},
{"source":57,"target":48,"value":1},
{"source":58,"target":55,"value":7},
{"source":58,"target":48,"value":7},
{"source":58,"target":27,"value":6},
{"source":58,"target":57,"value":1},
{"source":58,"target":11,"value":4},
{"source":59,"target":58,"value":15},
{"source":59,"target":55,"value":5},
{"source":59,"target":48,"value":6},
{"source":59,"target":57,"value":2},
{"source":60,"target":48,"value":1},
{"source":60,"target":58,"value":4},
{"source":60,"target":59,"value":2},
{"source":61,"target":48,"value":2},
{"source":61,"target":58,"value":6},
{"source":61,"target":60,"value":2},
{"source":61,"target":59,"value":5},
{"source":61,"target":57,"value":1},
{"source":61,"target":55,"value":1},
{"source":62,"target":55,"value":9},
{"source":62,"target":58,"value":17},
{"source":62,"target":59,"value":13},
{"source":62,"target":48,"value":7},
{"source":62,"target":57,"value":2},
{"source":62,"target":41,"value":1},
{"source":62,"target":61,"value":6},
{"source":62,"target":60,"value":3},
{"source":63,"target":59,"value":5},
{"source":63,"target":48,"value":5},
{"source":63,"target":62,"value":6},
{"source":63,"target":57,"value":2},
{"source":63,"target":58,"value":4},
{"source":63,"target":61,"value":3},
{"source":63,"target":60,"value":2},
{"source":63,"target":55,"value":1},
{"source":64,"target":55,"value":5},
{"source":64,"target":62,"value":12},
{"source":64,"target":48,"value":5},
{"source":64,"target":63,"value":4},
{"source":64,"target":58,"value":10},
{"source":64,"target":61,"value":6},
{"source":64,"target":60,"value":2},
{"source":64,"target":59,"value":9},
{"source":64,"target":57,"value":1},
{"source":64,"target":11,"value":1},
{"source":65,"target":63,"value":5},
{"source":65,"target":64,"value":7},
{"source":65,"target":48,"value":3},
{"source":65,"target":62,"value":5},
{"source":65,"target":58,"value":5},
{"source":65,"target":61,"value":5},
{"source":65,"target":60,"value":2},
{"source":65,"target":59,"value":5},
{"source":65,"target":57,"value":1},
{"source":65,"target":55,"value":2},
{"source":66,"target":64,"value":3},
{"source":66,"target":58,"value":3},
{"source":66,"target":59,"value":1},
{"source":66,"target":62,"value":2},
{"source":66,"target":65,"value":2},
{"source":66,"target":48,"value":1},
{"source":66,"target":63,"value":1},
{"source":66,"target":61,"value":1},
{"source":66,"target":60,"value":1},
{"source":67,"target":57,"value":3},
{"source":68,"target":25,"value":5},
{"source":68,"target":11,"value":1},
{"source":68,"target":24,"value":1},
{"source":68,"target":27,"value":1},
{"source":68,"target":48,"value":1},
{"source":68,"target":41,"value":1},
{"source":69,"target":25,"value":6},
{"source":69,"target":68,"value":6},
{"source":69,"target":11,"value":1},
{"source":69,"target":24,"value":1},
{"source":69,"target":27,"value":2},
{"source":69,"target":48,"value":1},
{"source":69,"target":41,"value":1},
{"source":70,"target":25,"value":4},
{"source":70,"target":69,"value":4},
{"source":70,"target":68,"value":4},
{"source":70,"target":11,"value":1},
{"source":70,"target":24,"value":1},
{"source":70,"target":27,"value":1},
{"source":70,"target":41,"value":1},
{"source":70,"target":58,"value":1},
{"source":71,"target":27,"value":1},
{"source":71,"target":69,"value":2},
{"source":71,"target":68,"value":2},
{"source":71,"target":70,"value":2},
{"source":71,"target":11,"value":1},
{"source":71,"target":48,"value":1},
{"source":71,"target":41,"value":1},
{"source":71,"target":25,"value":1},
{"source":72,"target":26,"value":2},
{"source":72,"target":27,"value":1},
{"source":72,"target":11,"value":1},
{"source":73,"target":48,"value":2},
{"source":74,"target":48,"value":2},
{"source":74,"target":73,"value":3},
{"source":75,"target":69,"value":3},
{"source":75,"target":68,"value":3},
{"source":75,"target":25,"value":3},
{"source":75,"target":48,"value":1},
{"source":75,"target":41,"value":1},
{"source":75,"target":70,"value":1},
{"source":75,"target":71,"value":1},
{"source":76,"target":64,"value":1},
{"source":76,"target":65,"value":1},
{"source":76,"target":66,"value":1},
{"source":76,"target":63,"value":1},
{"source":76,"target":62,"value":1},
{"source":76,"target":48,"value":1},
{"source":76,"target":58,"value":1}
]
}
}
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
However, I can't figure out how to generate the radial graph above when the structure is not hierarchical. In the example given here
https://gist.github.com/mbostock/7607999
they use the bundle() and cluster.nodes() functions which require a hierarchical data structure. Can I use the same json data structure that I use for the force-directed graph for this type of radial graph? If yes, how?
EDIT: Here is a (non-working) JSFiddle http://jsfiddle.net/12sb8jxg/
I added
nested = d3.nest()
.key(function (d) {
return d.group;
})
.entries(graph.nodes);
but
cluster.nodes(nested)
still doesn't append the .x, .y, .parent etc. necessary for the bundle function to work.
Related
Unable to display text label with D3 force layout [duplicate]
<!DOCTYPE html> <html> <meta charset="utf-8"> <style> .node { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: .6; } </style> <body> </body> <script src="d3.v3.min.js"></script> <script> 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); d3.json("data.json", function(error, graph) { 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("circle") .attr("class", "node") .attr("r", function(d) {return d.r;}) .style("fill", function(d) { return color(d.group); }) node.append("title") .text(function(d) { return d.name; }); node.append("text") .text("A"); 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; }); }); }); </script> </html> The code above is using D3js to draw a Force-directed graph drawing from some data, and I just want to place some text on the circle so I use node.append("text") you can see it above. But however when add it it does not work, there is still not text on the circle so I wonder how could it be????
SVG does not allow a text element inside an circle element. You should put the circle and the text element inside a common g. Try something like this (not tested): var node = svg.selectAll(".node") .data(graph.nodes).enter().append('g').classed('node', true); node.append("circle") .attr("r", function(d) {return d.r;}) .style("fill", function(d) { return color(d.group); }) .append("title") .text(function(d) { return d.name; }); node.append("text") .text("A"); And then instead of setting cx and cy on nodes, set the transform property on the g.node: force.on("tick", function() { // ... node.attr("transform", function(d) { return 'translate(' + [d.x, d.y] + ')'; }) });
What settings to choose for force directed graph layout in d3
I am visualising a graph of relationships between people with d3. All nodes are connected to a single central node, and then have relationships with other nodes. I've got the basics working, but I'm struggling to work out how to set the parameters like linkDistance, linkStrength, gravity and charge. Each edge has a rating from 0-5, which I'm then using to compute linkDistance using an inverse linear scale. The main problem is getting the relationships to be represented properly. The central node seems to be much further away than any other node, even though it has the shortest linkDistance with some other nodes. I'm also finding it difficult to find the right settings to get nodes to be an appropriate distance apart. var h = 500, w = 1000 var color = d3.scale.category20() var svg = d3.select("body") .append("svg") .attr({ height: h, width: w }) queue() .defer(d3.json, "nodes.json") .defer(d3.json, "links.json") .await(makeDiag); function makeDiag(error, nodes, links, table) { links = links.filter(function(link) { if (link.value) return true }) var scale = d3.scale.linear().domain([0,5]).range([20,0]) var edges = svg.selectAll("line") .data(links) .enter() .append("line") .style("stroke", "#ccc") .style("stroke-width", 1) /* Establish the dynamic force behavor of the nodes */ var force = d3.layout.force() .nodes(nodes) .links(links) .size([w,h]) .linkDistance(function(d) { if (d.value == 0) return null console.log('in',d.value,'out',scale(d.value)) return scale(d.value) }) .charge(-1400) .start(); /* Draw the edges/links between the nodes */ var texts = svg.selectAll("text") .data(nodes) .enter() .append("text") .attr("fill", "black") .attr("font-family", "sans-serif") .attr("font-size", "10px") .text(function(d) { return d.name; }); var nodes = svg.selectAll("circle") .data(nodes) .enter() .append("circle") .attr("r", function(d,i) { return 20 }) .attr("opacity", 0.7) .style("fill", function(d,i) { return color(i); }) .call(force.drag); /* Draw the nodes themselves */ /* Run the Force effect */ force.on("tick", function() { edges.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; }); nodes.attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }) texts.attr("transform", function(d) { return "translate(" + (d.x - 12.5) + "," + (d.y + 5) + ")"; }); }); }; jsFiddle full screen result
D3.js force-directed graph from a JSON data file - not showing any nodes
I am a newbie in D3JS and I was trying to do a similar example to this one : http://bl.ocks.org/mbostock/4062045 I have generated this JSON file output.json and I try to get it running but nothing shows up! {"nodes":[{"name":"Hiroyasu Nakata","group":1},{"name":"Kazuo Satoh","group":1},{"name":"Tyuzi Ohyama","group":1},{"name":"Yasufumi Fujiwara","group":1},{"name":"Youichi Nonogaki","group":1},{"name":"Yoshikazu Takeda","group":1},{"name":"N. Tamari","group":2},{"name":"S. H. Wemple","group":3},{"name":"Kun-Jing Lee","group":4},{"name":"Z. C. Huang","group":4},{"name":"J. C. Chen","group":4},{"name":"L. Cai","group":5},{"name":"S. Han","group":5},{"name":"G. May","group":5},{"name":"S. Kamra","group":5},{"name":"T. Krygowski","group":5},{"name":"A. Rohatgi","group":5},{"name":"Stephen Miller","group":7},{"name":"Paul H. Holloway","group":7}],"links":[{"source":1,"target":2},{"source":1,"target":3},{"source":1,"target":4},{"source":1,"target":5},{"source":1,"target":6},{"source":2,"target":3},{"source":2,"target":4},{"source":2,"target":5},{"source":2,"target":6},{"source":3,"target":4},{"source":3,"target":5},{"source":3,"target":6},{"source":4,"target":5},{"source":4,"target":6},{"source":5,"target":6},{"source":9,"target":10},{"source":9,"target":11},{"source":10,"target":11},{"source":12,"target":13},{"source":12,"target":14},{"source":12,"target":15},{"source":12,"target":16},{"source":12,"target":17},{"source":13,"target":14},{"source":13,"target":15},{"source":13,"target":16},{"source":13,"target":17},{"source":14,"target":15},{"source":14,"target":16},{"source":14,"target":17},{"source":15,"target":16},{"source":15,"target":17},{"source":16,"target":17},{"source":18,"target":19}]} This is the HTML file : <!DOCTYPE html> <meta charset="utf-8"> <style> .node { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: .6; } </style> <body> <script src="http://d3js.org/d3.v3.min.js"></script> <script> 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); d3.json("output.json", function(error, graph) { 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("circle") .attr("class", "node") .attr("r", 5) .style("fill", function(d) { return color(d.group); }) .call(force.drag); 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("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); }); }); </script> What did I do wrong? And how can I fix it? Thanks!
How to display a text when mouseover a node in D3 force layout
I am trying to display the text when I move the mouse over a node in Force-Directed Graph in D3.js. My problem is that when I move the mouse over any node, all the texts of these nodes are displayed. Here is my code: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> .node { stroke: #fff; stroke-width: 1.5px; } .nodeDetail { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: .6; } node .text { font: 12px sans-serif; pointer-events: none; } </style> </head> <body> <script src="http://d3js.org/d3.v3.js"></script> <script src="d3/d3.v3.min.js charset=UTF-8"></script> <script> var graph = { "nodes":[ {"name":"Myriel","group":1}, {"name":"Napoleon","group":1}, {"name":"Mlle.Baptistine","group":1}, {"name":"Mme.Magloire","group":1}, {"name":"CountessdeLo","group":1} ], "links":[ {"source":1,"target":0,"value":1}, {"source":2,"target":0,"value":8}, {"source":3,"target":0,"value":10}, {"source":3,"target":2,"value":6}, {"source":4,"target":0,"value":1} ] }; 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); var drawGraph = function(graph) { 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 gnodes = svg.selectAll('g.gnode')//('g.gnode') .data(graph.nodes) .enter() .append('g') .classed('gnode', true); var node = gnodes.append("circle") .attr("class", "node") .attr("r", 5) .style("fill", function(d) { return color(d.group); }) .on("mouseover", function(d) { d3.select(this).transition() .duration(750) .attr("r", 15); return labels.style("visibility", "visible"); }) .on("mouseout", function() { d3.select(this).transition() .duration(750) .attr("r", 5); return labels.style("visibility", "hidden");//}) }) .call(force.drag); var labels = gnodes.append("text") .text(function(d) { return d.name; }) .style("visibility", "hidden"); /*gnodes.append("text") .text(function(d) { return d.name; }) .style("visibility", "hidden");*/ 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; }); gnodes.attr("transform", function(d) { return 'translate(' + [d.x, d.y] + ')'; }); }); }; drawGraph(graph); </script> </body> </html> I tried to do the following codes but it did not work neither: .on("mouseover", function(d) { d3.select(this).transition() .duration(750) .attr("r", 15); d3.select(this).append(text) .style("visibility", "visible"); }) How can I display the text that is related to a particular node when I move the mouse over that node? Could anyone please help me solve this problem. Thank you in advance.
This should help: .on("mouseover", function(d) { d3.select(labels[0][d.index]).style("visibility","visible") }) .on("mouseout", function(d) { d3.select(labels[0][d.index]).style("visibility","hidden") })
Learning d3 myself here - also thanks very much to juvian I find a more transparent way of coding this would be to say .on("mouseover", function(d) { d3.select(this).select("text").style("visibility", "visible") }) which selects the object you hover over (a group), selects the text inside it and changes the style to visible. This also avoids the need to make a labels variable which gets a bit messy with the array indexing.
forced directed graphs using d3.js
I have started using the d3.js library for making forced directed graphs. Could somebody tell me why this code also mentioned in this site does not work? index.html .node { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: .6; } </style> <body> <script src="http://d3js.org/d3.v3.min.js"></script> <script> 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); d3.json("miserables.json", function(error, graph) { 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("circle") .attr("class", "node") .attr("r", 5) .style("fill", function(d) { return color(d.group); }) .call(force.drag); 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("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); }); }); </script> miserables.json { "nodes":[ {"name":"Myriel","group":1}, {"name":"Napoleon","group":1}, {"name":"Mlle.Baptistine","group":1}, {"name":"Mme.Magloire","group":1}, {"name":"CountessdeLo","group":1}, {"name":"Geborand","group":1}, {"name":"Champtercier","group":1}, {"name":"Cravatte","group":1}, {"name":"Count","group":1}, {"name":"OldMan","group":1}, {"name":"Labarre","group":2}, {"name":"Valjean","group":2}, {"name":"Marguerite","group":3}, {"name":"Mme.deR","group":2}, {"name":"Isabeau","group":2}, {"name":"Gervais","group":2}, {"name":"Tholomyes","group":3}, {"name":"Listolier","group":3}, {"name":"Fameuil","group":3}, {"name":"Blacheville","group":3}, {"name":"Favourite","group":3}, {"name":"Dahlia","group":3}, {"name":"Zephine","group":3}, {"name":"Fantine","group":3}, {"name":"Mme.Thenardier","group":4}, {"name":"Thenardier","group":4}, {"name":"Cosette","group":5}, {"name":"Javert","group":4}, {"name":"Fauchelevent","group":0}, {"name":"Bamatabois","group":2}, {"name":"Perpetue","group":3}, {"name":"Simplice","group":2}, {"name":"Scaufflaire","group":2}, {"name":"Woman1","group":2}, {"name":"Judge","group":2}, {"name":"Champmathieu","group":2}, {"name":"Brevet","group":2}, {"name":"Chenildieu","group":2}, {"name":"Cochepaille","group":2}, {"name":"Pontmercy","group":4}, {"name":"Boulatruelle","group":6}, {"name":"Eponine","group":4}, {"name":"Anzelma","group":4}, {"name":"Woman2","group":5}, {"name":"MotherInnocent","group":0}, {"name":"Gribier","group":0}, {"name":"Jondrette","group":7}, {"name":"Mme.Burgon","group":7}, {"name":"Gavroche","group":8}, {"name":"Gillenormand","group":5}, {"name":"Magnon","group":5}, {"name":"Mlle.Gillenormand","group":5}, {"name":"Mme.Pontmercy","group":5}, {"name":"Mlle.Vaubois","group":5}, {"name":"Lt.Gillenormand","group":5}, {"name":"Marius","group":8}, {"name":"BaronessT","group":5}, {"name":"Mabeuf","group":8}, {"name":"Enjolras","group":8}, {"name":"Combeferre","group":8}, {"name":"Prouvaire","group":8}, {"name":"Feuilly","group":8}, {"name":"Courfeyrac","group":8}, {"name":"Bahorel","group":8}, {"name":"Bossuet","group":8}, {"name":"Joly","group":8}, {"name":"Grantaire","group":8}, {"name":"MotherPlutarch","group":9}, {"name":"Gueulemer","group":4}, {"name":"Babet","group":4}, {"name":"Claquesous","group":4}, {"name":"Montparnasse","group":4}, {"name":"Toussaint","group":5}, {"name":"Child1","group":10}, {"name":"Child2","group":10}, {"name":"Brujon","group":4}, {"name":"Mme.Hucheloup","group":8} ], "links":[ {"source":1,"target":0,"value":1}, {"source":2,"target":0,"value":8}, {"source":3,"target":0,"value":10}, {"source":3,"target":2,"value":6}, {"source":4,"target":0,"value":1}, {"source":5,"target":0,"value":1}, {"source":6,"target":0,"value":1}, {"source":7,"target":0,"value":1}, {"source":8,"target":0,"value":2}, {"source":9,"target":0,"value":1}, {"source":11,"target":10,"value":1}, {"source":11,"target":3,"value":3}, {"source":11,"target":2,"value":3}, {"source":11,"target":0,"value":5}, {"source":12,"target":11,"value":1}, {"source":13,"target":11,"value":1}, {"source":14,"target":11,"value":1}, {"source":15,"target":11,"value":1}, {"source":17,"target":16,"value":4}, {"source":18,"target":16,"value":4}, {"source":18,"target":17,"value":4}, {"source":19,"target":16,"value":4}, {"source":19,"target":17,"value":4}, {"source":19,"target":18,"value":4}, {"source":20,"target":16,"value":3}, {"source":20,"target":17,"value":3}, {"source":20,"target":18,"value":3}, {"source":20,"target":19,"value":4}, {"source":21,"target":16,"value":3}, {"source":21,"target":17,"value":3}, {"source":21,"target":18,"value":3}, {"source":21,"target":19,"value":3}, {"source":21,"target":20,"value":5}, {"source":22,"target":16,"value":3}, {"source":22,"target":17,"value":3}, {"source":22,"target":18,"value":3}, {"source":22,"target":19,"value":3}, {"source":22,"target":20,"value":4}, {"source":22,"target":21,"value":4}, {"source":23,"target":16,"value":3}, {"source":23,"target":17,"value":3}, {"source":23,"target":18,"value":3}, {"source":23,"target":19,"value":3}, {"source":23,"target":20,"value":4}, {"source":23,"target":21,"value":4}, {"source":23,"target":22,"value":4}, {"source":23,"target":12,"value":2}, {"source":23,"target":11,"value":9}, {"source":24,"target":23,"value":2}, {"source":24,"target":11,"value":7}, {"source":25,"target":24,"value":13}, {"source":25,"target":23,"value":1}, {"source":25,"target":11,"value":12}, {"source":26,"target":24,"value":4}, {"source":26,"target":11,"value":31}, {"source":26,"target":16,"value":1}, {"source":26,"target":25,"value":1}, {"source":27,"target":11,"value":17}, {"source":27,"target":23,"value":5}, {"source":27,"target":25,"value":5}, {"source":27,"target":24,"value":1}, {"source":27,"target":26,"value":1}, {"source":28,"target":11,"value":8}, {"source":28,"target":27,"value":1}, {"source":29,"target":23,"value":1}, {"source":29,"target":27,"value":1}, {"source":29,"target":11,"value":2}, {"source":30,"target":23,"value":1}, {"source":31,"target":30,"value":2}, {"source":31,"target":11,"value":3}, {"source":31,"target":23,"value":2}, {"source":31,"target":27,"value":1}, {"source":32,"target":11,"value":1}, {"source":33,"target":11,"value":2}, {"source":33,"target":27,"value":1}, {"source":34,"target":11,"value":3}, {"source":34,"target":29,"value":2}, {"source":35,"target":11,"value":3}, {"source":35,"target":34,"value":3}, {"source":35,"target":29,"value":2}, {"source":36,"target":34,"value":2}, {"source":36,"target":35,"value":2}, {"source":36,"target":11,"value":2}, {"source":36,"target":29,"value":1}, {"source":37,"target":34,"value":2}, {"source":37,"target":35,"value":2}, {"source":37,"target":36,"value":2}, {"source":37,"target":11,"value":2}, {"source":37,"target":29,"value":1}, {"source":38,"target":34,"value":2}, {"source":38,"target":35,"value":2}, {"source":38,"target":36,"value":2}, {"source":38,"target":37,"value":2}, {"source":38,"target":11,"value":2}, {"source":38,"target":29,"value":1}, {"source":39,"target":25,"value":1}, {"source":40,"target":25,"value":1}, {"source":41,"target":24,"value":2}, {"source":41,"target":25,"value":3}, {"source":42,"target":41,"value":2}, {"source":42,"target":25,"value":2}, {"source":42,"target":24,"value":1}, {"source":43,"target":11,"value":3}, {"source":43,"target":26,"value":1}, {"source":43,"target":27,"value":1}, {"source":44,"target":28,"value":3}, {"source":44,"target":11,"value":1}, {"source":45,"target":28,"value":2}, {"source":47,"target":46,"value":1}, {"source":48,"target":47,"value":2}, {"source":48,"target":25,"value":1}, {"source":48,"target":27,"value":1}, {"source":48,"target":11,"value":1}, {"source":49,"target":26,"value":3}, {"source":49,"target":11,"value":2}, {"source":50,"target":49,"value":1}, {"source":50,"target":24,"value":1}, {"source":51,"target":49,"value":9}, {"source":51,"target":26,"value":2}, {"source":51,"target":11,"value":2}, {"source":52,"target":51,"value":1}, {"source":52,"target":39,"value":1}, {"source":53,"target":51,"value":1}, {"source":54,"target":51,"value":2}, {"source":54,"target":49,"value":1}, {"source":54,"target":26,"value":1}, {"source":55,"target":51,"value":6}, {"source":55,"target":49,"value":12}, {"source":55,"target":39,"value":1}, {"source":55,"target":54,"value":1}, {"source":55,"target":26,"value":21}, {"source":55,"target":11,"value":19}, {"source":55,"target":16,"value":1}, {"source":55,"target":25,"value":2}, {"source":55,"target":41,"value":5}, {"source":55,"target":48,"value":4}, {"source":56,"target":49,"value":1}, {"source":56,"target":55,"value":1}, {"source":57,"target":55,"value":1}, {"source":57,"target":41,"value":1}, {"source":57,"target":48,"value":1}, {"source":58,"target":55,"value":7}, {"source":58,"target":48,"value":7}, {"source":58,"target":27,"value":6}, {"source":58,"target":57,"value":1}, {"source":58,"target":11,"value":4}, {"source":59,"target":58,"value":15}, {"source":59,"target":55,"value":5}, {"source":59,"target":48,"value":6}, {"source":59,"target":57,"value":2}, {"source":60,"target":48,"value":1}, {"source":60,"target":58,"value":4}, {"source":60,"target":59,"value":2}, {"source":61,"target":48,"value":2}, {"source":61,"target":58,"value":6}, {"source":61,"target":60,"value":2}, {"source":61,"target":59,"value":5}, {"source":61,"target":57,"value":1}, {"source":61,"target":55,"value":1}, {"source":62,"target":55,"value":9}, {"source":62,"target":58,"value":17}, {"source":62,"target":59,"value":13}, {"source":62,"target":48,"value":7}, {"source":62,"target":57,"value":2}, {"source":62,"target":41,"value":1}, {"source":62,"target":61,"value":6}, {"source":62,"target":60,"value":3}, {"source":63,"target":59,"value":5}, {"source":63,"target":48,"value":5}, {"source":63,"target":62,"value":6}, {"source":63,"target":57,"value":2}, {"source":63,"target":58,"value":4}, {"source":63,"target":61,"value":3}, {"source":63,"target":60,"value":2}, {"source":63,"target":55,"value":1}, {"source":64,"target":55,"value":5}, {"source":64,"target":62,"value":12}, {"source":64,"target":48,"value":5}, {"source":64,"target":63,"value":4}, {"source":64,"target":58,"value":10}, {"source":64,"target":61,"value":6}, {"source":64,"target":60,"value":2}, {"source":64,"target":59,"value":9}, {"source":64,"target":57,"value":1}, {"source":64,"target":11,"value":1}, {"source":65,"target":63,"value":5}, {"source":65,"target":64,"value":7}, {"source":65,"target":48,"value":3}, {"source":65,"target":62,"value":5}, {"source":65,"target":58,"value":5}, {"source":65,"target":61,"value":5}, {"source":65,"target":60,"value":2}, {"source":65,"target":59,"value":5}, {"source":65,"target":57,"value":1}, {"source":65,"target":55,"value":2}, {"source":66,"target":64,"value":3}, {"source":66,"target":58,"value":3}, {"source":66,"target":59,"value":1}, {"source":66,"target":62,"value":2}, {"source":66,"target":65,"value":2}, {"source":66,"target":48,"value":1}, {"source":66,"target":63,"value":1}, {"source":66,"target":61,"value":1}, {"source":66,"target":60,"value":1}, {"source":67,"target":57,"value":3}, {"source":68,"target":25,"value":5}, {"source":68,"target":11,"value":1}, {"source":68,"target":24,"value":1}, {"source":68,"target":27,"value":1}, {"source":68,"target":48,"value":1}, {"source":68,"target":41,"value":1}, {"source":69,"target":25,"value":6}, {"source":69,"target":68,"value":6}, {"source":69,"target":11,"value":1}, {"source":69,"target":24,"value":1}, {"source":69,"target":27,"value":2}, {"source":69,"target":48,"value":1}, {"source":69,"target":41,"value":1}, {"source":70,"target":25,"value":4}, {"source":70,"target":69,"value":4}, {"source":70,"target":68,"value":4}, {"source":70,"target":11,"value":1}, {"source":70,"target":24,"value":1}, {"source":70,"target":27,"value":1}, {"source":70,"target":41,"value":1}, {"source":70,"target":58,"value":1}, {"source":71,"target":27,"value":1}, {"source":71,"target":69,"value":2}, {"source":71,"target":68,"value":2}, {"source":71,"target":70,"value":2}, {"source":71,"target":11,"value":1}, {"source":71,"target":48,"value":1}, {"source":71,"target":41,"value":1}, {"source":71,"target":25,"value":1}, {"source":72,"target":26,"value":2}, {"source":72,"target":27,"value":1}, {"source":72,"target":11,"value":1}, {"source":73,"target":48,"value":2}, {"source":74,"target":48,"value":2}, {"source":74,"target":73,"value":3}, {"source":75,"target":69,"value":3}, {"source":75,"target":68,"value":3}, {"source":75,"target":25,"value":3}, {"source":75,"target":48,"value":1}, {"source":75,"target":41,"value":1}, {"source":75,"target":70,"value":1}, {"source":75,"target":71,"value":1}, {"source":76,"target":64,"value":1}, {"source":76,"target":65,"value":1}, {"source":76,"target":66,"value":1}, {"source":76,"target":63,"value":1}, {"source":76,"target":62,"value":1}, {"source":76,"target":48,"value":1}, {"source":76,"target":58,"value":1} ] }
The code you provided works, as you can see on this jsFiddle. The only difference is that I didn't use the d3.json function to load the json file. The problem you have is certainly that you want to run it locally, and that the json is not loaded. You need to run a server on your computer to make it work. Here is a question that can also help: d3.json: "Uncaught TypeError: Cannot read property 'children' of undefined" The simplest way to have a local web server, as explained here is to run this command in the directory where you have your source code: python -m SimpleHTTPServer 8888 & Then just load the page http://localhost:8888