@operato/scene-table 8.0.0-beta.0 → 8.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/table.ts DELETED
@@ -1,1448 +0,0 @@
1
- /*
2
- * Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { Component, ComponentNature, Container, Control, Layout, State, Style } from '@hatiolab/things-scene'
6
-
7
- import {
8
- above,
9
- after,
10
- array,
11
- before,
12
- below,
13
- buildCopiedCell,
14
- buildNewCell,
15
- CLEAR_STYLE,
16
- columnControlHandler,
17
- isBottomMost,
18
- isLeftMost,
19
- isRightMost,
20
- isTopMost,
21
- rowControlHandler,
22
- setCellBorder,
23
- WHERE,
24
- adjustCellWidth,
25
- adjustCellHeight
26
- } from './helper-functions'
27
- import TableCell from './table-cell'
28
-
29
- const NATURE: ComponentNature = {
30
- mutable: false,
31
- resizable: true,
32
- rotatable: true,
33
- properties: [
34
- {
35
- type: 'number',
36
- label: 'rows',
37
- name: 'rows',
38
- property: 'rows'
39
- },
40
- {
41
- type: 'number',
42
- label: 'columns',
43
- name: 'columns',
44
- property: 'columns'
45
- },
46
- {
47
- type: 'select',
48
- label: 'data-spread-to',
49
- name: 'spreadTo',
50
- property: {
51
- options: ['', 'text']
52
- }
53
- }
54
- ],
55
- 'value-property': 'data',
56
- help: 'scene/component/table'
57
- }
58
-
59
- export default class Table extends Container {
60
- reflowing: boolean = false
61
-
62
- created() {
63
- var tobeSize = this.rows * this.columns
64
- var gap = this.size() - tobeSize
65
-
66
- if (this.data) {
67
- this.setCellsData()
68
- }
69
-
70
- if (gap == 0) {
71
- return
72
- } else if (gap > 0) {
73
- let removals = this.components.slice(gap)
74
- this.remove(removals)
75
- } else {
76
- let newbies = []
77
-
78
- for (let i = 0; i < -gap; i++) newbies.push(buildNewCell('table-cell', this.app))
79
-
80
- this.add(newbies)
81
- }
82
-
83
- var widths = this.getState('widths')
84
- var heights = this.getState('heights')
85
-
86
- if (!widths || widths.length < this.columns) this.set('widths', this.widths)
87
- if (!heights || heights.length < this.rows) this.set('heights', this.heights)
88
- }
89
-
90
- containable(component: Component) {
91
- return component.getState('type') == 'table-cell'
92
- }
93
-
94
- get focusible() {
95
- /* 이 컨테이너에는 컴포넌트를 임의로 추가 및 삭제할 수 없도록 함 */
96
- return false
97
- }
98
-
99
- get widths() {
100
- var widths = this.getState('widths')
101
-
102
- if (!widths) return array(1, this.columns)
103
-
104
- if (widths.length < this.columns) return widths.concat(array(1, this.columns - widths.length))
105
- else if (widths.length > this.columns) return widths.slice(0, this.columns)
106
-
107
- return widths
108
- }
109
-
110
- get heights() {
111
- var heights = this.getState('heights')
112
-
113
- if (!heights) return array(1, this.rows)
114
-
115
- if (heights.length < this.rows) return heights.concat(array(1, this.rows - heights.length))
116
- else if (heights.length > this.rows) return heights.slice(0, this.rows)
117
-
118
- return heights
119
- }
120
-
121
- buildCells(newrows: number, newcolumns: number, oldrows: number, oldcolumns: number) {
122
- if (newrows < oldrows) {
123
- let removals: TableCell[] = ([] = this.components.slice(oldcolumns * newrows) as TableCell[])
124
-
125
- // 지우려는 셀중에 병합된 셀을 찾는다.
126
- let mergedCells: TableCell[] = []
127
- removals.forEach(cell => {
128
- if (cell.merged === true || cell.rowspan > 1 || cell.colspan > 1) mergedCells.push(cell)
129
- })
130
-
131
- // 병합된 셀 중에서 슈퍼셀을 찾는다.
132
- if (mergedCells.length > 0) {
133
- // 부모 셀을 저장
134
- let superCells: TableCell[] = []
135
- // 부모 셀의 인덱스를 저장
136
- let superCellIndexes: number[] = []
137
- mergedCells.forEach(cell => {
138
- let col, row, index
139
- col = this.components.indexOf(cell) % oldcolumns
140
- row = Math.floor(this.components.indexOf(cell) / oldcolumns)
141
- index = row * oldcolumns + col + 1
142
- while (index) {
143
- --index
144
- let component: TableCell = this.components[index] as TableCell
145
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
146
- if (component.rowspan > 1 || component.colspan > 1) {
147
- let spColStart = this.components.indexOf(component) % oldcolumns
148
- let spColEnd = (this.components.indexOf(component) % oldcolumns) + component.colspan
149
- let spRowStart = Math.floor(this.components.indexOf(component) / oldcolumns)
150
- let spRowEnd = Math.floor(this.components.indexOf(component) / oldcolumns) + component.rowspan
151
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
152
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
153
- if (-1 == superCellIndexes.indexOf(index)) {
154
- superCellIndexes.push(index)
155
- superCells.push(component)
156
- }
157
- }
158
- }
159
- }
160
- })
161
- // 슈퍼셀에서 colspan 을 감소시킨다
162
- superCells.forEach(cell => {
163
- // newcolumns < oldcolumns 케이스와 이 부분만 다름
164
- cell.rowspan -= oldrows - newrows
165
- })
166
- }
167
-
168
- this.remove(removals)
169
- }
170
-
171
- var minrows = Math.min(newrows, oldrows)
172
-
173
- if (newcolumns > oldcolumns) {
174
- for (let r = 0; r < minrows; r++) {
175
- for (let c = oldcolumns; c < newcolumns; c++) {
176
- this.insertComponentAt(buildNewCell('table-cell', this.app), r * newcolumns + c)
177
- }
178
- }
179
- } else if (newcolumns < oldcolumns) {
180
- let removals: TableCell[] = []
181
-
182
- for (let r = 0; r < minrows; r++) {
183
- for (let c = newcolumns; c < oldcolumns; c++) {
184
- removals.push(this.components[r * oldcolumns + c] as TableCell)
185
- }
186
- }
187
- // 지우려는 셀중에 병합된 셀을 찾는다.
188
- let mergedCells: TableCell[] = []
189
- removals.forEach(cell => {
190
- if (cell.merged === true || cell.rowspan > 1 || cell.colspan > 1) mergedCells.push(cell)
191
- })
192
-
193
- // 병합된 셀 중에서 슈퍼셀을 찾는다.
194
- if (mergedCells.length > 0) {
195
- // 부모 셀을 저장
196
- let superCells: TableCell[] = []
197
- // 부모 셀의 인덱스를 저장
198
- let superCellIndexes: number[] = []
199
- mergedCells.forEach(cell => {
200
- let col, row, index
201
- col = this.components.indexOf(cell) % oldcolumns
202
- row = Math.floor(this.components.indexOf(cell) / oldcolumns)
203
- index = row * oldcolumns + col + 1
204
- while (index) {
205
- --index
206
- let component = this.components[index] as TableCell
207
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
208
- if (component.rowspan > 1 || component.colspan > 1) {
209
- let spColStart = this.components.indexOf(component) % oldcolumns
210
- let spColEnd = (this.components.indexOf(component) % oldcolumns) + component.colspan
211
- let spRowStart = Math.floor(this.components.indexOf(component) / oldcolumns)
212
- let spRowEnd = Math.floor(this.components.indexOf(component) / oldcolumns) + component.rowspan
213
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
214
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
215
- if (-1 == superCellIndexes.indexOf(index)) {
216
- superCellIndexes.push(index)
217
- superCells.push(component)
218
- }
219
- }
220
- }
221
- }
222
- })
223
- // 슈퍼셀에서 colspan 을 감소시킨다
224
- superCells.forEach(cell => {
225
- cell.colspan -= oldcolumns - newcolumns
226
- })
227
- }
228
-
229
- this.remove(removals)
230
- }
231
-
232
- if (newrows > oldrows) {
233
- let newbies = []
234
-
235
- for (let r = oldrows; r < newrows; r++) {
236
- for (let i = 0; i < newcolumns; i++) {
237
- newbies.push(buildNewCell('table-cell', this.app))
238
- }
239
- }
240
- this.add(newbies)
241
- }
242
-
243
- this.set({
244
- widths: this.widths,
245
- heights: this.heights
246
- })
247
- }
248
-
249
- get layout() {
250
- return Layout.get('table')
251
- }
252
-
253
- get rows() {
254
- return Number(this.getState('rows'))
255
- }
256
-
257
- setCellsStyle(cells: TableCell[], style: Style, where: WHERE, clearBefore = true) {
258
- var components = this.components
259
- var total = components.length
260
- var columns = this.getState('columns')
261
-
262
- // 병합된 셀도 포함시킨다.
263
- var _cells: TableCell[] = []
264
- cells.forEach(c => {
265
- _cells.push(c)
266
- if (c.colspan || c.rowspan) {
267
- let col = this.getRowColumn(c).column
268
- let row = this.getRowColumn(c).row
269
- for (let i = row; i < row + c.rowspan; i++)
270
- for (let j = col; j < col + c.colspan; j++)
271
- if (i != row || j != col) _cells.push(this.components[i * this.columns + j] as TableCell)
272
- }
273
- })
274
- var indices = _cells.map(cell => components.indexOf(cell))
275
- indices.forEach(i => {
276
- var cell = components[i]
277
- clearBefore && setCellBorder(cell, CLEAR_STYLE, 'all')
278
-
279
- switch (where) {
280
- case 'all':
281
- setCellBorder(cell, style, where)
282
-
283
- if (isLeftMost(total, columns, indices, i)) setCellBorder(components[before(columns, i)], style, 'right')
284
- if (isRightMost(total, columns, indices, i)) setCellBorder(components[after(columns, i)], style, 'left')
285
- if (isTopMost(total, columns, indices, i)) setCellBorder(components[above(columns, i)], style, 'bottom')
286
- if (isBottomMost(total, columns, indices, i)) setCellBorder(components[below(columns, i)], style, 'top')
287
- break
288
- case 'in':
289
- if (!isLeftMost(total, columns, indices, i)) {
290
- setCellBorder(cell, style, 'left')
291
- }
292
- if (!isRightMost(total, columns, indices, i)) {
293
- setCellBorder(cell, style, 'right')
294
- }
295
- if (!isTopMost(total, columns, indices, i)) {
296
- setCellBorder(cell, style, 'top')
297
- }
298
- if (!isBottomMost(total, columns, indices, i)) {
299
- setCellBorder(cell, style, 'bottom')
300
- }
301
- break
302
- case 'out':
303
- if (isLeftMost(total, columns, indices, i)) {
304
- setCellBorder(cell, style, 'left')
305
- setCellBorder(components[before(columns, i)], style, 'right')
306
- }
307
- if (isRightMost(total, columns, indices, i)) {
308
- setCellBorder(cell, style, 'right')
309
- setCellBorder(components[after(columns, i)], style, 'left')
310
- }
311
- if (isTopMost(total, columns, indices, i)) {
312
- setCellBorder(cell, style, 'top')
313
- setCellBorder(components[above(columns, i)], style, 'bottom')
314
- }
315
- if (isBottomMost(total, columns, indices, i)) {
316
- setCellBorder(cell, style, 'bottom')
317
- setCellBorder(components[below(columns, i)], style, 'top')
318
- }
319
- break
320
- case 'left':
321
- if (isLeftMost(total, columns, indices, i)) {
322
- setCellBorder(cell, style, 'left')
323
- setCellBorder(components[before(columns, i)], style, 'right')
324
- }
325
- break
326
- case 'right':
327
- if (isRightMost(total, columns, indices, i)) {
328
- setCellBorder(cell, style, 'right')
329
- setCellBorder(components[after(columns, i)], style, 'left')
330
- }
331
- break
332
- case 'center':
333
- if (!isLeftMost(total, columns, indices, i)) {
334
- setCellBorder(cell, style, 'left')
335
- }
336
- if (!isRightMost(total, columns, indices, i)) {
337
- setCellBorder(cell, style, 'right')
338
- }
339
- break
340
- case 'middle':
341
- if (!isTopMost(total, columns, indices, i)) {
342
- setCellBorder(cell, style, 'top')
343
- }
344
- if (!isBottomMost(total, columns, indices, i)) {
345
- setCellBorder(cell, style, 'bottom')
346
- }
347
- break
348
- case 'top':
349
- if (isTopMost(total, columns, indices, i)) {
350
- setCellBorder(cell, style, 'top')
351
- setCellBorder(components[above(columns, i)], style, 'bottom')
352
- }
353
- break
354
- case 'bottom':
355
- if (isBottomMost(total, columns, indices, i)) {
356
- setCellBorder(cell, style, 'bottom')
357
- setCellBorder(components[below(columns, i)], style, 'top')
358
- }
359
- break
360
- case 'clear':
361
- setCellBorder(cell, CLEAR_STYLE, 'all')
362
-
363
- if (isLeftMost(total, columns, indices, i))
364
- setCellBorder(components[before(columns, i)], CLEAR_STYLE, 'right')
365
- if (isRightMost(total, columns, indices, i)) setCellBorder(components[after(columns, i)], CLEAR_STYLE, 'left')
366
- if (isTopMost(total, columns, indices, i)) setCellBorder(components[above(columns, i)], CLEAR_STYLE, 'bottom')
367
- if (isBottomMost(total, columns, indices, i)) setCellBorder(components[below(columns, i)], CLEAR_STYLE, 'top')
368
- }
369
- })
370
- }
371
-
372
- setCellsData() {
373
- var data = this.data
374
-
375
- if (!data) return
376
-
377
- data = this.toObjectArrayValue(data) || []
378
-
379
- var cells = this.components as TableCell[]
380
-
381
- var { spreadTo } = this.state
382
-
383
- cells.forEach(cell => {
384
- var dataKey = cell.model.dataKey
385
- var dataIndex = cell.model.dataIndex
386
-
387
- if (dataIndex >= 0) {
388
- const cellData = dataKey ? (data[dataIndex] || {})[dataKey] : data[dataIndex]
389
-
390
- ;(cell as any).data = cellData
391
- if (spreadTo) {
392
- ;(cell as any)[spreadTo] = cellData
393
- }
394
- }
395
- })
396
- }
397
-
398
- getRowColumn(cell: TableCell): { column: number; row: number } {
399
- var idx = this.components.indexOf(cell)
400
-
401
- return {
402
- column: idx % this.columns,
403
- row: Math.floor(idx / this.columns)
404
- }
405
- }
406
-
407
- getCellsByRow(row: number) {
408
- return this.components.slice(row * this.columns, (row + 1) * this.columns)
409
- }
410
-
411
- getCellsByColumn(column: number) {
412
- var cells = []
413
- for (var i = 0; i < this.rows; i++) cells.push(this.components[this.columns * i + column])
414
-
415
- return cells
416
- }
417
-
418
- // 한 개의 행을 매개변수로 받아서 첫 번째 셀부터 우측으로 이동하면서 병합된 셀이 있는지 검사한다.
419
- findMergedCellByX(row: number) {
420
- let mergedCells: TableCell[] = []
421
- let cell: TableCell
422
- for (let i = 0; i < this.columns; i++) {
423
- cell = this.components[row * this.columns + i] as TableCell
424
- if (cell.merged === true || cell.rowspan > 1 || cell.colspan > 1) mergedCells.push(cell)
425
- }
426
- return mergedCells
427
- }
428
-
429
- // 한 개의 열을 매개변수로 받아서 첫 번째 셀부터 아래로 이동하면서 병합된 셀이 있는지 검사한다.
430
- findMergedCellByY(column: number) {
431
- let mergedCells: TableCell[] = []
432
- let cell: TableCell
433
- for (let i = 0; i < this.rows; i++) {
434
- cell = this.components[i * this.columns + column] as TableCell
435
- if (cell.merged === true || cell.rowspan > 1 || cell.colspan > 1) mergedCells.push(cell)
436
- }
437
- return mergedCells
438
- }
439
-
440
- mergeCells(cells: TableCell[]) {
441
- // 선택한 셀이 들어있는 행
442
- let mergeableRows: number[] = []
443
- cells.forEach(cell => {
444
- let row = this.getRowColumn(cell).row
445
- if (-1 == mergeableRows.indexOf(row)) mergeableRows.push(row)
446
- })
447
-
448
- // 선택한 셀의 행이 연속적인 숫자가 아니라면 병합하지 않는다.
449
- if (mergeableRows.length - 1 !== mergeableRows[mergeableRows.length - 1] - mergeableRows[0]) return false
450
-
451
- // 선택한 셀이 들어있는 열
452
- let mergeableColumns: number[] = []
453
- cells.forEach(cell => {
454
- let column = this.getRowColumn(cell).column
455
- if (-1 == mergeableColumns.indexOf(column)) mergeableColumns.push(column)
456
- })
457
-
458
- // 선택한 셀의 열이 연속적인 숫자가 아니라면 병합하지 않는다.
459
- if (mergeableColumns.length - 1 !== mergeableColumns[mergeableColumns.length - 1] - mergeableColumns[0])
460
- return false
461
-
462
- // 병합할 행의 수
463
- let numberOfRows = mergeableRows.length
464
-
465
- // 병합할 열의 수
466
- let numberOfColumns = mergeableColumns.length
467
-
468
- // 선택된 셀의 수
469
- let numberOfCells = cells.length
470
-
471
- // 병합될 조건 검사
472
- // 행과 열의 곱이 셀의 수가 아니거나 셀의 수가 2보다 작은 경우는 병합하지 않는다.
473
- if (numberOfCells !== numberOfRows * numberOfColumns || numberOfCells < 2) return false
474
-
475
- // 선택한 셀들을 index 값이 낮은 것부터 순서대로 재정렬
476
- cells.sort((a, b) => {
477
- return (
478
- this.getRowColumn(a).row * this.columns +
479
- this.getRowColumn(a).column -
480
- (this.getRowColumn(b).row * this.columns + this.getRowColumn(b).column)
481
- )
482
- })
483
-
484
- // 셀을 병합함
485
- let firstCell = cells[0]
486
- firstCell.set({
487
- colspan: numberOfColumns,
488
- rowspan: numberOfRows
489
- })
490
-
491
- // 첫 번째 셀을 제외한 나머지 셀을 true로 지정
492
- for (let i = 1; i < numberOfCells; i++) cells[i].merged = true
493
-
494
- // 병합 후에는 첫 번째 셀을 선택하도록 함
495
- this.root.selected = [firstCell]
496
- }
497
-
498
- splitCells(cells: TableCell[]) {
499
- // 선택한 병합된 셀의 정보를 가져온다.
500
- let firstCellRowColumn = this.getRowColumn(cells[0])
501
- let firstCell = cells[0]
502
- let firstCellIndex = this.components.indexOf(cells[0])
503
- let length = this.components.length
504
- let lastCell = this.components[length - 1] as TableCell
505
- let lastCellRowColumn = this.getRowColumn(lastCell)
506
- let startIndex = length / (lastCellRowColumn.row + 1)
507
-
508
- // 병합된 셀들을 구해서 merged를 false로 설정한다.
509
- // 자식 셀이 갖고 있는 부모 셀의 위치를 초기화 한다.
510
- for (let j = 0; j < firstCell.rowspan; j++) {
511
- let index
512
- let nextCell: TableCell
513
- for (let i = firstCellIndex; i < firstCellIndex + firstCell.colspan; i++) {
514
- index = startIndex * j + i
515
- nextCell = this.components[index] as TableCell
516
- nextCell.merged = false
517
- }
518
- }
519
-
520
- // 첫 번째 셀의 rowspan, colspan = 1로 지정한다.
521
- firstCell.colspan = 1
522
- firstCell.rowspan = 1
523
- }
524
-
525
- deleteRows(cells: TableCell[]) {
526
- // 만약 선택한 셀이 병합된 셀이라면 삭제하지 않는다.
527
- if (cells[0].merged == true) return false
528
- // 먼저 cells 위치의 행을 구한다.
529
- let rows: number[] = []
530
- cells.forEach(cell => {
531
- let row = this.getRowColumn(cell).row
532
- if (-1 == rows.indexOf(row)) rows.push(row)
533
- })
534
- rows.sort((a, b) => {
535
- return a - b
536
- })
537
- rows.reverse()
538
- var heights = this.heights.slice()
539
- rows.forEach(row => {
540
- // rows에서 가로 방향으로 이동하면서 병합된 셀을 찾는다.
541
- let mergedCells = this.findMergedCellByX(row)
542
- // mergedCells.length가 0이면 일반적으로 행을 지운다.
543
- if (mergedCells.length === 0) {
544
- this.remove(this.getCellsByRow(row))
545
- }
546
- // mergedCells.length가 0이 아니면 병합된 셀을 고려하여 행을 지워야 한다.
547
- //
548
- else {
549
- // 삭제할 행에서 병합된 셀을 삭제할 때 해당 셀을 임시로 저장
550
- let temp = []
551
- // 부모 셀을 저장
552
- let superCells = []
553
- // 부모 셀의 인덱스 값을 저장
554
- let superCellIndexes: number[] = []
555
- mergedCells.forEach(cell => {
556
- let col, row, index
557
- col = this.getRowColumn(cell).column
558
- row = this.getRowColumn(cell).row
559
- index = row * this.columns + col + 1
560
- while (index) {
561
- --index
562
- let component = this.components[index] as TableCell
563
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
564
- if (component.rowspan > 1 || component.colspan > 1) {
565
- let spColStart = this.getRowColumn(component).column
566
- let spColEnd = this.getRowColumn(component).column + component.colspan
567
- let spRowStart = this.getRowColumn(component).row
568
- let spRowEnd = this.getRowColumn(component).row + component.rowspan
569
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
570
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
571
- if (-1 == superCellIndexes.indexOf(index)) {
572
- superCellIndexes.push(index)
573
- superCells.push(component)
574
- }
575
- }
576
- }
577
- }
578
- })
579
- superCellIndexes.forEach(index => {
580
- let superCellRow = Math.floor(index / this.columns)
581
- // 지우려는 행이 슈퍼셀을 포함한 경우이면서 슈퍼셀이 마지막 행의 셀이 아닌 경우
582
- // 그리고 슈퍼셀의 rowspan이 1보다 큰 경우
583
- let aCell: TableCell = this.components[index + this.columns] as TableCell
584
- let bCell: TableCell = this.components[index] as TableCell
585
- if (row === superCellRow && superCellRow !== this.rows - 1 && bCell.rowspan > 1) {
586
- aCell.rowspan = bCell.rowspan - 1
587
- aCell.colspan = bCell.colspan
588
- aCell.merged = false
589
- aCell.set('text', bCell.getState('text'))
590
- } else {
591
- bCell.rowspan -= 1
592
- }
593
- })
594
- this.remove(this.getCellsByRow(row))
595
- }
596
- })
597
-
598
- rows.forEach(row => heights.splice(row, 1))
599
-
600
- this.model.rows -= rows.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
601
- this.set('heights', heights)
602
- }
603
-
604
- deleteColumns(cells: TableCell[]) {
605
- // 만약 선택한 셀이 병합된 셀이라면 삭제하지 않는다.
606
- if (cells[0].merged == true) return false
607
- // 먼저 cells 위치의 열을 구한다.
608
- let columns: number[] = []
609
- cells.forEach(cell => {
610
- let column = this.getRowColumn(cell).column
611
- if (-1 == columns.indexOf(column)) columns.push(column)
612
- })
613
- columns.sort((a, b) => {
614
- return a - b
615
- })
616
- columns.reverse()
617
-
618
- columns.forEach(column => {
619
- var widths = this.widths.slice()
620
- // columns에서 세로 방향으로 이동하면서 병합된 셀을 찾는다.
621
- let mergedCells = this.findMergedCellByY(column)
622
- // mergedCells.length가 0이면 일반적으로 열을 지운다.
623
- if (mergedCells.length === 0) {
624
- this.remove(this.getCellsByColumn(column))
625
- }
626
- // mergedCells.length가 0이 아니면 병합된 셀을 고려하여 열을 지워야 한다.
627
- else {
628
- // 삭제할 열에서 병합된 셀을 삭제할 때 해당 셀을 임시로 저장
629
- let temp = []
630
- // 부모 셀을 저장
631
- let superCells = []
632
- // 부모 셀의 인덱스를 저장
633
- let superCellIndexes: number[] = []
634
- mergedCells.forEach(cell => {
635
- let col, row, index
636
- col = this.getRowColumn(cell).column
637
- row = this.getRowColumn(cell).row
638
- index = row * this.columns + col + 1
639
- while (index) {
640
- --index
641
- let component = this.components[index] as TableCell
642
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
643
- if (component.rowspan > 1 || component.colspan > 1) {
644
- let spColStart = this.getRowColumn(component).column
645
- let spColEnd = this.getRowColumn(component).column + component.colspan
646
- let spRowStart = this.getRowColumn(component).row
647
- let spRowEnd = this.getRowColumn(component).row + component.rowspan
648
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
649
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
650
- if (-1 == superCellIndexes.indexOf(index)) {
651
- superCellIndexes.push(index)
652
- superCells.push(component)
653
- }
654
- }
655
- }
656
- }
657
- })
658
- superCellIndexes.forEach(index => {
659
- let superCellColumn = index % this.columns
660
-
661
- let aCell: TableCell = this.components[index + 1] as TableCell
662
- let bCell: TableCell = this.components[index] as TableCell
663
- // 지우려는 열이 슈퍼셀을 포함한 경우이면서 슈퍼셀이 마지막 열의 셀이 아닌 경우
664
- // 그리고 슈퍼셀의 colspan이 1보다 큰 경우
665
- if (column === superCellColumn && superCellColumn !== this.columns - 1 && bCell.colspan > 1) {
666
- aCell.rowspan = bCell.rowspan
667
- aCell.colspan = bCell.colspan - 1
668
- aCell.merged = false
669
- aCell.set('text', bCell.getState('text'))
670
- } else {
671
- bCell.colspan -= 1
672
- }
673
- })
674
- this.remove(this.getCellsByColumn(column))
675
- }
676
- widths.splice(column, 1)
677
- this.model.columns -= 1 // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
678
- this.set('widths', widths)
679
- })
680
- }
681
-
682
- insertCellsAbove(cells: TableCell[]) {
683
- // 먼저 cells 위치의 행을 구한다.
684
- let rows: number[] = []
685
- cells.forEach(cell => {
686
- let row = this.getRowColumn(cell).row
687
- if (-1 == rows.indexOf(row)) rows.push(row)
688
- })
689
- rows.sort((a, b) => {
690
- return a - b
691
- })
692
- rows.reverse()
693
- // 행 2개 이상은 추가 안함. 임시로 막아놓음
694
- if (rows.length >= 2) return false
695
- let insertionRowPosition = rows[0]
696
- let newbieRowHeights: number[] = []
697
- let newbieCells: TableCell[] = []
698
- rows.forEach(row => {
699
- // rows에서 가로 방향으로 이동하면서 병합된 셀을 찾는다.
700
- let mergedCells = this.findMergedCellByX(row)
701
- // mergedCells.length가 0이면 일반적으로 행을 위에 추가한다.
702
- if (mergedCells.length === 0) {
703
- for (let i = 0; i < this.columns; i++)
704
- newbieCells.push(buildCopiedCell(this.components[row * this.columns + i].model, this.app))
705
- newbieRowHeights.push(this.heights[row])
706
-
707
- newbieCells.reverse().forEach(cell => {
708
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
709
- })
710
-
711
- let heights = this.heights.slice()
712
- heights.splice(insertionRowPosition, 0, ...newbieRowHeights)
713
- this.set('heights', heights)
714
-
715
- this.model.rows += rows.length
716
-
717
- this.clearCache()
718
- }
719
- // mergedCells.length가 0이 아니면 병합된 셀을 고려하여 행을 추가해야 한다.
720
- else {
721
- // 선택한 행이 2개 이상 있고 그 중에 병합된 셀이 적어도 한 개라도 있으면
722
- // 병합된 셀이 포함된 행의 추가는 무시한다. 임시방편으로 막아놈
723
- if (rows.length > 1) return false
724
- // 추가할 행에서 병합된 셀을 추가할 때 해당 셀을 임시로 저장
725
- let temp = []
726
- // 부모 셀을 저장
727
- let superCells = []
728
- // 부모 셀의 인덱스 값을 저장
729
- let superCellIndexes: number[] = []
730
- mergedCells.forEach(cell => {
731
- let col, row, index
732
- col = this.getRowColumn(cell).column
733
- row = this.getRowColumn(cell).row
734
- index = row * this.columns + col + 1
735
- while (index) {
736
- --index
737
- let component = this.components[index] as TableCell
738
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
739
- if (component.rowspan > 1 || component.colspan > 1) {
740
- let spColStart = this.getRowColumn(component).column
741
- let spColEnd = this.getRowColumn(component).column + component.colspan
742
- let spRowStart = this.getRowColumn(component).row
743
- let spRowEnd = this.getRowColumn(component).row + component.rowspan
744
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
745
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
746
- if (-1 == superCellIndexes.indexOf(index)) {
747
- superCellIndexes.push(index)
748
- superCells.push(component)
749
- }
750
- }
751
- }
752
- }
753
- })
754
- superCellIndexes.forEach(index => {
755
- // 추가하려는 셀은 일반 셀인데 그 위치에 다른 병합된 셀이 있는 문제로 임시로 막아 놓음. 수정해야함
756
- if (superCellIndexes.length >= 2) return false
757
- let superCellRow = Math.floor(index / this.columns)
758
- let cell: TableCell = this.components[index] as TableCell
759
-
760
- let superCellObj = {
761
- rowspan: cell.rowspan,
762
- colspan: cell.colspan,
763
- text: cell.getState('text'),
764
- merged: cell.merged
765
- }
766
-
767
- // 추가하려는 행이 슈퍼셀을 포함한 경우
768
- if (superCellRow === row) {
769
- for (let i = 0; i < this.columns; i++) newbieCells.push(buildNewCell('table-cell', this.app))
770
- newbieRowHeights.push(this.heights[row])
771
-
772
- newbieCells.reverse().forEach(cell => {
773
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
774
- })
775
- let addedCell = this.components[index + this.columns] as TableCell
776
-
777
- addedCell.rowspan = superCellObj.rowspan
778
- addedCell.colspan = superCellObj.colspan
779
- addedCell.set('text', superCellObj.text)
780
- addedCell.merged = superCellObj.merged
781
- } else {
782
- for (let i = 0; i < this.columns; i++)
783
- newbieCells.push(buildCopiedCell(this.components[row * this.columns + i].model, this.app))
784
- newbieRowHeights.push(this.heights[row])
785
-
786
- newbieCells.reverse().forEach(cell => {
787
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
788
- })
789
- cell.rowspan += 1
790
- }
791
- let heights = this.heights.slice()
792
- heights.splice(insertionRowPosition, 0, ...newbieRowHeights)
793
- this.set('heights', heights)
794
-
795
- this.model.rows += rows.length
796
-
797
- this.clearCache()
798
- })
799
- }
800
- })
801
- }
802
-
803
- insertCellsBelow(cells: TableCell[]) {
804
- // 먼저 cells 위치의 행을 구한다.
805
- let rows: number[] = []
806
- cells.forEach(cell => {
807
- let row = this.getRowColumn(cell).row
808
- if (-1 == rows.indexOf(row)) rows.push(row)
809
- })
810
- rows.sort((a, b) => {
811
- return a - b
812
- })
813
- rows.reverse()
814
-
815
- // 행 2개 이상은 추가 안함. 임시로 막아놓음
816
- if (rows.length >= 2) return false
817
- let insertionRowPosition = rows[rows.length - 1] + 1
818
- let newbieRowHeights: number[] = []
819
- let newbieCells: TableCell[] = []
820
-
821
- rows.forEach(row => {
822
- // rows에서 가로 방향으로 이동하면서 병합된 셀을 찾는다.
823
- let mergedCells = this.findMergedCellByX(row)
824
- // mergedCells.length가 0이면 일반적으로 행을 아래에 추가한다.
825
- if (mergedCells.length === 0) {
826
- for (let i = 0; i < this.columns; i++)
827
- newbieCells.push(buildCopiedCell(this.components[row * this.columns + i].model, this.app))
828
- newbieRowHeights.push(this.heights[row])
829
-
830
- newbieCells.reverse().forEach(cell => {
831
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
832
- })
833
-
834
- let heights = this.heights.slice()
835
- heights.splice(insertionRowPosition, 0, ...newbieRowHeights)
836
- this.set('heights', heights)
837
-
838
- this.model.rows += 1
839
-
840
- this.clearCache()
841
- }
842
- // mergedCells.length가 0이 아니면 병합된 셀을 고려하여 행을 추가해야 한다.
843
- else {
844
- // 추가할 행에서 병합된 셀을 추가할 때 해당 셀을 임시로 저장
845
- let temp = []
846
- // 부모 셀을 저장
847
- let superCells: TableCell[] = []
848
- // 부모 셀의 인덱스 값을 저장
849
- let superCellIndexes: number[] = []
850
- mergedCells.forEach(cell => {
851
- let col, row, index
852
- col = this.getRowColumn(cell).column
853
- row = this.getRowColumn(cell).row
854
- index = row * this.columns + col + 1
855
- while (index) {
856
- --index
857
- let component = this.components[index] as TableCell
858
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
859
- if (component.rowspan > 1 || component.colspan > 1) {
860
- let spColStart = this.getRowColumn(component).column
861
- let spColEnd = this.getRowColumn(component).column + component.colspan
862
- let spRowStart = this.getRowColumn(component).row
863
- let spRowEnd = this.getRowColumn(component).row + component.rowspan
864
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
865
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
866
- if (-1 == superCellIndexes.indexOf(index)) {
867
- superCellIndexes.push(index)
868
- superCells.push(component)
869
- }
870
- }
871
- }
872
- }
873
- })
874
- superCellIndexes.forEach(index => {
875
- // 추가하려는 셀은 일반 셀인데 그 위치에 다른 병합된 셀이 있는 문제로 임시로 막아 놓음. 수정해야함
876
- if (superCellIndexes.length >= 2) return false
877
- let superCellRow = Math.floor(index / this.columns)
878
- let cell = this.components[index] as TableCell
879
-
880
- let superCellObj = {
881
- rowspan: cell.rowspan,
882
- colspan: cell.colspan,
883
- text: cell.getState('text'),
884
- merged: cell.merged
885
- }
886
- // 추가하려는 행이 병합된 셀중 마지막 행인 경우
887
- if (superCellRow + superCellObj.rowspan - 1 === row) {
888
- for (let i = 0; i < this.columns; i++) newbieCells.push(buildNewCell('table-cell', this.app))
889
- newbieRowHeights.push(this.heights[row])
890
-
891
- newbieCells.reverse().forEach(cell => {
892
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
893
- })
894
- } else if (superCellRow === row) {
895
- for (let i = 0; i < this.columns; i++)
896
- newbieCells.push(buildCopiedCell(this.components[row * this.columns + i].model, this.app))
897
- newbieRowHeights.push(this.heights[row])
898
-
899
- newbieCells.reverse().forEach(cell => {
900
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
901
- })
902
-
903
- cell.rowspan += 1
904
-
905
- let newbieCell = this.components[index + this.columns] as TableCell
906
- // 슈퍼셀이 복사됐으므로 그 해당 셀을 병합된 셀로 설정한다.
907
- newbieCell.rowspan = 1
908
- newbieCell.colspan = 1
909
- newbieCell.merged = true
910
- newbieCell.set('text', '')
911
- } else {
912
- for (let i = 0; i < this.columns; i++)
913
- newbieCells.push(buildCopiedCell(this.components[row * this.columns + i].model, this.app))
914
- newbieRowHeights.push(this.heights[row])
915
-
916
- newbieCells.reverse().forEach(cell => {
917
- this.insertComponentAt(cell, insertionRowPosition * this.columns)
918
- })
919
- cell.rowspan += 1
920
- }
921
-
922
- let heights = this.heights.slice()
923
- heights.splice(insertionRowPosition, 0, ...newbieRowHeights)
924
- this.set('heights', heights)
925
-
926
- this.model.rows += 1
927
-
928
- this.clearCache()
929
- })
930
- }
931
- })
932
- }
933
-
934
- insertCellsLeft(cells: TableCell[]) {
935
- // 먼저 cells 위치의 열을 구한다.
936
- let columns: number[] = []
937
- cells.forEach(cell => {
938
- let column = this.getRowColumn(cell).column
939
- if (-1 == columns.indexOf(column)) columns.push(column)
940
- })
941
- columns.sort((a, b) => {
942
- return a - b
943
- })
944
- columns.reverse()
945
- // 열 2개 이상은 추가 안함. 임시로 막아놓음
946
- if (columns.length >= 2) return false
947
- let insertionColumnPosition = columns[0]
948
- let newbieColumnWidths: number[] = []
949
- let newbieCells: TableCell[] = []
950
- columns.forEach(column => {
951
- // columns에서 세로 방향으로 이동하면서 병합된 셀을 찾는다.
952
- let mergedCells = this.findMergedCellByY(column)
953
- // mergedCells.length가 0이면 일반적으로 열을 왼쪽에 추가한다.
954
- if (mergedCells.length === 0) {
955
- for (let i = 0; i < this.rows; i++)
956
- newbieCells.push(buildCopiedCell(this.components[column + this.columns * i].model, this.app))
957
- newbieColumnWidths.push(this.widths[column])
958
-
959
- let increasedColumns = this.columns
960
- let index = this.rows
961
- newbieCells.reverse().forEach(cell => {
962
- if (index == 0) {
963
- index = this.rows
964
- increasedColumns++
965
- }
966
-
967
- index--
968
- this.insertComponentAt(cell, insertionColumnPosition + index * increasedColumns)
969
- })
970
-
971
- let widths = this.widths.slice()
972
- this.model.columns += columns.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
973
-
974
- widths.splice(insertionColumnPosition, 0, ...newbieColumnWidths)
975
-
976
- this.set('widths', widths)
977
- }
978
- // mergedCells.length가 0이 아니면 병합된 셀을 고려하여 열을 추가해야 한다.
979
- else {
980
- // 부모 셀을 저장
981
- let superCells = []
982
- // 부모 셀의 인덱스 값을 저장
983
- let superCellIndexes: number[] = []
984
- mergedCells.forEach(cell => {
985
- let col, row, index
986
- col = this.getRowColumn(cell).column
987
- row = this.getRowColumn(cell).row
988
- index = row * this.columns + col + 1
989
- while (index) {
990
- --index
991
- let component = this.components[index] as TableCell
992
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
993
- if (component.rowspan > 1 || component.colspan > 1) {
994
- let spColStart = this.getRowColumn(component).column
995
- let spColEnd = this.getRowColumn(component).column + component.colspan
996
- let spRowStart = this.getRowColumn(component).row
997
- let spRowEnd = this.getRowColumn(component).row + component.rowspan
998
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
999
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
1000
- if (-1 == superCellIndexes.indexOf(index)) {
1001
- superCellIndexes.push(index)
1002
- superCells.push(component)
1003
- }
1004
- }
1005
- }
1006
- }
1007
- })
1008
- superCellIndexes.forEach(index => {
1009
- // 추가하려는 셀은 일반 셀인데 그 위치에 다른 병합된 셀이 있는 문제로 임시로 막아 놓음. 수정해야함
1010
- if (superCellIndexes.length >= 2) return false
1011
- let superCellColumn = index % this.columns
1012
- let cell = this.components[index] as TableCell
1013
-
1014
- let superCellObj = {
1015
- rowspan: cell.rowspan,
1016
- colspan: cell.colspan,
1017
- text: cell.getState('text'),
1018
- merged: cell.merged
1019
- }
1020
- // 추가하려는 열이 슈퍼셀을 포함한 경우
1021
- if (superCellColumn === column) {
1022
- for (let i = 0; i < this.rows; i++) newbieCells.push(buildNewCell('table-cell', this.app))
1023
- newbieColumnWidths.push(this.widths[column])
1024
-
1025
- let increasedColumns = this.columns
1026
- let rowIndex = this.rows
1027
- newbieCells.reverse().forEach(cell => {
1028
- if (rowIndex == 0) {
1029
- rowIndex = this.rows
1030
- increasedColumns++
1031
- }
1032
-
1033
- rowIndex--
1034
- this.insertComponentAt(cell, insertionColumnPosition + rowIndex * increasedColumns)
1035
- })
1036
- } else {
1037
- cell.colspan += 1
1038
- for (let i = 0; i < this.rows; i++)
1039
- newbieCells.push(buildCopiedCell(this.components[column + this.columns * i].model, this.app))
1040
- newbieColumnWidths.push(this.widths[column])
1041
-
1042
- let increasedColumns = this.columns
1043
- let rowIndex = this.rows
1044
- newbieCells.reverse().forEach(cell => {
1045
- if (rowIndex == 0) {
1046
- rowIndex = this.rows
1047
- increasedColumns++
1048
- }
1049
-
1050
- rowIndex--
1051
- this.insertComponentAt(cell, insertionColumnPosition + rowIndex * increasedColumns)
1052
- })
1053
- }
1054
- let widths = this.widths.slice()
1055
- this.model.columns += columns.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
1056
-
1057
- widths.splice(insertionColumnPosition, 0, ...newbieColumnWidths)
1058
-
1059
- this.set('widths', widths)
1060
- })
1061
- }
1062
- })
1063
- }
1064
-
1065
- insertCellsRight(cells: TableCell[]) {
1066
- // 먼저 cells 위치의 열을 구한다.
1067
- let columns: number[] = []
1068
- cells.forEach(cell => {
1069
- let column = this.getRowColumn(cell).column
1070
- if (-1 == columns.indexOf(column)) columns.push(column)
1071
- })
1072
- columns.sort((a, b) => {
1073
- return a - b
1074
- })
1075
- columns.reverse()
1076
- // 열 2개 이상은 추가 안함. 임시로 막아놓음
1077
- if (columns.length >= 2) return false
1078
- let insertionColumnPosition = columns[columns.length - 1] + 1
1079
- let newbieColumnWidths: number[] = []
1080
- let newbieCells: TableCell[] = []
1081
- columns.forEach(column => {
1082
- // columns에서 세로 방향으로 이동하면서 병합된 셀을 찾는다.
1083
- let mergedCells = this.findMergedCellByY(column)
1084
- // mergedCells.length가 0이면 일반적으로 열을 오른쪽에 추가한다.
1085
- if (mergedCells.length === 0) {
1086
- for (let i = 0; i < this.rows; i++)
1087
- newbieCells.push(buildCopiedCell(this.components[column + this.columns * i].model, this.app))
1088
- newbieColumnWidths.push(this.widths[column])
1089
-
1090
- let increasedColumns = this.columns
1091
- let index = this.rows
1092
- newbieCells.reverse().forEach(cell => {
1093
- if (index == 0) {
1094
- index = this.rows
1095
- increasedColumns++
1096
- }
1097
-
1098
- index--
1099
- this.insertComponentAt(cell, insertionColumnPosition + index * increasedColumns)
1100
- })
1101
-
1102
- let widths = this.widths.slice()
1103
- this.model.columns += columns.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
1104
-
1105
- widths.splice(insertionColumnPosition, 0, ...newbieColumnWidths)
1106
-
1107
- this.set('widths', widths)
1108
- }
1109
- // mergedCells.length가 0이 아니면 병합된 셀을 고려하여 열을 추가해야 한다.
1110
- else {
1111
- // 부모 셀을 저장
1112
- let superCells = []
1113
- // 부모 셀의 인덱스 값을 저장
1114
- let superCellIndexes: number[] = []
1115
- mergedCells.forEach(cell => {
1116
- let col, row, index
1117
- col = this.getRowColumn(cell).column
1118
- row = this.getRowColumn(cell).row
1119
- index = row * this.columns + col + 1
1120
- while (index) {
1121
- --index
1122
- let component = this.components[index] as TableCell
1123
- // 슈퍼셀을 찾고 슈퍼셀의 위치에서 rowspan, colspan 거리만큼 이동하면서 cell이 있는지 검증해야함
1124
- if (component.rowspan > 1 || component.colspan > 1) {
1125
- let spColStart = this.getRowColumn(component).column
1126
- let spColEnd = this.getRowColumn(component).column + component.colspan
1127
- let spRowStart = this.getRowColumn(component).row
1128
- let spRowEnd = this.getRowColumn(component).row + component.rowspan
1129
- // 슈퍼셀 영역 안에 자식 셀이 있으면 superCells에 부모셀을 추가
1130
- if (col >= spColStart && col < spColEnd && row >= spRowStart && row < spRowEnd) {
1131
- if (-1 == superCellIndexes.indexOf(index)) {
1132
- superCellIndexes.push(index)
1133
- superCells.push(component)
1134
- }
1135
- }
1136
- }
1137
- }
1138
- })
1139
- superCellIndexes.forEach(index => {
1140
- // 추가하려는 셀은 일반 셀인데 그 위치에 다른 병합된 셀이 있는 문제로 임시로 막아 놓음. 수정해야함
1141
- if (superCellIndexes.length >= 2) return false
1142
- let superCellRow = Math.floor(index / this.columns)
1143
- let superCellColumn = index % this.columns
1144
- let cell = this.components[index] as TableCell
1145
-
1146
- let superCellObj = {
1147
- rowspan: cell.rowspan,
1148
- colspan: cell.colspan,
1149
- text: cell.getState('text'),
1150
- merged: cell.merged
1151
- }
1152
- // 추가하려는 열이 병합된 셀중 마지막 열인 경우
1153
- if (superCellColumn + superCellObj.colspan - 1 === column) {
1154
- for (let i = 0; i < this.rows; i++) newbieCells.push(buildNewCell('table-cell', this.app))
1155
- newbieColumnWidths.push(this.widths[column])
1156
-
1157
- let increasedColumns = this.columns
1158
- let rowIndex = this.rows
1159
- newbieCells.reverse().forEach(cell => {
1160
- if (rowIndex == 0) {
1161
- rowIndex = this.rows
1162
- increasedColumns++
1163
- }
1164
-
1165
- rowIndex--
1166
- this.insertComponentAt(cell, insertionColumnPosition + rowIndex * increasedColumns)
1167
- })
1168
- } else if (superCellColumn === column) {
1169
- cell.colspan += 1
1170
- for (let i = 0; i < this.rows; i++)
1171
- newbieCells.push(buildCopiedCell(this.components[column + this.columns * i].model, this.app))
1172
- newbieColumnWidths.push(this.widths[column])
1173
-
1174
- let increasedColumns = this.columns
1175
- let rowIndex = this.rows
1176
- newbieCells.reverse().forEach(cell => {
1177
- if (rowIndex == 0) {
1178
- rowIndex = this.rows
1179
- increasedColumns++
1180
- }
1181
-
1182
- rowIndex--
1183
- this.insertComponentAt(cell, insertionColumnPosition + rowIndex * increasedColumns)
1184
- })
1185
- // 슈퍼셀이 복사됐으므로 그 해당 셀을 병합된 셀로 설정한다.
1186
- let newbieCell = this.components[index + superCellRow + 1] as TableCell
1187
- newbieCell.rowspan = 1
1188
- newbieCell.colspan = 1
1189
- newbieCell.merged = true
1190
- newbieCell.set('text', '')
1191
- } else {
1192
- cell.colspan += 1
1193
- for (let i = 0; i < this.rows; i++)
1194
- newbieCells.push(buildCopiedCell(this.components[column + this.columns * i].model, this.app))
1195
- newbieColumnWidths.push(this.widths[column])
1196
-
1197
- let increasedColumns = this.columns
1198
- let rowIndex = this.rows
1199
- newbieCells.reverse().forEach(cell => {
1200
- if (rowIndex == 0) {
1201
- rowIndex = this.rows
1202
- increasedColumns++
1203
- }
1204
-
1205
- rowIndex--
1206
- this.insertComponentAt(cell, insertionColumnPosition + rowIndex * increasedColumns)
1207
- })
1208
- }
1209
- let widths = this.widths.slice()
1210
- this.model.columns += columns.length // 고의적으로, change 이벤트가 발생하지 않도록 set(..)을 사용하지 않음.
1211
-
1212
- widths.splice(insertionColumnPosition, 0, ...newbieColumnWidths)
1213
-
1214
- this.set('widths', widths)
1215
- })
1216
- }
1217
- })
1218
- }
1219
-
1220
- distributeHorizontal(cells: TableCell[]) {
1221
- var columns: number[] = []
1222
-
1223
- cells.forEach(cell => {
1224
- let rowcolumn = this.getRowColumn(cell)
1225
-
1226
- if (-1 == columns.indexOf(rowcolumn.column)) columns.push(rowcolumn.column)
1227
- })
1228
-
1229
- var sum = columns.reduce((sum, column) => {
1230
- return sum + this.widths[column]
1231
- }, 0)
1232
-
1233
- var newval = Math.round((sum / columns.length) * 100) / 100
1234
- var widths = this.widths.slice()
1235
- columns.forEach(column => {
1236
- widths[column] = newval
1237
- })
1238
-
1239
- this.set('widths', widths)
1240
- }
1241
-
1242
- distributeVertical(cells: TableCell[]) {
1243
- var rows: number[] = []
1244
-
1245
- cells.forEach((cell: TableCell) => {
1246
- let rowcolumn = this.getRowColumn(cell)
1247
-
1248
- if (-1 == rows.indexOf(rowcolumn.row)) rows.push(rowcolumn.row)
1249
- })
1250
-
1251
- var sum: number = rows.reduce((sum, row) => {
1252
- return sum + this.heights[row]
1253
- }, 0)
1254
-
1255
- var newval = Math.round((sum / rows.length) * 100) / 100
1256
- var heights = this.heights.slice()
1257
- rows.forEach(row => {
1258
- heights[row] = newval
1259
- })
1260
-
1261
- this.set('heights', heights)
1262
- }
1263
-
1264
- toObjectArrayValue(array: any[]) {
1265
- if (!array || array.length === 0) return null
1266
-
1267
- if (!array[0].hasOwnProperty('__field1')) {
1268
- return array
1269
- }
1270
-
1271
- let indexKeyMap: { [key: string]: any } = {}
1272
- let value = []
1273
-
1274
- for (let key in array[0]) {
1275
- indexKeyMap[key] = array[0][key]
1276
- }
1277
-
1278
- for (var i = 1; i < array.length; i++) {
1279
- let object: { [key: string]: any } = {}
1280
- let thisObject = array[i]
1281
- for (let key in indexKeyMap) {
1282
- let k = indexKeyMap[key]
1283
- let v = thisObject[key]
1284
- object[k] = v
1285
- }
1286
-
1287
- value.push(object)
1288
- }
1289
-
1290
- return value
1291
- }
1292
-
1293
- get columns() {
1294
- return Number(this.getState('columns'))
1295
- }
1296
-
1297
- get lefts() {
1298
- return this.components.filter((c, i) => {
1299
- return !(i % this.columns)
1300
- })
1301
- }
1302
-
1303
- get centers() {
1304
- return this.components.filter((c, i) => {
1305
- return i % this.columns && (i + 1) % this.columns
1306
- })
1307
- }
1308
-
1309
- get rights() {
1310
- return this.components.filter((c, i) => {
1311
- return !((i + 1) % this.columns)
1312
- })
1313
- }
1314
-
1315
- get tops() {
1316
- return this.components.slice(0, this.columns)
1317
- }
1318
-
1319
- get middles() {
1320
- return this.components.slice(this.columns, this.columns * (this.rows - 1))
1321
- }
1322
-
1323
- get bottoms() {
1324
- return this.components.slice(this.columns * (this.rows - 1))
1325
- }
1326
-
1327
- get widths_sum(): number {
1328
- var widths = this.widths
1329
- return widths
1330
- ? widths
1331
- .filter((width: number, i: number) => i < this.columns)
1332
- .reduce((sum: number, width: number) => sum + width, 0)
1333
- : this.columns
1334
- }
1335
-
1336
- get heights_sum(): number {
1337
- var heights = this.heights
1338
- return heights
1339
- ? heights
1340
- .filter((height: number, i: number) => i < this.rows)
1341
- .reduce((sum: number, height: number) => sum + height, 0)
1342
- : this.rows
1343
- }
1344
-
1345
- get nature(): ComponentNature {
1346
- return NATURE
1347
- }
1348
-
1349
- get controls(): Control[] {
1350
- var widths = this.widths
1351
- var heights = this.heights
1352
- var inside = this.textBounds
1353
-
1354
- var width_unit = inside!.width / this.widths_sum
1355
- var height_unit = inside!.height / this.heights_sum
1356
-
1357
- var x = inside!.left
1358
- var y = inside!.top
1359
-
1360
- var controls: Control[] = []
1361
-
1362
- widths.slice(0, this.columns - 1).forEach((width: number) => {
1363
- x += width * width_unit
1364
- controls.push({
1365
- x: x,
1366
- y: inside!.top,
1367
- handler: columnControlHandler
1368
- })
1369
- })
1370
-
1371
- heights.slice(0, this.rows - 1).forEach((height: number) => {
1372
- y += height * height_unit
1373
- controls.push({
1374
- x: inside!.left,
1375
- y: y,
1376
- handler: rowControlHandler
1377
- })
1378
- })
1379
-
1380
- return controls
1381
- }
1382
-
1383
- onchange(after: State, before: State) {
1384
- if ('rows' in after || 'columns' in after) {
1385
- let { rows, columns } = this
1386
-
1387
- this.buildCells(
1388
- rows,
1389
- columns,
1390
- 'rows' in before ? before.rows : rows,
1391
- 'columns' in before ? before.columns : columns
1392
- )
1393
- }
1394
-
1395
- if ('data' in after) {
1396
- this.setCellsData()
1397
- }
1398
- }
1399
-
1400
- get eventMap() {
1401
- return {
1402
- '(self)': {
1403
- '(descendant)': {
1404
- change: this.oncellchanged
1405
- }
1406
- }
1407
- }
1408
- }
1409
-
1410
- reflow() {
1411
- this.reflowing = true
1412
- super.reflow()
1413
- this.reflowing = false
1414
- }
1415
-
1416
- oncellchanged(after: State, before: State, hint: { origin: Component }) {
1417
- if ('dataKey' in after || 'dataIndex' in after) {
1418
- this.setCellsData()
1419
- }
1420
-
1421
- if (!this.reflowing) {
1422
- if ('width' in after) {
1423
- var diff = after.width - before.width
1424
- var index = this.components.indexOf(hint.origin)
1425
-
1426
- if (index !== -1) {
1427
- adjustCellWidth(this, index % this.columns, diff)
1428
- }
1429
- }
1430
-
1431
- if ('height' in after) {
1432
- var diff = after.height - before.height
1433
- var index = this.components.indexOf(hint.origin)
1434
-
1435
- if (index !== -1) {
1436
- index = Math.floor(index / this.columns)
1437
- adjustCellHeight(this, index, diff)
1438
- }
1439
- }
1440
- }
1441
- }
1442
- }
1443
-
1444
- ;['rows', 'columns', 'widths', 'heights', 'widths_sum', 'heights_sum', 'controls'].forEach(getter =>
1445
- Component.memoize(Table.prototype, getter, false)
1446
- )
1447
-
1448
- Component.register('table', Table)