meridbt
meridbt

Reputation: 377

Chart.js Line chart fixed tooltip

is it possible to call a default on-canvas tooltip at a fixed datalabel position without hovering the mouse?

enter image description here

Upvotes: 1

Views: 1376

Answers (2)

LeeLenalee
LeeLenalee

Reputation: 31321

You can use the setActiveElements function like so:

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'
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderColor: 'orange',
        backgroundColor: 'orange'
      }
    ]
  },
  options: {}
}

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

document.getElementById("tt").addEventListener("click", () => {
  const {
    tooltip,
    chartArea
  } = chart;

  tooltip.setActiveElements([{
      datasetIndex: 0,
      index: 1
    },
    {
      datasetIndex: 1,
      index: 1
    }
  ]);

  chart.update();
});
<body>
  <button id="tt">
      Make tooltip active
    </button>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.js"></script>
</body>

Upvotes: 1

rustyBucketBay
rustyBucketBay

Reputation: 4561

You can dispatch hover events as in this example, got from this answer:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<button id="a">Hover a</button>
<button id="b">Hover b</button>
<button id="c">Hover c</button>
<button id="d">Hover d</button>
<button id="e">Hover all</button>
<canvas id="chart"></canvas>
<script>
  let c = new Chart($("#chart"), {
    type: "doughnut",
    data: {
      labels: ["a", "b", "c", "d"],
      datasets: [
        {
          data: [1, 2, 4, 8],
          backgroundColor: ["red", "blue", "green", "orange"]
        }
      ]
    }
  });
  console.log("chart drawn!");
  $("#a").on("click", function () {
    t(0);
  });
  $("#b").on("click", function () {
    t(1);
  });
  $("#c").on("click", function () {
    t(2);
  });
  $("#d").on("click", function () {
    t(3);
  });
  $("#e").on("click", function () {
    hoverAll();
  });

  function t(idx) {
    var meta = c.getDatasetMeta(0),
      rect = c.canvas.getBoundingClientRect(),
      point = meta.data[idx].getCenterPoint(),
      evt = new MouseEvent("mousemove", {
        clientX: rect.left + point.x,
        clientY: rect.top + point.y
      }),
      node = c.canvas;
    node.dispatchEvent(evt);
  }

  function hoverAll() {
    for (let i = 0; i < 4; i++) {
      console.log(i);
      t(i);
    }
  }
</script>

But, hover events seems to be mutually exclusive, meaning that you have only one at once, because there is only one mouse that can hover over one element once at a time. That is why the added hoverall button does not work, and leaves the last one hovered element. If you want all the datasets and records of your chart displayed, the datalabels plugin seems the way to go, as suggested in the comments.

Upvotes: 1

Related Questions