Syntax question about .data([data]) binding for Pies and Arcs

299 views
Skip to first unread message

Guerino1

unread,
Apr 2, 2012, 7:22:30 PM4/2/12
to d3...@googlegroups.com
Hi,

Can someone please help me with what I believe is a Javascript syntax understanding issue...

I started playing with the pie Bakery example by Ian Johnson ("enjalot") to get a deeper understanding of how pie charts and arcs work.

In his example he defines a simple array of random data using the "var data = d3.range(10).map(Math.random)" statement.  He could have easily used a fixed array like: "var data = [10, 50, 6, 100, 82, 4, 9]", which also works.

When he creates the code to generate the pie, he binds the data using the syntax ".data([data])", surrounding the array with square brackets (i.e. "[" "]").  It looks like he's turning the array into an array of an array.  Is this accurate?  If so, why does this need to be done w/ the Pie/Arc generators because it doesn't seem to happen with drawing lines and rectangles?

Thanks,

Frank

Tore

unread,
Apr 3, 2012, 2:25:13 AM4/3/12
to d3...@googlegroups.com
Hi Frank,

It is the pie function (https://github.com/mbostock/d3/wiki/Pie-Layout#wiki-_pie) that requires an array of values. In Ian's code this function is called donut. When invoked, it returns an array of objects; each object is an arc descriptor which the arc function uses to generate the path string for one pie segment (https://github.com/mbostock/d3/wiki/SVG-Shapes#wiki-_arc). 

This data-join of arc descriptors could have been implemented by invoking the pie-function with the simple array of values as argument:
        var arcs = pie.selectAll("g.arc")
           .data(donut(data))
See this modified Bakery example: http://bl.ocks.org/2289227

However, in the original Bakery example, Ian choose to bind the simple array of values itself to the document. It is bound to the container in which the g.arcs live: the #charts element. 

When you have a selection, like pie = d3.select("#charts"), and make a subsequent selection, like pie.selectAll("g.arc"), you obtain sub-selection or groups. When you use the data method on this sub-selection to join data to the groups, you have to specify a function. In our case that function is donut. For each group, that function will receive one row of its parent's selection data as a first argument. That is why that parent selection needs to be joined to a 2-dimensional array. 

        var pie = d3.select("#charts")
            .append("svg:g")
                //.data([data.sort(d3.descending)])
                .data([data])
                .attr("class", classname);

        var arcs = pie.selectAll("g.arc")
           .data(donut)

This is analogous to the matrix and table example described in the documentation: https://github.com/mbostock/d3/wiki/Selections#wiki-data. In the Bakery example we only have one group and one matrix row.

Tore

Darrick Wiebe

unread,
Apr 3, 2012, 2:40:04 AM4/3/12
to d3...@googlegroups.com
Hey Tore, an unrelated question here, what did you use to format that email so nicely?

Cheers,
Darrick

Tore

unread,
Apr 3, 2012, 10:13:02 AM4/3/12
to d3...@googlegroups.com
Hi Darrick,

I used the Google Groups web interface to reply and I copied the code snippets from http://bl.ocks.org/. Pasting kept the original formatting from the bl.ocks.org html page.

Tore

On Monday, April 2, 2012 11:40:04 PM UTC-7, Darrick Wiebe wrote:
Hey Tore, an unrelated question here, what did you use to format that email so nicely?

Cheers,
Darrick

Frank Guerino

unread,
Apr 3, 2012, 5:00:43 PM4/3/12
to d3...@googlegroups.com
Thanks Tore.  I appreciate the help.

The goal is to replace using a simple array of numbers (i.e. dataSet = [1, 7, 5, 6];) with a more complex structure like:

// Data Used for this example...
var dataSet1 = [
    {"setName": "Set Label", legendLabel: "Legend String 1", magnitude: 5, link: "http://www.if4it.com"},
    {"setName": "Set Label", legendLabel: "Legend String 2", magnitude: 2, link: "http://www.guerino.net"},
    {"setName": "Set Label", legendLabel: "Legend String 3", magnitude: 9, link: "http://www.google.com"},
    {"setName": "Set Label", legendLabel: "Legend String 4", magnitude: 7, link: "http://www.yahoo.com"}];

... where we can now bind each "magnitude" to each arc in the pie, associate each label with each arc, and finally associate each link with each arc.

Based on your response, I started to explore accessing and placing different datum from such a data structure in my example:  "Simple Pie Chart with Magnitudes in Arcs and Legends Outside and Along Arcs", which is based on Ian Johnson's (enjalot's) original example, called "Simple Pie Chart example with D3.js"  I can now successfully 1) bind the more complex data structure, 2) access individual arc legend labels, and 3) access individual arc magnitudes (while also rotating them).

My next steps involve things like specifying links in the data structure and finding ways to bind individual links to each arc in the pie, as well as adding mouseover functionality that does things like highlighting individual arcs.

Thanks again for the help,

Frank






Reply all
Reply to author
Forward
0 new messages