Skip to content

Commit

Permalink
perf: seperate debounce update relates for correct updating and bette…
Browse files Browse the repository at this point in the history
…r performance
  • Loading branch information
Yanyan-Wang committed Nov 9, 2023
1 parent fde08a4 commit 8cfa5e6
Show file tree
Hide file tree
Showing 22 changed files with 894 additions and 1,952 deletions.
28 changes: 18 additions & 10 deletions packages/g6/src/runtime/controller/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,15 +529,21 @@ export class ItemController {
const { dataTypeField: nodeDataTypeField } = nodeTheme;
const edgeIdsToUpdate: Set<ID> = new Set<ID>();
const comboIdsToUpdate: Set<ID> = new Set<ID>();
const updateRelates = (edgeIds?: Set<ID>) => {
const ids = edgeIds
? [...edgeIds]
: [...comboIdsToUpdate, ...edgeIdsToUpdate];
ids.forEach((nid) => {
const updateRelates = (param: { edgeIds?: Set<ID>; callback?: any }) => {
const { edgeIds, callback } = param;
edgeIds.forEach((nid) => {
const item = itemMap.get(nid) as Edge | Combo;
if (item && !item.destroyed) item.forceUpdate();
});
callback?.();
};
const updateAllRelates = () => {
[...comboIdsToUpdate, ...edgeIdsToUpdate].forEach((nid) => {
const item = itemMap.get(nid) as Edge | Combo;
if (item && !item.destroyed) item.forceUpdate();
});
};
const debounceUpdateAllRelates = debounce(updateAllRelates, 16, false);
const debounceUpdateRelates = debounce(updateRelates, 16, false);

Object.values(nodeComboUpdate).forEach((updateObj: any) => {
Expand Down Expand Up @@ -638,7 +644,7 @@ export class ItemController {
nodeRelatedIdsToUpdate.add(edge.id);
});

item.onframe = () => updateRelates(nodeRelatedIdsToUpdate);
item.onframe = () => updateRelates({ edgeIds: nodeRelatedIdsToUpdate });
let statesCache;
if (
innerModel.data._isCombo &&
Expand All @@ -656,15 +662,17 @@ export class ItemController {
animate,
// call after updating finished
(_, canceled) => {
// @ts-ignore
debounceUpdateRelates(nodeRelatedIdsToUpdate);
item.onframe = undefined;
if (statesCache) {
statesCache.forEach((state) =>
this.graph.setItemState(id, state, true),
);
}
callback(innerModel, canceled);
// @ts-ignore
debounceUpdateRelates({
edgeIds: nodeRelatedIdsToUpdate,
callback: () => callback(innerModel, canceled),
});
},
);

Expand All @@ -675,7 +683,7 @@ export class ItemController {
});
}
});
debounceUpdateRelates();
debounceUpdateAllRelates();
}
// === 6. update edges' data ===
if (groupedChanges.EdgeDataUpdated.length) {
Expand Down
3 changes: 3 additions & 0 deletions packages/g6/src/stdlib/theme/light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export const LightTheme = {
},
labelShape: {
fontWeight: 700,
fontSize: 14,
},
haloShape: {
opacity: 0.25,
Expand Down Expand Up @@ -231,6 +232,7 @@ export const LightTheme = {
},
labelShape: {
fontWeight: 700,
fontSize: 14,
},
haloShape: {
opacity: 0.25,
Expand Down Expand Up @@ -323,6 +325,7 @@ export const LightTheme = {
},
labelShape: {
fontWeight: 700,
fontSize: 14,
},
haloShape: {
opacity: 0.25,
Expand Down
4 changes: 4 additions & 0 deletions packages/site/docs/apis/layout/CircularLayoutOptions.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: CircularLayoutOptions
order: 3
---
111 changes: 111 additions & 0 deletions packages/site/docs/apis/layout/CircularLayoutOptions.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
title: CircularLayoutOptions
order: 3
---

本文展示所有圆形布局配置项。[圆形布局 DEMO](/zh/examples/net/circular/#circularConfigurationTranslate)

<img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*H6DyT6468ZMAAAAAAAAAAAAADmJ7AQ/original" width=300 />
<img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*1PpVQLFTaQwAAAAAAAAAAAAADmJ7AQ/original" width=300 />

## radius

**类型**`number`

**默认值**: 默认从节点大小与间距形成的周长计算而得

**是否必须**:false

**说明**:圆形布局的半径。若设置了 `radius`,则 `startRadius``endRadius` 不生效

## center

**类型**`[number, number]`

**默认值**:当前容器的中心位置

**是否必须**:false

**说明**:圆形布局的中心位置

## clockwise

**类型**`boolean`

**默认值**`true`

**是否必须**:false

**说明**:是否为顺时针布局

## divisions

**类型**`number`

**默认值**`1`

**是否必须**:false

**说明**:节点在环上的分段数(几个段将均匀分布),在 endRadius - startRadius != 0 时生效

## ordering

**类型**`'topology'` \| `'degree'` \| `null`

**默认值**`null`

**是否必须**:false

**说明**:节点在环上排序的依据。默认 null 代表直接使用数据中的顺序。'topology' 按照拓扑排序。'degree' 按照度数大小排序

## angleRatio

**类型**`number`

**默认值**`1`

**是否必须**:false

**说明**:从第一个节点到最后节点之间相隔多少个 2\*PI

## startRadius

**类型**`number` \| `null`

**默认值**`null`

**是否必须**:false

**说明**:螺旋状布局的起始半径

## endRadius

**类型**`number` \| `null`

**默认值**`null`

**是否必须**:false

**说明**:螺旋状布局的结束半径

## nodeSize

**类型**`number` \| `number`[] \| (`nodeData`: `Node`) => `number`

**默认值**:读取节点数据中的 data.size,若无则默认值为 `10`

**是否必须**:false

**说明**: 节点占据的大小,在未指定 `radius` 时用于计算周长以得到圆形布局的半径

## workerEnabled

**类型**`boolean`

**默认值**`false`

**是否必须**:false

**说明**: 是否启用 web-worker 以防布局计算时间过长阻塞页面交互

<span style="background-color: rgb(251, 233, 231); color: rgb(139, 53, 56)"><strong>⚠️ 注意:</strong></span> `workerEnabled: true` 时,不支持所有函数类型的参数。
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: ComboCombinedLayoutOptions
order: 2
---
120 changes: 120 additions & 0 deletions packages/site/docs/apis/layout/ComboCombinedLayoutOptions.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
title: ComboCombinedLayoutOptions
order: 2
---

本文展示所有 Combo 复合布局的配置项。[ComboCombined 布局 DEMO](/zh/examples/net/comboLayout/#comboCombined)

<img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*zPAzSZ3XxpUAAAAAAAAAAAAADmJ7AQ/original" width=400 />

## center

**类型**`[number, number]`

**默认值**:画布中心

**是否必须**:false

**说明**:布局的中心

## outerLayout

**类型**`LayoutInstance`

**默认值**:Force 布局

**是否必须**:false

**说明**:最外层的布局算法,默认为 `force`。具体参数详见被使用布局的文档。默认情况下 `force` 布局将使用以下参数:

```javascript
outerLayout: new G6.Extensions.ForceLayout({
gravity: 1,
factor: 2,
linkDistance: (edge: EdgeInnerModel, source: NodeInnerModel, target: NodeInnerModel) => {
const nodeSize = ((source.data.size?.[0] || 30) + (target.data.size?.[0] || 30)) / 2;
return Math.min(nodeSize * 1.5, 700);
},
});
```
## innerLayout
**类型**:`LayoutInstance`
**默认值**:Concentric 布局
**是否必须**:false
**说明**:combo 内部的布局算法,需要使用同步的布局算法,默认为 `concentric`。具体参数详见被使用布局的文档。
默认情况下 `concentric` 布局将使用以下参数:
```javascript
innerLayout: new G6.Extensions.ConcentricLayout({
sortBy: 'id',
});
```
## comboPadding
**类型**:`number` \| (`comboModel`: `ComboInnerModel`) => `number`
**默认值**:`10`
**是否必须**:false
**说明**:Combo 内部的 padding 值,不用于渲染,仅用于计算力。推荐设置为与视图上 Combo 内部 padding 值相同的值
```javascript
(comboModel) => {
// d is a combo inner model
if (d.id === 'combo1') {
return 100;
}
return 10;
};
```
## nodeSize
**类型**:`number` \| `number`[] \| (`nodeModel`: `NodeInnerModel`) => `number`
**默认值**:`10`
**是否必须**:false
**说明**:节点大小(直径)。用于碰撞检测。若不指定,则根据传入的节点数据的 `data.size` 属性计算。若即不指定,节点中也没有 `data.size`,则默认大小为 `10`
## spacing
**类型**:`number` \| `number`[] \| (`nodeModel`: `NodeInnerModel`) => `number`
**默认值**:`0`
**是否必须**:false
**说明**:`preventNodeOverlap``preventOverlap``true` 时生效, 防止重叠时节点/ combo 边缘间距的最小值。可以是回调函数, 为不同节点设置不同的最小间距, 如示例
**示例**:
```typescript
(nodeModel: NodeInnerModel) => {
// d is a node's inner model
if (nodeModel.id === 'node1') {
return 100;
}
return 10;
};
```
## workerEnabled
**类型**:`boolean`
**默认值**:`false`
**是否必须**:false
**说明**:是否启用 web-worker 以防布局计算时间过长阻塞页面交互。
<span style="background-color: rgb(251, 233, 231); color: rgb(139, 53, 56)"><strong>⚠️ 注意:</strong></span> `workerEnabled: true` 时,不支持所有函数类型的参数。
4 changes: 4 additions & 0 deletions packages/site/docs/apis/layout/DagreLayoutOptions.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: DagreLayoutOptions
order: 1
---
Loading

0 comments on commit 8cfa5e6

Please sign in to comment.