From 2d79ce989d7ae23aff99eb6fa45c42a1940794eb Mon Sep 17 00:00:00 2001 From: Yanyan Wang Date: Thu, 15 Dec 2022 19:41:35 +0800 Subject: [PATCH] fix: destroy graph and call layout problem, closes: #4126; (#4142) * fix: destroy graph and call layout problem, closes: #4126; * remove duplicated event emit, closes: #4043; fix: mousedown on other DOMs and mouseup on canvas, click is triggered unexpectly, closes: #2922; fix: mousemove and mouseup are not triggered with drag and dragend, closes: #3086; fix: replace DOMMouseScroll and mousewheel with wheel event, closes: #3256; perf: refresh item when updateChild, updateChildren, addChild, removeChild for TreeGraph; * chore: refine * chore: update version num --- CHANGELOG.md | 9 ++++ packages/core/package.json | 2 +- packages/core/src/global.ts | 2 +- packages/core/src/graph/controller/layout.ts | 8 +++- packages/element/package.json | 4 +- packages/g6/package.json | 4 +- packages/g6/src/index.ts | 4 +- packages/pc/package.json | 8 ++-- packages/pc/src/global.ts | 2 +- packages/pc/src/graph/controller/event.ts | 43 +++++++++++++++---- packages/pc/src/graph/controller/layout.ts | 2 + packages/pc/src/graph/tree-graph.ts | 28 ++++++++---- .../tests/unit/graph/controller/event-spec.ts | 9 +++- packages/plugin/package.json | 6 +-- packages/site/docs/api/shapeProperties.zh.md | 2 +- .../item/customNode/demo/scrollNode.js | 15 ++++--- packages/site/package.json | 2 +- 17 files changed, 106 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26cdc330732..2e9870c4298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # ChangeLog +### 4.8.0 + +- fix: destroy graph and call layout problem, closes: #4126; +- fix: remove duplicated event emit, closes: #4043; +- fix: mousedown on other DOMs and mouseup on canvas, click is triggered unexpectly, closes: #2922; +- fix: mousemove and mouseup are not triggered with drag and dragend, closes: #3086; +- fix: replace DOMMouseScroll and mousewheel with wheel event, closes: #3256; +- perf: refresh item when updateChild, updateChildren, addChild, removeChild for TreeGraph; + ### 4.7.17 - fix: expandCombo and the edges of the children are not refreshed, closes: #3250; diff --git a/packages/core/package.json b/packages/core/package.json index f77a5c38c58..a156a1877c6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g6-core", - "version": "0.7.17", + "version": "0.8.0", "description": "A Graph Visualization Framework in JavaScript", "keywords": [ "antv", diff --git a/packages/core/src/global.ts b/packages/core/src/global.ts index 3c6d5e8ebe1..dc28c4f3120 100644 --- a/packages/core/src/global.ts +++ b/packages/core/src/global.ts @@ -64,7 +64,7 @@ const colorSet = { }; export default { - version: '0.7.17', + version: '0.8.0', rootContainerClassName: 'root-container', nodeContainerClassName: 'node-container', edgeContainerClassName: 'edge-container', diff --git a/packages/core/src/graph/controller/layout.ts b/packages/core/src/graph/controller/layout.ts index abeb71fb6e9..2b6e0adac9f 100644 --- a/packages/core/src/graph/controller/layout.ts +++ b/packages/core/src/graph/controller/layout.ts @@ -118,10 +118,13 @@ export default abstract class LayoutController { // 销毁布局,不能使用 this.destroy,因为 controller 还需要被使用,只是把布局算法销毁 public destroyLayout() { - const { graph } = this; this.destoryLayoutMethods(); - graph.set('layout', undefined); + const { graph } = this; + if (graph && !graph.get('destroyed')) { + graph.set('layout', undefined); + } + this.layoutCfg = undefined; this.layoutType = undefined; this.layoutMethods = undefined; @@ -192,6 +195,7 @@ export default abstract class LayoutController { // 重新布局 public relayout(reloadData?: boolean) { const { graph, layoutMethods, layoutCfg } = this; + if (!graph || graph.get('destroyed')) return; if (reloadData) { this.data = this.setDataFromGraph(); diff --git a/packages/element/package.json b/packages/element/package.json index e2a3b1b77db..9f1d374dc6e 100644 --- a/packages/element/package.json +++ b/packages/element/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g6-element", - "version": "0.7.17", + "version": "0.8.0", "description": "A Graph Visualization Framework in JavaScript", "keywords": [ "antv", @@ -61,7 +61,7 @@ }, "dependencies": { "@antv/g-base": "^0.5.1", - "@antv/g6-core": "0.7.17", + "@antv/g6-core": "0.8.0", "@antv/util": "~2.0.5" }, "devDependencies": { diff --git a/packages/g6/package.json b/packages/g6/package.json index dc55c66b27a..cc5a7212814 100644 --- a/packages/g6/package.json +++ b/packages/g6/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g6", - "version": "4.7.17", + "version": "4.8.0", "description": "A Graph Visualization Framework in JavaScript", "keywords": [ "antv", @@ -66,7 +66,7 @@ ] }, "dependencies": { - "@antv/g6-pc": "0.7.17" + "@antv/g6-pc": "0.8.0" }, "devDependencies": { "@babel/core": "^7.7.7", diff --git a/packages/g6/src/index.ts b/packages/g6/src/index.ts index 7c2f2733338..f20d4ba3629 100644 --- a/packages/g6/src/index.ts +++ b/packages/g6/src/index.ts @@ -1,7 +1,7 @@ import G6 from '@antv/g6-pc'; -G6.version = '4.7.17'; +G6.version = '4.8.0'; export * from '@antv/g6-pc'; export default G6; -export const version = '4.7.17'; +export const version = '4.8.0'; \ No newline at end of file diff --git a/packages/pc/package.json b/packages/pc/package.json index a7b0970ef38..8b1712d1d74 100644 --- a/packages/pc/package.json +++ b/packages/pc/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g6-pc", - "version": "0.7.17", + "version": "0.8.0", "description": "A Graph Visualization Framework in JavaScript", "keywords": [ "antv", @@ -75,9 +75,9 @@ "@antv/g-canvas": "^0.5.2", "@antv/g-math": "^0.1.1", "@antv/g-svg": "^0.5.1", - "@antv/g6-core": "0.7.17", - "@antv/g6-element": "0.7.17", - "@antv/g6-plugin": "0.7.17", + "@antv/g6-core": "0.8.0", + "@antv/g6-element": "0.8.0", + "@antv/g6-plugin": "0.8.0", "@antv/hierarchy": "^0.6.7", "@antv/layout": "^0.3.0", "@antv/matrix-util": "^3.1.0-beta.3", diff --git a/packages/pc/src/global.ts b/packages/pc/src/global.ts index f9ab76ccfe4..a0c53c2a9d4 100644 --- a/packages/pc/src/global.ts +++ b/packages/pc/src/global.ts @@ -7,7 +7,7 @@ const textColor = 'rgb(0, 0, 0)'; const colorSet = getColorsWithSubjectColor(subjectColor, backColor); export default { - version: '0.7.17', + version: '0.8.0', rootContainerClassName: 'root-container', nodeContainerClassName: 'node-container', edgeContainerClassName: 'edge-container', diff --git a/packages/pc/src/graph/controller/event.ts b/packages/pc/src/graph/controller/event.ts index 5c851ac40a4..5f7f1c1f995 100644 --- a/packages/pc/src/graph/controller/event.ts +++ b/packages/pc/src/graph/controller/event.ts @@ -17,6 +17,8 @@ export default class EventController extends AbstractEvent { protected dragging: boolean = false; + protected mousedown: boolean = false; + protected preItem: Item | null = null; public destroyed: boolean; @@ -48,8 +50,7 @@ export default class EventController extends AbstractEvent { canvas.off('*').on('*', canvasHandler); this.canvasHandler = canvasHandler; - extendEvents.push(addEventListener(el, 'DOMMouseScroll', wheelHandler)); - extendEvents.push(addEventListener(el, 'mousewheel', wheelHandler)); + extendEvents.push(addEventListener(el, 'wheel', wheelHandler)); if (typeof window !== 'undefined') { extendEvents.push(addEventListener(window as any, 'keydown', originHandler)); @@ -81,6 +82,31 @@ export default class EventController extends AbstractEvent { const canvas = graph.get('canvas'); const { target } = evt; const eventType = evt.type; + + switch(eventType) { + // solve G's problem: mousemove and mosueup are not triggered with drag and dragend + case 'drag': + this.onCanvasEvents(Object.assign({}, evt, { type: 'mousemove' })); + break; + case 'dragend': + this.onCanvasEvents(Object.assign({}, evt, { type: 'mouseup' })); + break; + // solve G's problem: mousedown on other DOMs, mouseup on canvas, click event is triggered unexpectly + case 'mousedown': + this.mousedown = true; + break; + case 'dragend': + case 'mouseup': + // mouseup happend before click, so setTimeout to reset the tag for reference in click event + setTimeout(() => this.mousedown = false); + break; + case 'click': + // the mousedown is not happend, the click is invalid + if (!this.mousedown) return; + break; + default: + break; + } /** * (clientX, clientY): 相对于页面的坐标; * (canvasX, canvasY): 相对于 左上角的坐标; @@ -140,12 +166,12 @@ export default class EventController extends AbstractEvent { evt.canvasY = canvasPoint.y; } - // emit('click', evt); - graph.emit(eventType, evt); - - if (evt.name && !evt.name.includes(':')) graph.emit(`${type}:${eventType}`, evt); - // emit('node:click', evt) - else graph.emit(evt.name, evt); // emit('text-shape:click', evt) + if (evt.name && !evt.name.includes(':')) { + graph.emit(`${type}:${eventType}`, evt); // emit('node:click', evt) + graph.emit(eventType, evt); // emit('click', evt); + } else if (evt.name) { + graph.emit(evt.name, evt); // emit('text-shape:click', evt) + } if (eventType === 'dragstart') { this.dragging = true; @@ -222,6 +248,7 @@ export default class EventController extends AbstractEvent { } private resetStatus() { + this.mousedown = false; this.dragging = false; this.preItem = null; } diff --git a/packages/pc/src/graph/controller/layout.ts b/packages/pc/src/graph/controller/layout.ts index 29148b4fe7a..d18c96b45a9 100644 --- a/packages/pc/src/graph/controller/layout.ts +++ b/packages/pc/src/graph/controller/layout.ts @@ -205,6 +205,7 @@ export default class LayoutController extends AbstractLayout { */ public layout(success?: () => void): boolean { const { graph } = this; + if (!graph || graph.get('destroyed')) return; this.data = this.setDataFromGraph(); const { nodes, hiddenNodes } = this.data; @@ -544,6 +545,7 @@ export default class LayoutController extends AbstractLayout { // 更新布局参数 public updateLayoutCfg(cfg) { const { graph, layoutMethods } = this; + if (!graph || graph.get('destroyed')) return; // disableTriggerLayout 不触发重新布局,仅更新参数 const { disableTriggerLayout, ...otherCfg } = cfg; const layoutCfg = mix({}, this.layoutCfg, otherCfg); diff --git a/packages/pc/src/graph/tree-graph.ts b/packages/pc/src/graph/tree-graph.ts index 3bbd8f0af46..da12de2a0d7 100644 --- a/packages/pc/src/graph/tree-graph.ts +++ b/packages/pc/src/graph/tree-graph.ts @@ -345,6 +345,8 @@ export default class TreeGraph extends Graph implements ITreeGraph { parentData.children = []; } parentData.children.push(data); + const parentItem = self.findById(parent); + parentItem.refresh(); self.changeData(); } } @@ -358,7 +360,8 @@ export default class TreeGraph extends Graph implements ITreeGraph { const self = this; // 如果没有父节点或找不到该节点,是全量的更新,直接重置data - if (!parentId || !self.findById(parentId)) { + const parentItem = self.findById(parentId); + if (!parentId || !parentItem) { console.warn(`Update children failed! There is no node with id '${parentId}'`); return; } @@ -367,6 +370,8 @@ export default class TreeGraph extends Graph implements ITreeGraph { parentModel.children = data; + parentItem.refresh(); + self.changeData(); } @@ -398,8 +403,10 @@ export default class TreeGraph extends Graph implements ITreeGraph { parentModel.children.push(data); } else { const index = TreeGraph.indexOfChild(parentModel.children, data.id); - parentModel.children[index] = data; + if (index > -1) parentModel.children[index] = data; } + const parentItem = self.findById(parentId); + parentItem?.refresh(); self.changeData(); } @@ -411,18 +418,23 @@ export default class TreeGraph extends Graph implements ITreeGraph { const self = this; const node = self.findById(id); + let parent; if (!node) { - return; + parent = self.getNodes().find(node => { + const children = node.getModel().children || []; + return !!children.find(child => child.id === id); + }); + } else { + parent = node?.get('parent'); } - const parent = node.get('parent'); if (parent && !parent.destroyed) { - const parentNode = self.findDataById(parent.get('id')); + const parentId = parent.get('id'); + const parentNode = self.findDataById(parentId); const siblings = (parentNode && parentNode.children) || []; - const model: NodeConfig = node.getModel() as NodeConfig; - - const index = TreeGraph.indexOfChild(siblings, model.id); + const index = TreeGraph.indexOfChild(siblings, id); siblings.splice(index, 1); + parent.refresh(); } self.changeData(); } diff --git a/packages/pc/tests/unit/graph/controller/event-spec.ts b/packages/pc/tests/unit/graph/controller/event-spec.ts index bbc6b520453..34b5af8d959 100644 --- a/packages/pc/tests/unit/graph/controller/event-spec.ts +++ b/packages/pc/tests/unit/graph/controller/event-spec.ts @@ -239,8 +239,15 @@ describe('event', () => { count += 1; expect(e.type).toEqual('mousemove'); }); + const keyShape = node.get('keyShape') + const keyShapeName = keyShape.get('name'); + graph.on(`${keyShapeName}:mousemove`, (e) => { + count += 1; + expect(e.type).toEqual('mousemove'); + expect(e.name).toEqual(`${keyShapeName}:mousemove`); + }); - canvas.emit('mousemove', { type: 'mousemove', target: node.get('keyShape') }); + canvas.emit('mousemove', { type: 'mousemove', target: keyShape, name: `${keyShapeName}:mousemove` }); expect(count).toEqual(1); expect(triggered).toBe(false); diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 14e43658af2..727039bdc9b 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g6-plugin", - "version": "0.7.17", + "version": "0.8.0", "description": "G6 Plugin", "main": "lib/index.js", "module": "es/index.js", @@ -22,8 +22,8 @@ "@antv/g-base": "^0.5.1", "@antv/g-canvas": "^0.5.2", "@antv/g-svg": "^0.5.2", - "@antv/g6-core": "0.7.17", - "@antv/g6-element": "0.7.17", + "@antv/g6-core": "0.8.0", + "@antv/g6-element": "0.8.0", "@antv/matrix-util": "^3.1.0-beta.3", "@antv/scale": "^0.3.4", "@antv/util": "^2.0.9", diff --git a/packages/site/docs/api/shapeProperties.zh.md b/packages/site/docs/api/shapeProperties.zh.md index 53b1878fe10..a6969064132 100644 --- a/packages/site/docs/api/shapeProperties.zh.md +++ b/packages/site/docs/api/shapeProperties.zh.md @@ -38,7 +38,7 @@ G6 支持以下图形: _String_ **required** -图形名称标识,G6 3.3 版本以上必须配置。**且在统一自定义元素类型中,值必须唯一。**否则可能导致图形样式更新与恢复的错误。 +图形名称标识,G6 3.3 版本以上必须配置。**且在统一自定义元素类型中,值必须唯一。** 否则可能导致图形样式更新与恢复的错误。 ### fill diff --git a/packages/site/examples/item/customNode/demo/scrollNode.js b/packages/site/examples/item/customNode/demo/scrollNode.js index 1bb487fa1e1..532862e41c6 100644 --- a/packages/site/examples/item/customNode/demo/scrollNode.js +++ b/packages/site/examples/item/customNode/demo/scrollNode.js @@ -145,6 +145,7 @@ registerBehavior("dice-er-scroll", { if (!y && navigator.userAgent.indexOf('Firefox') > -1) y = (-e.wheelDelta * 125) / 3 if (nodes) { + const edgesToUpdate = new Set(); nodes.forEach((node) => { const model = node.getModel(); if (model.attrs.length < 2) { @@ -163,11 +164,15 @@ registerBehavior("dice-er-scroll", { if (startIndex > model.attrs.length - 1) { startIndex = model.attrs.length - 1; } - graph.update(node, { + graph.updateItem(node, { startIndex, startX, }); + node.getEdges().forEach(edge => edgesToUpdate.add(edge)) }); + // G6 update the related edges when graph.updateItem with a node according to the new properties + // here you need to update the related edges manualy since the new properties { startIndex, startX } for the nodes are custom, and cannot be recognized by G6 + edgesToUpdate.forEach(edge => edge.refresh()) } @@ -176,15 +181,11 @@ registerBehavior("dice-er-scroll", { const { graph } = this; - const { - y - } = e; const item = e.item; const shape = e.shape; if (!item) { return; } - const model = item.getModel(); if (shape.get("name") === "collapse") { graph.updateItem(item, { @@ -231,7 +232,7 @@ registerEdge("dice-er-edge", { let sourceY = 15; if (!sourceNode.collapsed && sourceIndex > sourceStartIndex - 1) { - sourceY = 30 + (sourceIndex - sourceStartIndex + 0.5) * 30; + sourceY = 30 + (sourceIndex - sourceStartIndex + 0.5) * itemHeight; sourceY = Math.min(sourceY, 80); } @@ -244,7 +245,7 @@ registerEdge("dice-er-edge", { let targetY = 15; if (!targetNode.collapsed && targetIndex > targetStartIndex - 1) { - targetY = (targetIndex - targetStartIndex + 0.5) * 30 + 30; + targetY = (targetIndex - targetStartIndex + 0.5) * itemHeight + 30; targetY = Math.min(targetY, 80); } diff --git a/packages/site/package.json b/packages/site/package.json index 8c1b5cffb91..16a21540a1e 100644 --- a/packages/site/package.json +++ b/packages/site/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@antv/g6-site", - "version": "4.7.17", + "version": "4.8.0", "description": "G6 sites deployed on gh-pages", "keywords": [ "antv",