@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.
Files changed (52) hide show
  1. package/dist/assets/edgeWorker-b57ca007.js +2 -0
  2. package/dist/assets/edgeWorker-b57ca007.js.map +1 -0
  3. package/dist/index.d.ts +633 -30
  4. package/dist/index.esm.js +8728 -4734
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/index.umd.js +1 -1
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/style.css +1 -1
  9. package/package.json +1 -1
  10. package/src/components/Common/Tree.vue +451 -0
  11. package/src/components/Common/index.ts +2 -0
  12. package/src/components/DiagramListTooltip/DiagramListTooltip.vue +1 -2
  13. package/src/components/Edge/Edge.vue +172 -169
  14. package/src/components/Gantt/Gantt.vue +1544 -0
  15. package/src/components/GanttContextMenu/GanttContextMenu.vue +304 -0
  16. package/src/components/InteractionLayer.vue +343 -147
  17. package/src/components/Matrix/Matrix.vue +828 -0
  18. package/src/components/Matrix/index.ts +168 -0
  19. package/src/components/Shape/ConceptualRole.vue +2 -34
  20. package/src/components/Table/Table.vue +970 -0
  21. package/src/constants/edgeShapeKeys.ts +8 -5
  22. package/src/constants/index.ts +259 -45
  23. package/src/hooks/index.ts +2 -0
  24. package/src/hooks/useChartRowSelection.ts +456 -0
  25. package/src/hooks/useResize.ts +2 -2
  26. package/src/hooks/useVirtualScroll.ts +258 -0
  27. package/src/index.ts +1 -1
  28. package/src/render/shape-renderer.ts +62 -2
  29. package/src/statics/icons/childIcons//345/221/275/344/273/244@3x.png +0 -0
  30. package/src/statics/icons/childIcons//346/210/230/347/225/245/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  31. package/src/statics/icons/childIcons//346/216/247/345/210/266@3x.png +0 -0
  32. package/src/statics/icons/createMenu/down.png +0 -0
  33. package/src/statics/icons/createMenu/remove.png +0 -0
  34. package/src/statics/icons/createMenu/up.png +0 -0
  35. package/src/store/graphStore.ts +217 -44
  36. package/src/types/index.ts +86 -4
  37. package/src/utils/batchAutoExpand.ts +9 -10
  38. package/src/utils/containers.ts +72 -17
  39. package/src/utils/contextMenuUtils.ts +7 -7
  40. package/src/utils/dateUtils.ts +160 -0
  41. package/src/utils/diagram.ts +10 -8
  42. package/src/utils/drag.ts +6 -5
  43. package/src/utils/edgeUtils.ts +344 -427
  44. package/src/utils/edgeWorker.ts +471 -0
  45. package/src/utils/hittest.ts +37 -38
  46. package/src/utils/index.ts +3 -0
  47. package/src/utils/keyboardUtils.ts +5 -5
  48. package/src/utils/packageOutline.ts +96 -0
  49. package/src/utils/rafThrottle.ts +162 -0
  50. package/src/utils/workerManager.ts +335 -0
  51. package/src/view/graph.vue +47 -33
  52. /package/src/statics/icons/childIcons//346/210/230/347/225/{245@3x.png" → 245/345/261/202@3x.png"} +0 -0
@@ -0,0 +1,304 @@
1
+ <template>
2
+ <teleport to="body">
3
+ <div
4
+ v-if="visible"
5
+ class="gantt-context-menu px-[6px]"
6
+ :style="dynamicMenuStyle"
7
+ @contextmenu.prevent
8
+ @click.stop
9
+ ref="menuRef"
10
+ >
11
+ <!-- 属性配置 -->
12
+ <div class="menu-item" @click="handlePropertyConfig">
13
+ <div class="flex items-center box-border border-b-[1px] border-solid border-[#DCDFE6]">
14
+ <img :src="getIcon('createMenu', 'config')" class="w-[18px] h-[18px] mr-[10px] ml-[2px]" alt="属性配置" />
15
+ <span>属性配置</span>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- 树上高亮 -->
20
+ <div class="menu-item" @click="handleTreeHighlight">
21
+ <div class="flex items-center box-border border-b-[1px] border-solid border-[#DCDFE6]">
22
+ <img :src="getIcon('createMenu', 'tree')" class="w-[18px] h-[18px] mr-[10px] ml-[2px]" alt="树上高亮" />
23
+ <span>树上高亮</span>
24
+ </div>
25
+ </div>
26
+
27
+ <!-- 上移 -->
28
+ <div class="menu-item" :class="{ 'menu-disabled': !canMoveUp }" @click="handleMoveUp">
29
+ <div class="flex items-center box-border border-b-[1px] border-solid border-[#DCDFE6]">
30
+ <img :src="getIcon('createMenu', 'up')" class="w-[18px] h-[18px] mr-[10px] ml-[2px]" alt="上移" />
31
+ <span>上移</span>
32
+ </div>
33
+ </div>
34
+
35
+ <!-- 下移 -->
36
+ <div class="menu-item" :class="{ 'menu-disabled': !canMoveDown }" @click="handleMoveDown">
37
+ <div class="flex items-center box-border border-b-[1px] border-solid border-[#DCDFE6]">
38
+ <img :src="getIcon('createMenu', 'down')" class="w-[18px] h-[18px] mr-[10px] ml-[2px]" alt="下移" />
39
+ <span>下移</span>
40
+ </div>
41
+ </div>
42
+
43
+ <!-- 删除 -->
44
+ <div class="menu-item" @click="handleDelete">
45
+ <div class="flex items-center box-border border-b-[1px] border-solid border-[#DCDFE6]">
46
+ <img :src="getIcon('createMenu', 'delete')" class="w-[18px] h-[18px] mr-[10px] ml-[2px]" alt="删除" />
47
+ <span>删除</span>
48
+ </div>
49
+ </div>
50
+
51
+ <!-- 移除 -->
52
+ <div class="menu-item" @click="handleRemove">
53
+ <div class="flex items-center">
54
+ <img :src="getIcon('createMenu', 'remove')" class="w-[18px] h-[18px] mr-[10px] ml-[2px]" alt="移除" />
55
+ <span>移除</span>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </teleport>
60
+ </template>
61
+
62
+ <script setup lang="ts">
63
+ import { ref, watch, onMounted, onUnmounted, type CSSProperties } from 'vue'
64
+ import { getIcon } from '../../utils/iconLoader'
65
+
66
+ interface Props {
67
+ visible: boolean
68
+ position: {
69
+ x: number
70
+ y: number
71
+ }
72
+ canMoveUp: boolean
73
+ canMoveDown: boolean
74
+ }
75
+
76
+ const props = defineProps<Props>()
77
+
78
+ const emit = defineEmits<{
79
+ (e: 'update:visible', value: boolean): void
80
+ (e: 'property-config'): void
81
+ (e: 'tree-highlight'): void
82
+ (e: 'move-up'): void
83
+ (e: 'move-down'): void
84
+ (e: 'delete'): void
85
+ (e: 'remove'): void
86
+ }>()
87
+
88
+ const menuRef = ref<HTMLElement | null>(null)
89
+
90
+ // 菜单尺寸常量
91
+ const MENU_WIDTH = 180
92
+ const MENU_HEIGHT = 240 // 估算菜单高度
93
+ const SAFE_MARGIN = 10
94
+
95
+ // 动态菜单样式
96
+ const dynamicMenuStyle = ref<CSSProperties>({
97
+ left: '0px',
98
+ top: '0px',
99
+ display: 'none',
100
+ position: 'fixed',
101
+ zIndex: '9999',
102
+ minWidth: `${MENU_WIDTH}px`,
103
+ })
104
+
105
+ // 计算并更新菜单位置
106
+ const updateMenuPosition = () => {
107
+ if (!props.visible) {
108
+ dynamicMenuStyle.value = { ...dynamicMenuStyle.value, display: 'none' }
109
+ return
110
+ }
111
+
112
+ // 获取视口尺寸
113
+ const viewportWidth = window.innerWidth
114
+ const viewportHeight = window.innerHeight
115
+
116
+ // 初始位置
117
+ let left = props.position.x
118
+ let top = props.position.y
119
+
120
+ // 水平方向调整 - 确保不超出右侧边界
121
+ if (left + MENU_WIDTH > viewportWidth) {
122
+ left = viewportWidth - MENU_WIDTH - SAFE_MARGIN
123
+ }
124
+ // 确保不小于左侧边界
125
+ left = Math.max(SAFE_MARGIN, left)
126
+
127
+ // 垂直方向调整 - 确保不超出底部边界
128
+ if (top + MENU_HEIGHT > viewportHeight) {
129
+ top = viewportHeight - MENU_HEIGHT - SAFE_MARGIN
130
+ }
131
+ // 确保不小于顶部边界
132
+ top = Math.max(SAFE_MARGIN, top)
133
+
134
+ dynamicMenuStyle.value = {
135
+ left: `${left}px`,
136
+ top: `${top}px`,
137
+ display: 'block',
138
+ position: 'fixed',
139
+ zIndex: '9999',
140
+ minWidth: `${MENU_WIDTH}px`,
141
+ }
142
+ }
143
+
144
+ // 关闭菜单
145
+ const closeMenu = () => {
146
+ emit('update:visible', false)
147
+ }
148
+
149
+ // 处理点击外部关闭菜单
150
+ const handleClickOutside = (event: MouseEvent) => {
151
+ if (!props.visible || !menuRef.value) return
152
+
153
+ if (!menuRef.value.contains(event.target as Node)) {
154
+ closeMenu()
155
+ }
156
+ }
157
+
158
+ // 监听 props 变化
159
+ watch(
160
+ () => [props.visible, props.position],
161
+ () => {
162
+ updateMenuPosition()
163
+
164
+ // 当菜单显示时,延迟添加点击外部关闭的监听
165
+ if (props.visible) {
166
+ // 使用 setTimeout 确保当前的右键点击事件已经完成
167
+ setTimeout(() => {
168
+ document.addEventListener('click', handleClickOutside, { capture: true })
169
+ }, 0)
170
+ } else {
171
+ // 菜单隐藏时移除监听
172
+ document.removeEventListener('click', handleClickOutside, { capture: true })
173
+ }
174
+ },
175
+ { immediate: true }
176
+ )
177
+
178
+ // 菜单项处理函数
179
+ const handlePropertyConfig = () => {
180
+ emit('property-config')
181
+ closeMenu()
182
+ }
183
+
184
+ const handleTreeHighlight = () => {
185
+ emit('tree-highlight')
186
+ closeMenu()
187
+ }
188
+
189
+ const handleMoveUp = () => {
190
+ if (!props.canMoveUp) return
191
+ emit('move-up')
192
+ closeMenu()
193
+ }
194
+
195
+ const handleMoveDown = () => {
196
+ if (!props.canMoveDown) return
197
+ emit('move-down')
198
+ closeMenu()
199
+ }
200
+
201
+ const handleDelete = () => {
202
+ emit('delete')
203
+ closeMenu()
204
+ }
205
+
206
+ const handleRemove = () => {
207
+ emit('remove')
208
+ closeMenu()
209
+ }
210
+
211
+ // 处理窗口大小变化
212
+ const handleWindowResize = () => {
213
+ if (props.visible) {
214
+ updateMenuPosition()
215
+ }
216
+ }
217
+
218
+ // 组件挂载时添加事件监听
219
+ onMounted(() => {
220
+ window.addEventListener('resize', handleWindowResize)
221
+ updateMenuPosition()
222
+ })
223
+
224
+ // 组件卸载时移除事件监听
225
+ onUnmounted(() => {
226
+ document.removeEventListener('click', handleClickOutside, { capture: true })
227
+ window.removeEventListener('resize', handleWindowResize)
228
+ })
229
+ </script>
230
+
231
+ <style scoped lang="scss">
232
+ .gantt-context-menu {
233
+ background-color: #fff;
234
+ border: 1px solid #ebeef5;
235
+ border-radius: 6px;
236
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
237
+ padding: 6px 0;
238
+ overflow-y: auto;
239
+ box-sizing: border-box;
240
+ transition: opacity 0.2s ease, transform 0.2s ease;
241
+ transform-origin: top left;
242
+ }
243
+
244
+ .gantt-context-menu[style*='display: block'] {
245
+ animation: fadeIn 0.2s ease forwards;
246
+ }
247
+
248
+ @keyframes fadeIn {
249
+ from {
250
+ opacity: 0;
251
+ transform: scale(0.95);
252
+ }
253
+
254
+ to {
255
+ opacity: 1;
256
+ transform: scale(1);
257
+ }
258
+ }
259
+
260
+ /* 滚动条优化 */
261
+ .gantt-context-menu::-webkit-scrollbar {
262
+ width: 6px;
263
+ }
264
+
265
+ .gantt-context-menu::-webkit-scrollbar-thumb {
266
+ background-color: #ddd;
267
+ border-radius: 3px;
268
+ }
269
+
270
+ .gantt-context-menu::-webkit-scrollbar-track {
271
+ background-color: #f5f5f5;
272
+ }
273
+
274
+ .menu-item {
275
+ padding: 0 15px;
276
+ cursor: pointer;
277
+ font-size: 14px;
278
+ color: #606266;
279
+ border-radius: 4px;
280
+ height: 36px;
281
+ line-height: 36px;
282
+ box-sizing: border-box;
283
+
284
+ &:hover:not(.menu-disabled) {
285
+ background-color: #f5f7fa;
286
+ color: #303133;
287
+ }
288
+ }
289
+
290
+ /* 置灰样式 */
291
+ .menu-disabled {
292
+ color: #c0c4cc !important;
293
+ cursor: not-allowed !important;
294
+ pointer-events: none;
295
+
296
+ &:hover {
297
+ background-color: transparent !important;
298
+ }
299
+
300
+ img {
301
+ opacity: 0.5;
302
+ }
303
+ }
304
+ </style>