3

I'm learning D3.js and trying to get my head around data keys used with streamgraphs. I would like to adapt the official streamgraph example:

enter image description here

...so that each path has an explicit data key, and so that the mouseover logs the data key.

The official example adds paths as follows:

var area = d3.svg.area()
   .x(function(d) { console.log('x', d.data); return d.x * w / mx; })
   .y0(function(d) { return h - d.y0 * h / my; })
   .y1(function(d) { return h - (d.y + d.y0) * h / my; });
vis.selectAll("path")
 .data(data0) 
 .enter().append("path")
 .style("fill", function() { return color(Math.random()); })
 .attr("d", area);

I tried adapting the code as follows, but I'm not sure how to change the structure of data0 (currently an array of arrays) to achieve what I want:

vis.selectAll("path")
 .data(data0, function(d) { return d.name }) // Add key function
 .enter().append("path")
 .style("fill", function() { return color(Math.random()); })
 .attr("d", area)
 .on("mouseover", function (d,i) { 
     console.log("mouseover", d.name); // Log name property on mouseover
  });

As it stands, without my having made any changes to the structure of data0, it unsurprisingly does not work. How can I add a name property to data0 without also messing up the area and .data() functions?

UPDATE: To be a bit clearer: the D3 docs say that the area function is expecting a two-dimensional array. So if I change data0 from a two-dimensional array, to an array of objects, each with a name key and a data key, how can I also change what I pass to area?

VividD
  • 10,456
  • 6
  • 64
  • 111
Richard
  • 31,629
  • 29
  • 108
  • 145

2 Answers2

6

The data in the example doesn't have a "name" property, so you would need to add that to the data to use it. The data keys you refer to are used when merging/updating data, i.e. you have drawn some paths already and then update (some of them). The .data() function will try to figure out what data is updated and what data is new. If that doesn't work for you, you can use the data key to help it, i.e. in your case tell it that things with the same name are the same data.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • Yes, but if I add a 'name' key to the data (i.e. if I restructure it to be an array of objects rather than an array of arrays), then the area function stops working. How can I adjust the area function too? – Richard Mar 13 '12 at 10:07
  • 2
    That would similarly become something like `.attr("d", function(d) { return area(d.data); }` assuming that you put the data array under `data`. – Lars Kotthoff Mar 13 '12 at 18:46
  • Ahhhh! That's the breakthrough I'd failed to make. Thank you very much. – Richard Mar 13 '12 at 22:24
0

If what you mean by data keys are "data legends", then you might want to take a look at the following examples where I've completely separated the placement of magnitudes, legend bullets and legend text in different areas of the charts.

In each of the examples, you'll clearly see how the data is labeled, structured, passed in, and used.

I also tied them together through mouseover and mouseout events so that mousing over or out of any element causes all elements in a set to change color simultaneously.

I hope this helps.

Frank

Information Technology
  • 2,243
  • 3
  • 30
  • 46