1

So there is a problem with custom tooltip interaction in ChartJS using it with React.

Example of current behaviour of custom tooltip

So originally I use interaction with intersect: false for my chart, and I want to tooltip appear while I just mouseover the chart. But as you see on the video above, it only works when I interact exactly with the dataset line and area under it, but I should be able to see tooltip even if I mouseover above that lines too.

My config for interaction(this is last one, I've tried a lot of combinations, but for real they don't work as expected for me):

interaction: {
  intersect: false,
  includeInvisible: true,
  mode: 'nearest',
  axis: 'x',
},

I also noticed, that my tooltip opacity is 0, while I mouseover the dataset line and area above it, and I can't get why. With original tooltip it works pretty well. Here is the code of my custom tooltip:

tooltip: {
 enabled: false,
 external: ({ chart, tooltip }) => {
   if (!chart) {
     return;
   }
   if (tooltip.opacity === 0) {
     setTooltipData(prevValue => ({ ...prevValue, visible: false }));
     return;
   }

  // get coordinates of 2 points and get maximum of them to display tooltip according to it
  const position = chart.canvas.getBoundingClientRect();
  const maxX = Math.max(XusersPointPosition, XsubscribersPointPosition);
  const maxY = Math.min(YusersPointPosition, YsubscribersPointPosition);

  ....................................................................................


  setTooltipData({ top: maxY + offsetY, left: maxX + offsetX, label, data, visible: true });
}

Here is also my plugin for drawing dashed line on X coordinate of dataset points(I also think this line doesn't work because of tooltip seems to be opacity 0 and that's why also not active, so we also can't see the line)

export const plugins = [{
  beforeDatasetsDraw: chart => {
    // eslint-disable-next-line no-underscore-dangle
    if (chart.tooltip._active && chart.tooltip._active.length) {
      // find coordinates of tooltip
      const [activePoint] = chart.tooltip._active;
      const { ctx } = chart;
      const { x, y } = activePoint.element;
      const bottomY = chart.scales.y.bottom;
      // draw vertical line
      ctx.save();
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x, bottomY);
      ctx.lineWidth = 1;
      ctx.strokeStyle = '#718086';
      ctx.setLineDash([4, 2]);
      ctx.stroke();
      ctx.restore();
    }
  },
}];

And finally rendering of tooltip itself

const NotificationStatisticsChart = ({ statistics }) => {
  const [tooltipData, setTooltipData] = useState({
    top: 0,
    left: 0,
    label: '',
    data: null,
    visible: false,
  });
  const data = useMemo(() => createDataObjectForChart(statistics), [statistics]);
  const options = useMemo(() => createOptions(statistics, setTooltipData), [statistics]);

  return (
    <div className={styles.chart}>
      <Line options={options} data={data} plugins={plugins} />
      {visible ? (
        <div className={styles.tooltip} style={{ top: top, left: left }}>
         <div className={styles.date}>{tooltipLabel}</div>
         {data.map(item => (
            <div key={item.type} className={styles.amount}>
              <span>{item.total}</span>
              <span className={styles.count}>{item.delta}</span>
              <span>{item.type}</span>
            </div>
         ))}
        </div>
       ) : null}
    </div>
  );
};

1 Answers1

0

I've finally fixed that! So the problem was in hovering custom tooltip itself and it caused some strange behaviour. To fix this you just need to remove pointer-events from your tooltip:

tooltip.style.pointerEvents = 'none';