JavaScript Chart.js - 自定义数据格式以在工具提示上显示

65

我查看了各种文档以及这里的类似问题,但似乎找不到特定的解决方案。如果我漏掉了任何明显的东西或者重复了这个问题,请谅解!

作为背景信息,我使用Chart.js插件实现了4个图表,并使用PHP从数据库中传入所需数据。这一切都正常工作,很好。

我的问题是,我需要在工具提示中以格式化的方式显示数据,例如以数字和%的形式。举个例子,我的一个来自数据库的数据是-0.17222。我已经将其格式化为百分数以在表格中显示,一切正常。然而,在设置chart.js柱状图的数据时,数据显然缺少这种格式,并且显示为-0.17222,这是我不想要的。

抱歉,我想发布图片,但我的声望太差了!

我从数据库中获取数据,然后将其设置到我的表格中:

var kpiRex = new Handsontable(example1, {
    data: getRexData(),

然后我在图表区域这样使用这些数据:

data: kpiRex.getDataAtRow(3)
任何帮助都将是极好的!我被卡在这个问题上已经好几个小时了,很可能只是我忽略了一些非常简单的东西。
12个回答

132

对于chart.js 2.0+版本,这已经有所改变(不再使用tooltipTemplate/multiTooltipTemplate)。对于那些只想访问当前未格式化值并开始调整的人, 默认工具提示与以下内容相同:

options: {
    tooltips: {
        callbacks: {
            label: function(tooltipItem, data) {
                return tooltipItem.yLabel;
            }
        }
    }
}

也就是说,您可以返回修改 tooltipItem.yLabel 的内容,它保存了 y 轴的值。在我的情况下,我想要为一个财务图表添加美元符号、四舍五入和千位分隔符,所以我使用了以下代码:

options: {
    tooltips: {
        callbacks: {
            label: function(tooltipItem, data) {
                return "$" + Number(tooltipItem.yLabel).toFixed(0).replace(/./g, function(c, i, a) {
                    return i > 0 && c !== "." && (a.length - i) % 3 === 0 ? "," + c : c;
                });
            }
        }
    }
}

2
这很好,但它会移除系列的标签。 - RafaelTSCS
我使用回调函数来生成我的工具提示,如下所示... callbacks: { label: function(tooltipItem, data) { return tooltipItem.yLabel + '%'; } },但它还显示了x轴值... 我想隐藏我的工具提示中的x轴值。 - Rajiv
1
@Kyrth。是的,它仍然显示x轴的值。如何只显示y轴的值? - Asif Iqbal
4
@RafaelTSCS,你可以将返回语句更改为 return data.datasets[tooltipItem.datasetIndex].label + " $" 以保留标签。 - Alex Levine
4
文档链接:http://www.chartjs.org/docs/latest/configuration/tooltip.html#label-callback这个文档讲述了如何在 Chart.js 中自定义工具提示标签的内容。您可以编写回调函数来返回所需的标签值。该文档提供了有关回调函数接受的参数以及应如何使用它们的详细信息。 - prokaktus
对于较新的chartjs版本,必须使用RC Whim答案中给出的语法。 - Lahiru Chandima

40

在chart.js 2.1.6中,我做了类似于这样的事情(使用TypeScript):

  let that = this;
  options = {
    legend: {
      display: false,
      responsive: false
    },
    tooltips: {
      callbacks: {
        label: function(tooltipItem, data) {
          let account: Account = that.accounts[tooltipItem.index];
          return account.accountNumber+":"+account.balance+"€";
        }
      }
    }
  }

40

您想在图表选项中指定自定义的工具提示模板,如下所示:

 // String - Template string for single tooltips
 tooltipTemplate: "<%if (label){%><%=label %>: <%}%><%= value + ' %' %>",
 // String - Template string for multiple tooltips
 multiTooltipTemplate: "<%= value + ' %' %>",

如果需要的话,您可以在您的值后面添加“%”符号。

这是一个 jsfiddle示例

请注意,如果您只有一个数据集,则应用 tooltipTemplate ,如果您有多个数据集,则应用 multiTooltipTemplate

这些选项在文档中的全局图表配置部分中提到。不妨仔细研究一下,其中还可以自定义其他选项。

请注意,您的数据集应仅包含数字值(没有“%”符号或其他内容)。


11
您可以给tooltipTemplate传递一个函数,并根据您的需求格式化工具提示:
tooltipTemplate: function(v) {return someFunction(v.value);}
multiTooltipTemplate: function(v) {return someOtherFunction(v.value);}

给定的 'v' 参数除了 'value' 属性之外还包含很多信息。您可以在该函数内部放置一个 'debugger' 并自行检查这些信息。


“someOtherFunction()”应该返回什么?像“<%datasetLabel-value%>”这样的字符串模板,字符串或其他内容?更准确地说,它应该做什么?返回一些内容还是修改所提供参数的属性? - SomethingOn
@SomethingOn someOtherFunction() 应该返回你想在工具提示中显示的字符串,而不是模板,只需返回字符串即可。您可以随意操作 v.value,只要返回一个字符串即可。它不应该修改 v,那似乎很危险。 - Ariel Cabib

10
tooltips: {
          callbacks: {
            label: (tooltipItem, data) => {
              // data for manipulation
              return data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
            },
          },
        },

1
这个答案涵盖了更多的用例。只有当yLabel具有可用值时,所选选项才是正确的,但有时它可能只是一个空字符串。 - Ignacio Lago

9
这里的答案对我在Char.js 3.8.0上没有用。提示框选项回调对象已经移动了,显然现在它在options.plugins.tooltip下面。

https://www.chartjs.org/docs/latest/configuration/tooltip.html

OP的示例:

    options: {
        plugins: {
            tooltip: {
                callbacks: {
                    label: function (tooltipItem, data) {
                        console.log(data);
                        console.log(tooltipItem);
                        return tooltipItem.formattedValue + '%';
                    }
                }
            }
        },
        ...

8

这对我来说完美无缺。它接受标签并格式化值。

options: {
        tooltips: {
            callbacks: {
                label: function(tooltipItem, data) {

                    let label = data.labels[tooltipItem.index];
                    let value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
                    return ' ' + label + ': ' + value + ' %';

                }
            }
        }
    }

7
tooltips: {
    callbacks: {
        label: function (tooltipItem) {
            return (new Intl.NumberFormat('en-US', {
                style: 'currency',
                currency: 'USD',
            })).format(tooltipItem.value);
        }
    }
}

9
虽然这段代码可能解决了问题,但是如果你能包含一个解释说明为什么这个代码可以解决问题的话,将有助于提高你的帖子质量并可能导致更多的赞。请记住,你正在回答未来的读者而不仅仅是现在提问的人。请编辑你的答案以添加解释,并指出适用的限制和假设。 - double-beep
非常好的回答,非常简洁! - Brendan Sluke

4
在 Chart.Js 2.8.0 中,自定义工具提示的配置可以在此处找到: https://www.chartjs.org/docs/latest/configuration/tooltip.html#label-callback (感谢 @prokaktus)。
如果您想显示一些带有前缀或后缀的值(例如,在示例中,脚本将kWh作为单位添加到图表中的值中),可以按如下方式进行:
options: {
  rotation: 1 * Math.PI,
  circumference: 1 * Math.PI,
  tooltips: {
    callbacks: {
      label: function(tooltipItem, data) {
        console.log(data);
        console.log(tooltipItem);

        var label = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index] || '';

        if (label) {
          label += ' kWh';
        }

        return label;
      }
    }
  }
}

这里有一个示例,也可以在这里查看: https://jsfiddle.net/y3petw58/1/

2
你需要使用标签回调函数。 一个常见的例子是将数据值四舍五入到两位小数,以下示例将数据舍入到两位小数。
var chart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        tooltips: {
            callbacks: {
                label: function(tooltipItem, data) {
                    var label = data.datasets[tooltipItem.datasetIndex].label || '';

                    if (label) {
                        label += ': ';
                    }
                    label += Math.round(tooltipItem.yLabel * 100) / 100;
                    return label;
                }
            }
        }
    }
});

现在让我写一下我使用标签回调功能的情况。

首先记录Label Callback函数的参数,你将看到类似于这里数据集的结构,它由不同的行组成,你想在图表中绘制。 在我的情况下,有4个,因此数据集数组的长度为4。

enter image description here

在我的情况下,我需要对每个数据集执行一些计算,并且每次悬停在图表中的一条线上时都需要识别正确的线。
为了区分不同的线并根据其他线的数据操作悬停提示框的数据,我必须编写这个逻辑。
  callbacks: {
    label: function (tooltipItem, data) {
      console.log('data', data);
      console.log('tooltipItem', tooltipItem);
      let updatedToolTip: number;
      if (tooltipItem.datasetIndex == 0) {
        updatedToolTip = tooltipItem.yLabel;
      }
      if (tooltipItem.datasetIndex == 1) {
        updatedToolTip = tooltipItem.yLabel - data.datasets[0].data[tooltipItem.index];
      }
      if (tooltipItem.datasetIndex == 2) {
        updatedToolTip = tooltipItem.yLabel - data.datasets[1].data[tooltipItem.index];
      }
      if (tooltipItem.datasetIndex == 3) {
        updatedToolTip = tooltipItem.yLabel - data.datasets[2].data[tooltipItem.index]
      }
      return updatedToolTip;
    }
  } 

上述场景在绘制折线图并根据图表中不同线的不同点的数据操纵悬停点的工具提示时非常有用,前提是这些点在相同的索引位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接