@visactor/vue-vtable 1.25.0 → 1.25.1-alpha.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 (143) hide show
  1. package/cjs/components/component/menu.js +3 -3
  2. package/cjs/components/component/tooltip.js +3 -3
  3. package/cjs/components/custom/checkBox.js +3 -3
  4. package/cjs/components/custom/group.js +3 -3
  5. package/cjs/components/custom/image.js +3 -3
  6. package/cjs/components/custom/radio.js +3 -3
  7. package/cjs/components/custom/tag.js +3 -3
  8. package/cjs/components/custom/text.js +3 -3
  9. package/cjs/components/custom/vtable-vue-attribute-plugin.js +622 -408
  10. package/cjs/components/list/list-column.js +3 -3
  11. package/cjs/components/pivot/pivot-column-dimension.js +3 -3
  12. package/cjs/components/pivot/pivot-column-header-title.js +3 -3
  13. package/cjs/components/pivot/pivot-corner.js +3 -3
  14. package/cjs/components/pivot/pivot-indicator.js +3 -3
  15. package/cjs/components/pivot/pivot-row-dimension.js +3 -3
  16. package/cjs/components/pivot/pivot-row-header-title.js +3 -3
  17. package/cjs/constants.js +1 -0
  18. package/cjs/edit/editor.js +209 -194
  19. package/cjs/edit/util.js +51 -31
  20. package/cjs/eventsUtils.js +97 -60
  21. package/cjs/hooks/useCellRender.js +27 -20
  22. package/cjs/hooks/useEditorRender.js +75 -52
  23. package/cjs/index.js +5 -5
  24. package/cjs/tables/base-table.vue.js +266 -237
  25. package/cjs/tables/chartModule.js +2 -2
  26. package/cjs/tables/list-table.vue.js +41 -39
  27. package/cjs/tables/pivot-chart.vue.js +35 -37
  28. package/cjs/tables/pivot-table.vue.js +36 -38
  29. package/cjs/utils/customLayoutUtils.js +109 -96
  30. package/cjs/utils/slotUtils.js +85 -88
  31. package/cjs/utils/stringUtils.js +14 -12
  32. package/cjs/utils/vnodeUtils.js +3 -2
  33. package/dist/vue-vtable.js +1715 -1358
  34. package/dist/vue-vtable.min.js +1 -1
  35. package/es/components/component/menu.js +3 -3
  36. package/es/components/component/tooltip.js +3 -3
  37. package/es/components/custom/checkBox.js +3 -3
  38. package/es/components/custom/group.js +3 -3
  39. package/es/components/custom/image.js +3 -3
  40. package/es/components/custom/radio.js +3 -3
  41. package/es/components/custom/tag.js +3 -3
  42. package/es/components/custom/text.js +3 -3
  43. package/es/components/custom/vtable-vue-attribute-plugin.js +622 -408
  44. package/es/components/list/list-column.js +3 -3
  45. package/es/components/pivot/pivot-column-dimension.js +3 -3
  46. package/es/components/pivot/pivot-column-header-title.js +3 -3
  47. package/es/components/pivot/pivot-corner.js +3 -3
  48. package/es/components/pivot/pivot-indicator.js +3 -3
  49. package/es/components/pivot/pivot-row-dimension.js +3 -3
  50. package/es/components/pivot/pivot-row-header-title.js +3 -3
  51. package/es/constants.js +1 -0
  52. package/es/edit/editor.js +209 -194
  53. package/es/edit/util.js +51 -31
  54. package/es/eventsUtils.js +97 -60
  55. package/es/hooks/useCellRender.js +27 -20
  56. package/es/hooks/useEditorRender.js +75 -52
  57. package/es/index.js +3 -3
  58. package/es/tables/base-table.vue.js +266 -237
  59. package/es/tables/chartModule.js +2 -2
  60. package/es/tables/list-table.vue.js +41 -39
  61. package/es/tables/pivot-chart.vue.js +35 -37
  62. package/es/tables/pivot-table.vue.js +36 -38
  63. package/es/utils/customLayoutUtils.js +109 -96
  64. package/es/utils/slotUtils.js +85 -88
  65. package/es/utils/stringUtils.js +14 -12
  66. package/es/utils/vnodeUtils.js +3 -2
  67. package/package.json +5 -5
  68. package/cjs/components/component/menu.d.ts +0 -14
  69. package/cjs/components/component/tooltip.d.ts +0 -11
  70. package/cjs/components/custom/checkBox.d.ts +0 -20
  71. package/cjs/components/custom/custom-layout.d.ts +0 -20
  72. package/cjs/components/custom/group.d.ts +0 -6
  73. package/cjs/components/custom/image.d.ts +0 -6
  74. package/cjs/components/custom/radio.d.ts +0 -17
  75. package/cjs/components/custom/tag.d.ts +0 -16
  76. package/cjs/components/custom/text.d.ts +0 -6
  77. package/cjs/components/custom/vtable-vue-attribute-plugin.d.ts +0 -62
  78. package/cjs/components/index.d.ts +0 -15
  79. package/cjs/components/list/list-column.d.ts +0 -7
  80. package/cjs/components/pivot/pivot-column-dimension.d.ts +0 -11
  81. package/cjs/components/pivot/pivot-column-header-title.d.ts +0 -7
  82. package/cjs/components/pivot/pivot-corner.d.ts +0 -7
  83. package/cjs/components/pivot/pivot-indicator.d.ts +0 -7
  84. package/cjs/components/pivot/pivot-row-dimension.d.ts +0 -11
  85. package/cjs/components/pivot/pivot-row-header-title.d.ts +0 -7
  86. package/cjs/constants.d.ts +0 -1
  87. package/cjs/edit/editor.d.ts +0 -50
  88. package/cjs/edit/index.d.ts +0 -2
  89. package/cjs/edit/util.d.ts +0 -4
  90. package/cjs/eventsUtils.d.ts +0 -120
  91. package/cjs/hooks/index.d.ts +0 -2
  92. package/cjs/hooks/useCellRender.d.ts +0 -2
  93. package/cjs/hooks/useEditorRender.d.ts +0 -2
  94. package/cjs/index.d.ts +0 -6
  95. package/cjs/tables/base-table.vue.d.ts +0 -543
  96. package/cjs/tables/chartModule.d.ts +0 -1
  97. package/cjs/tables/index.d.ts +0 -5
  98. package/cjs/tables/list-table.vue.d.ts +0 -38
  99. package/cjs/tables/pivot-chart.vue.d.ts +0 -38
  100. package/cjs/tables/pivot-table.vue.d.ts +0 -38
  101. package/cjs/utils/customLayoutUtils.d.ts +0 -5
  102. package/cjs/utils/slotUtils.d.ts +0 -28
  103. package/cjs/utils/stringUtils.d.ts +0 -2
  104. package/cjs/utils/vnodeUtils.d.ts +0 -1
  105. package/cjs/utils.d.ts +0 -4
  106. package/es/components/component/menu.d.ts +0 -14
  107. package/es/components/component/tooltip.d.ts +0 -11
  108. package/es/components/custom/checkBox.d.ts +0 -20
  109. package/es/components/custom/custom-layout.d.ts +0 -20
  110. package/es/components/custom/group.d.ts +0 -6
  111. package/es/components/custom/image.d.ts +0 -6
  112. package/es/components/custom/radio.d.ts +0 -17
  113. package/es/components/custom/tag.d.ts +0 -16
  114. package/es/components/custom/text.d.ts +0 -6
  115. package/es/components/custom/vtable-vue-attribute-plugin.d.ts +0 -62
  116. package/es/components/index.d.ts +0 -15
  117. package/es/components/list/list-column.d.ts +0 -7
  118. package/es/components/pivot/pivot-column-dimension.d.ts +0 -11
  119. package/es/components/pivot/pivot-column-header-title.d.ts +0 -7
  120. package/es/components/pivot/pivot-corner.d.ts +0 -7
  121. package/es/components/pivot/pivot-indicator.d.ts +0 -7
  122. package/es/components/pivot/pivot-row-dimension.d.ts +0 -11
  123. package/es/components/pivot/pivot-row-header-title.d.ts +0 -7
  124. package/es/constants.d.ts +0 -1
  125. package/es/edit/editor.d.ts +0 -50
  126. package/es/edit/index.d.ts +0 -2
  127. package/es/edit/util.d.ts +0 -4
  128. package/es/eventsUtils.d.ts +0 -120
  129. package/es/hooks/index.d.ts +0 -2
  130. package/es/hooks/useCellRender.d.ts +0 -2
  131. package/es/hooks/useEditorRender.d.ts +0 -2
  132. package/es/index.d.ts +0 -6
  133. package/es/tables/base-table.vue.d.ts +0 -543
  134. package/es/tables/chartModule.d.ts +0 -1
  135. package/es/tables/index.d.ts +0 -5
  136. package/es/tables/list-table.vue.d.ts +0 -38
  137. package/es/tables/pivot-chart.vue.d.ts +0 -38
  138. package/es/tables/pivot-table.vue.d.ts +0 -38
  139. package/es/utils/customLayoutUtils.d.ts +0 -5
  140. package/es/utils/slotUtils.d.ts +0 -28
  141. package/es/utils/stringUtils.d.ts +0 -2
  142. package/es/utils/vnodeUtils.d.ts +0 -1
  143. package/es/utils.d.ts +0 -4
@@ -1,416 +1,630 @@
1
- import { __rest } from 'tslib';
2
1
  import { CUSTOM_CONTAINER_NAME, CUSTOM_MERGE_PRE_NAME } from '@visactor/vtable';
3
2
  import { HtmlAttributePlugin, vglobal, application } from '@visactor/vtable/es/vrender';
4
3
  import { isNil, isEqual, isObject, isArray, calculateAnchorOfBounds, isFunction, isString, styleStringToObject } from '@visactor/vutils';
5
4
  import { render } from 'vue';
6
5
 
7
- class VTableVueAttributePlugin extends HtmlAttributePlugin {
8
- constructor(currentContext) {
9
- super();
10
- this.name = 'VTableVueAttributePlugin';
11
- this.renderQueue = new Set();
12
- this.isRendering = false;
13
- this.MAX_CACHE_COUNT = 100;
14
- this.accessQueue = [];
15
- this.VIEWPORT_BUFFER = 100;
16
- this.BUFFER_ZONE = 500;
17
- this.styleUpdateQueue = new Map();
18
- this.styleUpdateRequested = false;
19
- this.eventHandlers = new WeakMap();
20
- this.currentContext = currentContext;
21
- }
22
- renderGraphicHTML(graphic) {
23
- if (!this.checkNeedRender(graphic)) {
24
- return;
25
- }
26
- this.renderQueue.add(graphic);
27
- this.scheduleRender();
28
- }
29
- scheduleRender() {
30
- if (this.isRendering) {
31
- return;
32
- }
33
- this.isRendering = true;
34
- vglobal.getRequestAnimationFrame()(() => {
35
- this.renderQueue.forEach(graphic => {
36
- try {
37
- this.doRenderGraphic(graphic);
38
- }
39
- catch (error) {
40
- const { id } = this.getGraphicOptions(graphic) || {};
41
- this.removeElement(id, true);
42
- }
43
- });
44
- this.renderQueue.clear();
45
- this.isRendering = false;
46
- });
47
- }
48
- doRenderGraphic(graphic) {
49
- var _a;
50
- const { id, options } = this.getGraphicOptions(graphic);
51
- if (!id) {
52
- return;
53
- }
54
- const stage = graphic.stage;
55
- const { element, container: expectedContainer } = options;
56
- const actualContainer = expectedContainer ? checkFrozenContainer(graphic) : expectedContainer;
57
- let targetMap = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id];
58
- if (targetMap && actualContainer && actualContainer !== targetMap.container) {
59
- this.removeElement(id);
60
- targetMap = null;
61
- }
62
- this.checkToPassAppContext(element, graphic);
63
- if (!targetMap || !this.checkDom(targetMap.wrapContainer)) {
64
- this.checkAndClearCache(graphic);
65
- const { wrapContainer, nativeContainer, reuse } = this.getWrapContainer(stage, actualContainer, { id, options });
66
- if (wrapContainer) {
67
- const dataRenderId = `${this.renderId}`;
68
- wrapContainer.id = id;
69
- wrapContainer.setAttribute('data-vue-renderId', dataRenderId);
70
- wrapContainer.style.display = 'none';
71
- if (!reuse) {
72
- render(element, wrapContainer);
73
- }
74
- targetMap = {
75
- wrapContainer,
76
- nativeContainer,
77
- container: actualContainer,
78
- renderId: this.renderId,
79
- graphic,
80
- isInViewport: true,
81
- lastPosition: null,
82
- lastStyle: {}
83
- };
84
- this.htmlMap[id] = targetMap;
85
- }
86
- }
87
- if (targetMap) {
88
- targetMap.renderId = this.renderId;
89
- targetMap.lastAccessed = Date.now();
90
- this.updateAccessQueue(id);
91
- this.updateStyleOfWrapContainer(graphic, stage, targetMap.wrapContainer, targetMap.nativeContainer);
92
- }
93
- }
94
- getGraphicOptions(graphic) {
95
- var _a;
96
- const { vue } = (graphic === null || graphic === void 0 ? void 0 : graphic.attribute) || {};
97
- if (!vue) {
98
- return null;
99
- }
100
- const id = isNil(vue.id) ? (_a = graphic.id) !== null && _a !== void 0 ? _a : graphic._uid : vue.id;
101
- return { id: `vue_${id}`, options: vue };
102
- }
103
- checkToPassAppContext(vnode, graphic) {
104
- var _a, _b;
105
- try {
106
- const customConfig = this.getCustomConfig(graphic);
107
- const userAppContext = (_b = (_a = customConfig === null || customConfig === void 0 ? void 0 : customConfig.getVueUserAppContext) === null || _a === void 0 ? void 0 : _a.call(customConfig)) !== null && _b !== void 0 ? _b : this.currentContext;
108
- if (!!(userAppContext === null || userAppContext === void 0 ? void 0 : userAppContext.components) && !!(userAppContext === null || userAppContext === void 0 ? void 0 : userAppContext.directives)) {
109
- vnode.appContext = userAppContext;
110
- }
111
- }
112
- catch (error) { }
113
- }
114
- getCustomConfig(graphic) {
115
- var _a, _b, _c;
116
- const target = getTargetGroup(graphic);
117
- return (_c = (_b = (_a = target === null || target === void 0 ? void 0 : target.stage) === null || _a === void 0 ? void 0 : _a.table) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.customConfig;
118
- }
119
- checkNeedRender(graphic) {
120
- const { id, options } = this.getGraphicOptions(graphic) || {};
121
- if (!id) {
122
- return false;
123
- }
124
- const stage = graphic.stage;
125
- if (!stage) {
126
- return false;
127
- }
128
- const { element } = options;
129
- if (!element) {
130
- return false;
131
- }
132
- const isInViewport = this.checkInViewport(graphic);
133
- return isInViewport;
134
- }
135
- checkInViewport(graphic) {
136
- return this.checkInViewportByZone(graphic, this.VIEWPORT_BUFFER);
137
- }
138
- checkInBuffer(graphic) {
139
- return this.checkInViewportByZone(graphic, this.BUFFER_ZONE);
140
- }
141
- checkInViewportByZone(graphic, buffer = 0) {
142
- const { stage, globalAABBBounds: cBounds } = graphic;
143
- if (!stage) {
144
- return false;
145
- }
146
- const { AABBBounds: vBounds } = stage;
147
- const eBounds = {
148
- x1: vBounds.x1 - buffer,
149
- x2: vBounds.x2 + buffer,
150
- y1: vBounds.y1 - buffer,
151
- y2: vBounds.y2 + buffer
152
- };
153
- const isIntersecting = cBounds.x1 < eBounds.x2 && cBounds.x2 > eBounds.x1 && cBounds.y1 < eBounds.y2 && cBounds.y2 > eBounds.y1;
154
- return isIntersecting;
155
- }
156
- updateAccessQueue(id) {
157
- const index = this.accessQueue.indexOf(id);
158
- if (index > -1) {
159
- this.accessQueue.splice(index, 1);
160
- }
161
- this.accessQueue.unshift(id);
162
- }
163
- checkAndClearCache(graphic) {
164
- var _a;
165
- const { viewportNodes, bufferNodes, cacheNodes } = this.classifyNodes();
166
- const total = viewportNodes.length + bufferNodes.length + cacheNodes.length;
167
- const customConfig = this.getCustomConfig(graphic);
168
- const maxTotal = (_a = customConfig === null || customConfig === void 0 ? void 0 : customConfig.maxDomCacheCount) !== null && _a !== void 0 ? _a : this.MAX_CACHE_COUNT;
169
- if (total <= maxTotal) {
170
- return;
171
- }
172
- const exceedingCount = total - maxTotal;
173
- let toRemove = cacheNodes.slice(0, exceedingCount);
174
- if (toRemove.length < exceedingCount) {
175
- const bufferCandidates = bufferNodes
176
- .sort((a, b) => this.htmlMap[a].lastAccessed - this.htmlMap[b].lastAccessed)
177
- .slice(0, exceedingCount - toRemove.length);
178
- toRemove = toRemove.concat(bufferCandidates);
179
- }
180
- toRemove.forEach(id => this.removeElement(id, true));
181
- }
182
- classifyNodes() {
183
- const viewportNodes = [];
184
- const bufferNodes = [];
185
- const cacheNodes = [];
186
- Object.keys(this.htmlMap).forEach(id => {
187
- const node = this.htmlMap[id];
188
- if (node.isInViewport) {
189
- viewportNodes.push(id);
190
- }
191
- else if (this.checkInBuffer(node.graphic)) {
192
- bufferNodes.push(id);
193
- }
194
- else {
195
- cacheNodes.push(id);
196
- }
197
- });
198
- return {
199
- viewportNodes,
200
- bufferNodes,
201
- cacheNodes
202
- };
203
- }
204
- checkDom(dom) {
205
- if (!dom) {
206
- return false;
207
- }
208
- return document.contains(dom);
209
- }
210
- removeAllDom(g) {
211
- if (this.htmlMap) {
212
- Object.keys(this.htmlMap).forEach(key => {
213
- this.removeElement(key, true);
214
- });
215
- this.htmlMap = null;
216
- }
217
- }
218
- removeElement(id, clear) {
219
- var _a;
220
- const record = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id];
221
- if (!record) {
222
- return;
223
- }
224
- const { wrapContainer } = record;
225
- if (!wrapContainer) {
226
- return;
227
- }
228
- if (!clear) {
229
- wrapContainer.remove();
230
- record.isInViewport = false;
231
- const index = this.accessQueue.indexOf(id);
232
- if (index > -1) {
233
- this.accessQueue.splice(index, 1);
234
- }
235
- }
236
- else {
237
- render(null, wrapContainer);
238
- this.checkDom(wrapContainer) && super.removeElement(id);
239
- delete this.htmlMap[id];
240
- }
241
- this.removeWrapContainerEventListener(wrapContainer);
242
- }
243
- getWrapContainer(stage, userContainer, domParams) {
244
- var _a;
245
- let nativeContainer;
246
- if (userContainer) {
247
- nativeContainer =
248
- typeof userContainer === 'string' ? application.global.getElementById(userContainer) : userContainer;
249
- }
250
- else {
251
- nativeContainer = stage.window.getContainer();
252
- }
253
- const { id } = domParams || {};
254
- const record = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id];
255
- if (record && !record.isInViewport) {
256
- const { wrapContainer } = record;
257
- if (!this.checkDom(wrapContainer)) {
258
- nativeContainer.appendChild(wrapContainer);
259
- }
260
- return {
261
- reuse: true,
262
- wrapContainer,
263
- nativeContainer
264
- };
265
- }
266
- return {
267
- wrapContainer: application.global.createDom({ tagName: 'div', parent: nativeContainer }),
268
- nativeContainer
269
- };
270
- }
271
- updateStyleOfWrapContainer(graphic, stage, wrapContainer, nativeContainer) {
272
- const { attribute, type } = graphic;
273
- const _a = attribute || {}, { vue: options, width, height, visible, display } = _a, rest = __rest(_a, ["vue", "width", "height", "visible", "display"]);
274
- const { x: left, y: top } = this.calculatePosition(graphic, options.anchorType);
275
- const { left: offsetX, top: offsetTop } = this.calculateOffset(stage, nativeContainer, left, top);
276
- const { id } = this.getGraphicOptions(graphic) || {};
277
- const record = id ? this.htmlMap[id] : null;
278
- if (!record) {
279
- return;
280
- }
281
- const positionChanged = !record.lastPosition || record.lastPosition.x !== offsetX || record.lastPosition.y !== offsetTop;
282
- if (!positionChanged) {
283
- return;
284
- }
285
- const { pointerEvents } = options;
286
- const calculateStyle = this.parseDefaultStyleFromGraphic(graphic);
287
- const style = this.convertCellStyle(graphic);
288
- Object.assign(calculateStyle, Object.assign(Object.assign(Object.assign({ width: `${width}px`, height: `${height}px`, overflow: 'hidden' }, (style || {})), (rest || {})), { transform: `translate(${offsetX}px, ${offsetTop}px)`, boxSizing: 'border-box', display: visible !== false ? display || 'block' : 'none', pointerEvents: pointerEvents === true ? 'all' : pointerEvents || 'none', position: 'absolute' }));
289
- if (calculateStyle.pointerEvents !== 'none') {
290
- this.checkToAddEventListener(wrapContainer);
291
- }
292
- if (type === 'text' && options.anchorType === 'position') {
293
- Object.assign(calculateStyle, this.getTransformOfText(graphic));
294
- }
295
- this.applyUserStyles(options, calculateStyle, { offsetX, offsetTop, graphic, wrapContainer });
296
- const styleChanged = !isEqual(record.lastStyle, calculateStyle);
297
- if (styleChanged) {
298
- this.styleUpdateQueue.set(wrapContainer.id, calculateStyle);
299
- this.requestStyleUpdate();
300
- record.lastStyle = calculateStyle;
301
- }
302
- }
303
- checkToAddEventListener(wrapContainer) {
304
- if (!this.eventHandlers.has(wrapContainer)) {
305
- const handler = (e) => {
306
- e.preventDefault();
307
- this.onWheel(e);
308
- };
309
- wrapContainer.addEventListener('wheel', handler, { passive: false });
310
- this.eventHandlers.set(wrapContainer, handler);
311
- }
312
- }
313
- requestStyleUpdate() {
314
- if (!this.styleUpdateRequested) {
315
- this.styleUpdateRequested = true;
316
- vglobal.getRequestAnimationFrame()(() => {
317
- this.styleUpdateQueue.forEach((changes, id) => {
318
- var _a, _b;
319
- const container = (_b = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.wrapContainer;
320
- if (container) {
321
- Object.assign(container.style, changes);
322
- }
323
- });
324
- this.styleUpdateQueue.clear();
325
- this.styleUpdateRequested = false;
326
- });
327
- }
328
- }
329
- convertCellStyle(graphic) {
330
- var _a;
331
- const { col, row, stage } = getTargetGroup(graphic);
332
- const style = (_a = stage === null || stage === void 0 ? void 0 : stage.table) === null || _a === void 0 ? void 0 : _a.getCellStyle(col, row);
333
- if (!isObject(style)) {
334
- return;
335
- }
336
- const _b = style, { lineHeight, padding } = _b, rest = __rest(_b, ["lineHeight", "padding"]);
337
- return Object.assign(Object.assign({}, rest), { padding: isArray(padding) ? padding.map(value => `${value}px`).join(' ') : padding });
338
- }
339
- calculatePosition(graphic, anchorType) {
340
- const bounds = graphic.globalAABBBounds;
341
- if (anchorType === 'position' || bounds.empty()) {
342
- const matrix = graphic.globalTransMatrix;
343
- return { x: matrix.e, y: matrix.f };
344
- }
345
- return calculateAnchorOfBounds(bounds, anchorType || 'top-left');
346
- }
347
- calculateOffset(stage, nativeContainer, x, y) {
348
- const containerTL = application.global.getElementTopLeft(nativeContainer, false);
349
- const windowTL = stage.window.getTopLeft(false);
350
- return {
351
- left: x + windowTL.left - containerTL.left,
352
- top: y + windowTL.top - containerTL.top
353
- };
354
- }
355
- applyUserStyles(options, baseStyle, context) {
356
- if (isFunction(options.style)) {
357
- const userStyle = options.style({
358
- top: context.offsetTop,
359
- left: context.offsetX,
360
- width: context.graphic.globalAABBBounds.width(),
361
- height: context.graphic.globalAABBBounds.height()
362
- }, context.graphic, context.wrapContainer);
363
- Object.assign(baseStyle, userStyle);
364
- }
365
- else if (isObject(options.style)) {
366
- Object.assign(baseStyle, options.style);
367
- }
368
- else if (isString(options.style)) {
369
- Object.assign(baseStyle, styleStringToObject(options.style));
370
- }
371
- }
372
- }
373
- function checkFrozenContainer(graphic) {
374
- var _a;
375
- const { col, row, stage } = getTargetGroup(graphic);
376
- let container = (_a = graphic.attribute.vue) === null || _a === void 0 ? void 0 : _a.container;
377
- const { table } = stage;
378
- if (container === table.bodyDomContainer) {
379
- if (col < table.frozenColCount && row >= table.rowCount - table.bottomFrozenRowCount) {
380
- container = table.bottomFrozenBodyDomContainer;
381
- }
382
- else if (col >= table.colCount - table.rightFrozenColCount &&
383
- row >= table.rowCount - table.bottomFrozenRowCount) {
384
- container = table.rightFrozenBottomDomContainer;
385
- }
386
- else if (row >= table.rowCount - table.bottomFrozenRowCount) {
387
- container = table.bottomFrozenBodyDomContainer;
388
- }
389
- else if (col < table.frozenColCount) {
390
- container = table.frozenBodyDomContainer;
391
- }
392
- else if (col >= table.colCount - table.rightFrozenColCount) {
393
- container = table.rightFrozenBodyDomContainer;
394
- }
395
- }
396
- else if (container === table.headerDomContainer) {
397
- if (col < table.frozenColCount) {
398
- container = table.frozenHeaderDomContainer;
399
- }
400
- else if (col >= table.colCount - table.rightFrozenColCount) {
401
- container = table.rightFrozenHeaderDomContainer;
402
- }
403
- }
404
- return container;
405
- }
406
- function getTargetGroup(target) {
407
- while (target === null || target === void 0 ? void 0 : target.parent) {
408
- if (target.name === CUSTOM_CONTAINER_NAME || (target.name || '').startsWith(CUSTOM_MERGE_PRE_NAME)) {
409
- return target;
410
- }
411
- target = target.parent;
412
- }
413
- return { col: -1, row: -1, stage: null };
6
+ var __rest = (undefined && undefined.__rest) || function (s, e) {
7
+ var t = {};
8
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
9
+ t[p] = s[p];
10
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
11
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
12
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
13
+ t[p[i]] = s[p[i]];
14
+ }
15
+ return t;
16
+ };
17
+ /**
18
+ * 表格自定义组件集成插件
19
+ */
20
+ class VTableVueAttributePlugin extends HtmlAttributePlugin {
21
+ constructor(currentContext) {
22
+ super();
23
+ this.name = 'VTableVueAttributePlugin';
24
+ /** 渲染队列 */
25
+ this.renderQueue = new Set();
26
+ /** 是否正在渲染 */
27
+ this.isRendering = false;
28
+ /** 最大缓存节点数(兜底值) */
29
+ this.MAX_CACHE_COUNT = 100;
30
+ /** 记录节点访问顺序(LRU用) */
31
+ this.accessQueue = [];
32
+ /** 目标可视区区(可视区外一定范围内的节点,保留) */
33
+ this.VIEWPORT_BUFFER = 100;
34
+ /** 缓冲区(非可视区且非缓冲区的节点需清理) */
35
+ this.BUFFER_ZONE = 500;
36
+ // 新增批量更新队列
37
+ this.styleUpdateQueue = new Map();
38
+ /** 样式更新中 */
39
+ this.styleUpdateRequested = false;
40
+ /** 事件集 */
41
+ this.eventHandlers = new WeakMap();
42
+ this.currentContext = currentContext;
43
+ }
44
+ /**
45
+ * @description: 单元格变化后重新渲染组件,由 HtmlAttributePlugin 插件触发
46
+ * @param {IGraphic} graphic
47
+ * @return {*}
48
+ */
49
+ renderGraphicHTML(graphic) {
50
+ if (!this.checkNeedRender(graphic)) {
51
+ return;
52
+ }
53
+ // 加入异步渲染队列
54
+ this.renderQueue.add(graphic);
55
+ this.scheduleRender();
56
+ }
57
+ /**
58
+ * @description: 渲染调度
59
+ * @return {*}
60
+ */
61
+ scheduleRender() {
62
+ if (this.isRendering) {
63
+ return;
64
+ }
65
+ this.isRendering = true;
66
+ vglobal.getRequestAnimationFrame()(() => {
67
+ this.renderQueue.forEach(graphic => {
68
+ try {
69
+ this.doRenderGraphic(graphic);
70
+ }
71
+ catch (error) {
72
+ const { id } = this.getGraphicOptions(graphic) || {};
73
+ this.removeElement(id, true);
74
+ }
75
+ });
76
+ this.renderQueue.clear();
77
+ this.isRendering = false;
78
+ });
79
+ }
80
+ /**
81
+ * @description: 单元格变化后实际组件渲染方法
82
+ * @param {IGraphic} graphic
83
+ * @return {*}
84
+ */
85
+ doRenderGraphic(graphic) {
86
+ var _a;
87
+ const { id, options } = this.getGraphicOptions(graphic);
88
+ if (!id) {
89
+ return;
90
+ }
91
+ const stage = graphic.stage;
92
+ const { element, container: expectedContainer } = options;
93
+ // 获取实际容器
94
+ const actualContainer = expectedContainer ? checkFrozenContainer(graphic) : expectedContainer;
95
+ // 检查是否需要移除旧容器
96
+ let targetMap = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id];
97
+ if (targetMap && actualContainer && actualContainer !== targetMap.container) {
98
+ // 容器变更
99
+ this.removeElement(id);
100
+ targetMap = null;
101
+ }
102
+ // 校验并传递上下文
103
+ this.checkToPassAppContext(element, graphic);
104
+ // 渲染或更新 Vue 组件
105
+ if (!targetMap || !this.checkDom(targetMap.wrapContainer)) {
106
+ // 缓存节点检查
107
+ this.checkAndClearCache(graphic);
108
+ const { wrapContainer, nativeContainer, reuse } = this.getWrapContainer(stage, actualContainer, { id, options });
109
+ if (wrapContainer) {
110
+ const dataRenderId = `${this.renderId}`;
111
+ wrapContainer.id = id;
112
+ wrapContainer.setAttribute('data-vue-renderId', dataRenderId);
113
+ // 先隐藏
114
+ wrapContainer.style.display = 'none';
115
+ if (!reuse) {
116
+ // 仅在非复用时需要重新渲染
117
+ render(element, wrapContainer);
118
+ }
119
+ targetMap = {
120
+ wrapContainer,
121
+ nativeContainer,
122
+ container: actualContainer,
123
+ renderId: this.renderId,
124
+ graphic,
125
+ isInViewport: true,
126
+ lastPosition: null,
127
+ lastStyle: {}
128
+ };
129
+ this.htmlMap[id] = targetMap;
130
+ }
131
+ }
132
+ // 更新样式并记录渲染 ID
133
+ if (targetMap) {
134
+ targetMap.renderId = this.renderId;
135
+ targetMap.lastAccessed = Date.now();
136
+ this.updateAccessQueue(id);
137
+ this.updateStyleOfWrapContainer(graphic, stage, targetMap.wrapContainer, targetMap.nativeContainer);
138
+ }
139
+ }
140
+ /**
141
+ * @description: 获取渲染参数
142
+ * @param {IGraphic} graphic
143
+ * @return {*}
144
+ */
145
+ getGraphicOptions(graphic) {
146
+ var _a;
147
+ // TODO render 组件接入 vue 类型
148
+ //@ts-ignore
149
+ const { vue } = (graphic === null || graphic === void 0 ? void 0 : graphic.attribute) || {};
150
+ if (!vue) {
151
+ return null;
152
+ }
153
+ const id = isNil(vue.id) ? (_a = graphic.id) !== null && _a !== void 0 ? _a : graphic._uid : vue.id;
154
+ return { id: `vue_${id}`, options: vue };
155
+ }
156
+ /**
157
+ * @description: 校验并传递上下文
158
+ * @param {VNode} vnode
159
+ * @param {IGraphic} graphic
160
+ * @return {*}
161
+ */
162
+ checkToPassAppContext(vnode, graphic) {
163
+ var _a, _b;
164
+ try {
165
+ const customConfig = this.getCustomConfig(graphic);
166
+ const userAppContext = (_b = (_a = customConfig === null || customConfig === void 0 ? void 0 : customConfig.getVueUserAppContext) === null || _a === void 0 ? void 0 : _a.call(customConfig)) !== null && _b !== void 0 ? _b : this.currentContext;
167
+ // 简单校验合法性
168
+ if (!!(userAppContext === null || userAppContext === void 0 ? void 0 : userAppContext.components) && !!(userAppContext === null || userAppContext === void 0 ? void 0 : userAppContext.directives)) {
169
+ vnode.appContext = userAppContext;
170
+ }
171
+ }
172
+ catch (error) { }
173
+ }
174
+ /**
175
+ * @description: 获取自定义配置
176
+ * @param {IGraphic} graphic
177
+ * @return {*}
178
+ */
179
+ getCustomConfig(graphic) {
180
+ var _a, _b, _c;
181
+ const target = getTargetGroup(graphic);
182
+ return (_c = (_b = (_a = target === null || target === void 0 ? void 0 : target.stage) === null || _a === void 0 ? void 0 : _a.table) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.customConfig;
183
+ }
184
+ /**
185
+ * @description: 检查是否需要渲染
186
+ * @param {IGraphic} graphic
187
+ * @return {*}
188
+ */
189
+ checkNeedRender(graphic) {
190
+ const { id, options } = this.getGraphicOptions(graphic) || {};
191
+ if (!id) {
192
+ return false;
193
+ }
194
+ const stage = graphic.stage;
195
+ if (!stage) {
196
+ return false;
197
+ }
198
+ const { element } = options;
199
+ if (!element) {
200
+ return false;
201
+ }
202
+ const isInViewport = this.checkInViewport(graphic);
203
+ // 不在可视区内暂时不需要移除,因为在 clearCacheContainer 方法中提前被移除了
204
+ return isInViewport;
205
+ }
206
+ /**
207
+ * @description: 判断是否在可视范围内
208
+ * @param {IGraphic} graphic
209
+ * @return {*}
210
+ */
211
+ checkInViewport(graphic) {
212
+ return this.checkInViewportByZone(graphic, this.VIEWPORT_BUFFER);
213
+ }
214
+ /**
215
+ * @description: 判断是否在缓冲区内
216
+ * @param {IGraphic} graphic
217
+ * @return {*}
218
+ */
219
+ checkInBuffer(graphic) {
220
+ return this.checkInViewportByZone(graphic, this.BUFFER_ZONE);
221
+ }
222
+ /**
223
+ * @description: 判断当前是否在指定视口范围内
224
+ * @param {IGraphic} graphic
225
+ * @param {number} buffer
226
+ * @return {*}
227
+ */
228
+ checkInViewportByZone(graphic, buffer = 0) {
229
+ const { stage, globalAABBBounds: cBounds } = graphic;
230
+ if (!stage) {
231
+ return false;
232
+ }
233
+ // 获取视口的AABB边界
234
+ //@ts-ignore
235
+ const { AABBBounds: vBounds } = stage;
236
+ // 扩展视口判断范围
237
+ const eBounds = {
238
+ x1: vBounds.x1 - buffer,
239
+ x2: vBounds.x2 + buffer,
240
+ y1: vBounds.y1 - buffer,
241
+ y2: vBounds.y2 + buffer
242
+ };
243
+ // 判断两个区域是否相交
244
+ const isIntersecting = cBounds.x1 < eBounds.x2 && cBounds.x2 > eBounds.x1 && cBounds.y1 < eBounds.y2 && cBounds.y2 > eBounds.y1;
245
+ return isIntersecting;
246
+ }
247
+ /**
248
+ * @description: 节点访问顺序队列
249
+ * @param {string} id
250
+ * @return {*}
251
+ */
252
+ updateAccessQueue(id) {
253
+ // 移除旧记录
254
+ const index = this.accessQueue.indexOf(id);
255
+ if (index > -1) {
256
+ this.accessQueue.splice(index, 1);
257
+ }
258
+ // 添加到队列头部
259
+ this.accessQueue.unshift(id);
260
+ }
261
+ /**
262
+ * @description: 在添加新节点前检查缓存大小
263
+ * @param {IGraphic} graphic
264
+ * @return {*}
265
+ */
266
+ checkAndClearCache(graphic) {
267
+ var _a;
268
+ const { viewportNodes, bufferNodes, cacheNodes } = this.classifyNodes();
269
+ const total = viewportNodes.length + bufferNodes.length + cacheNodes.length;
270
+ const customConfig = this.getCustomConfig(graphic);
271
+ const maxTotal = (_a = customConfig === null || customConfig === void 0 ? void 0 : customConfig.maxDomCacheCount) !== null && _a !== void 0 ? _a : this.MAX_CACHE_COUNT;
272
+ // 仅当总数超过阈值时清理
273
+ if (total <= maxTotal) {
274
+ return;
275
+ }
276
+ const exceedingCount = total - maxTotal;
277
+ // 优先清理缓存区节点: 移除缓存区的前 exceedingCount 个节点
278
+ let toRemove = cacheNodes.slice(0, exceedingCount);
279
+ // 若缓存区节点不满足阈值,为了控制内存占用率,按最后访问时间清除最早访问的缓冲区节点
280
+ if (toRemove.length < exceedingCount) {
281
+ const bufferCandidates = bufferNodes
282
+ .sort((a, b) => this.htmlMap[a].lastAccessed - this.htmlMap[b].lastAccessed)
283
+ .slice(0, exceedingCount - toRemove.length);
284
+ toRemove = toRemove.concat(bufferCandidates);
285
+ }
286
+ // 执行清理
287
+ toRemove.forEach(id => this.removeElement(id, true));
288
+ }
289
+ /**
290
+ * @description: 节点按可视区/缓存区/缓冲区分类
291
+ * @return {*}
292
+ */
293
+ classifyNodes() {
294
+ /** 可视区节点 */
295
+ const viewportNodes = [];
296
+ /** 缓冲区节点 */
297
+ const bufferNodes = [];
298
+ /** 既不在可视区也不在缓冲区的节点 */
299
+ const cacheNodes = [];
300
+ Object.keys(this.htmlMap).forEach(id => {
301
+ const node = this.htmlMap[id];
302
+ if (node.isInViewport) {
303
+ viewportNodes.push(id);
304
+ }
305
+ else if (this.checkInBuffer(node.graphic)) {
306
+ bufferNodes.push(id);
307
+ }
308
+ else {
309
+ cacheNodes.push(id);
310
+ }
311
+ });
312
+ return {
313
+ viewportNodes,
314
+ bufferNodes,
315
+ cacheNodes
316
+ };
317
+ }
318
+ /**
319
+ * @description: 检查 dom 是否存在
320
+ * @param {HTMLElement} dom
321
+ * @return {*}
322
+ */
323
+ checkDom(dom) {
324
+ if (!dom) {
325
+ return false;
326
+ }
327
+ return document.contains(dom);
328
+ }
329
+ /**
330
+ * @description: 清除所有 dom
331
+ * @param {IGraphic} g
332
+ * @return {*}
333
+ */
334
+ removeAllDom(g) {
335
+ if (this.htmlMap) {
336
+ Object.keys(this.htmlMap).forEach(key => {
337
+ this.removeElement(key, true);
338
+ });
339
+ this.htmlMap = null;
340
+ }
341
+ }
342
+ /**
343
+ * @description: 移除元素
344
+ * @param {string} id
345
+ * @param {boolean} clear 强制清除
346
+ * @return {*}
347
+ * 目前涉及到页面重绘的操作(比如列宽拖动会使得图形重绘,id变更),会有短暂的容器插拔现象
348
+ */
349
+ removeElement(id, clear) {
350
+ var _a;
351
+ const record = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id];
352
+ if (!record) {
353
+ return;
354
+ }
355
+ const { wrapContainer } = record;
356
+ if (!wrapContainer) {
357
+ return;
358
+ }
359
+ if (!clear) {
360
+ // 移除 dom 但保留在 htmlMap 中,供下次进入可视区时快速复用
361
+ wrapContainer.remove();
362
+ // 标记不在视口
363
+ record.isInViewport = false;
364
+ // 清理访问队列
365
+ const index = this.accessQueue.indexOf(id);
366
+ if (index > -1) {
367
+ this.accessQueue.splice(index, 1);
368
+ }
369
+ }
370
+ else {
371
+ // 卸载子组件
372
+ render(null, wrapContainer);
373
+ this.checkDom(wrapContainer) && super.removeElement(id);
374
+ // 清理引用
375
+ delete this.htmlMap[id];
376
+ }
377
+ // 清理事件
378
+ this.removeWrapContainerEventListener(wrapContainer);
379
+ }
380
+ /**
381
+ * @description: 获取包裹容器
382
+ * @param {IStage} stage
383
+ * @param {string} userContainer
384
+ * @param {CreateDOMParamsType} domParams
385
+ * @return {*}
386
+ */
387
+ getWrapContainer(stage, userContainer, domParams) {
388
+ var _a;
389
+ let nativeContainer;
390
+ if (userContainer) {
391
+ nativeContainer =
392
+ typeof userContainer === 'string' ? application.global.getElementById(userContainer) : userContainer;
393
+ }
394
+ else {
395
+ nativeContainer = stage.window.getContainer();
396
+ }
397
+ const { id } = domParams || {};
398
+ // 从 htmlMap 查找可复用 dom
399
+ const record = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id];
400
+ if (record && !record.isInViewport) {
401
+ const { wrapContainer } = record;
402
+ if (!this.checkDom(wrapContainer)) {
403
+ // 添加游离节点
404
+ nativeContainer.appendChild(wrapContainer);
405
+ }
406
+ return {
407
+ reuse: true,
408
+ wrapContainer,
409
+ nativeContainer
410
+ };
411
+ }
412
+ return {
413
+ wrapContainer: application.global.createDom({ tagName: 'div', parent: nativeContainer }),
414
+ nativeContainer
415
+ };
416
+ }
417
+ /**
418
+ * @description: 更新包裹容器样式
419
+ * @param {IGraphic} graphic
420
+ * @param {IStage} stage
421
+ * @param {HTMLElement} wrapContainer
422
+ * @param {HTMLElement} nativeContainer
423
+ * @return {*}
424
+ */
425
+ updateStyleOfWrapContainer(graphic, stage, wrapContainer, nativeContainer) {
426
+ const { attribute, type } = graphic;
427
+ //@ts-ignore
428
+ const _a = attribute || {}, { vue: options, width, height, visible, display } = _a, rest = __rest(_a, ["vue", "width", "height", "visible", "display"]);
429
+ const { x: left, y: top } = this.calculatePosition(graphic, options.anchorType);
430
+ const { left: offsetX, top: offsetTop } = this.calculateOffset(stage, nativeContainer, left, top);
431
+ const { id } = this.getGraphicOptions(graphic) || {};
432
+ const record = id ? this.htmlMap[id] : null;
433
+ if (!record) {
434
+ return;
435
+ }
436
+ // 位置变化检查
437
+ const positionChanged = !record.lastPosition || record.lastPosition.x !== offsetX || record.lastPosition.y !== offsetTop;
438
+ if (!positionChanged) {
439
+ // 位置没有变化,无需更新样式
440
+ return;
441
+ }
442
+ // 默认自定义区域内也可带动表格画布滚动
443
+ const { pointerEvents } = options;
444
+ const calculateStyle = this.parseDefaultStyleFromGraphic(graphic);
445
+ // 单元格样式
446
+ const style = this.convertCellStyle(graphic);
447
+ Object.assign(calculateStyle, Object.assign(Object.assign(Object.assign({ width: `${width}px`, height: `${height}px`, overflow: 'hidden' }, (style || {})), (rest || {})), { transform: `translate(${offsetX}px, ${offsetTop}px)`, boxSizing: 'border-box', display: visible !== false ? display || 'block' : 'none', pointerEvents: pointerEvents === true ? 'all' : pointerEvents || 'none', position: 'absolute' }));
448
+ if (calculateStyle.pointerEvents !== 'none') {
449
+ this.checkToAddEventListener(wrapContainer);
450
+ }
451
+ if (type === 'text' && options.anchorType === 'position') {
452
+ Object.assign(calculateStyle, this.getTransformOfText(graphic));
453
+ }
454
+ this.applyUserStyles(options, calculateStyle, { offsetX, offsetTop, graphic, wrapContainer });
455
+ // 样式变化检查
456
+ const styleChanged = !isEqual(record.lastStyle, calculateStyle);
457
+ if (styleChanged) {
458
+ this.styleUpdateQueue.set(wrapContainer.id, calculateStyle);
459
+ // 请求批量更新
460
+ this.requestStyleUpdate();
461
+ // TODO 确认是否需要对接 VTableBrowserEnvContribution
462
+ // application.global.updateDom(wrapContainer, {
463
+ // width,
464
+ // height,
465
+ // style: calculateStyle
466
+ // });
467
+ record.lastStyle = calculateStyle;
468
+ }
469
+ }
470
+ /**
471
+ * @description: 事件监听器管理
472
+ * @param {HTMLElement} wrapContainer
473
+ * @return {*}
474
+ */
475
+ checkToAddEventListener(wrapContainer) {
476
+ if (!this.eventHandlers.has(wrapContainer)) {
477
+ const handler = (e) => {
478
+ e.preventDefault();
479
+ this.onWheel(e);
480
+ };
481
+ wrapContainer.addEventListener('wheel', handler, { passive: false });
482
+ this.eventHandlers.set(wrapContainer, handler);
483
+ }
484
+ }
485
+ /**
486
+ * @description: 样式更新
487
+ * @return {*}
488
+ */
489
+ requestStyleUpdate() {
490
+ if (!this.styleUpdateRequested) {
491
+ this.styleUpdateRequested = true;
492
+ vglobal.getRequestAnimationFrame()(() => {
493
+ this.styleUpdateQueue.forEach((changes, id) => {
494
+ var _a, _b;
495
+ const container = (_b = (_a = this.htmlMap) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.wrapContainer;
496
+ if (container) {
497
+ Object.assign(container.style, changes);
498
+ }
499
+ });
500
+ this.styleUpdateQueue.clear();
501
+ this.styleUpdateRequested = false;
502
+ });
503
+ }
504
+ }
505
+ /**
506
+ * @description: 转换单元格样式
507
+ * @param {IGraphic} graphic
508
+ * @return {*}
509
+ */
510
+ convertCellStyle(graphic) {
511
+ var _a;
512
+ const { col, row, stage } = getTargetGroup(graphic);
513
+ const style = (_a = stage === null || stage === void 0 ? void 0 : stage.table) === null || _a === void 0 ? void 0 : _a.getCellStyle(col, row);
514
+ if (!isObject(style)) {
515
+ return;
516
+ }
517
+ const _b = style, { lineHeight, padding } = _b, rest = __rest(_b, ["lineHeight", "padding"]);
518
+ // TODO 表格提供具体解析方法,暂时只解析padding
519
+ return Object.assign(Object.assign({}, rest), { padding: isArray(padding) ? padding.map(value => `${value}px`).join(' ') : padding });
520
+ }
521
+ /**
522
+ * @description: 位置计算
523
+ * @param {IGraphic} graphic
524
+ * @param {string} anchorType
525
+ * @return {*}
526
+ */
527
+ calculatePosition(graphic, anchorType) {
528
+ const bounds = graphic.globalAABBBounds;
529
+ if (anchorType === 'position' || bounds.empty()) {
530
+ const matrix = graphic.globalTransMatrix;
531
+ return { x: matrix.e, y: matrix.f };
532
+ }
533
+ return calculateAnchorOfBounds(bounds, anchorType || 'top-left');
534
+ }
535
+ /**
536
+ * @description: 偏移计算
537
+ * @param {IStage} stage
538
+ * @param {HTMLElement} nativeContainer
539
+ * @param {number} x
540
+ * @param {number} y
541
+ * @return {*}
542
+ */
543
+ calculateOffset(stage, nativeContainer, x, y) {
544
+ const containerTL = application.global.getElementTopLeft(nativeContainer, false);
545
+ const windowTL = stage.window.getTopLeft(false);
546
+ return {
547
+ left: x + windowTL.left - containerTL.left,
548
+ top: y + windowTL.top - containerTL.top
549
+ };
550
+ }
551
+ /**
552
+ * @description: 应用用户样式
553
+ * @param {SimpleDomStyleOptions & CommonDomOptions} options
554
+ * @param {Record<string, any>} baseStyle
555
+ * @param {Object} context
556
+ * @return {*}
557
+ */
558
+ applyUserStyles(options, baseStyle, context) {
559
+ if (isFunction(options.style)) {
560
+ const userStyle = options.style({
561
+ top: context.offsetTop,
562
+ left: context.offsetX,
563
+ width: context.graphic.globalAABBBounds.width(),
564
+ height: context.graphic.globalAABBBounds.height()
565
+ }, context.graphic, context.wrapContainer);
566
+ Object.assign(baseStyle, userStyle);
567
+ }
568
+ else if (isObject(options.style)) {
569
+ Object.assign(baseStyle, options.style);
570
+ }
571
+ else if (isString(options.style)) {
572
+ Object.assign(baseStyle, styleStringToObject(options.style));
573
+ }
574
+ }
575
+ }
576
+ /**
577
+ * @description: 检查冻结容器
578
+ * @param {IGraphic} graphic
579
+ * @return {*}
580
+ */
581
+ function checkFrozenContainer(graphic) {
582
+ var _a;
583
+ const { col, row, stage } = getTargetGroup(graphic);
584
+ // @ts-ignore
585
+ let container = (_a = graphic.attribute.vue) === null || _a === void 0 ? void 0 : _a.container;
586
+ const { table } = stage;
587
+ if (container === table.bodyDomContainer) {
588
+ if (col < table.frozenColCount && row >= table.rowCount - table.bottomFrozenRowCount) {
589
+ container = table.bottomFrozenBodyDomContainer;
590
+ }
591
+ else if (col >= table.colCount - table.rightFrozenColCount &&
592
+ row >= table.rowCount - table.bottomFrozenRowCount) {
593
+ container = table.rightFrozenBottomDomContainer;
594
+ }
595
+ else if (row >= table.rowCount - table.bottomFrozenRowCount) {
596
+ container = table.bottomFrozenBodyDomContainer;
597
+ }
598
+ else if (col < table.frozenColCount) {
599
+ container = table.frozenBodyDomContainer;
600
+ }
601
+ else if (col >= table.colCount - table.rightFrozenColCount) {
602
+ container = table.rightFrozenBodyDomContainer;
603
+ }
604
+ }
605
+ else if (container === table.headerDomContainer) {
606
+ if (col < table.frozenColCount) {
607
+ container = table.frozenHeaderDomContainer;
608
+ }
609
+ else if (col >= table.colCount - table.rightFrozenColCount) {
610
+ container = table.rightFrozenHeaderDomContainer;
611
+ }
612
+ }
613
+ return container;
614
+ }
615
+ /**
616
+ * @description: 获取目标组
617
+ * @param {any} target
618
+ * @return {*}
619
+ */
620
+ function getTargetGroup(target) {
621
+ while (target === null || target === void 0 ? void 0 : target.parent) {
622
+ if (target.name === CUSTOM_CONTAINER_NAME || (target.name || '').startsWith(CUSTOM_MERGE_PRE_NAME)) {
623
+ return target;
624
+ }
625
+ target = target.parent;
626
+ }
627
+ return { col: -1, row: -1, stage: null };
414
628
  }
415
629
 
416
630
  export { VTableVueAttributePlugin };