D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
cpietsch
Full window
Github gist
Pseudo-Dorling Cartogram
temp. working fork of /mbostock/4055892
<!DOCTYPE html> <meta charset="utf-8"> <title>Dorling Cartogram</title> <style> circle { fill: #eee; stroke: #000; stroke-width: 1.5px; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> // Ratio of Obese (BMI >= 30) in U.S. Adults, CDC 2008 var valueById = [ NaN, .187, .198, NaN, .133, .175, .151, NaN, .100, .125, .171, NaN, .172, .133, NaN, .108, .142, .167, .201, .175, .159, .169, .177, .141, .163, .117, .182, .153, .195, .189, .134, .163, .133, .151, .145, .130, .139, .169, .164, .175, .135, .152, .169, NaN, .132, .167, .139, .184, .159, .140, .146, .157, NaN, .139, .183, .160, .143 ]; var margin = {top: 0, right: 0, bottom: 0, left: 0}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom, padding = 3; var projection = d3.geo.albersUsa(); var radius = d3.scale.sqrt() .domain([0, d3.max(valueById)]) .range([0, 30]); var force = d3.layout.force() .charge(0) .gravity(0) .size([width, height]); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.json("https://gist.githubusercontent.com/mbostock/3750900/raw/91fe3afc0d94dc44348fd939df5843a0707d24aa/us-state-centroids.json", function(error, states) { if (error) throw error; var nodes = states.features .filter(function(d) { return !isNaN(valueById[+d.id]); }) .map(function(d) { var point = projection(d.geometry.coordinates), value = valueById[+d.id]; if (isNaN(value)) fail(); return { x: point[0], y: point[1], x0: point[0], y0: point[1], r: radius(value), value: value }; }); force .nodes(nodes) .on("tick", tick) .start(); var node = svg.selectAll("circle") .data(nodes) .enter().append("circle") .attr("r", function(d) { return d.r; }); function tick(e) { node.each(gravity(e.alpha * .1)) .each(collide(.5)) .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); } function gravity(k) { return function(d) { d.x += (d.x0 - d.x) * k; d.y += (d.y0 - d.y) * k; }; } function collide(k) { var q = d3.geom.quadtree(nodes); return function(node) { var nr = node.r + padding, nx1 = node.x - nr, nx2 = node.x + nr, ny1 = node.y - nr, ny2 = node.y + nr; q.visit(function(quad, x1, y1, x2, y2) { if (quad.point && (quad.point !== node)) { var x = node.x - quad.point.x, y = node.y - quad.point.y, l = x * x + y * y, r = nr + quad.point.r; if (l < r * r) { l = ((l = Math.sqrt(l)) - r) / l * k; node.x -= x *= l; node.y -= y *= l; quad.point.x += x; quad.point.y += y; } } return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; }); }; } }); </script>
https://d3js.org/d3.v3.min.js