[Chartjs]-ChartJs line chart – display permanent icon above some data points with text on hover

5πŸ‘

βœ…

In case your chart (canvas) is of fixed size, you can easily solve this problem by adding an additional dataset that specifies nothing but the icons to be shown in the chart.

{
  data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null),
  fill: false,
  pointStyle: icon,
  pointRadius: 22,
  pointHoverRadius: 22
}

Given the data array data2 and the array imageIndexes, the data of the icons dataset can be built using Array.map. Note that the values – where any – are derived from corresponding values in data2 but slightly increased to make the images appear on top of them.

data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null)

Further you’ll need to define a tooltips object inside the chart options in order to style the popup and to make sure, tooltips are only displayed when the mouse hovers over the icons.

tooltips: {
  filter: tooltipItem => tooltipItem.datasetIndex == 2,
  titleFontSize: 16,
  titleAlign: 'center',
  callbacks: {
    title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
    label: () => null
  }
},

Please have a look at the runnable code snipped below.

const labels = ['A', 'B', 'C', 'D', 'E', 'F'];
const alerts = ['B', 'D'];
const data1 = [0, 2, 1, 3, 2, 1];
const data2 = [1, 3, 3, 4, 3, 2];
const imageIndexes = [1, 3];
const tooltipText = 'Efficiency of Standard Curve\nnot opimal';

var icon = new Image();
icon.src = 'https://i.stack.imgur.com/YvlWY.png';

const chart = new Chart(document.getElementById("myChart"), {
  type: "line",
  data: {
    labels: labels,
    datasets: [{
        data: data1,
        fill: false,
        backgroundColor: 'blue',
        borderColor: 'blue',
        lineTension: 0,
        pointRadius: 5,
        pointHoverRadius: 5,
        pointBorderWidth: 3,
        pointHoverBorderWidth: 3,
        pointBorderColor: 'white',
        pointHoverBorderColor: 'white'
      },
      {
        data: data2,
        fill: false,
        showLine: false,
        backgroundColor: 'orange',
        pointRadius: 4,
        pointHoverRadius: 4
      },
      {
        data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null),
        fill: false,
        pointStyle: icon,
        pointRadius: 22,
        pointHoverRadius: 22
      }
    ]
  },
  options: {
    responsive: false,
    title: {
      display: false
    },
    legend: {
      display: false
    },
    tooltips: {
      filter: tooltipItem => tooltipItem.datasetIndex == 2,
      titleFontSize: 16,
      titleAlign: 'center',
      callbacks: {
        title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
        label: () => null
      }
    },
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
          max: 6,
          stepSize: 1
        }
      }],
      xAxes: [{
        gridLines: {
          display: false
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" style="width: 500px; height: 200px"></canvas>

Leave a comment