Thymeleaf循环中Chart.js水平柱状图显示及数据统计异常排查
问题解决指南:飞盘高尔夫计分系统Chart.js渲染与数据统计问题
一、循环中仅第一个图表显示的修复
在Thymeleaf的th:each循环内,每个canvas必须配置唯一动态ID,否则Chart.js只会绑定首个匹配元素。正确实现示例:
<div th:each="round, stat : ${rounds}"> <canvas th:id="'scoreChart-' + ${stat.index}" th:data-scores="${round.scores}"></canvas> </div>
JS端遍历所有目标canvas,通过动态ID+自定义属性初始化图表:
document.querySelectorAll('canvas[id^="scoreChart-"]').forEach(canvas => { // 从data属性获取对应分数数据 const scores = JSON.parse(canvas.dataset.scores); // 后续图表初始化逻辑... });
二、分数统计出现NaN的修复
从你提供的分数数组['2', ' 4', ' 4', ' 2', ' 3', ' 2', ' 3', ' 3', ' 3']可以看出,部分元素带有前置空格(如' 4'),直接转数字会因空格解析失败返回NaN。
具体修复步骤:
- 清洗数据:先去除每个分数字符串的前后空格,再转为数字(指定基数10避免八进制解析问题)
- 过滤无效值:移除转数字后产生的NaN
- 重新统计:基于清洗后的有效数据统计次数
完整的图表初始化代码示例:
document.querySelectorAll('canvas[id^="scoreChart-"]').forEach(canvas => { // 解析原始分数数据 const rawScores = JSON.parse(canvas.dataset.scores); // 清洗+过滤有效分数 const validScores = rawScores .map(score => parseInt(score.trim(), 10)) .filter(score => !isNaN(score)); // 统计分数出现次数 const scoreCounts = {}; validScores.forEach(score => { scoreCounts[score] = (scoreCounts[score] || 0) + 1; }); // 准备Chart.js所需的标签与数据 const labels = Object.keys(scoreCounts).sort((a,b) => a - b); const data = labels.map(label => scoreCounts[label]); // 初始化水平柱状图 new Chart(canvas, { type: 'bar', data: { labels: labels, datasets: [{ label: '分数统计', data: data, backgroundColor: 'rgba(54, 162, 235, 0.6)' }] }, options: { indexAxis: 'y', // 设置为水平柱状图 responsive: true, scales: { x: { beginAtZero: true } } } }); });
额外优化建议
- 后端传递分数时,优先使用
List<Integer>类型数组,避免前端处理字符串转数字的额外工作 - 若必须传递字符串格式分数,后端可提前做trim处理,减少前端逻辑复杂度
内容的提问来源于stack exchange,提问作者Kayd Anderson
相关产品推荐
相关产品推荐

