当线不在第一个标签开始时,Chart.js折线图工具提示显示错误的标签

时间:2020-10-21 15:04:16

标签: javascript chart.js

我有一个简单的折线图,在x轴上有5个标签:'Oct 2018', 'Jan 2019', 'Apr 2019', 'Jul 2019', 'Oct 2019',而一条线仅在3个中间标签'Jan 2019', 'Apr 2019', 'Jul 2019'上有点。

问题在于,当行数据不是从第一个标签开始时(如我的情况),工具提示会在悬停时显示不正确的标签。从下图可以看到,当我将鼠标悬停在'Apr 2019'数据点上时,工具提示将显示'Jan 2019'。同样,当我将鼠标悬停在'Jul 2019'数据点上时,工具提示将显示'Apr 2019'。你能告诉我我想念什么吗?

wrong tooltip label

这是代码:

<canvas id="canvas" ></canvas>
<script>
    var lineChartData = {
        labels: ['Oct 2018', 'Jan 2019', 'Apr 2019', 'Jul 2019', 'Oct 2019'],
        datasets: [
            {
                label: 'Oranges',
                borderColor: window.chartColors.blue,
                backgroundColor: window.chartColors.blue,
                fill: false,
                data: 
                [
                    {y: 30, x: 'Jan 2019'},
                    {y: 20, x: 'Apr 2019'},
                    {y: 25, x: 'Jul 2019'},
                ],              
            }           
        ]
    };

    window.onload = function() {
        var ctx = document.getElementById('canvas').getContext('2d');
        window.myLine = Chart.Line(ctx, {
            data: lineChartData,
            options: {
                responsive: true,
                hoverMode: 'index',
                stacked: false,
                scales: {
                    yAxes: [{
                        type: 'linear',
                        display: true,
                        position: 'left'
                    }],
                }
            }
        });
    };
</script>

2 个答案:

答案 0 :(得分:1)

Chart.js不喜欢将日期标签用作字符串。您应该使用Date()momentjs()对象来指定日期。


使用MomentJS,您的图形可能看起来像这样;

const newDate = (mdy) => moment(mdy, "MM-DD-YYYY");

var lineChartData = {
    labels: [newDate('9-1-2018'), newDate('1-1-2019'), newDate('4-1-2019'), newDate('6-1-2019'), newDate('9-1-2019')],
    datasets: [{
        label: 'Oranges',
        borderColor: 'blue',
        backgroundColor: 'orange',
        fill: false,
        data: [
            { y: 30, x: newDate('1-1-2019') },
            { y: 20, x: newDate('4-1-2019') },
            { y: 25, x: newDate('6-1-2019') }
        ],
    }]
};

window.onload = function() {
    var ctx = document.getElementById('canvas').getContext('2d');
    window.myLine = Chart.Line(ctx, {
        data: lineChartData,
        options: {
            hover: {
                mode: 'new mode'
            },
            responsive: true,
            hoverMode: 'index',
            stacked: false,
            scales: {
                yAxes: [{
                    type: 'linear',
                    display: true,
                    position: 'left'
                }],
                xAxes: [{
                    type: 'time',
                    time: {
                        displayFormats: {
                            'millisecond': 'MMM YY',
                            'second': 'MMM YY',
                            'minute': 'MMM YY',
                            'hour': 'MMM YY',
                            'day': 'MMM YY',
                            'week': 'MMM YY',
                            'month': 'MMM YY',
                            'quarter': 'MMM YY',
                            'year': 'MMM YY',
                        }
                    }
                }]
            }
        }
    });
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<canvas id="canvas" ></canvas>

(注意;多余的空数据可以删除,请查看Chartjs time docs


编辑:基于注释,这是一个更完整的解决方案,其中原始数据已按OP预期进行了解析。

const newDate = (mdy) => moment(mdy, "MMM YYYY");
const data = {
  labels: ['Oct 2018', 'Jan 2019', 'Apr 2019', 'Jul 2019', 'Oct 2019'],
  points: [
    {y: 30, x: 'Jan 2019'},
    {y: 20, x: 'Apr 2019'},
    {y: 25, x: 'Jul 2019'}
  ]
};

var lineChartData = {
    labels: data.labels.map(l => newDate(l)),
    datasets: [{
        label: 'Oranges',
        borderColor: 'blue',
        backgroundColor: 'orange',
        fill: false,
        data: data.points.map(p => { return { ...p, x: newDate(p.x) } })
    }]
};

window.onload = function() {
    var ctx = document.getElementById('canvas').getContext('2d');
    window.myLine = Chart.Line(ctx, {
        data: lineChartData,
        options: {
            hover: {
                mode: 'new mode'
            },
            responsive: true,
            hoverMode: 'index',
            stacked: false,
            scales: {
                yAxes: [{
                    type: 'linear',
                    display: true,
                    position: 'left'
                }],
                xAxes: [{
                    type: 'time',
                    time: {
                    parser: 'MMM YYYY',
                        tooltipFormat: 'MMM YYYY',
                        displayFormats: {
                            'millisecond': 'MMM YYYY',
                            'second': 'MMM YYYY',
                            'minute': 'MMM YYYY',
                            'hour': 'MMM YYYY',
                            'day': 'MMM YYYY',
                            'week': 'MMM YYYY',
                            'month': 'MMM YYYY',
                            'quarter': 'MMM YYYY',
                            'year': 'MMM YYYY',
                        }
                    }
                }]
            }
        }
    });
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<canvas id="canvas" ></canvas>

答案 1 :(得分:0)

基本上,答案是将其替换:

[
    {y: 30, x: 'Jan 2019'},
    {y: 20, x: 'Apr 2019'},
    {y: 25, x: 'Jul 2019'},
]

与此:

[null, 30, 20, 25, null]