Skip to content

Commit

Permalink
fix(react-chart): fix axis layout after update data (#2199)
Browse files Browse the repository at this point in the history
  • Loading branch information
Krijovnick authored Aug 5, 2019
1 parent 0ee86fd commit 2b84bd8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 32 deletions.
52 changes: 26 additions & 26 deletions packages/dx-react-chart/src/plugins/axis.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,76 +167,76 @@ describe('Axis', () => {
setupAxisCoordinates([0, 1]);
const tree = mount(<AxisTester position="left" />);

(tree.find(RootComponent).props() as any).onSizeChange({ tag: 'size' });
(tree.find(RootComponent).props() as any).onSizeChange({ width: 350, height: 250 });

expect(defaultDeps.action.changeBBox.mock.calls[0][0]).toEqual({
placeholder: 'left-axis-test-domain', bBox: { tag: 'size' },
placeholder: 'left-axis-test-domain', bBox: { width: 350, height: 250 },
});

enforceUpdate(tree);

expect(getDivStyle(tree)).toEqual({ position: 'relative', width: 250 });
expect(tree.find('svg').props()).toMatchObject({ width: 400, height: 300 });
});

it('should call changeBBox one time, zises are not changed after update', () => {
setupAxisCoordinates([0, 1]);
const tree = mount(<AxisTester position="left" />);

const { onSizeChange } = tree.find(RootComponent).props() as any;

onSizeChange({ tag: 'size' });
onSizeChange({ tag: 'size' });

expect(defaultDeps.action.changeBBox.mock.calls.length).toBe(1);
expect(tree.find('svg').props()).toMatchObject({ width: 350, height: 300 });
});

it('should pass correct bbox, vertical-right position', () => {
setupAxisCoordinates([0, 1]);
const tree = mount(<AxisTester position="right" />);

(tree.find(RootComponent).props() as any).onSizeChange({ tag: 'size' });
(tree.find(RootComponent).props() as any).onSizeChange({ width: 350, height: 250 });

expect(defaultDeps.action.changeBBox.mock.calls[0][0]).toEqual({
placeholder: 'right-axis-test-domain', bBox: { tag: 'size' },
placeholder: 'right-axis-test-domain', bBox: { width: 350, height: 250 },
});

enforceUpdate(tree);

expect(getDivStyle(tree)).toEqual({ position: 'relative', width: 300 });
expect(tree.find('svg').props()).toMatchObject({ width: 400, height: 300 });
expect(tree.find('svg').props()).toMatchObject({ width: 350, height: 300 });
});

it('should pass correct bbox, horizontal-top position', () => {
setupAxisCoordinates([1, 0]);
const tree = mount(<AxisTester position="top" />);

(tree.find(RootComponent).props() as any).onSizeChange({ tag: 'size' });
(tree.find(RootComponent).props() as any).onSizeChange({ width: 350, height: 250 });

expect(defaultDeps.action.changeBBox.mock.calls[0][0]).toEqual({
placeholder: 'top-axis-test-domain', bBox: { tag: 'size' },
placeholder: 'top-axis-test-domain', bBox: { width: 350, height: 250 },
});

enforceUpdate(tree);

expect(getDivStyle(tree)).toEqual({ position: 'relative', height: 100, flexGrow: 1 });
expect(tree.find('svg').props()).toMatchObject({ width: 400, height: 300 });
expect(tree.find('svg').props()).toMatchObject({ width: 400, height: 250 });
});

it('should pass correct bbox for group, horizontal-bottom position', () => {
setupAxisCoordinates([1, 0]);
const tree = mount(<AxisTester />);

(tree.find(RootComponent).props() as any).onSizeChange({ tag: 'size' });
(tree.find(RootComponent).props() as any).onSizeChange({ width: 350, height: 250 });

expect(defaultDeps.action.changeBBox.mock.calls[0][0]).toEqual({
placeholder: 'bottom-axis-test-domain', bBox: { tag: 'size' },
placeholder: 'bottom-axis-test-domain', bBox: { width: 350, height: 250 },
});

enforceUpdate(tree);

expect(getDivStyle(tree)).toEqual({ position: 'relative', height: 150, flexGrow: 1 });
expect(tree.find('svg').props()).toMatchObject({ width: 400, height: 300 });
expect(tree.find('svg').props()).toMatchObject({ width: 400, height: 250 });
});

it('should call changeBBox one time, zises are not changed after update', () => {
setupAxisCoordinates([0, 1]);
const tree = mount(<AxisTester position="left" />);

const { onSizeChange } = tree.find(RootComponent).props() as any;

onSizeChange({ width: 300, height: 200 });
onSizeChange({ width: 300, height: 200 });

expect(defaultDeps.action.changeBBox.mock.calls.length).toBe(1);
});

it('should pass axisCoordinates method correct parameters, horizontal orientation', () => {
Expand Down Expand Up @@ -384,7 +384,7 @@ describe('Axis', () => {
setupAxisCoordinates([1, 0]);
const tree = mount(<AxisTester />);

(tree.find(RootComponent).props() as any).onSizeChange({ tag: 'size' });
(tree.find(RootComponent).props() as any).onSizeChange({ width: 350, height: 250 });
enforceUpdate(tree);

expect(tree.find(LineComponent).props()).toEqual({
Expand All @@ -399,7 +399,7 @@ describe('Axis', () => {
setupAxisCoordinates([0, 1]);
const tree = mount(<AxisTester />);

(tree.find(RootComponent).props() as any).onSizeChange({ tag: 'size' });
(tree.find(RootComponent).props() as any).onSizeChange({ width: 350, height: 250 });
enforceUpdate(tree);

expect(tree.find(LineComponent).props()).toEqual({
Expand Down
13 changes: 8 additions & 5 deletions packages/dx-react-chart/src/plugins/axis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class RawAxis extends React.PureComponent<RawAxisProps> {
lineComponent: LineComponent,
} = this.props;
const placeholder = `${position}-axis`;
const layoutName = `${placeholder}-${scaleName}`;
return (
<Template name={placeholder}>
<TemplatePlaceholder />
Expand All @@ -68,9 +69,8 @@ class RawAxis extends React.PureComponent<RawAxisProps> {
if (!scale) {
return null;
}

const layoutName = `${placeholder}-${scaleName}`;
const { width, height } = layouts[layoutName] || { width: 0, height: 0 };

const { sides: [dx, dy], ticks } = axisCoordinates({
scaleName: scaleName!,
position: position!,
Expand All @@ -90,17 +90,20 @@ class RawAxis extends React.PureComponent<RawAxisProps> {
// Let's see if anything could be done to improve the situation.
const visibleTicks = ticks
.filter(createTickFilter([dx * this.adjustedWidth, dy * this.adjustedHeight]));

const handleSizeChange: onSizeChangeFn = (size) => {
// The callback is called when DOM is available -
// *rootRef.current* can be surely accessed.
const rect = this.rootRef.current!.getBoundingClientRect();
if (rect.width === this.adjustedWidth && rect.height === this.adjustedHeight) {
const rectSize = [dx ? rect.width : size.width, dy ? rect.height : size.height];

if (rectSize[0] === this.adjustedWidth && rectSize[1] === this.adjustedHeight) {
return;
}
// *setState* is not used because it would cause excessive Plugin rerenders.
// Template rerender is provided by *changeBBox* invocation.
this.adjustedWidth = rect.width;
this.adjustedHeight = rect.height;
this.adjustedWidth = rectSize[0];
this.adjustedHeight = rectSize[1];
changeBBox({ placeholder: layoutName, bBox: size });
};

Expand Down
2 changes: 1 addition & 1 deletion packages/dx-react-chart/src/templates/axis/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class Root extends React.PureComponent<Axis.RootProps, Axis.RootState> {
}

render() {
const { children, onSizeChange, ...restProps } = this.props;
const { children, onSizeChange, dx, dy, ...restProps } = this.props;
const { x, y } = this.state;
return (
<g
Expand Down

0 comments on commit 2b84bd8

Please sign in to comment.