generate(); function generate(){ var height = window.innerHeight; var width = window.innerWidth; var svg = d3.select("#chartArea").append("svg") .attr("width", width) .attr("height", height) coords = [] for(var i = 0; i < 50; i++){ var cy = Math.random()*(height-100) + 50 var cx = Math.random()*(width-100) + 50 coords.push([cx, cy]) } //Hull var hull = svg.append("path") .attr("class", "hull"); hull.data([d3.geom.hull(coords)]) .attr("d", function(d) { return "M" + d.join("L") + "Z"; }) .attr("opacity", .3) console.log('area', d3.geom.polygon(d3.geom.hull(coords)).area()) //Voronoi -> how to make a weighted version of this depending on the node in the center? var voronoi = d3.geom.voronoi() .clipExtent([[0, 0], [width, height]]); //voronoi.triangles seems very similar to the outside of a hull? var path = svg.append("g").selectAll("path"); path = path.data(voronoi.triangles(coords), polygon); path.enter().append("path") .attr("class", function(d, i) { return "q" + (i % 9) + "-9" + " voronoiTriangles"; }) .attr("fill", 'none') .attr("stroke", "maroon") .attr("d", polygon) .on('mouseover', function() { d3.selectAll('.voronoiTriangles').style('stroke-width', 3) }) .on('mouseout', function() { d3.selectAll('.voronoiTriangles').style('stroke-width', 1) }) function polygon(d) { return "M" + d.join("L") + "Z"; } //Voronoi path = path.data(voronoi(coords), polygon); path.enter().append("path") .attr("class", function(d, i) { return "q" + (i % 9) + "-9" + " voronoi"; }) .attr("fill", 'none') .attr("stroke", "#3CA1A5") .attr("d", polygon) .on('mouseover', function() { d3.selectAll('.voronoi').style('stroke-width', 3) }) .on('mouseout', function() { d3.selectAll('.voronoi').style('stroke-width', 1) }) //QuadTrees var quadtree = d3.geom.quadtree() .extent([[0, 0], [width, height]]); var rect = svg.selectAll(".node") .data(nodes(quadtree(coords))) .enter().append("rect") .attr("class", "node quadTrees") .attr("fill", 'none') .attr("stroke", "#7D9B47") .attr("x", function(d) { return d.x1; }) .attr("y", function(d) { return d.y1; }) .attr("width", function(d) { return d.x2 - d.x1; }) .attr("height", function(d) { return d.y2 - d.y1; }) .on('mouseover', function() { d3.selectAll('.quadTrees').style('stroke-width', 3) }) .on('mouseout', function() { d3.selectAll('.quadTrees').style('stroke-width', 1) }) function nodes(quadtree) { var nodes = []; quadtree.depth = 0; // root quadtree.visit(function(node, x1, y1, x2, y2) { node.x1 = x1; node.y1 = y1; node.x2 = x2; node.y2 = y2; nodes.push(node); for (var i=0; i<4; i++) { if (node.nodes[i]) node.nodes[i].depth = node.depth+1; } }); return nodes; } //Circles svg.selectAll('circle') .data(coords).enter().append('circle') .classed('circle', true) .attr('cx', function(d) { return d[0]; }) .attr('cy', function(d) { return d[1]; }) .attr('r', 5) }