Stacked Bar Chart Transition

with explanation on function(d,i,j)...nested selections

by Nivaldo

HTML

<p>You're almost there -- you need to use .delay() to achieve this, as you're doing already. The only problem is that you're using a nested selection (i.e. <code>rects></code> within <code>g</code>'s) and the index you get is that of the inner selection. This is always 0 because there's only one rect per g. <p>To make it work, reference the secret third argument in a nested selection, which is the index within the data passed to the parent:</p><code>.delay(function(d,i,j){console.log('hi',d,j); return j*500;})</code>
</p>

<div id="tooltip" class="hidden">
    <p><span id="value">100</span></p>
</div>

CSS

.bar {
}
.axis path, .axis line {
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
}
.axis text {
    font-family: sans-serif;
    font-size: 11px;
}
#tooltip {
    position: absolute;
    text-align: center;
    width: 40px;
    height: auto;
    padding: 10px;
    background-color: white;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    pointer-events: none;
}
#tooltip.hidden {
    display: none;
}
#tooltip p {
    margin: 0;
    font-family: sans-serif;
    font-size: 16px;
    line-height: 20px;
}
.axis {
}

JavaScript

var margins = {
    top: 12,
    left: 48,
    right: 24,
    bottom: 24
},
legendPanel = {
    width: 240
},
width = window.innerWidth - margins.left - margins.right - legendPanel.width,
    height = 100 - margins.top - margins.bottom,
    dataset = [{
        data: [{
            month: 'Oct',
            count: 345
        }],
        name: 'Series #1'
    }, {
        data: [{
            month: 'Oct',
            count: 573
        }],
        name: 'Series #2'
    }, {
        data: [{
            month: 'Oct',
            count: 200
        }],
        name: 'Series #2'
    }, {
        data: [{
            month: 'Oct',
            count: 250
        }],
        name: 'Series #2'
    }

    ],
    series = dataset.map(function (d) {
        return d.name;
    }),
    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.count,
                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
        };
    });
}),
    svg = d3.select('body')
        .append('svg')
        .attr('width', width + margins.left + margins.right + legendPanel.width)
        .attr('height', height + margins.top + margins.bottom)
        .append('g')
        .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')'),
    xMax = d3.max(dataset, function (group) {
        return d3.max(group, function (d) {
            return d.x + d.x0;
        });

    }),
    xScale = d3.scale.linear().domain([0, xMax]).range([0, width]),
    months = dataset[0].map(function (d) {
        return d.y;
    }),
    _ = console.log(months),
    yScale =...