@mui/x-charts
Version:
The community edition of MUI X Charts components.
72 lines (70 loc) • 2.99 kB
JavaScript
;
'use client';
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useRegisterItemClickHandlers = useRegisterItemClickHandlers;
var React = _interopRequireWildcard(require("react"));
var _useSvgRef = require("../hooks/useSvgRef");
var _ChartProvider = require("../context/ChartProvider");
var _getSVGPoint = require("../internals/getSVGPoint");
var _useStore = require("../internals/store/useStore");
var _useChartCartesianAxisPosition = require("../internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisPosition.selectors");
/**
* Hook that registers pointer event handlers for chart item clicking.
* @param onItemClick Callback for item click events.
*/
function useRegisterItemClickHandlers(onItemClick) {
const {
instance
} = (0, _ChartProvider.useChartContext)();
const svgRef = (0, _useSvgRef.useSvgRef)();
const store = (0, _useStore.useStore)();
React.useEffect(() => {
const element = svgRef.current;
if (!element || !onItemClick) {
return undefined;
}
let lastPointerUp = null;
const onClick = function onClick(event) {
let point = event;
/* The click event doesn't contain decimal values in clientX/Y, but the pointermove does.
* This caused a problem when rendering many bars that were thinner than a pixel where the tooltip or the highlight
* would refer to a different bar than the click since those rely on the pointermove event.
* As a fix, we use the pointerup event to get the decimal values and check if the pointer up event was close enough
* to the click event (1px difference in each direction); if so, then we can use the pointerup's clientX/Y; if not,
* we default to the click event's clientX/Y. */
if (lastPointerUp) {
if (Math.abs(event.clientX - lastPointerUp.clientX) <= 1 && Math.abs(event.clientY - lastPointerUp.clientY) <= 1) {
point = {
clientX: lastPointerUp.clientX,
clientY: lastPointerUp.clientY
};
}
}
lastPointerUp = null;
const svgPoint = (0, _getSVGPoint.getSVGPoint)(element, point);
if (!instance.isPointInside(svgPoint.x, svgPoint.y)) {
return;
}
const item = (0, _useChartCartesianAxisPosition.selectorBarItemAtPosition)(store.state, svgPoint);
if (item) {
onItemClick(event, {
type: 'bar',
seriesId: item.seriesId,
dataIndex: item.dataIndex
});
}
};
const onPointerUp = function onPointerUp(event) {
lastPointerUp = event;
};
element.addEventListener('click', onClick);
element.addEventListener('pointerup', onPointerUp);
return () => {
element.removeEventListener('click', onClick);
element.removeEventListener('pointerup', onPointerUp);
};
}, [instance, onItemClick, store, svgRef]);
}