Chart.js折线图仅显示指定X轴标签且保留工具提示显示的实现问题
Chart.js折线图仅显示指定X轴标签且保留工具提示显示的实现问题
看起来你是想让折线图的X轴只显示1年(365天)、2年(730天)、3年(1095天)这三个标签,其他X轴标签隐藏,但鼠标hover到任意点时,工具提示能正常显示对应天数的信息对吧?
你当前的代码没生效,主要有两个核心原因:一是你用的是Chart.js 3.x版本,但还在沿用2.x的xAxes数组配置方式(3.x开始已经改成了对象式的scales.x配置);二是代码里同时存在xAxes数组和scales.x配置,导致配置冲突,旧的规则被忽略了。
接下来我给你修正后的完整代码,同时拆解关键修改点:
关键修改说明
- 适配Chart.js 3.x的X轴配置:彻底移除旧的
xAxes数组,把所有X轴配置移到scales.x下,这是3.x版本的标准写法 - 修复X轴标签回调逻辑:在
scales.x.ticks.callback里(3.x中callback替代了2.x的userCallback),只返回指定索引(364、729、1094,对应365/730/1095天,因为数组从0开始计数)的标签,其他返回null实现隐藏 - 修正点半径判断错误:你的
customRadius函数里用了index = 364(这是赋值操作),改成严格相等的index === 364才是正确的条件判断 - 清理冲突配置:删掉了原来
scales里重复的x对象配置,把属性合并到正确的配置节点中
修正后的完整代码
// Reward Over Time Chart Function var rewardChart = null; var ctx3 = document.getElementById('rewardOverTimeChart').getContext('2d'); rewardChartCreator(13); function rewardChartCreator(dailyRewardUSD) { // Set time period const days3Years = 365 * 3; // Calculate the rewards over time var rewards = []; for (let day = 1; day <= days3Years; day++) { rewards.push(dailyRewardUSD * day); } if (rewardChart != null) { rewardChart.destroy(); // DESTROYING OLD CHART BEFORE CREATING NEW ONE } // Create the chart rewardChart = new Chart(ctx3, { type: 'line', data: { labels: Array.from({ length: days3Years }, (_, i) => i === 0 ? '1 Day' : `${i + 1} Days`), datasets: [{ label: ' Reward', data: rewards, borderColor: '#00ABE7', // Blue backgroundColor: 'rgba(254, 33, 209, 0.2)', borderWidth: 1, pointBackgroundColor: rewards.map((_, i) => [364, 729, 1094].includes(i) ? 'white' : '#00ABE7'), pointRadius: function(context) { let index = context.dataIndex; return [364, 729, 1094].includes(index) ? 10 : 1; }, pointHoverRadius: 4, fill: true }] }, options: { responsive: true, maintainAspectRatio: true, scales: { x: { type: 'category', position: 'bottom', ticks: { callback: function(value, index) { // 仅返回指定索引对应的X轴标签,其他标签隐藏 if (index === 364 || index === 729 || index === 1094) { return this.getLabelForValue(value); } return null; }, autoSkip: false // 强制关闭自动跳过,确保指定标签必显示 } }, y: { title: { display: false, text: 'Reward', font: { size: 16, weight: 'bold' } }, ticks: { stepSize: 300, callback: function(value) { if (value == 0) return '$' + 100; else return '$' + value; } } } }, plugins: { legend: { display: false, }, tooltip: { callbacks: { label: function(context) { let label = context.dataset.label || ''; if (label) { label += ': '; } if (context.parsed.y !== null) { label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.parsed.y); } return label; } } } }, animation: { duration: 1000, // Animation duration in milliseconds easing: 'easeInOutElastic' // Easing function for the animation }, elements: { point: { radius: customRadius, display: true } } } }); } function customRadius(context) { let index = context.dataIndex; // 修正条件判断:用严格相等===替代赋值= return index === 364 || index === 729 || index === 1094 ? 10 : 2; }
对应的HTML部分:
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0/dist/chart.min.js"></script> <canvas id="rewardOverTimeChart"></canvas>
备注:内容来源于stack exchange,提问作者Aimal
相关产品推荐
相关产品推荐

