Chart.js 饼图更新月度数据后不渲染无报错如何解决
问题原因及修复方案
核心问题出在以下4处代码逻辑错误:
- 未对AJAX返回的JSON字符串做解析:jQuery的
$.ajax默认不会自动解析返回的JSON字符串,除非手动指定dataType: 'json',否则拿到的monthly_stats是字符串类型,遍历操作无法正确提取字段值,最终转成数字后都是NaN,无有效数据自然不会渲染图表,也不会抛出错误。 - 数据集赋值路径错误:Chart实例的
datasets是数组类型,原有赋值语句userDiaryMonthSessionStatsChart.data.datasets.data = userMonthlySessionStatsData是给数组本身加了个data属性,根本没有赋值到第一个数据集的data字段,正确路径应为userDiaryMonthSessionStatsChart.data.datasets[0].data。 - 重复创建图表实例:每次切换月份触发请求时,都在同一个canvas元素上新建Chart实例,旧实例没有销毁会导致渲染冲突,甚至完全不渲染。
- 初始化数据集data类型错误:初始化图表时给
datasets[0].data赋值的是空对象{},而Chart要求该字段必须是数组类型,也会导致初始化异常。
修复后完整代码
// 全局保留图表实例引用,避免重复创建 let userDiaryMonthSessionStatsChart = null; $.ajax({ url: "../diary/includes/training/diary-training-monthly-session-stats.php?month=" + month + "&year=" + year, type: "GET", // 指定返回数据类型为json,自动解析 dataType: "json", success: function(monthly_stats) { // 直接取返回数组第一个元素即可,不需要循环 const stats = monthly_stats[0]; const userMonthlySessionStatsData = [ parseInt(stats.session_intervall), parseInt(stats.session_longrun), parseInt(stats.session_speedwork), parseInt(stats.session_stabilisation), parseInt(stats.session_competition), parseInt(stats.session_cycling), parseInt(stats.session_swimming) ]; const options = { legend: { display: false }, plugins: { labels: { render: 'value', fontSize: 14, fontStyle: 'bold', fontColor: '#fff', textShadow: true, shadowColor: 'rgba(0,0,0,0.75)' } } }; const ctx = $("#monthy_session_stats"); // 先销毁旧实例 if(userDiaryMonthSessionStatsChart) { userDiaryMonthSessionStatsChart.destroy(); } // 新建实例时直接传入正确数据,不需要后续再赋值更新 userDiaryMonthSessionStatsChart = new Chart(ctx, { type: 'pie', data: { datasets: [{ data: userMonthlySessionStatsData, backgroundColor: ['#e8e838', '#43bbd1', '#ff9f40', '#49d1b8', '#4286c9', '#38c7a1', '#ff497d'] }], labels: ['Intervall', 'Longrun', 'Speedwork', 'Stabilisation', 'Competition', 'Cycling', 'Swimming'] }, options: options }); } })
效果参考

内容的提问来源于stack exchange,提问作者Sven Lorenzino
相关产品推荐
相关产品推荐

