UNPKG

victory-voronoi-container

Version:

Interactive Voronoi Mouseover Component for Victory

225 lines (222 loc) 7.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useVictoryVoronoiContainer = exports.VictoryVoronoiContainer = exports.VICTORY_VORONOI_CONTAINER_DEFAULT_PROPS = void 0; var _react = _interopRequireDefault(require("react")); var _defaults = _interopRequireDefault(require("lodash/defaults")); var _pick = _interopRequireDefault(require("lodash/pick")); var _victoryTooltip = require("victory-tooltip"); var _victoryCore = require("victory-core"); var _voronoiHelpers = require("./voronoi-helpers"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const VICTORY_VORONOI_CONTAINER_DEFAULT_PROPS = exports.VICTORY_VORONOI_CONTAINER_DEFAULT_PROPS = { activateData: true, activateLabels: true, labelComponent: /*#__PURE__*/_react.default.createElement(_victoryTooltip.VictoryTooltip, null), voronoiPadding: 5 }; const getPoint = point => { const whitelist = ["_x", "_x1", "_x0", "_y", "_y1", "_y0"]; return (0, _pick.default)(point, whitelist); }; const useVictoryVoronoiContainer = initialProps => { const props = { ...VICTORY_VORONOI_CONTAINER_DEFAULT_PROPS, ...initialProps }; const { children } = props; const getDimension = () => { const { horizontal, voronoiDimension } = props; if (!horizontal || !voronoiDimension) { return voronoiDimension; } return voronoiDimension === "x" ? "y" : "x"; }; const getLabelPosition = (labelProps, points) => { const { mousePosition, mouseFollowTooltips } = props; const voronoiDimension = getDimension(); const point = getPoint(points[0]); // @ts-expect-error scale is defined but the types do not reflect that const basePosition = _victoryCore.Helpers.scalePoint(props, point); let center = mouseFollowTooltips ? mousePosition : undefined; if (!voronoiDimension || points.length < 2) { return { ...basePosition, center: (0, _defaults.default)({}, labelProps.center, center) }; } const x = voronoiDimension === "y" ? mousePosition.x : basePosition.x; const y = voronoiDimension === "x" ? mousePosition.y : basePosition.y; center = mouseFollowTooltips ? mousePosition : { x, y }; return { x, y, center: (0, _defaults.default)({}, labelProps.center, center) }; }; const getStyle = (points, type) => { const { labels, labelComponent, theme } = props; const componentProps = labelComponent.props || {}; const themeStyles = theme && theme.voronoi && theme.voronoi.style ? theme.voronoi.style : {}; const componentStyleArray = type === "flyout" ? componentProps.flyoutStyle : componentProps.style; return points.reduce((memo, datum, index) => { const labelProps = (0, _defaults.default)({}, componentProps, { datum, active: true }); const text = _victoryCore.Helpers.isFunction(labels) ? labels(labelProps) : undefined; const textArray = text !== undefined ? `${text}`.split("\n") : []; const baseStyle = datum.style && datum.style[type] || {}; const componentStyle = Array.isArray(componentStyleArray) ? componentStyleArray[index] : componentStyleArray; const style = _victoryCore.Helpers.evaluateStyle((0, _defaults.default)({}, componentStyle, baseStyle, themeStyles[type]), labelProps); const styleArray = textArray.length ? textArray.map(() => style) : [style]; return memo.concat(styleArray); }, []); }; const getDefaultLabelProps = points => { const { voronoiDimension, horizontal, mouseFollowTooltips } = props; const point = getPoint(points[0]); const multiPoint = voronoiDimension && points.length > 1; const y = point._y1 !== undefined ? point._y1 : point._y; const defaultHorizontalOrientation = y < 0 ? "left" : "right"; const defaultOrientation = y < 0 ? "bottom" : "top"; const labelOrientation = horizontal ? defaultHorizontalOrientation : defaultOrientation; const orientation = mouseFollowTooltips ? undefined : labelOrientation; return { orientation, pointerLength: multiPoint ? 0 : undefined, constrainToVisibleArea: multiPoint || mouseFollowTooltips ? true : undefined }; }; const getLabelProps = points => { const { labels, scale, labelComponent, theme, width, height } = props; const componentProps = labelComponent.props || {}; const text = points.reduce((memo, datum) => { const labelProps = (0, _defaults.default)({}, componentProps, { datum, active: true }); const t = _victoryCore.Helpers.isFunction(labels) ? labels(labelProps) : null; if (t === null || t === undefined) { return memo; } return memo.concat(`${t}`.split("\n")); }, []); // remove properties from first point to make datum // eslint-disable-next-line @typescript-eslint/no-unused-vars const { childName, eventKey, style, continuous, ...datum } = points[0]; const name = props.name === childName ? childName : `${props.name}-${childName}`; const labelProps = (0, _defaults.default)({ key: `${name}-${eventKey}-voronoi-tooltip`, id: `${name}-${eventKey}-voronoi-tooltip`, active: true, renderInPortal: false, activePoints: points, datum, scale, theme }, componentProps, { text, width, height, style: getStyle(points, "labels"), flyoutStyle: getStyle(points, "flyout")[0] }, getDefaultLabelProps(points)); const labelPosition = getLabelPosition(labelProps, points); return (0, _defaults.default)({}, labelPosition, labelProps); }; const getTooltip = () => { const { labels, activePoints, labelComponent } = props; if (!labels) { return null; } if (Array.isArray(activePoints) && activePoints.length) { const labelProps = getLabelProps(activePoints); const { text } = labelProps; const showLabel = Array.isArray(text) ? text.filter(Boolean).length : text; return showLabel ? /*#__PURE__*/_react.default.cloneElement(labelComponent, labelProps) : null; } return null; }; return { props, children: [..._react.default.Children.toArray(children), getTooltip()] }; }; exports.useVictoryVoronoiContainer = useVictoryVoronoiContainer; const VictoryVoronoiContainer = initialProps => { const { props, children } = useVictoryVoronoiContainer(initialProps); return /*#__PURE__*/_react.default.createElement(_victoryCore.VictoryContainer, props, children); }; exports.VictoryVoronoiContainer = VictoryVoronoiContainer; VictoryVoronoiContainer.role = "container"; VictoryVoronoiContainer.defaultEvents = initialProps => { const props = { ...VICTORY_VORONOI_CONTAINER_DEFAULT_PROPS, ...initialProps }; const createEventHandler = (handler, disabled) => // eslint-disable-next-line max-params (event, targetProps, eventKey, context) => disabled || props.disable ? {} : handler(event, { ...props, ...targetProps }, eventKey, context); return [{ target: "parent", eventHandlers: { onMouseLeave: createEventHandler(_voronoiHelpers.VoronoiHelpers.onMouseLeave), onTouchCancel: createEventHandler(_voronoiHelpers.VoronoiHelpers.onMouseLeave), onMouseMove: createEventHandler(_voronoiHelpers.VoronoiHelpers.onMouseMove), onTouchMove: createEventHandler(_voronoiHelpers.VoronoiHelpers.onMouseMove) } }, { target: "data", eventHandlers: props.disable ? {} : { onMouseOver: () => null, onMouseOut: () => null, onMouseMove: () => null } }]; };