Reputation: 2230
I have a newby question. Can D3 draw this: http://www.nytimes.com/interactive/2008/05/03/business/20080403_SPENDING_GRAPHIC.html?_r=0 using the voronoi function within d3? What i am thinking is a svg that behaves like a and binds the voronoi found here http://bl.ocks.org/mbostock/4060366 to a circle. NY Times has accomplished the above visualization using flash. Any ideas? I have tried creating a large circle and embeding the smaller circles, but the voronoi does not show up and the points are not confined to the outer circle. Code generated:
<svg class="PiYG" width="560" height="570">
<circle cx="270" cy="300" r="260" style="stroke: rgb(0, 0, 0);">
<g>
My js code looks something like this:
var width = 560, height = 570;
var svg = d3.select("#VD1").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "PiYG");
var path = svg.append("circle")
.attr("cx", 270)
.attr("cy", 300)
.attr("r", 260)
.style("stroke", "#000")
.append("g")
.selectAll("path");
var vertices = d3.range(count).map(function(d) {
return [Math.random() * width, Math.random() * height];
});
var voronoi = d3.geom.voronoi()
.clipExtent([[0, 0], [width, height]]);
svg.selectAll("circle")
.data(vertices.slice(2))
.enter().append("circle")
.attr("transform", function(d) { return "translate(" + d + ")"; })
.attr("r", 2);
Thanks so much!
Upvotes: 5
Views: 1219
Reputation: 7687
Not really, but not due to any shortcomings of d3, but rather because that's not what a Voronoi function does. A Voronoi function builds lines based on which regions of a graph are closest to a given point. It is not a way of proportionately dividing a circle into smaller segments, with size corresponding to data.
That being said, it is definitely possible to create a circular Voronoi diagram. To do so, you'll have to make a few changes to the example Voronoi diagram code.
First you'll have to make sure that all of the points fit in a circle. In your example, point location is given by d
, here:
.attr("transform", function(d) { return "translate(" + d + ")"; })
Either d
(your dataset) needs to fit in the circle, or you need to make some transformation of it. For data normalized to (-1,1) in both dimensions, the function
.attr("transform", function(d) { return "translate([" +
d[0]*Math.sqrt(1 - Math.pow(d[1],2)/2)
+ "," +
d[1]*Math.sqrt(1 - Math.pow(d[0],2)/2)
+ "])"; })
will do so. Here, we've created a new array that will be bounded by a circle from the array originally in d
.
Next, you would need to clip your Voronoi diagram to be contained within a circle. The fun part is, there isn't a built in 'circle' geometric object to clip with, so you'll need to get creative! Either build a custom way to do this, or let the Voronoi extend beyond your circle and build an SVG to cover it up. Either should work.
Upvotes: 2