PHP中chartjs-plugin-zoom插件鼠标/移动端缩放失效如何解决
问题背景
- 数据库存储200余条业务数据
- 需求:图表默认仅展示最后5条数据,支持用户通过滚动、缩放操作浏览全量图表数据
- 异常:完成配置后,鼠标滚轮缩放、移动端触控缩放功能均无法正常生效
现有脚本引入
<!-- JQUERY --> <script src="<?= base_url() ?>assets/js/jquery.js"></script> <script src="<?= base_url()?>assets/js/jquery/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8"></script> <script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8/hammer.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js@3.8.0/dist/chart.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@1.2.1/dist/chartjs-plugin-zoom.min.js"></script>
现有业务代码
后端数据拉取函数
function datagrafico(base_url){ $.ajax({ url: base_url + "index.php/Admin/getDataDias", type:"POST", dataType:"json", success:function(data){ var dias = new Array(); var montos = new Array(); $.each(data,function(key, value){ dias.push(value.fecha_actualizacion); valor = Number(value.monto); montos.push(valor); }); grafica2(dias,montos); } }); }
图表渲染函数
function grafica2(dias, montos) { const ctx = document.getElementById('myChart').getContext('2d'); const myChart = new Chart(ctx, { type: 'bar', data: { labels: dias, datasets: [{ label: 'Monto', data: montos, backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1, }] }, options: { scales: { y: { beginAtZero: true }, plugins: { zoom: { pan: { enabled: true, mode: 'xy' }, zoom: { enabled: true, mode: 'xy' } }, } } } }); }
问题原因与修复方案
核心问题点
- 配置层级错误:zoom插件配置被错误放在
options.scales.plugins节点下,Chart.js规定所有插件配置必须和scales节点平级,放在options.plugins路径下,层级错误会导致配置完全不生效。 - 重复引入依赖:当前代码重复引入2次jQuery、2次Hammer.js、2次Chart.js,后加载的脚本会覆盖全局对象,导致之前注册的zoom插件失效。
- 缺少缩放场景开关:仅配置
zoom.enabled = true不会默认开启滚轮、双指触控能力,需要显式开启对应场景的开关。 - 未配置默认展示范围:现有代码没有设置x轴初始显示区间,加载后会默认展示全量数据,不符合默认显示最后5条的需求。
修复后代码
1. 清理重复的脚本引入,每个依赖仅保留一份
<!-- JQUERY 仅保留压缩版 --> <script src="<?= base_url()?>assets/js/jquery/jquery.min.js"></script> <!-- Hammer.js 触控依赖,放在Chart.js之前加载,仅保留压缩版 --> <script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8/hammer.min.js"></script> <!-- Chart.js 保留和zoom插件兼容的3.8.0版本,删除重复的无版本引入 --> <script src="https://cdn.jsdelivr.net/npm/chart.js@3.8.0/dist/chart.min.js"></script> <!-- 缩放插件 --> <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@1.2.1/dist/chartjs-plugin-zoom.min.js"></script>
2. 修正图表渲染配置
function grafica2(dias, montos) { const ctx = document.getElementById('myChart').getContext('2d'); const totalDataLen = dias.length; const myChart = new Chart(ctx, { type: 'bar', data: { labels: dias, datasets: [{ label: 'Monto', data: montos, backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true }, x: { // 配置默认展示最后5条数据 min: totalDataLen - 5, max: totalDataLen - 1 } }, // 插件配置移到和scales平级的正确层级 plugins: { zoom: { pan: { enabled: true, mode: 'x' // 柱状图仅需横向平移即可,需要双向可改回xy }, zoom: { wheel: { enabled: true // 开启鼠标滚轮缩放 }, pinch: { enabled: true // 开启移动端双指捏合缩放 }, mode: 'x' // 柱状图仅需横向缩放即可,需要双向可改回xy } } } } }); }
替换后清空浏览器缓存刷新即可生效,默认加载会显示最后5条数据,鼠标滚轮、双指捏合缩放、拖拽平移功能均可正常使用,用户可自由浏览全量数据。
内容的提问来源于stack exchange,提问作者Robinson Davis Villabon Trujil
相关产品推荐
相关产品推荐

