Skip to content

Commit

Permalink
core(graphin):change didupdate logic
Browse files Browse the repository at this point in the history
  • Loading branch information
pomelo-nwu committed May 31, 2020
1 parent 2931dc2 commit a1975c7
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 23 deletions.
4 changes: 2 additions & 2 deletions packages/graphin/package.json
Expand Up @@ -41,8 +41,8 @@
"author": "Ant Financial",
"license": "MIT",
"dependencies": {
"@antv/g-canvas": "^0.4.9",
"@antv/g6": "^3.4.7",
"@antv/g-canvas": "^0.4.12",
"@antv/g6": "^3.5.0",
"deepmerge": "^4.0.0",
"lodash": "^4.17.15",
"react": "^16.8.6",
Expand Down
31 changes: 12 additions & 19 deletions packages/graphin/src/Graphin.tsx
Expand Up @@ -16,6 +16,7 @@ import { GraphinProps, GraphinState, ExtendedGraphOptions, GraphType, ForceSimul

/** utils */
import shallowEqual from './utils/shallowEqual';
import deepEqual from './utils/deepEqual';

import './index.less';

Expand Down Expand Up @@ -83,8 +84,8 @@ class Graph extends React.PureComponent<GraphinProps, GraphinState> {
}

componentDidUpdate(prevProps: GraphinProps) {
const isDataChange = this.shouldUpdateWithDeps(prevProps, ['data']);
const isLayoutChange = this.shouldUpdateWithDeps(prevProps, ['layout']);
const isDataChange = this.shouldUpdate(prevProps, 'data');
const isLayoutChange = this.shouldUpdate(prevProps, 'layout');

// only rerender when data or layout change
if (isDataChange || isLayoutChange) {
Expand Down Expand Up @@ -144,21 +145,13 @@ class Graph extends React.PureComponent<GraphinProps, GraphinState> {
);
};

shouldUpdateWithDeps(prevProps: GraphinProps, deps: string[]) {
const { props } = this;
let shouldUpdate = false;
deps.forEach((key) => {
const prevVal = prevProps[key] as DiffValue;
const currentVal = props[key] as DiffValue;
if (prevVal !== currentVal) {
if (!prevVal || !currentVal) {
shouldUpdate = true;
} else if (!shallowEqual(prevVal, currentVal)) {
shouldUpdate = true;
}
}
});
return shouldUpdate;
shouldUpdate(prevProps: GraphinProps, key: string) {
const prevVal = prevProps[key] as DiffValue;
const currentVal = this.props[key] as DiffValue;
// console.time('deep equal');
const isEqual = deepEqual(prevVal, currentVal);
// console.timeEnd('deep equal');
return !isEqual;
}

handleEvents() {
Expand Down Expand Up @@ -278,7 +271,7 @@ class Graph extends React.PureComponent<GraphinProps, GraphinState> {
children = [children];
}

return React.Children.map(children, (child) => {
return React.Children.map(children, child => {
// do not pass props if element is a DOM element or not a valid react element.
if (!React.isValidElement(child) || typeof child.type === 'string') {
return child;
Expand All @@ -296,7 +289,7 @@ class Graph extends React.PureComponent<GraphinProps, GraphinState> {
<div
data-testid="custom-element"
className="graphin-core"
ref={(node) => {
ref={node => {
this.graphDOM = node;
}}
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/graphin/src/controller/init.ts
Expand Up @@ -118,10 +118,10 @@ const initGraph = (props: GraphinProps, graphDOM: HTMLDivElement, behaviorsMode:
},
];
const defaultModes = innerBehaviors
.filter((c) => {
.filter(c => {
return !c.disable;
})
.map((c) => {
.map(c => {
return {
type: c.type,
...c.options,
Expand Down
81 changes: 81 additions & 0 deletions packages/graphin/src/utils/__tests__/deepEqual.test.ts
@@ -0,0 +1,81 @@
import deepEqual from '../deepEqual';

describe('compare ', () => {
it('compare', () => {
expect(deepEqual('a', 'a')).toEqual(true);
expect(deepEqual(0, 0)).toEqual(true);
expect(deepEqual(1, 1)).toEqual(true);
expect(deepEqual(NaN, NaN)).toEqual(true);
expect(deepEqual(undefined, undefined)).toEqual(true);
expect(deepEqual({}, {})).toEqual(true);
expect(deepEqual([], [])).toEqual(true);
expect(
deepEqual(
() => {
console.log('hello');
},
() => {
console.log('hello');
},
),
).toEqual(true);
expect(
deepEqual(
{
name: 'pomelo',
},
{
name: 'pomelo',
},
),
).toEqual(true);
});
it('compare complex object', () => {
const a = {
name: 'pomelo',
do: () => {
console.log('do.');
},
circle: {
a: [
'a',
{
name: 'a',
},
],
},
};
const b = {
name: 'pomelo',
do: () => {
console.log('do.');
},
circle: {
a: [
'a',
{
name: 'a',
},
],
},
};
const c = {
name: 'pomelo',
do: () => {
console.log('do');
},
circle: {
a: [
'a',
{
name: 'a',
},
],
},
};

expect(deepEqual(a, b)).toEqual(true);
expect(deepEqual(a, c)).toEqual(false);
expect(deepEqual(a.circle, c.circle)).toEqual(true);
});
});
38 changes: 38 additions & 0 deletions packages/graphin/src/utils/deepEqual.ts
@@ -0,0 +1,38 @@
const deepEqual = (x: any, y: any): boolean => {
/** 1. NaN */
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
/** 2. primitives and function reference */
if (x === y) {
return true;
}
/** 3.Function,Date,RegExp,String,Number */
if (
(typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)
) {
return x.toString() === y.toString();
}
/** 4.plain object */
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
const isEqualArray = [];
const xKey = Object.keys(x);
const yKey = Object.keys(y);
if (xKey.length !== yKey.length) {
return false;
}
for (let i = 0; i < xKey.length; i++) {
const key = xKey[i];
const isEqual = deepEqual(x[key], y[key]);
isEqualArray.push(isEqual);
}
return isEqualArray.every(c => c);
};

export default deepEqual;

0 comments on commit a1975c7

Please sign in to comment.