I was trying to think of different ways of animating and this was one of my first thoughts. Used a line to create the bars instead of rects.
xxxxxxxxxx
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 30},
width = 960 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var svg = d3.select('body').append('svg')
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + [margin.left, margin.top] + ')');
var x = d3.scaleBand()
.range([0,width])
.padding(.1);
var y = d3.scaleLinear()
.range([height,0]);
var data = [
{x: 0, y: 10},
{x: 1, y: 12},
{x: 2, y: 8},
{x: 3, y: 15},
{x: 4, y: 3},
{x: 5, y: 20}
];
x.domain(data.map(x => x.x));
y.domain([0,d3.max(data, d => d.y)]);
svg.append('g')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(x));
svg.append('g')
.call(d3.axisLeft(y))
var lineData = [];
var lineDataAfter = [];
data.forEach(d => {
lineData.push({x: x(d.x), y: 0});
lineData.push({x: x(d.x), y: d.y});
lineData.push({x: x(d.x) + x.bandwidth(), y: d.y});
lineData.push({x: x(d.x) + x.bandwidth(), y: 0});
lineDataAfter.push({x: x(d.x), y: 0});
lineDataAfter.push({x: x(d.x) - 20, y: d.y + d.y/8});
lineDataAfter.push({x: x(d.x) + x.bandwidth() + 20, y: d.y + d.y/8});
lineDataAfter.push({x: x(d.x) + x.bandwidth(), y: 0});
})
var line = d3.line()
.x(d => d.x)
.y(d => y(d.y))
.curve(d3.curveMonotoneX);
var linePath = svg.append('path')
.datum(lineData)
.attr('d', line)
.attr('fill', 'pink')
.attr('stroke', 'steelblue')
.attr('stroke-width', 3)
.transition().duration(1000)
.ease(d3.easeElastic)
.attr('d', line(lineDataAfter))
.transition().duration(1000)
.ease(d3.easeElastic)
.attr('d', line)
</script>
</body>
https://d3js.org/d3.v5.min.js