如何使用Chart.js为折线图上的数据点添加脉动动画?
给Chart.js折线图的特定数据点添加动画效果
要突出显示x=February、y=25这个数据点(对应数据索引1),可以通过以下两种实用方式实现动画效果:
方法1:利用内置动画回调实现点的缩放闪烁
修改原有配置与脚本,通过animation回调结合循环渲染,让目标数据点呈现缩放闪烁的动画:
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <canvas id="myLineChart" width="400" height="200"></canvas> <script> // 折线图示例数据 var data = { labels: ['January', 'February', 'March', 'April', 'May'], datasets: [{ label: 'Sample Data', data: [10, 25, 18, 30, 15], borderColor: 'blue', backgroundColor: 'rgba(0, 0, 255, 0.2)', fill: true, pointRadius: 5, // 默认点半径 pointHoverRadius: 5 }] }; // 目标数据点索引(February对应第2个元素,索引为1) const targetPointIndex = 1; let isScalingUp = true; let currentRadius = 5; // 配置选项 var options = { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'category', labels: data.labels, }, }, animation: { duration: 500, onComplete: function() { // 循环触发动画更新 requestAnimationFrame(() => { // 调整目标点的半径 currentRadius = isScalingUp ? currentRadius + 2 : currentRadius - 2; if (currentRadius >= 10 || currentRadius <=5) { isScalingUp = !isScalingUp; } // 更新目标点半径并重新渲染 myLineChart.data.datasets[0].pointRadius.forEach((r, idx) => { myLineChart.data.datasets[0].pointRadius[idx] = idx === targetPointIndex ? currentRadius : 5; }); myLineChart.update(); }); } } }; // 获取画布元素 var ctx = document.getElementById('myLineChart').getContext('2d'); // 创建折线图 var myLineChart = new Chart(ctx, { type: 'line', data: data, options: options }); </script> </body> </html>
代码说明:
- 用
targetPointIndex = 1定位February对应的数据点 - 通过
animation.onComplete回调结合requestAnimationFrame实现循环动画 - 动态调整目标点的
pointRadius,超出设定范围后反转缩放方向,形成闪烁效果
方法2:自定义插件绘制脉动外圈动画
如果需要更灵活的视觉效果(比如颜色变化的脉动圈),可以通过Chart.js自定义插件实现:
<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <canvas id="myLineChart" width="400" height="200"></canvas> <script> // 自定义高亮动画插件 const highlightPointPlugin = { id: 'highlightPoint', afterDraw: (chart) => { const ctx = chart.ctx; const targetIndex = 1; // February对应的索引 const meta = chart.getDatasetMeta(0); const point = meta.data[targetIndex]; // 获取目标点的坐标 const x = point.x; const y = point.y; // 基于时间计算脉动半径 const time = Date.now() % 1000; const radius = 5 + (Math.sin(time * 0.005) * 3); // 绘制半透明红色脉动外圈 ctx.save(); ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2); ctx.fillStyle = 'rgba(255, 0, 0, 0.3)'; ctx.fill(); ctx.restore(); } }; // 折线图示例数据 var data = { labels: ['January', 'February', 'March', 'April', 'May'], datasets: [{ label: 'Sample Data', data: [10, 25, 18, 30, 15], borderColor: 'blue', backgroundColor: 'rgba(0, 0, 255, 0.2)', fill: true, pointRadius: 5, pointBackgroundColor: 'blue' }] }; // 配置选项 var options = { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'category', labels: data.labels, }, }, animation: { duration: 0, // 禁用默认动画,交由自定义插件控制 } }; // 获取画布元素 var ctx = document.getElementById('myLineChart').getContext('2d'); // 创建折线图并注册自定义插件 var myLineChart = new Chart(ctx, { type: 'line', data: data, options: options, plugins: [highlightPointPlugin] }); // 触发持续重绘实现动画 function animate() { myLineChart.draw(); requestAnimationFrame(animate); } animate(); </script> </body> </html>
代码说明:
- 自定义插件
highlightPoint在afterDraw阶段绘制脉动外圈 - 通过
Date.now()获取时间,结合正弦函数实现平滑的半径变化 - 调用
requestAnimationFrame持续重绘,形成流畅的脉动动画
内容的提问来源于stack exchange,提问作者Ero Stefano
相关产品推荐
相关产品推荐

