常に特定のノードをセンターに置くサンプル
Built with blockbuilder.org
| license: mit |
常に特定のノードをセンターに置くサンプル
Built with blockbuilder.org
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <style> | |
| html, body, #graph { | |
| width: 100%; | |
| height: 100%; | |
| } </style> | |
| </head> | |
| <body> | |
| <div id="graph"></div> | |
| <script> | |
| !(function(){ | |
| "use strict" | |
| var width,height | |
| var chartWidth, chartHeight | |
| var margin | |
| var svg = d3.select("#graph").append("svg") | |
| var chartLayer = svg.append("g").classed("chartLayer", true) | |
| main() | |
| function main() { | |
| var range = 40 | |
| var data = { | |
| nodes:d3.range(0, range).map(function(d){ return {label: "l"+d ,r:~~d3.randomUniform(8, 28)(), color:"black"}}), | |
| links:d3.range(0, range).map(function(){ return {source:~~d3.randomUniform(range)(), target:~~d3.randomUniform(range)()} }) | |
| } | |
| //センターに指定するノードに必ずリンクをつける | |
| data.links.push({source:0, target:~~d3.randomUniform(range)()}) | |
| data.links.push({source:0, target:~~d3.randomUniform(range)()}) | |
| data.links.push({source:0, target:~~d3.randomUniform(range)()}) | |
| data.nodes[0].color = "red"; | |
| setSize(data) | |
| drawChart(data) | |
| } | |
| function setSize(data) { | |
| width = document.querySelector("#graph").clientWidth | |
| height = document.querySelector("#graph").clientHeight | |
| margin = {top:0, left:0, bottom:0, right:0 } | |
| chartWidth = width - (margin.left+margin.right) | |
| chartHeight = height - (margin.top+margin.bottom) | |
| svg.attr("width", width).attr("height", height) | |
| chartLayer | |
| .attr("width", chartWidth) | |
| .attr("height", chartHeight) | |
| .attr("transform", "translate("+[margin.left, margin.top]+")") | |
| } | |
| function drawChart(data) { | |
| var simulation = d3.forceSimulation() | |
| .force("link", d3.forceLink().id(function(d) { return d.index })) | |
| .force("collide",d3.forceCollide( function(d){return d.r + 8 }).iterations(16) ) | |
| .force("charge", d3.forceManyBody()) | |
| .force("center", d3.forceCenter(chartWidth / 2, chartHeight / 2)) | |
| .velocityDecay(0.4) | |
| .alphaTarget(0.1); | |
| var link = svg.append("g") | |
| .attr("class", "links") | |
| .selectAll("line") | |
| .data(data.links) | |
| .enter() | |
| .append("line") | |
| .attr("stroke", "black") | |
| var node = svg.append("g") | |
| .attr("class", "nodes") | |
| .selectAll("circle") | |
| .data(data.nodes) | |
| .enter().append("circle") | |
| .attr("cx", chartWidth / 2) | |
| .attr("cy", chartHeight / 2) | |
| .attr("r", function(d){ return d.r }) | |
| .attr("fill", function(d){ return d.color }) | |
| .call(d3.drag() | |
| .on("start", dragstarted) | |
| .on("drag", dragged) | |
| .on("end", dragended)); | |
| var ticked = function() { | |
| data.nodes[0].fx = chartWidth / 2; | |
| data.nodes[0].fy = chartHeight / 2; | |
| 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, i) { return d.x; }) | |
| .attr("cy", function(d, i) { return d.y; }); | |
| } | |
| simulation | |
| .nodes(data.nodes) | |
| .on("tick", ticked); | |
| simulation.force("link") | |
| .links(data.links); | |
| function dragstarted(d) { | |
| if (!d3.event.active) simulation.alphaTarget(0.3).restart(); | |
| d.fx = d.x; | |
| d.fy = d.y; | |
| } | |
| function dragged(d) { | |
| d.fx = d3.event.x; | |
| d.fy = d3.event.y; | |
| } | |
| function dragended(d) { | |
| if (!d3.event.active) simulation.alphaTarget(0); | |
| d.fx = null; | |
| d.fy = null; | |
| } | |
| } | |
| }()); | |
| </script> | |
| </script> | |
| </body> |