使用 Chart.js 版本 3,如何向外部工具提示添加自定义数据?

5
使用Chart JS版本3。如何传入自定义数据,以便外部工具提示可以使用?
我想在HTML中重新创建此工具提示。

enter image description here

我正在按照此页面上的示例“#外部(自定义)工具提示”进行操作:https://www.chartjs.org/docs/latest/configuration/tooltip.html,但我需要额外的数据来构建工具提示,例如图像网址或产品ID?我该如何将其添加到模型中?


缺少太多信息,比如你存储图像URL的位置在哪里。 - LeeLenalee
图像 URL 存储在数据库中与数据一起。这是一个示例 URL:(https://klasresearch.com/images/vendor-logos/epic-logo-61122.svg)。我想将其放入 <img> 标签中,但如何将 URL 放入 Chart.js 使用的模型以创建工具提示? - Rodney Hickman
2个回答

4

您可以将任何自定义/高级数据放入数据集中,例如(imgUrls、productIds、imgDataset):

var chartdata = {
            labels: ["Swimming", "Golf", "Soccer"],
    datasets: [{
        label: "Choices",
        data: [4, 10, 6],
        backgroundColor: ["#a19828", "#b15928", "#fb9a99"],
        imgDataUrls:['img1','img2','img3'],
        imgDataSet:'imgDataset',
        productIds:['id1','id2','id3'],
    }]
};

你可以在工具提示项上下文中使用datasetIndex和dataIndex获取自定义/高级数据。

// Index of the dataset the item comes from
datasetIndex: number,

    // Index of this data item in the dataset
dataIndex: number,

https://github.com/chartjs/Chart.js/blob/master/docs/samples/tooltip/html.md


这个上下文在哪里?还是只有 tooltip.datasetIndex - jjxtra

2
我不知道您如何获取数据,所以我假设您将其与常规数据一起获取。在这种情况下,您可以向数据集添加自定义属性并将其传递给工具提示。然后,它将在您外部处理程序的上下文中的以下命名空间中可用:context.tooltip.dataPoints [0] .dataset [customPropertyName]
然后,您只需创建一个图像元素并将其添加到头部即可:
titleLines.forEach(title => {
  const tr = document.createElement('tr');
  tr.style.borderWidth = 0;

  const th = document.createElement('th');
  th.style.borderWidth = 0;
  const text = document.createTextNode(title);
  th.appendChild(text);

  // THIS BLOCK ADDED
  const imageTh = document.createElement('th');
  th.style.borderWidth = 0;
  const image = document.createElement('img');
  image.style = 'width:20px'
  image.src = context.tooltip.dataPoints[0].dataset.url;
  imageTh.appendChild(image);

  tr.appendChild(th);
  tr.appendChild(imageTh);
  tableHead.appendChild(tr);
});

Fiddle: https://jsfiddle.net/Leelenaleee/xhrs2wvc/17/

完整代码(因为堆栈片段似乎不喜欢创建元素):

<body>
    <canvas id="chartJSContainer" width="600" height="400"></canvas>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
</body>

const getOrCreateTooltip = (chart) => {
  let tooltipEl = chart.canvas.parentNode.querySelector('div');

  if (!tooltipEl) {
    tooltipEl = document.createElement('div');
    tooltipEl.style.background = 'rgba(0, 0, 0, 0.7)';
    tooltipEl.style.borderRadius = '3px';
    tooltipEl.style.color = 'white';
    tooltipEl.style.opacity = 1;
    tooltipEl.style.pointerEvents = 'none';
    tooltipEl.style.position = 'absolute';
    tooltipEl.style.transform = 'translate(-50%, 0)';
    tooltipEl.style.transition = 'all .1s ease';

    const table = document.createElement('table');
    table.style.margin = '0px';

    tooltipEl.appendChild(table);
    chart.canvas.parentNode.appendChild(tooltipEl);
  }

  return tooltipEl;
};

const externalTooltipHandler = (context) => {
  // Tooltip Element
  const {
    chart,
    tooltip
  } = context;
  const tooltipEl = getOrCreateTooltip(chart);

  // Hide if no tooltip
  if (tooltip.opacity === 0) {
    tooltipEl.style.opacity = 0;
    return;
  }

  // Set Text
  if (tooltip.body) {
    const titleLines = tooltip.title || [];
    const bodyLines = tooltip.body.map(b => b.lines);

    const tableHead = document.createElement('thead');

    titleLines.forEach(title => {
      const tr = document.createElement('tr');
      tr.style.borderWidth = 0;

      const th = document.createElement('th');
      th.style.borderWidth = 0;
      const text = document.createTextNode(title);
      th.appendChild(text);

            // THIS BLOCK ADDED
      const imageTh = document.createElement('th');
      th.style.borderWidth = 0;
      const image = document.createElement('img');
      image.style = 'width:20px'
      image.src = context.tooltip.dataPoints[0].dataset.url;
      imageTh.appendChild(image);

      tr.appendChild(th);
      tr.appendChild(imageTh);
      tableHead.appendChild(tr);
    });

    const tableBody = document.createElement('tbody');
    bodyLines.forEach((body, i) => {
      const colors = tooltip.labelColors[i];

      const span = document.createElement('span');
      span.style.background = colors.backgroundColor;
      span.style.borderColor = colors.borderColor;
      span.style.borderWidth = '2px';
      span.style.marginRight = '10px';
      span.style.height = '10px';
      span.style.width = '10px';
      span.style.display = 'inline-block';

      const tr = document.createElement('tr');
      tr.style.backgroundColor = 'inherit';
      tr.style.borderWidth = 0;

      const td = document.createElement('td');
      td.style.borderWidth = 0;

      const text = document.createTextNode(body);

      td.appendChild(span);
      td.appendChild(text);
      tr.appendChild(td);
      tableBody.appendChild(tr);
    });

    const tableRoot = tooltipEl.querySelector('table');

    // Remove old children
    while (tableRoot.firstChild) {
      tableRoot.firstChild.remove();
    }

    // Add new children
    tableRoot.appendChild(tableHead);
    tableRoot.appendChild(tableBody);
  }

  const {
    offsetLeft: positionX,
    offsetTop: positionY
  } = chart.canvas;

  // Display, position, and set styles for font
  tooltipEl.style.opacity = 1;
  tooltipEl.style.left = positionX + tooltip.caretX + 'px';
  tooltipEl.style.top = positionY + tooltip.caretY + 'px';
  tooltipEl.style.font = tooltip.options.bodyFont.string;
  tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
};

const options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderColor: 'pink',
        backgroundColor: 'pink',
        url: 'https://www.chartjs.org/img/chartjs-logo.svg'
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderColor: 'orange',
        backgroundColor: 'orange',
        url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Stack_Overflow_icon.svg/512px-Stack_Overflow_icon.svg.png'
      }
    ]
  },
  options: {
    plugins: {
      tooltip: {
        enabled: false,
        position: 'nearest',
        external: externalTooltipHandler
      }
    }
  }
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);


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