Chart.js v3 延迟淡入淡出动画

Chart.js v3 Fade Animation in delay

我正在尝试使用 Chart.js 创建图表。我让一切都按我想要的方式工作,唯一剩下的就是动画总是从下往上浮动到位。我只想要一个淡入动画,但找不到任何关于如何做到这一点的信息。

甚至可以在 Chart.js 中制作淡入淡出动画吗?到目前为止,这是我的代码: #代码

编辑:

我可以使用 v3,但是我为此图表创建的函数现在不能正常工作。在视图中滚动后,我启动图表动画 1 秒。到那时,折线图已隐藏,只显示条形图。再过 1.5 秒后,线条应该会在原地淡入。 我过去常常通过首先隐藏线并在延迟后取消隐藏并更新图表来做到这一点。更新图表现在也会重置条形动画。在 v2 中它没有这样做。有没有办法让动画一个接一个地播放?

另外,由于更新,插件数据标签不再起作用。 v3 有替代方案吗?

这是我的代码:

<div class="chartcontainer">
    <div class="chartcontainer--inner">
        <script src="https://unpkg.com/chart.js@3.0.0-beta/dist/chart.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
        <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-deferred"></script>
        <style type="text/css">
            @media screen and (min-width: 1100px) {
                #myChart {min-height: 540px}
            }
            .chartcontainer {max-width: 67.625rem; margin-right: auto; margin-left: auto; overflow: hidden;}
            @media screen and (max-width: 700px){
                .chartcontainer--inner {width: 50rem;}
                .chartcontainer {overflow: scroll;}

            }
        </style>
        <canvas id="myChart"></canvas>
        <script type="text/javascript">
            var inView = false;

            function isScrolledIntoView(elem)
            {
                var docViewTop = $(window).scrollTop();
                var docViewBottom = docViewTop + $(window).height();

                var elemTop = $(elem).offset().top;
                var elemBottom = elemTop + $(elem).height();

                return ((elemTop <= docViewBottom) && (elemBottom >= docViewTop));
            }

            $(window).scroll(function() {
                if (isScrolledIntoView('#myChart') && !inView) {
                    // if (inView) { return; }
                    inView = true;

               console.log('in View: '+ inView);
                    
                    setTimeout(function(){

                        var ctx = document.getElementById('myChart').getContext('2d');
                        myChart = new Chart(ctx, {
                            type: 'bar',
                            data: {
                                labels: ['2018', '2019', '2020'],
                                datasets: [{
                                    label: ['a'],
                                    data: [7.1, 6.6, 6.6],
                                    backgroundColor: [
                                        '#05368b',
                                        '#05368b',
                                        '#05368b'
                                    ],
                                    order: 2
                                },{
                                    label: ['b'],
                                    data: [6.5, 6.4, 6.7],
                                    backgroundColor: [
                                        '#1792d7',
                                        '#1792d7',
                                        '#1792d7'
                                    ],
                                    order: 2
                                },{
                                    label: ['c'],
                                    data: [6.1, 5.8, 6.1],
                                    backgroundColor: [
                                        '#6c2475',
                                        '#6c2475',
                                        '#6c2475'
                                    ],
                                    order: 2
                                },{
                                    label: ['d'],
                                    data: [5.7, 5.8, 5.8],
                                    backgroundColor: [
                                        '#0d60b5',
                                        '#0d60b5',
                                        '#0d60b5'
                                    ],
                                    order: 2
                                },{
                                    label: ['e'],
                                    data: [4.3, 6.1, 6.3],
                                    type: 'line',
                                    lineTension: 0.4,
                                    borderColor: "#f48d3b",
                                    fill: false,
                                    pointBackgroundColor: function() {
                                        var color = "rgba(244, 141, 59, 1)";
                                        console.log(color);
                                        return color;
                                    },
                                    pointRadius: function(context) {
                                        var width = context.chart.width;
                                        var size = Math.round(width / 42);
                                        console.log(size);
                                        return size
                                    },
                                    borderWidth: 1,
                                    order: 1,
                                    hidden: true,
                                    borderWidth: 5
                                }]
                            },
                            options: {
                                tooltips: {enabled: false},
                                hover: {mode: null},
                                scales: {
                                    yAxes: [{
                                        ticks: {
                                            beginAtZero: true
                                        },
                                        gridLines: {
                                            color: '#eee'
                                        }
                                    }],
                                    xAxes: [{
                                        gridLines: {
                                            color: '#eee'
                                        }
                                    }]
                                },
                                legend: {
                                    position: 'bottom',
                                    labels: {
                                        padding: 20
                                    }
                                },
                                plugins: {
                                    datalabels: {
                                        align: 'top',
                                        anchor: 'start',
                                        color: 'white',
                                        // offset: 6,
                                        font: function(context) {
                                            var width = context.chart.width;
                                            var size = Math.round(width / 42);
                                            return {
                                                size: size
                                            };
                                        }
                                    }
                                }
                            }
                        });


                    }, 1000);

                    setTimeout(function(){
                        console.log(myChart.config.data.datasets[4].hidden);
                        myChart.config.data.datasets[4].hidden = false;
                        myChart.config.options.animation = {numbers: { duration: 0 },colors: {type: "color",duration: 1000,from: "transparent",}};
                        myChart.update();
                    }, 2500);


                } else {
                    // inView = false;  
                }
            });
        </script>
    </div>
</div>

对于 Chart.js v3,您可以使用以下动画选项:

chart.options.animation = {
  numbers: { duration: 0 },
  colors: {
    type: "color",
    duration: 1000,
    from: "transparent",
  }
}

对于 v2,我认为它们不提供对动画的任何 fine-grain 控制。如果这对您很重要,您可能需要更新到 v3。

附上显示效果的片段。

var ctx = document.getElementById('myChart').getContext('2d');

myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['2018', '2019', '2020'],
        datasets: [{
            label: ['x'],
            data: [7.1, 6.6, 6.6],
            backgroundColor: [
                '#05368b',
                '#05368b',
                '#05368b'
            ],
            order: 2
        },{
            label: ['y'],
            data: [6.5, 6.4, 6.7],
            backgroundColor: [
                '#1792d7',
                '#1792d7',
                '#1792d7'
            ],
            order: 2
        },{
            label: ['z'],
            data: [6.1, 5.8, 6.1],
            backgroundColor: [
                '#6c2475',
                '#6c2475',
                '#6c2475'
            ],
            order: 2
        },{
            label: ['n'],
            data: [5.7, 5.8, 5.8],
            backgroundColor: [
                '#0d60b5',
                '#0d60b5',
                '#0d60b5'
            ],
            order: 2
        },{
            label: ['av'],
            data: [4.3, 6.1, 6.3],
            type: 'line',
            lineTension: 0.4,
            borderColor: "#f48d3b",
            fill: false,
            pointBackgroundColor: function() {
                var color = "rgba(244, 141, 59, 1)";
                console.log(color);
                return color;
            },
            pointRadius: function(context) {
                var width = context.chart.width;
                var size = Math.round(width / 42);
                console.log(size);
                return size
            },
            borderWidth: 1,
            order: 1,
            hidden: true,
            borderWidth: 5
        }]
    },
    options: {
        animation: {
          numbers: { duration: 0 },
          colors: {
            type: "color",
            duration: 1000,
            from: "transparent",
          },
        },
        tooltips: {enabled: false},
        hover: {mode: null},
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                },
                gridLines: {
                    color: '#eee'
                }
            }],
            xAxes: [{
                gridLines: {
                    color: '#eee'
                }
            }]
        },
        legend: {
            position: 'bottom',
            labels: {
                padding: 20
            }
        },
        plugins: {
            datalabels: {
                align: 'top',
                anchor: 'start',
                color: 'white',
                // offset: 6,
                font: function(context) {
                    var width = context.chart.width;
                    var size = Math.round(width / 42);
                    return {
                        size: size
                    };
                }
            }
        }
    }
});
<script src="https://unpkg.com/chart.js@3.0.0-beta/dist/chart.min.js"></script>

<canvas id="myChart"></canvas>

我让它按预期工作了!我又回到了v2,因为v3带来了太多麻烦。

在修改 v3 时,我意识到我的 v2 版本有效,因为在 v2 中更新不会重置动画。所以我的回答是基于此。如果你调用 .update(0) 更新会在没有动画的情况下发生。所以我装箱了这个:

setTimeout(function(){
    myChart.config.data.datasets[4].hidden = false;
    myChart.update(0);
    fadeLoop();
}, 2500);

var i = 0.15;

function fadeLoop() {
    setTimeout(function() {
        myChart.config.data.datasets[4].pointBackgroundColor = "rgba(244, 141, 59, " + i +")";
        myChart.config.data.datasets[4].borderColor = "rgba(244, 141, 59, " + i +")";
        myChart.update(0);
        i += 0.05; 
        i = Math.round(i * 100) / 100;
        if (i <= 1) fadeLoop();
    }, 10)
}

因为我的 Line Fade-in 动画应该在 Bar 动画之后开始,所以我用隐藏属性初始化了 。 2.5 秒后,我删除了隐藏属性并启动了 FadeLoop。

我每 0.01 秒以 0.05 为增量从 0.15 数到 1。在循环中,我更新了线条的 BG 和边框颜色,并“无动画”地更新了它。

这不是最有效的方法,我不建议将其用于较大的图表或速度较慢的网站。不过对我来说已经足够了。