UNPKG

@data-ui/xy-chart

Version:

A package of charts with standard x- and y- axes. https://williaster.github.io/data-ui

73 lines (66 loc) 2.61 kB
import { Children } from 'react'; import { localPoint } from '@vx/event'; import findClosestDatum from './findClosestDatum'; import { componentName, isSeries } from './chartUtils'; var DEFAULT_MAX_DISTANCE_PX = 1000; export default function findClosestDatums(_ref) { var children = _ref.children, xScale = _ref.xScale, yScale = _ref.yScale, _ref$margin = _ref.margin, margin = _ref$margin === void 0 ? {} : _ref$margin, getX = _ref.getX, getY = _ref.getY, event = _ref.event, _ref$maxXDistancePx = _ref.maxXDistancePx, maxXDistancePx = _ref$maxXDistancePx === void 0 ? DEFAULT_MAX_DISTANCE_PX : _ref$maxXDistancePx; if (!event || !event.target || !event.target.ownerSVGElement) return null; var series = {}; var gElement = event.target.ownerSVGElement; var _localPoint = localPoint(gElement, event), svgMouseX = _localPoint.x, svgMouseY = _localPoint.y; var mouseX = svgMouseX - (margin.left || 0); var mouseY = svgMouseY - (margin.top || 0); var closestDatum; var minDeltaX = Infinity; var minDeltaY = Infinity; var flatSeriesChildren = []; Children.forEach(children, function (Child) { var name = componentName(Child); if (name === 'AreaDifferenceSeries') { Children.forEach(Child.props.children, function (NestedChild) { flatSeriesChildren.push(NestedChild); }); } else if (isSeries(name)) { flatSeriesChildren.push(Child); } }); // collect data from all series that have an x value near this point flatSeriesChildren.forEach(function (Child, childIndex) { if (!Child.props.disableMouseEvents) { var _Child$props = Child.props, data = _Child$props.data, seriesKey = _Child$props.seriesKey; // @TODO data should be sorted, come up with a way to enforce+cache instead of relying on user var datum = findClosestDatum({ data: data, getX: getX, xScale: xScale, event: event, marginLeft: margin.left }); var deltaX = Math.abs(xScale(getX(datum || {})) - mouseX); if (datum && deltaX <= maxXDistancePx) { var key = seriesKey || childIndex; // fall back to child index series[key] = datum; var deltaY = Math.abs(yScale(getY(datum)) - mouseY); closestDatum = deltaY < minDeltaY && deltaX <= minDeltaX ? datum : closestDatum; minDeltaX = closestDatum === datum ? deltaX : minDeltaX; minDeltaY = closestDatum === datum ? deltaY : minDeltaY; } } }); return { series: series, closestDatum: closestDatum }; }