vxe-gantt 0.0.3 → 3.0.0-beta.1

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 (106) hide show
  1. package/README.md +14 -46
  2. package/es/components.js +3 -2
  3. package/es/gantt/src/gantt-body.js +83 -49
  4. package/es/gantt/src/gantt-chart.js +91 -43
  5. package/es/gantt/src/gantt-header.js +63 -36
  6. package/es/gantt/src/gantt-view.js +638 -586
  7. package/es/gantt/src/gantt.js +1346 -1178
  8. package/es/gantt/src/util.js +1 -4
  9. package/es/gantt/style.css +62 -28
  10. package/es/gantt/style.min.css +1 -1
  11. package/es/index.esm.js +5 -2
  12. package/es/style.css +1 -1
  13. package/es/style.min.css +1 -1
  14. package/es/ui/index.js +9 -3
  15. package/es/ui/src/comp.js +1 -2
  16. package/es/ui/src/log.js +3 -2
  17. package/es/ui/src/utils.js +17 -17
  18. package/es/vxe-gantt/style.css +62 -28
  19. package/es/vxe-gantt/style.min.css +1 -1
  20. package/helper/vetur/attributes.json +1 -1
  21. package/helper/vetur/tags.json +1 -1
  22. package/lib/components.js +20 -19
  23. package/lib/components.min.js +1 -1
  24. package/lib/gantt/index.js +3 -3
  25. package/lib/gantt/index.min.js +1 -1
  26. package/lib/gantt/src/gantt-body.js +109 -87
  27. package/lib/gantt/src/gantt-body.min.js +1 -1
  28. package/lib/gantt/src/gantt-chart.js +109 -69
  29. package/lib/gantt/src/gantt-chart.min.js +1 -1
  30. package/lib/gantt/src/gantt-header.js +75 -56
  31. package/lib/gantt/src/gantt-header.min.js +1 -1
  32. package/lib/gantt/src/gantt-view.js +684 -686
  33. package/lib/gantt/src/gantt-view.min.js +1 -1
  34. package/lib/gantt/src/gantt.js +1630 -1559
  35. package/lib/gantt/src/gantt.min.js +1 -1
  36. package/lib/gantt/src/util.js +1 -4
  37. package/lib/gantt/src/util.min.js +1 -1
  38. package/lib/gantt/style/style.css +62 -28
  39. package/lib/gantt/style/style.min.css +1 -1
  40. package/lib/index.common.js +12 -7
  41. package/lib/index.umd.js +10704 -5870
  42. package/lib/index.umd.min.js +1 -1
  43. package/lib/style.css +1 -1
  44. package/lib/style.min.css +1 -1
  45. package/lib/ui/index.js +12 -16
  46. package/lib/ui/index.min.js +1 -1
  47. package/lib/ui/src/comp.js +3 -2
  48. package/lib/ui/src/comp.min.js +1 -1
  49. package/lib/ui/src/dom.js +33 -33
  50. package/lib/ui/src/dom.min.js +1 -1
  51. package/lib/ui/src/log.js +4 -3
  52. package/lib/ui/src/log.min.js +1 -1
  53. package/lib/ui/src/utils.js +21 -24
  54. package/lib/ui/src/utils.min.js +1 -1
  55. package/lib/vxe-gantt/index.js +4 -2
  56. package/lib/vxe-gantt/index.min.js +1 -1
  57. package/lib/vxe-gantt/style/style.css +62 -28
  58. package/lib/vxe-gantt/style/style.min.css +1 -1
  59. package/lib/vxe-ui/index.js +4 -2
  60. package/lib/vxe-ui/index.min.js +1 -1
  61. package/package.json +13 -13
  62. package/packages/components.ts +8 -5
  63. package/packages/gantt/index.ts +2 -2
  64. package/packages/gantt/src/gantt-body.ts +89 -53
  65. package/packages/gantt/src/gantt-chart.ts +100 -49
  66. package/packages/gantt/src/gantt-header.ts +69 -39
  67. package/packages/gantt/src/gantt-view.ts +692 -624
  68. package/packages/gantt/src/gantt.ts +1459 -1240
  69. package/packages/gantt/src/util.ts +1 -4
  70. package/packages/index.ts +6 -2
  71. package/packages/ui/index.ts +9 -3
  72. package/packages/ui/src/comp.ts +2 -2
  73. package/packages/ui/src/log.ts +3 -1
  74. package/packages/ui/src/utils.ts +22 -21
  75. package/styles/components/gantt-module/gantt-chart.scss +28 -9
  76. package/styles/components/gantt.scss +36 -21
  77. package/styles/theme/base.scss +5 -1
  78. package/types/all.d.ts +3 -3
  79. package/types/index.d.ts +2 -2
  80. package/README.en.md +0 -72
  81. package/README.ja-JP.md +0 -72
  82. package/README.zh-TW.md +0 -73
  83. package/es/gantt/src/emits.js +0 -4
  84. package/es/gantt/src/grid-emits.js +0 -16
  85. package/es/gantt/src/grid-props.js +0 -7
  86. package/es/gantt/src/props.js +0 -2
  87. package/es/gantt/src/table-emits.js +0 -97
  88. package/es/gantt/src/table-props.js +0 -298
  89. package/lib/gantt/src/emits.js +0 -8
  90. package/lib/gantt/src/emits.min.js +0 -1
  91. package/lib/gantt/src/grid-emits.js +0 -8
  92. package/lib/gantt/src/grid-emits.min.js +0 -1
  93. package/lib/gantt/src/grid-props.js +0 -24
  94. package/lib/gantt/src/grid-props.min.js +0 -1
  95. package/lib/gantt/src/props.js +0 -13
  96. package/lib/gantt/src/props.min.js +0 -1
  97. package/lib/gantt/src/table-emits.js +0 -7
  98. package/lib/gantt/src/table-emits.min.js +0 -1
  99. package/lib/gantt/src/table-props.js +0 -306
  100. package/lib/gantt/src/table-props.min.js +0 -1
  101. package/packages/gantt/src/emits.ts +0 -7
  102. package/packages/gantt/src/grid-emits.ts +0 -19
  103. package/packages/gantt/src/grid-props.ts +0 -23
  104. package/packages/gantt/src/props.ts +0 -13
  105. package/packages/gantt/src/table-emits.ts +0 -109
  106. package/packages/gantt/src/table-props.ts +0 -304
@@ -1,13 +1,14 @@
1
- import { h, ref, reactive, nextTick, inject, watch, provide, onMounted, onUnmounted } from 'vue'
1
+ import { VNode, CreateElement } from 'vue'
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
+ import { VxeUI } from '@vxe-ui/core'
3
4
  import { setScrollTop, setScrollLeft } from '../../ui/src/dom'
4
- import { VxeUI } from '../../ui'
5
5
  import { getRefElem } from './util'
6
6
  import XEUtils from 'xe-utils'
7
7
  import GanttViewHeaderComponent from './gantt-header'
8
8
  import GanttViewBodyComponent from './gantt-body'
9
9
 
10
- import type { VxeGanttViewConstructor, GanttViewReactData, GanttViewPrivateRef, VxeGanttPropTypes, VxeGanttDefines, VxeGanttViewPrivateMethods, GanttViewInternalData, VxeGanttViewMethods, GanttViewPrivateComputed, VxeGanttConstructor, VxeGanttPrivateMethods } from '../../../types'
10
+ import type { TableReactData, TableInternalData, VxeTableConstructor, VxeTableMethods, VxeTablePrivateMethods } from 'vxe-table'
11
+ import type { VxeGanttViewConstructor, GanttViewReactData, VxeGanttPropTypes, VxeGanttDefines, VxeGanttViewPrivateMethods, GanttViewInternalData, VxeGanttConstructor, VxeGanttPrivateMethods } from '../../../types'
11
12
 
12
13
  const { globalEvents } = VxeUI
13
14
 
@@ -43,33 +44,484 @@ function createInternalData (): GanttViewInternalData {
43
44
  const maxYHeight = 5e6
44
45
  const maxXWidth = 5e6
45
46
 
46
- export default defineVxeComponent({
47
- name: 'VxeGanttView',
48
- setup (props, context) {
49
- const xID = XEUtils.uniqueId()
47
+ function handleParseColumn ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
48
+ const $xeGantt = $xeGanttView.$xeGantt
49
+ const reactData = $xeGanttView.reactData
50
+ const internalData = $xeGanttView.internalData
51
+
52
+ const { minViewDate, maxViewDate } = reactData
53
+ const taskViewOpts = $xeGantt.computeTaskViewOpts
54
+ const fullCols: VxeGanttPropTypes.Column[] = []
55
+ const groupCols: VxeGanttPropTypes.Column[][] = []
56
+ switch (taskViewOpts.mode) {
57
+ case 'year':
58
+ break
59
+ case 'quarter':
60
+ break
61
+ case 'month':
62
+ break
63
+ case 'week':
64
+ break
65
+ default: {
66
+ if (minViewDate && maxViewDate) {
67
+ const currTime = minViewDate.getTime()
68
+ const diffDayNum = maxViewDate.getTime() - minViewDate.getTime()
69
+ const countDayNum = Math.max(6, Math.floor(diffDayNum / 86400000) + 1)
70
+ const groupList: VxeGanttDefines.GroupHeaderColumn[] = []
71
+ const colList: VxeGanttPropTypes.Column[] = []
72
+ const groupMaps: Record<string, VxeGanttDefines.GroupHeaderColumn> = {}
73
+ for (let i = 0; i < countDayNum; i++) {
74
+ const itemDate = new Date(currTime + (i * 86400000))
75
+ const yyyyy = `${itemDate.getFullYear()}-${itemDate.getMonth() + 1}`
76
+ const mmDd = `${itemDate.getDate()}`
77
+ let groupCol = groupMaps[yyyyy]
78
+ const column = {
79
+ field: `${yyyyy}-${mmDd}`,
80
+ title: mmDd
81
+ }
82
+ if (groupCol) {
83
+ groupCol.children.push(column)
84
+ fullCols.push(groupCol)
85
+ } else {
86
+ groupCol = {
87
+ field: yyyyy,
88
+ title: yyyyy,
89
+ children: [column]
90
+ }
91
+ groupList.push(groupCol)
92
+ fullCols.push(groupCol)
93
+ groupMaps[yyyyy] = groupCol
94
+ }
95
+ colList.push(column)
96
+ }
97
+ groupCols.push(groupList, colList)
98
+
99
+ const $xeTable = internalData.xeTable
100
+ if ($xeTable) {
101
+ const startField = $xeGantt.computeStartField
102
+ const endField = $xeGantt.computeEndField
103
+ const tableInternalData = $xeTable as unknown as TableInternalData
104
+ const { afterFullData } = tableInternalData
105
+ const ctMaps: Record<string, VxeGanttDefines.RowCacheItem> = {}
106
+ afterFullData.forEach(row => {
107
+ const rowid = $xeTable.getRowid(row)
108
+ const startValue = XEUtils.get(row, startField)
109
+ const endValue = XEUtils.get(row, endField)
110
+ if (startValue && endValue) {
111
+ const startDate = XEUtils.toStringDate(startValue)
112
+ const endDate = XEUtils.toStringDate(endValue)
113
+ const oLeftSize = Math.floor((startDate.getTime() - minViewDate.getTime()) / 86400000)
114
+ const oWidthSize = Math.floor((endDate.getTime() - startDate.getTime()) / 86400000) + 1
115
+ ctMaps[rowid] = {
116
+ row,
117
+ rowid,
118
+ oLeftSize,
119
+ oWidthSize
120
+ }
121
+ }
122
+ })
123
+ internalData.chartMaps = ctMaps
124
+ }
125
+ }
126
+ break
127
+ }
128
+ }
129
+ reactData.tableColumn = fullCols
130
+ reactData.headerGroups = groupCols
131
+ }
132
+
133
+ function handleUpdateData ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
134
+ const $xeGantt = $xeGanttView.$xeGantt
135
+ const reactData = $xeGanttView.reactData
136
+ const internalData = $xeGanttView.internalData
137
+
138
+ const $xeTable = internalData.xeTable
139
+ const sdMaps: Record<string, any> = {}
140
+ const edMaps: Record<string, any> = {}
141
+ let minDate: Date | null = null
142
+ let maxDate: Date | null = null
143
+ if ($xeTable) {
144
+ const startField = $xeGantt.computeStartField
145
+ const endField = $xeGantt.computeEndField
146
+ const tableInternalData = $xeTable as unknown as TableInternalData
147
+ const { afterFullData } = tableInternalData
148
+ afterFullData.forEach(row => {
149
+ const startValue = XEUtils.get(row, startField)
150
+ const endValue = XEUtils.get(row, endField)
151
+ if (startValue && endValue) {
152
+ const startDate = XEUtils.toStringDate(startValue)
153
+ if (!minDate || minDate.getTime() > startDate.getTime()) {
154
+ minDate = startDate
155
+ }
156
+ const endDate = XEUtils.toStringDate(endValue)
157
+ if (!maxDate || maxDate.getTime() < endDate.getTime()) {
158
+ maxDate = endDate
159
+ }
160
+ }
161
+ })
162
+ }
163
+ reactData.minViewDate = minDate
164
+ reactData.maxViewDate = maxDate
165
+ internalData.startMaps = sdMaps
166
+ internalData.endMaps = edMaps
167
+ handleParseColumn($xeGanttView)
168
+ }
169
+
170
+ function calcScrollbar ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
171
+ const $xeGantt = $xeGanttView.$xeGantt
172
+ const reactData = $xeGanttView.reactData
173
+ const internalData = $xeGanttView.internalData
174
+
175
+ const { scrollXWidth, scrollYHeight } = reactData
176
+ const { elemStore } = internalData
177
+ const scrollbarOpts = $xeGantt.computeScrollbarOpts
178
+ const bodyWrapperElem = getRefElem(elemStore['main-body-wrapper'])
179
+ const xHandleEl = $xeGanttView.$refs.refScrollXHandleElem as HTMLDivElement
180
+ const yHandleEl = $xeGanttView.$refs.refScrollYHandleElem as HTMLDivElement
181
+ let overflowY = false
182
+ let overflowX = false
183
+ if (bodyWrapperElem) {
184
+ overflowY = scrollYHeight > bodyWrapperElem.clientHeight
185
+ if (yHandleEl) {
186
+ reactData.scrollbarWidth = scrollbarOpts.width || (yHandleEl.offsetWidth - yHandleEl.clientWidth) || 14
187
+ }
188
+ reactData.overflowY = overflowY
189
+
190
+ overflowX = scrollXWidth > bodyWrapperElem.clientWidth
191
+ if (xHandleEl) {
192
+ reactData.scrollbarHeight = scrollbarOpts.height || (xHandleEl.offsetHeight - xHandleEl.clientHeight) || 14
193
+ }
194
+
195
+ reactData.overflowX = overflowX
196
+ }
197
+ }
198
+
199
+ function updateChart ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
200
+ const reactData = $xeGanttView.reactData
201
+ const internalData = $xeGanttView.internalData
202
+
203
+ const { viewCellWidth } = reactData
204
+ const { elemStore, chartMaps } = internalData
205
+ const chartWrapper = getRefElem(elemStore['main-chart-wrapper'])
206
+ if (chartWrapper) {
207
+ XEUtils.arrayEach(chartWrapper.children, (rowEl) => {
208
+ const barEl = rowEl.children[0] as HTMLDivElement
209
+ if (!barEl) {
210
+ return
211
+ }
212
+ const rowid = rowEl.getAttribute('rowid')
213
+ const rowRest = rowid ? chartMaps[rowid] : null
214
+ if (rowRest) {
215
+ barEl.style.left = `${viewCellWidth * rowRest.oLeftSize}px`
216
+ barEl.style.width = `${viewCellWidth * rowRest.oWidthSize}px`
217
+ }
218
+ })
219
+ }
220
+ return $xeGanttView.$nextTick()
221
+ }
222
+
223
+ function updateStyle ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
224
+ const $xeGantt = $xeGanttView.$xeGantt
225
+ const reactData = $xeGanttView.reactData
226
+ const internalData = $xeGanttView.internalData
227
+
228
+ const { scrollbarWidth, scrollbarHeight, tableColumn } = reactData
229
+ const { elemStore } = internalData
230
+ const $xeTable = internalData.xeTable
231
+
232
+ const el = $xeGanttView.$refs.refElem as HTMLDivElement
233
+ if (!el || !el.clientHeight) {
234
+ return
235
+ }
236
+
237
+ const scrollbarXToTop = $xeGantt.computeScrollbarXToTop
238
+
239
+ const xLeftCornerEl = $xeGanttView.$refs.refScrollXLeftCornerElem as HTMLDivElement
240
+ const xRightCornerEl = $xeGanttView.$refs.refScrollXRightCornerElem as HTMLDivElement
241
+ const scrollXVirtualEl = $xeGanttView.$refs.refScrollXVirtualElem as HTMLDivElement
242
+
243
+ const osbWidth = scrollbarWidth
244
+ const osbHeight = scrollbarHeight
245
+
246
+ let tbHeight = 0
247
+ let tHeaderHeight = 0
248
+ let tFooterHeight = 0
249
+ if ($xeTable) {
250
+ const tableInternalData = $xeTable as unknown as TableInternalData
251
+ tbHeight = tableInternalData.tBodyHeight
252
+ tHeaderHeight = tableInternalData.tHeaderHeight
253
+ tFooterHeight = tableInternalData.tFooterHeight
254
+ }
255
+
256
+ const headerScrollElem = getRefElem(elemStore['main-header-scroll'])
257
+ if (headerScrollElem) {
258
+ headerScrollElem.style.height = `${tHeaderHeight}px`
259
+ }
260
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
261
+ if (bodyScrollElem) {
262
+ bodyScrollElem.style.height = `${tbHeight}px`
263
+ }
264
+
265
+ if (scrollXVirtualEl) {
266
+ scrollXVirtualEl.style.height = `${osbHeight}px`
267
+ scrollXVirtualEl.style.visibility = 'visible'
268
+ }
269
+ const xWrapperEl = $xeGanttView.$refs.refScrollXWrapperElem as HTMLDivElement
270
+ if (xWrapperEl) {
271
+ xWrapperEl.style.left = scrollbarXToTop ? `${osbWidth}px` : ''
272
+ xWrapperEl.style.width = `${el.clientWidth - osbWidth}px`
273
+ }
274
+ if (xLeftCornerEl) {
275
+ xLeftCornerEl.style.width = scrollbarXToTop ? `${osbWidth}px` : ''
276
+ xLeftCornerEl.style.display = scrollbarXToTop ? (osbHeight ? 'block' : '') : ''
277
+ }
278
+ if (xRightCornerEl) {
279
+ xRightCornerEl.style.width = scrollbarXToTop ? '' : `${osbWidth}px`
280
+ xRightCornerEl.style.display = scrollbarXToTop ? '' : (osbHeight ? 'block' : '')
281
+ }
282
+
283
+ const scrollYVirtualEl = $xeGanttView.$refs.refScrollYVirtualElem as HTMLDivElement
284
+ if (scrollYVirtualEl) {
285
+ scrollYVirtualEl.style.width = `${osbWidth}px`
286
+ scrollYVirtualEl.style.height = `${tbHeight + tHeaderHeight + tFooterHeight}px`
287
+ scrollYVirtualEl.style.visibility = 'visible'
288
+ }
289
+ const yTopCornerEl = $xeGanttView.$refs.refScrollYTopCornerElem as HTMLDivElement
290
+ if (yTopCornerEl) {
291
+ yTopCornerEl.style.height = `${tHeaderHeight}px`
292
+ yTopCornerEl.style.display = tHeaderHeight ? 'block' : ''
293
+ }
294
+ const yWrapperEl = $xeGanttView.$refs.refScrollYWrapperElem as HTMLDivElement
295
+ if (yWrapperEl) {
296
+ yWrapperEl.style.height = `${tbHeight}px`
297
+ yWrapperEl.style.top = `${tHeaderHeight}px`
298
+ }
299
+ const yBottomCornerEl = $xeGanttView.$refs.refScrollYBottomCornerElem as HTMLDivElement
300
+ if (yBottomCornerEl) {
301
+ yBottomCornerEl.style.height = `${tFooterHeight}px`
302
+ yBottomCornerEl.style.top = `${tHeaderHeight + tbHeight}px`
303
+ yBottomCornerEl.style.display = tFooterHeight ? 'block' : ''
304
+ }
305
+
306
+ const colInfoElem = $xeGanttView.$refs.refColInfoElem as HTMLDivElement
307
+ if (colInfoElem) {
308
+ reactData.viewCellWidth = colInfoElem.clientWidth || 40
309
+ }
310
+ let viewTableWidth = reactData.viewCellWidth * tableColumn.length
311
+ if (bodyScrollElem) {
312
+ const viewWidth = bodyScrollElem.clientWidth
313
+ const remainWidth = viewWidth - viewTableWidth
314
+ if (remainWidth > 0) {
315
+ reactData.viewCellWidth += Math.floor(remainWidth / tableColumn.length)
316
+ viewTableWidth = viewWidth
317
+ }
318
+ }
319
+ const headerTableElem = getRefElem(elemStore['main-header-table'])
320
+ const bodyTableElem = getRefElem(elemStore['main-body-table'])
321
+ if (headerTableElem) {
322
+ headerTableElem.style.width = `${viewTableWidth}px`
323
+ }
324
+ if (bodyTableElem) {
325
+ bodyTableElem.style.width = `${viewTableWidth}px`
326
+ }
327
+
328
+ reactData.scrollXWidth = viewTableWidth
329
+
330
+ return updateChart($xeGanttView)
331
+ }
332
+
333
+ function handleLazyRecalculate ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
334
+ calcScrollbar($xeGanttView)
335
+ updateStyle($xeGanttView)
336
+ return $xeGanttView.$nextTick()
337
+ }
338
+
339
+ function updateScrollXSpace ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
340
+ const reactData = $xeGanttView.reactData
341
+ const internalData = $xeGanttView.internalData
342
+
343
+ const { scrollXLoad, scrollXWidth } = reactData
344
+ const { elemStore } = internalData
345
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
346
+ const bodyTableElem = getRefElem(elemStore['main-body-table'])
347
+
348
+ let xSpaceLeft = 0
349
+
350
+ let clientWidth = 0
351
+ if (bodyScrollElem) {
352
+ clientWidth = bodyScrollElem.clientWidth
353
+ }
354
+ // 虚拟渲染
355
+ let isScrollXBig = false
356
+ let ySpaceWidth = scrollXWidth
357
+ if (scrollXWidth > maxXWidth) {
358
+ // 触右
359
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollLeft + clientWidth >= maxXWidth) {
360
+ xSpaceLeft = maxXWidth - bodyTableElem.clientWidth
361
+ } else {
362
+ xSpaceLeft = (maxXWidth - clientWidth) * (xSpaceLeft / (scrollXWidth - clientWidth))
363
+ }
364
+ ySpaceWidth = maxXWidth
365
+ isScrollXBig = true
366
+ }
50
367
 
51
- const $xeGantt = inject('$xeGantt', {} as (VxeGanttConstructor & VxeGanttPrivateMethods))
368
+ if (bodyTableElem) {
369
+ bodyTableElem.style.transform = `translate(${xSpaceLeft}px, ${reactData.scrollYTop || 0}px)`
370
+ }
52
371
 
53
- const { computeTaskViewOpts, computeStartField, computeEndField, computeScrollbarOpts, computeScrollbarXToTop, computeScrollbarYToLeft } = $xeGantt.getComputeMaps()
372
+ const layoutList = ['header', 'body', 'footer']
373
+ layoutList.forEach(layout => {
374
+ const xSpaceElem = getRefElem(elemStore[`main-${layout}-xSpace`])
375
+ if (xSpaceElem) {
376
+ xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : ''
377
+ }
378
+ })
54
379
 
55
- const refElem = ref<HTMLDivElement>()
380
+ reactData.scrollXLeft = xSpaceLeft
381
+ reactData.scrollXWidth = ySpaceWidth
382
+ reactData.isScrollXBig = isScrollXBig
383
+
384
+ const scrollXSpaceEl = $xeGanttView.$refs.refScrollXSpaceElem as HTMLDivElement
385
+ if (scrollXSpaceEl) {
386
+ scrollXSpaceEl.style.width = `${ySpaceWidth}px`
387
+ }
388
+
389
+ calcScrollbar($xeGanttView)
390
+ return $xeGanttView.$nextTick().then(() => {
391
+ updateStyle($xeGanttView)
392
+ })
393
+ }
394
+
395
+ function updateScrollYSpace ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
396
+ const reactData = $xeGanttView.reactData
397
+ const internalData = $xeGanttView.internalData
398
+
399
+ const { scrollYLoad, overflowY } = reactData
400
+ const { elemStore } = internalData
401
+ const $xeTable = internalData.xeTable
402
+ const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
403
+ const bodyTableElem = getRefElem(elemStore['main-body-table'])
404
+
405
+ let ySpaceTop = 0
406
+ let scrollYHeight = 0
407
+ let isScrollYBig = false
408
+ if ($xeTable) {
409
+ const tableReactData = $xeTable as unknown as TableReactData
410
+ ySpaceTop = tableReactData.scrollYTop
411
+ scrollYHeight = tableReactData.scrollYHeight
412
+ isScrollYBig = tableReactData.isScrollYBig
413
+ }
56
414
 
57
- const refScrollXVirtualElem = ref<HTMLDivElement>()
58
- const refScrollYVirtualElem = ref<HTMLDivElement>()
59
- const refScrollXHandleElem = ref<HTMLDivElement>()
60
- const refScrollXLeftCornerElem = ref<HTMLDivElement>()
61
- const refScrollXRightCornerElem = ref<HTMLDivElement>()
62
- const refScrollYHandleElem = ref<HTMLDivElement>()
63
- const refScrollYTopCornerElem = ref<HTMLDivElement>()
64
- const refScrollXWrapperElem = ref<HTMLDivElement>()
65
- const refScrollYWrapperElem = ref<HTMLDivElement>()
66
- const refScrollYBottomCornerElem = ref<HTMLDivElement>()
67
- const refScrollXSpaceElem = ref<HTMLDivElement>()
68
- const refScrollYSpaceElem = ref<HTMLDivElement>()
415
+ let ySpaceHeight = scrollYHeight
416
+ let scrollYTop = ySpaceTop
69
417
 
70
- const refColInfoElem = ref<HTMLDivElement>()
418
+ let clientHeight = 0
419
+ if (bodyScrollElem) {
420
+ clientHeight = bodyScrollElem.clientHeight
421
+ }
422
+ if (isScrollYBig) {
423
+ // 触底
424
+ if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
425
+ scrollYTop = maxYHeight - bodyTableElem.clientHeight
426
+ } else {
427
+ scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight))
428
+ }
429
+ ySpaceHeight = maxYHeight
430
+ }
431
+ if (!(scrollYLoad && overflowY)) {
432
+ scrollYTop = 0
433
+ }
434
+
435
+ if (bodyTableElem) {
436
+ bodyTableElem.style.transform = `translate(${reactData.scrollXLeft || 0}px, ${scrollYTop}px)`
437
+ }
438
+
439
+ const layoutList = ['header', 'body', 'footer']
440
+ layoutList.forEach(layout => {
441
+ const ySpaceElem = getRefElem(elemStore[`main-${layout}-ySpace`])
442
+ if (ySpaceElem) {
443
+ ySpaceElem.style.height = ySpaceHeight ? `${ySpaceHeight}px` : ''
444
+ }
445
+ })
446
+
447
+ const scrollYSpaceEl = $xeGanttView.$refs.refScrollYSpaceElem as HTMLDivElement
448
+ if (scrollYSpaceEl) {
449
+ scrollYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : ''
450
+ }
451
+ reactData.scrollYTop = scrollYTop
452
+ reactData.scrollYHeight = scrollYHeight
453
+ reactData.isScrollYBig = isScrollYBig
454
+
455
+ calcScrollbar($xeGanttView)
456
+ return $xeGanttView.$nextTick().then(() => {
457
+ updateStyle($xeGanttView)
458
+ })
459
+ }
460
+
461
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
462
+ function checkLastSyncScroll ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods, isRollX: boolean, isRollY: boolean) {
463
+ const reactData = $xeGanttView.reactData
464
+ const internalData = $xeGanttView.internalData
465
+
466
+ const { lcsTimeout } = internalData
467
+ reactData.lazScrollLoading = true
468
+ if (lcsTimeout) {
469
+ clearTimeout(lcsTimeout)
470
+ }
471
+ internalData.lcsTimeout = setTimeout(() => {
472
+ internalData.lcsRunTime = Date.now()
473
+ internalData.lcsTimeout = undefined
474
+ internalData.intoRunScroll = false
475
+ internalData.inVirtualScroll = false
476
+ internalData.inWheelScroll = false
477
+ internalData.inHeaderScroll = false
478
+ internalData.inBodyScroll = false
479
+ internalData.inFooterScroll = false
480
+ reactData.lazScrollLoading = false
481
+ }, 200)
482
+ }
483
+
484
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
485
+ function handleScrollEvent ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods, evnt: Event, isRollY: boolean, isRollX: boolean, scrollTop: number, scrollLeft: number) {
486
+ checkLastSyncScroll($xeGanttView, isRollX, isRollY)
487
+ }
71
488
 
72
- const reactData = reactive<GanttViewReactData>({
489
+ /**
490
+ * 同步表格滚动
491
+ */
492
+ function syncTableScrollTop ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods, scrollTop: number) {
493
+ const internalData = $xeGanttView.internalData
494
+
495
+ const $xeTable = internalData.xeTable
496
+ if ($xeTable) {
497
+ const tableInternalData = $xeTable as unknown as TableInternalData
498
+ const { elemStore: tableElemStore } = tableInternalData
499
+ const tableBodyScrollElem = getRefElem(tableElemStore['main-body-scroll'])
500
+ if (tableBodyScrollElem) {
501
+ tableBodyScrollElem.scrollTop = scrollTop
502
+ }
503
+ }
504
+ }
505
+
506
+ export default defineVxeComponent({
507
+ name: 'VxeGanttView',
508
+ inject: {
509
+ $xeGantt: {
510
+ default: null
511
+ }
512
+ },
513
+ provide () {
514
+ const $xeGanttView = this
515
+
516
+ return {
517
+ $xeGanttView
518
+ }
519
+ },
520
+ props: {},
521
+ data () {
522
+ const xID = XEUtils.uniqueId()
523
+
524
+ const reactData: GanttViewReactData = {
73
525
  // 是否启用了横向 X 可视渲染方式加载
74
526
  scrollXLoad: false,
75
527
  // 是否启用了纵向 Y 可视渲染方式加载
@@ -108,677 +560,300 @@ export default defineVxeComponent({
108
560
  small: 40,
109
561
  mini: 36
110
562
  }
111
- })
112
-
113
- const internalData = createInternalData()
114
-
115
- const refMaps: GanttViewPrivateRef = {
116
- refElem
117
563
  }
118
564
 
119
- const computeMaps: GanttViewPrivateComputed = {
120
- }
565
+ const internalData = createInternalData()
121
566
 
122
- const $xeGanttView = {
567
+ return {
123
568
  xID,
124
- props,
125
- context,
126
569
  reactData,
127
- internalData,
128
-
129
- getRefMaps: () => refMaps,
130
- getComputeMaps: () => computeMaps
131
- } as unknown as VxeGanttViewConstructor & VxeGanttViewPrivateMethods
132
-
133
- const handleParseColumn = () => {
134
- const { minViewDate, maxViewDate } = reactData
135
- const taskViewOpts = computeTaskViewOpts.value
136
- const fullCols: VxeGanttPropTypes.Column[] = []
137
- const groupCols: VxeGanttPropTypes.Column[][] = []
138
- switch (taskViewOpts.mode) {
139
- case 'year':
140
- break
141
- case 'quarter':
142
- break
143
- case 'month':
144
- break
145
- case 'week':
146
- break
147
- default: {
148
- if (minViewDate && maxViewDate) {
149
- const currTime = minViewDate.getTime()
150
- const diffDayNum = maxViewDate.getTime() - minViewDate.getTime()
151
- const countDayNum = Math.max(6, Math.floor(diffDayNum / 86400000) + 1)
152
- const groupList: VxeGanttDefines.GroupHeaderColumn[] = []
153
- const colList: VxeGanttPropTypes.Column[] = []
154
- const groupMaps: Record<string, VxeGanttDefines.GroupHeaderColumn> = {}
155
- for (let i = 0; i < countDayNum; i++) {
156
- const itemDate = new Date(currTime + (i * 86400000))
157
- const yyyyy = `${itemDate.getFullYear()}-${itemDate.getMonth() + 1}`
158
- const mmDd = `${itemDate.getDate()}`
159
- let groupCol = groupMaps[yyyyy]
160
- const column = {
161
- field: `${yyyyy}-${mmDd}`,
162
- title: mmDd
163
- }
164
- if (groupCol) {
165
- groupCol.children.push(column)
166
- fullCols.push(groupCol)
167
- } else {
168
- groupCol = {
169
- field: yyyyy,
170
- title: yyyyy,
171
- children: [column]
172
- }
173
- groupList.push(groupCol)
174
- fullCols.push(groupCol)
175
- groupMaps[yyyyy] = groupCol
176
- }
177
- colList.push(column)
178
- }
179
- groupCols.push(groupList, colList)
180
-
181
- const $xeTable = internalData.xeTable
182
- if ($xeTable) {
183
- const startField = computeStartField.value
184
- const endField = computeEndField.value
185
- const tableInternalData = $xeTable.internalData
186
- const { afterFullData } = tableInternalData
187
- const ctMaps: Record<string, VxeGanttDefines.RowCacheItem> = {}
188
- afterFullData.forEach(row => {
189
- const rowid = $xeTable.getRowid(row)
190
- const startValue = XEUtils.get(row, startField)
191
- const endValue = XEUtils.get(row, endField)
192
- if (startValue && endValue) {
193
- const startDate = XEUtils.toStringDate(startValue)
194
- const endDate = XEUtils.toStringDate(endValue)
195
- const oLeftSize = Math.floor((startDate.getTime() - minViewDate.getTime()) / 86400000)
196
- const oWidthSize = Math.floor((endDate.getTime() - startDate.getTime()) / 86400000) + 1
197
- ctMaps[rowid] = {
198
- row,
199
- rowid,
200
- oLeftSize,
201
- oWidthSize
202
- }
203
- }
204
- })
205
- internalData.chartMaps = ctMaps
206
- }
207
- }
208
- break
209
- }
210
- }
211
- reactData.tableColumn = fullCols
212
- reactData.headerGroups = groupCols
570
+ internalData
213
571
  }
572
+ },
573
+ computed: {
574
+ ...({} as {
575
+ $xeGantt(): (VxeGanttConstructor & VxeGanttPrivateMethods)
576
+ })
577
+ },
578
+ methods: {
579
+ //
580
+ // Method
581
+ //
582
+ refreshData (): Promise<void> {
583
+ const $xeGanttView = this
584
+
585
+ handleUpdateData($xeGanttView)
586
+ return handleLazyRecalculate($xeGanttView)
587
+ },
588
+ updateViewData (): Promise<void> {
589
+ const $xeGanttView = this
590
+ const reactData = $xeGanttView.reactData
591
+ const internalData = $xeGanttView.internalData
214
592
 
215
- const handleUpdateData = () => {
216
593
  const $xeTable = internalData.xeTable
217
- const sdMaps: Record<string, any> = {}
218
- const edMaps: Record<string, any> = {}
219
- let minDate: Date | null = null
220
- let maxDate: Date | null = null
221
594
  if ($xeTable) {
222
- const startField = computeStartField.value
223
- const endField = computeEndField.value
224
- const tableInternalData = $xeTable.internalData
225
- const { afterFullData } = tableInternalData
226
- afterFullData.forEach(row => {
227
- const startValue = XEUtils.get(row, startField)
228
- const endValue = XEUtils.get(row, endField)
229
- if (startValue && endValue) {
230
- const startDate = XEUtils.toStringDate(startValue)
231
- if (!minDate || minDate.getTime() > startDate.getTime()) {
232
- minDate = startDate
233
- }
234
- const endDate = XEUtils.toStringDate(endValue)
235
- if (!maxDate || maxDate.getTime() < endDate.getTime()) {
236
- maxDate = endDate
237
- }
238
- }
239
- })
595
+ const tableReactData = $xeTable as unknown as TableReactData
596
+ const { tableData } = tableReactData
597
+ reactData.tableData = tableData
240
598
  }
241
- reactData.minViewDate = minDate
242
- reactData.maxViewDate = maxDate
243
- internalData.startMaps = sdMaps
244
- internalData.endMaps = edMaps
245
- handleParseColumn()
246
- }
247
-
248
- const calcScrollbar = () => {
249
- const { scrollXWidth, scrollYHeight } = reactData
250
- const { elemStore } = internalData
251
- const scrollbarOpts = computeScrollbarOpts.value
252
- const bodyWrapperElem = getRefElem(elemStore['main-body-wrapper'])
253
- const xHandleEl = refScrollXHandleElem.value
254
- const yHandleEl = refScrollYHandleElem.value
255
- let overflowY = false
256
- let overflowX = false
257
- if (bodyWrapperElem) {
258
- overflowY = scrollYHeight > bodyWrapperElem.clientHeight
259
- if (yHandleEl) {
260
- reactData.scrollbarWidth = scrollbarOpts.width || (yHandleEl.offsetWidth - yHandleEl.clientWidth) || 14
261
- }
262
- reactData.overflowY = overflowY
263
-
264
- overflowX = scrollXWidth > bodyWrapperElem.clientWidth
265
- if (xHandleEl) {
266
- reactData.scrollbarHeight = scrollbarOpts.height || (xHandleEl.offsetHeight - xHandleEl.clientHeight) || 14
267
- }
268
-
269
- reactData.overflowX = overflowX
270
- }
271
- }
272
-
273
- const updateChart = () => {
274
- const { viewCellWidth } = reactData
275
- const { elemStore, chartMaps } = internalData
276
- const chartWrapper = getRefElem(elemStore['main-chart-wrapper'])
277
- if (chartWrapper) {
278
- XEUtils.arrayEach(chartWrapper.children, (rowEl) => {
279
- const barEl = rowEl.children[0] as HTMLDivElement
280
- if (!barEl) {
281
- return
282
- }
283
- const rowid = rowEl.getAttribute('rowid')
284
- const rowRest = rowid ? chartMaps[rowid] : null
285
- if (rowRest) {
286
- barEl.style.left = `${viewCellWidth * rowRest.oLeftSize}px`
287
- barEl.style.width = `${viewCellWidth * rowRest.oWidthSize}px`
288
- }
289
- })
290
- }
291
- return nextTick()
292
- }
599
+ return $xeGanttView.$nextTick()
600
+ },
601
+ connectUpdate ({ $table }: {
602
+ $table: VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods
603
+ }) {
604
+ const $xeGanttView = this
605
+ const internalData = $xeGanttView.internalData
293
606
 
294
- const updateStyle = () => {
295
- const { scrollbarWidth, scrollbarHeight, tableColumn } = reactData
296
- const { elemStore } = internalData
297
- const $xeTable = internalData.xeTable
298
- const el = refElem.value
299
- if (!el || !el.clientHeight) {
300
- return
607
+ if ($table) {
608
+ internalData.xeTable = $table
301
609
  }
610
+ return $xeGanttView.$nextTick()
611
+ },
612
+ handleUpdateStyle () {
613
+ const $xeGanttView = this
302
614
 
303
- const scrollbarXToTop = computeScrollbarXToTop.value
304
-
305
- const xLeftCornerEl = refScrollXLeftCornerElem.value
306
- const xRightCornerEl = refScrollXRightCornerElem.value
307
- const scrollXVirtualEl = refScrollXVirtualElem.value
615
+ return updateStyle($xeGanttView)
616
+ },
617
+ handleLazyRecalculate () {
618
+ const $xeGanttView = this
308
619
 
309
- const osbWidth = scrollbarWidth
310
- const osbHeight = scrollbarHeight
620
+ return handleLazyRecalculate($xeGanttView)
621
+ },
622
+ triggerHeaderScrollEvent (evnt: Event) {
623
+ const $xeGanttView = this
624
+ const internalData = $xeGanttView.internalData
311
625
 
312
- let tbHeight = 0
313
- let tHeaderHeight = 0
314
- let tFooterHeight = 0
315
- if ($xeTable) {
316
- const tableInternalData = $xeTable.internalData
317
- tbHeight = tableInternalData.tBodyHeight
318
- tHeaderHeight = tableInternalData.tHeaderHeight
319
- tFooterHeight = tableInternalData.tFooterHeight
626
+ const { elemStore, inVirtualScroll, inBodyScroll, inFooterScroll } = internalData
627
+ if (inVirtualScroll) {
628
+ return
320
629
  }
321
-
322
- const headerScrollElem = getRefElem(elemStore['main-header-scroll'])
323
- if (headerScrollElem) {
324
- headerScrollElem.style.height = `${tHeaderHeight}px`
630
+ if (inBodyScroll || inFooterScroll) {
631
+ return
325
632
  }
633
+ const wrapperEl = evnt.currentTarget as HTMLDivElement
326
634
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
327
- if (bodyScrollElem) {
328
- bodyScrollElem.style.height = `${tbHeight}px`
635
+ const xHandleEl = $xeGanttView.$refs.refScrollXHandleElem as HTMLDivElement
636
+ if (bodyScrollElem && wrapperEl) {
637
+ const isRollX = true
638
+ const isRollY = false
639
+ const currLeftNum = wrapperEl.scrollLeft
640
+ internalData.inHeaderScroll = true
641
+ setScrollLeft(xHandleEl, currLeftNum)
642
+ setScrollLeft(bodyScrollElem, currLeftNum)
643
+ handleScrollEvent($xeGanttView, evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
329
644
  }
645
+ },
646
+ triggerBodyScrollEvent (evnt: Event) {
647
+ const $xeGanttView = this
648
+ const internalData = $xeGanttView.internalData
330
649
 
331
- if (scrollXVirtualEl) {
332
- scrollXVirtualEl.style.height = `${osbHeight}px`
333
- scrollXVirtualEl.style.visibility = 'visible'
334
- }
335
- const xWrapperEl = refScrollXWrapperElem.value
336
- if (xWrapperEl) {
337
- xWrapperEl.style.left = scrollbarXToTop ? `${osbWidth}px` : ''
338
- xWrapperEl.style.width = `${el.clientWidth - osbWidth}px`
650
+ const { elemStore, inVirtualScroll, inHeaderScroll, inFooterScroll } = internalData
651
+ if (inVirtualScroll) {
652
+ return
339
653
  }
340
- if (xLeftCornerEl) {
341
- xLeftCornerEl.style.width = scrollbarXToTop ? `${osbWidth}px` : ''
342
- xLeftCornerEl.style.display = scrollbarXToTop ? (osbHeight ? 'block' : '') : ''
654
+ if (inHeaderScroll || inFooterScroll) {
655
+ return
343
656
  }
344
- if (xRightCornerEl) {
345
- xRightCornerEl.style.width = scrollbarXToTop ? '' : `${osbWidth}px`
346
- xRightCornerEl.style.display = scrollbarXToTop ? '' : (osbHeight ? 'block' : '')
657
+ const wrapperEl = evnt.currentTarget as HTMLDivElement
658
+ const headerScrollElem = getRefElem(elemStore['main-header-scroll'])
659
+ const xHandleEl = $xeGanttView.$refs.refScrollXHandleElem as HTMLDivElement
660
+ const yHandleEl = $xeGanttView.$refs.refScrollYHandleElem as HTMLDivElement
661
+ if (headerScrollElem && wrapperEl) {
662
+ const isRollX = true
663
+ const isRollY = true
664
+ const currLeftNum = wrapperEl.scrollLeft
665
+ const currTopNum = wrapperEl.scrollTop
666
+ internalData.inBodyScroll = true
667
+ setScrollLeft(xHandleEl, currLeftNum)
668
+ setScrollLeft(headerScrollElem, currLeftNum)
669
+ setScrollTop(yHandleEl, currTopNum)
670
+ syncTableScrollTop($xeGanttView, currTopNum)
671
+ handleScrollEvent($xeGanttView, evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
347
672
  }
673
+ },
674
+ triggerFooterScrollEvent (evnt: Event) {
675
+ const $xeGanttView = this
676
+ const internalData = $xeGanttView.internalData
348
677
 
349
- const scrollYVirtualEl = refScrollYVirtualElem.value
350
- if (scrollYVirtualEl) {
351
- scrollYVirtualEl.style.width = `${osbWidth}px`
352
- scrollYVirtualEl.style.height = `${tbHeight + tHeaderHeight + tFooterHeight}px`
353
- scrollYVirtualEl.style.visibility = 'visible'
354
- }
355
- const yTopCornerEl = refScrollYTopCornerElem.value
356
- if (yTopCornerEl) {
357
- yTopCornerEl.style.height = `${tHeaderHeight}px`
358
- yTopCornerEl.style.display = tHeaderHeight ? 'block' : ''
678
+ const { inVirtualScroll, inHeaderScroll, inBodyScroll } = internalData
679
+ if (inVirtualScroll) {
680
+ return
359
681
  }
360
- const yWrapperEl = refScrollYWrapperElem.value
361
- if (yWrapperEl) {
362
- yWrapperEl.style.height = `${tbHeight}px`
363
- yWrapperEl.style.top = `${tHeaderHeight}px`
682
+ if (inHeaderScroll || inBodyScroll) {
683
+ return
364
684
  }
365
- const yBottomCornerEl = refScrollYBottomCornerElem.value
366
- if (yBottomCornerEl) {
367
- yBottomCornerEl.style.height = `${tFooterHeight}px`
368
- yBottomCornerEl.style.top = `${tHeaderHeight + tbHeight}px`
369
- yBottomCornerEl.style.display = tFooterHeight ? 'block' : ''
685
+ const wrapperEl = evnt.currentTarget as HTMLDivElement
686
+ if (wrapperEl) {
687
+ const isRollX = true
688
+ const isRollY = false
689
+ const currLeftNum = wrapperEl.scrollLeft
690
+ handleScrollEvent($xeGanttView, evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
370
691
  }
692
+ },
693
+ triggerVirtualScrollXEvent (evnt: Event) {
694
+ const $xeGanttView = this
695
+ const internalData = $xeGanttView.internalData
371
696
 
372
- const colInfoElem = refColInfoElem.value
373
- if (colInfoElem) {
374
- reactData.viewCellWidth = colInfoElem.clientWidth || 40
375
- }
376
- let viewTableWidth = reactData.viewCellWidth * tableColumn.length
377
- if (bodyScrollElem) {
378
- const viewWidth = bodyScrollElem.clientWidth
379
- const remainWidth = viewWidth - viewTableWidth
380
- if (remainWidth > 0) {
381
- reactData.viewCellWidth += Math.floor(remainWidth / tableColumn.length)
382
- viewTableWidth = viewWidth
383
- }
384
- }
385
- const headerTableElem = getRefElem(elemStore['main-header-table'])
386
- const bodyTableElem = getRefElem(elemStore['main-body-table'])
387
- if (headerTableElem) {
388
- headerTableElem.style.width = `${viewTableWidth}px`
389
- }
390
- if (bodyTableElem) {
391
- bodyTableElem.style.width = `${viewTableWidth}px`
697
+ const { elemStore, inHeaderScroll, inBodyScroll } = internalData
698
+ if (inHeaderScroll || inBodyScroll) {
699
+ return
392
700
  }
393
-
394
- reactData.scrollXWidth = viewTableWidth
395
-
396
- return updateChart()
397
- }
398
-
399
- const handleLazyRecalculate = () => {
400
- calcScrollbar()
401
- updateStyle()
402
- return nextTick()
403
- }
404
-
405
- const updateScrollXSpace = () => {
406
- const { scrollXLoad, scrollXWidth } = reactData
407
- const { elemStore } = internalData
701
+ const wrapperEl = evnt.currentTarget as HTMLDivElement
702
+ const headerScrollElem = getRefElem(elemStore['main-header-scroll'])
408
703
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
409
- const bodyTableElem = getRefElem(elemStore['main-body-table'])
410
-
411
- let xSpaceLeft = 0
412
-
413
- let clientWidth = 0
414
- if (bodyScrollElem) {
415
- clientWidth = bodyScrollElem.clientWidth
416
- }
417
- // 虚拟渲染
418
- let isScrollXBig = false
419
- let ySpaceWidth = scrollXWidth
420
- if (scrollXWidth > maxXWidth) {
421
- // 触右
422
- if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollLeft + clientWidth >= maxXWidth) {
423
- xSpaceLeft = maxXWidth - bodyTableElem.clientWidth
424
- } else {
425
- xSpaceLeft = (maxXWidth - clientWidth) * (xSpaceLeft / (scrollXWidth - clientWidth))
426
- }
427
- ySpaceWidth = maxXWidth
428
- isScrollXBig = true
704
+ if (wrapperEl) {
705
+ const isRollY = false
706
+ const isRollX = true
707
+ const currLeftNum = wrapperEl.scrollLeft
708
+ internalData.inVirtualScroll = true
709
+ setScrollLeft(headerScrollElem, currLeftNum)
710
+ setScrollLeft(bodyScrollElem, currLeftNum)
711
+ handleScrollEvent($xeGanttView, evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
429
712
  }
713
+ },
714
+ triggerVirtualScrollYEvent (evnt: Event) {
715
+ const $xeGanttView = this
716
+ const internalData = $xeGanttView.internalData
430
717
 
431
- if (bodyTableElem) {
432
- bodyTableElem.style.transform = `translate(${xSpaceLeft}px, ${reactData.scrollYTop || 0}px)`
433
- }
434
-
435
- const layoutList = ['header', 'body', 'footer']
436
- layoutList.forEach(layout => {
437
- const xSpaceElem = getRefElem(elemStore[`main-${layout}-xSpace`])
438
- if (xSpaceElem) {
439
- xSpaceElem.style.width = scrollXLoad ? `${ySpaceWidth}px` : ''
440
- }
441
- })
442
-
443
- reactData.scrollXLeft = xSpaceLeft
444
- reactData.scrollXWidth = ySpaceWidth
445
- reactData.isScrollXBig = isScrollXBig
446
-
447
- const scrollXSpaceEl = refScrollXSpaceElem.value
448
- if (scrollXSpaceEl) {
449
- scrollXSpaceEl.style.width = `${ySpaceWidth}px`
718
+ const { elemStore, inHeaderScroll, inBodyScroll } = internalData
719
+ if (inHeaderScroll || inBodyScroll) {
720
+ return
450
721
  }
451
-
452
- calcScrollbar()
453
- return nextTick().then(() => {
454
- updateStyle()
455
- })
456
- }
457
-
458
- const updateScrollYSpace = () => {
459
- const { scrollYLoad, overflowY } = reactData
460
- const { elemStore } = internalData
461
- const $xeTable = internalData.xeTable
722
+ const wrapperEl = evnt.currentTarget as HTMLDivElement
462
723
  const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
463
- const bodyTableElem = getRefElem(elemStore['main-body-table'])
464
-
465
- let ySpaceTop = 0
466
- let scrollYHeight = 0
467
- let isScrollYBig = false
468
- if ($xeTable) {
469
- const tableReactData = $xeTable.reactData
470
- ySpaceTop = tableReactData.scrollYTop
471
- scrollYHeight = tableReactData.scrollYHeight
472
- isScrollYBig = tableReactData.isScrollYBig
724
+ if (wrapperEl) {
725
+ const isRollY = true
726
+ const isRollX = false
727
+ const currTopNum = wrapperEl.scrollTop
728
+ internalData.inVirtualScroll = true
729
+ setScrollTop(bodyScrollElem, currTopNum)
730
+ syncTableScrollTop($xeGanttView, currTopNum)
731
+ handleScrollEvent($xeGanttView, evnt, isRollY, isRollX, currTopNum, wrapperEl.scrollLeft)
473
732
  }
733
+ },
734
+ updateScrollXSpace () {
735
+ const $xeGanttView = this
474
736
 
475
- let ySpaceHeight = scrollYHeight
476
- let scrollYTop = ySpaceTop
477
-
478
- let clientHeight = 0
479
- if (bodyScrollElem) {
480
- clientHeight = bodyScrollElem.clientHeight
481
- }
482
- if (isScrollYBig) {
483
- // 触底
484
- if (bodyScrollElem && bodyTableElem && bodyScrollElem.scrollTop + clientHeight >= maxYHeight) {
485
- scrollYTop = maxYHeight - bodyTableElem.clientHeight
486
- } else {
487
- scrollYTop = (maxYHeight - clientHeight) * (ySpaceTop / (scrollYHeight - clientHeight))
488
- }
489
- ySpaceHeight = maxYHeight
490
- }
491
- if (!(scrollYLoad && overflowY)) {
492
- scrollYTop = 0
493
- }
494
-
495
- if (bodyTableElem) {
496
- bodyTableElem.style.transform = `translate(${reactData.scrollXLeft || 0}px, ${scrollYTop}px)`
497
- }
498
-
499
- const layoutList = ['header', 'body', 'footer']
500
- layoutList.forEach(layout => {
501
- const ySpaceElem = getRefElem(elemStore[`main-${layout}-ySpace`])
502
- if (ySpaceElem) {
503
- ySpaceElem.style.height = ySpaceHeight ? `${ySpaceHeight}px` : ''
504
- }
505
- })
506
-
507
- const scrollYSpaceEl = refScrollYSpaceElem.value
508
- if (scrollYSpaceEl) {
509
- scrollYSpaceEl.style.height = ySpaceHeight ? `${ySpaceHeight}px` : ''
510
- }
511
- reactData.scrollYTop = scrollYTop
512
- reactData.scrollYHeight = scrollYHeight
513
- reactData.isScrollYBig = isScrollYBig
514
-
515
- calcScrollbar()
516
- return nextTick().then(() => {
517
- updateStyle()
518
- })
519
- }
520
-
521
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
522
- const checkLastSyncScroll = (isRollX: boolean, isRollY: boolean) => {
523
- const { lcsTimeout } = internalData
524
- reactData.lazScrollLoading = true
525
- if (lcsTimeout) {
526
- clearTimeout(lcsTimeout)
527
- }
528
- internalData.lcsTimeout = setTimeout(() => {
529
- internalData.lcsRunTime = Date.now()
530
- internalData.lcsTimeout = undefined
531
- internalData.intoRunScroll = false
532
- internalData.inVirtualScroll = false
533
- internalData.inWheelScroll = false
534
- internalData.inHeaderScroll = false
535
- internalData.inBodyScroll = false
536
- internalData.inFooterScroll = false
537
- reactData.lazScrollLoading = false
538
- }, 200)
539
- }
540
-
541
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
542
- const handleScrollEvent = (evnt: Event, isRollY: boolean, isRollX: boolean, scrollTop: number, scrollLeft: number) => {
543
- checkLastSyncScroll(isRollX, isRollY)
544
- }
545
-
546
- const ganttViewMethods: VxeGanttViewMethods = {
547
- updateViewData () {
548
- const $xeTable = internalData.xeTable
549
- if ($xeTable) {
550
- const tableReactData = $xeTable.reactData
551
- const { tableData } = tableReactData
552
- reactData.tableData = tableData
553
- }
554
- return nextTick()
555
- },
556
- connectUpdate ({ $table }) {
557
- if ($table) {
558
- internalData.xeTable = $table
559
- }
560
- return nextTick()
561
- }
562
- }
563
-
564
- /**
565
- * 同步表格滚动
566
- */
567
- const syncTableScrollTop = (scrollTop: number) => {
568
- const $xeTable = internalData.xeTable
569
- if ($xeTable) {
570
- const tableInternalData = $xeTable.internalData
571
- const { elemStore: tableElemStore } = tableInternalData
572
- const tableBodyScrollElem = getRefElem(tableElemStore['main-body-scroll'])
573
- if (tableBodyScrollElem) {
574
- tableBodyScrollElem.scrollTop = scrollTop
575
- }
576
- }
577
- }
737
+ return updateScrollXSpace($xeGanttView)
738
+ },
739
+ updateScrollYSpace () {
740
+ const $xeGanttView = this
578
741
 
579
- const ganttViewPrivateMethods: VxeGanttViewPrivateMethods = {
580
- handleUpdateStyle: updateStyle,
581
- handleLazyRecalculate,
582
- triggerHeaderScrollEvent (evnt) {
583
- const { elemStore, inVirtualScroll, inBodyScroll, inFooterScroll } = internalData
584
- if (inVirtualScroll) {
585
- return
586
- }
587
- if (inBodyScroll || inFooterScroll) {
588
- return
589
- }
590
- const wrapperEl = evnt.currentTarget as HTMLDivElement
591
- const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
592
- const xHandleEl = refScrollXHandleElem.value
593
- if (bodyScrollElem && wrapperEl) {
594
- const isRollX = true
595
- const isRollY = false
596
- const currLeftNum = wrapperEl.scrollLeft
597
- internalData.inHeaderScroll = true
598
- setScrollLeft(xHandleEl, currLeftNum)
599
- setScrollLeft(bodyScrollElem, currLeftNum)
600
- handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
601
- }
602
- },
603
- triggerBodyScrollEvent (evnt) {
604
- const { elemStore, inVirtualScroll, inHeaderScroll, inFooterScroll } = internalData
605
- if (inVirtualScroll) {
606
- return
607
- }
608
- if (inHeaderScroll || inFooterScroll) {
609
- return
610
- }
611
- const wrapperEl = evnt.currentTarget as HTMLDivElement
612
- const headerScrollElem = getRefElem(elemStore['main-header-scroll'])
613
- const xHandleEl = refScrollXHandleElem.value
614
- const yHandleEl = refScrollYHandleElem.value
615
- if (headerScrollElem && wrapperEl) {
616
- const isRollX = true
617
- const isRollY = true
618
- const currLeftNum = wrapperEl.scrollLeft
619
- const currTopNum = wrapperEl.scrollTop
620
- internalData.inBodyScroll = true
621
- setScrollLeft(xHandleEl, currLeftNum)
622
- setScrollLeft(headerScrollElem, currLeftNum)
623
- setScrollTop(yHandleEl, currTopNum)
624
- syncTableScrollTop(currTopNum)
625
- handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
626
- }
627
- },
628
- triggerFooterScrollEvent (evnt) {
629
- const { inVirtualScroll, inHeaderScroll, inBodyScroll } = internalData
630
- if (inVirtualScroll) {
631
- return
632
- }
633
- if (inHeaderScroll || inBodyScroll) {
634
- return
635
- }
636
- const wrapperEl = evnt.currentTarget as HTMLDivElement
637
- if (wrapperEl) {
638
- const isRollX = true
639
- const isRollY = false
640
- const currLeftNum = wrapperEl.scrollLeft
641
- handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
642
- }
643
- },
644
- triggerVirtualScrollXEvent (evnt) {
645
- const { elemStore, inHeaderScroll, inBodyScroll } = internalData
646
- if (inHeaderScroll || inBodyScroll) {
647
- return
648
- }
649
- const wrapperEl = evnt.currentTarget as HTMLDivElement
650
- const headerScrollElem = getRefElem(elemStore['main-header-scroll'])
651
- const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
652
- if (wrapperEl) {
653
- const isRollY = false
654
- const isRollX = true
655
- const currLeftNum = wrapperEl.scrollLeft
656
- internalData.inVirtualScroll = true
657
- setScrollLeft(headerScrollElem, currLeftNum)
658
- setScrollLeft(bodyScrollElem, currLeftNum)
659
- handleScrollEvent(evnt, isRollY, isRollX, wrapperEl.scrollTop, currLeftNum)
660
- }
661
- },
662
- triggerVirtualScrollYEvent (evnt) {
663
- const { elemStore, inHeaderScroll, inBodyScroll } = internalData
664
- if (inHeaderScroll || inBodyScroll) {
665
- return
666
- }
667
- const wrapperEl = evnt.currentTarget as HTMLDivElement
668
- const bodyScrollElem = getRefElem(elemStore['main-body-scroll'])
669
- if (wrapperEl) {
670
- const isRollY = true
671
- const isRollX = false
672
- const currTopNum = wrapperEl.scrollTop
673
- internalData.inVirtualScroll = true
674
- setScrollTop(bodyScrollElem, currTopNum)
675
- syncTableScrollTop(currTopNum)
676
- handleScrollEvent(evnt, isRollY, isRollX, currTopNum, wrapperEl.scrollLeft)
677
- }
678
- },
679
- updateScrollXSpace,
680
- updateScrollYSpace
681
- }
742
+ return updateScrollYSpace($xeGanttView)
743
+ },
744
+ handleGlobalResizeEvent () {
745
+ const $xeGanttView = this
682
746
 
683
- const handleGlobalResizeEvent = () => {
684
- handleLazyRecalculate()
685
- }
747
+ handleLazyRecalculate($xeGanttView)
748
+ },
686
749
 
687
- Object.assign($xeGanttView, ganttViewMethods, ganttViewPrivateMethods)
750
+ //
751
+ // Render
752
+ //
753
+ renderScrollX (h: CreateElement) {
754
+ const $xeGanttView = this
688
755
 
689
- const renderScrollX = () => {
690
756
  return h('div', {
691
757
  key: 'vsx',
692
- ref: refScrollXVirtualElem,
758
+ ref: 'refScrollXVirtualElem',
693
759
  class: 'vxe-gantt-view--scroll-x-virtual'
694
760
  }, [
695
761
  h('div', {
696
- ref: refScrollXLeftCornerElem,
762
+ ref: 'refScrollXLeftCornerElem',
697
763
  class: 'vxe-gantt-view--scroll-x-left-corner'
698
764
  }),
699
765
  h('div', {
700
- ref: refScrollXWrapperElem,
766
+ ref: 'refScrollXWrapperElem',
701
767
  class: 'vxe-gantt-view--scroll-x-wrapper'
702
768
  }, [
703
769
  h('div', {
704
- ref: refScrollXHandleElem,
770
+ ref: 'refScrollXHandleElem',
705
771
  class: 'vxe-gantt-view--scroll-x-handle',
706
- onScroll: $xeGanttView.triggerVirtualScrollXEvent
772
+ on: {
773
+ scroll: $xeGanttView.triggerVirtualScrollXEvent
774
+ }
707
775
  }, [
708
776
  h('div', {
709
- ref: refScrollXSpaceElem,
777
+ ref: 'refScrollXSpaceElem',
710
778
  class: 'vxe-gantt-view--scroll-x-space'
711
779
  })
712
780
  ])
713
781
  ]),
714
782
  h('div', {
715
- ref: refScrollXRightCornerElem,
783
+ ref: 'refScrollXRightCornerElem',
716
784
  class: 'vxe-gantt-view--scroll-x-right-corner'
717
785
  })
718
786
  ])
719
- }
787
+ },
788
+ renderScrollY (h: CreateElement) {
789
+ const $xeGanttView = this
720
790
 
721
- const renderScrollY = () => {
722
791
  return h('div', {
723
- ref: refScrollYVirtualElem,
792
+ ref: 'refScrollYVirtualElem',
724
793
  class: 'vxe-gantt-view--scroll-y-virtual'
725
794
  }, [
726
795
  h('div', {
727
- ref: refScrollYTopCornerElem,
796
+ ref: 'refScrollYTopCornerElem',
728
797
  class: 'vxe-gantt-view--scroll-y-top-corner'
729
798
  }),
730
799
  h('div', {
731
- ref: refScrollYWrapperElem,
800
+ ref: 'refScrollYWrapperElem',
732
801
  class: 'vxe-gantt-view--scroll-y-wrapper'
733
802
  }, [
734
803
  h('div', {
735
- ref: refScrollYHandleElem,
804
+ ref: 'refScrollYHandleElem',
736
805
  class: 'vxe-gantt-view--scroll-y-handle',
737
- onScroll: $xeGanttView.triggerVirtualScrollYEvent
806
+ on: {
807
+ scroll: $xeGanttView.triggerVirtualScrollYEvent
808
+ }
738
809
  }, [
739
810
  h('div', {
740
- ref: refScrollYSpaceElem,
811
+ ref: 'refScrollYSpaceElem',
741
812
  class: 'vxe-gantt-view--scroll-y-space'
742
813
  })
743
814
  ])
744
815
  ]),
745
816
  h('div', {
746
- ref: refScrollYBottomCornerElem,
817
+ ref: 'refScrollYBottomCornerElem',
747
818
  class: 'vxe-gantt-view--scroll-y-bottom-corner'
748
819
  })
749
820
  ])
750
- }
751
-
752
- const renderViewport = () => {
821
+ },
822
+ renderViewport (h: CreateElement) {
753
823
  return h('div', {
754
824
  class: 'vxe-gantt-view--viewport-wrapper'
755
825
  }, [
756
826
  h(GanttViewHeaderComponent),
757
827
  h(GanttViewBodyComponent)
758
828
  ])
759
- }
829
+ },
830
+ renderBody (h: CreateElement) {
831
+ const $xeGanttView = this
832
+ const $xeGantt = $xeGanttView.$xeGantt
760
833
 
761
- const renderBody = () => {
762
- const scrollbarYToLeft = computeScrollbarYToLeft.value
834
+ const scrollbarYToLeft = $xeGantt.computeScrollbarYToLeft
763
835
  return h('div', {
764
836
  class: 'vxe-gantt-view--layout-wrapper'
765
837
  }, scrollbarYToLeft
766
838
  ? [
767
- renderScrollY(),
768
- renderViewport()
839
+ $xeGanttView.renderScrollY(h),
840
+ $xeGanttView.renderViewport(h)
769
841
  ]
770
842
  : [
771
- renderViewport(),
772
- renderScrollY()
843
+ $xeGanttView.renderViewport(h),
844
+ $xeGanttView.renderScrollY(h)
773
845
  ])
774
- }
846
+ },
847
+ renderVN (h: CreateElement): VNode {
848
+ const $xeGanttView = this
849
+ const $xeGantt = $xeGanttView.$xeGantt
850
+ const reactData = $xeGanttView.reactData
775
851
 
776
- const renderVN = () => {
777
852
  const { overflowX, overflowY, scrollXLoad, scrollYLoad } = reactData
778
- const taskViewOpts = computeTaskViewOpts.value
779
- const scrollbarXToTop = computeScrollbarXToTop.value
853
+ const taskViewOpts = $xeGantt.computeTaskViewOpts
854
+ const scrollbarXToTop = $xeGantt.computeScrollbarXToTop
780
855
  return h('div', {
781
- ref: refElem,
856
+ ref: 'refElem',
782
857
  class: ['vxe-gantt-view', `mode--${taskViewOpts.mode || 'day'}`, {
783
858
  'is--scroll-y': overflowY,
784
859
  'is--scroll-x': overflowX,
@@ -790,51 +865,44 @@ export default defineVxeComponent({
790
865
  class: 'vxe-gantt-view--render-wrapper'
791
866
  }, scrollbarXToTop
792
867
  ? [
793
- renderScrollX(),
794
- renderBody()
868
+ $xeGanttView.renderScrollX(h),
869
+ $xeGanttView.renderBody(h)
795
870
  ]
796
871
  : [
797
- renderBody(),
798
- renderScrollX()
872
+ $xeGanttView.renderBody(h),
873
+ $xeGanttView.renderScrollX(h)
799
874
  ]),
800
875
  h('div', {
801
876
  class: 'vxe-gantt-view--render-vars'
802
877
  }, [
803
878
  h('div', {
804
- ref: refColInfoElem,
879
+ ref: 'refColInfoElem',
805
880
  class: 'vxe-gantt-view--column-info'
806
881
  })
807
882
  ])
808
883
  ])
809
884
  }
885
+ },
886
+ watch: {
887
+ 'reactData.tableData' () {
888
+ const $xeGanttView = this
810
889
 
811
- const tdFlag = ref(0)
812
- watch(() => reactData.tableData, () => {
813
- tdFlag.value++
814
- })
815
- watch(() => reactData.tableData.length, () => {
816
- tdFlag.value++
817
- })
818
- watch(tdFlag, () => {
819
- handleUpdateData()
820
- })
821
-
822
- onMounted(() => {
823
- globalEvents.on($xeGanttView, 'resize', handleGlobalResizeEvent)
824
- })
825
-
826
- onUnmounted(() => {
827
- globalEvents.off($xeGanttView, 'keydown')
828
- XEUtils.assign(internalData, createInternalData())
829
- })
830
-
831
- $xeGanttView.renderVN = renderVN
890
+ handleUpdateData($xeGanttView)
891
+ }
892
+ },
893
+ mounted () {
894
+ const $xeGanttView = this
832
895
 
833
- provide('$xeGanttView', $xeGanttView)
896
+ globalEvents.on($xeGanttView, 'resize', $xeGanttView.handleGlobalResizeEvent)
897
+ },
898
+ beforeDestroy () {
899
+ const $xeGanttView = this
900
+ const internalData = $xeGanttView.internalData
834
901
 
835
- return $xeGanttView
902
+ globalEvents.off($xeGanttView, 'keydown')
903
+ XEUtils.assign(internalData, createInternalData())
836
904
  },
837
- render () {
838
- return this.renderVN()
905
+ render (this: any, h) {
906
+ return this.renderVN(h)
839
907
  }
840
908
  })