【问题标题】:JavaScript - Chart.js tooltip shows wrong x-axis valueJavaScript - Chart.js 工具提示显示错误的 x 轴值
【发布时间】:2017-12-11 10:06:35
【问题描述】:

我有一个包含两个不同数据集的图表,但有时它们具有相同的 x、y 坐标。但是,当我将鼠标悬停在共享点上时,它有时会显示错误的日期。 y 值是正确的,但是 x 值显示不正确。

尝试悬停共享点 here on codepen。

在下图中,您可以看到我悬停在{ y: 56.04, x: April 05, 2014 },但它显示了58.28 的xLabel 值,即April 15, 2012。另外,您可以在图表中看到57.05 和58.28 都将April 15, 2012 作为x 值,但它们不在同一个y 位置!

代码太长,无法在 stackoverflow 上分享,但我制作了 this codepen,因此您可以在那里查看、分叉和编辑它。


更新

我更新了日期相同的笔和定点。感谢@Oluwafemi Sule,我还添加了type: 'time'。

Here my edited pen.

但是现在,x 轴上的日期很奇怪。他们不再说March 06, 2011,而是说Q1 2011。而且工具提示仍然存在错误。

【问题讨论】:

    标签: javascript jquery canvas chart.js


    【解决方案1】:

    您在图表配置中为类别笛卡尔轴定义了自定义比例。将 xAxes 的类型设置为“类别”。这可能不是必需的,因为 ChartJS 默认会选择它。

    options: {
        scales: {
            xAxes: [{
                type: 'category',
                ....
    

    另外,第二个数据集的格式不正确。您应该以{x: xval, y: yval} 格式提供数据点。

    参考资料:

    http://www.chartjs.org/docs/latest/axes/cartesian/time.html#time-cartesian-axis

    【讨论】:

    • 第二个数据集:我问了这个问题后发现,这确实是我的小问题。我现在就试试这个类型:'time'!
    • Here 我添加了type: 'time',但现在日期格式很奇怪......codepen.io/DerkJanS/pen/EXemgb
    • 可以设置显示格式
    • 好的,我将如何在 displayFormats 中使用 moment.format() 函数?或者这样我可以本地化日期字符串? Here my edit
    • 要继续使用您在xLabels 中设置的标签,请将类型设置为category。还请删除您添加的 displayFormats。我错过了这个细节。要回答有关格式化和本地化标签的问题,您只需在 displayFormats 中传递该时间单位的格式字符串,例如季度:MMMM DD, YYYY。我会更新我的答案以反映这一变化
    【解决方案2】:

    我相信你需要通过标签。

    labels: ["09:00", "09:30", "09:50", "10:10", "10:30", "10:50", "11:10"],
    

    //////////////////////////////////////

    var chartPluginLineaHorizontal = {
            afterDraw: function (chartobj, chartobjDos) {
                if (chartobj.options.lineaHorizontal) {
                    var ctx = chartobj.chart.ctx;
                    var valorY = chartobj.scales["y-axis-0"].getPixelForValue(chartobj.options.lineaHorizontal);
                    ctx.beginPath();
                    ctx.moveTo(0, valorY);
                    ctx.lineTo(chartobj.chart.width, valorY);
                    ctx.strokeStyle = "red";
                    ctx.stroke();
    
                }
            }
        }
        Chart.pluginService.register(chartPluginLineaHorizontal);
    
        var chartPluginLineaHorizontalDos = {
            afterDraw: function (chartobj) {
                if (chartobj.options.lineaHorizontal) {
                    var ctx = chartobj.chart.ctx;
                    var valorY = chartobj.scales["y-axis-0"].getPixelForValue(chartobj.options.lineaHorizontalDos);
                    ctx.beginPath();
                    ctx.moveTo(0, valorY);
                    ctx.lineTo(chartobj.chart.width, valorY);
                    ctx.strokeStyle = "red";
                    ctx.stroke();
                }
            }
        }
        Chart.pluginService.register(chartPluginLineaHorizontalDos);
    
        // Define a plugin to provide data labels
        Chart.plugins.register({
            afterDatasetsDraw: function (chartobj) {
                var ctx = chartobj.chart.ctx;
    
                chartobj.data.datasets.forEach(function (dataset, i) {
                    //debugger
                    var meta = chartobj.getDatasetMeta(i);
                    if (!meta.hidden) {
                        meta.data.forEach(function (element, index) {
                            // Draw the text in black, with the specified font
                            ctx.fillStyle = 'rgb(0, 0, 0)';
    
                            var fontSize = 16;
                            var fontStyle = 'inherit';
                            var fontFamily = 'sans-serif';
                            ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
    
                            // Just naively convert to string for now
                            var dataString = dataset.data[index].y.toString();
    
                            // Make sure alignment settings are correct
                            ctx.textAlign = 'center';
                            ctx.textBaseline = 'middle';
    
                            var padding = 5;
                            var position = element.tooltipPosition();
                            ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
                        });
                    }
                });
            }
        });
    
                    var ctx = document.getElementById('myChart').getContext('2d');
                    var myChart = new Chart(ctx, {
                        type: 'line',
                        data: {
                            labels: ["09:00", "09:30", "09:50", "10:10", "10:30", "10:50", "11:10"],
                            datasets: [{
                                label: "My First dataset",
                                data: [
                                        {
                                            x: "09:30",
                                            y: 127
                                        },
                                       {
                                           x: "09:30",
                                           y: 140
                                       },
                                       {
                                           x: "09:50",
                                           y: 135
                                       },
                                       {
                                           x: "10:10",
                                           y: 122
                                       }, {
                                           x: "10:30",
                                           y: 135
                                       }, {
                                           x: "10:50",
                                           y: 135
                                       }],
                                backgroundColor: "rgba(0,255,51,0.5)",
                                            borderColor: "rgba(0,255,51,0.5)",
                                            fill: false
                            },
                                    {
                                        label: "My second dataset",
                                        data: [
                                            {
                                                x: "09:50",
                                                y: 95
                                            },
                                       {
                                           x: "10:10",
                                           y: 140
                                       },
                                       {
                                           x: "10:30",
                                           y: 130
                                       },
                                       {
                                           x: "10:50", 
                                           y: 150
                                       },
                                       {
                                           x: "11:10",
                                           y: 143
                                       }],
                                                    backgroundColor: "rgba(0,98,31,0.5)",
                                                    borderColor: "rgba(0,98,31,0.5)",
                                                    fill: false
                                    }]
                        },
                        options: {
                            lineaHorizontal: 140,
                            lineaHorizontalDos: 100,
                            elements: {
                                line: {
                                    tension: 0
                                }
                            }
    
                        }
    
    
                    })
    

    【讨论】:

      【解决方案3】:

      我通过使用这样的工具提示回调解决了我的问题:

      options: {
          tooltips: {
              callbacks: {
                  title: function(tooltipItems, data) {
                      return data.datasets[tooltipItems[0].datasetIndex].data[tooltipItems[0].index].x;
                  }
              }
          }
      }
      

      现在我的工具提示直接从相应的dataset 获取标题。

      Chartjs 版本:2.9.3

      【讨论】:

      • 这并不能解决我在问题中提供的图像中看到的视觉悬停错误。为数据点提供 x 和 y 值(正如@oluwafemiSule 在他的回答中描述的那样)是解决我的问题的方法。
      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多