UNPKG

victory-group

Version:
224 lines (219 loc) 7.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCalculatedProps = getCalculatedProps; exports.getChildren = getChildren; exports.useMemoizedProps = useMemoizedProps; var _react = _interopRequireDefault(require("react")); var _victoryCore = require("victory-core"); var _reactFastCompare = _interopRequireDefault(require("react-fast-compare")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const fallbackProps = { width: 450, height: 300, padding: 50, offset: 0 }; function getCalculatedProps(initialProps, childComponents) { const role = "group"; const props = _victoryCore.Helpers.modifyProps(initialProps, fallbackProps, role); const style = _victoryCore.Wrapper.getStyle(props.theme, props.style, role); const { offset, colorScale, color, polar, horizontal } = props; const categories = props.categories || _victoryCore.Wrapper.getCategories(props, childComponents, null); const datasets = props.datasets || _victoryCore.Wrapper.getDataFromChildren(props, null); const domain = { x: _victoryCore.Wrapper.getDomain(Object.assign({}, props, { categories }), "x", childComponents), y: _victoryCore.Wrapper.getDomain(Object.assign({}, props, { categories }), "y", childComponents) }; const range = props.range || { x: _victoryCore.Helpers.getRange(props, "x"), y: _victoryCore.Helpers.getRange(props, "y") }; const baseScale = { x: _victoryCore.Scale.getScaleFromProps(props, "x") || _victoryCore.Wrapper.getScale(props, "x"), y: _victoryCore.Scale.getScaleFromProps(props, "y") || _victoryCore.Wrapper.getScale(props, "y") }; const scale = { x: baseScale.x.domain(domain.x).range(props.horizontal ? range.y : range.x), y: baseScale.y.domain(domain.y).range(props.horizontal ? range.x : range.y) }; const origin = polar ? props.origin : _victoryCore.Helpers.getPolarOrigin(props); const padding = _victoryCore.Helpers.getPadding(props.padding); return { datasets, categories, range, domain, horizontal, scale, style, colorScale, color, offset, origin, padding }; } // We need to remove sharedEvents in order to memoize the calculated data // With shared events, the props change on every event, and every value is re-calculated const withoutSharedEvents = props => { const { children } = props; const modifiedChildren = _react.default.Children.toArray(children).map(child => { return { ...child, props: _victoryCore.Helpers.omit(child.props, ["sharedEvents"]) }; }); props.children = modifiedChildren; return props; }; function useMemoizedProps(initialProps) { const modifiedProps = withoutSharedEvents(initialProps); const [props, setProps] = _react.default.useState(modifiedProps); // React.memo uses shallow equality to compare objects. This way props // will only be re-calculated when they change. _react.default.useEffect(() => { if (!(0, _reactFastCompare.default)(modifiedProps, props)) { setProps(modifiedProps); } }, [props, setProps, modifiedProps]); return _react.default.useMemo(() => { return getCalculatedProps(props, props.children); }, [props]); } function pixelsToValue(props, axis, calculatedProps) { if (!props.offset) { return 0; } const currentAxis = _victoryCore.Helpers.getCurrentAxis(axis, props.horizontal); const domain = calculatedProps.domain[axis]; const range = calculatedProps.range[currentAxis]; const domainExtent = Math.max(...domain) - Math.min(...domain); const rangeExtent = Math.max(...range) - Math.min(...range); return domainExtent / rangeExtent * props.offset; } // eslint-disable-next-line max-params function getX0(props, calculatedProps, index, role) { const groupLength = role === "stack" ? calculatedProps.datasets[0].length : calculatedProps.datasets.length; const center = (groupLength - 1) / 2; const totalWidth = pixelsToValue(props, "x", calculatedProps); return (index - center) * totalWidth; } // eslint-disable-next-line max-params function getPolarX0(props, calculatedProps, index, role) { const groupLength = role === "stack" ? calculatedProps.datasets[0].length : calculatedProps.datasets.length; const center = (groupLength - 1) / 2; const width = getAngularWidth(props, calculatedProps); return (index - center) * width; } function getAngularWidth(props, calculatedProps) { const { range } = calculatedProps; const angularRange = Math.abs(range.x[1] - range.x[0]); const r = Math.max(...range.y); return props.offset / (2 * Math.PI * r) * angularRange; } function getLabels(props, datasets, index) { if (!props.labels) { return undefined; } return Math.floor(datasets.length / 2) === index ? props.labels : undefined; } function getChildProps(props, calculatedProps) { const { categories, domain, range, scale, horizontal, origin, padding } = calculatedProps; const { width, height, theme, polar } = props; return { height, width, theme, polar, origin, categories, domain, range, scale, horizontal, padding, standalone: false }; } function getColorScale(props, child) { const role = child.type && child.type.role; const colorScaleOptions = child.props.colorScale || props.colorScale; if (role !== "group" && role !== "stack") { return undefined; } return props.theme && props.theme.group ? colorScaleOptions || props.theme.group.colorScale : colorScaleOptions; } function getDataWithOffset(props, defaultDataset, offset) { if (defaultDataset === void 0) { defaultDataset = []; } const dataset = props.data || props.y ? _victoryCore.Data.getData(props) : defaultDataset; const xOffset = offset || 0; return dataset.map(datum => { const _x1 = datum._x instanceof Date ? new Date(datum._x.getTime() + xOffset) : datum._x + xOffset; return Object.assign({}, datum, { _x1 }); }); } function getChildren(initialProps, childComponents, calculatedProps) { const props = _victoryCore.Helpers.modifyProps(initialProps, fallbackProps, "stack"); const children = childComponents || _react.default.Children.toArray(props.children); const newCalculatedProps = calculatedProps || getCalculatedProps(props, children); const { datasets } = newCalculatedProps; const { labelComponent, polar, theme } = props; const childProps = getChildProps(props, newCalculatedProps); const parentName = props.name || "group"; return children.map((child, index) => { const role = child.type && child.type.role; const xOffset = polar ? getPolarX0(props, newCalculatedProps, index, role) : getX0(props, newCalculatedProps, index, role); const style = role === "voronoi" || role === "tooltip" || role === "label" ? child.props.style : _victoryCore.Wrapper.getChildStyle(child, index, newCalculatedProps, theme); const labels = props.labels ? getLabels(props, datasets, index) : child.props.labels; const name = child.props.name || `${parentName}-${role}-${index}`; return /*#__PURE__*/_react.default.cloneElement(child, Object.assign({ labels, style, key: `${name}-key-${index}`, name, data: getDataWithOffset(props, datasets[index], xOffset), colorScale: getColorScale(props, child), labelComponent: labelComponent || child.props.labelComponent, xOffset }, childProps)); }); }