@operato/gantt 8.0.0-alpha.40 → 8.0.0-alpha.47

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.
@@ -2,7 +2,7 @@ import './ox-task-tooltip.js'
2
2
  import './ox-resource-chart.js'
3
3
 
4
4
  import { LitElement, html, css, PropertyValues, PropertyValueMap } from 'lit'
5
- import { customElement, property, query } from 'lit/decorators.js'
5
+ import { customElement, property, query, state } from 'lit/decorators.js'
6
6
  import * as d3 from 'd3'
7
7
  import { locales } from './locales'
8
8
 
@@ -89,6 +89,8 @@ export class OxGanttChart extends gesture(LitElement) {
89
89
  @property({ type: String }) locale: string = 'en-US'
90
90
  @property({ type: Object }) colorProvider!: (task: Task) => string
91
91
 
92
+ @state() dateRangeSelected?: { start: Date; end: Date }
93
+
92
94
  @query('svg[header]') svgHeader!: SVGElement
93
95
  @query('svg[body]') svgBody!: SVGElement
94
96
  @query('[chart-container]') container!: HTMLDivElement
@@ -99,7 +101,7 @@ export class OxGanttChart extends gesture(LitElement) {
99
101
  protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
100
102
  this.initHeaderGestureHandlers()
101
103
 
102
- this.addEventListener('date-range-cleared', e => this.clearSelection())
104
+ // this.addEventListener('date-range-cleared', e => this.clearSelection())
103
105
  }
104
106
 
105
107
  connectedCallback(): void {
@@ -151,16 +153,13 @@ export class OxGanttChart extends gesture(LitElement) {
151
153
 
152
154
  this.ganttChartController.drawAxes(this.svgHeader)
153
155
  this.ganttChartController.drawBody(this.svgBody, this.tooltip)
156
+ this.drawSelectedRange()
154
157
  }
155
158
 
156
159
  render() {
157
160
  return html`
158
161
  <div chart-container @wheel=${(e: WheelEvent) => this.ganttChartController.handleWheelForBody(e, this.container)}>
159
- <svg
160
- header
161
- @date-range-selected=${(e: CustomEvent) => this.handleDateRangeSelected(e)}
162
- @wheel=${this.handleWheelForHeader.bind(this)}
163
- ></svg>
162
+ <svg header @wheel=${this.handleWheelForHeader.bind(this)}></svg>
164
163
  <svg body></svg>
165
164
  <div class="scroll-button left" @click=${this.scrollToStart} @touchstart=${this.scrollToStart}></div>
166
165
  <div class="scroll-button right" @click=${this.scrollToEnd} @touchstart=${this.scrollToEnd}></div>
@@ -266,11 +265,6 @@ export class OxGanttChart extends gesture(LitElement) {
266
265
  this.dispatchEvent(customEvent)
267
266
  }
268
267
 
269
- handleDateRangeSelected(event: CustomEvent) {
270
- const detail = event.detail
271
- this.dispatchEvent(new CustomEvent('date-range-selected', { detail, bubbles: true, composed: true }))
272
- }
273
-
274
268
  updateLocale(locale: string) {
275
269
  const localeDefinition = (locales as any)[locale || 'en-US']
276
270
  if (localeDefinition) {
@@ -323,9 +317,6 @@ export class OxGanttChart extends gesture(LitElement) {
323
317
  }
324
318
 
325
319
  highlightSelection(startX: number, endX: number) {
326
- const header = d3.select(this.svgHeader)
327
- const body = d3.select(this.svgBody)
328
-
329
320
  let startDate = this.ganttChartController.timeScale.invert(startX)
330
321
  let endDate = this.ganttChartController.timeScale.invert(endX)
331
322
 
@@ -345,44 +336,10 @@ export class OxGanttChart extends gesture(LitElement) {
345
336
  end = d3.timeDay.offset(d3.timeMonth.every(3)!.ceil(d3.max([startDate, endDate])!), -1)
346
337
  }
347
338
 
348
- header.selectAll('.selection-rect').remove()
349
- body.selectAll('.selection-rect').remove()
350
-
351
- header
352
- .append('rect')
353
- .attr('class', 'selection-rect')
354
- .attr('x', this.ganttChartController.timeScale(start!))
355
- .attr('y', 20)
356
- .attr(
357
- 'width',
358
- this.ganttChartController.timeScale(end!) -
359
- this.ganttChartController.timeScale(start!) +
360
- this.ganttChartController.baseWidth / this.ganttChartController.getScale()
361
- )
362
- .attr('height', 20)
363
- .attr('fill', 'var(--ox-gantt-selection-color, var(--md-sys-color-on-primary-container))')
364
- .attr('opacity', '.2')
365
-
366
- body
367
- .append('rect')
368
- .attr('class', 'selection-rect')
369
- .attr('x', this.ganttChartController.timeScale(start!))
370
- .attr('y', 0)
371
- .attr(
372
- 'width',
373
- this.ganttChartController.timeScale(end!) -
374
- this.ganttChartController.timeScale(start!) +
375
- this.ganttChartController.baseWidth / this.ganttChartController.getScale()
376
- )
377
- .attr('height', '100%')
378
- .attr('fill', 'var(--ox-gantt-selection-color, var(--md-sys-color-on-primary-container))')
379
- .attr('opacity', '.2')
339
+ this.dateRangeSelected = { start: start!, end: end! }
380
340
  }
381
341
 
382
342
  finalizeSelection(startX: number, endX: number) {
383
- const header = d3.select(this.svgHeader)
384
- const body = d3.select(this.svgBody)
385
-
386
343
  let startDate = this.ganttChartController.timeScale.invert(startX)
387
344
  let endDate = this.ganttChartController.timeScale.invert(endX)
388
345
 
@@ -402,6 +359,29 @@ export class OxGanttChart extends gesture(LitElement) {
402
359
  end = d3.timeDay.offset(d3.timeMonth.every(3)!.ceil(d3.max([startDate, endDate])!), -1)
403
360
  }
404
361
 
362
+ this.dateRangeSelected = { start: start!, end: end! }
363
+
364
+ const formatDate = d3.timeFormat('%Y-%m-%d')
365
+
366
+ this.dispatchEvent(
367
+ new CustomEvent('date-range-selected', {
368
+ detail: { start: formatDate(start!), end: formatDate(end!) },
369
+ bubbles: true,
370
+ composed: true
371
+ })
372
+ )
373
+ }
374
+
375
+ drawSelectedRange() {
376
+ if (!this.dateRangeSelected) {
377
+ return
378
+ }
379
+
380
+ let { start, end } = this.dateRangeSelected
381
+
382
+ const header = d3.select(this.svgHeader)
383
+ const body = d3.select(this.svgBody)
384
+
405
385
  header.selectAll('.selection-rect').remove()
406
386
  body.selectAll('.selection-rect').remove()
407
387
 
@@ -434,21 +414,5 @@ export class OxGanttChart extends gesture(LitElement) {
434
414
  .attr('height', '100%')
435
415
  .attr('fill', 'var(--ox-gantt-selection-color, var(--md-sys-color-on-primary-container))')
436
416
  .attr('opacity', '.2')
437
-
438
- const formatDate = d3.timeFormat('%Y-%m-%d')
439
- const customEvent = new CustomEvent('date-range-selected', {
440
- detail: { start: formatDate(start!), end: formatDate(end!) }
441
- })
442
-
443
- header.node()?.dispatchEvent(customEvent)
444
- }
445
-
446
- clearSelection() {
447
- const header = d3.select(this.svgHeader)
448
- const body = d3.select(this.svgBody)
449
-
450
- // 선택한 영역을 나타내는 모든 'selection-rect' 요소를 제거합니다.
451
- header.selectAll('.selection-rect').remove()
452
- body.selectAll('.selection-rect').remove()
453
417
  }
454
418
  }
package/src/ox-gantt.ts CHANGED
@@ -155,15 +155,9 @@ export class OxGantt extends localize(i18next)(LitElement) {
155
155
  @property({ type: Boolean, attribute: 'extend-grid-lines' }) extendGridLines: boolean = false
156
156
  @property({ type: String, attribute: 'time-scale' }) timeScale: TimeScale = 'week-day'
157
157
  @property({ type: Object }) colorProvider: (task: Task) => string = (task: Task) => {
158
- const { tags = [] } = task
159
- if (tags.includes('critical')) {
160
- return 'red'
161
- } else if (tags.includes('milestone')) {
162
- return 'blue'
163
- } else if (tags.includes('done')) {
164
- return 'green'
165
- }
166
- return 'grey'
158
+ const { style } = task
159
+
160
+ return style || 'gray'
167
161
  }
168
162
  @property({ type: Object }) columnConfigProvider: () => ColumnConfig[] = function () {
169
163
  return [
package/src/types.ts CHANGED
@@ -11,6 +11,7 @@ export interface Task {
11
11
  dependsOn?: string
12
12
  duration: number
13
13
  tags?: TaskTag[]
14
+ style?: string
14
15
  children?: Task[]
15
16
  resources?: Resource[]
16
17
  collapsed?: boolean
@@ -141,6 +141,7 @@ Regular.args = {
141
141
  id: '2',
142
142
  title: 'Development',
143
143
  type: 'milestone',
144
+ style: 'blue',
144
145
  startDate: '2023-01-06',
145
146
  endDate: '2023-01-06',
146
147
  progress: 30,
@@ -160,6 +161,7 @@ Regular.args = {
160
161
  dependsOn: '2',
161
162
  duration: 9,
162
163
  tags: ['critical'],
164
+ style: 'red',
163
165
  children: [
164
166
  {
165
167
  id: '3-1',
@@ -171,6 +173,7 @@ Regular.args = {
171
173
  dependsOn: '',
172
174
  duration: 4,
173
175
  tags: ['done'],
176
+ style: 'green',
174
177
  children: [
175
178
  {
176
179
  id: '3-1-1',
@@ -223,6 +226,7 @@ Regular.args = {
223
226
  dependsOn: '1',
224
227
  duration: 1,
225
228
  tags: ['done'],
229
+ style: 'green',
226
230
  resources: [{ type: '방수공', allocated: 5 }],
227
231
  children: []
228
232
  },
@@ -230,6 +234,7 @@ Regular.args = {
230
234
  id: '5',
231
235
  title: 'Deploy',
232
236
  type: 'milestone',
237
+ style: 'blue',
233
238
  startDate: '2023-01-15',
234
239
  endDate: '2023-01-21',
235
240
  dependsOn: '4',
@@ -242,6 +247,7 @@ Regular.args = {
242
247
  id: '6',
243
248
  title: 'Publishing',
244
249
  type: 'milestone',
250
+ style: 'blue',
245
251
  startDate: '2023-01-11',
246
252
  endDate: '2023-01-15',
247
253
  dependsOn: '5',
@@ -254,6 +260,7 @@ Regular.args = {
254
260
  id: '7',
255
261
  title: 'Provisioning',
256
262
  type: 'milestone',
263
+ style: 'blue',
257
264
  startDate: '2023-01-12',
258
265
  endDate: '2023-01-15',
259
266
  dependsOn: '6',
@@ -266,6 +273,7 @@ Regular.args = {
266
273
  id: '8',
267
274
  title: 'Alpha Test',
268
275
  type: 'milestone',
276
+ style: 'blue',
269
277
  startDate: '2023-01-15',
270
278
  endDate: '2023-01-17',
271
279
  dependsOn: '7',
@@ -278,6 +286,7 @@ Regular.args = {
278
286
  id: '9',
279
287
  title: 'Beta Task',
280
288
  type: 'milestone',
289
+ style: 'blue',
281
290
  startDate: '2023-01-15',
282
291
  endDate: '2023-01-18',
283
292
  dependsOn: '8',
@@ -296,6 +305,7 @@ Regular.args = {
296
305
  dependsOn: '9',
297
306
  duration: 1,
298
307
  tags: ['critical'],
308
+ style: 'red',
299
309
  resources: [{ type: '조적공', allocated: 6 }],
300
310
  children: []
301
311
  },
@@ -303,6 +313,7 @@ Regular.args = {
303
313
  id: '11',
304
314
  title: 'Zeta Test',
305
315
  type: 'milestone',
316
+ style: 'blue',
306
317
  startDate: '2023-01-18',
307
318
  endDate: '2023-01-22',
308
319
  dependsOn: '9',
@@ -315,6 +326,7 @@ Regular.args = {
315
326
  id: '12',
316
327
  title: 'Release',
317
328
  type: 'milestone',
329
+ style: 'blue',
318
330
  startDate: '2023-01-18',
319
331
  endDate: '2023-01-23',
320
332
  dependsOn: '9',
@@ -332,6 +344,7 @@ Regular.args = {
332
344
  dependsOn: '',
333
345
  duration: 4,
334
346
  tags: ['done'],
347
+ style: 'green',
335
348
  resources: [{ type: '방수공', allocated: 6 }],
336
349
  children: []
337
350
  },
@@ -358,12 +371,14 @@ Regular.args = {
358
371
  dependsOn: '12',
359
372
  duration: 1,
360
373
  tags: ['done'],
374
+ style: 'green',
361
375
  children: []
362
376
  },
363
377
  {
364
378
  id: '14',
365
379
  title: 'Release',
366
380
  type: 'milestone',
381
+ style: 'blue',
367
382
  startDate: '2023-01-27',
368
383
  endDate: '2023-01-30',
369
384
  dependsOn: '13',
@@ -376,6 +391,7 @@ Regular.args = {
376
391
  id: '15',
377
392
  title: 'Release',
378
393
  type: 'milestone',
394
+ style: 'blue',
379
395
  startDate: '2023-01-30',
380
396
  endDate: '2023-01-31',
381
397
  dependsOn: '14',
@@ -387,6 +403,7 @@ Regular.args = {
387
403
  id: '16',
388
404
  title: 'Release',
389
405
  type: 'milestone',
406
+ style: 'blue',
390
407
  startDate: '2023-01-31',
391
408
  endDate: '2023-02-05',
392
409
  dependsOn: '15',
@@ -399,6 +416,7 @@ Regular.args = {
399
416
  id: '17',
400
417
  title: 'Release',
401
418
  type: 'milestone',
419
+ style: 'blue',
402
420
  startDate: '2023-02-06',
403
421
  endDate: '2023-02-07',
404
422
  dependsOn: '16',
@@ -415,12 +433,14 @@ Regular.args = {
415
433
  dependsOn: '17',
416
434
  duration: 1,
417
435
  tags: ['critical'],
436
+ style: 'red',
418
437
  children: []
419
438
  },
420
439
  {
421
440
  id: '19',
422
441
  title: 'Release',
423
442
  type: 'milestone',
443
+ style: 'blue',
424
444
  startDate: '2023-02-10',
425
445
  endDate: '2023-02-25',
426
446
  dependsOn: '18',