简体   繁体   中英

Updating a stacked bar chart in d3.js (includes JSFiddle)

jsfiddle example can be seen here

I'm expecting the chart to update correctly with the new dataset contained in the function "redraw", however this isn't happening.

Although the current rects are updated with the new dataset, the issue seems to be that the enter().append() part of the code isn't working:

var groups = svg.selectAll('g')
  .data(dataset, retd);

groups.style('fill', function (d, i) {
      return colours(i);
});

groups.enter()
  .append('g')
  .style('fill', function (d, i) {
      return colours(i);
});

groups.exit().remove();

//update the Rects
var rects = groups.selectAll('rect')
            .data(function (d) {
               return d;
            }, thisy);

rects.transition()
  .attr('x', function (d) {
      return xScale(d.x0);
  })
  .attr('y', function (d, i) {
      return yScale(d.y);
  })
  .attr('height', function (d) {
      return yScale.rangeBand();
  })
  .attr('width', function (d) {
      return xScale(d.x);
  });

rects.enter()
    .append('rect')
    .attr('x', function (d) {
        return xScale(d.x0);
    })
    .attr('y', function (d, i) {
        return yScale(d.y);
    })
    .attr('height', function (d) {
        return yScale.rangeBand();
    })
    .attr('width', function (d) {
        return xScale(d.x);
    });

Any help/insight would be appreciated.

Since the first draw worked fine, I turned it into a function. Only had to remove the already written SVG to make it reusable: JSFiddle

<button id="reset">Redraw</button>

<script>

document.getElementById('reset').onclick = function() {
    var dataset = [
        {"data":[
            {"IssueMonth":"Apr","IS":"350","month":"Apr"},
            {"IssueMonth":null,"IS":"100","month":"Aug"},
            {"IssueMonth":null,"IS":"0","month":"Dec"}],
         "name":"CHF"},
        {"data":[
            {"IssueMonth":null,"IS":"100","month":"Apr"},
            {"IssueMonth":null,"IS":"200","month":"Aug"},
            {"IssueMonth":null,"IS":"40","month":"Dec"}],
         "name":"GBP"}
    ];
    drawit(dataset);
}

var dataset = [
    {"data":[
        {"IssueMonth":"Apr","IS":"350","month":"Apr"},
        {"IssueMonth":null,"IS":"0","month":"Aug"},
        {"IssueMonth":null,"IS":"0","month":"Dec"}],
     "name":"CHF"},
    {"data":[
        {"IssueMonth":null,"IS":"100","month":"Apr"},
        {"IssueMonth":null,"IS":"0","month":"Aug"},
        {"IssueMonth":null,"IS":"50","month":"Dec"}],
     "name":"GBP"}
];

drawit(dataset);

function drawit(dataset) {

    var margins = {
        top: 40,
        left: 40,
        right: 40,
        bottom: 40
    };

    var width = 400;
    var height = 500 - margins.top - margins.bottom;

    var series = dataset.map(function (d) {
        return d.name;
    });

    var dataset = dataset.map(function (d) {
        return d.data.map(function (o, i) {
            // Structure it so that your numeric
            // axis (the stacked amount) is y
            return {
                y: +o.IS,
                x: o.month
            };
        });
    });

    stack = d3.layout.stack();

    stack(dataset);

    var dataset = dataset.map(function (group) {
        return group.map(function (d) {
            // Invert the x and y values, and y0 becomes x0
            return {
                x: d.y,
                y: d.x,
                x0: d.y0
            };
        });
    });

    d3.select("svg").remove();    
    var svg = d3.select('body')
    .append('svg')
    .attr('width', width + margins.left + margins.right)
    .attr('height', height + margins.top + margins.bottom)
    .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')')

    var xMax = d3.max(dataset, function (group) {
        return d3.max(group, function (d) {
            return d.x + d.x0;
        });
    })

    var xScale = d3.scale.linear()
    .domain([0, xMax])
    .range([0, width]);

    var months = dataset[0].map(function (d) {
        return d.y;
    });

    var yScale = d3.scale.ordinal()
    .domain(months)
    .rangeRoundBands([0, height], .1);

    var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient('bottom');

    var yAxis = d3.svg.axis()
    .scale(yScale)
    .orient('left');

    var colours = d3.scale.category20();

    var groups = svg.selectAll('g')
    .data(dataset)
    .enter()
    .append('g')
    .style('fill', function (d, i) {
        return colours(i);
    });

    var rects = groups.selectAll('rect')
    .data(function (d) {
        return d;
    })
    .enter()
    .append('rect')
    .attr('x', function (d) {
        return xScale(d.x0);
    })
    .attr('y', function (d, i) {
        return yScale(d.y);
    })
    .attr('height', function (d) {
        return yScale.rangeBand();
    })
    .attr('width', function (d) {
        return xScale(d.x);
    });

    svg.append('g')
    .attr('class', 'x axis')
    .attr('transform', 'translate(0,' + height + ')')
    .call(xAxis);

    svg.append('g')
    .attr('class', 'y axis')
    .call(yAxis);
}

</script>

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