D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
larsenmtl
Full window
Github gist
Letter Spitter
Press any letter on the keyboard.
<!DOCTYPE html> <meta charset="utf-8"> <style> text { fill: steelblue; font-size: 30px; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var width = window.innerWidth - 40, height = (window.innerHeight * 1.75) - 40, padding = 6, // separation between nodes radius = 15; var m = 11 // total number of coloumns; d3.select('body') .style('height', height + 'px') .style('overflow-y', 'hidden'); var x = d3.scale.ordinal() .domain(d3.range(m)) .rangePoints([0, width], 1); function makeNode(letter){ var column = 0; switch(letter) { case 'Q': case 'A': column = 0; break; case 'W': case 'Z': column = 1; break; case 'S': case 'X': column = 2; break; case 'E': case 'D': column = 3; break; case 'C': case 'R': case 'T': case 'F': case 'V': column = 4; break; case 'Y': case 'H': case 'G': case 'B': column = 5; break; case 'U': case 'N': column = 6; break; case 'J': case 'M': column = 7; break; case 'I': case 'K': column = 8; break; case 'O': case 'L': column = 9; break; case 'P': column = 10; break; default: return false; }; return { letter: letter, x: width/2, y: 0, cx: x(column), cy: height / 2, radius: 10 }; } var nodes = []; var force = d3.layout.force() .nodes(nodes) .size([width, height]) .gravity(0) .charge(0) .on("tick", tick); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); function update(letter){ var node = makeNode(letter); if (node){ nodes.push(node); letters = svg.selectAll("text") .data(nodes); letters .enter() .append("text") .text(function(d){ return d.letter; }); force.nodes(nodes); force.start(); } } d3.select("body") .on("keydown", function() { update(String.fromCharCode(d3.event.keyCode)); }); function tick(e) { letters .each(gravity(.2 * e.alpha)) .each(collide(.5)) .attr("x", function(d) { return d.x; }) .attr("y", function(d) { return d.y; }); letters.attr("x", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); }) .attr("y", function(d) { return d.y = Math.max(radius, Math.min((height / 2) - radius, d.y)); }); } // Move nodes toward cluster focus. function gravity(alpha) { return function(d) { d.y += (d.cy - d.y) * alpha; d.x += (d.cx - d.x) * alpha; }; } // Resolve collisions between nodes. function collide(alpha) { var quadtree = d3.geom.quadtree(nodes); return function(d) { var r = (2 * radius) + padding, nx1 = d.x - r, nx2 = d.x + r, ny1 = d.y - r, ny2 = d.y + r; quadtree.visit(function(quad, x1, y1, x2, y2) { if (quad.point && (quad.point !== d)) { var x = d.x - quad.point.x, y = d.y - quad.point.y, l = Math.sqrt(x * x + y * y), r = (2 * radius); if (l < r) { l = (l - r) / l * alpha; d.x -= x *= l; d.y -= y *= l; quad.point.x += x; quad.point.y += y; } } return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; }); }; } document.addEventListener("DOMContentLoaded", function(event) { self.frameElement.focus(); }); </script>
https://d3js.org/d3.v3.min.js