简体   繁体   中英

Stacked Area in D3.js

I'm using D3.js and I'm having trouble setting up a stacked layout for an area chart with multiple series. I have two possible structures of my data (if that helps). One is the raw data fed to the script, in this structure:

var data = [{key: 'Group1', value: 37, date: '04/23/12'},
           {key: 'Group2', value: 12, date: '04/23/12'},
           {key: 'Group3', value: 46, date: '04/23/12'},
           {key: 'Group1', value: 32, date: '04/24/12'},
           {key: 'Group2', value: 19, date: '04/24/12'},
           {key: 'Group3', value: 42, date: '04/24/12'},
           {key: 'Group1', value: 45, date: '04/25/12'},
           {key: 'Group2', value: 16, date: '04/25/12'},
           {key: 'Group3', value: 44, date: '04/25/12'},
           {key: 'Group1', value: 24, date: '04/26/12'},
           {key: 'Group2', value: 52, date: '04/26/12'},
           {key: 'Group3', value: 64, date: '04/26/12'}]

Second is a nested structure, created using this code:

 pData = d3.nest()
            .key(function(d) { return d.key; })
            .map(data);

Resulting in this structure:

pData = {Group1: [{date: 04/23/12, key: "Group1", value: 37}, 
                  {date: 04/24/12, key: "Group1", value: 32}, 
                  {date: 04/25/12, key: "Group1", value: 45},
                  ...],
         Group2: [{date: 04/23/12, key: "Group2", value: 12},
                  {etc, etc, etc}],
         GroupX: [...] }

My questions is : How do I setup a d3.layout.stack() generator, using one of the above data structures (or some variation), to create a stacked structure for my data such that I can pass it to an area generator similar to this:

var areaGenerator = d3.svg.area()
    .interpolate('monotone')
    .x(function(d) { return x(d.date); })
    .y0(h)
    .y1(function(d) { return y(d.value); });

You must feed an array of layers to the stack layout, so the first thing to change is to use nest.entries rather than nest.map . This returns an array of objects with a key field (such as "Group1") and a values array which contains the associated records. You would then specify a stack.values accessor so that the stack layout can access the values array for each layer.

You will also need to define suitable x and y accessors to the stack layout so that it can understand your input data: the x -accessor should return d.date , and the y -accessor should return d.value . You will also need to convert your date strings to Dates; you can use d3.time.format to help with this. For example:

var format = d3.time.format("%m/%d/%y");
data.forEach(function(d) { d.date = format.parse(d.date); });

Lastly, change your area definition so that the baseline y0 is defined as y(d.y0) and the topline y1 is defined as y(d.y0 + dy) .

Here's a working example:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM