Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of Wrapper components (Chart, Group, Stack) #1494

Merged
merged 13 commits into from
Mar 9, 2020
6 changes: 3 additions & 3 deletions packages/victory-bar/src/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ const getCalculatedValues = (props) => {
const { theme, polar } = props;
const defaultStyles = theme && theme.bar && theme.bar.style ? theme.bar.style : {};
const style = Helpers.getStyles(props.style, defaultStyles);
const data = Data.getData(props);
const range = {
const data = Data.getData(props); // Data.getData needs to be called to format the data (we may be able to do this in a wrapper component)
const range = props.range || {
x: Helpers.getRange(props, "x"),
y: Helpers.getRange(props, "y")
};
const domain = {
const domain = props.domain || {
x: Domain.getDomainWithZero(props, "x"),
y: Domain.getDomainWithZero(props, "y")
};
Expand Down
1 change: 1 addition & 0 deletions packages/victory-chart/src/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ function getCalculatedProps(props, childComponents) {
x: baseScale.x.domain(domain.x).range(horizontal ? range.y : range.x),
y: baseScale.y.domain(domain.y).range(horizontal ? range.x : range.y)
};

const origin = polar ? Helpers.getPolarOrigin(props) : Axis.getOrigin(domain);

const originSign = {
Expand Down
11 changes: 4 additions & 7 deletions packages/victory-core/src/victory-util/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,10 @@ function reduceChildren(
const childName = child.props.name || `${childRole}-${names[index]}`;
if (child.props && child.props.children) {
const childProps = assign({}, child.props, pick(parentProps, sharedProps));
const nestedChildren =
child.type && isFunction(child.type.getChildren)
? child.type.getChildren(childProps)
: React.Children.toArray(child.props.children).map((c) => {
const nestedChildProps = assign({}, c.props, pick(childProps, sharedProps));
return React.cloneElement(c, nestedChildProps);
});
const nestedChildren = React.Children.toArray(child.props.children).map((c) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the issue for stacking. The domain won't be correctly calculated if VictoryStack getChildren isn't called when calculating the domain, because the y0 / y1 values wont be set on the children. I'm guessing removing this is also where we're getting most of our perf improvements, though. It's probably worth writing a specialized method for calculating a domain for VictoryStack.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this! I'll start poking around to see what I can figure out 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... we also have to make sure that VictoryChart and VictoryGroup actually use VictoryStack's getDomain method. Maybe it should be a static on that class the same way it is on components like VictoryBar

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually looking into potentially having VictoryChart and VictoryGroup properly calculate y0 and y1 in their getCalculatedProps so we can bank on the those values being available/memoized on subsequent/child getCalculateProps calls.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I'm using the wrong terms... I mean _y0 and _y1. Values that get added to each data point when we stack values

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had a ton of time to spend on this since last week, but I did figure out a small win to fix the regression (I think, still need to check chromatic). It does decrease performance, from 690 milliseconds to about 1.07 seconds, and also increased the number of reduceChildren from 21 to 771, but that is significantly better than the original 7234 calls.

const nestedChildProps = assign({}, c.props, pick(childProps, sharedProps));
return React.cloneElement(c, nestedChildProps);
});
const childNames = nestedChildren.map((c, i) => `${childName}-${i}`);
const nestedResults = traverseChildren(nestedChildren, childNames, child);
memo = combine(memo, nestedResults);
Expand Down
8 changes: 4 additions & 4 deletions packages/victory-group/src/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ function getCalculatedProps(props, childComponents) {
props = Helpers.modifyProps(props, fallbackProps, role);
const style = Wrapper.getStyle(props.theme, props.style, role);
const { offset, colorScale, color, polar, horizontal } = props;
const categories = Wrapper.getCategories(props, childComponents);
const datasets = Wrapper.getDataFromChildren(props);
const domain = {
const categories = props.categories || Wrapper.getCategories(props, childComponents);
const datasets = props.datasets || Wrapper.getDataFromChildren(props);
const domain = props.domain || {
x: Wrapper.getDomain(assign({}, props, { categories }), "x", childComponents),
y: Wrapper.getDomain(assign({}, props, { categories }), "y", childComponents)
};
const range = {
const range = props.range || {
x: Helpers.getRange(props, "x"),
y: Helpers.getRange(props, "y")
};
Expand Down
8 changes: 4 additions & 4 deletions packages/victory-stack/src/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ function getCalculatedProps(props, childComponents) {
const role = "stack";
props = Helpers.modifyProps(props, fallbackProps, role);
const style = Wrapper.getStyle(props.theme, props.style, role);
const categories = Wrapper.getCategories(props, childComponents);
const datasets = stackData(props, childComponents);
const categories = props.categories || Wrapper.getCategories(props, childComponents);
const datasets = props.datasets || stackData(props, childComponents);
const children = childComponents.map((c, i) => {
return React.cloneElement(c, { data: datasets[i] });
});
const domain = {
const domain = props.domain || {
x: Wrapper.getDomain(assign({}, props, { categories }), "x", children),
y: Wrapper.getDomain(assign({}, props, { categories }), "y", children)
};
const range = {
const range = props.range || {
x: Helpers.getRange(props, "x"),
y: Helpers.getRange(props, "y")
};
Expand Down