I have used @nivo/bar for plotting bar charts in my react application. added line to display average value. on bars, the tooltip is working fine. I want to add a tooltip when the user hover over the line to show the average value.attached image
I am not sure if anyone will ever need to implement similar functionality. but I did some research on this one, here is the answer to my own questions:
const CustomTagretLine = ({ props }) => {
const { bars } = props
const { showTooltipAt, hideTooltip } = useTooltip()
//show tooltip on mouse enter
const handleMouseEnter = (point) => {
showTooltipAt(
props.tooltip(point),
[point.x + props.margin.left, point.y + props.margin.top],
'top'
)
}
//move tooltip with mouse position
const handleMouseMove = (point) => {
showTooltipAt(
props.tooltip(point),
[point.x + props.margin.left, point.y + props.margin.top],
'top'
)
}
const handleMouseLeave = () => {
hideTooltip()
}
return (
<>
{bars.map((bar, idx) => (
<>
{bar.height && (
<line
onMouseOver={() =>
handleMouseEnter({
x: bar.x - 5,
y: props.yScale(bar?.data?.data?.avgVal || 0), //whatever you want
absX: bar.x - 5 + 70,
absY: props.yScale(bar?.data?.data?.avgVal || 0) + 50,
width: 70,
height: 4,
data: {
...bar?.data?.data,
isAvg: true,
},
formattedValue: formatNumber(
parseInt(bar?.data?.data?.avgVal) || 0
),
})
}
onMouseLeave={() =>
handleMouseLeave({
x: bar.x - 5,
y: props.yScale(bar?.data?.data?.avgVal || 0), //whatever you want
absX: bar.x - 5 + 70,
absY: props.yScale(bar?.data?.data?.avgVal || 0) + 50,
width: 70,
height: 4,
data: {
...bar?.data?.data,
isAvg: true,
},
formattedValue: formatNumber(
parseInt(bar?.data?.data?.avgVal) || 0
),
})
}
onMouseMove={() =>
handleMouseMove({
x: bar.x - 5,
y: props.yScale(bar?.data?.data?.avgVal || 0), //whatever you want
absX: bar.x - 5 + 70,
absY: props.yScale(bar?.data?.data?.avgVal || 0) + 50,
width: 70,
height: 4,
data: {
...bar?.data?.data,
isAvg: true,
},
formattedValue: formatNumber(
parseInt(bar?.data?.data?.avgVal) || 0
),
})
}
key={idx}
opacity="1"
x1={bar.x - 5}
x2={bar.x + bar.width + 5}
y1={props.yScale(bar?.data?.data?.avgVal || 0)}
y2={props.yScale(bar?.data?.data?.avgVal || 0)}
stroke="#000000"
strokeWidth="3"
></line>
)}
</>
))}
</>
)}
CustomTargetLine is custom layer, which can be added like this in bar
layers={[
'grid',
'axes',
'bars',
'legends',
'annotations',
(props) => <CustomTagretLine props={props} />,
]}
refrence: https://nivo.rocks/bar/