D3: how to get the bars on a bar chart to float directly downward, but only when scrolling to that element?

I’m using D3 to create a bar chart that looks like this:

enter image description here

Currently, the bars are floating in on an angle from the top left corner (because of the D3 coordinate system). I would like the bars to float directly downward, but only when the user scrolls to that part of the page (note: the page is quite lenghty and it would take a few minutes for the user to scroll to that element).

Here is my code:

    let data = [
{"color": "Blue", "plotValue": 11},
{"color": "Red", "plotValue": 20},
{"color": "Orange", "plotValue": 21},
{"color": "Purple", "plotValue": 30},
{"color": "Green", "plotValue": 35},
{"color": "Violet", "plotValue": 40},
               ]


        vis.margin = {top: 70, right: 90, bottom: 90, left: 80};
        vis.width = 800 - vis.margin.left - vis.margin.right;

        // initialize the drawing area
        vis.svg = d3.select('#' + vis.parentElement).append('svg')
            .attr('width', vis.width + vis.margin.left + vis.margin.right)
            .attr('height', vis.height + vis.margin.top + vis.margin.bottom)
            .append('g')
            .attr('transform', `translate (${vis.margin.left}, ${vis.margin.top})`);


        // scales and axes
        vis.xScale = d3.scaleBand()
            .range( [ 0, vis.width ] )
            .padding(0.4);

        vis.yScale = d3.scaleLinear()
            .range( [ vis.height, 0 ] );

        vis.xAxis = d3.axisBottom()
            .scale(vis.xScale);

        vis.yAxis = d3.axisLeft()
            .scale(vis.yScale);

        // add chart title
        vis.svg.append('g')
            .attr('class', 'title bar-chart-title')
            .append('text')
            .text(vis.chartTitle)
            .attr('transform', `translate(${vis.width / 2 + 45}, -50)`)
            .attr('text-anchor', 'middle');

        // tooltip
        vis.tooltip = d3.select('body').append('div')
            .attr('class', 'tooltip')
            .attr('id', 'barChartTooltip');


        // create the axis groups
        vis.xAxisGroup = vis.svg.append('g')
            .attr('class', 'x-axis axis')
            .attr('transform', 'translate(0, ' + vis.height + ')');

        vis.yAxisGroup = vis.svg.append('g')
            .attr('class', 'y-axis axis');



        let vis = this;

        // update the domains
        vis.xScale.domain(vis.data.map(function (d) { return d.color; }));
        vis.yScale.domain( [ 0, 100 ] );

        // draw the bars
        vis.bars = vis.svg.selectAll('.bar')
            .data(vis.data)

        vis.bars.exit().remove();

        vis.bars
            .enter()
            .append('rect')
            .attr('class', 'bar')
            .on('mouseover', function(event, d) {
                d3.select(this)
                    .attr('stroke-width', '2px')
                    .attr('stroke', 'grey')
                    .attr('fill', 'blue')

                vis.tooltip
                    .style('opacity', 1)
                    .style('left', event.pageX + 20 + 'px')
                    .style('top', event.pageY + 'px')
                    .html(`
                    <div style='border: thin solid grey; border-radius: 5px; background: lightgrey; padding: 20px'>
                    <h3>${d.color}</h3>
                    <h4> ${100- d.plotValue.toLocaleString()}% decline </h4>
                    </div>
                                        
                    `)

            })
            .on('mouseout', function(event, d) {
                d3.select(this)
                    .attr('stroke-width', 1)
                    .attr('stroke', '#456983')
                    .attr('fill', function(d) {
                        return 'red'
                    })

                vis.tooltip
                    .style('opacity', 0)
                    .style('left', 0)
                    .style('top', 0)
                    .html(``);

            })
            .merge(vis.bars)
            .transition()
            .duration(1200)
            .attr('x', d => vis.xScale(d.color) )
            .attr('y', d => vis.yScale(d.plotValue) )
            .attr('width', vis.xScale.bandwidth() )
            .attr('height', function(d) { return vis.height - vis.yScale(d.plotValue); })
            .attr('fill', 'red')
//            .attr('stroke', 'grey');


        // add the axes
        vis.xAxisGroup
            .transition()
            .duration(500)
            .style('font-size', '15px')
            .style('color', 'blue')
            .call(d3.axisBottom((vis.xScale)))
            .selectAll('text')
            .attr('y', 30)
            .attr('x', -35)
            .attr('dy', '.35em')
            .attr('transform', 'rotate(-30)')
        ;

        vis.yAxisGroup
            .transition()
            .duration(500)
            .style('font-size', '15px')
            .style('color', 'blue')
            .call(d3.axisLeft(vis.yScale));

        vis.text = vis.svg.selectAll('.text')
            .data(vis.data)

        vis.text
            .enter()
            .append('text')
            .attr('class', 'text')
            .attr('text-anchor', 'middle')
            .attr('x', d => vis.xScale(d.color) + 27)
            .attr('y', d => vis.yScale(d.plotValue) - 10)
            .text( function (d) {
                return '-' + (100 - d.plotValue) + '%';
            })

How would I amend my code to get the bars to float directly downward, and only triggered when the user scrolls to that part of the page?

Thanks in advance for any advice you can give!