You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ChartJS 3.9.1如何仅在日期切换点显示垂直网格线与标签?

解决ChartJS仅在日期切换处显示垂直网格线与标签的问题

要实现仅在日期(颜色编码)变化的位置显示垂直网格线和对应标签,你可以通过ChartJS的刻度钩子函数和自定义配置来实现。核心思路是过滤X轴刻度,只保留日期分界点的刻度,同时让网格线和标签仅在这些位置显示。

修改后的完整代码

function setCharts() {
    const colorDays = ['#54bebe', '#76c8c8', '#98d1d1', '#badbdb', '#dedad2', '#e4bcad', '#df979e', '#d7658b', '#c80064'];
    const dayNames = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']; // 可自定义日期名称

    let dataRandom = fillRandomValues();

    const tab = document.getElementById('tabCharts');
    tab.innerHTML = '';

    let ctx = document.createElement('canvas');
    ctx.id = 'canvasChart';

    new Chart(ctx, {
        type: 'line',
        data: {
            idxDays: dataRandom.listIdxDays,
            labels: dataRandom.listIdxValues,
            datasets: [{
                label: `example`,
                fill: true,
                backgroundColor: '#54bebe',
                borderColor: '#54bebe',
                borderWidth: 2,
                pointRadius: 0,
                data: dataRandom.listValues,
                segment: {
                    backgroundColor: (ctx) => (colorDays[ctx.chart.data.idxDays[ctx.p0DataIndex]]),
                }
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                y: {
                    beginAtZero: true
                },
                x: {
                    // 过滤刻度:仅保留第一个点和日期变化的分界点
                    afterBuildTicks: function(scale) {
                        const filteredTicks = [];
                        filteredTicks.push(scale.ticks[0]); // 保留起始刻度
                        // 遍历数据,找到日期索引变化的位置
                        for (let i = 1; i < scale.chart.data.idxDays.length; i++) {
                            if (scale.chart.data.idxDays[i] !== scale.chart.data.idxDays[i - 1]) {
                                filteredTicks.push(scale.ticks[i]);
                            }
                        }
                        scale.ticks = filteredTicks;
                    },
                    ticks: {
                        // 将标签替换为日期名称(可改为原索引或其他格式)
                        callback: function(value) {
                            const dayIdx = dataRandom.listIdxDays[value];
                            return dayNames[dayIdx];
                        },
                        maxRotation: 0, // 防止标签旋转重叠
                        minRotation: 0
                    },
                    grid: {
                        // 仅在保留的刻度位置绘制垂直网格线
                        drawOnChartArea: true,
                        drawTicks: true
                    }
                }
            }
        }
    });

    tab.appendChild(ctx);
}

function fillRandomValues() {
    let data = {
        listValues: [], // 实际数值
        listIdxValues: [],  // 数值索引(用于Chart labels)
        listIdxDays: [], // 日期索引(0=周一,1=周二...)
        listIsDayChanged: [], // 标记是否发生日期切换
    };

    let dayActual = 0;

    for (let d = 0; d < 100; d++) { // 生成100个随机值
        let rand = 50 + (Math.floor(Math.random() * 10));

        if (rand < 55) {
            dayActual = dayActual === 6 ? 0 : dayActual++;
            data.listIsDayChanged[d] = true;
        } else {
            data.listIsDayChanged[d] = false;
        }

        data.listValues[d] = rand;
        data.listIdxDays[d] = dayActual;
        data.listIdxValues[d] = d;
    }

    return data;
}

HTML代码

<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1"></script>
<div id="tabCharts" class="tabContent" style="width: 1000px; height: 500px;"></div>

关键配置说明

  1. afterBuildTicks 刻度过滤:
    这个钩子函数在X轴刻度生成后执行,通过比较相邻数据点的idxDays值,只保留第一个点和日期发生变化的位置对应的刻度,确保X轴仅显示关键分界点。

  2. ticks.callback 自定义标签:
    将原来的数字索引替换为直观的日期名称,你也可以根据需求修改为原索引或其他格式。同时设置maxRotation:0避免标签旋转重叠。

  3. 垂直网格线控制:
    由于已经过滤了刻度,ChartJS会自动在保留的刻度位置绘制垂直网格线,配合drawOnChartArea: true确保网格线显示在图表区域内。

内容的提问来源于stack exchange,提问作者szvarga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 06:05:04