UNPKG

victory-core

Version:
112 lines (108 loc) 3.19 kB
import * as Collection from "./collection"; // Private Functions function transformTarget(target, matrix, dimension) { const { a, d, e, f } = matrix; return dimension === "y" ? d * target + f : a * target + e; } function getTransformationMatrix(svg) { return svg.getScreenCTM().inverse(); } function isNativeTouchEvent(nativeEvent) { return !!(nativeEvent && nativeEvent.identifier !== undefined); } function isReactTouchEvent(evt) { return evt.changedTouches && evt.changedTouches.length > 0; } // Exported Functions export function getParentSVG(evt) { if (isNativeTouchEvent(evt.nativeEvent)) { // @ts-expect-error Seems like a superfluous check. return undefined; } const getParent = target => { if (target.nodeName === "svg") { return target; } return target.parentNode ? getParent(target.parentNode) : target; }; return getParent(evt.target); } export function getSVGEventCoordinates(evt, svg) { if (isNativeTouchEvent(evt.nativeEvent)) { // react-native override. relies on the RN.View being the _exact_ same size as its child SVG. // this should be fine: the svg is the only child of View and the View shirks to its children return { x: evt.nativeEvent.locationX, y: evt.nativeEvent.locationY }; } const location = isReactTouchEvent(evt) ? evt.changedTouches[0] : evt; const matrix = getTransformationMatrix(svg || getParentSVG(location)); return { x: transformTarget(location.clientX, matrix, "x"), y: transformTarget(location.clientY, matrix, "y") }; } export function getDomainCoordinates(props, domain) { const { horizontal } = props; const scale = props.scale; // FIXME: add support for DomainTuple: [number, number] const domainObj = domain || { x: scale.x.domain(), y: scale.y.domain() }; return { x: horizontal ? [scale.y(domainObj.y[0]), scale.y(domainObj.y[1])] : [scale.x(domainObj.x[0]), scale.x(domainObj.x[1])], y: horizontal ? [scale.x(domainObj.x[0]), scale.x(domainObj.x[1])] : [scale.y(domainObj.y[0]), scale.y(domainObj.y[1])] }; } // eslint-disable-next-line max-params export function getDataCoordinates(props, scale, x, y) { const { polar, horizontal } = props; if (!polar) { return { x: horizontal ? scale.x.invert(y) : scale.x.invert(x), y: horizontal ? scale.y.invert(x) : scale.y.invert(y) }; } const origin = props.origin || { x: 0, y: 0 }; const baseX = x - origin.x; const baseY = y - origin.y; const radius = Math.abs(baseX * Math.sqrt(1 + Math.pow(-baseY / baseX, 2))); const angle = (-Math.atan2(baseY, baseX) + Math.PI * 2) % (Math.PI * 2); return { x: scale.x.invert(angle), y: scale.y.invert(radius) }; } export function getBounds(props) { const { x1, x2, y1, y2, scale } = props; const point1 = getDataCoordinates(props, scale, x1, y1); const point2 = getDataCoordinates(props, scale, x2, y2); const makeBound = (a, b) => { return [Collection.getMinValue([a, b]), Collection.getMaxValue([a, b])]; }; return { x: makeBound(point1.x, point2.x), y: makeBound(point1.y, point2.y) }; }