Playing with the Beeswarm along a path approach, forked from 1wheel's block: beeswarm-path, which was suggested by Arman.
forked from tomshanley's block: beeswarm on square and circle path
| license: mit |
Playing with the Beeswarm along a path approach, forked from 1wheel's block: beeswarm-path, which was suggested by Arman.
forked from tomshanley's block: beeswarm on square and circle path
| <!DOCTYPE html> | |
| <meta charset='utf-8'> | |
| <style> | |
| path { | |
| fill: none; | |
| stroke: #00ff50; | |
| stroke-linecap: round; | |
| stroke-width: 40; | |
| opacity: .2; | |
| } | |
| body{ | |
| font-family: monaco, Consolas, 'Lucida Console', monospace; | |
| margin: 0px; | |
| } | |
| </style> | |
| <div id='graph'></div> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script> | |
| var r = 3 | |
| var w = 800, h = 800 | |
| var svg = d3.select('#graph') | |
| .html('') | |
| .append('svg') | |
| .attr("width", w) | |
| .attr("height", h) | |
| //square | |
| var squareNode = svg.append('path') | |
| .attr("d", 'M 50,50 L750,50 L750,750 50,750 z') | |
| //circle | |
| var circleNode = svg.append('path') | |
| .attr("d", 'M 400,400 m -150,0 a 150,150 0 1,0 300,0 a 150,150 0 1,0 -300,0') | |
| var randomData1 = d3.range(300).map(x => { | |
| var val = Math.random() * 400 | |
| return {val} | |
| }) | |
| var randomData2 = d3.range(300).map(x => { | |
| var val = Math.random() * 400 | |
| return {val} | |
| }) | |
| addSwarm(squareNode, randomData1) | |
| addSwarm(circleNode, randomData2) | |
| function addSwarm(path, _data) { | |
| var node = path.node() | |
| var scaleLength = d3.scaleLinear() | |
| .domain([0, d3.max(_data, function(d){ return d.val })]) | |
| .range([0, node.getTotalLength()]) | |
| var scaleX = function(d){ | |
| return node.getPointAtLength(scaleLength(d.val)).x | |
| } | |
| var scaleY = function(d){ | |
| return node.getPointAtLength(scaleLength(d.val)).y | |
| } | |
| var simulation = d3.forceSimulation(_data) | |
| .force('x', d3.forceX(d => scaleX(d))) | |
| .force('y', d3.forceY(d => scaleY(d))) | |
| .force('collide', d3.forceCollide(r + 1)) | |
| .on("tick", ticked); | |
| var circles = svg.append("g").selectAll('circle') | |
| .data(_data) | |
| .enter() | |
| .append('circle') | |
| .attr("r", r) | |
| function ticked() { | |
| d3.selectAll('circle') | |
| .attr("cx", function(d) { return d.x; }) | |
| .attr("cy", function(d) { return d.y; }); | |
| } | |
| } | |
| </script> |