Custom Tooltip opacity always 1
I need to have custom Tooltip and I design a react-component using hooks, check out the code:
import {Line} from "react-chartjs-2";
import {Button} from "reactstrap";
import React, {useState, useRef} from "react";
// noinspection ES6UnusedImports
// eslint-disable-next-line no-unused-vars
// import Drag from "../DraggableChart";
export default function ProgramChart({data}) {
const [tooltipData, setTooltipData] = useState(null);
const chartRef = useRef(null);
return (
<div>
<Line
ref={chartRef}
options={{
legend: {
display: false
},
tooltips: {
"enabled": false,
"mode": "point",
"intersect": false,
custom: (tooltipModel) => {
// hide tooltip if needed
if (tooltipModel.opacity === 0) {
setTooltipData(null);
console.log("Hide tooltip");
return;
}
const chart = chartRef.current.chartInstance;
const canvas = chart.ctx.canvas;
if (canvas) {
const position = canvas.getBoundingClientRect();
// set position of tooltip
const left = position.left + tooltipModel.caretX;
const top = position.top + tooltipModel.caretY;
setTooltipData({top, left});
}
}
},
}}
data={chartData}
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
textAlign: "center",
flex: 1,
height: "100%",
}}/>
{tooltipData ? <GraphTooltip data={tooltipData}/> : <div/>}
</div>
);
};
const GraphTooltip = ({data}) => <div
style={{
padding: 20,
position: "fixed",
border: "1px solid",
borderColor: "#fff8f9",
backgroundColor: "rgba(53,53,53,0.81)",
borderRadius: 4,
top: data.top,
left: data.left,
}}
>
<Button>Whatever</Button>
</div>;
Tooltip is rendered but it never disappear!
If I remove setTooltipData({top, left}); line than there are no problem..
Have anyone any idea?
@velthune I've copied your code into a sandbox and it functions exactly the same way the chart.js examples do: https://www.chartjs.org/samples/latest/tooltips/custom-points.html
Can you please describe the behaviour you are expecting in a bit more detail? Do you want the tooltips to disappear when the mouse moves out of the chart/tooltip element? Or if a user clicks elsewhere on the page?
If that's the case then you will need to manage those events yourself on custom tooltip elements.
@velthune Did you ever figure this out? Seems like the function is only run when the tooltip is active (opacity:1). In this example https://www.chartjs.org/samples/latest/tooltips/custom-points.html the tooltip disappears if you move the mouse off the canvas as the custom tooltip function is called on exit.
If anyone is still looking for an answer, I was able to solve this by putting the function into a useCallback with empty dependencies. Without useCallback it doesn't work and I'm not sure why. So if anyone knows a reason that would be great!
Could you please be more specific on how you solved it? I have been trying to do so but I keep having the same problem, my tooltip opacity is always 1.
I decided to take it out due to having issues creating my own that looked nice but I found what I used that worked.
const customTooltip = useCallback((tooltipModel: any) => {
// if chart is not defined, return early
let chart = chartRef.current;
if (!chart) {
return;
}
// hide the tooltip when chartjs determines you've hovered out
if (tooltipModel.opacity === 0) {
setOpenToolTip(false);
return;
}
const position = chart.chartInstance.canvas.getBoundingClientRect();
// assuming your tooltip is `position: fixed`
// set position of tooltip
const left = position.left + tooltipModel.caretX;
const top = position.top - tooltipModel.height;
// set values for display of data in the tooltip
const label = tooltipModel.dataPoints[0].xLabel;
const index = tooltipModel.dataPoints[0].index;
setPositionAndData({top, left, label, index});
setOpenToolTip(true);
}, []);
And then I called it in the options:
tooltips: {
enabled: false,
custom: customTooltip,
}
From what I remember, not defining the customTooltip with a useCallback gave the error where opacity did not change. Hope it helps!
Unfortunately, useCallback doesn't work for me. But I found another workaround using setTimeout.
const customTooltip = tooltipModel => {
const result = {}
// Hide if no tooltip
result.visible = tooltipModel.opacity !== 0
// Get content for the tooltip
if (tooltipModel.dataPoints) {
result.xLabel = tooltipModel.dataPoints[0].xLabel
result.yLabel = tooltipModel.dataPoints[0].yLabel
}
result.xPos = tooltipModel.caretX
result.yPos = tooltipModel.caretY
setTimeout(setTooltipAttr, 20, result)
}
But if anybody can explain, why is there a problem, it would be great. I don't have any idea.
None of you guys have a problem where hovering while using a custom tooltip rerenders the chart itself?
None of you guys have a problem where hovering while using a custom tooltip rerenders the chart itself?
@PCPbiscuit I'm facing same issue, did you find any workaround ?
None of you guys have a problem where hovering while using a custom tooltip rerenders the chart itself?
@PCPbiscuit I'm facing same issue, did you find any workaround ?
The only workaround which works for me is using test-react-chartjs2