javascriptlayoutd3.jsoffsetstream-graph

d3.layout.stack() with 'wiggle' offset issue


I wrote a function in d3 in order to create multiple plots showing different datasets in the sampe page.

I'm using streamgraph and stack layout, and I cannot understand why with the same code I can generate plots using as offset zero, expand and silhouette while using the same dataset and the same stack layout the wiggle offset does not produce anything. (I already read more than once the documentation)

Herewith an excerpt of the code:

var stack = d3.layout.stack()
    .values(function(d) {
        return d.values;
    }).offset(o || 'silhouette');// o could be one of [expand, wiggle, zero, silhouette]

var layers = stack(stacked.datalayers()); // See after this piece of code

var maxY = d3.max(layers, function(c) {
    return d3.max(c.values, function(d) {
        return d.y0 + d.y;
    });
});

var x = d3.scale.ordinal().domain(stacked.x()).rangeRoundBands([0, w]); // stacked.x() returns an array with the min and the max values for X
var y = d3.scale.linear().domain([0, maxY]).range([h, 0]);

var area = d3.svg.area()
        .x(function(d) {
            return x(d.x) + (x.rangeBand() / 2);
        })
        .y0(function(d) {
            return y(d.y0);
        })
        .y1(function(d) {
            return y(d.y0 + d.y);
        }).interpolate("monotone");

...

series.append("path")
        .attr("d", function(d) {
            return area(d.values);
        })
        .style("fill", function(d) {
            return color(cdomain.indexOf(d.name));
        })
        .style("fill-opacity", ".5")
        .style("stroke", function(d) {
            return color(cdomain.indexOf(d.name));
        })
        .style("stroke-width", "2px");

This is the structure of the data as returned from stacked.datalayer():

[
  {
    "name": "US",
    "values": [
      {
        "x": "01/2014",
        "y": 1.726118500604595,
        "name": "US",
        "y0": 0.8662854227545267
      },
      {
        "x": "02/2014",
        "y": 2.5897229845496037,
        "name": "US",
        "y0": 0.38969767845094694
      },
      {
        "x": "03/2014",
        "y": 2.388349800480026,
        "name": "US",
        "y0": 0.518912280793379
      }
    ]
  },
  {
    "name": "Europe28",
    "values": [
      {
        "x": "01/2014",
        "y": 0.42541539123546496,
        "name": "Europe28",
        "y0": 2.5924039233591216
      },
      {
        "x": "02/2014",
        "y": 0.5149863958976154,
        "name": "Europe28",
        "y0": 2.9794206630005506
      },
      {
        "x": "03/2014",
        "y": 0.4579303752823291,
        "name": "Europe28",
        "y0": 2.907262081273405
      }
    ]
  }
]

Here are some screenshots of the results (using the same dataset):

offset 'zero': offset 'zero'

offset 'expanded': offset 'expanded'

offset 'silhouette': offset 'silhouette'

offset 'wiggle': offset 'wiggle'


Solution

  • From the documentation for stack.x:

    The return value of the accessor must be a number.

    The default accessor returns d.x, and your data currently contains strings for this property (e.g. "01/2014"). You can either set your own accessor, or modify the data so that the x-value is a number. The reason it only affected the wiggle mode is that it uses the x-value to compute the gradient.