【问题标题】:Chart.js line chart tooltip shows wrong label when line doesn't start at first labelChart.js 折线图工具提示在第一个标签未开始行时显示错误标签
【发布时间】:2020-10-22 04:02:16
【问题描述】:

我有一个简单的折线图,在 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'。你能告诉我我错过了什么吗?

代码如下:

<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>

【问题讨论】:

    标签: javascript chart.js


    【解决方案1】:

    基本上,答案是替换这个:

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

    用这个:

    [null, 30, 20, 25, null]
    

    【讨论】:

      【解决方案2】:

      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


      编辑:基于 cmets,一个更完整的解决方案,原始数据按照 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>

      【讨论】:

      • 嘿@0stone0,不幸的是,这对我没有帮助,因为标签应该保持提供的方式。我很感激你的回答。请参阅我的answer,了解我是如何在不更改标签的情况下实现这一目标的。
      • @gdrt 请查看我的编辑,这样您就可以保留问题中显示的数据。您的答案使用分离的标签和数据,这很好,但是在处理大型数据集时,我总是将数据用作值/标签以使其更清晰。很高兴您找到了解决方案;)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多