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

fix: 修复 axis rerender 不更新布局和 labelOffset 报错 #1293

Merged
merged 2 commits into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions packages/f2/src/chart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ class Chart extends Component implements IChart, InteractionMixin {
const {
style: nextStyle,
data: nextData,
coord: nextCoord,
scale: nextScale,
interactions: nextInteractions,
} = nextProps;
Expand All @@ -118,11 +117,6 @@ class Chart extends Component implements IChart, InteractionMixin {
coordController.updateLayout(this.layout);
}

// willReceiveProps 一定会触发render,
// render 时要重置 coord 范围,重置后需要让所有子组件都重新render
// 所以这里不比较是否有差异,每次都新建,让所有子组件重新render
this.coord = coordController.create(nextCoord, this.layout);

if (nextData !== lastData) {
scaleController.changeData(nextData);
}
Expand All @@ -133,6 +127,13 @@ class Chart extends Component implements IChart, InteractionMixin {
}
}

willUpdate() {
const { coordController, props } = this;
// render 时要重置 coord 范围,重置后需要让所有子组件都重新render
// 所以这里不比较是否有差异,每次都新建,让所有子组件重新render
this.coord = coordController.create(props.coord, this.layout);
}

private getStyle(props, context) {
const { theme, px2hd, left, top, width, height } = context;
const { style } = props;
Expand Down
25 changes: 6 additions & 19 deletions packages/f2/src/components/axis/withAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type BBox = {
export default (View) => {
return class Axis extends Component<AxisProps> {
style: Style = {};
maxBBox: BBox;

constructor(props: AxisProps) {
super(props);
Expand Down Expand Up @@ -67,7 +66,7 @@ export default (View) => {
}
// 获取ticks最大的宽高
getMaxBBox(ticks, style: Style): BBox {
const { context, maxBBox } = this;
const { context } = this;
const { measureText } = context;
const { labelOffset } = style;

Expand All @@ -80,20 +79,10 @@ export default (View) => {
height = Math.max(height, bbox.height);
});

let bbox = {
const bbox = {
width: width + labelOffset,
height: height + labelOffset,
};

// 增量更新,以最大的宽高作为限制
if (maxBBox) {
bbox = {
Copy link
Member

Choose a reason for hiding this comment

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

这段逻辑如果去掉的话, 如果多次update 会导致Chart里的layout越来越小

Copy link
Member

Choose a reason for hiding this comment

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

具体可以跑下 packages/f2/test/components/interaction/pan.test.tsx 这个用例复现出来

Copy link
Member Author

Choose a reason for hiding this comment

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

改好了,这个是update 时 坐标轴没有重置导致的

height: Math.max(0, maxBBox.height - bbox.height),
width: Math.max(0, maxBBox.width - bbox.width),
};
}

this.maxBBox = bbox;
return bbox;
}

Expand Down Expand Up @@ -132,14 +121,12 @@ export default (View) => {
if (style[key] === null) {
return;
}
const styleValue = isFunction(style[key]) ? undefined : style[key]
const styleValue = isFunction(style[key]) ? undefined : style[key];

if (isString(value) || isNumber(value)) {
this.style[key] = px2hd(styleValue) || value;
} else {
this.style[key] = px2hd(
deepMix(clone(value), styleValue)
);
this.style[key] = px2hd(deepMix(clone(value), styleValue));
}
});

Expand Down Expand Up @@ -182,8 +169,8 @@ export default (View) => {

// 主要是计算coord的布局
updateCoord() {
const { props, context } = this;
const { visible, style, chart, coord } = props;
const { props } = this;
const { visible, chart, coord } = props;
if (visible === false) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions packages/f2/test/components/axis/axis.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ describe('Axis 轴', () => {
}
return cfg;
},
labelOffset: '8px',
}}
/>
<Line x="index" y="value" color="#2FC25B" />
Expand Down
84 changes: 24 additions & 60 deletions packages/f2/test/components/interaction/pan.test.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,22 @@
// @ts-nocheck
import { jsx } from '../../../src';
import { Polar, Rect } from '../../../src/coord';
import { Canvas, Chart, Component } from '../../../src';
import { Interval, Axis, Legend, Tooltip, Line } from '../../../src/components';
import { createContext } from '../../util';

class Interaction {}

class CustomInteraction extends Interaction {}

class InjectTestComponent extends Component {
didMount() {
const interactionContext = this.props.chart.interaction.context;
window.interactionContext = interactionContext;
interactionContext.doZoom(0.5, 0.5, 1.5);

for (let i = 0; i <= 9; i++) {
setTimeout(() => {
// interactionContext.doZoom(0.5, 0.5, 1.5)
interactionContext.start();
interactionContext.doMove(-0.001 * i);
}, i * 100);
}
}
}
import { Canvas, Chart } from '../../../src';
import { Axis, Line } from '../../../src/components';
import { createContext, delay } from '../../util';

describe('Interaction 交互', () => {
it.only('平移和缩放', async () => {
it('平移和缩放', async () => {
const context = createContext('基础柱状图', {
width: '500px',
width: '350px',
height: '300px',
});
const chartRef = { current: null };
const res = await fetch('https://gw.alipayobjects.com/os/antfincdn/KbnoL5QgL0/index.json');
const data = await res.json();
const { type, props } = (
<Canvas context={context} pixelRatio={window.devicePixelRatio}>
const { props } = (
<Canvas context={context} pixelRatio={1}>
<Chart
ref={chartRef}
data={data}
coord={
{
// type: Polar,
// transposed: true,
// left: 100,
// top: 100,
// right: 100,
// bottom: 100,
}
}
scale={{
// genre: {},
reportDateTimestamp: {
range: [0, 1],
mask: 'MM-DD',
},
}}
interactions={[
{
type: 'pan', // 平移
Expand All @@ -75,25 +36,28 @@ describe('Interaction 交互', () => {
// }
]}
>
{/* <Legend /> */}
<Axis field="reportDateTimestamp" type="timeCat" />
<Axis field="reportDateTimestamp" type="timeCat" mask="MM-DD" />
<Axis field="rate" />
{/* <Axis field="genre" position="top"/> */}
{/* <Axis field="sold" position="right" /> */}
<Line
x="reportDateTimestamp"
y="rate"
color="codeType"
// adjust="stack"
/>
<InjectTestComponent />
{/* <Tooltip /> */}
<Line x="reportDateTimestamp" y="rate" color="codeType" />
</Chart>
</Canvas>
);

// @ts-ignore
const canvas = new type(props);
const canvas = new Canvas(props);
canvas.render();

const chart = chartRef.current;

const interactionContext = chart.interaction.context;
interactionContext.doZoom(0.5, 0.5, 1.5);

await delay(100);
interactionContext.start();
interactionContext.doMove(-0.008);

await delay(100);
expect(chart.coord.top).toBe(15);
expect(chart.coord.left).toBeCloseTo(41.96);
expect(chart.coord.bottom).toBeCloseTo(267.5);
});
});
10 changes: 9 additions & 1 deletion packages/f2/test/util.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
function delay(time) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, time);
});
}

const createContext = (title = '', { height = '225px', width = '300px' }: any = {}) => {
const canvasEl = document.createElement('canvas');
const titleEl = document.createElement('p');
Expand All @@ -11,4 +19,4 @@ const createContext = (title = '', { height = '225px', width = '300px' }: any =
return context;
};

export { createContext };
export { createContext, delay };