在 Chart.js 中更改提示框颜色

3

我正在尝试根据数据的值自定义工具提示。此外,当折线图上的线条上升或下降时,角落处会有这些小圆形连接器或连接点,我也想尝试更改它们的颜色,但对于这些我甚至不知道从哪里开始。以下是我正在使用的一部分代码,我正在尝试使用Chart.js返回和更改工具提示颜色。

        tooltips: {
          mode: 'index',
          intersect: false,
          callbacks: {

            label: function(tooltipItem, data) {
              if (tooltipItem.yLabel === 1) {

    //return 'Normal';
            return { 'Normal',
             tooltipFillColor: 'rgb(255, 99, 132)', // red
        };

              } else if (tooltipItem.yLabel === 2) {

               // return 'Active';
        return { 'Acitve',
             tooltipFillColor: 'rgb(75, 192, 192)', // green
        };

              }
            }
          }
        },

感谢所有的帮助!

我理解了根据值更改工具提示颜色的部分,但你能否提供一张图片来解释一下你所说的“线图角落上的这些小圆形连接器或连接点”是什么意思? - jordanwillis
嗨,小圆形连接器,抱歉找不到正确的名称。它们由数据集中的以下内容控制:datasets: [{borderJoinStyle: '', pointBorderColor: '#000000', pointBackgroundColor: "#ff0000", pointBorderWidth: 1, pointHoverRadius: 5,}]。我正在尝试根据“d.eventState”的值更改它们的颜色。谢谢! - Maresia
请查看我的“答案”评论以及我的更新答案。 - jordanwillis
2个回答

4

或者,您可以使用标签颜色函数。

tooltips: {
     callbacks: {
       labelColor: function(tooltipItem,data) {
           if (tooltipItem.datasetIndex === 0) {
                return {
                    borderColor: "#FFFFFF",
                    backgroundColor: "#FFCD2E"
                        };
                 }

3
几乎在任何时候,如果你想要个性化定制 tooltip 的外观和样式超出了 chart.js 提供的配置选项,你都需要使用自定义 tooltip。自定义 tooltip 的好处是它们基于 html/css,因此您的样式选项是无限的。
在这种情况下,由于您正在尝试根据数据值更改 tooltip 的背景颜色,因此您可以简单地定义一些 css 类来处理两种样式选项,然后在自定义 tooltip 函数中实现逻辑以根据值分配适当的 css 类。
以下是一个例子。
custom: function(tooltip) {
  // get the tooltip element
  var tooltipEl = document.getElementById('chartjs-tooltip');

  // create one if it does not yet exist
  if (!tooltipEl) {
    tooltipEl = document.createElement('div');
    tooltipEl.id = 'chartjs-tooltip';
    tooltipEl.innerHTML = "<table></table>"
    document.body.appendChild(tooltipEl);
  }

  // hide the tooltip and restore the cursor
  // if there isn't one to display yet
  if (tooltip.opacity === 0) {
    tooltipEl.style.opacity = 0;
    $(this._chart.canvas).css("cursor", "default");
    return;
  } else {
    // otherwise change the cursor to pointer
    $(this._chart.canvas).css("cursor", "pointer");
  }

  // clear all classes and add the correct background color
  tooltipEl.classList.remove('active', 'normal');
  if (tooltip.dataPoints[0].yLabel === 2) {
    tooltipEl.classList.add('active');
  } else {
    tooltipEl.classList.add('normal');
  }

  function getBody(bodyItem) {
    return bodyItem.lines;
  }

  // set tooltip text
  if (tooltip.body) {
    var titleLines = tooltip.title || [];
    var bodyLines = tooltip.body.map(getBody);
    var innerHtml = '<thead>';

    titleLines.forEach(function(title) {
      innerHtml += '<tr><th>' + title + '</th></tr>';
    });
    innerHtml += '</thead><tbody>';

    bodyLines.forEach(function(body, i) {
      // map the number that is going to be displayed state value
      if (tooltip.dataPoints[0].yLabel === 2) {
        body = 'Active';
      } else {
        body = 'Normal';
      }

      var colors = tooltip.labelColors[i];
      var style = 'background:' + colors.backgroundColor;
      style += '; border-color:' + colors.borderColor;
      style += '; border-width: 2px'; 
      var span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>';
      innerHtml += '<tr><td>' + span + body + '</td></tr>';
    });
    innerHtml += '</tbody>';

    var tableRoot = tooltipEl.querySelector('table');
    tableRoot.innerHTML = innerHtml;
  }

  // get the position of tooltip
  var position = this._chart.canvas.getBoundingClientRect();

  // set display, position, and font styles
  tooltipEl.style.opacity = 1;
  tooltipEl.style.left = position.left + tooltip.caretX + 'px';
  tooltipEl.style.top = position.top + tooltip.caretY + 'px';
  tooltipEl.style.fontFamily = tooltip._fontFamily;
  tooltipEl.style.fontSize = tooltip.fontSize;
  tooltipEl.style.fontStyle = tooltip._fontStyle;
  tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
}

似乎您想根据数据值自定义点的颜色。这实际上非常简单,不需要使用任何回调函数。您只需将颜色数组传递给 pointBackgroundColor 和 pointBorderColor 属性,其中数组中的每个索引都映射到数据数组中的索引。
例如,如果您想让第一个和第三个点具有不同的颜色,则数组可能如下所示:[蓝色,红色,蓝色,红色]。您可以在构建图表数据对象时(例如,在 prepareDataForChart() 函数中)同时构建颜色数组。
以下是示例:
// this function processess our raw data and converts
// it to a format that chart.js can understand
var prepareDataForChart = function(data) {
  var chartData = {
    data: [],
    pointColors: [],
  };

  data.forEach(function(d) {
    var yValue;
    var pointColor;

    // since we cannot use a category scale on the y-axis,
    // lets map the eventState to an arbitrary numerical value
    // and set the point color
    if (d.eventState === 'A') {
      yValue = 2;
      pointColor = chartColors.red;
    } else if (d.eventState === 'N') {
      yValue = 1;
      pointColor = chartColors.blue;
    }

    // we have to use the 'alternate' dataset format
    // in order to graph this correctly
    chartData.data.push({
      x: d.eventTime,
      y: yValue,
    });

    // add our point color to the colors array
    chartData.pointColors.push(pointColor);
  });

  return chartData;
};

然后当您创建图表时,只需使用由您的函数返回的pointColors数组即可。

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
  type: 'line',
  data: {
    datasets: [{
      label: "Object 1",
      fill: false,
      borderColor: chartColors.red,
      borderWidth: 2,
      backgroundColor: chartColors.white,
      pointBorderColor: chartData.pointColors,
      pointBackgroundColor: chartData.pointColors,
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHitRadius: 20,
      steppedLine: true,
      data: chartData.data,
    }]
  },
// ...rest of chart options...

这里有一个CodePen示例,演示了所有讨论过的内容(彩色工具提示和点)。

嗨Jordan,我看到你发布的代码非常接近我正在尝试的内容,但如果我可以根据“tooltipItem.yLabel”的值更改数据集中这四个项目的值:[{pointBorderColor:'#000000',pointBackgroundColor:“#ff0000”,pointBorderWidth:1,pointHoverRadius:5,...}],那么它对我来说就行了。这就是我在“if”语句的“return”中尝试做的事情。 - Maresia
你实际上可以通过将数组传递给 pointBackgroundColorpointBorderColor 来单独设置点的颜色。请参阅我的更新答案,其中解释了所有这些内容(我也更新了 CodePen)。 - jordanwillis
太好了,比我之前尝试的更简单,只需创建另一个函数来根据d.eventState的值获取颜色。我发现一个问题,如果我只有一个值,为什么聊天记录不会显示该值的任何行,只有工具提示显示:https://codepen.io/anon/pen/yMQNaM - Maresia

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