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

Chart.js笛卡尔时间线图报错及自定义配置求助

Chart.js时间线图报错及格式配置问题

问题场景

使用Chart.js渲染笛卡尔时间线图,数据来自后端List<tuple<string, int>>转JSON,包含字符串日期时间和整数计数,转换逻辑在cshtml视图中实现。饼图可正常渲染,但线图执行new Chart(ctx...)时触发报错:

Uncaught Error: This method is not implemented: Check that a complete date adapter is provided

JSON数据示例:

{Item1: '03/08/2023 07:46:11', Item2: 0}

解析后的数据格式:

{t: Wed Mar 08 2023 07:46:11 GMT+0000 (Greenwich Mean Time), y: 0}

已做以下尝试:

  • 引入chartjs-adapter-date-fns适配器仍报错,引入代码:
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
  • 使用xAxes/yAxes配置轴时出现Invalid scale configuration for scale: xAxes/yAxes错误,改为x/y数组配置后仍无效;
  • 调整配置后图表可显示数据,但X轴无法渲染日期时间;
  • 尝试自定义tooltip格式,相关代码如下:
// Function to render the line chart using Chart.js
function renderLineChart(data1, data2, canvasid) {
    var canvas = document.getElementById(canvasid);
    var ctx = canvas.getContext('2d');

    console.log("Rendering line chart...");

    // Destroy old line chart if it exists
    if (window.chartInstances[canvasid]) {
        console.log('Destroying old line chart...');
        window.chartInstances[canvasid].destroy();
    }

    console.log("Creating new line chart...");
    if (!window.chartInstances[canvasid]) 
    {
        window.chartInstances = {};
        // Create a new Chart.js instance if it doesn't exist
        window.chartInstances[canvasid] = new Chart(ctx, {
        type: 'line',
        data: {
            datasets: [{
                label: 'Total  Count (1)',
                data: data1.map(item => ({
                    x: item.x,
                    y: item.y,
                    string1: item.string1,
                    string2: item.string2
                })),
                borderColor: 'rgb(75, 192, 192)'
            },
            {
                label: 'Total  Count (2)',
                data: data2.map(item => ({
                    x: item.x,
                    y: item.y,
                    string1: item.string1,
                    string2: item.string2
                })),
                borderColor: 'rgb(255, 99, 132)'
            }]
        },
            options: {
                scales: {
                    x: {
                    type: 'time',  // Use time scale for x-axis
                    time: {
                        tooltipFormat: dd/MM/yyyy HH:mm:ss' // Format for tooltip display
                        displayFormats: {
                            second: 'dd/MM HH:mm:ss',  // Format for x-axis labels
                        },
                    },
                    title: {
                        display: true,
                        text: 'Timestamp',
                        },
                    },
                    y: {
                        beginAtZero: true,
                        title:{
                            display: true,
                            text: 'Counts'
                        }
                    }
                },
                plugins: {
                    tooltip: {
                        callbacks: {
                            tooltipFormat: function (context) {
                            const xValue = context.parsed.x;
                            const yValue = context.parsed.y;
                            const dataset = context.dataset;
                            const dataItem = dataset.data[context.dataIndex];
                            const string1 = dataItem.string1 || '';
                            const string2 = dataItem.string2 || '';
                            const label2 = 'Current Data:';
                            return `${label2} ${xValue} - ${yValue} - ${string1} - ${string2}`;
                            }
                        }
                    }
                }
            }
        });
    } 
    else 
    {
        // Update the existing Chart.js instance with new data and options
        window.chartInstances[canvasid].data.datasets[0].data = data1;
        window.chartInstances[canvasid].data.datasets[1].data = data2;
        window.chartInstances[canvasid].update();
    }
}

求助需求

  1. 解决日期适配器报错问题;
  2. 实现X轴日期时间正常渲染;
  3. 完成自定义tooltip格式配置。

解决方案

1. 修复日期适配器报错

  • 版本匹配:确保chartjs-adapter-date-fns版本与Chart.js兼容(Chart.js v4+需搭配v3.x以上适配器),使用bundle版适配器已包含date-fns核心依赖,无需额外引入。
  • 标准化日期数据:解析后的日期必须是标准Date类型,避免自定义时间对象,映射数据时强制转换:
    data: data1.map(item => ({
        x: new Date(item.x), // 转为标准Date实例
        y: item.y,
        string1: item.string1,
        string2: item.string2
    }))
    
  • 修正配置语法:Chart.js v4中,时间轴需明确指定适配器,且配置层级调整:
    x: {
        type: 'time',
        adapter: 'date-fns', // 明确指定适配器
        time: {
            displayFormats: {
                second: 'dd/MM HH:mm:ss'
            }
        }
    }
    

2. 实现X轴日期时间渲染

  • 确保X轴type设为'time',并配置与输入日期匹配的解析格式(比如你的日期是日/月/年格式):
    x: {
        type: 'time',
        adapter: 'date-fns',
        time: {
            parser: 'dd/MM/yyyy HH:mm:ss', // 匹配输入日期字符串格式
            displayFormats: {
                second: 'dd/MM HH:mm:ss'
            }
        },
        title: {
            display: true,
            text: 'Timestamp'
        }
    }
    

3. 自定义Tooltip格式

  • Chart.js没有tooltipFormat回调钩子,改用label回调实现自定义内容,同时格式化日期显示:
    plugins: {
        tooltip: {
            callbacks: {
                label: function(context) {
                    // 格式化日期为指定格式
                    const xValue = new Date(context.parsed.x).toLocaleString('en-GB', {
                        day: '2-digit',
                        month: '2-digit',
                        year: 'numeric',
                        hour: '2-digit',
                        minute: '2-digit',
                        second: '2-digit'
                    });
                    const yValue = context.parsed.y;
                    const dataItem = context.dataset.data[context.dataIndex];
                    const string1 = dataItem.string1 || '';
                    const string2 = dataItem.string2 || '';
                    return `Current Data: ${xValue} - ${yValue} - ${string1} - ${string2}`;
                }
            }
        }
    }
    

完整修正后的核心代码

整合所有修正点后的配置示例:

window.chartInstances[canvasid] = new Chart(ctx, {
    type: 'line',
    data: {
        datasets: [{
            label: 'Total  Count (1)',
            data: data1.map(item => ({
                x: new Date(item.x),
                y: item.y,
                string1: item.string1,
                string2: item.string2
            })),
            borderColor: 'rgb(75, 192, 192)'
        },
        {
            label: 'Total  Count (2)',
            data: data2.map(item => ({
                x: new Date(item.x),
                y: item.y,
                string1: item.string1,
                string2: item.string2
            })),
            borderColor: 'rgb(255, 99, 132)'
        }]
    },
    options: {
        scales: {
            x: {
                type: 'time',
                adapter: 'date-fns',
                time: {
                    parser: 'dd/MM/yyyy HH:mm:ss',
                    displayFormats: {
                        second: 'dd/MM HH:mm:ss'
                    }
                },
                title: {
                    display: true,
                    text: 'Timestamp'
                }
            },
            y: {
                beginAtZero: true,
                title:{
                    display: true,
                    text: 'Counts'
                }
            }
        },
        plugins: {
            tooltip: {
                callbacks: {
                    label: function(context) {
                        const xValue = new Date(context.parsed.x).toLocaleString('en-GB', {
                            day: '2-digit',
                            month: '2-digit',
                            year: 'numeric',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        });
                        const yValue = context.parsed.y;
                        const dataItem = context.dataset.data[context.dataIndex];
                        const string1 = dataItem.string1 || '';
                        const string2 = dataItem.string2 || '';
                        return `Current Data: ${xValue} - ${yValue} - ${string1} - ${string2}`;
                    }
                }
            }
        }
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:57:04