@mx-sose-front/mx-sose-graph 1.1.8 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/edgeWorker-b57ca007.js +2 -0
- package/dist/assets/edgeWorker-b57ca007.js.map +1 -0
- package/dist/index.d.ts +633 -30
- package/dist/index.esm.js +8728 -4734
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Common/Tree.vue +451 -0
- package/src/components/Common/index.ts +2 -0
- package/src/components/DiagramListTooltip/DiagramListTooltip.vue +1 -2
- package/src/components/Edge/Edge.vue +172 -169
- package/src/components/Gantt/Gantt.vue +1544 -0
- package/src/components/GanttContextMenu/GanttContextMenu.vue +304 -0
- package/src/components/InteractionLayer.vue +343 -147
- package/src/components/Matrix/Matrix.vue +828 -0
- package/src/components/Matrix/index.ts +168 -0
- package/src/components/Shape/ConceptualRole.vue +2 -34
- package/src/components/Table/Table.vue +970 -0
- package/src/constants/edgeShapeKeys.ts +8 -5
- package/src/constants/index.ts +259 -45
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useChartRowSelection.ts +456 -0
- package/src/hooks/useResize.ts +2 -2
- package/src/hooks/useVirtualScroll.ts +258 -0
- package/src/index.ts +1 -1
- package/src/render/shape-renderer.ts +62 -2
- package/src/statics/icons/childIcons//345/221/275/344/273/244@3x.png +0 -0
- package/src/statics/icons/childIcons//346/210/230/347/225/245/346/246/202/345/277/265/350/241/250@3x.png +0 -0
- package/src/statics/icons/childIcons//346/216/247/345/210/266@3x.png +0 -0
- package/src/statics/icons/createMenu/down.png +0 -0
- package/src/statics/icons/createMenu/remove.png +0 -0
- package/src/statics/icons/createMenu/up.png +0 -0
- package/src/store/graphStore.ts +217 -44
- package/src/types/index.ts +86 -4
- package/src/utils/batchAutoExpand.ts +9 -10
- package/src/utils/containers.ts +72 -17
- package/src/utils/contextMenuUtils.ts +7 -7
- package/src/utils/dateUtils.ts +160 -0
- package/src/utils/diagram.ts +10 -8
- package/src/utils/drag.ts +6 -5
- package/src/utils/edgeUtils.ts +344 -427
- package/src/utils/edgeWorker.ts +471 -0
- package/src/utils/hittest.ts +37 -38
- package/src/utils/index.ts +3 -0
- package/src/utils/keyboardUtils.ts +5 -5
- package/src/utils/packageOutline.ts +96 -0
- package/src/utils/rafThrottle.ts +162 -0
- package/src/utils/workerManager.ts +335 -0
- package/src/view/graph.vue +47 -33
- /package/src/statics/icons/childIcons//346/210/230/347/225/{245@3x.png" → 245/345/261/202@3x.png"} +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { TreeNode, ColumnHeaderCell } from '../../types'
|
|
2
|
+
|
|
3
|
+
/** 递归收集树中所有叶子节点(按遍历顺序) */
|
|
4
|
+
export function getLeafNodes(nodes: TreeNode[]): TreeNode[] {
|
|
5
|
+
const leaves: TreeNode[] = []
|
|
6
|
+
function walk(list: TreeNode[]) {
|
|
7
|
+
for (const node of list) {
|
|
8
|
+
if (node.isLeaf || !node.children?.length) {
|
|
9
|
+
leaves.push(node)
|
|
10
|
+
} else {
|
|
11
|
+
walk(node.children)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
walk(nodes)
|
|
16
|
+
return leaves
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 根据 rowId + colId 从 matrixNodes 中取单元格数据 */
|
|
20
|
+
export function getMatrixCell(
|
|
21
|
+
matrixNodes: ColumnHeaderCell[],
|
|
22
|
+
rowNodeId: string,
|
|
23
|
+
columnNodeId: string
|
|
24
|
+
): ColumnHeaderCell | undefined {
|
|
25
|
+
return matrixNodes.find(
|
|
26
|
+
(n) => n.rowNodeId === rowNodeId && n.columnNodeId === columnNodeId
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface FlattenRowItem {
|
|
31
|
+
node: TreeNode
|
|
32
|
+
depth: number
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 按展开状态扁平化行树:行方向可展开,每行一个节点 */
|
|
36
|
+
export function flattenRowTree(
|
|
37
|
+
nodes: TreeNode[],
|
|
38
|
+
expandedIds: Set<string>,
|
|
39
|
+
depth = 0
|
|
40
|
+
): FlattenRowItem[] {
|
|
41
|
+
const result: FlattenRowItem[] = []
|
|
42
|
+
for (const node of nodes) {
|
|
43
|
+
result.push({ node, depth })
|
|
44
|
+
const hasChildren = node.children && node.children.length > 0
|
|
45
|
+
if (hasChildren && expandedIds.has(node.id)) {
|
|
46
|
+
result.push(...flattenRowTree(node.children!, expandedIds, depth + 1))
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** 按展开状态得到可见的列叶子(最深一层),用于数据列 */
|
|
53
|
+
export function getVisibleColumnLeaves(
|
|
54
|
+
nodes: TreeNode[],
|
|
55
|
+
expandedIds: Set<string>
|
|
56
|
+
): TreeNode[] {
|
|
57
|
+
const result: TreeNode[] = []
|
|
58
|
+
function walk(list: TreeNode[]) {
|
|
59
|
+
for (const node of list) {
|
|
60
|
+
const hasChildren = node.children && node.children.length > 0
|
|
61
|
+
if (!hasChildren || !expandedIds.has(node.id)) {
|
|
62
|
+
result.push(node)
|
|
63
|
+
} else {
|
|
64
|
+
walk(node.children!)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
walk(nodes)
|
|
69
|
+
return result
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** 递归收集树中所有节点 id(用于判断某 id 是否属于该树,折叠时子节点不应当「补列」) */
|
|
73
|
+
export function getAllColumnNodeIds(nodes: TreeNode[]): Set<string> {
|
|
74
|
+
const ids = new Set<string>()
|
|
75
|
+
function walk(list: TreeNode[]) {
|
|
76
|
+
for (const node of list) {
|
|
77
|
+
ids.add(node.id)
|
|
78
|
+
if (node.children?.length) walk(node.children)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
walk(nodes)
|
|
82
|
+
return ids
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 与行对齐的列顺序:先根(战略层(1))算一列,再子节点(能力…)。
|
|
87
|
+
* 单根且已展开且有子节点时,返回 [根, ...叶子];否则仅返回叶子。
|
|
88
|
+
*/
|
|
89
|
+
export function getVisibleColumnNodesWithRoot(
|
|
90
|
+
nodes: TreeNode[],
|
|
91
|
+
expandedIds: Set<string>
|
|
92
|
+
): TreeNode[] {
|
|
93
|
+
const leaves = getVisibleColumnLeaves(nodes, expandedIds)
|
|
94
|
+
if (nodes.length !== 1) return leaves
|
|
95
|
+
const root = nodes[0]
|
|
96
|
+
const hasChildren = root.children && root.children.length > 0
|
|
97
|
+
if (!hasChildren || !expandedIds.has(root.id)) return leaves
|
|
98
|
+
return [root, ...leaves]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface ColHeaderCell {
|
|
102
|
+
node: TreeNode
|
|
103
|
+
colspan: number
|
|
104
|
+
rowspan: number
|
|
105
|
+
isEmpty?: boolean
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** 计算列头多行:列方向竖着展开,每层表头一行;叶子节点用 rowspan 跨到最底行 */
|
|
109
|
+
export function getColumnHeaderRows(
|
|
110
|
+
nodes: TreeNode[],
|
|
111
|
+
expandedIds: Set<string>
|
|
112
|
+
): ColHeaderCell[][] {
|
|
113
|
+
const rows: ColHeaderCell[][] = []
|
|
114
|
+
function countLeaves(n: TreeNode): number {
|
|
115
|
+
if (!n.children?.length) return 1
|
|
116
|
+
if (!expandedIds.has(n.id)) return 1
|
|
117
|
+
return n.children.reduce((s, c) => s + countLeaves(c), 0)
|
|
118
|
+
}
|
|
119
|
+
function calcMaxDepth(list: TreeNode[], depth: number): number {
|
|
120
|
+
let max = depth
|
|
121
|
+
for (const n of list) {
|
|
122
|
+
if (n.children?.length && expandedIds.has(n.id)) {
|
|
123
|
+
max = Math.max(max, calcMaxDepth(n.children, depth + 1))
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return max
|
|
127
|
+
}
|
|
128
|
+
const totalRows = calcMaxDepth(nodes, 1)
|
|
129
|
+
|
|
130
|
+
function buildRow(list: TreeNode[], currentRow: number): void {
|
|
131
|
+
const cells: ColHeaderCell[] = list.map((node) => {
|
|
132
|
+
const hasExpandedChildren = !!(node.children?.length && expandedIds.has(node.id))
|
|
133
|
+
return {
|
|
134
|
+
node,
|
|
135
|
+
colspan: countLeaves(node),
|
|
136
|
+
rowspan: hasExpandedChildren ? 1 : Math.max(1, totalRows - currentRow + 1),
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
rows.push(cells)
|
|
140
|
+
const next: TreeNode[] = []
|
|
141
|
+
for (const node of list) {
|
|
142
|
+
if (node.children?.length && expandedIds.has(node.id)) next.push(...node.children)
|
|
143
|
+
}
|
|
144
|
+
if (next.length) buildRow(next, currentRow + 1)
|
|
145
|
+
}
|
|
146
|
+
buildRow(nodes, 1)
|
|
147
|
+
return rows
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** 判断行节点是否用「文件夹+方框」样式(Strategy、123 等),否则用「橙圆 C+三角」 */
|
|
151
|
+
export function isFolderLikeNode(node: TreeNode): boolean {
|
|
152
|
+
return node.nodeType === 'folder' || node.nodeType === 'group'
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** 递归收集树中所有有子节点的节点 id(用于默认全部展开) */
|
|
156
|
+
export function getAllExpandableIds(nodes: TreeNode[]): Set<string> {
|
|
157
|
+
const ids = new Set<string>()
|
|
158
|
+
function walk(list: TreeNode[]) {
|
|
159
|
+
for (const node of list) {
|
|
160
|
+
if (node.children?.length) {
|
|
161
|
+
ids.add(node.id)
|
|
162
|
+
walk(node.children)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
walk(nodes)
|
|
167
|
+
return ids
|
|
168
|
+
}
|
|
@@ -4,11 +4,6 @@
|
|
|
4
4
|
:style="shapeStyle"
|
|
5
5
|
@click="onClick"
|
|
6
6
|
@dblclick="onDoubleClick"
|
|
7
|
-
@mousedown="preventScaleAndDrag"
|
|
8
|
-
@touchstart="preventScaleAndDrag"
|
|
9
|
-
@touchmove="preventTouchScale"
|
|
10
|
-
@touchend="preventTouchScale"
|
|
11
|
-
@wheel="onWheel"
|
|
12
7
|
@contextmenu.prevent
|
|
13
8
|
>
|
|
14
9
|
<svg :width="vbW" :height="vbH" :viewBox="`0 0 ${vbW} ${vbH}`" class="diagram-svg">
|
|
@@ -194,37 +189,10 @@ const shapeStyle = computed<CSSProperties>(() => {
|
|
|
194
189
|
})
|
|
195
190
|
|
|
196
191
|
const onClick = (event: MouseEvent) => {
|
|
197
|
-
event.stopPropagation();
|
|
198
|
-
event.preventDefault();
|
|
199
192
|
emit('shape-click', props.shape, event)
|
|
200
193
|
}
|
|
201
194
|
|
|
202
|
-
const onDoubleClick = (
|
|
203
|
-
event.stopPropagation();
|
|
204
|
-
event.preventDefault();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// 阻止拖拽和缩放相关的事件
|
|
208
|
-
const preventScaleAndDrag = (event: Event) => {
|
|
209
|
-
event.stopPropagation();
|
|
210
|
-
event.preventDefault();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// 阻止触摸缩放事件
|
|
214
|
-
const preventTouchScale = (event: TouchEvent) => {
|
|
215
|
-
// 阻止多点触控缩放
|
|
216
|
-
if (event.touches.length > 1) {
|
|
217
|
-
event.stopPropagation();
|
|
218
|
-
event.preventDefault();
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// 阻止鼠标滚轮缩放 - 完全禁用缩放功能
|
|
223
|
-
const onWheel = (event: WheelEvent) => {
|
|
224
|
-
// 完全阻止所有滚轮事件,包括缩放
|
|
225
|
-
event.stopPropagation();
|
|
226
|
-
event.preventDefault();
|
|
227
|
-
}
|
|
195
|
+
const onDoubleClick = (_event: MouseEvent) => {}
|
|
228
196
|
|
|
229
197
|
const onImageClick = (event: MouseEvent) => {
|
|
230
198
|
event.stopPropagation()
|
|
@@ -263,4 +231,4 @@ const onNameClick = (event: MouseEvent) => {
|
|
|
263
231
|
transform: none !important;
|
|
264
232
|
-webkit-transform: none !important;
|
|
265
233
|
}
|
|
266
|
-
</style>
|
|
234
|
+
</style>
|