[Chartjs]-Make Chart.js render a line between points in a scatterplot on hover

1👍

You can use a custom plugin for this:

const EXPANDO_KEY = 'customLinePlugin';

const data = {
  "datasets": [{
      "label": "Active",
      "sentences": [
        "A1",
        "A2",
        "A3"
      ],
      "data": [
        [
          "0.4340433805869016",
          "0.12813240157479788"
        ],
        [
          "-0.39983629799199083",
          "0.12125799115087213"
        ],
        [
          "-0.04289228113339527",
          "0.10106119377169194"
        ]
      ],
      "borderColor": "#43a047",
      "backgroundColor": "#7cb342"
    },
    {
      "label": "Passive",
      "sentences": [
        "P1",
        "P2",
        "P3"
      ],
      "data": [
        [
          "0.4295487808020268",
          "0.19271652809947026"
        ],
        [
          "-0.4438451670978469",
          "-0.08848766134414247"
        ],
        [
          "-0.10789534989054622",
          "0.08013654263956245"
        ]
      ],
      "borderColor": "#1e88e5",
      "backgroundColor": "#039be5"
    }
  ],
  "labels": []
};

const plugin = {
  id: "customLine",
  afterInit: (chart) => {
    chart[EXPANDO_KEY] = {
      index: null
    }
  },
  afterEvent: (chart, evt) => {
    const activeEls = chart.getElementsAtEventForMode(evt.event, 'nearest', {
      intersect: true
    }, true)

    if (activeEls.length === 0) {
      chart[EXPANDO_KEY].index = null
      return;
    }


    chart[EXPANDO_KEY].index = activeEls[0].index;
  },
  beforeDatasetsDraw: (chart, _, opts) => {
    const {
      ctx
    } = chart;
    const {
      index
    } = chart[EXPANDO_KEY];

    if (index === null) {
      return;
    }
    const dp0 = chart.getDatasetMeta(0).data[index]
    const dp1 = chart.getDatasetMeta(1).data[index]

    ctx.lineWidth = opts.width || 0;
    ctx.setLineDash(opts.dash || []);
    ctx.strokeStyle = opts.color || 'black'

    ctx.save();
    ctx.beginPath();
    ctx.moveTo(dp0.x, dp0.y);
    ctx.lineTo(dp1.x, dp1.y);
    ctx.stroke();
    ctx.restore();
  }
}

new Chart(document.getElementById("sentences"), {
  type: "scatter",
  data: data,
  options: {
    responsive: true,
    plugins: {
      customLine: {
        dash: [2, 2],
        color: 'red',
        width: 2
      },
      legend: {
        position: "top",
      },
      tooltip: {
        callbacks: {
          label: ctx => ctx.dataset.sentences[ctx.dataIndex]
        }
      }
    }
  },
  plugins: [plugin]
});
<body>
  <canvas id="sentences"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.2/chart.js"></script>
</body>

EDIT:
For some reason stack snippet in creation works but doesnt like so itself, so here is a fiddle link: https://jsfiddle.net/Leelenaleee/btux41dz/

Leave a comment