D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
SleepyHarry
Full window
Github gist
Dandelion WIP
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } .node { fill: black; } .link { stroke: black; stroke-opacity: 0.24; } .windicator { stroke: blue; stroke-opacity: 0; /* remove for windicator */ } </style> </head> <body> <script> var margin = {top: 20, right: 20, bottom: 20, left: 20}, outerWidth = 960, outerHeight = 500, width = outerWidth - margin.left - margin.right, height = outerHeight - margin.top - margin.bottom; var svg = d3.select('body').append('svg') .attr('width', outerWidth) .attr('height', outerHeight) .append('g') .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); var center = [width / 2, height / 2]; var NUM_SEEDS = 1000; var nodes = d3.range(NUM_SEEDS).map(d => { return { id: d + 1 }; }); nodes.unshift({ id: 0, fx: center[0], fy: center[1], }); var links = d3.range(NUM_SEEDS).map(d => { return { source: 0, target: d + 1, }; }); var node = svg.append('g') .attr('class', 'nodes') .selectAll('circle') .data(nodes) .enter().append('circle').attr('class', 'node') .attr('r', d => d.id === 0 ? 5 : 2); var link = svg.append('g') .attr('class', 'links') .selectAll('line') .data(links) .enter().append('line').attr('class', 'link'); var windicator = svg.append('line').attr('class', 'windicator') .attr('x2', center[0] + width / 4) .attr('y2', center[1]); var currentWind = [0.4, 0.8]; var windForce = function (alpha) { currentWind[0] = Math.max(-2, Math.min(2, currentWind[0] + (Math.random() - 0.5) / 4)); currentWind[1] = Math.max(-2, Math.min(2, currentWind[1] + (Math.random() - 0.5) / 4)); for (var i=1; i < nodes.length; i++) { var thisNode = nodes[i]; thisNode.vx += currentWind[0]; thisNode.vy += currentWind[1]; } windicator .attr('x1', center[0] + width / 4 + currentWind[0] * 20) .attr('y1', center[1] + currentWind[1] * 20); }; var sim = d3.forceSimulation() .force('link', d3.forceLink().id(d => d.id)) // .force('charge', d3.forceManyBody()) .force('center', d3.forceCenter(...center)) .force('wind', windForce); sim.alphaDecay(0); // run forever sim.nodes(nodes); sim.on('tick', function () { node .attr('cx', d => d.x) .attr('cy', d => d.y); link .attr('x1', d => d.source.x) .attr('y1', d => d.source.y) .attr('x2', d => d.target.x) .attr('y2', d => d.target.y); }); var randRadius = function (r) { return function () { var x = Math.cos(Math.random() * Math.PI), y = Math.cos(Math.random() * Math.PI); return r * Math.sqrt(x ** 2 + y ** 2); }; }; var rand = randRadius(100); sim.force('link') .links(links) .distance(rand); </script> </body>
https://d3js.org/d3.v4.min.js