Chart.js点击横向柱状图滚动到区域报错:Uncaught TypeError求助
问题:点击Chart.js横向柱状图报错并无法跳转对应区块
问题场景
用Chart.js制作了展示各国交通数据的横向堆叠柱状图,希望点击图表柱子时页面平滑滚动到下方对应ID的section,但一直弹出错误:Uncaught TypeError: Cannot read properties of undefined (reading 'link'),尝试多种写法24小时仍未解决。
报错原因分析
- Link与Section ID不匹配:部分dataset的
link属性值和页面section的ID不一致,既会导致跳转失效,也可能触发后续逻辑的隐性错误 - 事件绑定方式不可靠:直接给canvas元素绑定
onclick事件,配合getElementsAtEventForMode获取点击元素,在堆叠柱状图场景下可能获取到无效的datasetIndex,导致读取dataset.link时出现undefined错误 - 缺少严谨的空值校验:未对
dataset做存在性校验,当firstPoint的datasetIndex超出数据集范围时,直接访问dataset.link会抛出异常
修复方案
- 修正Link与Section ID的对应关系:确保每个dataset的
link值和页面section的ID完全匹配 - 改用Chart.js内置事件回调:在图表配置的
options中添加onClick回调,Chart.js会自动处理点击事件并传递正确的点击元素信息 - 增加多层空值校验:依次校验点击元素、数据集的存在性,避免访问undefined属性
完整修正代码
<script> var xValues = [['California', 'United States'], ['New York City', 'United States'], ['London','United Kingdom'], ['Paris','France'], ['Shanghai', 'China'], ['Hong Kong'], ['Kuala Lumpur', 'Malaysia'], "Singapore"]; Chart.defaults.global.backgroundColor = '#f9f9f9' Chart.defaults.global.defaultFontColor = '#f9f9f9' const config = { type: "horizontalBar", data: { labels: xValues, datasets: [ { label: 'Bicycle/Electric Bikes', backgroundColor: "rgba(160, 206, 128, 0.8)", data: [0.8, 1.5, 5.6, 3.25, 20, 1, 0.3, 2.08], maxBarThickness: 30, link: '#data-bicycle' }, { label: 'Electric Car', backgroundColor: "rgba(249, 199, 132, 0.8)", data: [25, 2.5, 34.3, 25.26, 4.87, 1.1, 1.15, 0.2], maxBarThickness: 30, link: '#data-car' // 修正:匹配section的ID }, { label: 'Electric Bus/Trolley Bus', backgroundColor: "rgba(237, 106, 90, 0.8)", data: [4.7, 12, 5.15, 7.64, 11.11, 0.83, 0.77, 0.79], maxBarThickness: 30, link: '#data-bus' }, { label: 'Tram', backgroundColor: "rgba(205, 160, 204, 0.8)", data: [2, 0.08, 1.81, 16.3, 0, 3.1, 0, 0], maxBarThickness: 30, link: '#data-tram' }, { label: 'Metro/Trains', backgroundColor: "rgba(81, 163, 163, 0.8)", data: [2.68, 66.59, 49.22, 32.6, 49.39, 56, 19.14, 62.4], maxBarThickness: 30, link: '#data-trains' // 修正:匹配section的ID }, { label: 'Electric Ships', backgroundColor: "rgba(52, 107, 134, 0.8)", data: [0.002, 0.24, 0.16, 0.06, 0.04, 0.2, 0, 0.02], maxBarThickness: 30, link: '#data-ship' }, { label: 'Others', backgroundColor: "rgba(249, 249, 249, 0.2)", data: [64.818, 17.09, 3.76, 14.89, 14.59, 37.77, 78.64, 34.51], maxBarThickness: 30, link: '#data-other' } ], }, options: { legend: { display: true, }, title: { display: false, }, scales: { xAxes: [{ ticks: { min: 0, max: 100, }, type: 'linear', stacked: true, gridLines: { color: 'rgba(255, 255, 255, 0.1)' }, afterTickToLabelConversion : function(q){ for(var tick in q.ticks){ q.ticks[tick] += '%'; } }, }], yAxes: [{ stacked: true, gridLines: { display: false, }, }], }, responsive: true, maintainAspectRatio: false, // 改用Chart.js内置的onClick回调 onClick: function(event, elements) { if (elements.length > 0) { const firstElement = elements[0]; const dataset = this.data.datasets[firstElement._datasetIndex]; // 增加dataset存在性校验 if (dataset && dataset.link) { scrollToSection(dataset.link); } } } } }; document.addEventListener('DOMContentLoaded', function() { const ctx = document.getElementById('hero-chart'); const heroChart = new Chart(ctx, config); function scrollToSection(sectionId) { const section = document.querySelector(sectionId); if (section) { section.scrollIntoView({ behavior: 'smooth' }); } } }); </script> <section id="data-bicycle"></section> <section id="data-car"></section> <section id="data-bus"></section> <section id="data-tram"></section> <section id="data-trains"></section> <section id="data-ship"></section> <section id="data-other"></section>
内容的提问来源于stack exchange,提问作者Addy
相关产品推荐
相关产品推荐

