@operato/gantt 8.0.0-alpha.6 → 8.0.0-beta.0
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/CHANGELOG.md +113 -0
- package/dist/src/gantt-chart-controller.d.ts +5 -6
- package/dist/src/gantt-chart-controller.js +92 -37
- package/dist/src/gantt-chart-controller.js.map +1 -1
- package/dist/src/ox-gantt-chart.d.ts +378 -3
- package/dist/src/ox-gantt-chart.js +86 -180
- package/dist/src/ox-gantt-chart.js.map +1 -1
- package/dist/src/ox-gantt-resize-splitter.d.ts +6 -2
- package/dist/src/ox-gantt-resize-splitter.js +70 -39
- package/dist/src/ox-gantt-resize-splitter.js.map +1 -1
- package/dist/src/ox-gantt.js +11 -11
- package/dist/src/ox-gantt.js.map +1 -1
- package/dist/src/ox-resource-chart.js +2 -0
- package/dist/src/ox-resource-chart.js.map +1 -1
- package/dist/src/ox-task-tooltip.d.ts +3 -1
- package/dist/src/ox-task-tooltip.js +36 -11
- package/dist/src/ox-task-tooltip.js.map +1 -1
- package/dist/src/types.d.ts +1 -0
- package/dist/src/types.js.map +1 -1
- package/dist/stories/ox-gantt.stories.js +37 -1
- package/dist/stories/ox-gantt.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -13
- package/src/gantt-chart-controller.ts +100 -34
- package/src/ox-gantt-chart.ts +92 -192
- package/src/ox-gantt-resize-splitter.ts +72 -44
- package/src/ox-gantt.ts +12 -9
- package/src/ox-resource-chart.ts +2 -0
- package/src/ox-task-tooltip.ts +31 -9
- package/src/types.ts +1 -0
- package/stories/ox-gantt.stories.ts +37 -1
- package/themes/calendar-theme.css +3 -1
- package/assets/images/icon-editor-gradient-direction.png +0 -0
- package/assets/images/icon-properties-label.png +0 -0
- package/assets/images/icon-properties-line-type.png +0 -0
- package/assets/images/icon-properties-table.png +0 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@operato/gantt",
|
|
3
3
|
"description": "Webcomponents for gantt chart following open-wc recommendations",
|
|
4
4
|
"author": "heartyoh@hatiolab.com",
|
|
5
|
-
"version": "8.0.0-
|
|
5
|
+
"version": "8.0.0-beta.0",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
7
7
|
"module": "dist/src/index.js",
|
|
8
8
|
"license": "MIT",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@operato/i18n": "^8.0.0-
|
|
46
|
-
"@operato/styles": "^8.0.0-
|
|
47
|
-
"@operato/utils": "^8.0.0-
|
|
45
|
+
"@operato/i18n": "^8.0.0-beta.0",
|
|
46
|
+
"@operato/styles": "^8.0.0-beta.0",
|
|
47
|
+
"@operato/utils": "^8.0.0-beta.0",
|
|
48
48
|
"d3": "^7.8.5",
|
|
49
49
|
"d3-time-format": "^4.1.0",
|
|
50
50
|
"i18next": "^23.11.5",
|
|
@@ -52,18 +52,18 @@
|
|
|
52
52
|
"lodash-es": "^4.17.21"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@custom-elements-manifest/analyzer": "^0.
|
|
55
|
+
"@custom-elements-manifest/analyzer": "^0.10.0",
|
|
56
56
|
"@hatiolab/prettier-config": "^1.0.0",
|
|
57
57
|
"@open-wc/eslint-config": "^12.0.3",
|
|
58
|
-
"@open-wc/testing": "^
|
|
58
|
+
"@open-wc/testing": "^4.0.0",
|
|
59
59
|
"@types/lodash-es": "^4.17.5",
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
61
|
-
"@typescript-eslint/parser": "^
|
|
62
|
-
"@web/dev-server": "^0.
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
61
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
62
|
+
"@web/dev-server": "^0.4.0",
|
|
63
63
|
"@web/dev-server-storybook": "^2.0.1",
|
|
64
|
-
"@web/test-runner": "^0.
|
|
65
|
-
"concurrently": "^
|
|
66
|
-
"eslint": "^
|
|
64
|
+
"@web/test-runner": "^0.19.0",
|
|
65
|
+
"concurrently": "^9.0.0",
|
|
66
|
+
"eslint": "^9.0.0",
|
|
67
67
|
"eslint-config-prettier": "^9.1.0",
|
|
68
68
|
"husky": "^9.0.11",
|
|
69
69
|
"lint-staged": "^15.2.2",
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"prettier --write"
|
|
86
86
|
]
|
|
87
87
|
},
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "c4e9cc245659d050a9ffd66542083a6daad4bcb9"
|
|
89
89
|
}
|
|
@@ -3,19 +3,16 @@ import * as d3 from 'd3'
|
|
|
3
3
|
import { TimeScale, Task, TaskTag } from './types'
|
|
4
4
|
import { OxTaskTooltip } from './ox-task-tooltip'
|
|
5
5
|
import { drawTimeScaleHeader, getScale, getChartWidth } from './draw-time-scale-header'
|
|
6
|
+
import { levelDown, levelUp } from './utils'
|
|
7
|
+
import { GestureEventPinch, GestureEventDoubleTap, GestureEventDrag } from '@operato/utils/gesture-mixin.js'
|
|
6
8
|
|
|
7
9
|
export class GanttChartController implements ReactiveController {
|
|
8
|
-
private host: ReactiveControllerHost & LitElement
|
|
10
|
+
private host: (ReactiveControllerHost & LitElement) | null
|
|
9
11
|
private fromTime: Date
|
|
10
12
|
private toTime: Date
|
|
11
13
|
private totalDays: number
|
|
12
14
|
private _timeScale?: d3.ScaleTime<number, number, never>
|
|
13
15
|
|
|
14
|
-
private touchStartX?: number
|
|
15
|
-
private touchStartY?: number
|
|
16
|
-
private scrollStartX?: number
|
|
17
|
-
private scrollStartY?: number
|
|
18
|
-
|
|
19
16
|
private colorProvider?: (task: Task) => string
|
|
20
17
|
|
|
21
18
|
public baseWidth: number = 30
|
|
@@ -34,6 +31,10 @@ export class GanttChartController implements ReactiveController {
|
|
|
34
31
|
this.host.addController(this)
|
|
35
32
|
}
|
|
36
33
|
|
|
34
|
+
dispose() {
|
|
35
|
+
this.host = null
|
|
36
|
+
}
|
|
37
|
+
|
|
37
38
|
hostConnected() {
|
|
38
39
|
this.updateTimeScale()
|
|
39
40
|
}
|
|
@@ -57,12 +58,12 @@ export class GanttChartController implements ReactiveController {
|
|
|
57
58
|
this.toTime = new Date(toDate)
|
|
58
59
|
this.totalDays = d3.timeDay.count(this.fromTime, d3.timeDay.offset(this.toTime, 1))
|
|
59
60
|
this._timeScale = undefined
|
|
60
|
-
this.host
|
|
61
|
+
this.host?.requestUpdate()
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
setTasks(tasks: Task[]) {
|
|
64
65
|
this.tasks = tasks
|
|
65
|
-
this.host
|
|
66
|
+
this.host?.requestUpdate()
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
updateTimeScale() {
|
|
@@ -93,7 +94,7 @@ export class GanttChartController implements ReactiveController {
|
|
|
93
94
|
.append('marker')
|
|
94
95
|
.attr('id', 'arrow')
|
|
95
96
|
.attr('viewBox', '0 0 10 10')
|
|
96
|
-
.attr('refX', 10)
|
|
97
|
+
.attr('refX', 10)
|
|
97
98
|
.attr('refY', 5)
|
|
98
99
|
.attr('markerWidth', 6)
|
|
99
100
|
.attr('markerHeight', 6)
|
|
@@ -150,14 +151,20 @@ export class GanttChartController implements ReactiveController {
|
|
|
150
151
|
const taskWidth = endX - startX + this.baseWidth / this.getScale()
|
|
151
152
|
const taskY = index * 30 + 7.5
|
|
152
153
|
|
|
153
|
-
const showTooltip = (event: MouseEvent) => {
|
|
154
|
+
const showTooltip = (event: MouseEvent | TouchEvent) => {
|
|
155
|
+
tooltip.hide()
|
|
156
|
+
|
|
157
|
+
const touch = 'touches' in event
|
|
158
|
+
const x = touch ? event.touches[0].clientX : event.clientX
|
|
159
|
+
const y = touch ? event.touches[0].clientY : event.clientY
|
|
160
|
+
|
|
154
161
|
tooltip.title = task.title
|
|
155
162
|
tooltip.startDate = startDate.toISOString().split('T')[0]
|
|
156
163
|
tooltip.endDate = endDate.toISOString().split('T')[0]
|
|
157
164
|
tooltip.progress = task.progress ?? 0
|
|
158
165
|
tooltip.type = task.type
|
|
159
166
|
|
|
160
|
-
tooltip.show(
|
|
167
|
+
tooltip.show(x, y)
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
const hideTooltip = () => {
|
|
@@ -185,15 +192,18 @@ export class GanttChartController implements ReactiveController {
|
|
|
185
192
|
.attr('stroke-width', 1)
|
|
186
193
|
|
|
187
194
|
taskBar
|
|
188
|
-
.on('click',
|
|
195
|
+
.on('click', e => {
|
|
189
196
|
this.selectedTaskId = task.id
|
|
190
197
|
const customEvent = new CustomEvent('task-clicked', {
|
|
191
198
|
detail: { taskId: task.id },
|
|
192
199
|
bubbles: true,
|
|
193
200
|
composed: true
|
|
194
201
|
})
|
|
195
|
-
|
|
196
|
-
|
|
202
|
+
|
|
203
|
+
showTooltip(e)
|
|
204
|
+
|
|
205
|
+
this.host?.dispatchEvent(customEvent)
|
|
206
|
+
this.host?.requestUpdate()
|
|
197
207
|
})
|
|
198
208
|
.on('mouseover', showTooltip)
|
|
199
209
|
.on('mouseout', hideTooltip)
|
|
@@ -209,15 +219,18 @@ export class GanttChartController implements ReactiveController {
|
|
|
209
219
|
.attr('fill', 'lightgreen')
|
|
210
220
|
|
|
211
221
|
progressBar
|
|
212
|
-
.on('click',
|
|
222
|
+
.on('click', e => {
|
|
213
223
|
this.selectedTaskId = task.id
|
|
214
224
|
const customEvent = new CustomEvent('task-clicked', {
|
|
215
225
|
detail: { taskId: task.id },
|
|
216
226
|
bubbles: true,
|
|
217
227
|
composed: true
|
|
218
228
|
})
|
|
219
|
-
|
|
220
|
-
|
|
229
|
+
|
|
230
|
+
showTooltip(e)
|
|
231
|
+
|
|
232
|
+
this.host?.dispatchEvent(customEvent)
|
|
233
|
+
this.host?.requestUpdate()
|
|
221
234
|
})
|
|
222
235
|
.on('mouseover', showTooltip)
|
|
223
236
|
.on('mouseout', hideTooltip)
|
|
@@ -256,7 +269,7 @@ export class GanttChartController implements ReactiveController {
|
|
|
256
269
|
.attr('stroke', 'var(--md-sys-color-on-primary-container, black)')
|
|
257
270
|
.attr('fill', 'none')
|
|
258
271
|
.attr('stroke-width', 1)
|
|
259
|
-
.attr('marker-end', 'url(#arrow)')
|
|
272
|
+
.attr('marker-end', 'url(#arrow)')
|
|
260
273
|
}
|
|
261
274
|
})
|
|
262
275
|
}
|
|
@@ -277,6 +290,8 @@ export class GanttChartController implements ReactiveController {
|
|
|
277
290
|
event.preventDefault()
|
|
278
291
|
event.stopPropagation()
|
|
279
292
|
|
|
293
|
+
const { offsetHeight } = container
|
|
294
|
+
|
|
280
295
|
const deltaModeFactor =
|
|
281
296
|
event.deltaMode === WheelEvent.DOM_DELTA_LINE
|
|
282
297
|
? 16
|
|
@@ -288,7 +303,8 @@ export class GanttChartController implements ReactiveController {
|
|
|
288
303
|
|
|
289
304
|
// 가로 스크롤 및 세로 스크롤 모두 처리
|
|
290
305
|
container.scrollLeft += deltaX
|
|
291
|
-
container.scrollTop += deltaY
|
|
306
|
+
// container.scrollTop += deltaY
|
|
307
|
+
container.scrollTop = Math.min(this.tasks.length * 30 - (offsetHeight - 40), container.scrollTop + deltaY)
|
|
292
308
|
|
|
293
309
|
const customEvent = new CustomEvent('scroll', {
|
|
294
310
|
detail: {
|
|
@@ -299,28 +315,78 @@ export class GanttChartController implements ReactiveController {
|
|
|
299
315
|
composed: true
|
|
300
316
|
})
|
|
301
317
|
|
|
302
|
-
this.host
|
|
318
|
+
this.host?.dispatchEvent(customEvent)
|
|
303
319
|
}
|
|
304
320
|
|
|
305
|
-
|
|
306
|
-
event.
|
|
321
|
+
handlePinchForBody = (event: GestureEventPinch) => {
|
|
322
|
+
const { scale } = event.detail
|
|
323
|
+
|
|
324
|
+
this.baseWidth *= scale
|
|
325
|
+
|
|
326
|
+
if (this.baseWidth > 40) {
|
|
327
|
+
if (this.level === 'week-day') {
|
|
328
|
+
this.baseWidth = 40
|
|
329
|
+
} else {
|
|
330
|
+
this.level = levelDown(this.level)
|
|
331
|
+
this.baseWidth = 30
|
|
332
|
+
}
|
|
333
|
+
} else if (this.baseWidth < 30) {
|
|
334
|
+
if (this.level === 'year-quarter') {
|
|
335
|
+
this.baseWidth = 30
|
|
336
|
+
}
|
|
337
|
+
}
|
|
307
338
|
|
|
308
|
-
this.
|
|
309
|
-
|
|
339
|
+
if (this.baseWidth < 20) {
|
|
340
|
+
this.level = levelUp(this.level)
|
|
341
|
+
this.baseWidth = 30
|
|
342
|
+
}
|
|
310
343
|
|
|
311
|
-
this.
|
|
312
|
-
this.
|
|
344
|
+
this.updateTimeScale()
|
|
345
|
+
this.host?.requestUpdate()
|
|
346
|
+
|
|
347
|
+
const customEvent = new CustomEvent('timescale-changed', {
|
|
348
|
+
detail: {
|
|
349
|
+
baseWidth: this.baseWidth,
|
|
350
|
+
level: this.level
|
|
351
|
+
},
|
|
352
|
+
bubbles: true,
|
|
353
|
+
composed: true
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
this.host?.dispatchEvent(customEvent)
|
|
313
357
|
}
|
|
314
358
|
|
|
315
|
-
|
|
316
|
-
const
|
|
317
|
-
|
|
359
|
+
handleDoubleTapForBody = (event: GestureEventDoubleTap) => {
|
|
360
|
+
const container = (this.host as any).container
|
|
361
|
+
|
|
362
|
+
container.scrollLeft = 0
|
|
363
|
+
container.scrollTop = 0
|
|
364
|
+
|
|
365
|
+
this.baseWidth = 30
|
|
366
|
+
this.level = 'week-day'
|
|
367
|
+
|
|
368
|
+
this.updateTimeScale()
|
|
369
|
+
this.host?.requestUpdate()
|
|
370
|
+
|
|
371
|
+
const customEvent = new CustomEvent('timescale-changed', {
|
|
372
|
+
detail: {
|
|
373
|
+
baseWidth: this.baseWidth,
|
|
374
|
+
level: this.level
|
|
375
|
+
},
|
|
376
|
+
bubbles: true,
|
|
377
|
+
composed: true
|
|
378
|
+
})
|
|
379
|
+
|
|
380
|
+
this.host?.dispatchEvent(customEvent)
|
|
381
|
+
}
|
|
318
382
|
|
|
319
|
-
|
|
320
|
-
const deltaY =
|
|
383
|
+
handleDragForBody = (event: GestureEventDrag) => {
|
|
384
|
+
const { deltaX: dx, deltaY: dy } = event.detail
|
|
385
|
+
const container = (this.host as any).container
|
|
386
|
+
const { offsetHeight } = container
|
|
321
387
|
|
|
322
|
-
container.scrollLeft
|
|
323
|
-
container.scrollTop = this.
|
|
388
|
+
container.scrollLeft -= dx
|
|
389
|
+
container.scrollTop = Math.min(this.tasks.length * 30 - (offsetHeight - 40), container.scrollTop - dy)
|
|
324
390
|
|
|
325
391
|
const customEvent = new CustomEvent('scroll', {
|
|
326
392
|
detail: {
|
|
@@ -331,6 +397,6 @@ export class GanttChartController implements ReactiveController {
|
|
|
331
397
|
composed: true
|
|
332
398
|
})
|
|
333
399
|
|
|
334
|
-
this.host
|
|
400
|
+
this.host?.dispatchEvent(customEvent)
|
|
335
401
|
}
|
|
336
402
|
}
|