chinmaymk / angular-charts

angular directives for creating common charts using d3
MIT License
1.03k stars 270 forks source link

Stacked area chart #182

Open xaguzman opened 9 years ago

xaguzman commented 9 years ago

How can a stacked area chart be created with this library?

I am guessing that the areaChart function would only need some small changes, I did dig into the code, however I am not really experienced with d3, thus having a hard time.

Specifically, I think I would need to change the d3.svg.area() for a svg.layout.stack() call.

I did try setting it up like this:

series.slice(0, yMaxPoints).forEach(function (value, index) {
              var d = {};
              d.series = value;
              d.values = points.map(function (point, idxPoint) {
                  return point.y.map(function (e, idxY) {
                      return {
                          x: point.x,
                          y0: idxPoint > 0 ? points[idxPoint - 1].y[idxY] : 0,
                          y: e
                      };
                  })[index] || {
                      x: points[index].x,
                      y: 0,
                      y0: idxPoint > 0 ? points[idxPoint - 1].y[idxY] : 0
                  };
              });
              linedata.push(d);
          });
          var svg = d3.select(chartContainer[0]).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
          var padding = d3.max(yData) * 0.2;
          y.domain([
            d3.min(yData),
            d3.max(yData) + padding
          ]);
          svg.append('g').attr('class', 'x axis').attr('transform', 'translate(0,' + height + ')').call(xAxis);
          svg.append('g').attr('class', 'y axis').call(yAxis);
          var point = svg.selectAll('.points').data(linedata).enter().append('g');

          //var area = d3.svg.area().interpolate('basis').x(function (d) {
          //    return getX(d.x);
          //}).y0(function (d) {
          //    return y(d.y0);
          //}).y1(function (d) {
          //    return y(d.y0 + d.y);
          //});

          var area = d3.layout.stack()
            .offset("zero")
            .x(function (d) {
                return getX(d.x);
            })
            .y(function (d) {
                return d.y;
            });

      point.append('path').attr('class', 'area').attr('d', function (d) {
              return area(d.values);
          }).style('fill', function (d, i) {
              return getColor(i);
          }).style('opacity', '0.7');

The code above gives me an error, if I do try to use the commented out code, I do not get a desirable result:

image

Also note that the above is not producing the series labels. I am quite sure it should be easy to pull a stacked area chart using d3, given certain experience with the library.

Could anybody assist me with this?

xaguzman commented 9 years ago

I did implement myself this. Is this a contribution the angular-charts would be interested in?

Asking since sometimes it seems the project is not that active anymore.