From 23ae97b9fce109d71ec5c8d16912ba81ea6e9ffb Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Thu, 29 Jul 2021 14:41:38 +0800 Subject: [PATCH 01/14] feat(graph): simple layout graph support dragging --- src/chart/graph/GraphView.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts index 1c8d10f921..fd5640b731 100644 --- a/src/chart/graph/GraphView.ts +++ b/src/chart/graph/GraphView.ts @@ -37,6 +37,8 @@ import List from '../../data/List'; import Line from '../helper/Line'; import { getECData } from '../../util/innerStore'; +import { simpleLayoutEdge } from './simpleLayoutHelper'; + function isViewCoordSys(coordSys: CoordinateSystem): coordSys is View { return coordSys.type === 'view'; } @@ -139,13 +141,20 @@ class GraphView extends ChartView { // Write position back to layout data.setItemLayout(idx, [el.x, el.y]); } + // handle simple layout dragging + if (!seriesModel.get('layout') || seriesModel.get('layout') === 'none') { + data.setItemLayout(idx, [el.x, el.y]); + // update edge + simpleLayoutEdge(seriesModel.getGraph(), seriesModel); + this.updateLayout(seriesModel); + } }).on('dragend', () => { if (forceLayout) { forceLayout.setUnfixed(idx); } }); } - el.setDraggable(draggable && !!forceLayout); + el.setDraggable(draggable); const focus = itemModel.get(['emphasis', 'focus']); From 78b247521da4db3bfa4d42da0d7812e8a1d8fad1 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Thu, 29 Jul 2021 14:46:41 +0800 Subject: [PATCH 02/14] test(graph): add simple graph draggable test case --- test/graph-simple.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/graph-simple.html b/test/graph-simple.html index 25899700ea..5e08e1a0c1 100644 --- a/test/graph-simple.html +++ b/test/graph-simple.html @@ -75,7 +75,8 @@ name: '节点1', x: 300, y: 300, - value: 'set_style_on_item' + value: 'set_style_on_item', + draggable: true, }, { name: '节点2', x: 800, @@ -162,7 +163,7 @@ title: [ '[focusNodeAdjacency: **true**]', 'hover node3, edge label should be displayed.', - '节点1 should display value in tooltip.', + '节点1 should display value in tooltip, and should be draggable', 'series.lineStyle: 5', 'hover set_style_on_item, lineStyle: {opacity 0.1, color: "blue", width: 20}, label: {color: "red", fontSize: 40}.', 'focusNodeAdjacency triggered and returned, opacity change MUST NOT be kept' @@ -175,7 +176,7 @@ title: [ '[focusNodeAdjacency: **false**]', 'hover node3, edge label should be displayed.', - '节点1 should display value in tooltip.', + '节点1 should display value in tooltip, and should be draggable', 'hover set_style_on_item, lineStyle: {opacity 0.1, color: "blue", width: 20}, label: {color: "red", fontSize: 40}.', 'focusNodeAdjacency triggered and returned, opacity change MUST NOT be kept' ], From 1d962f663505cde896f1ec44eb591b87b13fef93 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Sun, 1 Aug 2021 00:25:19 +0800 Subject: [PATCH 03/14] feat(graph): update circular layout helper function --- src/chart/graph/circularLayoutHelper.ts | 69 +++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts index a81538c377..318e08a1e5 100644 --- a/src/chart/graph/circularLayoutHelper.ts +++ b/src/chart/graph/circularLayoutHelper.ts @@ -20,8 +20,9 @@ import * as vec2 from 'zrender/src/core/vector'; import {getSymbolSize, getNodeGlobalScale} from './graphHelper'; -import GraphSeriesModel, { GraphEdgeItemOption } from './GraphSeries'; -import Graph from '../../data/Graph'; +import GraphSeriesModel, { GraphEdgeItemOption, GraphNodeItemOption } from './GraphSeries'; +import Graph, { GraphNode } from '../../data/Graph'; +import Symbol from '../helper/Symbol'; import List from '../../data/List'; import * as zrUtil from 'zrender/src/core/util'; import {getCurvenessForEdge} from '../helper/multipleGraphEdgeHelper'; @@ -51,7 +52,8 @@ const _symbolRadiansHalf: number[] = []; */ export function circularLayout( seriesModel: GraphSeriesModel, - basedOn: 'value' | 'symbolSize' + basedOn: 'value' | 'symbolSize', + draggingNode?: GraphNode ) { const coordSys = seriesModel.coordinateSystem; if (coordSys && coordSys.type !== 'view') { @@ -77,6 +79,25 @@ export function circularLayout( return; } + if (draggingNode) { + const [tempX, tempY] = draggingNode.getLayout(); + const tan = (tempY - cy) / (tempX - cx); + const radian = -Math.atan(tan); + + tempX > cx + ? draggingNode.setLayout([ + r * Math.cos(radian) + cx, + r * -Math.sin(radian) + cy + ]) : draggingNode.setLayout([ + r * -Math.cos(radian) + cx, + r * Math.sin(radian) + cy + ]); + + const circularRotateLabel = seriesModel.get('layout') === 'circular' + && seriesModel.get(['circular', 'rotateLabel']); + rotateNodeLabel(draggingNode, circularRotateLabel, cx, cy); + } + _layoutNodesBasedOn[basedOn](seriesModel, graph, nodeData, r, cx, cy, count); graph.eachEdge(function (edge, index) { @@ -163,7 +184,8 @@ const _layoutNodesBasedOn: Record<'value' | 'symbolSize', LayoutNode> = { const radianHalf = halfRemainRadian + _symbolRadiansHalf[node.dataIndex]; angle += radianHalf; - node.setLayout([ + // auto circular layout for not dragged node + !node.getFixed() && node.setLayout([ r * Math.cos(angle) + cx, r * Math.sin(angle) + cy ]); @@ -171,3 +193,42 @@ const _layoutNodesBasedOn: Record<'value' | 'symbolSize', LayoutNode> = { }); } }; + +export function rotateNodeLabel( + node: GraphNode, + circularRotateLabel: boolean, + cx: number, + cy: number +) { + const nodeModel = node.getModel(); + const el = node.getGraphicEl() as Symbol; + let labelRotate = nodeModel.get(['label', 'rotate']) || 0; + const symbolPath = el.getSymbolPath(); + if (circularRotateLabel) { + const pos = node.getLayout(); + let rad = Math.atan2(pos[1] - cy, pos[0] - cx); + if (rad < 0) { + rad = Math.PI * 2 + rad; + } + const isLeft = pos[0] < cx; + if (isLeft) { + rad = rad - Math.PI; + } + const textPosition = isLeft ? 'left' as const : 'right' as const; + + symbolPath.setTextConfig({ + rotation: -rad, + position: textPosition, + origin: 'center' + }); + const emphasisState = symbolPath.ensureState('emphasis'); + zrUtil.extend(emphasisState.textConfig || (emphasisState.textConfig = {}), { + position: textPosition + }); + } + else { + symbolPath.setTextConfig({ + rotation: labelRotate *= Math.PI / 180 + }); + } +} From ae38c73f1bab18bd72c259756fff3e3644ffe731 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Sun, 1 Aug 2021 00:26:59 +0800 Subject: [PATCH 04/14] feat(graph): support draggable for all graph layout ('none' | 'circular' | 'force') --- src/chart/graph/GraphView.ts | 74 ++++++++++++++---------------------- src/data/Graph.ts | 11 ++++++ 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts index fd5640b731..ec3af054a2 100644 --- a/src/chart/graph/GraphView.ts +++ b/src/chart/graph/GraphView.ts @@ -38,6 +38,7 @@ import Line from '../helper/Line'; import { getECData } from '../../util/innerStore'; import { simpleLayoutEdge } from './simpleLayoutHelper'; +import { circularLayout, rotateNodeLabel } from './circularLayoutHelper'; function isViewCoordSys(coordSys: CoordinateSystem): coordSys is View { return coordSys.type === 'view'; @@ -124,6 +125,8 @@ class GraphView extends ChartView { this._startForceLayoutIteration(forceLayout, layoutAnimation); } + const layout = seriesModel.get('layout'); + data.graph.eachNode((node) => { const idx = node.dataIndex; const el = node.getGraphicEl() as Symbol; @@ -133,20 +136,30 @@ class GraphView extends ChartView { const draggable = itemModel.get('draggable'); if (draggable) { el.on('drag', () => { - if (forceLayout) { - forceLayout.warmUp(); - !this._layouting - && this._startForceLayoutIteration(forceLayout, layoutAnimation); - forceLayout.setFixed(idx); - // Write position back to layout - data.setItemLayout(idx, [el.x, el.y]); - } - // handle simple layout dragging - if (!seriesModel.get('layout') || seriesModel.get('layout') === 'none') { - data.setItemLayout(idx, [el.x, el.y]); - // update edge - simpleLayoutEdge(seriesModel.getGraph(), seriesModel); - this.updateLayout(seriesModel); + switch (layout) { + case 'force': + forceLayout.warmUp(); + !this._layouting + && this._startForceLayoutIteration(forceLayout, layoutAnimation); + forceLayout.setFixed(idx); + // Write position back to layout + data.setItemLayout(idx, [el.x, el.y]); + break; + case 'circular': + // mark node fixed + node.setFixed(true); + data.setItemLayout(idx, [el.x, el.y]); + // recalculate circular layout + circularLayout(seriesModel, 'symbolSize', node); + this.updateLayout(seriesModel); + break; + case 'none': + default: + data.setItemLayout(idx, [el.x, el.y]); + // update edge + simpleLayoutEdge(seriesModel.getGraph(), seriesModel); + this.updateLayout(seriesModel); + break; } }).on('dragend', () => { if (forceLayout) { @@ -179,37 +192,8 @@ class GraphView extends ChartView { && seriesModel.get(['circular', 'rotateLabel']); const cx = data.getLayout('cx'); const cy = data.getLayout('cy'); - data.eachItemGraphicEl(function (el: Symbol, idx) { - const itemModel = data.getItemModel(idx); - let labelRotate = itemModel.get(['label', 'rotate']) || 0; - const symbolPath = el.getSymbolPath(); - if (circularRotateLabel) { - const pos = data.getItemLayout(idx); - let rad = Math.atan2(pos[1] - cy, pos[0] - cx); - if (rad < 0) { - rad = Math.PI * 2 + rad; - } - const isLeft = pos[0] < cx; - if (isLeft) { - rad = rad - Math.PI; - } - const textPosition = isLeft ? 'left' as const : 'right' as const; - - symbolPath.setTextConfig({ - rotation: -rad, - position: textPosition, - origin: 'center' - }); - const emphasisState = symbolPath.ensureState('emphasis'); - zrUtil.extend(emphasisState.textConfig || (emphasisState.textConfig = {}), { - position: textPosition - }); - } - else { - symbolPath.setTextConfig({ - rotation: labelRotate *= Math.PI / 180 - }); - } + data.graph.eachNode((node) => { + rotateNodeLabel(node, circularRotateLabel, cx, cy); }); this._firstRender = false; diff --git a/src/data/Graph.ts b/src/data/Graph.ts index 75ec38f654..ee76a77e57 100644 --- a/src/data/Graph.ts +++ b/src/data/Graph.ts @@ -333,6 +333,9 @@ class GraphNode { // Used in traverse of Graph __visited: boolean; + // NOTE: only use in circular layout + private _fixed: boolean = false; + constructor(id?: string, dataIndex?: number) { this.id = id == null ? '' : id; this.dataIndex = dataIndex == null ? -1 : dataIndex; @@ -387,6 +390,14 @@ class GraphNode { } return dataIndices; } + + setFixed(fixed: boolean) { + this._fixed = fixed; + } + + getFixed() { + return this._fixed; + } } From ebae2649401ad7ef5dc5fcea398a929f725d3d28 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Sun, 1 Aug 2021 00:28:40 +0800 Subject: [PATCH 05/14] test(graph): add graph draggable test case --- test/graph-draggable.html | 441 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) create mode 100644 test/graph-draggable.html diff --git a/test/graph-draggable.html b/test/graph-draggable.html new file mode 100644 index 0000000000..d681e98e19 --- /dev/null +++ b/test/graph-draggable.html @@ -0,0 +1,441 @@ + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + From 8144dcc0b2ba3dd5467a13ea28d6d25fe40cbaa2 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Sun, 1 Aug 2021 00:29:36 +0800 Subject: [PATCH 06/14] Revert "test(graph): add simple graph draggable test case" This reverts commit 78b247521da4db3bfa4d42da0d7812e8a1d8fad1. --- test/graph-simple.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/graph-simple.html b/test/graph-simple.html index 5e08e1a0c1..25899700ea 100644 --- a/test/graph-simple.html +++ b/test/graph-simple.html @@ -75,8 +75,7 @@ name: '节点1', x: 300, y: 300, - value: 'set_style_on_item', - draggable: true, + value: 'set_style_on_item' }, { name: '节点2', x: 800, @@ -163,7 +162,7 @@ title: [ '[focusNodeAdjacency: **true**]', 'hover node3, edge label should be displayed.', - '节点1 should display value in tooltip, and should be draggable', + '节点1 should display value in tooltip.', 'series.lineStyle: 5', 'hover set_style_on_item, lineStyle: {opacity 0.1, color: "blue", width: 20}, label: {color: "red", fontSize: 40}.', 'focusNodeAdjacency triggered and returned, opacity change MUST NOT be kept' @@ -176,7 +175,7 @@ title: [ '[focusNodeAdjacency: **false**]', 'hover node3, edge label should be displayed.', - '节点1 should display value in tooltip, and should be draggable', + '节点1 should display value in tooltip.', 'hover set_style_on_item, lineStyle: {opacity 0.1, color: "blue", width: 20}, label: {color: "red", fontSize: 40}.', 'focusNodeAdjacency triggered and returned, opacity change MUST NOT be kept' ], From 5f8f0c6d4d450b2b3578e7e18c6207fad818c467 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Fri, 6 Aug 2021 01:15:30 +0800 Subject: [PATCH 07/14] fix(graph): node el check for circular layout --- src/chart/graph/circularLayoutHelper.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts index 318e08a1e5..acc0697753 100644 --- a/src/chart/graph/circularLayoutHelper.ts +++ b/src/chart/graph/circularLayoutHelper.ts @@ -200,8 +200,12 @@ export function rotateNodeLabel( cx: number, cy: number ) { - const nodeModel = node.getModel(); const el = node.getGraphicEl() as Symbol; + // need to check if el exists. '-' value may not create node element. + if (!el) { + return; + } + const nodeModel = node.getModel(); let labelRotate = nodeModel.get(['label', 'rotate']) || 0; const symbolPath = el.getSymbolPath(); if (circularRotateLabel) { From db01e51282bf0402f33c25a924b0db3d33abe0b0 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Fri, 6 Aug 2021 15:38:18 +0800 Subject: [PATCH 08/14] fix(graph): remove GraphNode `_fixed` field --- src/data/Graph.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/data/Graph.ts b/src/data/Graph.ts index ee76a77e57..75ec38f654 100644 --- a/src/data/Graph.ts +++ b/src/data/Graph.ts @@ -333,9 +333,6 @@ class GraphNode { // Used in traverse of Graph __visited: boolean; - // NOTE: only use in circular layout - private _fixed: boolean = false; - constructor(id?: string, dataIndex?: number) { this.id = id == null ? '' : id; this.dataIndex = dataIndex == null ? -1 : dataIndex; @@ -390,14 +387,6 @@ class GraphNode { } return dataIndices; } - - setFixed(fixed: boolean) { - this._fixed = fixed; - } - - getFixed() { - return this._fixed; - } } From 2b1595dba31c7da7c5346418356e6fed1d7d9422 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Fri, 6 Aug 2021 15:42:33 +0800 Subject: [PATCH 09/14] fix(graph): use zrender/vector calculate node layout --- src/chart/graph/GraphView.ts | 2 +- src/chart/graph/circularLayoutHelper.ts | 22 +++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts index ec3af054a2..cf8ff11312 100644 --- a/src/chart/graph/GraphView.ts +++ b/src/chart/graph/GraphView.ts @@ -147,7 +147,7 @@ class GraphView extends ChartView { break; case 'circular': // mark node fixed - node.setFixed(true); + node.getModel().mergeOption({fixed: true}); data.setItemLayout(idx, [el.x, el.y]); // recalculate circular layout circularLayout(seriesModel, 'symbolSize', node); diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts index acc0697753..5648630876 100644 --- a/src/chart/graph/circularLayoutHelper.ts +++ b/src/chart/graph/circularLayoutHelper.ts @@ -81,17 +81,10 @@ export function circularLayout( if (draggingNode) { const [tempX, tempY] = draggingNode.getLayout(); - const tan = (tempY - cy) / (tempX - cx); - const radian = -Math.atan(tan); - - tempX > cx - ? draggingNode.setLayout([ - r * Math.cos(radian) + cx, - r * -Math.sin(radian) + cy - ]) : draggingNode.setLayout([ - r * -Math.cos(radian) + cx, - r * Math.sin(radian) + cy - ]); + const v = [tempX - cx, tempY - cy]; + vec2.normalize(v, v); + vec2.scale(v, v, r); + draggingNode.setLayout([cx + v[0], cy + v[1]]); const circularRotateLabel = seriesModel.get('layout') === 'circular' && seriesModel.get(['circular', 'rotateLabel']); @@ -184,8 +177,11 @@ const _layoutNodesBasedOn: Record<'value' | 'symbolSize', LayoutNode> = { const radianHalf = halfRemainRadian + _symbolRadiansHalf[node.dataIndex]; angle += radianHalf; - // auto circular layout for not dragged node - !node.getFixed() && node.setLayout([ + // init circular layout for + // 1. layout undefined node + // 2. not fixed node + (!node.getLayout() || !node.getModel().get('fixed')) + && node.setLayout([ r * Math.cos(angle) + cx, r * Math.sin(angle) + cy ]); From 472e72b6fde58a2ff9f14f698e3c197cb03ec917 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Tue, 28 Sep 2021 23:13:53 +0800 Subject: [PATCH 10/14] fix: not trigger roam on el's child --- src/component/helper/RoamController.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts index edff61052d..cda4d1e9b4 100644 --- a/src/component/helper/RoamController.ts +++ b/src/component/helper/RoamController.ts @@ -179,6 +179,14 @@ class RoamController extends Eventful<{ return; } + let el = e.target; + while (el) { + if (el.draggable) { + return; + } + el = el.__hostTarget ? el.__hostTarget : el.parent; + } + const x = e.offsetX; const y = e.offsetY; From 657f379177b9348fa5a74f92f2f54bc8186500da Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Wed, 29 Sep 2021 13:20:31 +0800 Subject: [PATCH 11/14] fix: fix code --- src/chart/graph/circularLayoutHelper.ts | 3 +-- src/component/helper/RoamController.ts | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts index 86228467e1..171805cec3 100644 --- a/src/chart/graph/circularLayoutHelper.ts +++ b/src/chart/graph/circularLayoutHelper.ts @@ -86,8 +86,7 @@ export function circularLayout( vec2.scale(v, v, r); draggingNode.setLayout([cx + v[0], cy + v[1]]); - const circularRotateLabel = seriesModel.get('layout') === 'circular' - && seriesModel.get(['circular', 'rotateLabel']); + const circularRotateLabel = seriesModel.get(['circular', 'rotateLabel']); rotateNodeLabel(draggingNode, circularRotateLabel, cx, cy); } diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts index cda4d1e9b4..247ac1b693 100644 --- a/src/component/helper/RoamController.ts +++ b/src/component/helper/RoamController.ts @@ -184,7 +184,8 @@ class RoamController extends Eventful<{ if (el.draggable) { return; } - el = el.__hostTarget ? el.__hostTarget : el.parent; + // check if host is draggable + el = el.__hostTarget || el.parent; } const x = e.offsetX; From aeb66aa7c35fcdc9c6650f6c75c42fe62e806880 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Wed, 29 Sep 2021 13:26:37 +0800 Subject: [PATCH 12/14] fix: remove useless code --- src/component/helper/RoamController.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts index 247ac1b693..874865ebee 100644 --- a/src/component/helper/RoamController.ts +++ b/src/component/helper/RoamController.ts @@ -173,9 +173,7 @@ class RoamController extends Eventful<{ } private _mousedownHandler(e: ZRElementEvent) { - if (eventTool.isMiddleOrRightButtonOnMouseUpDown(e) - || (e.target && e.target.draggable) - ) { + if (eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) { return; } From 45a1ebd5c007a586bacd8d79b46928aff3aec934 Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Wed, 29 Sep 2021 14:24:15 +0800 Subject: [PATCH 13/14] fix: store fixed state in layout object --- src/chart/graph/GraphView.ts | 4 ++-- src/chart/graph/circularLayoutHelper.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts index ff463f6efa..2e3da638a5 100644 --- a/src/chart/graph/GraphView.ts +++ b/src/chart/graph/GraphView.ts @@ -146,9 +146,9 @@ class GraphView extends ChartView { data.setItemLayout(idx, [el.x, el.y]); break; case 'circular': - // mark node fixed - node.getModel().mergeOption({fixed: true}); data.setItemLayout(idx, [el.x, el.y]); + // mark node fixed + node.setLayout({ fixed: true }, true); // recalculate circular layout circularLayout(seriesModel, 'symbolSize', node); this.updateLayout(seriesModel); diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts index 171805cec3..453414fdd7 100644 --- a/src/chart/graph/circularLayoutHelper.ts +++ b/src/chart/graph/circularLayoutHelper.ts @@ -84,7 +84,7 @@ export function circularLayout( const v = [tempX - cx, tempY - cy]; vec2.normalize(v, v); vec2.scale(v, v, r); - draggingNode.setLayout([cx + v[0], cy + v[1]]); + draggingNode.setLayout([cx + v[0], cy + v[1]], true); const circularRotateLabel = seriesModel.get(['circular', 'rotateLabel']); rotateNodeLabel(draggingNode, circularRotateLabel, cx, cy); @@ -179,7 +179,7 @@ const _layoutNodesBasedOn: Record<'value' | 'symbolSize', LayoutNode> = { // init circular layout for // 1. layout undefined node // 2. not fixed node - (!node.getLayout() || !node.getModel().get('fixed')) + (!node.getLayout() || !node.getLayout().fixed) && node.setLayout([ r * Math.cos(angle) + cx, r * Math.sin(angle) + cy From 155364a6b5084e0f64e3d6fc05ab6ef02b48a58c Mon Sep 17 00:00:00 2001 From: kongmoumou Date: Wed, 29 Sep 2021 14:30:43 +0800 Subject: [PATCH 14/14] fix: use mouse position calculate circular layout --- src/chart/graph/GraphView.ts | 4 ++-- src/chart/graph/circularLayoutHelper.ts | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts index 2e3da638a5..20f4448eb3 100644 --- a/src/chart/graph/GraphView.ts +++ b/src/chart/graph/GraphView.ts @@ -135,7 +135,7 @@ class GraphView extends ChartView { el.off('drag').off('dragend'); const draggable = itemModel.get('draggable'); if (draggable) { - el.on('drag', () => { + el.on('drag', (e) => { switch (layout) { case 'force': forceLayout.warmUp(); @@ -150,7 +150,7 @@ class GraphView extends ChartView { // mark node fixed node.setLayout({ fixed: true }, true); // recalculate circular layout - circularLayout(seriesModel, 'symbolSize', node); + circularLayout(seriesModel, 'symbolSize', node, [e.offsetX, e.offsetY]); this.updateLayout(seriesModel); break; case 'none': diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts index 453414fdd7..af01fb0f8c 100644 --- a/src/chart/graph/circularLayoutHelper.ts +++ b/src/chart/graph/circularLayoutHelper.ts @@ -53,7 +53,8 @@ const _symbolRadiansHalf: number[] = []; export function circularLayout( seriesModel: GraphSeriesModel, basedOn: 'value' | 'symbolSize', - draggingNode?: GraphNode + draggingNode?: GraphNode, + pointer?: [number, number] ) { const coordSys = seriesModel.coordinateSystem; if (coordSys && coordSys.type !== 'view') { @@ -80,7 +81,7 @@ export function circularLayout( } if (draggingNode) { - const [tempX, tempY] = draggingNode.getLayout(); + const [tempX, tempY] = coordSys.pointToData(pointer) as [number, number]; const v = [tempX - cx, tempY - cy]; vec2.normalize(v, v); vec2.scale(v, v, r);