-
Notifications
You must be signed in to change notification settings - Fork 19.8k
feat(graph): make graph node draggable in none and circular layout
#15428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
23ae97b
78b2475
1d962f6
ae38c73
ebae264
8144dcc
5f8f0c6
db01e51
2b1595d
7891815
472e72b
657f379
aeb66aa
45a1ebd
155364a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 SeriesData from '../../data/SeriesData'; | ||
| import * as zrUtil from 'zrender/src/core/util'; | ||
| import {getCurvenessForEdge} from '../helper/multipleGraphEdgeHelper'; | ||
|
|
@@ -51,7 +52,9 @@ const _symbolRadiansHalf: number[] = []; | |
| */ | ||
| export function circularLayout( | ||
| seriesModel: GraphSeriesModel, | ||
| basedOn: 'value' | 'symbolSize' | ||
| basedOn: 'value' | 'symbolSize', | ||
| draggingNode?: GraphNode, | ||
| pointer?: [number, number] | ||
| ) { | ||
| const coordSys = seriesModel.coordinateSystem; | ||
| if (coordSys && coordSys.type !== 'view') { | ||
|
|
@@ -77,6 +80,17 @@ export function circularLayout( | |
| return; | ||
| } | ||
|
|
||
| if (draggingNode) { | ||
| const [tempX, tempY] = coordSys.pointToData(pointer) as [number, number]; | ||
| const v = [tempX - cx, tempY - cy]; | ||
| vec2.normalize(v, v); | ||
| vec2.scale(v, v, r); | ||
| draggingNode.setLayout([cx + v[0], cy + v[1]], true); | ||
|
|
||
| const circularRotateLabel = seriesModel.get(['circular', 'rotateLabel']); | ||
| rotateNodeLabel(draggingNode, circularRotateLabel, cx, cy); | ||
| } | ||
|
|
||
| _layoutNodesBasedOn[basedOn](seriesModel, graph, nodeData, r, cx, cy, count); | ||
|
|
||
| graph.eachEdge(function (edge, index) { | ||
|
|
@@ -163,11 +177,58 @@ const _layoutNodesBasedOn: Record<'value' | 'symbolSize', LayoutNode> = { | |
| const radianHalf = halfRemainRadian + _symbolRadiansHalf[node.dataIndex]; | ||
|
|
||
| angle += radianHalf; | ||
| node.setLayout([ | ||
| // init circular layout for | ||
| // 1. layout undefined node | ||
| // 2. not fixed node | ||
| (!node.getLayout() || !node.getLayout().fixed) | ||
| && node.setLayout([ | ||
| r * Math.cos(angle) + cx, | ||
| r * Math.sin(angle) + cy | ||
| ]); | ||
| angle += radianHalf; | ||
| }); | ||
| } | ||
| }; | ||
|
|
||
| export function rotateNodeLabel( | ||
| node: GraphNode, | ||
| circularRotateLabel: boolean, | ||
| cx: number, | ||
| cy: number | ||
| ) { | ||
| 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<GraphNodeItemOption>(); | ||
| 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 { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic do not only related to 'circular layout'. All other layout use it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or maybe |
||
| symbolPath.setTextConfig({ | ||
| rotation: labelRotate *= Math.PI / 180 | ||
| }); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.