@mogura/moguchart-core 0.6.0 → 0.7.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/README.en.md +1 -1
- package/README.md +1 -1
- package/dist/components/gantt-bar.d.ts +1 -0
- package/dist/components/gantt-calendar.d.ts +1 -0
- package/dist/components/gantt-chart-export.d.ts +2 -1
- package/dist/components/gantt-chart.d.ts +39 -0
- package/dist/components/gantt-row.d.ts +1 -0
- package/dist/core/critical-path.d.ts +18 -0
- package/dist/core/types.d.ts +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/moguchart-core.mjs +263 -50
- package/dist/moguchart-core.umd.js +40 -18
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -18,7 +18,7 @@ A lightweight yet feature-rich Gantt chart Web Component built with Lit. Works w
|
|
|
18
18
|
- Light/Dark/System theme switching + custom color themes
|
|
19
19
|
- Task bar fill patterns (13 types including stripes, dots, checkerboard, etc.)
|
|
20
20
|
- CSS styling
|
|
21
|
-
- 🔗 **Dependency Visualization**: Curved lines with arrows showing task dependencies (S-curve support for reverse direction)
|
|
21
|
+
- 🔗 **Dependency Visualization**: Curved lines with arrows showing task dependencies (S-curve support for reverse direction). Automatic critical path detection and highlighting
|
|
22
22
|
- 📅 **Flexible Calendar**:
|
|
23
23
|
- Day / Week / Month view switching
|
|
24
24
|
- Adjustable zoom level (pixels per day or per month) and display period
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Vue, React, Angular, Svelte など、どのフレームワークでも動作す
|
|
|
20
20
|
- ライト/ダーク/システムテーマの切り替え+カスタムカラーテーマ
|
|
21
21
|
- タスクバーの塗りつぶしパターン(ストライプ、ドット、チェッカーボードなど13種類)
|
|
22
22
|
- CSSによるスタイリング
|
|
23
|
-
- 🔗 **依存関係の表示**: タスク間の依存関係を矢印付き曲線で可視化(S
|
|
23
|
+
- 🔗 **依存関係の表示**: タスク間の依存関係を矢印付き曲線で可視化(S字カーブ対応)。クリティカルパス(最長チェーン)の自動検出+ハイライト表示
|
|
24
24
|
- 📅 **柔軟なカレンダー**:
|
|
25
25
|
- 日単位 / 週単位 / 月単位の表示切り替え
|
|
26
26
|
- ズームレベル(1日・1ヶ月あたりの幅)や表示期間の調整が可能
|
|
@@ -4,6 +4,7 @@ export declare class GanttCalendarElement extends LitElement {
|
|
|
4
4
|
option: GanttChartOption;
|
|
5
5
|
theme: 'light' | 'dark';
|
|
6
6
|
currentTime: Date;
|
|
7
|
+
isExporting: boolean;
|
|
7
8
|
hoveredMilestoneId: string | null;
|
|
8
9
|
cornerContent?: () => string | unknown;
|
|
9
10
|
calendarMonthContent?: (context: CalendarMonthCellContext) => string | unknown;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Shadow DOM の cloneNode では内部コンテンツがコピーされないため、
|
|
5
5
|
* rows / option / theme などのデータから SVG を直接描画します。
|
|
6
6
|
*/
|
|
7
|
+
import type { GanttChartElement } from './gantt-chart';
|
|
7
8
|
export interface ExportImageOptions {
|
|
8
9
|
/** ダウンロード時のファイル名(拡張子なし)。省略時は 'gantt-chart' */
|
|
9
10
|
filename?: string;
|
|
@@ -17,4 +18,4 @@ export interface ExportImageOptions {
|
|
|
17
18
|
/**
|
|
18
19
|
* html2canvas-pro を使用してエクスポートする(Shadow DOMネイティブ対応版)
|
|
19
20
|
*/
|
|
20
|
-
export declare function exportGanttWithHtml2Canvas(chartElement:
|
|
21
|
+
export declare function exportGanttWithHtml2Canvas(chartElement: GanttChartElement, format?: 'png' | 'pdf', options?: ExportImageOptions): Promise<string | Blob>;
|
|
@@ -38,6 +38,8 @@ export declare class GanttChartElement extends LitElement {
|
|
|
38
38
|
private isExporting;
|
|
39
39
|
private focusedTaskId;
|
|
40
40
|
private focusedRowId;
|
|
41
|
+
private zoomPxPerDay;
|
|
42
|
+
private zoomPxPerMonth;
|
|
41
43
|
private _layoutCache;
|
|
42
44
|
private resizeObserver;
|
|
43
45
|
private _cachedSelectedTaskIds;
|
|
@@ -45,7 +47,18 @@ export declare class GanttChartElement extends LitElement {
|
|
|
45
47
|
private _cachedCurrentOption;
|
|
46
48
|
private _lastOptionRef;
|
|
47
49
|
private _lastLabelWidth;
|
|
50
|
+
private _lastZoomPxPerDay;
|
|
51
|
+
private _lastZoomPxPerMonth;
|
|
52
|
+
private _scrollContainer;
|
|
48
53
|
private get displayRows();
|
|
54
|
+
/**
|
|
55
|
+
* 現在有効な pxPerDay(ズームオーバーライドがあればそちらを優先)
|
|
56
|
+
*/
|
|
57
|
+
private get effectivePxPerDay();
|
|
58
|
+
/**
|
|
59
|
+
* 現在有効な pxPerMonth(ズームオーバーライドがあればそちらを優先)
|
|
60
|
+
*/
|
|
61
|
+
private get effectivePxPerMonth();
|
|
49
62
|
static styles: import("lit").CSSResult;
|
|
50
63
|
protected firstUpdated(): void;
|
|
51
64
|
connectedCallback(): void;
|
|
@@ -99,6 +112,15 @@ export declare class GanttChartElement extends LitElement {
|
|
|
99
112
|
rowId: string;
|
|
100
113
|
date: Date;
|
|
101
114
|
} | null;
|
|
115
|
+
/**
|
|
116
|
+
* 各行のY座標(カレンダーヘッダーを含まない、行領域の上端からの相対位置)
|
|
117
|
+
* のレイアウト情報を取得します。
|
|
118
|
+
*/
|
|
119
|
+
getRowPositions(): {
|
|
120
|
+
top: number;
|
|
121
|
+
height: number;
|
|
122
|
+
bottom: number;
|
|
123
|
+
}[];
|
|
102
124
|
/**
|
|
103
125
|
* html2canvas を使用してガントチャートを画像としてエクスポートする。
|
|
104
126
|
* (Shadow DOMネイティブ対応版 html2canvas-pro を使用)
|
|
@@ -106,6 +128,23 @@ export declare class GanttChartElement extends LitElement {
|
|
|
106
128
|
* @param options エクスポートオプション。
|
|
107
129
|
*/
|
|
108
130
|
exportImage(format?: 'png' | 'pdf', options?: ExportImageOptions): Promise<string | Blob>;
|
|
131
|
+
/**
|
|
132
|
+
* Ctrl/Cmd + マウスホイールによるズーム処理
|
|
133
|
+
*/
|
|
134
|
+
private handleWheel;
|
|
135
|
+
/**
|
|
136
|
+
* 指定した pxPerDay(または pxPerMonth)にズームを設定する。
|
|
137
|
+
* @param value ズーム先の pxPerDay(月単位モード時は pxPerMonth)
|
|
138
|
+
*/
|
|
139
|
+
zoomTo(value: number): void;
|
|
140
|
+
/**
|
|
141
|
+
* 全タスクが表示領域に収まるようにズームレベルを自動調整する。
|
|
142
|
+
*/
|
|
143
|
+
zoomToFit(): void;
|
|
144
|
+
/**
|
|
145
|
+
* ズームをリセットし、option で設定された元のスケールに戻す。
|
|
146
|
+
*/
|
|
147
|
+
resetZoom(): void;
|
|
109
148
|
private clearSelection;
|
|
110
149
|
private handleKeyDown;
|
|
111
150
|
/**
|
|
@@ -30,6 +30,7 @@ export declare class GanttRowElement extends LitElement {
|
|
|
30
30
|
selectedTaskIds: string[];
|
|
31
31
|
focusedTaskId: string | null;
|
|
32
32
|
isExporting: boolean;
|
|
33
|
+
criticalPathTaskIds: string[];
|
|
33
34
|
private _cachedMonthGridLines;
|
|
34
35
|
private _cachedMonthGridStartTime;
|
|
35
36
|
private _cachedMonthGridEndTime;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GanttRow } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 依存関係グラフからクリティカルパス上のタスクIDの集合を計算する。
|
|
4
|
+
*
|
|
5
|
+
* 手動スケジュールのガントチャート向けに最適化:
|
|
6
|
+
* - 依存関係グラフの中で最長のチェーン(最終タスクの終了時刻が最も遅いパス)を検出する
|
|
7
|
+
* - 依存関係に参加していない独立タスクはクリティカルパス計算から除外する
|
|
8
|
+
*
|
|
9
|
+
* アルゴリズム:
|
|
10
|
+
* 1. 全タスクを走査し依存関係グラフを構築
|
|
11
|
+
* 2. 依存関係に参加しているタスクのみを抽出
|
|
12
|
+
* 3. トポロジカルソート順に前方パス(最早終了時刻 EF)を計算
|
|
13
|
+
* 4. 最終タスクから逆方向にバックトラックし、最長パスを構成するタスクを収集
|
|
14
|
+
*
|
|
15
|
+
* @param rows ガントチャートの全行データ
|
|
16
|
+
* @returns クリティカルパス上のタスクID集合
|
|
17
|
+
*/
|
|
18
|
+
export declare function computeCriticalPath(rows: GanttRow[]): Set<string>;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -316,6 +316,10 @@ export interface GanttChartOptionDependency {
|
|
|
316
316
|
lineStyle?: DependencyLineStyle;
|
|
317
317
|
/** orthogonalスタイル時の角丸半径 (px)。デフォルト: 8 */
|
|
318
318
|
cornerRadius?: number;
|
|
319
|
+
/** 接続ポイント(丸印)を表示するかどうか (デフォルト: true) */
|
|
320
|
+
showConnectors?: boolean;
|
|
321
|
+
/** クリティカルパスを表示するかどうか (デフォルト: false) */
|
|
322
|
+
showCriticalPath?: boolean;
|
|
319
323
|
}
|
|
320
324
|
/**
|
|
321
325
|
* ガントチャート全体のオプション設定
|
|
@@ -358,6 +362,17 @@ export interface GanttChartOption {
|
|
|
358
362
|
/** Shift+矢印キーでのタスク移動量(分)。省略時は snapDuration を使用 */
|
|
359
363
|
moveStep?: number;
|
|
360
364
|
};
|
|
365
|
+
/** ズーム機能の設定 */
|
|
366
|
+
zoom?: {
|
|
367
|
+
/** ズーム機能を有効にするか (デフォルト: false) */
|
|
368
|
+
enabled?: boolean;
|
|
369
|
+
/** 最小 pxPerDay (デフォルト: 2)。pxPerMonth モードの場合は最小 pxPerMonth */
|
|
370
|
+
min?: number;
|
|
371
|
+
/** 最大 pxPerDay (デフォルト: 200)。pxPerMonth モードの場合は最大 pxPerMonth */
|
|
372
|
+
max?: number;
|
|
373
|
+
/** ホイール1回あたりのズーム倍率 (デフォルト: 1.2) */
|
|
374
|
+
step?: number;
|
|
375
|
+
};
|
|
361
376
|
}
|
|
362
377
|
/**
|
|
363
378
|
* タスク更新イベントの詳細データ
|
|
@@ -561,6 +576,8 @@ export interface ThemeColorPalette {
|
|
|
561
576
|
thursday?: string;
|
|
562
577
|
/** 金曜日の背景色 (オプション) */
|
|
563
578
|
friday?: string;
|
|
579
|
+
/** クリティカルパスの色 (オプション) */
|
|
580
|
+
criticalPath?: string;
|
|
564
581
|
}
|
|
565
582
|
/**
|
|
566
583
|
* テーマセット (light/dark)
|
|
@@ -610,3 +627,12 @@ export interface TaskDeleteEventDetail {
|
|
|
610
627
|
/** 元のキーボードイベント */
|
|
611
628
|
event: KeyboardEvent;
|
|
612
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* ズーム変更イベントの詳細データ
|
|
632
|
+
*/
|
|
633
|
+
export interface ZoomChangeEventDetail {
|
|
634
|
+
/** ズーム後の pxPerDay */
|
|
635
|
+
pxPerDay: number;
|
|
636
|
+
/** ズーム後の pxPerMonth(月単位モード時のみ) */
|
|
637
|
+
pxPerMonth?: number;
|
|
638
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/moguchart-core.mjs
CHANGED
|
@@ -178,7 +178,8 @@ var k = {
|
|
|
178
178
|
rowSelectedHeader: "#dbeafe",
|
|
179
179
|
rowHiddenBg: "repeating-linear-gradient(45deg, #f3f4f6, #f3f4f6 10px, #e5e7eb 10px, #e5e7eb 20px)",
|
|
180
180
|
currentTimeLine: "rgba(239, 68, 68, 0.5)",
|
|
181
|
-
currentTimeLineText: "#ffffff"
|
|
181
|
+
currentTimeLineText: "#ffffff",
|
|
182
|
+
criticalPath: "rgba(220, 38, 38, 0.85)"
|
|
182
183
|
},
|
|
183
184
|
dark: {
|
|
184
185
|
bg: "#1e293b",
|
|
@@ -205,7 +206,8 @@ var k = {
|
|
|
205
206
|
rowSelectedHeader: "#1c2738",
|
|
206
207
|
rowHiddenBg: "repeating-linear-gradient(45deg, #0f172a, #0f172a 10px, #1e293b 10px, #1e293b 20px)",
|
|
207
208
|
currentTimeLine: "rgba(239, 68, 68, 0.5)",
|
|
208
|
-
currentTimeLineText: "#ffffff"
|
|
209
|
+
currentTimeLineText: "#ffffff",
|
|
210
|
+
criticalPath: "rgba(248, 113, 113, 0.85)"
|
|
209
211
|
}
|
|
210
212
|
}, M = (e, t, n, r) => {
|
|
211
213
|
if (r !== void 0) {
|
|
@@ -286,13 +288,13 @@ function B(e, t, n, r) {
|
|
|
286
288
|
//#region src/components/gantt-bar.ts
|
|
287
289
|
var V = class extends e {
|
|
288
290
|
constructor(...e) {
|
|
289
|
-
super(...e), this.lane = 0, this.selected = !1, this.focused = !1, this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragActive = !1, this.multiDragSameRow = !1, this.connectorDropTarget = !1, this.isExporting = !1, this._currentDragCursor = null, this._dragAnimationFrame = null, this._wasDragging = !1, this._connectorEdgeThreshold = 30, this.handleKeyDown = (e) => {
|
|
291
|
+
super(...e), this.lane = 0, this.selected = !1, this.focused = !1, this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragActive = !1, this.multiDragSameRow = !1, this.connectorDropTarget = !1, this.isExporting = !1, this.isCriticalPath = !1, this._currentDragCursor = null, this._dragAnimationFrame = null, this._wasDragging = !1, this._connectorEdgeThreshold = 30, this.handleKeyDown = (e) => {
|
|
290
292
|
(e.key === "Control" || e.key === "Alt") && this.updateCursor(!0);
|
|
291
293
|
}, this.handleKeyUp = (e) => {
|
|
292
294
|
(e.key === "Control" || e.key === "Alt") && this.updateCursor(!1);
|
|
293
295
|
}, this.onMouseMoveOnBar = (e) => {
|
|
294
296
|
let t = this.shadowRoot?.querySelector(".task-group");
|
|
295
|
-
if (!t || this.option.readOnly) return;
|
|
297
|
+
if (!t || this.option.readOnly || this.option.dependency?.showConnectors === !1) return;
|
|
296
298
|
let n = t.getBoundingClientRect(), r = e.clientX - n.left, i = r <= this._connectorEdgeThreshold, a = r >= n.width - this._connectorEdgeThreshold, o = this.shadowRoot?.querySelector(".connector-left"), s = this.shadowRoot?.querySelector(".connector-right");
|
|
297
299
|
o && o.classList.toggle("show-connector", i), s && s.classList.toggle("show-connector", a);
|
|
298
300
|
};
|
|
@@ -401,6 +403,15 @@ var V = class extends e {
|
|
|
401
403
|
outline-offset: 2px;
|
|
402
404
|
box-shadow: 0 0 12px rgba(59, 130, 246, 0.6);
|
|
403
405
|
}
|
|
406
|
+
:host([critical-path]) .bar {
|
|
407
|
+
outline: 2px solid var(--critical-path-color, rgba(220, 38, 38, 0.85));
|
|
408
|
+
outline-offset: 1px;
|
|
409
|
+
}
|
|
410
|
+
:host([selected][critical-path]) .bar {
|
|
411
|
+
outline: 2px solid #3b82f6;
|
|
412
|
+
outline-offset: 1px;
|
|
413
|
+
box-shadow: 0 0 8px rgba(59, 130, 246, 0.5);
|
|
414
|
+
}
|
|
404
415
|
.bar-label {
|
|
405
416
|
color: white;
|
|
406
417
|
font-size: 12px;
|
|
@@ -806,7 +817,7 @@ var V = class extends e {
|
|
|
806
817
|
<div class="handle-left" @pointerdown="${(e) => this.onResizeStart(e, "left")}"></div>
|
|
807
818
|
<div class="handle-right" @pointerdown="${(e) => this.onResizeStart(e, "right")}"></div>
|
|
808
819
|
` : ""}
|
|
809
|
-
${s
|
|
820
|
+
${!s && this.option.dependency?.showConnectors !== !1 ? n`
|
|
810
821
|
<div
|
|
811
822
|
class="connector-left"
|
|
812
823
|
@pointerdown="${(e) => this.onConnectorDragStart(e, "start")}"
|
|
@@ -815,7 +826,7 @@ var V = class extends e {
|
|
|
815
826
|
class="connector-right"
|
|
816
827
|
@pointerdown="${(e) => this.onConnectorDragStart(e, "end")}"
|
|
817
828
|
></div>
|
|
818
|
-
`}
|
|
829
|
+
` : ""}
|
|
819
830
|
</div>
|
|
820
831
|
`;
|
|
821
832
|
}
|
|
@@ -833,12 +844,16 @@ B([s({ type: Object })], V.prototype, "task", void 0), B([s({ type: Object })],
|
|
|
833
844
|
})], V.prototype, "connectorDropTarget", void 0), B([s({
|
|
834
845
|
type: Boolean,
|
|
835
846
|
reflect: !0
|
|
836
|
-
})], V.prototype, "isExporting", void 0),
|
|
847
|
+
})], V.prototype, "isExporting", void 0), B([s({
|
|
848
|
+
type: Boolean,
|
|
849
|
+
reflect: !0,
|
|
850
|
+
attribute: "critical-path"
|
|
851
|
+
})], V.prototype, "isCriticalPath", void 0), V = B([o("gantt-bar")], V);
|
|
837
852
|
//#endregion
|
|
838
853
|
//#region src/components/gantt-calendar.ts
|
|
839
854
|
var H = class extends e {
|
|
840
855
|
constructor(...e) {
|
|
841
|
-
super(...e), this.theme = "light", this.currentTime = /* @__PURE__ */ new Date(), this.hoveredMilestoneId = null, this._cachedDays = null, this._cachedMonths = null, this._cachedYears = null, this._cachedWeeks = null, this._cachedStartTime = 0, this._cachedEndTime = 0, this._cachedPxPerDay = 0, this._cachedPxPerMonth = void 0, this._cachedWeekStartDay = -1;
|
|
856
|
+
super(...e), this.theme = "light", this.currentTime = /* @__PURE__ */ new Date(), this.isExporting = !1, this.hoveredMilestoneId = null, this._cachedDays = null, this._cachedMonths = null, this._cachedYears = null, this._cachedWeeks = null, this._cachedStartTime = 0, this._cachedEndTime = 0, this._cachedPxPerDay = 0, this._cachedPxPerMonth = void 0, this._cachedWeekStartDay = -1;
|
|
842
857
|
}
|
|
843
858
|
injectCustomContent(e, t, n) {
|
|
844
859
|
let r = e.querySelector(`.${n}`);
|
|
@@ -1268,7 +1283,7 @@ var H = class extends e {
|
|
|
1268
1283
|
}
|
|
1269
1284
|
return a;
|
|
1270
1285
|
})()}
|
|
1271
|
-
${this.option.calendar.showCurrentTime && this.option.calendar.showCurrentTimeBadge === !0 && this.currentTime >= this.option.calendar.start && this.currentTime <= this.option.calendar.end ? n`
|
|
1286
|
+
${!this.isExporting && this.option.calendar.showCurrentTime && this.option.calendar.showCurrentTimeBadge === !0 && this.currentTime >= this.option.calendar.start && this.currentTime <= this.option.calendar.end ? n`
|
|
1272
1287
|
<div
|
|
1273
1288
|
class="current-time-badge"
|
|
1274
1289
|
style="
|
|
@@ -1333,7 +1348,7 @@ var H = class extends e {
|
|
|
1333
1348
|
`;
|
|
1334
1349
|
}
|
|
1335
1350
|
};
|
|
1336
|
-
B([s({ type: Object })], H.prototype, "option", void 0), B([s({ type: String })], H.prototype, "theme", void 0), B([s({ type: Object })], H.prototype, "currentTime", void 0), B([s({ type: String })], H.prototype, "hoveredMilestoneId", void 0), B([s({ attribute: !1 })], H.prototype, "cornerContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarMonthContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarDayContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarWeekContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarHourContent", void 0), H = B([o("gantt-calendar")], H);
|
|
1351
|
+
B([s({ type: Object })], H.prototype, "option", void 0), B([s({ type: String })], H.prototype, "theme", void 0), B([s({ type: Object })], H.prototype, "currentTime", void 0), B([s({ type: Boolean })], H.prototype, "isExporting", void 0), B([s({ type: String })], H.prototype, "hoveredMilestoneId", void 0), B([s({ attribute: !1 })], H.prototype, "cornerContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarMonthContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarDayContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarWeekContent", void 0), B([s({ attribute: !1 })], H.prototype, "calendarHourContent", void 0), H = B([o("gantt-calendar")], H);
|
|
1337
1352
|
//#endregion
|
|
1338
1353
|
//#region src/components/gantt-row-background.ts
|
|
1339
1354
|
var U = class extends e {
|
|
@@ -1412,7 +1427,7 @@ B([s({ type: Object })], U.prototype, "option", void 0), B([s({ type: String })]
|
|
|
1412
1427
|
//#region src/components/gantt-row.ts
|
|
1413
1428
|
var W = class extends e {
|
|
1414
1429
|
constructor(...e) {
|
|
1415
|
-
super(...e), this.isDragTarget = !1, this.draggingTask = null, this.draggingTaskIds = [], this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragSameRow = !1, this.externalDragTask = null, this.theme = "light", this.isSelected = !1, this.dropPosition = null, this.selectedTaskIds = [], this.focusedTaskId = null, this.isExporting = !1, this._cachedMonthGridLines = null, this._cachedMonthGridStartTime = 0, this._cachedMonthGridEndTime = 0, this._cachedMonthGridPxPerDay = 0, this._cachedMonthGridPxPerMonth = 0;
|
|
1430
|
+
super(...e), this.isDragTarget = !1, this.draggingTask = null, this.draggingTaskIds = [], this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragSameRow = !1, this.externalDragTask = null, this.theme = "light", this.isSelected = !1, this.dropPosition = null, this.selectedTaskIds = [], this.focusedTaskId = null, this.isExporting = !1, this.criticalPathTaskIds = [], this._cachedMonthGridLines = null, this._cachedMonthGridStartTime = 0, this._cachedMonthGridEndTime = 0, this._cachedMonthGridPxPerDay = 0, this._cachedMonthGridPxPerMonth = 0;
|
|
1416
1431
|
}
|
|
1417
1432
|
getDateX(e) {
|
|
1418
1433
|
return M(e, this.option.calendar.start, this.option.calendar.pxPerDay, this.option.calendar.pxPerMonth);
|
|
@@ -1786,6 +1801,7 @@ var W = class extends e {
|
|
|
1786
1801
|
.multiDragActive="${c}"
|
|
1787
1802
|
.multiDragSameRow="${this.multiDragSameRow}"
|
|
1788
1803
|
.isExporting="${this.isExporting}"
|
|
1804
|
+
.isCriticalPath="${this.criticalPathTaskIds.includes(e.id)}"
|
|
1789
1805
|
/>
|
|
1790
1806
|
`;
|
|
1791
1807
|
})}
|
|
@@ -1840,7 +1856,7 @@ B([s({ type: Object })], W.prototype, "row", void 0), B([s({ type: Object })], W
|
|
|
1840
1856
|
})], W.prototype, "isSelected", void 0), B([s({ type: String })], W.prototype, "dropPosition", void 0), B([s({ type: Array })], W.prototype, "selectedTaskIds", void 0), B([s({ type: String })], W.prototype, "focusedTaskId", void 0), B([s({
|
|
1841
1857
|
type: Boolean,
|
|
1842
1858
|
reflect: !0
|
|
1843
|
-
})], W.prototype, "isExporting", void 0), W = B([o("gantt-row")], W);
|
|
1859
|
+
})], W.prototype, "isExporting", void 0), B([s({ type: Array })], W.prototype, "criticalPathTaskIds", void 0), W = B([o("gantt-row")], W);
|
|
1844
1860
|
//#endregion
|
|
1845
1861
|
//#region src/components/gantt-chart-dependency-path.ts
|
|
1846
1862
|
function G(e, t, n, r, i, a, o, s) {
|
|
@@ -1986,6 +2002,9 @@ var K = t`
|
|
|
1986
2002
|
.dependency-group:hover .dependency-hit-area ~ .dependency-line {
|
|
1987
2003
|
opacity: 1;
|
|
1988
2004
|
}
|
|
2005
|
+
.dependency-line.critical-path {
|
|
2006
|
+
stroke-width: 3;
|
|
2007
|
+
}
|
|
1989
2008
|
.current-time-line {
|
|
1990
2009
|
position: absolute;
|
|
1991
2010
|
width: 2px;
|
|
@@ -2050,6 +2069,9 @@ function q(e, t) {
|
|
|
2050
2069
|
fill: none;
|
|
2051
2070
|
opacity: 0.7;
|
|
2052
2071
|
}
|
|
2072
|
+
.dependency-line.critical-path {
|
|
2073
|
+
stroke: ${n.criticalPath ?? n.dependencyLine};
|
|
2074
|
+
}
|
|
2053
2075
|
.header-resizer {
|
|
2054
2076
|
width: 4px;
|
|
2055
2077
|
cursor: col-resize;
|
|
@@ -2081,20 +2103,52 @@ async function Y(e, t = "png", n = {}) {
|
|
|
2081
2103
|
if (o && l > o) {
|
|
2082
2104
|
let t = 50, n = e.shadowRoot?.querySelector("gantt-calendar");
|
|
2083
2105
|
n && n.offsetHeight > 0 ? t = n.offsetHeight : e.calendarHeight && (t = e.calendarHeight);
|
|
2084
|
-
let r = u.height / l, i =
|
|
2106
|
+
let r = u.height / l, i = l - t, a = o - t, s = [];
|
|
2107
|
+
typeof e.getRowPositions == "function" && (s = e.getRowPositions().map((e) => e.bottom));
|
|
2108
|
+
let c = [0], d = 0;
|
|
2109
|
+
if (a > 0) for (; d < i;) {
|
|
2110
|
+
let e = d + a;
|
|
2111
|
+
if (e >= i) {
|
|
2112
|
+
c.push(i);
|
|
2113
|
+
break;
|
|
2114
|
+
}
|
|
2115
|
+
let t = -1;
|
|
2116
|
+
for (let n = 0; n < s.length; n++) {
|
|
2117
|
+
let r = s[n];
|
|
2118
|
+
r > d && r <= e && (t = Math.max(t, r));
|
|
2119
|
+
}
|
|
2120
|
+
if (t === -1) for (let e = 0; e < s.length; e++) {
|
|
2121
|
+
let n = s[e];
|
|
2122
|
+
if (n > d) {
|
|
2123
|
+
t = n;
|
|
2124
|
+
break;
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
(t === -1 || t === d) && (t = e), c.push(t), d = t;
|
|
2128
|
+
}
|
|
2129
|
+
else c.push(i);
|
|
2130
|
+
let f = c.length - 1;
|
|
2085
2131
|
if (f > 0) {
|
|
2086
|
-
let e = Math.
|
|
2087
|
-
n
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2132
|
+
let e = Math.floor(t * r), n = u.width, i = 0, a = [];
|
|
2133
|
+
for (let n = 0; n < f; n++) {
|
|
2134
|
+
let o = c[n], s = c[n + 1], l = Math.round((t + o) * r), u = Math.round((t + s) * r), d = u - l;
|
|
2135
|
+
a.push({
|
|
2136
|
+
srcStart: l,
|
|
2137
|
+
srcEnd: u,
|
|
2138
|
+
destHeight: d
|
|
2139
|
+
}), i += e + d;
|
|
2140
|
+
}
|
|
2141
|
+
let o = document.createElement("canvas");
|
|
2142
|
+
o.width = n, o.height = i;
|
|
2143
|
+
let s = o.getContext("2d");
|
|
2144
|
+
if (s) {
|
|
2145
|
+
let t = 0;
|
|
2146
|
+
for (let r = 0; r < f; r++) {
|
|
2147
|
+
s.drawImage(u, 0, 0, n, e, 0, t, n, e), t += e;
|
|
2148
|
+
let i = a[r];
|
|
2149
|
+
s.drawImage(u, 0, i.srcStart, n, i.destHeight, 0, t, n, i.destHeight), t += i.destHeight;
|
|
2096
2150
|
}
|
|
2097
|
-
u =
|
|
2151
|
+
u = o, l = i / r;
|
|
2098
2152
|
} else console.warn("[export] Failed to get 2D context for new canvas. It might be too large.");
|
|
2099
2153
|
}
|
|
2100
2154
|
}
|
|
@@ -2112,10 +2166,78 @@ async function Y(e, t = "png", n = {}) {
|
|
|
2112
2166
|
}
|
|
2113
2167
|
}
|
|
2114
2168
|
//#endregion
|
|
2169
|
+
//#region src/core/critical-path.ts
|
|
2170
|
+
function X(e) {
|
|
2171
|
+
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
|
|
2172
|
+
for (let n of e) for (let e of n.tasks) {
|
|
2173
|
+
let n = e.dependencies ?? [], i = e.start instanceof Date ? e.start.getTime() : new Date(e.start).getTime(), a = e.end instanceof Date ? e.end.getTime() : new Date(e.end).getTime();
|
|
2174
|
+
isNaN(i) || isNaN(a) || (t.set(e.id, {
|
|
2175
|
+
start: i,
|
|
2176
|
+
end: a,
|
|
2177
|
+
duration: a - i,
|
|
2178
|
+
dependencies: n
|
|
2179
|
+
}), r.set(e.id, 0));
|
|
2180
|
+
}
|
|
2181
|
+
let i = /* @__PURE__ */ new Set();
|
|
2182
|
+
for (let [e, a] of t) {
|
|
2183
|
+
let o = 0;
|
|
2184
|
+
for (let r of a.dependencies) if (t.has(r)) {
|
|
2185
|
+
o++;
|
|
2186
|
+
let t = n.get(r) ?? [];
|
|
2187
|
+
t.push(e), n.set(r, t), i.add(e), i.add(r);
|
|
2188
|
+
}
|
|
2189
|
+
r.set(e, o);
|
|
2190
|
+
}
|
|
2191
|
+
if (i.size < 2) return /* @__PURE__ */ new Set();
|
|
2192
|
+
let a = [];
|
|
2193
|
+
for (let e of i) (r.get(e) ?? 0) === 0 && a.push(e);
|
|
2194
|
+
let o = [];
|
|
2195
|
+
for (; a.length > 0;) {
|
|
2196
|
+
let e = a.shift();
|
|
2197
|
+
o.push(e);
|
|
2198
|
+
for (let t of n.get(e) ?? []) {
|
|
2199
|
+
if (!i.has(t)) continue;
|
|
2200
|
+
let e = (r.get(t) ?? 0) - 1;
|
|
2201
|
+
r.set(t, e), e === 0 && a.push(t);
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
if (o.length < i.size) {
|
|
2205
|
+
let e = new Set(o);
|
|
2206
|
+
for (let t of i) e.has(t) || i.delete(t);
|
|
2207
|
+
if (i.size < 2) return /* @__PURE__ */ new Set();
|
|
2208
|
+
}
|
|
2209
|
+
let s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map();
|
|
2210
|
+
for (let e of o) {
|
|
2211
|
+
let n = t.get(e);
|
|
2212
|
+
if (!n) continue;
|
|
2213
|
+
let r = n.dependencies.filter((e) => s.has(e));
|
|
2214
|
+
if (r.length === 0) s.set(e, n.end), c.set(e, null);
|
|
2215
|
+
else {
|
|
2216
|
+
let t = -Infinity, i = null;
|
|
2217
|
+
for (let e of r) {
|
|
2218
|
+
let r = s.get(e) + n.duration;
|
|
2219
|
+
r > t && (t = r, i = e);
|
|
2220
|
+
}
|
|
2221
|
+
n.end > t && (t = n.end), s.set(e, t), c.set(e, i);
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
let l = [];
|
|
2225
|
+
for (let e of o) (n.get(e) ?? []).filter((e) => i.has(e)).length === 0 && l.push(e);
|
|
2226
|
+
if (l.length === 0) return /* @__PURE__ */ new Set();
|
|
2227
|
+
let u = l[0], d = s.get(l[0]) ?? 0;
|
|
2228
|
+
for (let e = 1; e < l.length; e++) {
|
|
2229
|
+
let t = s.get(l[e]) ?? 0;
|
|
2230
|
+
t > d && (d = t, u = l[e]);
|
|
2231
|
+
}
|
|
2232
|
+
let f = /* @__PURE__ */ new Set(), p = u;
|
|
2233
|
+
for (; p !== null;) f.add(p), p = c.get(p) ?? null;
|
|
2234
|
+
return f.size <= 1 ? /* @__PURE__ */ new Set() : f;
|
|
2235
|
+
}
|
|
2236
|
+
//#endregion
|
|
2115
2237
|
//#region src/components/gantt-chart.ts
|
|
2116
|
-
var
|
|
2238
|
+
var Z = class extends e {
|
|
2117
2239
|
constructor(...e) {
|
|
2118
|
-
super(...e), this.rows = [], this.theme = "light", this.selectedRowIds = [], this.selectedTaskIds = [], this.externalDraggingTask = null, this.selectedRows = /* @__PURE__ */ new Set(), this.selectedTasks = /* @__PURE__ */ new Set(), this.lastClickedRowId = null, this.virtualScrollTop = 0, this.dragTargetRowIndex = null, this.draggingTask = null, this.draggingTaskIds = [], this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragSameRow = !1, this.viewportHeight = 400, this.dragOverlayInfo = null, this.calendarHeight = 0, this.tooltip = null, this.dragOverRowId = null, this.dragOverPosition = null, this.currentTime = /* @__PURE__ */ new Date(), this.dragPreview = null, this.currentRowHeaderWidth = 150, this.isResizingHeader = !1, this.hoveredMilestoneId = null, this.cursorLineX = null, this.connectorDrag = null, this._systemThemeMediaQuery = null, this.isExporting = !1, this.focusedTaskId = null, this.focusedRowId = null, this._layoutCache = null, this.resizeObserver = null, this._cachedSelectedTaskIds = [], this._cachedSelectedTasksSize = -1, this._cachedCurrentOption = null, this._lastOptionRef = null, this._lastLabelWidth = -1, this.handleSystemThemeChange = (e) => {
|
|
2240
|
+
super(...e), this.rows = [], this.theme = "light", this.selectedRowIds = [], this.selectedTaskIds = [], this.externalDraggingTask = null, this.selectedRows = /* @__PURE__ */ new Set(), this.selectedTasks = /* @__PURE__ */ new Set(), this.lastClickedRowId = null, this.virtualScrollTop = 0, this.dragTargetRowIndex = null, this.draggingTask = null, this.draggingTaskIds = [], this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragSameRow = !1, this.viewportHeight = 400, this.dragOverlayInfo = null, this.calendarHeight = 0, this.tooltip = null, this.dragOverRowId = null, this.dragOverPosition = null, this.currentTime = /* @__PURE__ */ new Date(), this.dragPreview = null, this.currentRowHeaderWidth = 150, this.isResizingHeader = !1, this.hoveredMilestoneId = null, this.cursorLineX = null, this.connectorDrag = null, this._systemThemeMediaQuery = null, this.isExporting = !1, this.focusedTaskId = null, this.focusedRowId = null, this.zoomPxPerDay = null, this.zoomPxPerMonth = null, this._layoutCache = null, this.resizeObserver = null, this._cachedSelectedTaskIds = [], this._cachedSelectedTasksSize = -1, this._cachedCurrentOption = null, this._lastOptionRef = null, this._lastLabelWidth = -1, this._lastZoomPxPerDay = null, this._lastZoomPxPerMonth = null, this._scrollContainer = null, this.handleSystemThemeChange = (e) => {
|
|
2119
2241
|
(this.option?.theme === "system" || this.option?.theme !== "light" && this.option?.theme !== "dark") && (this.theme = e.matches ? "dark" : "light");
|
|
2120
2242
|
}, this.handleScroll = (e) => {
|
|
2121
2243
|
let t = e.target;
|
|
@@ -2137,6 +2259,26 @@ var X = class extends e {
|
|
|
2137
2259
|
this.cursorLineX = r;
|
|
2138
2260
|
}, this.handleContainerMouseLeave = () => {
|
|
2139
2261
|
this.cursorLineX = null;
|
|
2262
|
+
}, this.handleWheel = (e) => {
|
|
2263
|
+
if (!e.ctrlKey && !e.metaKey || this.option.zoom?.enabled !== !0) return;
|
|
2264
|
+
e.preventDefault();
|
|
2265
|
+
let t = this._scrollContainer;
|
|
2266
|
+
if (!t) return;
|
|
2267
|
+
let n = t.getBoundingClientRect(), r = this.currentRowHeaderWidth, i = e.clientX - n.left + t.scrollLeft - r, a = this.effectivePxPerMonth !== void 0, o = a ? this.effectivePxPerMonth : this.effectivePxPerDay, s = this.option.zoom?.step ?? 1.2, c = a ? 20 : 2, l = a ? 600 : 200, u = this.option.zoom?.min ?? c, d = this.option.zoom?.max ?? l, f = e.deltaY > 0 ? 1 / s : s, p = Math.max(u, Math.min(d, o * f));
|
|
2268
|
+
if (p === o) return;
|
|
2269
|
+
a ? this.zoomPxPerMonth = p : this.zoomPxPerDay = p;
|
|
2270
|
+
let m = p / o;
|
|
2271
|
+
this.updateComplete.then(() => {
|
|
2272
|
+
let e = i * m - i;
|
|
2273
|
+
t.scrollLeft += e;
|
|
2274
|
+
}), this.dispatchEvent(new CustomEvent("zoom-change", {
|
|
2275
|
+
detail: {
|
|
2276
|
+
pxPerDay: a ? this.effectivePxPerDay : p,
|
|
2277
|
+
pxPerMonth: a ? p : void 0
|
|
2278
|
+
},
|
|
2279
|
+
bubbles: !0,
|
|
2280
|
+
composed: !0
|
|
2281
|
+
}));
|
|
2140
2282
|
}, this.handleKeyDown = (e) => {
|
|
2141
2283
|
if (this.option.keyboard?.enabled === !1) return;
|
|
2142
2284
|
let t = e.composedPath()[0];
|
|
@@ -2187,6 +2329,12 @@ var X = class extends e {
|
|
|
2187
2329
|
get displayRows() {
|
|
2188
2330
|
return this.option.showHiddenRows ? this.rows : this.rows.filter((e) => e.visible !== !1);
|
|
2189
2331
|
}
|
|
2332
|
+
get effectivePxPerDay() {
|
|
2333
|
+
return this.zoomPxPerDay ?? this.option.calendar.pxPerDay ?? 50;
|
|
2334
|
+
}
|
|
2335
|
+
get effectivePxPerMonth() {
|
|
2336
|
+
return this.zoomPxPerMonth ?? this.option.calendar.pxPerMonth;
|
|
2337
|
+
}
|
|
2190
2338
|
static {
|
|
2191
2339
|
this.styles = K;
|
|
2192
2340
|
}
|
|
@@ -2195,16 +2343,16 @@ var X = class extends e {
|
|
|
2195
2343
|
let e = this.shadowRoot?.getElementById("calendar");
|
|
2196
2344
|
this.resizeObserver = new ResizeObserver((t) => {
|
|
2197
2345
|
for (let n of t) n.target === this ? this.viewportHeight = n.contentRect.height : n.target === e && (this.calendarHeight = n.target.offsetHeight);
|
|
2198
|
-
}), this.resizeObserver.observe(this), e && this.resizeObserver.observe(e);
|
|
2346
|
+
}), this.resizeObserver.observe(this), e && this.resizeObserver.observe(e), this._scrollContainer = this.shadowRoot?.querySelector(".scroll-container"), this._scrollContainer?.addEventListener("wheel", this.handleWheel, { passive: !1 });
|
|
2199
2347
|
}
|
|
2200
2348
|
connectedCallback() {
|
|
2201
2349
|
super.connectedCallback(), this._systemThemeMediaQuery = window.matchMedia ? window.matchMedia("(prefers-color-scheme: dark)") : null, this._systemThemeMediaQuery?.addEventListener("change", this.handleSystemThemeChange), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), this.setAttribute("aria-label", "Gantt Chart"), this.addEventListener("keydown", this.handleKeyDown), this.option?.theme === "system" || this.option?.theme !== "light" && this.option?.theme !== "dark" ? this.theme = this._systemThemeMediaQuery?.matches ? "dark" : "light" : this.theme = this.option.theme;
|
|
2202
2350
|
}
|
|
2203
2351
|
disconnectedCallback() {
|
|
2204
|
-
super.disconnectedCallback(), this.resizeObserver?.disconnect(), this.stopCurrentTimeTimer(), this._systemThemeMediaQuery?.removeEventListener("change", this.handleSystemThemeChange), this.removeEventListener("keydown", this.handleKeyDown);
|
|
2352
|
+
super.disconnectedCallback(), this.resizeObserver?.disconnect(), this.stopCurrentTimeTimer(), this._systemThemeMediaQuery?.removeEventListener("change", this.handleSystemThemeChange), this.removeEventListener("keydown", this.handleKeyDown), this._scrollContainer?.removeEventListener("wheel", this.handleWheel), this._scrollContainer = null;
|
|
2205
2353
|
}
|
|
2206
2354
|
willUpdate(e) {
|
|
2207
|
-
if (e.has("option") && (this.option?.theme === "light" || this.option?.theme === "dark" ? this.theme = this.option.theme : this._systemThemeMediaQuery && (this.theme = this._systemThemeMediaQuery.matches ? "dark" : "light")), e.has("option") && (this.setupCurrentTimeTimer(), this.isResizingHeader || (this.currentRowHeaderWidth = this.option.rowHeader?.width ?? 150)), (e.has("rows") || e.has("option") || e.has("currentRowHeaderWidth")) && (this._layoutCache = null), e.has("selectedRowIds")) {
|
|
2355
|
+
if (e.has("option") && (this.option?.theme === "light" || this.option?.theme === "dark" ? this.theme = this.option.theme : this._systemThemeMediaQuery && (this.theme = this._systemThemeMediaQuery.matches ? "dark" : "light")), e.has("option") && (this.setupCurrentTimeTimer(), this.isResizingHeader || (this.currentRowHeaderWidth = this.option.rowHeader?.width ?? 150), this.zoomPxPerDay = null, this.zoomPxPerMonth = null), (e.has("rows") || e.has("option") || e.has("currentRowHeaderWidth") || e.has("zoomPxPerDay") || e.has("zoomPxPerMonth")) && (this._layoutCache = null), e.has("selectedRowIds")) {
|
|
2208
2356
|
let e = new Set(this.selectedRowIds);
|
|
2209
2357
|
(e.size !== this.selectedRows.size || ![...e].every((e) => this.selectedRows.has(e))) && (this.selectedRows = e);
|
|
2210
2358
|
}
|
|
@@ -2317,7 +2465,7 @@ var X = class extends e {
|
|
|
2317
2465
|
r.addEventListener("pointermove", o), r.addEventListener("pointerup", s);
|
|
2318
2466
|
}
|
|
2319
2467
|
getDateX(e) {
|
|
2320
|
-
return M(e, this.option.calendar.start, this.
|
|
2468
|
+
return M(e, this.option.calendar.start, this.effectivePxPerDay, this.effectivePxPerMonth);
|
|
2321
2469
|
}
|
|
2322
2470
|
calculateLayout() {
|
|
2323
2471
|
if (this._layoutCache) return this._layoutCache;
|
|
@@ -2363,7 +2511,7 @@ var X = class extends e {
|
|
|
2363
2511
|
c && !l && (s = 0);
|
|
2364
2512
|
let u = n, d = r;
|
|
2365
2513
|
if (i !== void 0) {
|
|
2366
|
-
let e = this.
|
|
2514
|
+
let e = this.effectivePxPerDay, t = this.effectivePxPerMonth, a = this.getDateX(n), o = this.getDateX(r);
|
|
2367
2515
|
u = N(a + i, this.option.calendar.start, e, t), d = N(o + i, this.option.calendar.start, e, t);
|
|
2368
2516
|
}
|
|
2369
2517
|
(this.option.calendar.pxPerMonth || this.option.snapDuration && this.option.snapDuration >= 43200) && (u.getDate() > 15 && u.setMonth(u.getMonth() + 1), u.setDate(1), u.setHours(0, 0, 0, 0), d.getDate() > 15 && d.setMonth(d.getMonth() + 1), d.setDate(1), d.setHours(0, 0, 0, 0));
|
|
@@ -2445,7 +2593,7 @@ var X = class extends e {
|
|
|
2445
2593
|
A = this.rows.findIndex((t) => t.id === e.id);
|
|
2446
2594
|
}
|
|
2447
2595
|
if (D && i !== void 0) {
|
|
2448
|
-
let e = this.
|
|
2596
|
+
let e = this.effectivePxPerDay, t = this.effectivePxPerMonth;
|
|
2449
2597
|
if (O && A !== -1 && f !== A) {
|
|
2450
2598
|
let n = [...this.rows], r = { ...n[f] }, a = { ...n[A] };
|
|
2451
2599
|
r.tasks = [...r.tasks], a.tasks = [...a.tasks];
|
|
@@ -2619,7 +2767,7 @@ var X = class extends e {
|
|
|
2619
2767
|
let s = this.displayRows[o];
|
|
2620
2768
|
if (t) {
|
|
2621
2769
|
if ((this.dragOverRowId !== s.id || this.dragOverPosition !== null) && (this.dragOverRowId = s.id, this.dragOverPosition = null), this.externalDraggingTask) {
|
|
2622
|
-
let t = this.currentRowHeaderWidth, i = n.scrollLeft, a = e.clientX - r.left + i - t, o = this.
|
|
2770
|
+
let t = this.currentRowHeaderWidth, i = n.scrollLeft, a = e.clientX - r.left + i - t, o = this.effectivePxPerDay, c = this.effectivePxPerMonth, l = this.option.snapDuration ?? 1440, u = o / 1440 * l, d = N(Math.round(a / u) * u, this.option.calendar.start, o, c), f = this.externalDraggingTask.end.getTime() - this.externalDraggingTask.start.getTime(), p = new Date(d.getTime() + f);
|
|
2623
2771
|
(!this.dragPreview || this.dragPreview.rowId !== s.id || this.dragPreview.currentStart.getTime() !== d.getTime()) && (this.dragPreview = {
|
|
2624
2772
|
task: this.externalDraggingTask,
|
|
2625
2773
|
currentStart: d,
|
|
@@ -2669,7 +2817,7 @@ var X = class extends e {
|
|
|
2669
2817
|
end: i
|
|
2670
2818
|
}, o = this.shadowRoot?.querySelector(".scroll-container");
|
|
2671
2819
|
if (!o) return;
|
|
2672
|
-
let s = o.getBoundingClientRect(), c = o.scrollLeft, l = o.scrollTop, u = this.currentRowHeaderWidth, d = e.clientX - s.left + c - u, f = this.
|
|
2820
|
+
let s = o.getBoundingClientRect(), c = o.scrollLeft, l = o.scrollTop, u = this.currentRowHeaderWidth, d = e.clientX - s.left + c - u, f = this.effectivePxPerDay, p = this.effectivePxPerMonth, m = N(d, this.option.calendar.start, f, p), h = e.clientY - s.top + l - this.calendarHeight, { layouts: g } = this.calculateLayout(), _;
|
|
2673
2821
|
for (let e = 0; e < g.length; e++) {
|
|
2674
2822
|
let t = g[e];
|
|
2675
2823
|
if (h >= t.top && h < t.top + t.height) {
|
|
@@ -2732,7 +2880,7 @@ var X = class extends e {
|
|
|
2732
2880
|
}
|
|
2733
2881
|
}
|
|
2734
2882
|
if (c) {
|
|
2735
|
-
let t = e.clientX - n.left + r - a, i = this.
|
|
2883
|
+
let t = e.clientX - n.left + r - a, i = this.effectivePxPerDay, o = this.effectivePxPerMonth, s = N(t, this.option.calendar.start, i, o);
|
|
2736
2884
|
this.dispatchEvent(new CustomEvent("chart-contextmenu", {
|
|
2737
2885
|
detail: {
|
|
2738
2886
|
event: e,
|
|
@@ -2757,12 +2905,20 @@ var X = class extends e {
|
|
|
2757
2905
|
}
|
|
2758
2906
|
}
|
|
2759
2907
|
if (!l) return null;
|
|
2760
|
-
let u = e - r.left + i - o, d = this.
|
|
2908
|
+
let u = e - r.left + i - o, d = this.effectivePxPerDay, f = this.effectivePxPerMonth, p = N(u, this.option.calendar.start, d, f);
|
|
2761
2909
|
return {
|
|
2762
2910
|
rowId: l,
|
|
2763
2911
|
date: p
|
|
2764
2912
|
};
|
|
2765
2913
|
}
|
|
2914
|
+
getRowPositions() {
|
|
2915
|
+
let { layouts: e } = this.calculateLayout();
|
|
2916
|
+
return e.map((e) => ({
|
|
2917
|
+
top: e.top,
|
|
2918
|
+
height: e.height,
|
|
2919
|
+
bottom: e.top + e.height
|
|
2920
|
+
}));
|
|
2921
|
+
}
|
|
2766
2922
|
async exportImage(e = "png", t = {}) {
|
|
2767
2923
|
this.isExporting = !0, await this.updateComplete, await new Promise((e) => requestAnimationFrame(e));
|
|
2768
2924
|
try {
|
|
@@ -2771,6 +2927,52 @@ var X = class extends e {
|
|
|
2771
2927
|
this.isExporting = !1, await this.updateComplete;
|
|
2772
2928
|
}
|
|
2773
2929
|
}
|
|
2930
|
+
zoomTo(e) {
|
|
2931
|
+
let t = this.effectivePxPerMonth !== void 0, n = t ? 20 : 2, r = t ? 600 : 200, i = this.option.zoom?.min ?? n, a = this.option.zoom?.max ?? r, o = Math.max(i, Math.min(a, e));
|
|
2932
|
+
t ? this.zoomPxPerMonth = o : this.zoomPxPerDay = o, this.dispatchEvent(new CustomEvent("zoom-change", {
|
|
2933
|
+
detail: {
|
|
2934
|
+
pxPerDay: t ? this.effectivePxPerDay : o,
|
|
2935
|
+
pxPerMonth: t ? o : void 0
|
|
2936
|
+
},
|
|
2937
|
+
bubbles: !0,
|
|
2938
|
+
composed: !0
|
|
2939
|
+
}));
|
|
2940
|
+
}
|
|
2941
|
+
zoomToFit() {
|
|
2942
|
+
let e = this.shadowRoot?.querySelector(".scroll-container");
|
|
2943
|
+
if (!e) return;
|
|
2944
|
+
let t = null, n = null;
|
|
2945
|
+
for (let e of this.displayRows) for (let r of e.tasks) (!t || r.start < t) && (t = r.start), (!n || r.end > n) && (n = r.end);
|
|
2946
|
+
if (!t || !n) return;
|
|
2947
|
+
let r = this.currentRowHeaderWidth, i = e.clientWidth - r;
|
|
2948
|
+
if (!(i <= 0)) {
|
|
2949
|
+
if (this.effectivePxPerMonth !== void 0) {
|
|
2950
|
+
let e = (n.getFullYear() - t.getFullYear()) * 12 + (n.getMonth() - t.getMonth()), r = i / Math.max(1, e);
|
|
2951
|
+
this.zoomTo(r);
|
|
2952
|
+
} else {
|
|
2953
|
+
let e = n.getTime() - t.getTime(), r = i / Math.max(1, e / (1e3 * 60 * 60 * 24));
|
|
2954
|
+
this.zoomTo(r);
|
|
2955
|
+
}
|
|
2956
|
+
requestAnimationFrame(() => {
|
|
2957
|
+
let n = this.getDateX(t) + r;
|
|
2958
|
+
e.scrollLeft = Math.max(0, n - 10);
|
|
2959
|
+
});
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
resetZoom() {
|
|
2963
|
+
let e = this.zoomPxPerDay !== null || this.zoomPxPerMonth !== null;
|
|
2964
|
+
if (this.zoomPxPerDay = null, this.zoomPxPerMonth = null, e) {
|
|
2965
|
+
let e = this.option.calendar.pxPerMonth !== void 0;
|
|
2966
|
+
this.dispatchEvent(new CustomEvent("zoom-change", {
|
|
2967
|
+
detail: {
|
|
2968
|
+
pxPerDay: this.option.calendar.pxPerDay ?? 50,
|
|
2969
|
+
pxPerMonth: e ? this.option.calendar.pxPerMonth : void 0
|
|
2970
|
+
},
|
|
2971
|
+
bubbles: !0,
|
|
2972
|
+
composed: !0
|
|
2973
|
+
}));
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2774
2976
|
clearSelection() {
|
|
2775
2977
|
this.selectedRows.size === 0 && this.selectedTasks.size === 0 || (this.selectedRows.size > 0 && (this.selectedRows = /* @__PURE__ */ new Set(), this.dispatchEvent(new CustomEvent("row-selection-change", {
|
|
2776
2978
|
detail: { selectedIds: [] },
|
|
@@ -3024,13 +3226,18 @@ var X = class extends e {
|
|
|
3024
3226
|
}
|
|
3025
3227
|
render() {
|
|
3026
3228
|
let e = F(this.theme, this.option.customTheme), { layouts: t, taskCoords: r, totalHeight: a } = this.calculateLayout(), o = this.currentRowHeaderWidth;
|
|
3027
|
-
(this._lastOptionRef !== this.option || this._lastLabelWidth !== o) && (this._cachedCurrentOption = {
|
|
3229
|
+
(this._lastOptionRef !== this.option || this._lastLabelWidth !== o || this._lastZoomPxPerDay !== this.zoomPxPerDay || this._lastZoomPxPerMonth !== this.zoomPxPerMonth) && (this._cachedCurrentOption = {
|
|
3028
3230
|
...this.option,
|
|
3029
3231
|
rowHeader: {
|
|
3030
3232
|
...this.option.rowHeader,
|
|
3031
3233
|
width: o
|
|
3234
|
+
},
|
|
3235
|
+
calendar: {
|
|
3236
|
+
...this.option.calendar,
|
|
3237
|
+
pxPerDay: this.effectivePxPerDay,
|
|
3238
|
+
pxPerMonth: this.effectivePxPerMonth
|
|
3032
3239
|
}
|
|
3033
|
-
}, this._lastOptionRef = this.option, this._lastLabelWidth = o);
|
|
3240
|
+
}, this._lastOptionRef = this.option, this._lastLabelWidth = o, this._lastZoomPxPerDay = this.zoomPxPerDay, this._lastZoomPxPerMonth = this.zoomPxPerMonth);
|
|
3034
3241
|
let s = this._cachedCurrentOption, c = 0, l = this.displayRows.length - 1;
|
|
3035
3242
|
if (!this.isExporting) {
|
|
3036
3243
|
for (let e = 0; e < t.length; e++) if (t[e].top + t[e].height > this.virtualScrollTop) {
|
|
@@ -3042,7 +3249,7 @@ var X = class extends e {
|
|
|
3042
3249
|
break;
|
|
3043
3250
|
}
|
|
3044
3251
|
}
|
|
3045
|
-
let d = this.displayRows.slice(c, l + 1), f = this.isExporting ? 0 : t[c] ? t[c].top : 0, p = t[l], m = p ? p.top + p.height : 0, h = Math.max(0, a - m), g = a > this.viewportHeight, _ = [], v = this.option.readOnly === !0, y = this.option.dependency?.showArrows !== !1, b = this.option.dependency?.arrowSize ?? 8, x = this.option.dependency?.lineStyle ?? "orthogonal", S = this.option.dependency?.cornerRadius ?? 8;
|
|
3252
|
+
let d = this.displayRows.slice(c, l + 1), f = this.isExporting ? 0 : t[c] ? t[c].top : 0, p = t[l], m = p ? p.top + p.height : 0, h = Math.max(0, a - m), g = a > this.viewportHeight, _ = [], v = this.option.readOnly === !0, y = this.option.dependency?.showArrows !== !1, b = this.option.dependency?.arrowSize ?? 8, x = this.option.dependency?.lineStyle ?? "orthogonal", S = this.option.dependency?.cornerRadius ?? 8, C = this.option.dependency?.showCriticalPath === !0, w = C ? X(this.displayRows) : /* @__PURE__ */ new Set();
|
|
3046
3253
|
for (let [e, t] of r) if (t.dependencies) for (let n of t.dependencies) {
|
|
3047
3254
|
let a = r.get(n);
|
|
3048
3255
|
if (a) {
|
|
@@ -3062,12 +3269,12 @@ var X = class extends e {
|
|
|
3062
3269
|
${v ? "" : i`<path class="dependency-hit-area" d="${p}" @click="${(t) => {
|
|
3063
3270
|
t.stopPropagation(), this.handleDependencyLineClick(t, e, n);
|
|
3064
3271
|
}}" />`}
|
|
3065
|
-
<path class="dependency-line" d="${f}" />
|
|
3066
|
-
${y ? i`<path class="dependency-line dependency-arrow-line" d="${m}" marker-end="url(#dependency-arrowhead)" />` : ""}
|
|
3272
|
+
<path class="dependency-line ${C && w.has(e) && w.has(n) ? "critical-path" : ""}" d="${f}" />
|
|
3273
|
+
${y ? i`<path class="dependency-line dependency-arrow-line ${C && w.has(e) && w.has(n) ? "critical-path" : ""}" d="${m}" marker-end="url(#dependency-arrowhead)" />` : ""}
|
|
3067
3274
|
</g>`);
|
|
3068
3275
|
}
|
|
3069
3276
|
}
|
|
3070
|
-
let
|
|
3277
|
+
let T = null;
|
|
3071
3278
|
if (this.connectorDrag) {
|
|
3072
3279
|
let e = this.shadowRoot?.querySelector(".scroll-container");
|
|
3073
3280
|
if (e) {
|
|
@@ -3077,12 +3284,16 @@ var X = class extends e {
|
|
|
3077
3284
|
n ? (o = this.connectorDrag.targetEndpoint === "start" ? n.x : n.x + n.width, s = n.y + n.height / 2) : (o = this.connectorDrag.currentClientX - t.left + e.scrollLeft, s = this.connectorDrag.currentClientY - t.top + e.scrollTop - this.calendarHeight);
|
|
3078
3285
|
} else o = this.connectorDrag.currentClientX - t.left + e.scrollLeft, s = this.connectorDrag.currentClientY - t.top + e.scrollTop - this.calendarHeight;
|
|
3079
3286
|
let c = (n + o) / 2;
|
|
3080
|
-
|
|
3287
|
+
T = i`<path class="connector-preview-line" d="M ${n} ${a} C ${c} ${a} ${c} ${s} ${o} ${s}" />`;
|
|
3081
3288
|
}
|
|
3082
3289
|
}
|
|
3083
3290
|
return n`
|
|
3084
|
-
<style>${q(this.theme, this.option.customTheme)}
|
|
3085
|
-
|
|
3291
|
+
<style>${q(this.theme, this.option.customTheme)}
|
|
3292
|
+
:host {
|
|
3293
|
+
--critical-path-color: ${e.criticalPath ?? "rgba(220, 38, 38, 0.85)"};
|
|
3294
|
+
}
|
|
3295
|
+
</style>
|
|
3296
|
+
${this.isExporting ? n`<style>:host { overflow: visible !important; height: ${this.calendarHeight + a + 2}px !important; width: max-content !important; min-width: auto !important; border-radius: 0 !important; border: none !important; }</style>` : ""}
|
|
3086
3297
|
<div
|
|
3087
3298
|
class="scroll-container"
|
|
3088
3299
|
style="overflow-x: ${this.isExporting ? "visible" : "auto"}; overflow-y: ${this.isExporting ? "visible" : g ? "auto" : "hidden"}; height: ${this.isExporting ? "auto" : "100%"}; width: ${this.isExporting ? "max-content" : "100%"}; min-width: auto;"
|
|
@@ -3124,6 +3335,7 @@ var X = class extends e {
|
|
|
3124
3335
|
.option="${s}"
|
|
3125
3336
|
.theme="${this.theme}"
|
|
3126
3337
|
.currentTime="${this.currentTime}"
|
|
3338
|
+
.isExporting="${this.isExporting}"
|
|
3127
3339
|
.hoveredMilestoneId="${this.hoveredMilestoneId}"
|
|
3128
3340
|
.cornerContent="${this.option.customRendering?.cornerContent}"
|
|
3129
3341
|
.calendarMonthContent="${this.option.customRendering?.calendarMonthContent}"
|
|
@@ -3160,11 +3372,11 @@ var X = class extends e {
|
|
|
3160
3372
|
</defs>` : ""}
|
|
3161
3373
|
<g transform="translate(0, ${this.calendarHeight})">
|
|
3162
3374
|
${_}
|
|
3163
|
-
${
|
|
3375
|
+
${T}
|
|
3164
3376
|
</g>
|
|
3165
3377
|
</svg>
|
|
3166
3378
|
|
|
3167
|
-
${this.option.calendar.showCurrentTime && this.currentTime >= this.option.calendar.start && this.currentTime <= this.option.calendar.end ? n`
|
|
3379
|
+
${!this.isExporting && this.option.calendar.showCurrentTime && this.currentTime >= this.option.calendar.start && this.currentTime <= this.option.calendar.end ? n`
|
|
3168
3380
|
<div
|
|
3169
3381
|
class="current-time-line"
|
|
3170
3382
|
style="
|
|
@@ -3235,6 +3447,7 @@ var X = class extends e {
|
|
|
3235
3447
|
.selectedTaskIds="${this._cachedSelectedTaskIds}"
|
|
3236
3448
|
.focusedTaskId="${this.focusedTaskId}"
|
|
3237
3449
|
.isExporting="${this.isExporting}"
|
|
3450
|
+
.criticalPathTaskIds="${C ? [...w] : []}"
|
|
3238
3451
|
@task-update="${this.handleTaskUpdate}"
|
|
3239
3452
|
@row-clicked="${this.handleRowClicked}"
|
|
3240
3453
|
@row-header-contextmenu="${this.handleRowContextMenu}"
|
|
@@ -3257,9 +3470,9 @@ var X = class extends e {
|
|
|
3257
3470
|
`;
|
|
3258
3471
|
}
|
|
3259
3472
|
};
|
|
3260
|
-
B([s({ type: Array })],
|
|
3473
|
+
B([s({ type: Array })], Z.prototype, "rows", void 0), B([s({ type: Object })], Z.prototype, "option", void 0), B([s({
|
|
3261
3474
|
type: String,
|
|
3262
3475
|
reflect: !0
|
|
3263
|
-
})],
|
|
3476
|
+
})], Z.prototype, "theme", void 0), B([s({ type: Array })], Z.prototype, "selectedRowIds", void 0), B([s({ type: Array })], Z.prototype, "selectedTaskIds", void 0), B([s({ attribute: !1 })], Z.prototype, "externalDraggingTask", void 0), B([c()], Z.prototype, "selectedRows", void 0), B([c()], Z.prototype, "selectedTasks", void 0), B([c()], Z.prototype, "lastClickedRowId", void 0), B([c()], Z.prototype, "virtualScrollTop", void 0), B([c()], Z.prototype, "dragTargetRowIndex", void 0), B([c()], Z.prototype, "draggingTask", void 0), B([c()], Z.prototype, "draggingTaskIds", void 0), B([c()], Z.prototype, "multiDragDx", void 0), B([c()], Z.prototype, "multiDragDy", void 0), B([c()], Z.prototype, "multiDragSameRow", void 0), B([c()], Z.prototype, "viewportHeight", void 0), B([c()], Z.prototype, "calendarHeight", void 0), B([c()], Z.prototype, "tooltip", void 0), B([c()], Z.prototype, "dragOverRowId", void 0), B([c()], Z.prototype, "dragOverPosition", void 0), B([c()], Z.prototype, "currentTime", void 0), B([c()], Z.prototype, "dragPreview", void 0), B([c()], Z.prototype, "currentRowHeaderWidth", void 0), B([c()], Z.prototype, "isResizingHeader", void 0), B([c()], Z.prototype, "hoveredMilestoneId", void 0), B([c()], Z.prototype, "cursorLineX", void 0), B([c()], Z.prototype, "connectorDrag", void 0), B([c()], Z.prototype, "isExporting", void 0), B([c()], Z.prototype, "focusedTaskId", void 0), B([c()], Z.prototype, "focusedRowId", void 0), B([c()], Z.prototype, "zoomPxPerDay", void 0), B([c()], Z.prototype, "zoomPxPerMonth", void 0), Z = B([o("gantt-chart")], Z);
|
|
3264
3477
|
//#endregion
|
|
3265
|
-
export { m as ALL_BAR_PATTERNS, V as GanttBarElement, H as GanttCalendarElement,
|
|
3478
|
+
export { m as ALL_BAR_PATTERNS, V as GanttBarElement, H as GanttCalendarElement, Z as GanttChartElement, W as GanttRowElement, y as PATTERN_CHECKERBOARD, S as PATTERN_CIRCLE, w as PATTERN_DIAGONAL_GRID, h as PATTERN_DIAGONAL_STRIPE, g as PATTERN_DIAGONAL_STRIPE_REVERSE, b as PATTERN_DOTS, D as PATTERN_DOTS_DENSE, C as PATTERN_GRID, v as PATTERN_HORIZONTAL_STRIPE, E as PATTERN_STRIPE_THICK, T as PATTERN_STRIPE_THIN, x as PATTERN_TRIANGLE, _ as PATTERN_VERTICAL_STRIPE, X as computeCriticalPath, A as enLocale, O as getPatternStyle, k as jaLocale };
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
background-image: linear-gradient(${t} 1px, transparent 1px), linear-gradient(90deg, ${t} 1px, transparent 1px);
|
|
52
52
|
background-size: ${n} ${n};
|
|
53
53
|
background-repeat: repeat;
|
|
54
|
-
`;default:return``}}var j={monthFormat:`YYYY年M月`,monthRowFormat:`M月`,dateFormat:e=>`${e.getFullYear()}/${e.getMonth()+1}/${e.getDate()}`,timeUnitDateFormat:e=>`${e.getFullYear()}年${e.getMonth()+1}月${e.getDate()}日`,dateTimeFormat:e=>{let t=`${e.getFullYear()}/${e.getMonth()+1}/${e.getDate()}`,n=e.getHours(),r=e.getMinutes();return n===0&&r===0?t:`${t} ${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`},yearMonthFormat:e=>`${e.getFullYear()}/${e.getMonth()+1}`,duration:{days:e=>`${e}日`,hours:e=>`${e}時間`,minutes:e=>`${e}分`,zero:`0分`},tooltip:{duration:e=>`所要日数: ${e}日`},dragOverlay:{noTitle:`タイトルなし`,moveTo:e=>`移動先: ${e}`,movingTasks:e=>`${e}件のタスクを移動中`}},M={monthFormat:`MMM YYYY`,monthRowFormat:`MMM`,dateFormat:e=>`${e.getMonth()+1}/${e.getDate()}/${e.getFullYear()}`,timeUnitDateFormat:e=>`${[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`][e.getMonth()]} ${e.getDate()}, ${e.getFullYear()}`,dateTimeFormat:e=>{let t=`${e.getMonth()+1}/${e.getDate()}/${e.getFullYear()}`,n=e.getHours(),r=e.getMinutes();return n===0&&r===0?t:`${t} ${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`},yearMonthFormat:e=>`${e.getFullYear()}/${e.getMonth()+1}`,duration:{days:e=>`${e} day${e===1?``:`s`}`,hours:e=>`${e} hour${e===1?``:`s`}`,minutes:e=>`${e} minute${e===1?``:`s`}`,zero:`0 minutes`},tooltip:{duration:e=>`Duration: ${e} day${e===1?``:`s`}`},dragOverlay:{noTitle:`No Title`,moveTo:e=>`Move to: ${e}`,movingTasks:e=>`Moving ${e} task${e===1?``:`s`}`}},N={light:{bg:`#f1f5f9`,text:`#0f172a`,border:`#cbd5e1`,gridLine:`#cbd5e1`,subGridLine:`#e2e8f0`,monthGridLine:`#94a3b8`,yearGridLine:`#64748b`,dragTarget:`#e0f2fe`,tooltipBg:`rgba(0, 0, 0, 0.8)`,tooltipText:`white`,dragOverlayBg:`rgba(0, 0, 0, 0.85)`,dragOverlayText:`white`,dragOverlaySubText:`#cbd5e1`,dragOverlayDivider:`#666`,dependencyLine:`#94a3b8`,calendarBg:`#e2e8f0`,saturday:`#dbeafe`,sunday:`#fee2e2`,holiday:`#fee2e2`,rowHeaderBg:`#e2e8f0`,rowSelected:`#bfdbfe`,rowSelectedHeader:`#dbeafe`,rowHiddenBg:`repeating-linear-gradient(45deg, #f3f4f6, #f3f4f6 10px, #e5e7eb 10px, #e5e7eb 20px)`,currentTimeLine:`rgba(239, 68, 68, 0.5)`,currentTimeLineText:`#ffffff`},dark:{bg:`#1e293b`,text:`#f8fafc`,border:`#263040`,gridLine:`#334155`,subGridLine:`#263040`,monthGridLine:`#475569`,yearGridLine:`#64748b`,dragTarget:`rgba(51, 65, 85, 0.5)`,tooltipBg:`rgba(255, 255, 255, 0.9)`,tooltipText:`#0f172a`,dragOverlayBg:`rgba(255, 255, 255, 0.9)`,dragOverlayText:`#0f172a`,dragOverlaySubText:`#64748b`,dragOverlayDivider:`#cbd5e1`,dependencyLine:`#475569`,calendarBg:`#0f172a`,saturday:`rgba(59, 130, 246, 0.15)`,sunday:`rgba(239, 68, 68, 0.15)`,holiday:`rgba(239, 68, 68, 0.15)`,rowHeaderBg:`#0f172a`,rowSelected:`#283548`,rowSelectedHeader:`#1c2738`,rowHiddenBg:`repeating-linear-gradient(45deg, #0f172a, #0f172a 10px, #1e293b 10px, #1e293b 20px)`,currentTimeLine:`rgba(239, 68, 68, 0.5)`,currentTimeLineText:`#ffffff`}},P=(e,t,n,r)=>{if(r!==void 0){let n=t.getFullYear(),i=t.getMonth(),a=e.getFullYear(),o=e.getMonth(),s=(a-n)*12+(o-i),c=new Date(n,i+1,0).getDate(),l=(t.getDate()-1+t.getHours()/24+t.getMinutes()/1440)/c,u=new Date(a,o+1,0).getDate();return(s+(e.getDate()-1+e.getHours()/24+e.getMinutes()/1440)/u-l)*r}return(e.getTime()-t.getTime())/(1e3*60*60*24)*n},F=(e,t,n,r)=>{if(r!==void 0){let n=t.getFullYear(),i=t.getMonth(),a=new Date(n,i+1,0).getDate(),o=(t.getDate()-1+t.getHours()/24+t.getMinutes()/1440)/a,s=e/r+o,c=i+Math.floor(s),l=n+Math.floor(c/12);c%=12,c<0&&(c+=12,--l);let u=(s-Math.floor(s))*new Date(l,c+1,0).getDate(),d=1+Math.floor(u),f=(u-Math.floor(u))*24,p=Math.floor(f),m=Math.round((f-p)*60);return new Date(l,c,d,p,m)}let i=e/n;return new Date(t.getTime()+i*24*60*60*1e3)};function I(e){if(!e.length)return{tasksWithLanes:[],laneCount:1};let t=[...e].sort((e,t)=>e.start.getTime()-t.start.getTime()),n=[],r=new Map;for(let e of t){let t=-1;for(let r=0;r<n.length;r++)if(e.start>=n[r]){n[r]=e.end,t=r;break}t===-1&&(n.push(e.end),t=n.length-1),r.set(e.id,t)}return{tasksWithLanes:e.map(e=>({...e,lane:r.get(e.id)??0})),laneCount:n.length||1}}var L=(e,t)=>({...N[e]||N.light,...t}),R=(e,t,n)=>{let r=e.getDay();return n&&n(e)?t.holiday:[t.sunday,t.monday??``,t.tuesday??``,t.wednesday??``,t.thursday??``,t.friday??``,t.saturday][r]};function z(e,t){return(t.getTime()-e.getTime())/(1e3*60*60*24)}var B=(e,t,n)=>{let r=n??j,i=t.getTime()-e.getTime(),a=Math.floor(i/(1e3*60*60*24)),o=i%(1e3*60*60*24),s=Math.floor(o/(1e3*60*60)),c=o%(1e3*60*60),l=Math.floor(c/(1e3*60)),u=``;return a>0&&(u+=r.duration.days(a)),s>0&&(u+=r.duration.hours(s)),l>0&&(u+=r.duration.minutes(l)),u||r.duration.zero},V={BAR:`#3b82f6`,LABEL_BACKGROUND:`#fafafa`,SATURDAY:`#dbeafe`,SUNDAY:`#fee2e2`,HOLIDAY:`#fee2e2`,BORDER:`#e2e8f0`}.BAR;function H(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var U=class extends t.LitElement{constructor(...e){super(...e),this.lane=0,this.selected=!1,this.focused=!1,this.multiDragDx=0,this.multiDragDy=0,this.multiDragActive=!1,this.multiDragSameRow=!1,this.connectorDropTarget=!1,this.isExporting=!1,this._currentDragCursor=null,this._dragAnimationFrame=null,this._wasDragging=!1,this._connectorEdgeThreshold=30,this.handleKeyDown=e=>{(e.key===`Control`||e.key===`Alt`)&&this.updateCursor(!0)},this.handleKeyUp=e=>{(e.key===`Control`||e.key===`Alt`)&&this.updateCursor(!1)},this.onMouseMoveOnBar=e=>{let t=this.shadowRoot?.querySelector(`.task-group`);if(!t||this.option.readOnly)return;let n=t.getBoundingClientRect(),r=e.clientX-n.left,i=r<=this._connectorEdgeThreshold,a=r>=n.width-this._connectorEdgeThreshold,o=this.shadowRoot?.querySelector(`.connector-left`),s=this.shadowRoot?.querySelector(`.connector-right`);o&&o.classList.toggle(`show-connector`,i),s&&s.classList.toggle(`show-connector`,a)}}static{this.styles=t.css`
|
|
54
|
+
`;default:return``}}var j={monthFormat:`YYYY年M月`,monthRowFormat:`M月`,dateFormat:e=>`${e.getFullYear()}/${e.getMonth()+1}/${e.getDate()}`,timeUnitDateFormat:e=>`${e.getFullYear()}年${e.getMonth()+1}月${e.getDate()}日`,dateTimeFormat:e=>{let t=`${e.getFullYear()}/${e.getMonth()+1}/${e.getDate()}`,n=e.getHours(),r=e.getMinutes();return n===0&&r===0?t:`${t} ${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`},yearMonthFormat:e=>`${e.getFullYear()}/${e.getMonth()+1}`,duration:{days:e=>`${e}日`,hours:e=>`${e}時間`,minutes:e=>`${e}分`,zero:`0分`},tooltip:{duration:e=>`所要日数: ${e}日`},dragOverlay:{noTitle:`タイトルなし`,moveTo:e=>`移動先: ${e}`,movingTasks:e=>`${e}件のタスクを移動中`}},M={monthFormat:`MMM YYYY`,monthRowFormat:`MMM`,dateFormat:e=>`${e.getMonth()+1}/${e.getDate()}/${e.getFullYear()}`,timeUnitDateFormat:e=>`${[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`][e.getMonth()]} ${e.getDate()}, ${e.getFullYear()}`,dateTimeFormat:e=>{let t=`${e.getMonth()+1}/${e.getDate()}/${e.getFullYear()}`,n=e.getHours(),r=e.getMinutes();return n===0&&r===0?t:`${t} ${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`},yearMonthFormat:e=>`${e.getFullYear()}/${e.getMonth()+1}`,duration:{days:e=>`${e} day${e===1?``:`s`}`,hours:e=>`${e} hour${e===1?``:`s`}`,minutes:e=>`${e} minute${e===1?``:`s`}`,zero:`0 minutes`},tooltip:{duration:e=>`Duration: ${e} day${e===1?``:`s`}`},dragOverlay:{noTitle:`No Title`,moveTo:e=>`Move to: ${e}`,movingTasks:e=>`Moving ${e} task${e===1?``:`s`}`}},N={light:{bg:`#f1f5f9`,text:`#0f172a`,border:`#cbd5e1`,gridLine:`#cbd5e1`,subGridLine:`#e2e8f0`,monthGridLine:`#94a3b8`,yearGridLine:`#64748b`,dragTarget:`#e0f2fe`,tooltipBg:`rgba(0, 0, 0, 0.8)`,tooltipText:`white`,dragOverlayBg:`rgba(0, 0, 0, 0.85)`,dragOverlayText:`white`,dragOverlaySubText:`#cbd5e1`,dragOverlayDivider:`#666`,dependencyLine:`#94a3b8`,calendarBg:`#e2e8f0`,saturday:`#dbeafe`,sunday:`#fee2e2`,holiday:`#fee2e2`,rowHeaderBg:`#e2e8f0`,rowSelected:`#bfdbfe`,rowSelectedHeader:`#dbeafe`,rowHiddenBg:`repeating-linear-gradient(45deg, #f3f4f6, #f3f4f6 10px, #e5e7eb 10px, #e5e7eb 20px)`,currentTimeLine:`rgba(239, 68, 68, 0.5)`,currentTimeLineText:`#ffffff`,criticalPath:`rgba(220, 38, 38, 0.85)`},dark:{bg:`#1e293b`,text:`#f8fafc`,border:`#263040`,gridLine:`#334155`,subGridLine:`#263040`,monthGridLine:`#475569`,yearGridLine:`#64748b`,dragTarget:`rgba(51, 65, 85, 0.5)`,tooltipBg:`rgba(255, 255, 255, 0.9)`,tooltipText:`#0f172a`,dragOverlayBg:`rgba(255, 255, 255, 0.9)`,dragOverlayText:`#0f172a`,dragOverlaySubText:`#64748b`,dragOverlayDivider:`#cbd5e1`,dependencyLine:`#475569`,calendarBg:`#0f172a`,saturday:`rgba(59, 130, 246, 0.15)`,sunday:`rgba(239, 68, 68, 0.15)`,holiday:`rgba(239, 68, 68, 0.15)`,rowHeaderBg:`#0f172a`,rowSelected:`#283548`,rowSelectedHeader:`#1c2738`,rowHiddenBg:`repeating-linear-gradient(45deg, #0f172a, #0f172a 10px, #1e293b 10px, #1e293b 20px)`,currentTimeLine:`rgba(239, 68, 68, 0.5)`,currentTimeLineText:`#ffffff`,criticalPath:`rgba(248, 113, 113, 0.85)`}},P=(e,t,n,r)=>{if(r!==void 0){let n=t.getFullYear(),i=t.getMonth(),a=e.getFullYear(),o=e.getMonth(),s=(a-n)*12+(o-i),c=new Date(n,i+1,0).getDate(),l=(t.getDate()-1+t.getHours()/24+t.getMinutes()/1440)/c,u=new Date(a,o+1,0).getDate();return(s+(e.getDate()-1+e.getHours()/24+e.getMinutes()/1440)/u-l)*r}return(e.getTime()-t.getTime())/(1e3*60*60*24)*n},F=(e,t,n,r)=>{if(r!==void 0){let n=t.getFullYear(),i=t.getMonth(),a=new Date(n,i+1,0).getDate(),o=(t.getDate()-1+t.getHours()/24+t.getMinutes()/1440)/a,s=e/r+o,c=i+Math.floor(s),l=n+Math.floor(c/12);c%=12,c<0&&(c+=12,--l);let u=(s-Math.floor(s))*new Date(l,c+1,0).getDate(),d=1+Math.floor(u),f=(u-Math.floor(u))*24,p=Math.floor(f),m=Math.round((f-p)*60);return new Date(l,c,d,p,m)}let i=e/n;return new Date(t.getTime()+i*24*60*60*1e3)};function I(e){if(!e.length)return{tasksWithLanes:[],laneCount:1};let t=[...e].sort((e,t)=>e.start.getTime()-t.start.getTime()),n=[],r=new Map;for(let e of t){let t=-1;for(let r=0;r<n.length;r++)if(e.start>=n[r]){n[r]=e.end,t=r;break}t===-1&&(n.push(e.end),t=n.length-1),r.set(e.id,t)}return{tasksWithLanes:e.map(e=>({...e,lane:r.get(e.id)??0})),laneCount:n.length||1}}var L=(e,t)=>({...N[e]||N.light,...t}),R=(e,t,n)=>{let r=e.getDay();return n&&n(e)?t.holiday:[t.sunday,t.monday??``,t.tuesday??``,t.wednesday??``,t.thursday??``,t.friday??``,t.saturday][r]};function z(e,t){return(t.getTime()-e.getTime())/(1e3*60*60*24)}var B=(e,t,n)=>{let r=n??j,i=t.getTime()-e.getTime(),a=Math.floor(i/(1e3*60*60*24)),o=i%(1e3*60*60*24),s=Math.floor(o/(1e3*60*60)),c=o%(1e3*60*60),l=Math.floor(c/(1e3*60)),u=``;return a>0&&(u+=r.duration.days(a)),s>0&&(u+=r.duration.hours(s)),l>0&&(u+=r.duration.minutes(l)),u||r.duration.zero},V={BAR:`#3b82f6`,LABEL_BACKGROUND:`#fafafa`,SATURDAY:`#dbeafe`,SUNDAY:`#fee2e2`,HOLIDAY:`#fee2e2`,BORDER:`#e2e8f0`}.BAR;function H(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var U=class extends t.LitElement{constructor(...e){super(...e),this.lane=0,this.selected=!1,this.focused=!1,this.multiDragDx=0,this.multiDragDy=0,this.multiDragActive=!1,this.multiDragSameRow=!1,this.connectorDropTarget=!1,this.isExporting=!1,this.isCriticalPath=!1,this._currentDragCursor=null,this._dragAnimationFrame=null,this._wasDragging=!1,this._connectorEdgeThreshold=30,this.handleKeyDown=e=>{(e.key===`Control`||e.key===`Alt`)&&this.updateCursor(!0)},this.handleKeyUp=e=>{(e.key===`Control`||e.key===`Alt`)&&this.updateCursor(!1)},this.onMouseMoveOnBar=e=>{let t=this.shadowRoot?.querySelector(`.task-group`);if(!t||this.option.readOnly||this.option.dependency?.showConnectors===!1)return;let n=t.getBoundingClientRect(),r=e.clientX-n.left,i=r<=this._connectorEdgeThreshold,a=r>=n.width-this._connectorEdgeThreshold,o=this.shadowRoot?.querySelector(`.connector-left`),s=this.shadowRoot?.querySelector(`.connector-right`);o&&o.classList.toggle(`show-connector`,i),s&&s.classList.toggle(`show-connector`,a)}}static{this.styles=t.css`
|
|
55
55
|
:host {
|
|
56
56
|
display: block;
|
|
57
57
|
position: absolute;
|
|
@@ -154,6 +154,15 @@
|
|
|
154
154
|
outline-offset: 2px;
|
|
155
155
|
box-shadow: 0 0 12px rgba(59, 130, 246, 0.6);
|
|
156
156
|
}
|
|
157
|
+
:host([critical-path]) .bar {
|
|
158
|
+
outline: 2px solid var(--critical-path-color, rgba(220, 38, 38, 0.85));
|
|
159
|
+
outline-offset: 1px;
|
|
160
|
+
}
|
|
161
|
+
:host([selected][critical-path]) .bar {
|
|
162
|
+
outline: 2px solid #3b82f6;
|
|
163
|
+
outline-offset: 1px;
|
|
164
|
+
box-shadow: 0 0 8px rgba(59, 130, 246, 0.5);
|
|
165
|
+
}
|
|
157
166
|
.bar-label {
|
|
158
167
|
color: white;
|
|
159
168
|
font-size: 12px;
|
|
@@ -233,7 +242,7 @@
|
|
|
233
242
|
<div class="handle-left" @pointerdown="${e=>this.onResizeStart(e,`left`)}"></div>
|
|
234
243
|
<div class="handle-right" @pointerdown="${e=>this.onResizeStart(e,`right`)}"></div>
|
|
235
244
|
`:``}
|
|
236
|
-
${s
|
|
245
|
+
${!s&&this.option.dependency?.showConnectors!==!1?t.html`
|
|
237
246
|
<div
|
|
238
247
|
class="connector-left"
|
|
239
248
|
@pointerdown="${e=>this.onConnectorDragStart(e,`start`)}"
|
|
@@ -242,9 +251,9 @@
|
|
|
242
251
|
class="connector-right"
|
|
243
252
|
@pointerdown="${e=>this.onConnectorDragStart(e,`end`)}"
|
|
244
253
|
></div>
|
|
245
|
-
|
|
254
|
+
`:``}
|
|
246
255
|
</div>
|
|
247
|
-
`}};H([(0,n.property)({type:Object})],U.prototype,`task`,void 0),H([(0,n.property)({type:Object})],U.prototype,`option`,void 0),H([(0,n.property)({type:Number})],U.prototype,`lane`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],U.prototype,`selected`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],U.prototype,`focused`,void 0),H([(0,n.property)({type:Number})],U.prototype,`multiDragDx`,void 0),H([(0,n.property)({type:Number})],U.prototype,`multiDragDy`,void 0),H([(0,n.property)({type:Boolean})],U.prototype,`multiDragActive`,void 0),H([(0,n.property)({type:Boolean})],U.prototype,`multiDragSameRow`,void 0),H([(0,n.property)({type:Boolean,reflect:!0,attribute:`connector-drop-target`})],U.prototype,`connectorDropTarget`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],U.prototype,`isExporting`,void 0),U=H([(0,n.customElement)(`gantt-bar`)],U);var W=class extends t.LitElement{constructor(...e){super(...e),this.theme=`light`,this.currentTime=new Date,this.hoveredMilestoneId=null,this._cachedDays=null,this._cachedMonths=null,this._cachedYears=null,this._cachedWeeks=null,this._cachedStartTime=0,this._cachedEndTime=0,this._cachedPxPerDay=0,this._cachedPxPerMonth=void 0,this._cachedWeekStartDay=-1}injectCustomContent(e,t,n){let r=e.querySelector(`.${n}`);if(r&&r.remove(),t instanceof HTMLElement)t.classList.add(n),e.appendChild(t);else if(typeof t==`string`){let r=document.createElement(`span`);r.classList.add(n),r.textContent=t,e.appendChild(r)}}updated(){let e=this.shadowRoot?.querySelector(`.label-placeholder`);if(!e)return;let t=e.querySelector(`.corner-content-root`);if(t&&t.remove(),this.cornerContent){let t=this.cornerContent();t instanceof HTMLElement&&(t.classList.add(`corner-content-root`),e.appendChild(t))}this.injectCalendarCustomContent()}injectCalendarCustomContent(){this.calendarMonthContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-month]`))?.forEach(e=>{let t=e,n={year:parseInt(t.dataset.calendarMonthYear??`0`,10),month:parseInt(t.dataset.calendarMonth??`0`,10),width:parseFloat(t.dataset.calendarMonthWidth??`0`),defaultLabel:t.dataset.calendarMonthLabel??``},r=this.calendarMonthContent(n);this.injectCustomContent(t,r,`custom-month-content`)}),this.calendarDayContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-day]`))?.forEach(e=>{let t=e,n=t.dataset.calendarDay??``,r={date:new Date(n),width:parseFloat(t.dataset.calendarDayWidth??`0`),isSaturday:t.dataset.calendarDaySaturday===`true`,isSunday:t.dataset.calendarDaySunday===`true`,isHoliday:t.dataset.calendarDayHoliday===`true`,defaultLabel:t.dataset.calendarDayLabel??``},i=this.calendarDayContent(r);this.injectCustomContent(t,i,`custom-day-content`)}),this.calendarWeekContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-week]`))?.forEach(e=>{let t=e,n=parseInt(t.dataset.calendarWeek??`0`,10),r=t.dataset.calendarWeekStart??``,i={weekNumber:n,startDate:new Date(r),width:parseFloat(t.dataset.calendarWeekWidth??`0`),defaultLabel:t.dataset.calendarWeekLabel??``},a=this.calendarWeekContent(i);this.injectCustomContent(t,a,`custom-week-content`)}),this.calendarHourContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-hour]`))?.forEach(e=>{let t=e,n=parseInt(t.dataset.calendarHour??`0`,10),r=parseFloat(t.dataset.calendarHourWidth??`0`),i=t.dataset.calendarHourDate??``,a={hour:n,width:r,date:new Date(i)},o=this.calendarHourContent(a);this.injectCustomContent(t,o,`custom-hour-content`)})}get totalDays(){return z(this.option.calendar.start,this.option.calendar.end)}static{this.styles=t.css`
|
|
256
|
+
`}};H([(0,n.property)({type:Object})],U.prototype,`task`,void 0),H([(0,n.property)({type:Object})],U.prototype,`option`,void 0),H([(0,n.property)({type:Number})],U.prototype,`lane`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],U.prototype,`selected`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],U.prototype,`focused`,void 0),H([(0,n.property)({type:Number})],U.prototype,`multiDragDx`,void 0),H([(0,n.property)({type:Number})],U.prototype,`multiDragDy`,void 0),H([(0,n.property)({type:Boolean})],U.prototype,`multiDragActive`,void 0),H([(0,n.property)({type:Boolean})],U.prototype,`multiDragSameRow`,void 0),H([(0,n.property)({type:Boolean,reflect:!0,attribute:`connector-drop-target`})],U.prototype,`connectorDropTarget`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],U.prototype,`isExporting`,void 0),H([(0,n.property)({type:Boolean,reflect:!0,attribute:`critical-path`})],U.prototype,`isCriticalPath`,void 0),U=H([(0,n.customElement)(`gantt-bar`)],U);var W=class extends t.LitElement{constructor(...e){super(...e),this.theme=`light`,this.currentTime=new Date,this.isExporting=!1,this.hoveredMilestoneId=null,this._cachedDays=null,this._cachedMonths=null,this._cachedYears=null,this._cachedWeeks=null,this._cachedStartTime=0,this._cachedEndTime=0,this._cachedPxPerDay=0,this._cachedPxPerMonth=void 0,this._cachedWeekStartDay=-1}injectCustomContent(e,t,n){let r=e.querySelector(`.${n}`);if(r&&r.remove(),t instanceof HTMLElement)t.classList.add(n),e.appendChild(t);else if(typeof t==`string`){let r=document.createElement(`span`);r.classList.add(n),r.textContent=t,e.appendChild(r)}}updated(){let e=this.shadowRoot?.querySelector(`.label-placeholder`);if(!e)return;let t=e.querySelector(`.corner-content-root`);if(t&&t.remove(),this.cornerContent){let t=this.cornerContent();t instanceof HTMLElement&&(t.classList.add(`corner-content-root`),e.appendChild(t))}this.injectCalendarCustomContent()}injectCalendarCustomContent(){this.calendarMonthContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-month]`))?.forEach(e=>{let t=e,n={year:parseInt(t.dataset.calendarMonthYear??`0`,10),month:parseInt(t.dataset.calendarMonth??`0`,10),width:parseFloat(t.dataset.calendarMonthWidth??`0`),defaultLabel:t.dataset.calendarMonthLabel??``},r=this.calendarMonthContent(n);this.injectCustomContent(t,r,`custom-month-content`)}),this.calendarDayContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-day]`))?.forEach(e=>{let t=e,n=t.dataset.calendarDay??``,r={date:new Date(n),width:parseFloat(t.dataset.calendarDayWidth??`0`),isSaturday:t.dataset.calendarDaySaturday===`true`,isSunday:t.dataset.calendarDaySunday===`true`,isHoliday:t.dataset.calendarDayHoliday===`true`,defaultLabel:t.dataset.calendarDayLabel??``},i=this.calendarDayContent(r);this.injectCustomContent(t,i,`custom-day-content`)}),this.calendarWeekContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-week]`))?.forEach(e=>{let t=e,n=parseInt(t.dataset.calendarWeek??`0`,10),r=t.dataset.calendarWeekStart??``,i={weekNumber:n,startDate:new Date(r),width:parseFloat(t.dataset.calendarWeekWidth??`0`),defaultLabel:t.dataset.calendarWeekLabel??``},a=this.calendarWeekContent(i);this.injectCustomContent(t,a,`custom-week-content`)}),this.calendarHourContent&&(this.shadowRoot?.querySelectorAll(`[data-calendar-hour]`))?.forEach(e=>{let t=e,n=parseInt(t.dataset.calendarHour??`0`,10),r=parseFloat(t.dataset.calendarHourWidth??`0`),i=t.dataset.calendarHourDate??``,a={hour:n,width:r,date:new Date(i)},o=this.calendarHourContent(a);this.injectCustomContent(t,o,`custom-hour-content`)})}get totalDays(){return z(this.option.calendar.start,this.option.calendar.end)}static{this.styles=t.css`
|
|
248
257
|
:host {
|
|
249
258
|
display: flex;
|
|
250
259
|
width: fit-content;
|
|
@@ -485,7 +494,7 @@
|
|
|
485
494
|
></div>`}),o=d[d.length-1];if(o&&i>r){let r=o.month===11,s=r?e.yearGridLine||e.monthGridLine||e.border:n?e.border:e.monthGridLine||e.border,c=r?3:1;a.push(t.html`<div
|
|
486
495
|
style="position: absolute; top: 0; bottom: 0; left: ${i-1}px; width: 1px; background-color: ${s}; pointer-events: none; z-index: ${c};"
|
|
487
496
|
></div>`)}return a})()}
|
|
488
|
-
${this.option.calendar.showCurrentTime&&this.option.calendar.showCurrentTimeBadge===!0&&this.currentTime>=this.option.calendar.start&&this.currentTime<=this.option.calendar.end?t.html`
|
|
497
|
+
${!this.isExporting&&this.option.calendar.showCurrentTime&&this.option.calendar.showCurrentTimeBadge===!0&&this.currentTime>=this.option.calendar.start&&this.currentTime<=this.option.calendar.end?t.html`
|
|
489
498
|
<div
|
|
490
499
|
class="current-time-badge"
|
|
491
500
|
style="
|
|
@@ -523,7 +532,7 @@
|
|
|
523
532
|
</div>
|
|
524
533
|
`)}
|
|
525
534
|
</div>
|
|
526
|
-
`}};H([(0,n.property)({type:Object})],W.prototype,`option`,void 0),H([(0,n.property)({type:String})],W.prototype,`theme`,void 0),H([(0,n.property)({type:Object})],W.prototype,`currentTime`,void 0),H([(0,n.property)({type:String})],W.prototype,`hoveredMilestoneId`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`cornerContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarMonthContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarDayContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarWeekContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarHourContent`,void 0),W=H([(0,n.customElement)(`gantt-calendar`)],W);var G=class extends t.LitElement{constructor(...e){super(...e),this.theme=`light`,this.rowId=``,this._cachedCells=null,this._cachedCellsStartTime=0,this._cachedCellsEndTime=0,this._cachedCellsPxPerDay=0,this._cachedCellsPxPerMonth=void 0,this._cachedCellsTheme=``}get totalDays(){return z(this.option.calendar.start,this.option.calendar.end)}static{this.styles=t.css`
|
|
535
|
+
`}};H([(0,n.property)({type:Object})],W.prototype,`option`,void 0),H([(0,n.property)({type:String})],W.prototype,`theme`,void 0),H([(0,n.property)({type:Object})],W.prototype,`currentTime`,void 0),H([(0,n.property)({type:Boolean})],W.prototype,`isExporting`,void 0),H([(0,n.property)({type:String})],W.prototype,`hoveredMilestoneId`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`cornerContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarMonthContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarDayContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarWeekContent`,void 0),H([(0,n.property)({attribute:!1})],W.prototype,`calendarHourContent`,void 0),W=H([(0,n.customElement)(`gantt-calendar`)],W);var G=class extends t.LitElement{constructor(...e){super(...e),this.theme=`light`,this.rowId=``,this._cachedCells=null,this._cachedCellsStartTime=0,this._cachedCellsEndTime=0,this._cachedCellsPxPerDay=0,this._cachedCellsPxPerMonth=void 0,this._cachedCellsTheme=``}get totalDays(){return z(this.option.calendar.start,this.option.calendar.end)}static{this.styles=t.css`
|
|
527
536
|
:host {
|
|
528
537
|
position: absolute;
|
|
529
538
|
top: 0;
|
|
@@ -552,7 +561,7 @@
|
|
|
552
561
|
${this._cachedCells.map(({width:e,color:n})=>t.html`<div
|
|
553
562
|
style="width: ${e}px; background-color: ${n}; flex-shrink: 0;"
|
|
554
563
|
></div>`)}
|
|
555
|
-
`}};H([(0,n.property)({type:Object})],G.prototype,`option`,void 0),H([(0,n.property)({type:String})],G.prototype,`theme`,void 0),H([(0,n.property)({type:String})],G.prototype,`rowId`,void 0),G=H([(0,n.customElement)(`gantt-row-background`)],G);var K=class extends t.LitElement{constructor(...e){super(...e),this.isDragTarget=!1,this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.externalDragTask=null,this.theme=`light`,this.isSelected=!1,this.dropPosition=null,this.selectedTaskIds=[],this.focusedTaskId=null,this.isExporting=!1,this._cachedMonthGridLines=null,this._cachedMonthGridStartTime=0,this._cachedMonthGridEndTime=0,this._cachedMonthGridPxPerDay=0,this._cachedMonthGridPxPerMonth=0}getDateX(e){return P(e,this.option.calendar.start,this.option.calendar.pxPerDay,this.option.calendar.pxPerMonth)}getMarkerPath(e,t){let n=t/2;switch(e){case`triangle-up`:return`M 0 ${t} L ${n} 0 L ${t} ${t} Z`;case`triangle-down`:return`M 0 0 L ${t} 0 L ${n} ${t} Z`;case`triangle-left`:return`M ${t} 0 L 0 ${n} L ${t} ${t} Z`;case`triangle-right`:return`M 0 0 L ${t} ${n} L 0 ${t} Z`;case`diamond`:return`M ${n} 0 L ${t} ${n} L ${n} ${t} L 0 ${n} Z`;case`square`:return`M 0 0 L ${t} 0 L ${t} ${t} L 0 ${t} Z`;default:return`M 0 ${t} L ${n} 0 L ${t} ${t} Z`}}estimateMarkerWidth(e,t){let n=e.name?e.name.length*7+4:0;return e.anchor===`center`?t:t+n}getMarkerXRange(e,t){let n=this.getDateX(e.date),r=this.estimateMarkerWidth(e,t),i=e.anchor===`center`,a=e.anchor===`end`,o;if(o=e.anchor===`start`?n:e.anchor===`end`?n-t:n-t/2,i)return{left:o,right:o+t};if(a){let e=r-t;return{left:o-e,right:o+t}}return{left:o,right:o+r}}calculateMarkerLanes(e,t){if(!e.length)return[];let n=e.map(e=>({marker:e,range:this.getMarkerXRange(e,t)})).sort((e,t)=>e.range.left-t.range.left),r=[],i=[];for(let e of n){let t=-1;for(let n=0;n<r.length;n++)if(e.range.left>=r[n]+2){r[n]=e.range.right,t=n;break}t===-1&&(r.push(e.range.right),t=r.length-1),i.push({marker:e.marker,lane:t})}return i}static{this.styles=t.css`
|
|
564
|
+
`}};H([(0,n.property)({type:Object})],G.prototype,`option`,void 0),H([(0,n.property)({type:String})],G.prototype,`theme`,void 0),H([(0,n.property)({type:String})],G.prototype,`rowId`,void 0),G=H([(0,n.customElement)(`gantt-row-background`)],G);var K=class extends t.LitElement{constructor(...e){super(...e),this.isDragTarget=!1,this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.externalDragTask=null,this.theme=`light`,this.isSelected=!1,this.dropPosition=null,this.selectedTaskIds=[],this.focusedTaskId=null,this.isExporting=!1,this.criticalPathTaskIds=[],this._cachedMonthGridLines=null,this._cachedMonthGridStartTime=0,this._cachedMonthGridEndTime=0,this._cachedMonthGridPxPerDay=0,this._cachedMonthGridPxPerMonth=0}getDateX(e){return P(e,this.option.calendar.start,this.option.calendar.pxPerDay,this.option.calendar.pxPerMonth)}getMarkerPath(e,t){let n=t/2;switch(e){case`triangle-up`:return`M 0 ${t} L ${n} 0 L ${t} ${t} Z`;case`triangle-down`:return`M 0 0 L ${t} 0 L ${n} ${t} Z`;case`triangle-left`:return`M ${t} 0 L 0 ${n} L ${t} ${t} Z`;case`triangle-right`:return`M 0 0 L ${t} ${n} L 0 ${t} Z`;case`diamond`:return`M ${n} 0 L ${t} ${n} L ${n} ${t} L 0 ${n} Z`;case`square`:return`M 0 0 L ${t} 0 L ${t} ${t} L 0 ${t} Z`;default:return`M 0 ${t} L ${n} 0 L ${t} ${t} Z`}}estimateMarkerWidth(e,t){let n=e.name?e.name.length*7+4:0;return e.anchor===`center`?t:t+n}getMarkerXRange(e,t){let n=this.getDateX(e.date),r=this.estimateMarkerWidth(e,t),i=e.anchor===`center`,a=e.anchor===`end`,o;if(o=e.anchor===`start`?n:e.anchor===`end`?n-t:n-t/2,i)return{left:o,right:o+t};if(a){let e=r-t;return{left:o-e,right:o+t}}return{left:o,right:o+r}}calculateMarkerLanes(e,t){if(!e.length)return[];let n=e.map(e=>({marker:e,range:this.getMarkerXRange(e,t)})).sort((e,t)=>e.range.left-t.range.left),r=[],i=[];for(let e of n){let t=-1;for(let n=0;n<r.length;n++)if(e.range.left>=r[n]+2){r[n]=e.range.right,t=n;break}t===-1&&(r.push(e.range.right),t=r.length-1),i.push({marker:e.marker,lane:t})}return i}static{this.styles=t.css`
|
|
556
565
|
:host {
|
|
557
566
|
display: block;
|
|
558
567
|
width: fit-content;
|
|
@@ -706,6 +715,7 @@
|
|
|
706
715
|
.multiDragActive="${c}"
|
|
707
716
|
.multiDragSameRow="${this.multiDragSameRow}"
|
|
708
717
|
.isExporting="${this.isExporting}"
|
|
718
|
+
.isCriticalPath="${this.criticalPathTaskIds.includes(e.id)}"
|
|
709
719
|
/>
|
|
710
720
|
`})}
|
|
711
721
|
${f.map(({marker:e,lane:n})=>{let r=this.getDateX(e.date),i=e.color??`#ef4444`,a=e.anchor===`center`,o=(a?m/2-u:(m-u)/2)+n*d,s=e.anchor===`start`?r:e.anchor===`end`?r-u:r-u/2,c=e.anchor===`end`;return t.html`
|
|
@@ -747,7 +757,7 @@
|
|
|
747
757
|
`})}
|
|
748
758
|
</div>
|
|
749
759
|
</div>
|
|
750
|
-
`}};H([(0,n.property)({type:Object})],K.prototype,`row`,void 0),H([(0,n.property)({type:Object})],K.prototype,`option`,void 0),H([(0,n.property)({type:Boolean})],K.prototype,`isDragTarget`,void 0),H([(0,n.property)({type:Object})],K.prototype,`draggingTask`,void 0),H([(0,n.property)({type:Array})],K.prototype,`draggingTaskIds`,void 0),H([(0,n.property)({type:Number})],K.prototype,`multiDragDx`,void 0),H([(0,n.property)({type:Number})],K.prototype,`multiDragDy`,void 0),H([(0,n.property)({type:Boolean})],K.prototype,`multiDragSameRow`,void 0),H([(0,n.property)({type:Object})],K.prototype,`externalDragTask`,void 0),H([(0,n.property)({type:String})],K.prototype,`theme`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],K.prototype,`isSelected`,void 0),H([(0,n.property)({type:String})],K.prototype,`dropPosition`,void 0),H([(0,n.property)({type:Array})],K.prototype,`selectedTaskIds`,void 0),H([(0,n.property)({type:String})],K.prototype,`focusedTaskId`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],K.prototype,`isExporting`,void 0),K=H([(0,n.customElement)(`gantt-row`)],K);function q(e,t,n,r,i,a,o,s){let c=n=>{if(Math.abs(t-r)<1)return`M ${e} ${t} L ${n} ${r}`;if(e<n){let i=(e+n)/2,a=r>t?1:-1,o=Math.min(s,i-e,n-i,Math.abs(r-t)/2);return[`M ${e} ${t}`,`L ${i-o} ${t}`,`Q ${i} ${t} ${i} ${t+a*o}`,`L ${i} ${r-a*o}`,`Q ${i} ${r} ${i+o} ${r}`,`L ${n} ${r}`].join(` `)}else{let i=Math.max(12,s+4),c=e+i,l=n-i,u=(t+r)/2,d=Math.abs(t-r)<a?u+a+o:u,f=d-t,p=r-d,m=f>=0?1:-1,h=p>=0?1:-1,g=l-c,_=g>=0?1:-1,v=Math.min(s,i,Math.abs(f)/2),y=Math.min(s,Math.abs(f)/2,Math.abs(g)/2),b=Math.min(s,Math.abs(g)/2,Math.abs(p)/2),x=Math.min(s,Math.abs(p)/2,i);return[`M ${e} ${t}`,`L ${c-v} ${t}`,`Q ${c} ${t} ${c} ${t+m*v}`,`L ${c} ${d-m*y}`,`Q ${c} ${d} ${c+_*y} ${d}`,`L ${l-_*b} ${d}`,`Q ${l} ${d} ${l} ${d+h*b}`,`L ${l} ${r-h*x}`,`Q ${l} ${r} ${l+x} ${r}`,`L ${n} ${r}`].join(` `)}};return{pathD:c(i),hitPathD:c(n)}}var J=t.css`
|
|
760
|
+
`}};H([(0,n.property)({type:Object})],K.prototype,`row`,void 0),H([(0,n.property)({type:Object})],K.prototype,`option`,void 0),H([(0,n.property)({type:Boolean})],K.prototype,`isDragTarget`,void 0),H([(0,n.property)({type:Object})],K.prototype,`draggingTask`,void 0),H([(0,n.property)({type:Array})],K.prototype,`draggingTaskIds`,void 0),H([(0,n.property)({type:Number})],K.prototype,`multiDragDx`,void 0),H([(0,n.property)({type:Number})],K.prototype,`multiDragDy`,void 0),H([(0,n.property)({type:Boolean})],K.prototype,`multiDragSameRow`,void 0),H([(0,n.property)({type:Object})],K.prototype,`externalDragTask`,void 0),H([(0,n.property)({type:String})],K.prototype,`theme`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],K.prototype,`isSelected`,void 0),H([(0,n.property)({type:String})],K.prototype,`dropPosition`,void 0),H([(0,n.property)({type:Array})],K.prototype,`selectedTaskIds`,void 0),H([(0,n.property)({type:String})],K.prototype,`focusedTaskId`,void 0),H([(0,n.property)({type:Boolean,reflect:!0})],K.prototype,`isExporting`,void 0),H([(0,n.property)({type:Array})],K.prototype,`criticalPathTaskIds`,void 0),K=H([(0,n.customElement)(`gantt-row`)],K);function q(e,t,n,r,i,a,o,s){let c=n=>{if(Math.abs(t-r)<1)return`M ${e} ${t} L ${n} ${r}`;if(e<n){let i=(e+n)/2,a=r>t?1:-1,o=Math.min(s,i-e,n-i,Math.abs(r-t)/2);return[`M ${e} ${t}`,`L ${i-o} ${t}`,`Q ${i} ${t} ${i} ${t+a*o}`,`L ${i} ${r-a*o}`,`Q ${i} ${r} ${i+o} ${r}`,`L ${n} ${r}`].join(` `)}else{let i=Math.max(12,s+4),c=e+i,l=n-i,u=(t+r)/2,d=Math.abs(t-r)<a?u+a+o:u,f=d-t,p=r-d,m=f>=0?1:-1,h=p>=0?1:-1,g=l-c,_=g>=0?1:-1,v=Math.min(s,i,Math.abs(f)/2),y=Math.min(s,Math.abs(f)/2,Math.abs(g)/2),b=Math.min(s,Math.abs(g)/2,Math.abs(p)/2),x=Math.min(s,Math.abs(p)/2,i);return[`M ${e} ${t}`,`L ${c-v} ${t}`,`Q ${c} ${t} ${c} ${t+m*v}`,`L ${c} ${d-m*y}`,`Q ${c} ${d} ${c+_*y} ${d}`,`L ${l-_*b} ${d}`,`Q ${l} ${d} ${l} ${d+h*b}`,`L ${l} ${r-h*x}`,`Q ${l} ${r} ${l+x} ${r}`,`L ${n} ${r}`].join(` `)}};return{pathD:c(i),hitPathD:c(n)}}var J=t.css`
|
|
751
761
|
:host {
|
|
752
762
|
display: block;
|
|
753
763
|
width: 100%;
|
|
@@ -854,6 +864,9 @@
|
|
|
854
864
|
.dependency-group:hover .dependency-hit-area ~ .dependency-line {
|
|
855
865
|
opacity: 1;
|
|
856
866
|
}
|
|
867
|
+
.dependency-line.critical-path {
|
|
868
|
+
stroke-width: 3;
|
|
869
|
+
}
|
|
857
870
|
.current-time-line {
|
|
858
871
|
position: absolute;
|
|
859
872
|
width: 2px;
|
|
@@ -915,6 +928,9 @@
|
|
|
915
928
|
fill: none;
|
|
916
929
|
opacity: 0.7;
|
|
917
930
|
}
|
|
931
|
+
.dependency-line.critical-path {
|
|
932
|
+
stroke: ${n.criticalPath??n.dependencyLine};
|
|
933
|
+
}
|
|
918
934
|
.header-resizer {
|
|
919
935
|
width: 4px;
|
|
920
936
|
cursor: col-resize;
|
|
@@ -926,7 +942,7 @@
|
|
|
926
942
|
.header-resizer.resizing {
|
|
927
943
|
background-color: ${n.border};
|
|
928
944
|
}
|
|
929
|
-
`}function X(e,t){let n=document.createElement(`a`);n.href=e,n.download=t,n.click()}async function Z(e,t=`png`,n={}){let{filename:r=`gantt-chart`,download:i=!1,scale:a=2,splitHeight:c}=n,l=e.shadowRoot?.querySelector(`.scroll-container`),u=l?l.scrollWidth:e.scrollWidth,d=l?l.scrollHeight:e.scrollHeight,f=await(0,o.default)(e,{backgroundColor:`#ffffff`,scale:a,width:u,height:d,windowWidth:u,windowHeight:d});if(c&&d>c){let t=50,n=e.shadowRoot?.querySelector(`gantt-calendar`);n&&n.offsetHeight>0?t=n.offsetHeight:e.calendarHeight&&(t=e.calendarHeight);let r=f.height/d,i=Math.floor(c*r),a=Math.floor(t*r),o=f.height,s=f.width,l=o-a,u=i-a;if(u>0){let e=Math.ceil(l/u),t=o+(e-1)*a,n=document.createElement(`canvas`);n.width=s,n.height=t;let c=n.getContext(`2d`);if(c){c.drawImage(f,0,0,s,i,0,0,s,i);let l=i,p=i;for(let t=1;t<e;t++){c.drawImage(f,0,0,s,a,0,p,s,a),p+=a;let e=o-l,t=Math.min(u,e);c.drawImage(f,0,l,s,t,0,p,s,t),l+=t,p+=t}f=n,d=t/r}else console.warn(`[export] Failed to get 2D context for new canvas. It might be too large.`)}}if(t===`pdf`){let e=f.toDataURL(`image/jpeg`,.9),t=new s.jsPDF({orientation:u>d?`l`:`p`,unit:`px`,format:[u,d],compress:!0});return t.addImage(e,`JPEG`,0,0,u,d,void 0,`FAST`),i&&t.save(`${r}.pdf`),t.output(`blob`)}else{let e=f.toDataURL(`image/png`);return i&&X(e,`${r}.png`),e}}var Q=class extends t.LitElement{constructor(...e){super(...e),this.rows=[],this.theme=`light`,this.selectedRowIds=[],this.selectedTaskIds=[],this.externalDraggingTask=null,this.selectedRows=new Set,this.selectedTasks=new Set,this.lastClickedRowId=null,this.virtualScrollTop=0,this.dragTargetRowIndex=null,this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.viewportHeight=400,this.dragOverlayInfo=null,this.calendarHeight=0,this.tooltip=null,this.dragOverRowId=null,this.dragOverPosition=null,this.currentTime=new Date,this.dragPreview=null,this.currentRowHeaderWidth=150,this.isResizingHeader=!1,this.hoveredMilestoneId=null,this.cursorLineX=null,this.connectorDrag=null,this._systemThemeMediaQuery=null,this.isExporting=!1,this.focusedTaskId=null,this.focusedRowId=null,this._layoutCache=null,this.resizeObserver=null,this._cachedSelectedTaskIds=[],this._cachedSelectedTasksSize=-1,this._cachedCurrentOption=null,this._lastOptionRef=null,this._lastLabelWidth=-1,this.handleSystemThemeChange=e=>{(this.option?.theme===`system`||this.option?.theme!==`light`&&this.option?.theme!==`dark`)&&(this.theme=e.matches?`dark`:`light`)},this.handleScroll=e=>{let t=e.target;this.updateScrollTop(t.scrollTop),this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&={...this.tooltip,visible:!1}},this.updateScrollTop=(0,a.throttle)(e=>{this.virtualScrollTop=e},100),this.handleContainerMouseMove=e=>{if(!this.option.calendar.showCursorLine)return;let t=this.shadowRoot?.querySelector(`.scroll-container`);if(!t)return;let n=t.getBoundingClientRect(),r=e.clientX-n.left+t.scrollLeft;if(r<this.currentRowHeaderWidth){this.cursorLineX=null;return}this.cursorLineX=r},this.handleContainerMouseLeave=()=>{this.cursorLineX=null},this.handleKeyDown=e=>{if(this.option.keyboard?.enabled===!1)return;let t=e.composedPath()[0];if(!(t!==this&&t?.tagName&&[`INPUT`,`TEXTAREA`,`SELECT`].includes(t.tagName)))switch(e.key){case`ArrowRight`:e.shiftKey&&!this.option.readOnly?this.moveSelectedTasksByKeyboard(1):this.moveFocusHorizontal(1),e.preventDefault();break;case`ArrowLeft`:e.shiftKey&&!this.option.readOnly?this.moveSelectedTasksByKeyboard(-1):this.moveFocusHorizontal(-1),e.preventDefault();break;case`ArrowDown`:this.moveFocusVertical(1),e.preventDefault();break;case`ArrowUp`:this.moveFocusVertical(-1),e.preventDefault();break;case`Enter`:case` `:this.focusedTaskId&&(e.ctrlKey||e.metaKey?this.toggleTaskSelection(this.focusedTaskId):this.selectSingleTask(this.focusedTaskId)),e.preventDefault();break;case`Escape`:this.clearSelection(),this.focusedTaskId=null,this.focusedRowId=null;break;case`Delete`:case`Backspace`:!this.option.readOnly&&this.selectedTasks.size>0&&this.dispatchEvent(new CustomEvent(`task-delete`,{detail:{taskIds:[...this.selectedTasks],event:e},bubbles:!0,composed:!0})),e.preventDefault();break;case`Home`:this.focusFirstOrLastTaskInRow(`first`),e.preventDefault();break;case`End`:this.focusFirstOrLastTaskInRow(`last`),e.preventDefault();break}}}get displayRows(){return this.option.showHiddenRows?this.rows:this.rows.filter(e=>e.visible!==!1)}static{this.styles=J}firstUpdated(){this.setupCurrentTimeTimer();let e=this.shadowRoot?.getElementById(`calendar`);this.resizeObserver=new ResizeObserver(t=>{for(let n of t)n.target===this?this.viewportHeight=n.contentRect.height:n.target===e&&(this.calendarHeight=n.target.offsetHeight)}),this.resizeObserver.observe(this),e&&this.resizeObserver.observe(e)}connectedCallback(){super.connectedCallback(),this._systemThemeMediaQuery=window.matchMedia?window.matchMedia(`(prefers-color-scheme: dark)`):null,this._systemThemeMediaQuery?.addEventListener(`change`,this.handleSystemThemeChange),this.hasAttribute(`tabindex`)||this.setAttribute(`tabindex`,`0`),this.setAttribute(`role`,`grid`),this.setAttribute(`aria-label`,`Gantt Chart`),this.addEventListener(`keydown`,this.handleKeyDown),this.option?.theme===`system`||this.option?.theme!==`light`&&this.option?.theme!==`dark`?this.theme=this._systemThemeMediaQuery?.matches?`dark`:`light`:this.theme=this.option.theme}disconnectedCallback(){super.disconnectedCallback(),this.resizeObserver?.disconnect(),this.stopCurrentTimeTimer(),this._systemThemeMediaQuery?.removeEventListener(`change`,this.handleSystemThemeChange),this.removeEventListener(`keydown`,this.handleKeyDown)}willUpdate(e){if(e.has(`option`)&&(this.option?.theme===`light`||this.option?.theme===`dark`?this.theme=this.option.theme:this._systemThemeMediaQuery&&(this.theme=this._systemThemeMediaQuery.matches?`dark`:`light`)),e.has(`option`)&&(this.setupCurrentTimeTimer(),this.isResizingHeader||(this.currentRowHeaderWidth=this.option.rowHeader?.width??150)),(e.has(`rows`)||e.has(`option`)||e.has(`currentRowHeaderWidth`))&&(this._layoutCache=null),e.has(`selectedRowIds`)){let e=new Set(this.selectedRowIds);(e.size!==this.selectedRows.size||![...e].every(e=>this.selectedRows.has(e)))&&(this.selectedRows=e)}if(e.has(`selectedTaskIds`)){let e=new Set(this.selectedTaskIds);(e.size!==this.selectedTasks.size||![...e].every(e=>this.selectedTasks.has(e)))&&(this.selectedTasks=e)}(e.has(`selectedTasks`)||this._cachedSelectedTasksSize!==this.selectedTasks.size)&&(this._cachedSelectedTaskIds=[...this.selectedTasks],this._cachedSelectedTasksSize=this.selectedTasks.size)}updated(e){if(super.updated(e),this.tooltip){let e=this.shadowRoot?.querySelector(`.tooltip`);if(e){let n=this.option.customRendering?.tooltip?this.option.customRendering.tooltip(this.tooltip.task):void 0;if(n)typeof n==`string`?e.textContent=n:(0,t.render)(n,e);else{let n=this.option.locale??j,r=!!this.option.calendar.pxPerMonth,i=Math.round((this.tooltip.task.end.getTime()-this.tooltip.task.start.getTime())/(1e3*60*60*24));if(r){let r=new Date(this.tooltip.task.end);r.setMonth(r.getMonth()-1),(0,t.render)(t.html`
|
|
945
|
+
`}function X(e,t){let n=document.createElement(`a`);n.href=e,n.download=t,n.click()}async function Z(e,t=`png`,n={}){let{filename:r=`gantt-chart`,download:i=!1,scale:a=2,splitHeight:c}=n,l=e.shadowRoot?.querySelector(`.scroll-container`),u=l?l.scrollWidth:e.scrollWidth,d=l?l.scrollHeight:e.scrollHeight,f=await(0,o.default)(e,{backgroundColor:`#ffffff`,scale:a,width:u,height:d,windowWidth:u,windowHeight:d});if(c&&d>c){let t=50,n=e.shadowRoot?.querySelector(`gantt-calendar`);n&&n.offsetHeight>0?t=n.offsetHeight:e.calendarHeight&&(t=e.calendarHeight);let r=f.height/d,i=d-t,a=c-t,o=[];typeof e.getRowPositions==`function`&&(o=e.getRowPositions().map(e=>e.bottom));let s=[0],l=0;if(a>0)for(;l<i;){let e=l+a;if(e>=i){s.push(i);break}let t=-1;for(let n=0;n<o.length;n++){let r=o[n];r>l&&r<=e&&(t=Math.max(t,r))}if(t===-1)for(let e=0;e<o.length;e++){let n=o[e];if(n>l){t=n;break}}(t===-1||t===l)&&(t=e),s.push(t),l=t}else s.push(i);let u=s.length-1;if(u>0){let e=Math.floor(t*r),n=f.width,i=0,a=[];for(let n=0;n<u;n++){let o=s[n],c=s[n+1],l=Math.round((t+o)*r),u=Math.round((t+c)*r),d=u-l;a.push({srcStart:l,srcEnd:u,destHeight:d}),i+=e+d}let o=document.createElement(`canvas`);o.width=n,o.height=i;let c=o.getContext(`2d`);if(c){let t=0;for(let r=0;r<u;r++){c.drawImage(f,0,0,n,e,0,t,n,e),t+=e;let i=a[r];c.drawImage(f,0,i.srcStart,n,i.destHeight,0,t,n,i.destHeight),t+=i.destHeight}f=o,d=i/r}else console.warn(`[export] Failed to get 2D context for new canvas. It might be too large.`)}}if(t===`pdf`){let e=f.toDataURL(`image/jpeg`,.9),t=new s.jsPDF({orientation:u>d?`l`:`p`,unit:`px`,format:[u,d],compress:!0});return t.addImage(e,`JPEG`,0,0,u,d,void 0,`FAST`),i&&t.save(`${r}.pdf`),t.output(`blob`)}else{let e=f.toDataURL(`image/png`);return i&&X(e,`${r}.png`),e}}function Q(e){let t=new Map,n=new Map,r=new Map;for(let n of e)for(let e of n.tasks){let n=e.dependencies??[],i=e.start instanceof Date?e.start.getTime():new Date(e.start).getTime(),a=e.end instanceof Date?e.end.getTime():new Date(e.end).getTime();isNaN(i)||isNaN(a)||(t.set(e.id,{start:i,end:a,duration:a-i,dependencies:n}),r.set(e.id,0))}let i=new Set;for(let[e,a]of t){let o=0;for(let r of a.dependencies)if(t.has(r)){o++;let t=n.get(r)??[];t.push(e),n.set(r,t),i.add(e),i.add(r)}r.set(e,o)}if(i.size<2)return new Set;let a=[];for(let e of i)(r.get(e)??0)===0&&a.push(e);let o=[];for(;a.length>0;){let e=a.shift();o.push(e);for(let t of n.get(e)??[]){if(!i.has(t))continue;let e=(r.get(t)??0)-1;r.set(t,e),e===0&&a.push(t)}}if(o.length<i.size){let e=new Set(o);for(let t of i)e.has(t)||i.delete(t);if(i.size<2)return new Set}let s=new Map,c=new Map;for(let e of o){let n=t.get(e);if(!n)continue;let r=n.dependencies.filter(e=>s.has(e));if(r.length===0)s.set(e,n.end),c.set(e,null);else{let t=-1/0,i=null;for(let e of r){let r=s.get(e)+n.duration;r>t&&(t=r,i=e)}n.end>t&&(t=n.end),s.set(e,t),c.set(e,i)}}let l=[];for(let e of o)(n.get(e)??[]).filter(e=>i.has(e)).length===0&&l.push(e);if(l.length===0)return new Set;let u=l[0],d=s.get(l[0])??0;for(let e=1;e<l.length;e++){let t=s.get(l[e])??0;t>d&&(d=t,u=l[e])}let f=new Set,p=u;for(;p!==null;)f.add(p),p=c.get(p)??null;return f.size<=1?new Set:f}var $=class extends t.LitElement{constructor(...e){super(...e),this.rows=[],this.theme=`light`,this.selectedRowIds=[],this.selectedTaskIds=[],this.externalDraggingTask=null,this.selectedRows=new Set,this.selectedTasks=new Set,this.lastClickedRowId=null,this.virtualScrollTop=0,this.dragTargetRowIndex=null,this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.viewportHeight=400,this.dragOverlayInfo=null,this.calendarHeight=0,this.tooltip=null,this.dragOverRowId=null,this.dragOverPosition=null,this.currentTime=new Date,this.dragPreview=null,this.currentRowHeaderWidth=150,this.isResizingHeader=!1,this.hoveredMilestoneId=null,this.cursorLineX=null,this.connectorDrag=null,this._systemThemeMediaQuery=null,this.isExporting=!1,this.focusedTaskId=null,this.focusedRowId=null,this.zoomPxPerDay=null,this.zoomPxPerMonth=null,this._layoutCache=null,this.resizeObserver=null,this._cachedSelectedTaskIds=[],this._cachedSelectedTasksSize=-1,this._cachedCurrentOption=null,this._lastOptionRef=null,this._lastLabelWidth=-1,this._lastZoomPxPerDay=null,this._lastZoomPxPerMonth=null,this._scrollContainer=null,this.handleSystemThemeChange=e=>{(this.option?.theme===`system`||this.option?.theme!==`light`&&this.option?.theme!==`dark`)&&(this.theme=e.matches?`dark`:`light`)},this.handleScroll=e=>{let t=e.target;this.updateScrollTop(t.scrollTop),this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&={...this.tooltip,visible:!1}},this.updateScrollTop=(0,a.throttle)(e=>{this.virtualScrollTop=e},100),this.handleContainerMouseMove=e=>{if(!this.option.calendar.showCursorLine)return;let t=this.shadowRoot?.querySelector(`.scroll-container`);if(!t)return;let n=t.getBoundingClientRect(),r=e.clientX-n.left+t.scrollLeft;if(r<this.currentRowHeaderWidth){this.cursorLineX=null;return}this.cursorLineX=r},this.handleContainerMouseLeave=()=>{this.cursorLineX=null},this.handleWheel=e=>{if(!e.ctrlKey&&!e.metaKey||this.option.zoom?.enabled!==!0)return;e.preventDefault();let t=this._scrollContainer;if(!t)return;let n=t.getBoundingClientRect(),r=this.currentRowHeaderWidth,i=e.clientX-n.left+t.scrollLeft-r,a=this.effectivePxPerMonth!==void 0,o=a?this.effectivePxPerMonth:this.effectivePxPerDay,s=this.option.zoom?.step??1.2,c=a?20:2,l=a?600:200,u=this.option.zoom?.min??c,d=this.option.zoom?.max??l,f=e.deltaY>0?1/s:s,p=Math.max(u,Math.min(d,o*f));if(p===o)return;a?this.zoomPxPerMonth=p:this.zoomPxPerDay=p;let m=p/o;this.updateComplete.then(()=>{let e=i*m-i;t.scrollLeft+=e}),this.dispatchEvent(new CustomEvent(`zoom-change`,{detail:{pxPerDay:a?this.effectivePxPerDay:p,pxPerMonth:a?p:void 0},bubbles:!0,composed:!0}))},this.handleKeyDown=e=>{if(this.option.keyboard?.enabled===!1)return;let t=e.composedPath()[0];if(!(t!==this&&t?.tagName&&[`INPUT`,`TEXTAREA`,`SELECT`].includes(t.tagName)))switch(e.key){case`ArrowRight`:e.shiftKey&&!this.option.readOnly?this.moveSelectedTasksByKeyboard(1):this.moveFocusHorizontal(1),e.preventDefault();break;case`ArrowLeft`:e.shiftKey&&!this.option.readOnly?this.moveSelectedTasksByKeyboard(-1):this.moveFocusHorizontal(-1),e.preventDefault();break;case`ArrowDown`:this.moveFocusVertical(1),e.preventDefault();break;case`ArrowUp`:this.moveFocusVertical(-1),e.preventDefault();break;case`Enter`:case` `:this.focusedTaskId&&(e.ctrlKey||e.metaKey?this.toggleTaskSelection(this.focusedTaskId):this.selectSingleTask(this.focusedTaskId)),e.preventDefault();break;case`Escape`:this.clearSelection(),this.focusedTaskId=null,this.focusedRowId=null;break;case`Delete`:case`Backspace`:!this.option.readOnly&&this.selectedTasks.size>0&&this.dispatchEvent(new CustomEvent(`task-delete`,{detail:{taskIds:[...this.selectedTasks],event:e},bubbles:!0,composed:!0})),e.preventDefault();break;case`Home`:this.focusFirstOrLastTaskInRow(`first`),e.preventDefault();break;case`End`:this.focusFirstOrLastTaskInRow(`last`),e.preventDefault();break}}}get displayRows(){return this.option.showHiddenRows?this.rows:this.rows.filter(e=>e.visible!==!1)}get effectivePxPerDay(){return this.zoomPxPerDay??this.option.calendar.pxPerDay??50}get effectivePxPerMonth(){return this.zoomPxPerMonth??this.option.calendar.pxPerMonth}static{this.styles=J}firstUpdated(){this.setupCurrentTimeTimer();let e=this.shadowRoot?.getElementById(`calendar`);this.resizeObserver=new ResizeObserver(t=>{for(let n of t)n.target===this?this.viewportHeight=n.contentRect.height:n.target===e&&(this.calendarHeight=n.target.offsetHeight)}),this.resizeObserver.observe(this),e&&this.resizeObserver.observe(e),this._scrollContainer=this.shadowRoot?.querySelector(`.scroll-container`),this._scrollContainer?.addEventListener(`wheel`,this.handleWheel,{passive:!1})}connectedCallback(){super.connectedCallback(),this._systemThemeMediaQuery=window.matchMedia?window.matchMedia(`(prefers-color-scheme: dark)`):null,this._systemThemeMediaQuery?.addEventListener(`change`,this.handleSystemThemeChange),this.hasAttribute(`tabindex`)||this.setAttribute(`tabindex`,`0`),this.setAttribute(`role`,`grid`),this.setAttribute(`aria-label`,`Gantt Chart`),this.addEventListener(`keydown`,this.handleKeyDown),this.option?.theme===`system`||this.option?.theme!==`light`&&this.option?.theme!==`dark`?this.theme=this._systemThemeMediaQuery?.matches?`dark`:`light`:this.theme=this.option.theme}disconnectedCallback(){super.disconnectedCallback(),this.resizeObserver?.disconnect(),this.stopCurrentTimeTimer(),this._systemThemeMediaQuery?.removeEventListener(`change`,this.handleSystemThemeChange),this.removeEventListener(`keydown`,this.handleKeyDown),this._scrollContainer?.removeEventListener(`wheel`,this.handleWheel),this._scrollContainer=null}willUpdate(e){if(e.has(`option`)&&(this.option?.theme===`light`||this.option?.theme===`dark`?this.theme=this.option.theme:this._systemThemeMediaQuery&&(this.theme=this._systemThemeMediaQuery.matches?`dark`:`light`)),e.has(`option`)&&(this.setupCurrentTimeTimer(),this.isResizingHeader||(this.currentRowHeaderWidth=this.option.rowHeader?.width??150),this.zoomPxPerDay=null,this.zoomPxPerMonth=null),(e.has(`rows`)||e.has(`option`)||e.has(`currentRowHeaderWidth`)||e.has(`zoomPxPerDay`)||e.has(`zoomPxPerMonth`))&&(this._layoutCache=null),e.has(`selectedRowIds`)){let e=new Set(this.selectedRowIds);(e.size!==this.selectedRows.size||![...e].every(e=>this.selectedRows.has(e)))&&(this.selectedRows=e)}if(e.has(`selectedTaskIds`)){let e=new Set(this.selectedTaskIds);(e.size!==this.selectedTasks.size||![...e].every(e=>this.selectedTasks.has(e)))&&(this.selectedTasks=e)}(e.has(`selectedTasks`)||this._cachedSelectedTasksSize!==this.selectedTasks.size)&&(this._cachedSelectedTaskIds=[...this.selectedTasks],this._cachedSelectedTasksSize=this.selectedTasks.size)}updated(e){if(super.updated(e),this.tooltip){let e=this.shadowRoot?.querySelector(`.tooltip`);if(e){let n=this.option.customRendering?.tooltip?this.option.customRendering.tooltip(this.tooltip.task):void 0;if(n)typeof n==`string`?e.textContent=n:(0,t.render)(n,e);else{let n=this.option.locale??j,r=!!this.option.calendar.pxPerMonth,i=Math.round((this.tooltip.task.end.getTime()-this.tooltip.task.start.getTime())/(1e3*60*60*24));if(r){let r=new Date(this.tooltip.task.end);r.setMonth(r.getMonth()-1),(0,t.render)(t.html`
|
|
930
946
|
<div style="font-weight: bold;">${this.tooltip.task.name}</div>
|
|
931
947
|
<div class="tooltip-row">
|
|
932
948
|
${n.yearMonthFormat(this.tooltip.task.start)} - ${n.yearMonthFormat(r)}
|
|
@@ -948,13 +964,17 @@
|
|
|
948
964
|
(${B(this.dragOverlayInfo.currentStart,this.dragOverlayInfo.currentEnd,this.option.locale)})
|
|
949
965
|
</div>
|
|
950
966
|
${r?t.html`<div class="drag-info-sub" style="margin-top: 4px; border-top: 1px solid ${e.dragOverlayDivider}; padding-top: 4px; width: 100%;">${(this.option.locale??j).dragOverlay.moveTo(r.name)}</div>`:``}
|
|
951
|
-
`,n)}if(this.dragOverlayInfo.clientY!==void 0){let e=this.dragOverlayInfo.clientX??0,t=this.dragOverlayInfo.clientY,r=this.getBoundingClientRect();if(e<r.left||e>r.right||t<r.top||t>r.bottom){n.classList.remove(`visible`);return}let i=n.offsetWidth||200,a=n.offsetHeight||60,o=window.innerWidth,s=window.innerHeight,c=e-i/2;c=Math.max(8,Math.min(c,o-i-8));let l=t-a-40;l<8&&(l=t+40),l+a>s-8&&(l=s-a-8),n.style.left=`${c}px`,n.style.transform=`none`,n.style.top=`${l}px`,n.style.bottom=`auto`}}hideDragOverlay(){let e=this.shadowRoot?.querySelector(`.drag-info-overlay`);e&&e.classList.remove(`visible`)}setupCurrentTimeTimer(){this.stopCurrentTimeTimer();let e=this.option.calendar.currentTimeUpdateInterval;e&&e>0&&(this.currentTimeTimer=window.setInterval(()=>{this.currentTime=new Date},e))}stopCurrentTimeTimer(){this.currentTimeTimer!==void 0&&(window.clearInterval(this.currentTimeTimer),this.currentTimeTimer=void 0)}handleHeaderResizeStart(e){e.preventDefault(),e.stopPropagation(),this.isResizingHeader=!0;let t=e.clientX,n=this.currentRowHeaderWidth,r=e.target;r.setPointerCapture(e.pointerId);let i=this.option.rowHeader?.minWidth??50,a=this.option.rowHeader?.maxWidth??2**53-1,o=e=>{let r=n+(e.clientX-t);this.currentRowHeaderWidth=Math.max(i,Math.min(a,r))},s=()=>{this.isResizingHeader=!1,r.releasePointerCapture(e.pointerId),r.removeEventListener(`pointermove`,o),r.removeEventListener(`pointerup`,s);let t=Math.round(this.currentRowHeaderWidth);this.currentRowHeaderWidth=t,this.dispatchEvent(new CustomEvent(`row-header-resize`,{detail:{width:t},bubbles:!0,composed:!0}))};r.addEventListener(`pointermove`,o),r.addEventListener(`pointerup`,s)}getDateX(e){return P(e,this.option.calendar.start,this.option.calendar.pxPerDay??50,this.option.calendar.pxPerMonth)}calculateLayout(){if(this._layoutCache)return this._layoutCache;let e=0,t=this.currentRowHeaderWidth,n=new Map,r={layouts:this.displayRows.map(r=>{let{tasksWithLanes:i,laneCount:a}=I(r.tasks),o=this.option.bar?.height??28,s=this.option.bar?.margin??4;i.forEach(r=>{let i=this.getDateX(r.start)+t,a=this.getDateX(r.end)+t-i,c=e+r.lane*(o+s)+s;n.set(r.id,{x:i,y:c,width:a,height:o,dependencies:r.dependencies})});let c=a*(o+s)+s,l={top:e,height:c};return e+=c,l}),taskCoords:n,totalHeight:e};return this._layoutCache=r,r}isMultiDrag(e){return this.selectedTasks.size>=2&&this.selectedTasks.has(e)}isMultiDragSameRow(){if(this.selectedTasks.size<2)return!1;let e=null;for(let t of this.rows)for(let n of t.tasks)if(this.selectedTasks.has(n.id)){if(e===null)e=t.id;else if(e!==t.id)return!1}return e!==null}handleTaskUpdate(e){e.stopPropagation();let{id:t,start:n,end:r,dx:i,isDragging:a,mode:o}=e.detail,{dy:s}=e.detail,c=this.isMultiDrag(t),l=c&&this.isMultiDragSameRow();c&&!l&&(s=0);let u=n,d=r;if(i!==void 0){let e=this.option.calendar.pxPerDay??50,t=this.option.calendar.pxPerMonth,a=this.getDateX(n),o=this.getDateX(r);u=F(a+i,this.option.calendar.start,e,t),d=F(o+i,this.option.calendar.start,e,t)}(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(u.getDate()>15&&u.setMonth(u.getMonth()+1),u.setDate(1),u.setHours(0,0,0,0),d.getDate()>15&&d.setMonth(d.getMonth()+1),d.setDate(1),d.setHours(0,0,0,0));let f=-1,p,m=-1;if(this.rows.find((e,n)=>{let r=e.tasks.findIndex(e=>e.id===t);return r===-1?!1:(f=n,p=e.tasks[r],m=r,!0)}),f===-1||!p)return;let{layouts:h}=this.calculateLayout(),g=this.displayRows.findIndex(e=>e.id===this.rows[f].id);if(g===-1)return;let _=h[g].top,{tasksWithLanes:v}=I(this.rows[f].tasks),y=v.find(e=>e.id===t),b=y?y.lane:0,x=this.option.bar?.height??28,S=this.option.bar?.margin??4,C=_+(b*(x+S)+S)+s+x/2,w=-1;for(let e=0;e<h.length;e++){let t=h[e];if(C>=t.top&&C<t.top+t.height){w=e;break}}let T=w===-1?void 0:this.displayRows[w].id,E=c?[...this.selectedTasks]:void 0;if(this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...e.detail,dy:s,start:u,end:d,targetRowId:T,selectedTaskIds:E},bubbles:!0,composed:!0})),a){if(this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&=null,(!this.draggingTask||this.draggingTask.id!==t)&&(this.draggingTask={id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,mode:o},c?this.draggingTaskIds=[...this.selectedTasks]:this.draggingTaskIds=[]),c?(this.multiDragDx=i??0,this.multiDragSameRow=l,l?this.multiDragDy=s:this.multiDragDy=0):(this.multiDragDx!==0||this.multiDragDy!==0)&&(this.multiDragDx=0,this.multiDragDy=0),!c||l){let e=w>=0?w:null;this.dragTargetRowIndex!==e&&(this.dragTargetRowIndex=e)}c?this.dragOverlayInfo={id:t,name:(this.option.locale??j).dragOverlay.movingTasks(this.selectedTasks.size),start:n,end:r,currentStart:u,currentEnd:d,visible:!0,clientX:e.detail.x,clientY:e.detail.y}:this.dragOverlayInfo={id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,targetRow:w>=0?this.displayRows[w]:void 0,visible:!0,clientX:e.detail.x,clientY:e.detail.y},this.updateDragOverlay();return}let D=this.draggingTaskIds.length>=2,O=this.multiDragSameRow;this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay()),this.tooltip&&={...this.tooltip,visible:!1};let k=-1;if(w!==-1){let e=this.displayRows[w];k=this.rows.findIndex(t=>t.id===e.id)}if(D&&i!==void 0){let e=this.option.calendar.pxPerDay??50,t=this.option.calendar.pxPerMonth;if(O&&k!==-1&&f!==k){let n=[...this.rows],r={...n[f]},a={...n[k]};r.tasks=[...r.tasks],a.tasks=[...a.tasks];let o=[];r.tasks=r.tasks.filter(n=>{if(this.selectedTasks.has(n.id)){let r=this.getDateX(n.start),a=this.getDateX(n.end),s=F(r+i,this.option.calendar.start,e,t),c=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0),c.getDate()>15&&c.setMonth(c.getMonth()+1),c.setDate(1),c.setHours(0,0,0,0)),o.push({...n,start:s,end:c}),!1}return!0}),a.tasks.push(...o),n[f]=r,n[k]=a,requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}else{let n=this.rows.map(n=>n.tasks.some(e=>this.selectedTasks.has(e.id))?{...n,tasks:n.tasks.map(n=>{if(!this.selectedTasks.has(n.id))return n;let r=this.getDateX(n.start),a=this.getDateX(n.end),o=F(r+i,this.option.calendar.start,e,t),s=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(o.getDate()>15&&o.setMonth(o.getMonth()+1),o.setDate(1),o.setHours(0,0,0,0),s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0)),{...n,start:o,end:s}})}:n);requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}return}if(o===`copy`){if(k!==-1){let e=[...this.rows],t={...e[k]};t.tasks=[...t.tasks];let n=`task-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,r={...p,id:n,start:u,end:d,dependencies:[]};t.tasks.push(r),e[k]=t,requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}else{let e=[...this.rows],t={...e[f]};if(t.tasks=[...t.tasks],e[f]=t,k!==-1&&f!==k){let n={...e[k]};n.tasks=[...n.tasks],e[k]=n;let[r]=t.tasks.splice(m,1);n.tasks.push({...r,start:u,end:d})}else t.tasks[m]={...p,start:u,end:d};requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}handleBarMouseEnter(e){if(this.draggingTask||this.option.showTooltip===!1)return;this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer);let t=this.option.tooltipDelay??500;t>0?this.hoverTimer=window.setTimeout(()=>{this.tooltip={...e.detail,visible:!0}},t):this.tooltip={...e.detail,visible:!0}}handleBarMouseLeave(){this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&={...this.tooltip,visible:!1}}async reorderRows(e,t,n){let r=Array.isArray(e)?e:[e],i=Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]),a=new Map;i.forEach(e=>{e.row&&a.set(e.row.id,e.getBoundingClientRect().top)});let o=[...this.rows],s=[];if(o.findIndex(e=>e.id===t)===-1)return;r.forEach(e=>{let t=o.findIndex(t=>t.id===e);t!==-1&&s.push(o[t])});let c=o.filter(e=>!r.includes(e.id));if(r.includes(t))return;let l=c.findIndex(e=>e.id===t);n===`bottom`&&l++,c.splice(l,0,...s),this.rows=c,await this.updateComplete,Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]).forEach(e=>{if(e.row){let t=a.get(e.row.id);if(t!==void 0){let n=t-e.getBoundingClientRect().top;n!==0&&e.animate([{transform:`translateY(${n}px)`,zIndex:`1`},{transform:`translateY(0)`,zIndex:`1`}],{duration:300,easing:`ease-out`})}}}),this.dispatchEvent(new CustomEvent(`row-reordered`,{detail:{sourceId:r[0],sourceIds:r,targetId:t,position:n,rows:this.rows},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleContainerDragOver(e){e.preventDefault();let t=e.dataTransfer&&e.dataTransfer.types.includes(`application/json`);if(t&&(e.dataTransfer.dropEffect=`copy`),!this.option.enableRowReordering&&!t)return;let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return;let r=n.getBoundingClientRect(),i=e.clientY-r.top+n.scrollTop-this.calendarHeight,{layouts:a}=this.calculateLayout(),o=-1;for(let e=0;e<a.length;e++){let t=a[e];if(i>=t.top&&i<t.top+t.height){o=e;break}}if(o!==-1){let s=this.displayRows[o];if(t){if((this.dragOverRowId!==s.id||this.dragOverPosition!==null)&&(this.dragOverRowId=s.id,this.dragOverPosition=null),this.externalDraggingTask){let t=this.currentRowHeaderWidth,i=n.scrollLeft,a=e.clientX-r.left+i-t,o=this.option.calendar.pxPerDay??50,c=this.option.calendar.pxPerMonth,l=this.option.snapDuration??1440,u=o/1440*l,d=F(Math.round(a/u)*u,this.option.calendar.start,o,c),f=this.externalDraggingTask.end.getTime()-this.externalDraggingTask.start.getTime(),p=new Date(d.getTime()+f);(!this.dragPreview||this.dragPreview.rowId!==s.id||this.dragPreview.currentStart.getTime()!==d.getTime())&&(this.dragPreview={task:this.externalDraggingTask,currentStart:d,currentEnd:p,rowId:s.id})}}else{let e=a[o],t=i-e.top<e.height/2?`top`:`bottom`;(this.dragOverRowId!==s.id||this.dragOverPosition!==t)&&(this.dragOverRowId=s.id,this.dragOverPosition=t)}}else this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null}handleContainerDragLeave(e){let t=this.shadowRoot?.querySelector(`.scroll-container`),n=e.relatedTarget;t&&t.contains(n)||(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null)}handleContainerDrop(e){e.preventDefault();let t=e.dataTransfer?.getData(`application/json`);if(t){this.handleExternalTaskDrop(e,t),this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null;return}if(!this.option.enableRowReordering)return;let n=e.dataTransfer?.getData(`text/plain`),r=this.dragOverRowId,i=this.dragOverPosition;if(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null,n&&r&&n!==r&&i)if(this.selectedRows.has(n)&&this.selectedRows.size>1){let e=Array.from(this.selectedRows);this.reorderRows(e,r,i)}else this.reorderRows(n,r,i)}handleExternalTaskDrop(e,t){try{let n=JSON.parse(t);if(!n||typeof n!=`object`||typeof n.id!=`string`||typeof n.name!=`string`||!n.start||!n.end){console.warn(`Invalid dropped task data: missing required fields (id, name, start, end)`);return}let r=new Date(n.start),i=new Date(n.end);if(isNaN(r.getTime())||isNaN(i.getTime())){console.warn(`Invalid dropped task data: start or end is not a valid date`);return}let a={...n,start:r,end:i},o=this.shadowRoot?.querySelector(`.scroll-container`);if(!o)return;let s=o.getBoundingClientRect(),c=o.scrollLeft,l=o.scrollTop,u=this.currentRowHeaderWidth,d=e.clientX-s.left+c-u,f=this.option.calendar.pxPerDay??50,p=this.option.calendar.pxPerMonth,m=F(d,this.option.calendar.start,f,p),h=e.clientY-s.top+l-this.calendarHeight,{layouts:g}=this.calculateLayout(),_;for(let e=0;e<g.length;e++){let t=g[e];if(h>=t.top&&h<t.top+t.height){_=this.displayRows[e].id;break}}_&&this.dispatchEvent(new CustomEvent(`task-drop`,{detail:{task:a,dropDate:m,targetRowId:_},bubbles:!0,composed:!0}))}catch(e){console.warn(`Failed to parse dropped task data`,e)}}handleRowClicked(e){let{rowId:t,event:n}=e.detail,{shiftKey:r,ctrlKey:i,metaKey:a}=n,o=new Set(this.selectedRows);if(r&&this.lastClickedRowId){let e=this.rows.findIndex(e=>e.id===this.lastClickedRowId),n=this.rows.findIndex(e=>e.id===t);if(e!==-1&&n!==-1){let t=Math.min(e,n),r=Math.max(e,n);for(let e=t;e<=r;e++)o.add(this.rows[e].id)}}else if(i||a)o.has(t)?o.delete(t):o.add(t),this.lastClickedRowId=t;else{if(o.has(t)){this.lastClickedRowId=t;return}o.clear(),o.add(t),this.lastClickedRowId=t}this.selectedRows=o,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:Array.from(this.selectedRows)},bubbles:!0,composed:!0}))}handleRowContextMenu(e){this.selectedRows.has(e.detail.rowId)||this.handleRowClicked(e)}handleContainerClick(e){e.defaultPrevented||this.clearSelection()}handleContainerContextMenu(e){if(e.defaultPrevented)return;e.preventDefault();let t=this.shadowRoot?.querySelector(`.scroll-container`);if(!t)return;let n=t.getBoundingClientRect(),r=t.scrollLeft,i=t.scrollTop,a=this.currentRowHeaderWidth,o=e.clientY-n.top+i-this.calendarHeight,{layouts:s}=this.calculateLayout(),c;for(let e=0;e<s.length;e++){let t=s[e];if(o>=t.top&&o<t.top+t.height){c=this.displayRows[e].id;break}}if(c){let t=e.clientX-n.left+r-a,i=this.option.calendar.pxPerDay??50,o=this.option.calendar.pxPerMonth,s=F(t,this.option.calendar.start,i,o);this.dispatchEvent(new CustomEvent(`chart-contextmenu`,{detail:{event:e,date:s,rowId:c},bubbles:!0,composed:!0}))}this.clearSelection()}hitTest(e,t){let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return null;let r=n.getBoundingClientRect(),i=n.scrollLeft,a=n.scrollTop,o=this.currentRowHeaderWidth,s=t-r.top+a-this.calendarHeight,{layouts:c}=this.calculateLayout(),l;for(let e=0;e<c.length;e++){let t=c[e];if(s>=t.top&&s<t.top+t.height){l=this.displayRows[e].id;break}}if(!l)return null;let u=e-r.left+i-o,d=this.option.calendar.pxPerDay??50,f=this.option.calendar.pxPerMonth,p=F(u,this.option.calendar.start,d,f);return{rowId:l,date:p}}async exportImage(e=`png`,t={}){this.isExporting=!0,await this.updateComplete,await new Promise(e=>requestAnimationFrame(e));try{return await Z(this,e,t)}finally{this.isExporting=!1,await this.updateComplete}}clearSelection(){this.selectedRows.size===0&&this.selectedTasks.size===0||(this.selectedRows.size>0&&(this.selectedRows=new Set,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))),this.selectedTasks.size>0&&(this.selectedTasks=new Set,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))))}moveFocusHorizontal(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}let r=t[n],i=[...r.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),a=i.findIndex(e=>e.id===this.focusedTaskId);if(a===-1){i.length>0&&this.setFocus(i[0].id,r.id);return}let o=a+e;o>=0&&o<i.length?this.setFocus(i[o].id,r.id):this.moveFocusVertical(e)}moveFocusVertical(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}for(let r=n+e;r>=0&&r<t.length;r+=e){let n=t[r];if(n.tasks.length>0){let t=[...n.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e>0?t[0]:t[t.length-1];this.setFocus(r.id,n.id);return}}}focusFirstAvailableTask(){for(let e of this.displayRows)if(e.tasks.length>0){let t=[...e.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime());this.setFocus(t[0].id,e.id);return}}focusFirstOrLastTaskInRow(e){if(!this.focusedRowId){this.focusFirstAvailableTask();return}let t=this.displayRows.find(e=>e.id===this.focusedRowId);if(!t||t.tasks.length===0)return;let n=[...t.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e===`first`?n[0]:n[n.length-1];this.setFocus(r.id,t.id)}setFocus(e,t){this.focusedTaskId=e,this.focusedRowId=t,this.scrollToTask(e)}toggleTaskSelection(e){let t=new Set(this.selectedTasks);t.has(e)?t.delete(e):t.add(e),this.selectedTasks=t,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...t]},bubbles:!0,composed:!0}))}selectSingleTask(e){this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0}))}moveSelectedTasksByKeyboard(e){if(this.selectedTasks.size===0)return;let t=(this.option.keyboard?.moveStep??this.option.snapDuration??1440)*60*1e3*e,n=this.rows.map(e=>e.tasks.some(e=>this.selectedTasks.has(e.id))?{...e,tasks:e.tasks.map(e=>this.selectedTasks.has(e.id)?{...e,start:new Date(e.start.getTime()+t),end:new Date(e.end.getTime()+t)}:e)}:e);for(let e of this.rows)for(let n of e.tasks){if(!this.selectedTasks.has(n.id))continue;let r=new Date(n.start.getTime()+t),i=new Date(n.end.getTime()+t);this.dispatchEvent(new CustomEvent(`task-update`,{detail:{id:n.id,name:n.name,start:r,end:i,dx:0,dy:0,isDragging:!1,mode:`move`,targetRowId:e.id},bubbles:!0,composed:!0}))}this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleBarClick(e){e.stopPropagation();let{task:t,isMultiSelect:n}=e.detail;this.draggingTask=null,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay());let r;n?(r=new Set(this.selectedTasks),r.has(t.id)?r.delete(t.id):r.add(t.id)):r=new Set([t.id]),this.selectedTasks=r,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...r]},bubbles:!0,composed:!0}))}handleBarContextMenu(e){let{task:t}=e.detail;this.selectedTasks.has(t.id)||(this.selectedTasks=new Set([t.id]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[t.id]},bubbles:!0,composed:!0})))}handleConnectorDragStart(e){let{taskId:t,endpoint:n,clientX:r,clientY:i}=e.detail;e.stopPropagation();let{taskCoords:a}=this.calculateLayout(),o=a.get(t),s=this.currentRowHeaderWidth,c=e.detail.startX+s,l=e.detail.startY;o&&(c=n===`start`?o.x:o.x+o.width,l=o.y+o.height/2),this.connectorDrag={sourceTaskId:t,sourceEndpoint:n,startX:c,startY:l,currentClientX:r,currentClientY:i,targetTaskId:null,targetEndpoint:null},this.tooltip&&=null}handleConnectorDragMove(e){if(!this.connectorDrag)return;e.stopPropagation();let{clientX:t,clientY:n}=e.detail,r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=r.getBoundingClientRect(),a=t-i.left+r.scrollLeft,o=n-i.top+r.scrollTop-this.calendarHeight,{taskCoords:s}=this.calculateLayout(),c=null,l=null,u=30;for(let[e,t]of s){if(e===this.connectorDrag.sourceTaskId)continue;let n=t.y+t.height/2,r=t.x,i=t.x+t.width,s=Math.sqrt((a-r)**2+(o-n)**2),d=Math.sqrt((a-i)**2+(o-n)**2);s<u&&(u=s,c=e,l=`start`),d<u&&(u=d,c=e,l=`end`)}let d=this.connectorDrag.targetTaskId;d!==c&&(d&&this._setConnectorDropTarget(d,!1),c&&this._setConnectorDropTarget(c,!0)),this.connectorDrag={...this.connectorDrag,currentClientX:t,currentClientY:n,targetTaskId:c,targetEndpoint:l}}handleConnectorDragEnd(e){if(!this.connectorDrag)return;e.stopPropagation();let{cancelled:t}=e.detail,{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a}=this.connectorDrag;i&&this._setConnectorDropTarget(i,!1),!t&&i&&a&&this.dispatchEvent(new CustomEvent(`dependency-create`,{detail:{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a},bubbles:!0,composed:!0})),this.connectorDrag=null}_setConnectorDropTarget(e,t){let n=this.shadowRoot?.querySelectorAll(`gantt-row`);if(n)for(let r of n){let n=r.shadowRoot?.querySelectorAll(`gantt-bar`);if(n){for(let r of n)if(r.task?.id===e){r.connectorDropTarget=t;return}}}}handleDependencyLineClick(e,t,n){this.dispatchEvent(new CustomEvent(`dependency-click`,{detail:{event:e,sourceTaskId:n,targetTaskId:t},bubbles:!0,composed:!0}))}selectTask(e){let t=!1;for(let n of this.displayRows)if(n.tasks.some(t=>t.id===e)){t=!0;break}return t?(this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0})),this.scrollToTask(e),!0):!1}scrollToTask(e){let{taskCoords:t}=this.calculateLayout(),n=t.get(e);if(!n)return;let r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=this.currentRowHeaderWidth,a=n.y+this.calendarHeight,o=a+n.height,s=r.scrollTop,c=r.scrollTop+r.clientHeight;if(a<s||o>c){let e=a-r.clientHeight/2+n.height/2;r.scrollTo({top:Math.max(0,e),behavior:`smooth`})}let l=n.x,u=n.x+n.width,d=r.scrollLeft+i,f=r.scrollLeft+r.clientWidth;if(l<d||u>f){let e=l-i-20;r.scrollTo({left:Math.max(0,e),behavior:`smooth`})}}render(){let e=L(this.theme,this.option.customTheme),{layouts:n,taskCoords:r,totalHeight:a}=this.calculateLayout(),o=this.currentRowHeaderWidth;(this._lastOptionRef!==this.option||this._lastLabelWidth!==o)&&(this._cachedCurrentOption={...this.option,rowHeader:{...this.option.rowHeader,width:o}},this._lastOptionRef=this.option,this._lastLabelWidth=o);let s=this._cachedCurrentOption,c=0,l=this.displayRows.length-1;if(!this.isExporting){for(let e=0;e<n.length;e++)if(n[e].top+n[e].height>this.virtualScrollTop){c=Math.max(0,e-5);break}for(let e=c;e<n.length;e++)if(n[e].top>this.virtualScrollTop+this.viewportHeight){l=Math.min(this.displayRows.length-1,e+5);break}}let u=this.displayRows.slice(c,l+1),d=this.isExporting?0:n[c]?n[c].top:0,f=n[l],p=f?f.top+f.height:0,m=Math.max(0,a-p),h=a>this.viewportHeight,g=[],_=this.option.readOnly===!0,v=this.option.dependency?.showArrows!==!1,y=this.option.dependency?.arrowSize??8,b=this.option.dependency?.lineStyle??`orthogonal`,x=this.option.dependency?.cornerRadius??8;for(let[e,n]of r)if(n.dependencies)for(let i of n.dependencies){let a=r.get(i);if(a){let r=a.x+a.width,o=a.y+a.height/2,s=n.x,c=n.y+n.height/2,l=r<s,u=v?s-y:s,d=l?Math.max(r,u):u,f,p,m,h=this.option.bar?.height??28,S=this.option.bar?.margin??4;if(Math.abs(o-c)<1&&l)f=d>r?`M ${r} ${o} L ${d} ${c}`:``,p=s>r?`M ${r} ${o} L ${s} ${c}`:``;else if(b===`orthogonal`){let e=q(r,o,s,c,d,h,S,x);f=e.pathD,p=e.hitPathD}else if(l){let e=(r+d)/2;f=`M ${r} ${o} C ${e} ${o} ${e} ${c} ${d} ${c}`,p=`M ${r} ${o} C ${(r+s)/2} ${o} ${(r+s)/2} ${c} ${s} ${c}`}else{let e=Math.max(12,(r-s)*.15),t=(o+c)/2,n=Math.abs(o-c)<h?t+h+S:t;f=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+d)/2} ${n} S ${d-e} ${c}, ${d} ${c}`,p=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+s)/2} ${n} S ${s-e} ${c}, ${s} ${c}`}m=v?`M ${d} ${c} L ${s} ${c}`:``,g.push(t.svg`<g class="dependency-group">
|
|
967
|
+
`,n)}if(this.dragOverlayInfo.clientY!==void 0){let e=this.dragOverlayInfo.clientX??0,t=this.dragOverlayInfo.clientY,r=this.getBoundingClientRect();if(e<r.left||e>r.right||t<r.top||t>r.bottom){n.classList.remove(`visible`);return}let i=n.offsetWidth||200,a=n.offsetHeight||60,o=window.innerWidth,s=window.innerHeight,c=e-i/2;c=Math.max(8,Math.min(c,o-i-8));let l=t-a-40;l<8&&(l=t+40),l+a>s-8&&(l=s-a-8),n.style.left=`${c}px`,n.style.transform=`none`,n.style.top=`${l}px`,n.style.bottom=`auto`}}hideDragOverlay(){let e=this.shadowRoot?.querySelector(`.drag-info-overlay`);e&&e.classList.remove(`visible`)}setupCurrentTimeTimer(){this.stopCurrentTimeTimer();let e=this.option.calendar.currentTimeUpdateInterval;e&&e>0&&(this.currentTimeTimer=window.setInterval(()=>{this.currentTime=new Date},e))}stopCurrentTimeTimer(){this.currentTimeTimer!==void 0&&(window.clearInterval(this.currentTimeTimer),this.currentTimeTimer=void 0)}handleHeaderResizeStart(e){e.preventDefault(),e.stopPropagation(),this.isResizingHeader=!0;let t=e.clientX,n=this.currentRowHeaderWidth,r=e.target;r.setPointerCapture(e.pointerId);let i=this.option.rowHeader?.minWidth??50,a=this.option.rowHeader?.maxWidth??2**53-1,o=e=>{let r=n+(e.clientX-t);this.currentRowHeaderWidth=Math.max(i,Math.min(a,r))},s=()=>{this.isResizingHeader=!1,r.releasePointerCapture(e.pointerId),r.removeEventListener(`pointermove`,o),r.removeEventListener(`pointerup`,s);let t=Math.round(this.currentRowHeaderWidth);this.currentRowHeaderWidth=t,this.dispatchEvent(new CustomEvent(`row-header-resize`,{detail:{width:t},bubbles:!0,composed:!0}))};r.addEventListener(`pointermove`,o),r.addEventListener(`pointerup`,s)}getDateX(e){return P(e,this.option.calendar.start,this.effectivePxPerDay,this.effectivePxPerMonth)}calculateLayout(){if(this._layoutCache)return this._layoutCache;let e=0,t=this.currentRowHeaderWidth,n=new Map,r={layouts:this.displayRows.map(r=>{let{tasksWithLanes:i,laneCount:a}=I(r.tasks),o=this.option.bar?.height??28,s=this.option.bar?.margin??4;i.forEach(r=>{let i=this.getDateX(r.start)+t,a=this.getDateX(r.end)+t-i,c=e+r.lane*(o+s)+s;n.set(r.id,{x:i,y:c,width:a,height:o,dependencies:r.dependencies})});let c=a*(o+s)+s,l={top:e,height:c};return e+=c,l}),taskCoords:n,totalHeight:e};return this._layoutCache=r,r}isMultiDrag(e){return this.selectedTasks.size>=2&&this.selectedTasks.has(e)}isMultiDragSameRow(){if(this.selectedTasks.size<2)return!1;let e=null;for(let t of this.rows)for(let n of t.tasks)if(this.selectedTasks.has(n.id)){if(e===null)e=t.id;else if(e!==t.id)return!1}return e!==null}handleTaskUpdate(e){e.stopPropagation();let{id:t,start:n,end:r,dx:i,isDragging:a,mode:o}=e.detail,{dy:s}=e.detail,c=this.isMultiDrag(t),l=c&&this.isMultiDragSameRow();c&&!l&&(s=0);let u=n,d=r;if(i!==void 0){let e=this.effectivePxPerDay,t=this.effectivePxPerMonth,a=this.getDateX(n),o=this.getDateX(r);u=F(a+i,this.option.calendar.start,e,t),d=F(o+i,this.option.calendar.start,e,t)}(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(u.getDate()>15&&u.setMonth(u.getMonth()+1),u.setDate(1),u.setHours(0,0,0,0),d.getDate()>15&&d.setMonth(d.getMonth()+1),d.setDate(1),d.setHours(0,0,0,0));let f=-1,p,m=-1;if(this.rows.find((e,n)=>{let r=e.tasks.findIndex(e=>e.id===t);return r===-1?!1:(f=n,p=e.tasks[r],m=r,!0)}),f===-1||!p)return;let{layouts:h}=this.calculateLayout(),g=this.displayRows.findIndex(e=>e.id===this.rows[f].id);if(g===-1)return;let _=h[g].top,{tasksWithLanes:v}=I(this.rows[f].tasks),y=v.find(e=>e.id===t),b=y?y.lane:0,x=this.option.bar?.height??28,S=this.option.bar?.margin??4,C=_+(b*(x+S)+S)+s+x/2,w=-1;for(let e=0;e<h.length;e++){let t=h[e];if(C>=t.top&&C<t.top+t.height){w=e;break}}let T=w===-1?void 0:this.displayRows[w].id,E=c?[...this.selectedTasks]:void 0;if(this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...e.detail,dy:s,start:u,end:d,targetRowId:T,selectedTaskIds:E},bubbles:!0,composed:!0})),a){if(this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&=null,(!this.draggingTask||this.draggingTask.id!==t)&&(this.draggingTask={id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,mode:o},c?this.draggingTaskIds=[...this.selectedTasks]:this.draggingTaskIds=[]),c?(this.multiDragDx=i??0,this.multiDragSameRow=l,l?this.multiDragDy=s:this.multiDragDy=0):(this.multiDragDx!==0||this.multiDragDy!==0)&&(this.multiDragDx=0,this.multiDragDy=0),!c||l){let e=w>=0?w:null;this.dragTargetRowIndex!==e&&(this.dragTargetRowIndex=e)}c?this.dragOverlayInfo={id:t,name:(this.option.locale??j).dragOverlay.movingTasks(this.selectedTasks.size),start:n,end:r,currentStart:u,currentEnd:d,visible:!0,clientX:e.detail.x,clientY:e.detail.y}:this.dragOverlayInfo={id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,targetRow:w>=0?this.displayRows[w]:void 0,visible:!0,clientX:e.detail.x,clientY:e.detail.y},this.updateDragOverlay();return}let D=this.draggingTaskIds.length>=2,O=this.multiDragSameRow;this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay()),this.tooltip&&={...this.tooltip,visible:!1};let k=-1;if(w!==-1){let e=this.displayRows[w];k=this.rows.findIndex(t=>t.id===e.id)}if(D&&i!==void 0){let e=this.effectivePxPerDay,t=this.effectivePxPerMonth;if(O&&k!==-1&&f!==k){let n=[...this.rows],r={...n[f]},a={...n[k]};r.tasks=[...r.tasks],a.tasks=[...a.tasks];let o=[];r.tasks=r.tasks.filter(n=>{if(this.selectedTasks.has(n.id)){let r=this.getDateX(n.start),a=this.getDateX(n.end),s=F(r+i,this.option.calendar.start,e,t),c=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0),c.getDate()>15&&c.setMonth(c.getMonth()+1),c.setDate(1),c.setHours(0,0,0,0)),o.push({...n,start:s,end:c}),!1}return!0}),a.tasks.push(...o),n[f]=r,n[k]=a,requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}else{let n=this.rows.map(n=>n.tasks.some(e=>this.selectedTasks.has(e.id))?{...n,tasks:n.tasks.map(n=>{if(!this.selectedTasks.has(n.id))return n;let r=this.getDateX(n.start),a=this.getDateX(n.end),o=F(r+i,this.option.calendar.start,e,t),s=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(o.getDate()>15&&o.setMonth(o.getMonth()+1),o.setDate(1),o.setHours(0,0,0,0),s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0)),{...n,start:o,end:s}})}:n);requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}return}if(o===`copy`){if(k!==-1){let e=[...this.rows],t={...e[k]};t.tasks=[...t.tasks];let n=`task-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,r={...p,id:n,start:u,end:d,dependencies:[]};t.tasks.push(r),e[k]=t,requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}else{let e=[...this.rows],t={...e[f]};if(t.tasks=[...t.tasks],e[f]=t,k!==-1&&f!==k){let n={...e[k]};n.tasks=[...n.tasks],e[k]=n;let[r]=t.tasks.splice(m,1);n.tasks.push({...r,start:u,end:d})}else t.tasks[m]={...p,start:u,end:d};requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}handleBarMouseEnter(e){if(this.draggingTask||this.option.showTooltip===!1)return;this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer);let t=this.option.tooltipDelay??500;t>0?this.hoverTimer=window.setTimeout(()=>{this.tooltip={...e.detail,visible:!0}},t):this.tooltip={...e.detail,visible:!0}}handleBarMouseLeave(){this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&={...this.tooltip,visible:!1}}async reorderRows(e,t,n){let r=Array.isArray(e)?e:[e],i=Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]),a=new Map;i.forEach(e=>{e.row&&a.set(e.row.id,e.getBoundingClientRect().top)});let o=[...this.rows],s=[];if(o.findIndex(e=>e.id===t)===-1)return;r.forEach(e=>{let t=o.findIndex(t=>t.id===e);t!==-1&&s.push(o[t])});let c=o.filter(e=>!r.includes(e.id));if(r.includes(t))return;let l=c.findIndex(e=>e.id===t);n===`bottom`&&l++,c.splice(l,0,...s),this.rows=c,await this.updateComplete,Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]).forEach(e=>{if(e.row){let t=a.get(e.row.id);if(t!==void 0){let n=t-e.getBoundingClientRect().top;n!==0&&e.animate([{transform:`translateY(${n}px)`,zIndex:`1`},{transform:`translateY(0)`,zIndex:`1`}],{duration:300,easing:`ease-out`})}}}),this.dispatchEvent(new CustomEvent(`row-reordered`,{detail:{sourceId:r[0],sourceIds:r,targetId:t,position:n,rows:this.rows},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleContainerDragOver(e){e.preventDefault();let t=e.dataTransfer&&e.dataTransfer.types.includes(`application/json`);if(t&&(e.dataTransfer.dropEffect=`copy`),!this.option.enableRowReordering&&!t)return;let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return;let r=n.getBoundingClientRect(),i=e.clientY-r.top+n.scrollTop-this.calendarHeight,{layouts:a}=this.calculateLayout(),o=-1;for(let e=0;e<a.length;e++){let t=a[e];if(i>=t.top&&i<t.top+t.height){o=e;break}}if(o!==-1){let s=this.displayRows[o];if(t){if((this.dragOverRowId!==s.id||this.dragOverPosition!==null)&&(this.dragOverRowId=s.id,this.dragOverPosition=null),this.externalDraggingTask){let t=this.currentRowHeaderWidth,i=n.scrollLeft,a=e.clientX-r.left+i-t,o=this.effectivePxPerDay,c=this.effectivePxPerMonth,l=this.option.snapDuration??1440,u=o/1440*l,d=F(Math.round(a/u)*u,this.option.calendar.start,o,c),f=this.externalDraggingTask.end.getTime()-this.externalDraggingTask.start.getTime(),p=new Date(d.getTime()+f);(!this.dragPreview||this.dragPreview.rowId!==s.id||this.dragPreview.currentStart.getTime()!==d.getTime())&&(this.dragPreview={task:this.externalDraggingTask,currentStart:d,currentEnd:p,rowId:s.id})}}else{let e=a[o],t=i-e.top<e.height/2?`top`:`bottom`;(this.dragOverRowId!==s.id||this.dragOverPosition!==t)&&(this.dragOverRowId=s.id,this.dragOverPosition=t)}}else this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null}handleContainerDragLeave(e){let t=this.shadowRoot?.querySelector(`.scroll-container`),n=e.relatedTarget;t&&t.contains(n)||(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null)}handleContainerDrop(e){e.preventDefault();let t=e.dataTransfer?.getData(`application/json`);if(t){this.handleExternalTaskDrop(e,t),this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null;return}if(!this.option.enableRowReordering)return;let n=e.dataTransfer?.getData(`text/plain`),r=this.dragOverRowId,i=this.dragOverPosition;if(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null,n&&r&&n!==r&&i)if(this.selectedRows.has(n)&&this.selectedRows.size>1){let e=Array.from(this.selectedRows);this.reorderRows(e,r,i)}else this.reorderRows(n,r,i)}handleExternalTaskDrop(e,t){try{let n=JSON.parse(t);if(!n||typeof n!=`object`||typeof n.id!=`string`||typeof n.name!=`string`||!n.start||!n.end){console.warn(`Invalid dropped task data: missing required fields (id, name, start, end)`);return}let r=new Date(n.start),i=new Date(n.end);if(isNaN(r.getTime())||isNaN(i.getTime())){console.warn(`Invalid dropped task data: start or end is not a valid date`);return}let a={...n,start:r,end:i},o=this.shadowRoot?.querySelector(`.scroll-container`);if(!o)return;let s=o.getBoundingClientRect(),c=o.scrollLeft,l=o.scrollTop,u=this.currentRowHeaderWidth,d=e.clientX-s.left+c-u,f=this.effectivePxPerDay,p=this.effectivePxPerMonth,m=F(d,this.option.calendar.start,f,p),h=e.clientY-s.top+l-this.calendarHeight,{layouts:g}=this.calculateLayout(),_;for(let e=0;e<g.length;e++){let t=g[e];if(h>=t.top&&h<t.top+t.height){_=this.displayRows[e].id;break}}_&&this.dispatchEvent(new CustomEvent(`task-drop`,{detail:{task:a,dropDate:m,targetRowId:_},bubbles:!0,composed:!0}))}catch(e){console.warn(`Failed to parse dropped task data`,e)}}handleRowClicked(e){let{rowId:t,event:n}=e.detail,{shiftKey:r,ctrlKey:i,metaKey:a}=n,o=new Set(this.selectedRows);if(r&&this.lastClickedRowId){let e=this.rows.findIndex(e=>e.id===this.lastClickedRowId),n=this.rows.findIndex(e=>e.id===t);if(e!==-1&&n!==-1){let t=Math.min(e,n),r=Math.max(e,n);for(let e=t;e<=r;e++)o.add(this.rows[e].id)}}else if(i||a)o.has(t)?o.delete(t):o.add(t),this.lastClickedRowId=t;else{if(o.has(t)){this.lastClickedRowId=t;return}o.clear(),o.add(t),this.lastClickedRowId=t}this.selectedRows=o,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:Array.from(this.selectedRows)},bubbles:!0,composed:!0}))}handleRowContextMenu(e){this.selectedRows.has(e.detail.rowId)||this.handleRowClicked(e)}handleContainerClick(e){e.defaultPrevented||this.clearSelection()}handleContainerContextMenu(e){if(e.defaultPrevented)return;e.preventDefault();let t=this.shadowRoot?.querySelector(`.scroll-container`);if(!t)return;let n=t.getBoundingClientRect(),r=t.scrollLeft,i=t.scrollTop,a=this.currentRowHeaderWidth,o=e.clientY-n.top+i-this.calendarHeight,{layouts:s}=this.calculateLayout(),c;for(let e=0;e<s.length;e++){let t=s[e];if(o>=t.top&&o<t.top+t.height){c=this.displayRows[e].id;break}}if(c){let t=e.clientX-n.left+r-a,i=this.effectivePxPerDay,o=this.effectivePxPerMonth,s=F(t,this.option.calendar.start,i,o);this.dispatchEvent(new CustomEvent(`chart-contextmenu`,{detail:{event:e,date:s,rowId:c},bubbles:!0,composed:!0}))}this.clearSelection()}hitTest(e,t){let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return null;let r=n.getBoundingClientRect(),i=n.scrollLeft,a=n.scrollTop,o=this.currentRowHeaderWidth,s=t-r.top+a-this.calendarHeight,{layouts:c}=this.calculateLayout(),l;for(let e=0;e<c.length;e++){let t=c[e];if(s>=t.top&&s<t.top+t.height){l=this.displayRows[e].id;break}}if(!l)return null;let u=e-r.left+i-o,d=this.effectivePxPerDay,f=this.effectivePxPerMonth,p=F(u,this.option.calendar.start,d,f);return{rowId:l,date:p}}getRowPositions(){let{layouts:e}=this.calculateLayout();return e.map(e=>({top:e.top,height:e.height,bottom:e.top+e.height}))}async exportImage(e=`png`,t={}){this.isExporting=!0,await this.updateComplete,await new Promise(e=>requestAnimationFrame(e));try{return await Z(this,e,t)}finally{this.isExporting=!1,await this.updateComplete}}zoomTo(e){let t=this.effectivePxPerMonth!==void 0,n=t?20:2,r=t?600:200,i=this.option.zoom?.min??n,a=this.option.zoom?.max??r,o=Math.max(i,Math.min(a,e));t?this.zoomPxPerMonth=o:this.zoomPxPerDay=o,this.dispatchEvent(new CustomEvent(`zoom-change`,{detail:{pxPerDay:t?this.effectivePxPerDay:o,pxPerMonth:t?o:void 0},bubbles:!0,composed:!0}))}zoomToFit(){let e=this.shadowRoot?.querySelector(`.scroll-container`);if(!e)return;let t=null,n=null;for(let e of this.displayRows)for(let r of e.tasks)(!t||r.start<t)&&(t=r.start),(!n||r.end>n)&&(n=r.end);if(!t||!n)return;let r=this.currentRowHeaderWidth,i=e.clientWidth-r;if(!(i<=0)){if(this.effectivePxPerMonth!==void 0){let e=(n.getFullYear()-t.getFullYear())*12+(n.getMonth()-t.getMonth()),r=i/Math.max(1,e);this.zoomTo(r)}else{let e=n.getTime()-t.getTime(),r=i/Math.max(1,e/(1e3*60*60*24));this.zoomTo(r)}requestAnimationFrame(()=>{let n=this.getDateX(t)+r;e.scrollLeft=Math.max(0,n-10)})}}resetZoom(){let e=this.zoomPxPerDay!==null||this.zoomPxPerMonth!==null;if(this.zoomPxPerDay=null,this.zoomPxPerMonth=null,e){let e=this.option.calendar.pxPerMonth!==void 0;this.dispatchEvent(new CustomEvent(`zoom-change`,{detail:{pxPerDay:this.option.calendar.pxPerDay??50,pxPerMonth:e?this.option.calendar.pxPerMonth:void 0},bubbles:!0,composed:!0}))}}clearSelection(){this.selectedRows.size===0&&this.selectedTasks.size===0||(this.selectedRows.size>0&&(this.selectedRows=new Set,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))),this.selectedTasks.size>0&&(this.selectedTasks=new Set,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))))}moveFocusHorizontal(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}let r=t[n],i=[...r.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),a=i.findIndex(e=>e.id===this.focusedTaskId);if(a===-1){i.length>0&&this.setFocus(i[0].id,r.id);return}let o=a+e;o>=0&&o<i.length?this.setFocus(i[o].id,r.id):this.moveFocusVertical(e)}moveFocusVertical(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}for(let r=n+e;r>=0&&r<t.length;r+=e){let n=t[r];if(n.tasks.length>0){let t=[...n.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e>0?t[0]:t[t.length-1];this.setFocus(r.id,n.id);return}}}focusFirstAvailableTask(){for(let e of this.displayRows)if(e.tasks.length>0){let t=[...e.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime());this.setFocus(t[0].id,e.id);return}}focusFirstOrLastTaskInRow(e){if(!this.focusedRowId){this.focusFirstAvailableTask();return}let t=this.displayRows.find(e=>e.id===this.focusedRowId);if(!t||t.tasks.length===0)return;let n=[...t.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e===`first`?n[0]:n[n.length-1];this.setFocus(r.id,t.id)}setFocus(e,t){this.focusedTaskId=e,this.focusedRowId=t,this.scrollToTask(e)}toggleTaskSelection(e){let t=new Set(this.selectedTasks);t.has(e)?t.delete(e):t.add(e),this.selectedTasks=t,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...t]},bubbles:!0,composed:!0}))}selectSingleTask(e){this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0}))}moveSelectedTasksByKeyboard(e){if(this.selectedTasks.size===0)return;let t=(this.option.keyboard?.moveStep??this.option.snapDuration??1440)*60*1e3*e,n=this.rows.map(e=>e.tasks.some(e=>this.selectedTasks.has(e.id))?{...e,tasks:e.tasks.map(e=>this.selectedTasks.has(e.id)?{...e,start:new Date(e.start.getTime()+t),end:new Date(e.end.getTime()+t)}:e)}:e);for(let e of this.rows)for(let n of e.tasks){if(!this.selectedTasks.has(n.id))continue;let r=new Date(n.start.getTime()+t),i=new Date(n.end.getTime()+t);this.dispatchEvent(new CustomEvent(`task-update`,{detail:{id:n.id,name:n.name,start:r,end:i,dx:0,dy:0,isDragging:!1,mode:`move`,targetRowId:e.id},bubbles:!0,composed:!0}))}this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleBarClick(e){e.stopPropagation();let{task:t,isMultiSelect:n}=e.detail;this.draggingTask=null,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay());let r;n?(r=new Set(this.selectedTasks),r.has(t.id)?r.delete(t.id):r.add(t.id)):r=new Set([t.id]),this.selectedTasks=r,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...r]},bubbles:!0,composed:!0}))}handleBarContextMenu(e){let{task:t}=e.detail;this.selectedTasks.has(t.id)||(this.selectedTasks=new Set([t.id]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[t.id]},bubbles:!0,composed:!0})))}handleConnectorDragStart(e){let{taskId:t,endpoint:n,clientX:r,clientY:i}=e.detail;e.stopPropagation();let{taskCoords:a}=this.calculateLayout(),o=a.get(t),s=this.currentRowHeaderWidth,c=e.detail.startX+s,l=e.detail.startY;o&&(c=n===`start`?o.x:o.x+o.width,l=o.y+o.height/2),this.connectorDrag={sourceTaskId:t,sourceEndpoint:n,startX:c,startY:l,currentClientX:r,currentClientY:i,targetTaskId:null,targetEndpoint:null},this.tooltip&&=null}handleConnectorDragMove(e){if(!this.connectorDrag)return;e.stopPropagation();let{clientX:t,clientY:n}=e.detail,r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=r.getBoundingClientRect(),a=t-i.left+r.scrollLeft,o=n-i.top+r.scrollTop-this.calendarHeight,{taskCoords:s}=this.calculateLayout(),c=null,l=null,u=30;for(let[e,t]of s){if(e===this.connectorDrag.sourceTaskId)continue;let n=t.y+t.height/2,r=t.x,i=t.x+t.width,s=Math.sqrt((a-r)**2+(o-n)**2),d=Math.sqrt((a-i)**2+(o-n)**2);s<u&&(u=s,c=e,l=`start`),d<u&&(u=d,c=e,l=`end`)}let d=this.connectorDrag.targetTaskId;d!==c&&(d&&this._setConnectorDropTarget(d,!1),c&&this._setConnectorDropTarget(c,!0)),this.connectorDrag={...this.connectorDrag,currentClientX:t,currentClientY:n,targetTaskId:c,targetEndpoint:l}}handleConnectorDragEnd(e){if(!this.connectorDrag)return;e.stopPropagation();let{cancelled:t}=e.detail,{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a}=this.connectorDrag;i&&this._setConnectorDropTarget(i,!1),!t&&i&&a&&this.dispatchEvent(new CustomEvent(`dependency-create`,{detail:{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a},bubbles:!0,composed:!0})),this.connectorDrag=null}_setConnectorDropTarget(e,t){let n=this.shadowRoot?.querySelectorAll(`gantt-row`);if(n)for(let r of n){let n=r.shadowRoot?.querySelectorAll(`gantt-bar`);if(n){for(let r of n)if(r.task?.id===e){r.connectorDropTarget=t;return}}}}handleDependencyLineClick(e,t,n){this.dispatchEvent(new CustomEvent(`dependency-click`,{detail:{event:e,sourceTaskId:n,targetTaskId:t},bubbles:!0,composed:!0}))}selectTask(e){let t=!1;for(let n of this.displayRows)if(n.tasks.some(t=>t.id===e)){t=!0;break}return t?(this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0})),this.scrollToTask(e),!0):!1}scrollToTask(e){let{taskCoords:t}=this.calculateLayout(),n=t.get(e);if(!n)return;let r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=this.currentRowHeaderWidth,a=n.y+this.calendarHeight,o=a+n.height,s=r.scrollTop,c=r.scrollTop+r.clientHeight;if(a<s||o>c){let e=a-r.clientHeight/2+n.height/2;r.scrollTo({top:Math.max(0,e),behavior:`smooth`})}let l=n.x,u=n.x+n.width,d=r.scrollLeft+i,f=r.scrollLeft+r.clientWidth;if(l<d||u>f){let e=l-i-20;r.scrollTo({left:Math.max(0,e),behavior:`smooth`})}}render(){let e=L(this.theme,this.option.customTheme),{layouts:n,taskCoords:r,totalHeight:a}=this.calculateLayout(),o=this.currentRowHeaderWidth;(this._lastOptionRef!==this.option||this._lastLabelWidth!==o||this._lastZoomPxPerDay!==this.zoomPxPerDay||this._lastZoomPxPerMonth!==this.zoomPxPerMonth)&&(this._cachedCurrentOption={...this.option,rowHeader:{...this.option.rowHeader,width:o},calendar:{...this.option.calendar,pxPerDay:this.effectivePxPerDay,pxPerMonth:this.effectivePxPerMonth}},this._lastOptionRef=this.option,this._lastLabelWidth=o,this._lastZoomPxPerDay=this.zoomPxPerDay,this._lastZoomPxPerMonth=this.zoomPxPerMonth);let s=this._cachedCurrentOption,c=0,l=this.displayRows.length-1;if(!this.isExporting){for(let e=0;e<n.length;e++)if(n[e].top+n[e].height>this.virtualScrollTop){c=Math.max(0,e-5);break}for(let e=c;e<n.length;e++)if(n[e].top>this.virtualScrollTop+this.viewportHeight){l=Math.min(this.displayRows.length-1,e+5);break}}let u=this.displayRows.slice(c,l+1),d=this.isExporting?0:n[c]?n[c].top:0,f=n[l],p=f?f.top+f.height:0,m=Math.max(0,a-p),h=a>this.viewportHeight,g=[],_=this.option.readOnly===!0,v=this.option.dependency?.showArrows!==!1,y=this.option.dependency?.arrowSize??8,b=this.option.dependency?.lineStyle??`orthogonal`,x=this.option.dependency?.cornerRadius??8,S=this.option.dependency?.showCriticalPath===!0,C=S?Q(this.displayRows):new Set;for(let[e,n]of r)if(n.dependencies)for(let i of n.dependencies){let a=r.get(i);if(a){let r=a.x+a.width,o=a.y+a.height/2,s=n.x,c=n.y+n.height/2,l=r<s,u=v?s-y:s,d=l?Math.max(r,u):u,f,p,m,h=this.option.bar?.height??28,w=this.option.bar?.margin??4;if(Math.abs(o-c)<1&&l)f=d>r?`M ${r} ${o} L ${d} ${c}`:``,p=s>r?`M ${r} ${o} L ${s} ${c}`:``;else if(b===`orthogonal`){let e=q(r,o,s,c,d,h,w,x);f=e.pathD,p=e.hitPathD}else if(l){let e=(r+d)/2;f=`M ${r} ${o} C ${e} ${o} ${e} ${c} ${d} ${c}`,p=`M ${r} ${o} C ${(r+s)/2} ${o} ${(r+s)/2} ${c} ${s} ${c}`}else{let e=Math.max(12,(r-s)*.15),t=(o+c)/2,n=Math.abs(o-c)<h?t+h+w:t;f=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+d)/2} ${n} S ${d-e} ${c}, ${d} ${c}`,p=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+s)/2} ${n} S ${s-e} ${c}, ${s} ${c}`}m=v?`M ${d} ${c} L ${s} ${c}`:``,g.push(t.svg`<g class="dependency-group">
|
|
952
968
|
${_?``:t.svg`<path class="dependency-hit-area" d="${p}" @click="${t=>{t.stopPropagation(),this.handleDependencyLineClick(t,e,i)}}" />`}
|
|
953
|
-
<path class="dependency-line" d="${f}" />
|
|
954
|
-
${v?t.svg`<path class="dependency-line dependency-arrow-line" d="${m}" marker-end="url(#dependency-arrowhead)" />`:``}
|
|
955
|
-
</g>`)}}let
|
|
956
|
-
<style>${Y(this.theme,this.option.customTheme)}
|
|
957
|
-
|
|
969
|
+
<path class="dependency-line ${S&&C.has(e)&&C.has(i)?`critical-path`:``}" d="${f}" />
|
|
970
|
+
${v?t.svg`<path class="dependency-line dependency-arrow-line ${S&&C.has(e)&&C.has(i)?`critical-path`:``}" d="${m}" marker-end="url(#dependency-arrowhead)" />`:``}
|
|
971
|
+
</g>`)}}let w=null;if(this.connectorDrag){let e=this.shadowRoot?.querySelector(`.scroll-container`);if(e){let n=e.getBoundingClientRect(),i=this.connectorDrag.startX,a=this.connectorDrag.startY,o,s;if(this.connectorDrag.targetTaskId&&this.connectorDrag.targetEndpoint){let t=r.get(this.connectorDrag.targetTaskId);t?(o=this.connectorDrag.targetEndpoint===`start`?t.x:t.x+t.width,s=t.y+t.height/2):(o=this.connectorDrag.currentClientX-n.left+e.scrollLeft,s=this.connectorDrag.currentClientY-n.top+e.scrollTop-this.calendarHeight)}else o=this.connectorDrag.currentClientX-n.left+e.scrollLeft,s=this.connectorDrag.currentClientY-n.top+e.scrollTop-this.calendarHeight;let c=(i+o)/2;w=t.svg`<path class="connector-preview-line" d="M ${i} ${a} C ${c} ${a} ${c} ${s} ${o} ${s}" />`}}return t.html`
|
|
972
|
+
<style>${Y(this.theme,this.option.customTheme)}
|
|
973
|
+
:host {
|
|
974
|
+
--critical-path-color: ${e.criticalPath??`rgba(220, 38, 38, 0.85)`};
|
|
975
|
+
}
|
|
976
|
+
</style>
|
|
977
|
+
${this.isExporting?t.html`<style>:host { overflow: visible !important; height: ${this.calendarHeight+a+2}px !important; width: max-content !important; min-width: auto !important; border-radius: 0 !important; border: none !important; }</style>`:``}
|
|
958
978
|
<div
|
|
959
979
|
class="scroll-container"
|
|
960
980
|
style="overflow-x: ${this.isExporting?`visible`:`auto`}; overflow-y: ${this.isExporting?`visible`:h?`auto`:`hidden`}; height: ${this.isExporting?`auto`:`100%`}; width: ${this.isExporting?`max-content`:`100%`}; min-width: auto;"
|
|
@@ -996,6 +1016,7 @@
|
|
|
996
1016
|
.option="${s}"
|
|
997
1017
|
.theme="${this.theme}"
|
|
998
1018
|
.currentTime="${this.currentTime}"
|
|
1019
|
+
.isExporting="${this.isExporting}"
|
|
999
1020
|
.hoveredMilestoneId="${this.hoveredMilestoneId}"
|
|
1000
1021
|
.cornerContent="${this.option.customRendering?.cornerContent}"
|
|
1001
1022
|
.calendarMonthContent="${this.option.customRendering?.calendarMonthContent}"
|
|
@@ -1030,11 +1051,11 @@
|
|
|
1030
1051
|
</defs>`:``}
|
|
1031
1052
|
<g transform="translate(0, ${this.calendarHeight})">
|
|
1032
1053
|
${g}
|
|
1033
|
-
${
|
|
1054
|
+
${w}
|
|
1034
1055
|
</g>
|
|
1035
1056
|
</svg>
|
|
1036
1057
|
|
|
1037
|
-
${this.option.calendar.showCurrentTime&&this.currentTime>=this.option.calendar.start&&this.currentTime<=this.option.calendar.end?t.html`
|
|
1058
|
+
${!this.isExporting&&this.option.calendar.showCurrentTime&&this.currentTime>=this.option.calendar.start&&this.currentTime<=this.option.calendar.end?t.html`
|
|
1038
1059
|
<div
|
|
1039
1060
|
class="current-time-line"
|
|
1040
1061
|
style="
|
|
@@ -1099,6 +1120,7 @@
|
|
|
1099
1120
|
.selectedTaskIds="${this._cachedSelectedTaskIds}"
|
|
1100
1121
|
.focusedTaskId="${this.focusedTaskId}"
|
|
1101
1122
|
.isExporting="${this.isExporting}"
|
|
1123
|
+
.criticalPathTaskIds="${S?[...C]:[]}"
|
|
1102
1124
|
@task-update="${this.handleTaskUpdate}"
|
|
1103
1125
|
@row-clicked="${this.handleRowClicked}"
|
|
1104
1126
|
@row-header-contextmenu="${this.handleRowContextMenu}"
|
|
@@ -1117,4 +1139,4 @@
|
|
|
1117
1139
|
style="top: ${this.tooltip.y}px; left: ${this.tooltip.x}px;"
|
|
1118
1140
|
/>
|
|
1119
1141
|
`:``}
|
|
1120
|
-
`}};H([(0,n.property)({type:Array})]
|
|
1142
|
+
`}};H([(0,n.property)({type:Array})],$.prototype,`rows`,void 0),H([(0,n.property)({type:Object})],$.prototype,`option`,void 0),H([(0,n.property)({type:String,reflect:!0})],$.prototype,`theme`,void 0),H([(0,n.property)({type:Array})],$.prototype,`selectedRowIds`,void 0),H([(0,n.property)({type:Array})],$.prototype,`selectedTaskIds`,void 0),H([(0,n.property)({attribute:!1})],$.prototype,`externalDraggingTask`,void 0),H([(0,n.state)()],$.prototype,`selectedRows`,void 0),H([(0,n.state)()],$.prototype,`selectedTasks`,void 0),H([(0,n.state)()],$.prototype,`lastClickedRowId`,void 0),H([(0,n.state)()],$.prototype,`virtualScrollTop`,void 0),H([(0,n.state)()],$.prototype,`dragTargetRowIndex`,void 0),H([(0,n.state)()],$.prototype,`draggingTask`,void 0),H([(0,n.state)()],$.prototype,`draggingTaskIds`,void 0),H([(0,n.state)()],$.prototype,`multiDragDx`,void 0),H([(0,n.state)()],$.prototype,`multiDragDy`,void 0),H([(0,n.state)()],$.prototype,`multiDragSameRow`,void 0),H([(0,n.state)()],$.prototype,`viewportHeight`,void 0),H([(0,n.state)()],$.prototype,`calendarHeight`,void 0),H([(0,n.state)()],$.prototype,`tooltip`,void 0),H([(0,n.state)()],$.prototype,`dragOverRowId`,void 0),H([(0,n.state)()],$.prototype,`dragOverPosition`,void 0),H([(0,n.state)()],$.prototype,`currentTime`,void 0),H([(0,n.state)()],$.prototype,`dragPreview`,void 0),H([(0,n.state)()],$.prototype,`currentRowHeaderWidth`,void 0),H([(0,n.state)()],$.prototype,`isResizingHeader`,void 0),H([(0,n.state)()],$.prototype,`hoveredMilestoneId`,void 0),H([(0,n.state)()],$.prototype,`cursorLineX`,void 0),H([(0,n.state)()],$.prototype,`connectorDrag`,void 0),H([(0,n.state)()],$.prototype,`isExporting`,void 0),H([(0,n.state)()],$.prototype,`focusedTaskId`,void 0),H([(0,n.state)()],$.prototype,`focusedRowId`,void 0),H([(0,n.state)()],$.prototype,`zoomPxPerDay`,void 0),H([(0,n.state)()],$.prototype,`zoomPxPerMonth`,void 0),$=H([(0,n.customElement)(`gantt-chart`)],$),e.ALL_BAR_PATTERNS=g,Object.defineProperty(e,`GanttBarElement`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(e,`GanttCalendarElement`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(e,`GanttChartElement`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(e,`GanttRowElement`,{enumerable:!0,get:function(){return K}}),e.PATTERN_CHECKERBOARD=x,e.PATTERN_CIRCLE=w,e.PATTERN_DIAGONAL_GRID=E,e.PATTERN_DIAGONAL_STRIPE=_,e.PATTERN_DIAGONAL_STRIPE_REVERSE=v,e.PATTERN_DOTS=S,e.PATTERN_DOTS_DENSE=k,e.PATTERN_GRID=T,e.PATTERN_HORIZONTAL_STRIPE=b,e.PATTERN_STRIPE_THICK=O,e.PATTERN_STRIPE_THIN=D,e.PATTERN_TRIANGLE=C,e.PATTERN_VERTICAL_STRIPE=y,e.computeCriticalPath=Q,e.enLocale=M,e.getPatternStyle=A,e.jaLocale=j});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mogura/moguchart-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "A lightweight, framework-agnostic Gantt chart Web Component built with Lit. Works with Vue, React, Angular, Svelte, and more.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Murakami Hiroyuki",
|