score:1

Accepted answer

You have many options depending on what exactly you mean by 'reversing' the bars.

If you want to keep the keys but reverse the axis, you can change the range in x_scale:

var x_scale = d3.scaleBand()
    .domain( d3.range( data.length ) )
    .rangeRound([ chart_width, 0 ])
    .paddingInner( 0.05 );

If you also want to change the underlying array, you could just update the keys:

data = data.map(d => ({
    key: data.length - d.key - 1,
    num: d.num
}));

But you also need to notify d3 about the change. Using the update-enter-exit pattern, you should modify the last function of your example:

d3.select( '#reverse' ).on( 'click', function(){
data = data.map((d, i) => ({
    key: data.length - d.key - 1,
    num: d.num
}));
// do something to reverse the order, not sure what to do here
svg.selectAll( 'rect' )
    .data( data )
    .transition()
    .attr( 'x', function( d, i ){
        return x_scale( d.key );
    });
});

Finally, with your example:

var data            =   [
    { key: 0, num: 6 },
    { key: 1, num: 20 }
];

var key             =   function(d){
    return d.key;
};

// Create SVG Element
var chart_width     =   800;
var chart_height    =   400;
var bar_padding     =   5;
var svg             =   d3.select( '#chart' )
    .append( 'svg' )
    .attr( 'width', chart_width )
    .attr( 'height', chart_height );

var x_scale         =   d3.scaleBand()
    .domain( d3.range( data.length ) )
    .rangeRound([ 0, chart_width ])
    .paddingInner( 0.05 );
var y_scale         =   d3.scaleLinear()
    .domain([
        0, d3.max(data, function( d ){
            return d.num;
        })
    ])
    .range([ 0, chart_height ]);

// Bind Data and create bars
svg.selectAll( 'rect' )
    .data( data, key )
    .enter()
    .append( 'rect' )
    .attr( 'x', function( d, i ){
        return x_scale( i );
    })
    .attr( 'y', function(d ){
        return chart_height - y_scale(d.num);
    })
    .attr( 'width', x_scale.bandwidth() )
    .attr( 'height', function( d ){
        return y_scale(d.num);
    });

// Events
d3.select( '#reverse' ).on( 'click', function(){
    data = data.map((d, i) => ({
        key: data.length - d.key - 1,
        num: d.num
    }));
    // do something to reverse the order, not sure what to do here
    svg.selectAll( 'rect' )
        .data( data )
        .transition()
        .attr( 'x', function( d, i ){
            return x_scale( d.key );
        });
});
#chart svg{
    /* width: 800px;
    height: 400px; */
    display: block;
    background-color: #f7f7f7;
    margin: 0 auto;
}
button{
    display: block;  
    margin: 0 auto; 
}
<!DOCTYPE html>
<html>

    <meta charset="utf-8">
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <body>  
        <div id="chart">
        </div>
        <br/>
        <button id ="reverse" type="button">
            Reverse Array
        </button>
    </body>
</html>

Note that in the above examples I used ES6 notation.

score:1

the simplest is to just reverse the element in the data array and use the index to get the x-coord

d3.select( '#reverse' ).on( 'click', function(){
    data.reverse();
    svg.selectAll( 'rect' )
        .data( data )
        .transition()
        .attr( 'x', function( d, i ){
            return x_scale( i );
        });
});

Related Query

More Query from same tag