Skip to content

Commit

Permalink
feat: 优化更新逻辑和性能
Browse files Browse the repository at this point in the history
  • Loading branch information
zengyue committed Sep 24, 2021
1 parent 8a31049 commit 1ead15f
Show file tree
Hide file tree
Showing 13 changed files with 359 additions and 51 deletions.
3 changes: 1 addition & 2 deletions packages/f2-next/src/base/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,12 @@ class Component {
}
beforeUpdate() {
}
// TODO updated
update(props: any) {
this.__props = props;
this.props = props;
}
// TODO
forceUpdate() {
this.__shouldRender = true;
}
render(): JSX.Element {
return null;
Expand Down
11 changes: 8 additions & 3 deletions packages/f2-next/src/base/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ class ContainerComponent extends Component {
const appendProps = this._getAppendProps();

map(components, (component: Component) => {
if (!component.__shouldRender) {
return;
}
this.renderComponent(component, appendProps);
component.__shouldRender = false;
});

// 自身不绘制任何内容
Expand Down Expand Up @@ -166,18 +170,19 @@ class ContainerComponent extends Component {
if (component.componentWillReceiveProps) {
component.componentWillReceiveProps(props);
}
component.props = props;
component.props = props;
if (component.update) {
component.update(props);
}
component.__shouldRender = true;
}
}
return component;
}

update(props: any, forceUpdate?) {
update(props: any) {
super.update(props);
const { components, layout } = this;
const { components } = this;
// 只处理数据和children的变化
const { children } = props;

Expand Down
22 changes: 18 additions & 4 deletions packages/f2-next/src/canvas/animation/animator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import interpolate from './interpolate';
import * as Easing from './easing';
import { ElementStatus } from '../../jsx';
import { each, isString } from '@antv/util';

class Animator {
// 对应G的shape
Expand Down Expand Up @@ -38,8 +39,15 @@ class Animator {
this.animation = animation;

const { property = [], easing, duration, delay = 0, start, end, onFrame } = animation;
const interpolates = property.map(key => {
return interpolate(start[key], end[key]);
const interpolates = property.map(name => {
if (isString(name)) {
return interpolate(start[name], end[name]);
}
// @ts-ignore
if (name.interpolate) {
// @ts-ignore
return name.interpolate(start, end);
}
});

this.easing = typeof easing === 'function' ? easing : (Easing[easing] || Easing.linear);
Expand Down Expand Up @@ -80,9 +88,15 @@ class Animator {
const { element, clip, interpolates, property, onFrame } = this;
let attrs = {};
for (let i = property.length - 1; i >= 0; i--) {
const key = property[i];
attrs[key] = interpolates[i](t);
const name = property[i];
if (isString(name)) {
attrs[name] = interpolates[i](t);
} else {
// @ts-ignore
attrs[name.name] = interpolates[i](t);
}
}
each
if (onFrame) {
attrs = {
...attrs,
Expand Down
8 changes: 7 additions & 1 deletion packages/f2-next/src/canvas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import createComponentTree from './createComponentTree';
import Component from '../base/component';
import Container from '../base/container';
import Layout from '../base/layout';
import equal from '../base/equal';
import Animation from './animation';
import { px2hd } from '../util';
import { createUpdater } from './updater';
Expand All @@ -29,6 +30,7 @@ class Canvas extends Component implements IF2Canvas {
canvas: any;
context: CanvasRenderingContext2D;
component: Container;
componentTree: any;
animation?: Animation;

constructor(props: ChartProps) {
Expand Down Expand Up @@ -68,6 +70,7 @@ class Canvas extends Component implements IF2Canvas {

// 实例化动画模块
this.animation = animate ? new Animation(canvas) : null;
this.componentTree = componentTree;

this.willMount();
this.mount();
Expand Down Expand Up @@ -122,8 +125,11 @@ class Canvas extends Component implements IF2Canvas {

const componentTree = createComponentTree(children, { canvas: this, width, height, context, layout });

component.update({ children: componentTree });
if (equal(this.componentTree, componentTree)) {
return;
}

component.update({ children: componentTree });
this.render();
}

Expand Down
27 changes: 24 additions & 3 deletions packages/f2-next/src/chart/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Coord from '../coord';
import { mix, each } from '@antv/util';
import { mix, each, isNil } from '@antv/util';
import { Scale } from '@antv/scale';
import Container from '../base/container';
import { applyMixins } from '../mixins';
Expand All @@ -8,6 +8,8 @@ import CoordMixin from '../mixins/coord';
import ScaleMixin from '../mixins/scale';
import defaultTheme from './theme';
import Layout from '../base/layout';
import equal from '../base/equal';
import { map } from '../util';

interface Point {
x: number;
Expand Down Expand Up @@ -149,12 +151,31 @@ class Chart extends Container implements IChart, ThemeMixin, CoordMixin, ScaleMi
super.mount();
}

// 自己管理所有子组件的状态
componentWillReceiveProps(nextProps) {
const { props } = this;
const { props, components } = this;
// 数据变化后,所有的子组件状态可能都有变化,需要重新更新
if (props.data !== nextProps.data) {
this.data = nextProps.data;
this.changeGetGeometryData(nextProps.data);
this.updateScales();
map(components, component => {
component.forceUpdate();
});
return;
}

// theme 变化,所有字组件只需要重新render
if (!isNil(nextProps.theme) && equal(props.theme, nextProps.theme)) {
map(components, component => {
component.__shouldRender = true;
});
}

// theme 变化,所有字组件只需要重新render
if (!isNil(nextProps.coord) && equal(props.coord, nextProps.coord)) {
map(components, component => {
component.__shouldRender = true;
});
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/f2-next/src/components/axis/withAxis.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mix } from '@antv/util';
import { mix, deepMix } from '@antv/util';
import { jsx } from '../../jsx';
import Component from '../../base/component';
import Chart from '../../chart';
Expand Down Expand Up @@ -46,7 +46,7 @@ export default View => {
return;
}
const { theme } = chart;
this.style = canvas.px2hd(mix({}, theme.axis, props.style));
this.style = canvas.px2hd(deepMix({}, theme.axis, props.style));
}

_getDimType() {
Expand Down
22 changes: 20 additions & 2 deletions packages/f2-next/src/components/geometry/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class Geometry extends Component implements AttrMixin {
this._createAttrs();
this._adjustScales();
this._processData();
this._initEvent();
this.isInit = true;
}

Expand Down Expand Up @@ -255,10 +256,24 @@ class Geometry extends Component implements AttrMixin {
this.dataArray = dataArray;
}

changeData() {
forceUpdate() {
super.forceUpdate();
this._processData();
}

_initEvent() {
const { container, props } = this;
const canvas = container.get("canvas");
["onPressStart", "onPress", "onPressEnd", 'onPan', 'onPanStart', 'onPanEnd'].forEach((eventName) => {
if (props[eventName]) {
canvas.on(eventName.substr(2).toLowerCase(), (ev) => {
ev.geometry = this;
props[eventName](ev);
});
}
});
}

getY0Value() {
const { attrs, chart } = this;
const { y } = attrs;
Expand Down Expand Up @@ -458,7 +473,10 @@ class Geometry extends Component implements AttrMixin {
const { chart } = this;
const { theme } = chart;
const ticks = scale.getTicks();
colorAttr.setRange(theme.colors);

if(!this.getAttrRange('color')) {
colorAttr.setRange(theme.colors);
}
const items = ticks.map(tick => {
const { text, tickValue } = tick;
const color = colorAttr.mapping(tickValue) || theme.colors[0];
Expand Down
8 changes: 7 additions & 1 deletion packages/f2-next/src/components/guide/withGuide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,13 @@ export default (View) => {
const points = records.map((record) => this.parsePoint(record));
const theme = this.getGuideTheme();

return <View ref={this.triggerRef} points={points} theme={theme} {...props} coord={coord} />;
return <View
ref={this.triggerRef}
points={points}
theme={theme}
coord={ coord }
{...props}
/>;
}
};
};
106 changes: 73 additions & 33 deletions packages/f2-next/src/controller/scale.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
import { each, isObject, mix } from '@antv/util';
import { values as arrayValues } from '../util/array';
import { Scale, Linear, Category } from '@antv/scale';
import { each, isObject, mix, isNil, isFunction } from '@antv/util';
import { values as arrayValues, getRange } from '../util/array';
import { registerTickMethod, Scale, getScale } from '@antv/scale';
import CatTick from './scale/cat-tick';
import LinearTick from './scale/linear-tick';

function adjustCategoryOption(option) {
if (option.range) {
return option;
}
const { values } = option;
const count = values.length;

let range = [0, 1];
// 如果只有一项,显示在中间
if (count === 1) {
range = [0.5, 1];
} else {
// 前后都留半个 1 / count
const offset = 1 / count * 0.5;
range = [ offset, 1 - offset ];
}

option.range = range;
// 覆盖0.3.x的 cat 方法
registerTickMethod('cat', CatTick);
registerTickMethod('time-cat', CatTick);
// 覆盖linear 度量的tick算法
registerTickMethod('wilkinson-extended', LinearTick);

return option;
}

class ScaleController {

Expand All @@ -46,16 +33,72 @@ class ScaleController {
this.scaleOptions = scaleOptions;
}

_getType(option) {
const { type, values } = option;
if (type) {
return type;
}
if (typeof values[0] === 'number') {
return 'linear';
}
return 'cat';
}

_getOption(option) {
const { values } = option;
const type = this._getType(option);

option.type = type;

// linear 类型
if (type === 'linear') {
// 设置默认nice
if (typeof option.nice !== 'boolean') {
option.nice = true;
}
// 重置最大最小
const { min, max } = getRange(values);
if (isNil(option.min)) {
option.min = min;
}
if (isNil(option.max)) {
option.max = max;
}

return option;
}
// 分类类型
if (type === 'cat') {
if (option.range) {
return option;
}
const count = values.length;
let range = [0, 1];
// 如果只有一项,显示在中间
if (count === 1) {
range = [0.5, 1];
} else {
// 前后都留半个 1 / count
const offset = 1 / count * 0.5;
range = [ offset, 1 - offset ];
}
option.range = range;
return option;
}
return option;
}

// 根据 scaleOptions scale的定义,批量更新所有scale
updateScales(data) {
const { scaleOptions, scales = {} } = this;
each(scaleOptions, (option, field) => {
const values = option.values ? option.values : arrayValues(data, field);
const instanceScale = scales[field];
const scaleOption = {
const scaleOption = this._getOption({
...option,
field,
values,
};
});

if (instanceScale) {
this.updateScale(instanceScale, scaleOption);
Expand All @@ -68,15 +111,12 @@ class ScaleController {
}

createScale(option) {
const { type, values } = option;
if (type) {
return new type({ ...option, values });
}
if (typeof values[0] === 'number') {
return new Linear({ ...option, values });
const { type } = option;
if (isFunction(type)) {
return new type(option);
}
const newOption = adjustCategoryOption({ ...option, values });
return new Category(newOption);
const Scale = getScale(type);
return new Scale(option);
}

updateScale(scale, option) {
Expand Down
Loading

0 comments on commit 1ead15f

Please sign in to comment.