@operato/gantt 8.0.0-alpha.35 → 8.0.0-alpha.36
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 +9 -0
- package/dist/src/gantt-chart-controller.d.ts +4 -12
- package/dist/src/gantt-chart-controller.js +72 -150
- package/dist/src/gantt-chart-controller.js.map +1 -1
- package/dist/src/ox-gantt-chart.d.ts +368 -2
- package/dist/src/ox-gantt-chart.js +40 -78
- package/dist/src/ox-gantt-chart.js.map +1 -1
- package/dist/stories/ox-gantt.stories.js +1 -1
- package/dist/stories/ox-gantt.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/gantt-chart-controller.ts +70 -152
- package/src/ox-gantt-chart.ts +36 -77
- package/stories/ox-gantt.stories.ts +1 -1
|
@@ -4,6 +4,7 @@ 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
6
|
import { levelDown, levelUp } from './utils'
|
|
7
|
+
import { GestureEventPinch, GestureEventDoubleTap, GestureEventDrag } from '@operato/utils/gesture-mixin.js'
|
|
7
8
|
|
|
8
9
|
export class GanttChartController implements ReactiveController {
|
|
9
10
|
private host: (ReactiveControllerHost & LitElement) | null
|
|
@@ -12,15 +13,6 @@ export class GanttChartController implements ReactiveController {
|
|
|
12
13
|
private totalDays: number
|
|
13
14
|
private _timeScale?: d3.ScaleTime<number, number, never>
|
|
14
15
|
|
|
15
|
-
private touchStartX: number | null = null
|
|
16
|
-
private touchStartY: number | null = null
|
|
17
|
-
private scrollStartX: number | null = null
|
|
18
|
-
private scrollStartY: number | null = null
|
|
19
|
-
private lastTouchDistance?: number | null
|
|
20
|
-
private draggingThreshold: number = 20
|
|
21
|
-
private dragging: boolean = false
|
|
22
|
-
private readyDragging: boolean = false
|
|
23
|
-
|
|
24
16
|
private colorProvider?: (task: Task) => string
|
|
25
17
|
|
|
26
18
|
public baseWidth: number = 30
|
|
@@ -200,17 +192,7 @@ export class GanttChartController implements ReactiveController {
|
|
|
200
192
|
.attr('stroke-width', 1)
|
|
201
193
|
|
|
202
194
|
taskBar
|
|
203
|
-
.on('click',
|
|
204
|
-
this.selectedTaskId = task.id
|
|
205
|
-
const customEvent = new CustomEvent('task-clicked', {
|
|
206
|
-
detail: { taskId: task.id },
|
|
207
|
-
bubbles: true,
|
|
208
|
-
composed: true
|
|
209
|
-
})
|
|
210
|
-
this.host?.dispatchEvent(customEvent)
|
|
211
|
-
this.host?.requestUpdate()
|
|
212
|
-
})
|
|
213
|
-
.on('touchstart', e => {
|
|
195
|
+
.on('click', e => {
|
|
214
196
|
this.selectedTaskId = task.id
|
|
215
197
|
const customEvent = new CustomEvent('task-clicked', {
|
|
216
198
|
detail: { taskId: task.id },
|
|
@@ -237,17 +219,7 @@ export class GanttChartController implements ReactiveController {
|
|
|
237
219
|
.attr('fill', 'lightgreen')
|
|
238
220
|
|
|
239
221
|
progressBar
|
|
240
|
-
.on('click',
|
|
241
|
-
this.selectedTaskId = task.id
|
|
242
|
-
const customEvent = new CustomEvent('task-clicked', {
|
|
243
|
-
detail: { taskId: task.id },
|
|
244
|
-
bubbles: true,
|
|
245
|
-
composed: true
|
|
246
|
-
})
|
|
247
|
-
this.host?.dispatchEvent(customEvent)
|
|
248
|
-
this.host?.requestUpdate()
|
|
249
|
-
})
|
|
250
|
-
.on('touchstart', e => {
|
|
222
|
+
.on('click', e => {
|
|
251
223
|
this.selectedTaskId = task.id
|
|
252
224
|
const customEvent = new CustomEvent('task-clicked', {
|
|
253
225
|
detail: { taskId: task.id },
|
|
@@ -318,6 +290,8 @@ export class GanttChartController implements ReactiveController {
|
|
|
318
290
|
event.preventDefault()
|
|
319
291
|
event.stopPropagation()
|
|
320
292
|
|
|
293
|
+
const { offsetHeight } = container
|
|
294
|
+
|
|
321
295
|
const deltaModeFactor =
|
|
322
296
|
event.deltaMode === WheelEvent.DOM_DELTA_LINE
|
|
323
297
|
? 16
|
|
@@ -329,7 +303,8 @@ export class GanttChartController implements ReactiveController {
|
|
|
329
303
|
|
|
330
304
|
// 가로 스크롤 및 세로 스크롤 모두 처리
|
|
331
305
|
container.scrollLeft += deltaX
|
|
332
|
-
container.scrollTop += deltaY
|
|
306
|
+
// container.scrollTop += deltaY
|
|
307
|
+
container.scrollTop = Math.min(this.tasks.length * 30 - (offsetHeight - 40), container.scrollTop + deltaY)
|
|
333
308
|
|
|
334
309
|
const customEvent = new CustomEvent('scroll', {
|
|
335
310
|
detail: {
|
|
@@ -343,142 +318,85 @@ export class GanttChartController implements ReactiveController {
|
|
|
343
318
|
this.host?.dispatchEvent(customEvent)
|
|
344
319
|
}
|
|
345
320
|
|
|
346
|
-
|
|
347
|
-
event.
|
|
348
|
-
event.stopPropagation()
|
|
349
|
-
|
|
350
|
-
const touch = 'touches' in event
|
|
351
|
-
const x = touch ? event.touches[0].clientX : event.clientX
|
|
352
|
-
const y = touch ? event.touches[0].clientY : event.clientY
|
|
321
|
+
handlePinchForBody = (event: GestureEventPinch) => {
|
|
322
|
+
const { scale } = event.detail
|
|
353
323
|
|
|
354
|
-
this.
|
|
355
|
-
this.readyDragging = true
|
|
356
|
-
|
|
357
|
-
if (touch && event.touches.length === 2) {
|
|
358
|
-
this.lastTouchDistance = this.getTouchDistance(event.touches)
|
|
359
|
-
} else {
|
|
360
|
-
this.touchStartX = x
|
|
361
|
-
this.touchStartY = y
|
|
324
|
+
this.baseWidth *= scale
|
|
362
325
|
|
|
363
|
-
|
|
364
|
-
this.
|
|
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
|
+
}
|
|
365
337
|
}
|
|
366
|
-
}
|
|
367
338
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
339
|
+
if (this.baseWidth < 20) {
|
|
340
|
+
this.level = levelUp(this.level)
|
|
341
|
+
this.baseWidth = 30
|
|
371
342
|
}
|
|
372
343
|
|
|
373
|
-
|
|
374
|
-
|
|
344
|
+
this.updateTimeScale()
|
|
345
|
+
this.host?.requestUpdate()
|
|
375
346
|
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
let zoomFactor = currentDistance / this.lastTouchDistance!
|
|
385
|
-
zoomFactor = 1 + (zoomFactor - 1) * zoomSensitivity
|
|
386
|
-
|
|
387
|
-
this.baseWidth *= zoomFactor
|
|
388
|
-
|
|
389
|
-
if (this.baseWidth > 40) {
|
|
390
|
-
if (this.level === 'week-day') {
|
|
391
|
-
this.baseWidth = 40
|
|
392
|
-
} else {
|
|
393
|
-
this.level = levelDown(this.level)
|
|
394
|
-
this.baseWidth = 30
|
|
395
|
-
}
|
|
396
|
-
} else if (this.baseWidth < 30) {
|
|
397
|
-
if (this.level === 'year-quarter') {
|
|
398
|
-
this.baseWidth = 30
|
|
399
|
-
}
|
|
400
|
-
}
|
|
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
|
+
})
|
|
401
355
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
this.baseWidth = 30
|
|
405
|
-
}
|
|
356
|
+
this.host?.dispatchEvent(customEvent)
|
|
357
|
+
}
|
|
406
358
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
this.host?.requestUpdate()
|
|
410
|
-
|
|
411
|
-
const customEvent = new CustomEvent('timescale-changed', {
|
|
412
|
-
detail: {
|
|
413
|
-
baseWidth: this.baseWidth,
|
|
414
|
-
level: this.level
|
|
415
|
-
},
|
|
416
|
-
bubbles: true,
|
|
417
|
-
composed: true
|
|
418
|
-
})
|
|
419
|
-
this.host?.dispatchEvent(customEvent)
|
|
420
|
-
} else if (this.touchStartX !== null) {
|
|
421
|
-
const dx = this.touchStartX! - x
|
|
422
|
-
const dy = this.touchStartY! - y
|
|
423
|
-
|
|
424
|
-
if (!this.dragging && this.readyDragging) {
|
|
425
|
-
if (Math.sqrt(dx * dx + dy * dy) > this.draggingThreshold) {
|
|
426
|
-
this.dragging = true
|
|
427
|
-
this.readyDragging = false
|
|
428
|
-
} else {
|
|
429
|
-
return
|
|
430
|
-
}
|
|
431
|
-
}
|
|
359
|
+
handleDoubleTapForBody = (event: GestureEventDoubleTap) => {
|
|
360
|
+
const container = (this.host as any).container
|
|
432
361
|
|
|
433
|
-
|
|
434
|
-
|
|
362
|
+
container.scrollLeft = 0
|
|
363
|
+
container.scrollTop = 0
|
|
435
364
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
scrollLeft: container.scrollLeft,
|
|
439
|
-
scrollTop: container.scrollTop
|
|
440
|
-
},
|
|
441
|
-
bubbles: true,
|
|
442
|
-
composed: true
|
|
443
|
-
})
|
|
365
|
+
this.baseWidth = 30
|
|
366
|
+
this.level = 'week-day'
|
|
444
367
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
368
|
+
this.updateTimeScale()
|
|
369
|
+
this.host?.requestUpdate()
|
|
448
370
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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
|
+
})
|
|
453
379
|
|
|
454
|
-
|
|
455
|
-
|
|
380
|
+
this.host?.dispatchEvent(customEvent)
|
|
381
|
+
}
|
|
456
382
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
this.host?.dispatchEvent(
|
|
462
|
-
new CustomEvent('date-range-cleared', {
|
|
463
|
-
bubbles: true,
|
|
464
|
-
composed: true
|
|
465
|
-
})
|
|
466
|
-
)
|
|
467
|
-
} else {
|
|
468
|
-
this.dragging = false
|
|
469
|
-
this.readyDragging = false
|
|
470
|
-
}
|
|
383
|
+
handleDragForBody = (event: GestureEventDrag) => {
|
|
384
|
+
const { deltaX: dx, deltaY: dy } = event.detail
|
|
385
|
+
const container = (this.host as any).container
|
|
386
|
+
const { offsetHeight } = container
|
|
471
387
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
this.scrollStartX = null
|
|
475
|
-
this.scrollStartY = null
|
|
476
|
-
}
|
|
477
|
-
}
|
|
388
|
+
container.scrollLeft -= dx
|
|
389
|
+
container.scrollTop = Math.min(this.tasks.length * 30 - (offsetHeight - 40), container.scrollTop - dy)
|
|
478
390
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
391
|
+
const customEvent = new CustomEvent('scroll', {
|
|
392
|
+
detail: {
|
|
393
|
+
scrollLeft: container.scrollLeft,
|
|
394
|
+
scrollTop: container.scrollTop
|
|
395
|
+
},
|
|
396
|
+
bubbles: true,
|
|
397
|
+
composed: true
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
this.host?.dispatchEvent(customEvent)
|
|
483
401
|
}
|
|
484
402
|
}
|
package/src/ox-gantt-chart.ts
CHANGED
|
@@ -13,8 +13,10 @@ import { Task, TimeScale } from './types.js'
|
|
|
13
13
|
import { levelDown, levelUp } from './utils'
|
|
14
14
|
import { OxTaskTooltip } from './ox-task-tooltip.js'
|
|
15
15
|
|
|
16
|
+
import { gesture } from '@operato/utils/gesture-mixin.js'
|
|
17
|
+
|
|
16
18
|
@customElement('ox-gantt-chart')
|
|
17
|
-
export class OxGanttChart extends LitElement {
|
|
19
|
+
export class OxGanttChart extends gesture(LitElement) {
|
|
18
20
|
static styles = [
|
|
19
21
|
MDTypeScaleStyles,
|
|
20
22
|
ScrollbarStyles,
|
|
@@ -31,6 +33,7 @@ export class OxGanttChart extends LitElement {
|
|
|
31
33
|
overflow-x: auto;
|
|
32
34
|
overflow-y: hidden;
|
|
33
35
|
overscroll-behavior: none;
|
|
36
|
+
touch-action: none;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
svg {
|
|
@@ -91,12 +94,7 @@ export class OxGanttChart extends LitElement {
|
|
|
91
94
|
@query('[chart-container]') container!: HTMLDivElement
|
|
92
95
|
@query('ox-task-tooltip') tooltip!: OxTaskTooltip
|
|
93
96
|
|
|
94
|
-
private ganttChartController
|
|
95
|
-
|
|
96
|
-
constructor() {
|
|
97
|
-
super()
|
|
98
|
-
this.ganttChartController = new GanttChartController(this, this.fromDate, this.toDate, this.axisScale)
|
|
99
|
-
}
|
|
97
|
+
private ganttChartController!: GanttChartController
|
|
100
98
|
|
|
101
99
|
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
|
102
100
|
this.initHeaderGestureHandlers()
|
|
@@ -104,9 +102,22 @@ export class OxGanttChart extends LitElement {
|
|
|
104
102
|
this.addEventListener('date-range-cleared', e => this.clearSelection())
|
|
105
103
|
}
|
|
106
104
|
|
|
105
|
+
connectedCallback(): void {
|
|
106
|
+
super.connectedCallback()
|
|
107
|
+
this.ganttChartController = new GanttChartController(this, this.fromDate, this.toDate, this.axisScale)
|
|
108
|
+
|
|
109
|
+
this.addEventListener('pinch', this.ganttChartController.handlePinchForBody as EventListener)
|
|
110
|
+
this.addEventListener('drag', this.ganttChartController.handleDragForBody as EventListener)
|
|
111
|
+
this.addEventListener('doubletap', this.ganttChartController.handleDoubleTapForBody as EventListener)
|
|
112
|
+
}
|
|
113
|
+
|
|
107
114
|
disconnectedCallback(): void {
|
|
108
115
|
super.disconnectedCallback()
|
|
109
116
|
|
|
117
|
+
this.removeEventListener('pinch', this.ganttChartController.handlePinchForBody as EventListener)
|
|
118
|
+
this.removeEventListener('drag', this.ganttChartController.handleDragForBody as EventListener)
|
|
119
|
+
this.removeEventListener('doubletap', this.ganttChartController.handleDoubleTapForBody as EventListener)
|
|
120
|
+
|
|
110
121
|
this.ganttChartController.dispose()
|
|
111
122
|
}
|
|
112
123
|
|
|
@@ -116,8 +127,9 @@ export class OxGanttChart extends LitElement {
|
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
if (changedProperties.has('tasks')) {
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
130
|
+
const flattenTasks = this.flattenTasks(this.tasks)
|
|
131
|
+
this.ganttChartController.setTasks(flattenTasks)
|
|
132
|
+
this.svgBody.style.height = Math.max(flattenTasks.length * 30, 2000) + 'px'
|
|
121
133
|
}
|
|
122
134
|
|
|
123
135
|
if (changedProperties.has('locale')) {
|
|
@@ -143,16 +155,7 @@ export class OxGanttChart extends LitElement {
|
|
|
143
155
|
|
|
144
156
|
render() {
|
|
145
157
|
return html`
|
|
146
|
-
<div
|
|
147
|
-
chart-container
|
|
148
|
-
@wheel=${(e: WheelEvent) => this.ganttChartController.handleWheelForBody(e, this.container)}
|
|
149
|
-
@mousedown=${(e: MouseEvent) => this.ganttChartController.handleTouchStartForBody(e, this.container)}
|
|
150
|
-
@mousemove=${(e: MouseEvent) => this.ganttChartController.handleTouchMoveForBody(e, this.container)}
|
|
151
|
-
@mouseup=${(e: MouseEvent) => this.ganttChartController.handleTouchEndForBody(e)}
|
|
152
|
-
@touchstart=${(e: TouchEvent) => this.ganttChartController.handleTouchStartForBody(e, this.container)}
|
|
153
|
-
@touchmove=${(e: TouchEvent) => this.ganttChartController.handleTouchMoveForBody(e, this.container)}
|
|
154
|
-
@touchend=${(e: TouchEvent) => this.ganttChartController.handleTouchEndForBody(e)}
|
|
155
|
-
>
|
|
158
|
+
<div chart-container @wheel=${(e: WheelEvent) => this.ganttChartController.handleWheelForBody(e, this.container)}>
|
|
156
159
|
<svg
|
|
157
160
|
header
|
|
158
161
|
@date-range-selected=${(e: CustomEvent) => this.handleDateRangeSelected(e)}
|
|
@@ -279,88 +282,44 @@ export class OxGanttChart extends LitElement {
|
|
|
279
282
|
initHeaderGestureHandlers() {
|
|
280
283
|
const header = d3.select(this.svgHeader)
|
|
281
284
|
|
|
282
|
-
let isDragging = false
|
|
283
285
|
let startX: number | null = null
|
|
284
286
|
|
|
285
|
-
const
|
|
287
|
+
const handlePointerDown = (event: PointerEvent) => {
|
|
286
288
|
event.preventDefault()
|
|
287
289
|
event.stopPropagation()
|
|
288
290
|
|
|
289
|
-
isDragging = true
|
|
290
|
-
const touch = event.touches[0]
|
|
291
291
|
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
292
|
-
startX =
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const handleTouchMove = (event: TouchEvent) => {
|
|
296
|
-
event.preventDefault()
|
|
297
|
-
event.stopPropagation()
|
|
292
|
+
startX = event.clientX - containerOffsetX
|
|
298
293
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
302
|
-
const currentX = touch.clientX - containerOffsetX
|
|
303
|
-
this.highlightSelection(startX, currentX)
|
|
304
|
-
}
|
|
294
|
+
window.addEventListener('pointermove', handlePointerMove)
|
|
295
|
+
window.addEventListener('pointerup', handlePointerUp)
|
|
305
296
|
}
|
|
306
297
|
|
|
307
|
-
const
|
|
298
|
+
const handlePointerMove = (event: PointerEvent) => {
|
|
308
299
|
event.preventDefault()
|
|
309
300
|
event.stopPropagation()
|
|
310
301
|
|
|
311
|
-
if (!isDragging || startX === null) {
|
|
312
|
-
const touch = event.changedTouches[0]
|
|
313
|
-
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
314
|
-
const clickX = touch.clientX - containerOffsetX
|
|
315
|
-
this.finalizeSelection(clickX, clickX)
|
|
316
|
-
return
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const touch = event.changedTouches[0]
|
|
320
302
|
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
321
|
-
const
|
|
322
|
-
this.finalizeSelection(startX, endX)
|
|
323
|
-
|
|
324
|
-
isDragging = false
|
|
325
|
-
startX = null
|
|
326
|
-
}
|
|
303
|
+
const currentX = event.clientX - containerOffsetX
|
|
327
304
|
|
|
328
|
-
|
|
329
|
-
isDragging = true
|
|
330
|
-
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
331
|
-
startX = event.clientX - containerOffsetX
|
|
305
|
+
this.highlightSelection(startX!, currentX)
|
|
332
306
|
}
|
|
333
307
|
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
338
|
-
const currentX = event.clientX - containerOffsetX
|
|
339
|
-
this.highlightSelection(startX, currentX)
|
|
340
|
-
}
|
|
308
|
+
const handlePointerUp = (event: PointerEvent) => {
|
|
309
|
+
event.preventDefault()
|
|
310
|
+
event.stopPropagation()
|
|
341
311
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
345
|
-
const clickX = event.clientX - containerOffsetX
|
|
346
|
-
this.finalizeSelection(clickX, clickX)
|
|
347
|
-
return
|
|
348
|
-
}
|
|
312
|
+
window.removeEventListener('pointermove', handlePointerMove)
|
|
313
|
+
window.removeEventListener('pointerup', handlePointerUp)
|
|
349
314
|
|
|
350
315
|
const containerOffsetX = header.node()!.getBoundingClientRect().left
|
|
351
316
|
const endX = event.clientX - containerOffsetX
|
|
352
|
-
this.finalizeSelection(startX
|
|
317
|
+
this.finalizeSelection(startX!, endX)
|
|
353
318
|
|
|
354
|
-
isDragging = false
|
|
355
319
|
startX = null
|
|
356
320
|
}
|
|
357
321
|
|
|
358
|
-
header.on('
|
|
359
|
-
header.on('mousemove', handleMouseMove)
|
|
360
|
-
header.on('mouseup', handleMouseUp)
|
|
361
|
-
header.on('touchstart', handleTouchStart)
|
|
362
|
-
header.on('touchmove', handleTouchMove)
|
|
363
|
-
header.on('touchend', handleTouchEnd)
|
|
322
|
+
header.on('pointerdown', handlePointerDown)
|
|
364
323
|
}
|
|
365
324
|
|
|
366
325
|
highlightSelection(startX: number, endX: number) {
|