D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
romsson
Full window
Github gist
Flexible node link layout
Built with
blockbuilder.org
<!DOCTYPE html> <meta charset="utf-8"> <title>Homework 2 GitHub Network Graphs</title> <style> .link { stroke: gray; stroke-width: 1.5px; } .node { fill: #66CC66; stroke: #000; stroke-width: 1px; } .node:hover { fill: red; } </style> <body> <script src="https://d3js.org/d3.v4.min.js"></script> <form> Layout: <label><input type="radio" name="layout" value="force" checked> Force</label> <label><input type="radio" name="layout" value="random" > Random</label> <label><input type="radio" name="layout" value="radial"> Radial</label> <label><input type="radio" name="layout" value="line"> Line</label> <label><input type="radio" name="layout" value="line_cat"> Line by Category</label> </form> <form> Color: <label><input type="radio" name="color" value="nocolor" checked> None</label> <label><input type="radio" name="color" value="color_cat" > Category</label> </form> <form> Size: <label><input type="radio" name="size" value="nosize" checked> None</label> <label><input type="radio" name="size" value="size_cat" > Category</label> </form> <script> var width = 900, height = 700; var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var link = svg.selectAll(".link"), node = svg.selectAll(".node"), fill = d3.scaleOrdinal(d3.schemeCategory20); var simulation; // Init graph data structure var graph = {nodes:[], links:[]}; // Generate random nodes var nb_nodes = 100, nb_cat = 10; graph.nodes = d3.range(nb_nodes).map(function() { return {cat: Math.floor(nb_cat * Math.random())}; }) graph.nodes.map(function(d, i) { graph.nodes.map(function(e, j) { if(Math.random()>.99 && i!=j) graph.links.push({"source": i, "target": j}) }); }); function random_layout() { simulation.stop(); graph.nodes.forEach(function(d, i) { d.x = width/4 + 2*width*Math.random()/4; d.y = height/4 + 2*height*Math.random()/4; }) graph_update(500); } function force_layout() { simulation = d3.forceSimulation(graph.nodes) .force("link", d3.forceLink(graph.links).id(d => d.index)) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)); simulation.on("tick", function() { graph_update(0) }); } function line_layout() { simulation.stop(); graph.nodes.forEach(function(d, i) { d.y = height/3; }) graph_update(500); } function line_cat_layout() { simulation.stop(); graph.nodes.forEach(function(d, i) { d.y = height/3 + d.cat * 20; }) graph_update(500); } function radial_layout() { simulation.stop(); var r = height/3; var arc = d3.arc() .outerRadius(r); var pie = d3.pie() .sort(function(a, b) { return a.cat - b.cat;}) .value(function(d, i) { return 1; }); // equal share for each point graph.nodes = pie(graph.nodes).map(function(d, i) { d.innerRadius = 0; d.outerRadius = r; d.data.x = arc.centroid(d)[0]+height/3; d.data.y = arc.centroid(d)[1]+width/3; d.data.endAngle = d.endAngle; d.data.startAngle = d.startAngle; return d.data; }) graph_update(500); } function category_color() { d3.selectAll("circle") .transition().duration(500) .style("fill", function(d) { return fill(d.cat); }); } function category_size() { d3.selectAll("circle") .transition().duration(500) .attr("r", function(d) { return Math.sqrt((d.cat+1)*10); }); } function graph_update(delay) { link.transition().duration(delay) .attr("x1", function(d) { return d.target.x; }) .attr("y1", function(d) { return d.target.y; }) .attr("x2", function(d) { return d.source.x; }) .attr("y2", function(d) { return d.source.y; }); node.transition().duration(delay) .attr("transform", function(d) { return "translate("+d.x+","+d.y+")"; }); } d3.select("input[value=\"force\"]").on("click", force_layout); d3.select("input[value=\"random\"]").on("click", random_layout); d3.select("input[value=\"line\"]").on("click", line_layout); d3.select("input[value=\"line_cat\"]").on("click", line_cat_layout); d3.select("input[value=\"radial\"]").on("click", radial_layout); d3.select("input[value=\"nocolor\"]").on("click", function() { d3.selectAll("circle").transition().duration(500).style("fill", "#66CC66"); }) d3.select("input[value=\"color_cat\"]").on("click", category_color); d3.select("input[value=\"nosize\"]").on("click", function() { d3.selectAll("circle").transition().duration(500).attr("r", 5); }) d3.select("input[value=\"size_cat\"]").on("click", category_size); link = link.data(graph.links) .enter().append("line") .attr("class", "link") node = node.data(graph.nodes) .enter().append("g").attr("class", "node"); node.append("circle") .attr("r", 5) force_layout(); </script> </body> </html>
https://d3js.org/d3.v4.min.js