score:3

Accepted answer

The main problems were with the application of the enter/update/exit pattern and also with forgetting to re-set the scale domains according to the new data. Here is the segment of interest:

function update() {
    data = [20, 10, 3];

    // must re-set scale domains with the new data
    x.domain([0, d3.max(data)]);
    y.domain(data);

    var outer = chart.selectAll(".bar-outer")
        .data(data);

    // exit selection
    outer
        .exit()
        .remove();

    // enter selection
    outer
      .enter()
      .append("rect")
        .attr('class', 'bar-outer');

    // update selection
    outer
        .transition()
        .duration(500)
        .ease("quad")
        .attr("x", leftWidth)
        .attr("y", y)
        .attr("width", x)
        .attr("height", y.rangeBand());

    var inner = chart.selectAll(".bar-inner")
        .data(data);

    // exit selection
    inner
        .exit()
        .remove();

    // enter selection
    inner
      .enter()
      .append("rect")
        .attr('class', 'bar-inner');

    // update selection
    inner
        .transition()
        .duration(500)
        .ease("quad")
        .attr("x", leftWidth)
        .attr("y", function (d) {
            return y(d) + barTopMargin
        })
        .attr("width", function (d) {
            return x(d) / 2;
        })
        .attr("height", barHeightInner);
};

Here is the complete FIDDLE.


Related Query