victory-chart
Version:
Chart Component for Victory
134 lines • 4.9 kB
JavaScript
import React from "react";
import defaults from "lodash/defaults";
import isEmpty from "lodash/isEmpty";
import { Background, Helpers, Hooks, UserProps, VictoryContainer, VictoryTheme, Wrapper } from "victory-core";
import { VictorySharedEvents } from "victory-shared-events";
import { VictoryAxis } from "victory-axis";
import { VictoryPolarAxis } from "victory-polar-axis";
import { getBackgroundWithProps, getChildComponents, getCalculatedProps, getChildren } from "./helper-methods";
import isEqual from "react-fast-compare";
const fallbackProps = {
width: 450,
height: 300,
padding: 50
};
const defaultProps = {
backgroundComponent: /*#__PURE__*/React.createElement(Background, null),
containerComponent: /*#__PURE__*/React.createElement(VictoryContainer, null),
defaultAxes: {
independent: /*#__PURE__*/React.createElement(VictoryAxis, null),
dependent: /*#__PURE__*/React.createElement(VictoryAxis, {
dependentAxis: true
})
},
defaultPolarAxes: {
independent: /*#__PURE__*/React.createElement(VictoryPolarAxis, null),
dependent: /*#__PURE__*/React.createElement(VictoryPolarAxis, {
dependentAxis: true
})
},
groupComponent: /*#__PURE__*/React.createElement("g", null),
standalone: true,
theme: VictoryTheme.grayscale
};
const VictoryChartImpl = initialProps => {
const propsWithDefaults = React.useMemo(() => defaults({}, initialProps, defaultProps), [initialProps]);
const role = "chart";
const {
getAnimationProps,
setAnimationState,
getProps
} = Hooks.useAnimationState();
const props = getProps(propsWithDefaults);
const modifiedProps = Helpers.modifyProps(props, fallbackProps, role);
const {
desc,
eventKey,
containerComponent,
standalone,
groupComponent,
externalEventMutations,
width,
height,
theme,
polar,
name,
title
} = modifiedProps;
const axes = props.polar ? modifiedProps.defaultPolarAxes : modifiedProps.defaultAxes;
const childComponents = React.useMemo(() => getChildComponents(modifiedProps, axes), [modifiedProps, axes]);
const calculatedProps = React.useMemo(() => getCalculatedProps(modifiedProps, childComponents), [modifiedProps, childComponents]);
const {
domain,
scale,
style,
origin,
horizontal
} = calculatedProps;
const newChildren = React.useMemo(() => {
const children = getChildren(props, childComponents, calculatedProps);
const mappedChildren = children.map((child, index) => {
const childProps = Object.assign({
animate: getAnimationProps(props, child, index)
}, child.props);
return /*#__PURE__*/React.cloneElement(child, childProps);
});
if (props.style && props.style.background) {
const backgroundComponent = getBackgroundWithProps(props, calculatedProps);
mappedChildren.unshift(backgroundComponent);
}
return mappedChildren;
}, [getAnimationProps, childComponents, props, calculatedProps]);
const containerProps = React.useMemo(() => {
if (standalone) {
return {
desc,
domain,
width,
height,
horizontal,
name,
origin: polar ? origin : undefined,
polar,
theme,
title,
scale,
standalone,
style: style.parent
};
}
return {};
}, [desc, domain, height, horizontal, name, origin, polar, scale, standalone, style, title, theme, width]);
const container = React.useMemo(() => {
if (standalone) {
const defaultContainerProps = defaults({}, containerComponent.props, containerProps, UserProps.getSafeUserProps(propsWithDefaults));
return /*#__PURE__*/React.cloneElement(containerComponent, defaultContainerProps);
}
return groupComponent;
}, [groupComponent, standalone, containerComponent, containerProps, propsWithDefaults]);
const events = React.useMemo(() => {
return Wrapper.getAllEvents(props);
}, [props]);
const previousProps = Hooks.usePreviousProps(propsWithDefaults);
React.useEffect(() => {
// This is called before dismount to keep state in sync
return () => {
if (propsWithDefaults.animate) {
setAnimationState(previousProps, propsWithDefaults);
}
};
}, [setAnimationState, previousProps, propsWithDefaults]);
if (!isEmpty(events)) {
return /*#__PURE__*/React.createElement(VictorySharedEvents, {
container: container,
eventKey: eventKey,
events: events,
externalEventMutations: externalEventMutations
}, newChildren);
}
return /*#__PURE__*/React.cloneElement(container, container.props, newChildren);
};
export const VictoryChart = /*#__PURE__*/React.memo(VictoryChartImpl, isEqual);
VictoryChart.displayName = "VictoryChart";
// @ts-expect-error FIXME: Does this "expectedComponents" do anything?
VictoryChart.expectedComponents = ["groupComponent", "containerComponent"];