score:2

Accepted answer

you can put any custom/advance datas to dataset for example (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'],
    }]
};

then you can use datasetindex, dataindex in tooltip item context to get your custom/advance datas.

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

score:1

dont know how you get your data so i assume you somehow get it together with your normal data. in this case you can add a custom property to the dataset and pass it to the tooltip. then it will be available in your context of your external handler in the following namespace: context.tooltip.datapoints[0].dataset[custompropertyname].

then you can just create an image element and add it to the head:

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/

full code (since stack snipet doesnt seem to like creating the elements):

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


Related Query

More Query from same tag