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