React Native Highcharts点击图表外部Tooltip不关闭问题求助
Hey there! Let's work through this tooltip issue you're hitting with Highcharts in React Native. It’s totally normal for tooltips to only close when you click inside the chart by default, but we can tweak things so they disappear whenever you tap anywhere outside the chart too.
The Root of the Problem
Highcharts only listens for click events within its own container to hide tooltips out of the box. To fix this, we need to add a global touch handler that triggers the tooltip’s close action when taps happen outside the chart area.
Optimal Solution: Use Refs + Global Touch Listener
Here’s how to adjust your code to make this work, with explanations along the way:
Grab the Highcharts Instance with a Ref
We’ll use a React ref to get access to the actual Highcharts chart object, which lets us call its nativehideTooltip()method whenever we need to close the tooltip.Add a Global Touch Listener
We’ll listen for touch events across the entire screen. When a tap happens outside the chart’s bounds, we’ll trigger the tooltip close.Clean Up the Listener
Always remove event listeners when the component unmounts to avoid memory leaks.
Here’s your modified code:
import React, { useRef, useEffect } from 'react'; // ... Keep your existing imports (LineChart, styles, I18n, etc.) const SalesChart = () => { const chartRef = useRef(null); useEffect(() => { // Function to close the tooltip const closeTooltip = () => { if (chartRef.current?.chart) { chartRef.current.chart.hideTooltip(); } }; // Handler to check if tap is outside the chart const handleGlobalTap = ({ nativeEvent }) => { const chartElement = chartRef.current?.container; if (!chartElement) return; // Get the chart's position and dimensions const chartRect = chartElement.getBoundingClientRect(); const { pageX, pageY } = nativeEvent; // Check if tap is outside the chart bounds const isOutside = pageX < chartRect.left || pageX > chartRect.right || pageY < chartRect.top || pageY > chartRect.bottom; if (isOutside) closeTooltip(); }; // Add the global touch listener document.addEventListener('touchend', handleGlobalTap); // Cleanup listener when component unmounts return () => { document.removeEventListener('touchend', handleGlobalTap); }; }, []); return ( <LineChart ref={chartRef} style={[styles.fullWidth, { height: 300, border: 0 }]} yAxisTitle={I18n.t("averageSalePricePerSq")} xAxisValue={quarterlySales} orientation="horizontal" data={sales} config={{ tooltip: { enabled: true, shared: true, pointFormat: `<span style="color:{point.series.color}">●</span> {point.series.name}: <b>{point.y} AED/sq ft</b><br />`, }, chart: { // Save the chart instance to our ref when it loads events: { load: function() { chartRef.current.chart = this; } } } }} /> ); }; export default SalesChart;
Why This Works
- Ref Access: We store the Highcharts instance in a ref once the chart loads, so we can call its built-in
hideTooltip()method anytime. - Smart Tap Detection: The listener checks if the tap’s coordinates fall outside the chart’s container, ensuring we only close the tooltip when the user taps elsewhere.
- Cleanup: The useEffect cleanup function removes the listener when the component unmounts, preventing memory leaks.
Alternative Quick Fix (If Your Wrapper Supports It)
Some React Native Highcharts wrappers offer an onChartReady prop to get the instance directly, which simplifies the code a bit:
<LineChart onChartReady={(chart) => { chartRef.current = chart; }} // ... other props />
You can use this instead of the chart.events.load handler if your wrapper supports it.
内容的提问来源于stack exchange,提问作者Muhammad Jahanzaib

