@operato/gantt 7.0.21 → 7.0.22

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.
@@ -154,6 +154,14 @@ export class OxGanttChart extends LitElement {
154
154
  return this.container.scrollTop
155
155
  }
156
156
 
157
+ setHorizontalOffset(offset: number) {
158
+ this.container.scrollLeft = offset
159
+ }
160
+
161
+ getHorizontalOffset(): number {
162
+ return this.container.scrollLeft
163
+ }
164
+
157
165
  handleWheelForHeader(event: WheelEvent) {
158
166
  event.preventDefault()
159
167
  event.stopPropagation()
@@ -185,6 +193,17 @@ export class OxGanttChart extends LitElement {
185
193
 
186
194
  this.ganttChartController.updateTimeScale()
187
195
  this.requestUpdate()
196
+
197
+ // Dispatch custom event to sync with ox-resource-chart
198
+ const customEvent = new CustomEvent('timescale-changed', {
199
+ detail: {
200
+ baseWidth: this.ganttChartController.baseWidth,
201
+ level: this.ganttChartController.level
202
+ },
203
+ bubbles: true,
204
+ composed: true
205
+ })
206
+ this.dispatchEvent(customEvent)
188
207
  }
189
208
  }
190
209
 
@@ -248,6 +267,17 @@ export class OxGanttChart extends LitElement {
248
267
  lastTouchDistance = currentDistance
249
268
  this.ganttChartController.updateTimeScale()
250
269
  this.requestUpdate()
270
+
271
+ // Dispatch custom event to sync with ox-resource-chart
272
+ const customEvent = new CustomEvent('timescale-changed', {
273
+ detail: {
274
+ baseWidth: this.ganttChartController.baseWidth,
275
+ level: this.ganttChartController.level
276
+ },
277
+ bubbles: true,
278
+ composed: true
279
+ })
280
+ this.dispatchEvent(customEvent)
251
281
  } else if (isDragging && startX !== null) {
252
282
  const touch = event.touches[0]
253
283
  const containerOffsetX = header.node()!.getBoundingClientRect().left
package/src/ox-gantt.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { LitElement, html, css, PropertyValues, PropertyValueMap, nothing, TemplateResult } from 'lit'
2
+ import * as d3 from 'd3'
2
3
  import i18next from 'i18next'
3
4
  import { customElement, property, query, state } from 'lit/decorators.js'
4
5
  import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
@@ -108,6 +109,7 @@ export class OxGantt extends LitElement {
108
109
  th {
109
110
  height: 40px;
110
111
  box-sizing: border-box;
112
+ text-align: center;
111
113
  }
112
114
 
113
115
  td {
@@ -182,11 +184,9 @@ export class OxGantt extends LitElement {
182
184
 
183
185
  @query('.task-container') taskContainer!: HTMLDivElement
184
186
  @query('.task-table-container') taskTableContainer!: HTMLDivElement
185
- @query('.task-chart-container') taskChartContainer!: HTMLDivElement
186
187
  @query('.resource-container') resourceContainer!: HTMLDivElement
187
188
  @query('.resource-table-container') resourceTableContainer!: HTMLDivElement
188
- @query('.resource-chart-container') resourceChartContainer!: HTMLDivElement
189
- @query('table') taskTable!: HTMLTableElement
189
+ @query('.task-table') taskTable!: HTMLTableElement
190
190
  @query('ox-gantt-chart') ganttChart!: OxGanttChart
191
191
  @query('ox-resource-chart') resourceChart!: OxResourceChart
192
192
 
@@ -207,10 +207,7 @@ export class OxGantt extends LitElement {
207
207
  ></ox-gantt-resize-splitter>
208
208
  <ox-gantt-chart
209
209
  class="task-chart-container"
210
- @scroll=${(e: CustomEvent) => {
211
- this.syncScroll(e)
212
- this.syncResourceChartScroll(e)
213
- }}
210
+ @scroll=${this.syncScroll}
214
211
  .fromDate=${this.fromDate}
215
212
  .toDate=${this.toDate}
216
213
  .tasks=${this.tasks}
@@ -218,6 +215,7 @@ export class OxGantt extends LitElement {
218
215
  .axisScale=${this.timeScale}
219
216
  ?extend-grid-lines=${this.extendGridLines}
220
217
  @task-clicked=${this.handleTaskClicked}
218
+ @timescale-changed=${(e: CustomEvent) => this.syncTimeScale(e)}
221
219
  ></ox-gantt-chart>
222
220
  </div>
223
221
  <ox-gantt-resize-splitter
@@ -227,12 +225,12 @@ export class OxGantt extends LitElement {
227
225
  @splitter-dragend=${(e: CustomEvent) => this.resizeVerticalEnd(e)}
228
226
  ></ox-gantt-resize-splitter>
229
227
  <div class="resource-container">
230
- <div class="resource-table-container">
228
+ <div class="resource-table-container" @scroll=${this.syncScroll}>
231
229
  <table>
232
230
  <thead>
233
231
  <tr>
234
- <th style="width: 100px">type</th>
235
- <th>allocated</th>
232
+ <th style="width: 100px">${i18next.t('label.gantt-resource-type')}</th>
233
+ <th>${i18next.t('label.gantt-resource-allocated')}</th>
236
234
  </tr>
237
235
  </thead>
238
236
  <tbody>
@@ -250,9 +248,10 @@ export class OxGantt extends LitElement {
250
248
  class="resource-chart-container"
251
249
  .fromDate=${this.fromDate}
252
250
  .toDate=${this.toDate}
251
+ .tasks=${this.tasks}
253
252
  .resources=${this.resources}
254
253
  .axisScale=${this.timeScale}
255
- @scroll=${this.syncTaskChartScroll}
254
+ @scroll=${this.syncScroll}
256
255
  ></ox-resource-chart>
257
256
  </div>
258
257
  </div>
@@ -268,7 +267,7 @@ export class OxGantt extends LitElement {
268
267
  const sortedColumns = [...this.columnConfig].sort((a, b) => a.order - b.order)
269
268
 
270
269
  return html`
271
- <table>
270
+ <table class="task-table">
272
271
  <thead>
273
272
  <tr>
274
273
  ${sortedColumns.map(col =>
@@ -295,7 +294,7 @@ export class OxGantt extends LitElement {
295
294
  <tr class=${this.selectedTaskId === task.id ? 'selected' : ''} @click=${() => this.selectTask(task.id)}>
296
295
  ${this.columnConfig.map(col =>
297
296
  col.visible
298
- ? html`<td class="task-row" style="padding-left: ${col.name == 'id' ? level * 20 : 0}px">
297
+ ? html`<td class="task-row" style="padding-left: ${col.name == 'title' ? level * 8 + 4 : 4}px">
299
298
  ${this.getTaskFieldValue(task, col.name)}
300
299
  </td>`
301
300
  : null
@@ -365,13 +364,20 @@ export class OxGantt extends LitElement {
365
364
  const traverseTasks = (tasks: Task[]) => {
366
365
  tasks.forEach(task => {
367
366
  if (task.resources) {
367
+ const startDate = new Date(task.startDate)
368
+ const endDate = new Date(task.endDate)
369
+ const durationDays = d3.timeDay.count(startDate, d3.timeDay.offset(endDate, 1))
370
+
368
371
  task.resources.forEach(resource => {
372
+ const totalAllocation = resource.allocated * durationDays
369
373
  if (!resourceMap[resource.type]) {
370
374
  resourceMap[resource.type] = 0
371
375
  }
372
- resourceMap[resource.type] += resource.allocated
376
+ resourceMap[resource.type] += totalAllocation
377
+ console.log(resource.type, resource.allocated, durationDays, totalAllocation)
373
378
  })
374
379
  }
380
+
375
381
  if (task.children) {
376
382
  traverseTasks(task.children)
377
383
  }
@@ -388,31 +394,41 @@ export class OxGantt extends LitElement {
388
394
 
389
395
  syncScroll(e: Event) {
390
396
  const target = e.target as HTMLElement
397
+
391
398
  if (target === this.taskTableContainer) {
392
- // Sync chart scroll with table scroll
393
399
  const newScrollTop = this.taskTableContainer.scrollTop
394
400
  this.ganttChart.setVerticalOffset(newScrollTop)
395
401
 
396
- // Ensure chart scroll matches table scroll
397
402
  if (this.ganttChart.getVerticalOffset() !== newScrollTop) {
398
403
  this.ganttChart.setVerticalOffset(newScrollTop)
399
404
  }
400
405
  } else if (target === this.ganttChart) {
401
- // Sync table scroll with chart scroll
402
406
  const newScrollTop = this.ganttChart.getVerticalOffset()
403
407
  this.taskTableContainer.scrollTop = newScrollTop
404
-
405
- // Ensure table scroll matches chart scroll
406
408
  this.ganttChart.setVerticalOffset(this.taskTableContainer.scrollTop)
407
- }
408
- }
409
409
 
410
- syncResourceChartScroll(e: CustomEvent) {
411
- this.resourceChart.renderRoot!.querySelector('div[chart-container]')!.scrollLeft = e.detail.offset
410
+ const newScrollLeft = this.ganttChart.getHorizontalOffset()
411
+ this.resourceChart.setHorizontalOffset(newScrollLeft)
412
+ } else if (target === this.resourceChart) {
413
+ const newScrollTop = this.ganttChart.getVerticalOffset()
414
+ this.resourceTableContainer.scrollTop = newScrollTop
415
+ this.resourceChart.setVerticalOffset(this.taskTableContainer.scrollTop)
416
+
417
+ const newScrollLeft = this.resourceChart.getHorizontalOffset()
418
+ this.ganttChart.setHorizontalOffset(newScrollLeft)
419
+ } else if (target === this.resourceTableContainer) {
420
+ const newScrollTop = this.taskTableContainer.scrollTop
421
+ this.resourceChart.setVerticalOffset(newScrollTop)
422
+
423
+ if (this.resourceChart.getVerticalOffset() !== newScrollTop) {
424
+ this.resourceChart.setVerticalOffset(newScrollTop)
425
+ }
426
+ }
412
427
  }
413
428
 
414
- syncTaskChartScroll(e: CustomEvent) {
415
- this.ganttChart.renderRoot!.querySelector('div[chart-container]')!.scrollLeft = e.detail.offset
429
+ syncTimeScale(e: CustomEvent) {
430
+ const detail = e.detail
431
+ this.resourceChart.syncTimeScale(detail)
416
432
  }
417
433
 
418
434
  resizeHorizontalStart(e: CustomEvent) {
@@ -1,9 +1,12 @@
1
1
  import { LitElement, html, css, PropertyValues } from 'lit'
2
- import { customElement, property } from 'lit/decorators.js'
2
+ import { customElement, property, query } from 'lit/decorators.js'
3
3
  import * as d3 from 'd3'
4
4
 
5
5
  import { ScrollbarStyles } from '@operato/styles'
6
6
 
7
+ import { drawTimeScaleHeader } from './draw-time-scale-header'
8
+ import { Task, TimeScale } from './types'
9
+
7
10
  @customElement('ox-resource-chart')
8
11
  export class OxResourceChart extends LitElement {
9
12
  static styles = [
@@ -14,14 +17,15 @@ export class OxResourceChart extends LitElement {
14
17
  overflow: hidden;
15
18
  position: relative;
16
19
  }
20
+
17
21
  div[chart-container] {
18
- display: block;
22
+ display: flex;
23
+ flex-direction: column;
24
+
19
25
  overflow-x: auto;
20
- overflow-y: hidden;
21
- }
22
- svg {
23
- min-width: 100%;
26
+ overflow-y: auto;
24
27
  }
28
+
25
29
  svg[header] {
26
30
  display: block;
27
31
  min-width: 100%;
@@ -34,23 +38,30 @@ export class OxResourceChart extends LitElement {
34
38
  top: 0;
35
39
  z-index: 1;
36
40
  }
41
+
37
42
  svg[body] {
43
+ flex: 1;
38
44
  display: block;
39
45
  min-width: 100%;
40
46
  }
47
+
41
48
  .top-axis text,
42
49
  .bottom-axis text {
43
50
  font-size: 12px;
44
51
  }
52
+
45
53
  .grid line {
46
54
  stroke: #e0e0e0;
47
55
  }
56
+
48
57
  .grid path {
49
58
  stroke-width: 0;
50
59
  }
60
+
51
61
  .no-select {
52
62
  user-select: none;
53
63
  }
64
+
54
65
  .selected {
55
66
  stroke-width: 2px;
56
67
  stroke: var(--ox-gantt-selected-color, blue);
@@ -62,10 +73,17 @@ export class OxResourceChart extends LitElement {
62
73
  @property({ type: String }) toDate: string = new Date(new Date().getFullYear(), 11, 31).toISOString().split('T')[0]
63
74
  @property({ type: String }) axisScale: string = 'week-day'
64
75
  @property({ type: Array }) resources: any[] = []
76
+ @property({ type: Array }) tasks: Task[] = []
65
77
 
66
- private _timeScale: any
67
- private _baseWidth: number = 30
68
- private _level: string = 'week-day'
78
+ private timeScale: any
79
+ private baseWidth: number = 30
80
+ private level: TimeScale = 'week-day'
81
+ private fromTime?: Date
82
+ private toTime?: Date
83
+
84
+ @query('[chart-container') container!: HTMLDivElement
85
+ @query('svg[header]') svgHeader!: SVGSVGElement
86
+ @query('svg[body]') svgBody!: SVGSVGElement
69
87
 
70
88
  render() {
71
89
  return html`
@@ -81,7 +99,7 @@ export class OxResourceChart extends LitElement {
81
99
  this.updateTimeScale()
82
100
  }
83
101
 
84
- if (changedProperties.has('resources')) {
102
+ if (changedProperties.has('resources') || changedProperties.has('tasks')) {
85
103
  this.drawBody()
86
104
  }
87
105
 
@@ -89,7 +107,10 @@ export class OxResourceChart extends LitElement {
89
107
  }
90
108
 
91
109
  updateTimeScale() {
92
- this._timeScale = d3
110
+ this.fromTime = new Date(this.fromDate)
111
+ this.toTime = new Date(this.toDate)
112
+
113
+ this.timeScale = d3
93
114
  .scaleTime()
94
115
  .domain([d3.timeDay.floor(new Date(this.fromDate)), d3.timeDay.offset(new Date(this.toDate), 1)])
95
116
  .range([0, this.getChartWidth()])
@@ -97,50 +118,42 @@ export class OxResourceChart extends LitElement {
97
118
 
98
119
  getChartWidth() {
99
120
  const totalDays = d3.timeDay.count(new Date(this.fromDate), d3.timeDay.offset(new Date(this.toDate), 1))
100
- return (totalDays * this._baseWidth) / this.getScale()
121
+ return (totalDays * this.baseWidth) / this.getScale()
101
122
  }
102
123
 
103
124
  getScale() {
104
- if (this._level == 'quarter-week') {
125
+ if (this.level == 'quarter-week') {
105
126
  return 7 / 2
106
- } else if (this._level == 'year-month') {
127
+ } else if (this.level == 'year-month') {
107
128
  return 30 / 2
108
- } else if (this._level == 'year-quarter') {
129
+ } else if (this.level === 'year-quarter') {
109
130
  return 90 / 2
110
131
  }
111
132
  return 1
112
133
  }
113
134
 
114
135
  drawAxes() {
115
- const header = d3.select(this.renderRoot.querySelector('svg[header]')!)
116
-
117
- header.selectAll('*').remove()
118
- header.attr('width', this.getChartWidth())
119
-
120
- const axisTop = d3.axisTop(this._timeScale).tickSize(-20)
121
- const axisBottom = d3.axisBottom(this._timeScale).tickSize(-20)
122
-
123
- header.append('g').attr('class', 'top-axis').attr('transform', 'translate(0, 20)').call(axisTop)
124
- header.append('g').attr('class', 'bottom-axis').attr('transform', 'translate(0, 40)').call(axisBottom)
136
+ drawTimeScaleHeader(this.svgHeader as any, this.timeScale, this.fromTime!, this.toTime!, this.baseWidth, this.level)
125
137
  }
126
138
 
127
139
  drawBody() {
128
- const body = d3.select(this.renderRoot.querySelector('svg[body]')!)
140
+ const body = d3.select(this.svgBody)
129
141
 
130
142
  body.selectAll('*').remove()
131
143
  body.attr('width', this.getChartWidth())
132
144
 
133
- // Add grid lines for resource chart
134
145
  if (this.resources.length > 0) {
146
+ const chartHeight = this.resources.length * 30
147
+
135
148
  const addVerticalGridLines = (ticks: Date[]) => {
136
149
  ticks.forEach(tick => {
137
- const startX = this._timeScale(tick)
150
+ const startX = this.timeScale(tick)
138
151
  body
139
152
  .append('line')
140
153
  .attr('x1', startX)
141
154
  .attr('x2', startX)
142
155
  .attr('y1', 0)
143
- .attr('y2', this.resources.length * 30) // Adjust according to the number of resource rows
156
+ .attr('y2', chartHeight) // Ensure vertical lines extend to the bottom
144
157
  .attr('stroke', 'var(--ox-gantt-color-gridlines, var(--md-sys-color-outline))')
145
158
  .attr('stroke-width', 1)
146
159
  })
@@ -158,35 +171,158 @@ export class OxResourceChart extends LitElement {
158
171
  .attr('stroke', 'var(--ox-gantt-color-gridlines, var(--md-sys-color-outline))')
159
172
  .attr('stroke-width', 1)
160
173
  })
174
+
175
+ // Ensure the last horizontal line extends to the bottom of the chart
176
+ body
177
+ .append('line')
178
+ .attr('x1', 0)
179
+ .attr('x2', this.getChartWidth())
180
+ .attr('y1', chartHeight)
181
+ .attr('y2', chartHeight)
182
+ .attr('stroke', 'var(--ox-gantt-color-gridlines, var(--md-sys-color-outline))')
183
+ .attr('stroke-width', 1)
161
184
  }
162
185
 
163
- if (this._level === 'week-day') {
164
- const dayTicks = d3.timeDay
186
+ let ticks
187
+ if (this.level === 'week-day') {
188
+ ticks = d3.timeDay
165
189
  .every(1)!
166
190
  .range(d3.timeDay.floor(new Date(this.fromDate)), d3.timeDay.offset(new Date(this.toDate), 1))
167
- addVerticalGridLines(dayTicks)
168
- } else if (this._level === 'quarter-week') {
169
- const weekTicks = d3.timeWeek
191
+ } else if (this.level === 'quarter-week') {
192
+ ticks = d3.timeWeek
170
193
  .every(1)!
171
194
  .range(d3.timeWeek.floor(new Date(this.fromDate)), d3.timeWeek.offset(new Date(this.toDate), 1))
172
- addVerticalGridLines(weekTicks)
173
- } else if (this._level === 'year-month') {
174
- const monthTicks = d3.timeMonth
195
+ } else if (this.level === 'year-month') {
196
+ ticks = d3.timeMonth
175
197
  .every(1)!
176
198
  .range(d3.timeMonth.floor(new Date(this.fromDate)), d3.timeMonth.offset(new Date(this.toDate), 1))
177
- addVerticalGridLines(monthTicks)
178
- } else if (this._level === 'year-quarter') {
179
- const quarterTicks = d3.timeMonth
199
+ } else if (this.level === 'year-quarter') {
200
+ ticks = d3.timeMonth
180
201
  .every(3)!
181
202
  .range(d3.timeMonth.floor(new Date(this.fromDate)), d3.timeMonth.offset(new Date(this.toDate), 3))
182
- addVerticalGridLines(quarterTicks)
183
203
  }
184
204
 
205
+ addVerticalGridLines(ticks!)
185
206
  addHorizontalGridLines()
207
+
208
+ // Render the resource allocations
209
+ this.renderResourceAllocations(body, ticks!)
186
210
  }
187
211
  }
188
212
 
189
- syncScroll(e: CustomEvent) {
190
- this.shadowRoot!.querySelector('div[chart-container]')!.scrollLeft = e.detail.offset
213
+ renderResourceAllocations(body: d3.Selection<SVGSVGElement, unknown, null, undefined>, ticks: Date[]) {
214
+ const resourceAllocations = this.calculateResourceAllocations(ticks)
215
+
216
+ this.resources.forEach((resource, index) => {
217
+ const y = index * 30 + 15 // Center the text vertically in the row
218
+ ticks.forEach(tick => {
219
+ const tickEnd = this.getTickEnd(tick)
220
+ const dateKey = this.formatDateKey(tick, tickEnd)
221
+ const allocation = resourceAllocations[resource.type][dateKey]
222
+ if (allocation > 0) {
223
+ const startX = this.timeScale(tick)
224
+ const tickInterval = this.timeScale(tickEnd) - startX
225
+
226
+ body
227
+ .append('text')
228
+ .attr('x', startX + tickInterval / 2)
229
+ .attr('y', y)
230
+ .attr('text-anchor', 'middle')
231
+ .attr('alignment-baseline', 'middle')
232
+ .attr('dominant-baseline', 'middle')
233
+ .text(allocation)
234
+ .style('font-size', '12px')
235
+ }
236
+ })
237
+ })
238
+ }
239
+
240
+ calculateResourceAllocations(ticks: Date[]) {
241
+ const resourceAllocations: { [key: string]: { [key: string]: number } } = {}
242
+
243
+ // Initialize the resourceAllocations object
244
+ this.resources.forEach(resource => {
245
+ resourceAllocations[resource.type] = {}
246
+ ticks.forEach(tick => {
247
+ const tickEnd = this.getTickEnd(tick)
248
+ const dateKey = this.formatDateKey(tick, tickEnd)
249
+ resourceAllocations[resource.type][dateKey] = 0
250
+ })
251
+ })
252
+
253
+ // Function to process tasks recursively
254
+ const processTask = (task: Task) => {
255
+ const startDate = new Date(task.startDate)
256
+ const endDate = new Date(task.endDate)
257
+ let currentDate = startDate
258
+
259
+ while (currentDate <= endDate) {
260
+ const tick = ticks.find(t => currentDate >= t && currentDate < this.getTickEnd(t))
261
+ if (tick) {
262
+ const tickEnd = this.getTickEnd(tick)
263
+ const dateKey = this.formatDateKey(tick, tickEnd)
264
+
265
+ ;(task.resources || []).forEach(resource => {
266
+ if (resourceAllocations[resource.type][dateKey] !== undefined) {
267
+ resourceAllocations[resource.type][dateKey] += resource.allocated
268
+ }
269
+ })
270
+ }
271
+
272
+ currentDate.setDate(currentDate.getDate() + 1)
273
+ }
274
+
275
+ // Recursively process child tasks
276
+ if (task.children) {
277
+ task.children.forEach(childTask => processTask(childTask))
278
+ }
279
+ }
280
+
281
+ // Process all tasks
282
+ this.tasks.forEach(task => processTask(task))
283
+
284
+ return resourceAllocations
285
+ }
286
+
287
+ getTickEnd(tick: Date) {
288
+ if (this.level === 'week-day') {
289
+ return d3.timeDay.offset(tick, 1)
290
+ } else if (this.level === 'quarter-week') {
291
+ return d3.timeWeek.offset(tick, 1)
292
+ } else if (this.level === 'year-month') {
293
+ return d3.timeMonth.offset(tick, 1)
294
+ } else if (this.level === 'year-quarter') {
295
+ return d3.timeMonth.offset(tick, 3)
296
+ }
297
+ return d3.timeDay.offset(tick, 1)
298
+ }
299
+
300
+ formatDateKey(start: Date, end: Date) {
301
+ return `${start.toISOString().split('T')[0]}_${end.toISOString().split('T')[0]}`
302
+ }
303
+
304
+ syncTimeScale(detail: { baseWidth: number; level: TimeScale }) {
305
+ this.baseWidth = detail.baseWidth
306
+ this.level = detail.level
307
+
308
+ this.updateTimeScale()
309
+ this.drawAxes()
310
+ this.drawBody()
311
+ }
312
+
313
+ setVerticalOffset(offset: number) {
314
+ this.container.scrollTop = offset
315
+ }
316
+
317
+ getVerticalOffset(): number {
318
+ return this.container.scrollTop
319
+ }
320
+
321
+ setHorizontalOffset(offset: number) {
322
+ this.container.scrollLeft = offset
323
+ }
324
+
325
+ getHorizontalOffset(): number {
326
+ return this.container.scrollLeft
191
327
  }
192
328
  }
@@ -78,8 +78,8 @@ const Template: Story<ArgTypes> = ({
78
78
  }
79
79
 
80
80
  ox-gantt {
81
- width: 90%;
82
- height: 500px;
81
+ width: 100%;
82
+ height: 800px;
83
83
  box-sizing: border-box;
84
84
 
85
85
  background-color: var(--md-sys-color-primary-container);
@@ -182,8 +182,8 @@ Regular.args = {
182
182
  progress: 60,
183
183
  dependsOn: '',
184
184
  length: '4d',
185
- tags: ['done'],
186
- resources: [{ type: '창호공', allocated: 6 }],
185
+ tags: ['active'],
186
+ resources: [{ type: '창호공', allocated: 5 }],
187
187
  children: []
188
188
  },
189
189
  {
@@ -196,7 +196,7 @@ Regular.args = {
196
196
  dependsOn: '3-1-1',
197
197
  length: '5d',
198
198
  tags: ['active'],
199
- resources: [{ type: '창호공', allocated: 6 }],
199
+ resources: [{ type: '창호공', allocated: 3 }],
200
200
  children: []
201
201
  }
202
202
  ]
@@ -227,7 +227,7 @@ Regular.args = {
227
227
  dependsOn: '1',
228
228
  length: '1d',
229
229
  tags: ['done'],
230
- resources: [{ type: '방수공', allocated: 6 }],
230
+ resources: [{ type: '방수공', allocated: 5 }],
231
231
  children: []
232
232
  },
233
233
  {
@@ -240,7 +240,7 @@ Regular.args = {
240
240
  dependsOn: '4',
241
241
  length: '1d',
242
242
  tags: ['milestone'],
243
- resources: [{ type: '목공', allocated: 6 }],
243
+ resources: [{ type: '목공', allocated: 3 }],
244
244
  children: []
245
245
  },
246
246
  {
@@ -253,7 +253,7 @@ Regular.args = {
253
253
  dependsOn: '5',
254
254
  length: '1d',
255
255
  tags: ['milestone'],
256
- resources: [{ type: '금속공', allocated: 6 }],
256
+ resources: [{ type: '금속공', allocated: 1 }],
257
257
  children: []
258
258
  },
259
259
  {
@@ -279,7 +279,7 @@ Regular.args = {
279
279
  dependsOn: '7',
280
280
  length: '1d',
281
281
  tags: ['critical'],
282
- resources: [{ type: '창호공', allocated: 6 }],
282
+ resources: [{ type: '창호공', allocated: 7 }],
283
283
  children: []
284
284
  },
285
285
  {
@@ -292,7 +292,7 @@ Regular.args = {
292
292
  dependsOn: '8',
293
293
  length: '1d',
294
294
  tags: ['active'],
295
- resources: [{ type: '도배공', allocated: 6 }],
295
+ resources: [{ type: '도배공', allocated: 8 }],
296
296
  children: []
297
297
  },
298
298
  {
@@ -318,6 +318,7 @@ Regular.args = {
318
318
  dependsOn: '9',
319
319
  length: '1d',
320
320
  tags: ['milestone'],
321
+ resources: [{ type: '철근/형틀공', allocated: 6 }],
321
322
  children: []
322
323
  },
323
324
  {
@@ -329,6 +330,7 @@ Regular.args = {
329
330
  endDate: '2023-01-23',
330
331
  dependsOn: '9',
331
332
  length: '1d',
333
+ resources: [{ type: '방수공', allocated: 6 }],
332
334
  tags: ['milestone'],
333
335
  children: [
334
336
  {
@@ -342,6 +344,7 @@ Regular.args = {
342
344
  dependsOn: '',
343
345
  length: '4d',
344
346
  tags: ['done'],
347
+ resources: [{ type: '방수공', allocated: 6 }],
345
348
  children: []
346
349
  },
347
350
  {
@@ -354,6 +357,7 @@ Regular.args = {
354
357
  dependsOn: '12-1',
355
358
  length: '5d',
356
359
  tags: ['active'],
360
+ resources: [{ type: '조적공', allocated: 6 }],
357
361
  children: []
358
362
  }
359
363
  ]
@@ -380,6 +384,7 @@ Regular.args = {
380
384
  dependsOn: '13',
381
385
  length: '1d',
382
386
  tags: ['milestone'],
387
+ resources: [{ type: '금속공', allocated: 1 }],
383
388
  children: []
384
389
  },
385
390
  {
@@ -403,6 +408,7 @@ Regular.args = {
403
408
  endDate: '2023-02-05',
404
409
  dependsOn: '15',
405
410
  length: '1d',
411
+ resources: [{ type: '창호공', allocated: 1 }],
406
412
  tags: ['active'],
407
413
  children: []
408
414
  },
@@ -440,6 +446,7 @@ Regular.args = {
440
446
  dependsOn: '18',
441
447
  length: '1d',
442
448
  tags: ['milestone'],
449
+ resources: [{ type: '창호공', allocated: 7 }],
443
450
  children: []
444
451
  }
445
452
  ]
@@ -8,5 +8,7 @@
8
8
  "label.gantt-task-tags": "tags",
9
9
  "label.gantt-task-progress": "progress",
10
10
  "label.gantt-task-previous": "previous",
11
- "label.gantt-task-resources": "resources"
11
+ "label.gantt-task-resources": "resources",
12
+ "label.gantt-resource-type": "type",
13
+ "label.gantt-resource-allocated": "allocated"
12
14
  }