@mogura/moguchart-core 1.1.1 → 1.2.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.ja.md CHANGED
@@ -13,6 +13,8 @@ Vue, React, Angular, Svelte など、どのフレームワークでも動作す
13
13
 
14
14
  - 🚀 **フレームワーク非依存**: Web Components (Custom Elements) として実装されており、あらゆる環境で動作します。
15
15
  - ⚡ **仮想スクロール**: 大量のタスクや行があってもスムーズに動作します。
16
+ - ↩️ **操作履歴管理 (Undo / Redo)**: コマンドパターンによる直感的な履歴管理。タスクの移動・リサイズ・進捗変更・削除、行の並び替え、依存関係の作成・削除など主要な編集操作の取り消し・やり直しを完全サポート(`Ctrl+Z` / `Ctrl+Y` 対応)。
17
+ - 🔍 **包括的なズーム制御**: パーセンテージ(50%〜200%)やスケール倍率(0.5〜2.0)に基づく柔軟な拡大縮小。カレンダー列幅・行ヘッダー幅・タスクバー高さ・フォントサイズ(`--moguchart-font-scale`)の一括連動スケーリング。ショートカットキー(`Ctrl/Cmd + + / - / 0`)やホイール操作に対応。
16
18
  - 🖱️ **インタラクティブ**:
17
19
  - ドラッグ&ドロップによるタスク移動(行間移動対応)
18
20
  - ハンドル操作による期間リサイズ
@@ -26,7 +28,11 @@ Vue, React, Angular, Svelte など、どのフレームワークでも動作す
26
28
  - ライト/ダーク/システムテーマの切り替え+カスタムカラーテーマ
27
29
  - タスクバーの塗りつぶしパターン(ストライプ、ドット、チェッカーボードなど13種類)
28
30
  - CSSによるスタイリング
29
- - 🔗 **依存関係の表示**: タスク間の依存関係を矢印付き曲線で可視化(S字カーブ対応)。クリティカルパス(最長チェーン)の自動検出+ハイライト表示
31
+ - 🔗 **依存関係の対話的操作**:
32
+ - タスク間の依存関係を矢印付き直線・曲線(直角折れ線/ベジェ曲線)で可視化
33
+ - 依存関係線のクリック選択とハイライト表示
34
+ - 選択中の線上の削除「×」ボタンまたは `Delete` / `Backspace` キーによるワンクリック削除
35
+ - クリティカルパス(最長チェーン)の自動検出+ハイライト表示
30
36
  - 📅 **柔軟なカレンダー**:
31
37
  - 日単位 / 週単位 / 月単位の表示切り替え
32
38
  - ズームレベル(1日・1ヶ月あたりの幅)や表示期間の調整が可能
@@ -42,10 +48,11 @@ Vue, React, Angular, Svelte など、どのフレームワークでも動作す
42
48
  - タスクバー上への進捗バー(オーバーレイ/下部・上部インジケーター)描画
43
49
  - ハンドル操作による直感的な進捗率のドラッグ編集(スナップ対応)
44
50
  - 進捗ラベル表示(配置カスタマイズ・カスタムフォーマット対応)
51
+ - サマリータスク(親集計バー)への進捗ラベル自動表示および専用カスタム色(`summaryColor`)対応
45
52
  - 進捗変更イベント(`task-progress-change`)の発火
46
53
  - 行・プロジェクト全体の進捗率計算ユーティリティ関数
47
54
  - 🧩 **プラグインアーキテクチャ**: コア本体を超軽量(数十KB)に保ちつつ、画像・PDFエクスポート等の機能をプラグインとして柔軟に拡張可能
48
- - 📷 **エクスポート(プラグイン)**: `@mogura/moguchart-plugin-export` による PNG画像およびPDF形式でのガントチャート全体エクスポート(自動ダウンロード対応、スクロール位置保持)
55
+ - 📷 **エクスポート(プラグイン)**: `@mogura/moguchart-plugin-export` による PNG画像およびPDF形式でのガントチャート全体エクスポート(自動ダウンロード対応、エクスポート時のズーム正規化 `normalizeZoom`、スクロール位置保持)
49
56
  - 外部からのドラッグ&ドロップによるタスク作成
50
57
  - タスクの移動/コピーモード
51
58
  - スナップ機能(時間単位でのグリッドスナップ)
@@ -57,11 +64,10 @@ Vue, React, Angular, Svelte など、どのフレームワークでも動作す
57
64
  - 配下の子タスクから自動計算されるサマリータスクバー(ブラケット形状)
58
65
  - サマリータスクバーの色設定(プロジェクト既定色および行単位の個別色指定)
59
66
  - 親行におけるサマリータスクと通常タスクの共存・同時描画
60
- - サマリータスクへの進捗率ラベル表示設定
61
67
  - 仮想スクロールやミニマップと完全に連動する折りたたみ
62
68
  - 階層を壊さない安全なD&D並び替え(子タスクのブロック連動移動・循環参照防止)
63
69
  - プログラムからの開閉操作(`toggleRowCollapse`, `collapseAll`, `expandAll`)
64
- - ⌨️ **キーボード操作**: 矢印キーでのナビゲーション・選択・Shift+矢印キーでのタスク移動・Deleteキーでの削除
70
+ - ⌨️ **キーボード操作**: 矢印キーでのナビゲーション・選択・Shift+矢印キーでのタスク移動・Deleteキーでのタスク/依存関係線削除・Undo/Redo・ズームショートカット
65
71
 
66
72
  ## パッケージ一覧(エコシステム)
67
73
 
@@ -486,24 +492,38 @@ gantt-chart {
486
492
 
487
493
  ### 依存関係線の設定
488
494
 
489
- `dependency` オプションで依存関係線の表示をカスタマイズできます。矢印の表示/非表示や大きさ、接続コネクターの表示、最長チェーン(クリティカルパス)の自動検出ハイライトを制御できます。
490
- 右→左方向の依存関係では自動的にS字カーブで描画され、接触箇所は常に水平に接続します。
495
+ `dependency` オプションで依存関係線の表示や操作をカスタマイズできます。
496
+ 矢印の表示/非表示や大きさ、接続コネクター、最長チェーン(クリティカルパス)の自動検出ハイライトを制御できます。
497
+ 線のクリックによる選択(ハイライト表示)、選択時の削除「×」ボタン、`Delete` / `Backspace` キーによる直感的な削除に対応しています。
491
498
 
492
499
  ```javascript
493
500
  const option = {
494
501
  dependency: {
502
+ lineStyle: 'orthogonal', // 接続線の形状 ('orthogonal': 角丸直角折れ線, 'curve': ベジェ曲線)
503
+ cornerRadius: 8, // 直角折れ線時の角丸半径 (px)
495
504
  showArrows: true, // 矢印を表示するかどうか (デフォルト: true)
496
505
  arrowSize: 10, // 矢印の大きさ (px、デフォルト: 8)
497
506
  showConnectors: true, // コネクター接続ポイント(丸印)を表示するかどうか (デフォルト: true)
498
507
  showCriticalPath: true, // クリティカルパス(最長チェーン)を自動計算しハイライト表示
508
+ creatable: true, // コネクタからのドラッグによる依存関係作成を許可 (デフォルト: true)
509
+ deletable: true, // 依存関係の削除を許可 (デフォルト: true)
510
+ showDeleteButton: true, // 選択時の削除「×」ボタンを表示 (デフォルト: true)
499
511
  },
500
512
  // ...
501
513
  }
514
+
515
+ // 依存関係の選択・削除イベント
516
+ chart.addEventListener('dependency-select', (e) => {
517
+ console.log('選択された依存関係:', e.detail.selected)
518
+ })
519
+ chart.addEventListener('dependency-delete', (e) => {
520
+ console.log('削除された依存関係:', e.detail.sourceTaskId, '->', e.detail.targetTaskId)
521
+ })
502
522
  ```
503
523
 
504
524
  ### タスク進捗管理
505
525
 
506
- 各タスクの `progress` プロパティ(`0` 〜 `100`)を設定することで、タスクバー上に進捗状況を視覚的に表示できます。`editable: true` を設定すると、進捗ハンドルのドラッグによる直感的な進捗率変更が可能になります。
526
+ 各タスクの `progress` プロパティ(`0` 〜 `100`)を設定することで、タスクバー上に進捗状況を視覚的に表示できます。`editable: true` を設定すると、進捗ハンドルのドラッグによる直感的な進捗率変更が可能になります。また、`showLabel: true` の場合、サマリータスクにも自動的に進捗ラベルが表示されます。
507
527
 
508
528
  ```javascript
509
529
  import {
@@ -517,8 +537,10 @@ const option = {
517
537
  progress: {
518
538
  enabled: true,
519
539
  editable: true, // ドラッグによる進捗編集を有効化
540
+ color: '#3b82f6', // 通常タスクの進捗バー色
541
+ summaryColor: 'rgba(255, 255, 255, 0.35)', // サマリータスク専用の進捗バー色
520
542
  showLabel: true, // 進捗ラベルを表示 (例: "50%")
521
- showSummaryLabel: false, // サマリータスクにも進捗ラベルを表示するかどうか (デフォルト: false)
543
+ showSummaryLabel: true, // サマリータスクにも進捗ラベルを表示するかどうか (デフォルト: true)
522
544
  labelPosition: 'inside', // 'inside' | 'right' | 'left' | 'center'
523
545
  snapStep: 5, // 5%刻みでスナップ
524
546
  indicatorPosition: 'full', // 'full' | 'bottom' | 'top'
@@ -753,31 +775,80 @@ const { exportChart } = await import('@mogura/moguchart-plugin-export')
753
775
  await exportChart(chart, 'png', { download: true })
754
776
  ```
755
777
 
756
- #### ズーム操作 (zoomTo / zoomToFit / resetZoom)
778
+ #### ズーム操作 (zoomToPercent / zoomToScale / zoomIn / zoomOut / resetZoom)
757
779
 
758
- `zoom` オプションを有効にすることで、Ctrl/Cmd + マウスホイールによるズームイン・ズームアウトが可能になります。また、メソッドによる動的なズーム制御にも対応しています。
780
+ `zoom` オプションを有効にすることで、Ctrl/Cmd + マウスホイール、ショートカットキー(`Ctrl/Cmd + + / - / 0`)、またはパブリックメソッドによる柔軟なズーム(50%〜200%)が可能になります。カレンダー列幅・行ヘッダー幅・バー高さ・フォントサイズ(`scaleElements`)が一括連動します。
759
781
 
760
782
  ```javascript
761
783
  const option = {
762
784
  zoom: {
763
785
  enabled: true, // ズーム機能を有効化 (デフォルト: false)
764
- min: 5, // 最小 pxPerDay (または pxPerMonth)
765
- max: 150, // 最大 pxPerDay (または pxPerMonth)
766
- step: 1.2, // 1回あたりのズーム倍率
786
+ minPercent: 50, // 最小倍率 (50%)
787
+ maxPercent: 200, // 最大倍率 (200%)
788
+ initialPercent: 100, // 初期倍率 (100%)
789
+ shortcuts: true, // キーボードショートカット有効化
790
+ scaleElements: {
791
+ calendar: true,
792
+ rowHeader: true,
793
+ barHeight: true,
794
+ fontScale: true,
795
+ },
767
796
  },
768
797
  }
769
798
 
770
799
  // プログラムによるズーム操作
771
- chart.zoomTo(50) // 1日あたり50pxにズーム
800
+ chart.zoomIn() // 1段階拡大 (Chrome準拠レベル)
801
+ chart.zoomOut() // 1段階縮小
802
+ chart.zoomToPercent(125) // 125% にズーム
803
+ chart.zoomToScale(1.5) // 1.5倍 にズーム
772
804
  chart.zoomToFit() // 全タスクが表示領域に収まるよう自動調整
773
- chart.resetZoom() // 初期設定のスケールにリセット
805
+ chart.resetZoom() // 100%(標準スケール)にリセット
774
806
 
775
807
  // ズーム変更イベント
776
808
  chart.addEventListener('zoom-change', (e) => {
777
- console.log('変更後のスケール:', e.detail.pxPerDay || e.detail.pxPerMonth)
809
+ console.log('ズーム変更:', e.detail.zoomPercent + '%', 'scale:', e.detail.zoomScale)
810
+ })
811
+ ```
812
+
813
+ #### 操作履歴・Undo / Redo (undo / redo / clearHistory)
814
+
815
+ ユーザーによる各種操作(タスク移動・リサイズ・進捗変更・削除、行並び替え、依存関係作成/削除)を自動記録し、プログラムまたはキーボード(`Ctrl+Z` / `Ctrl+Y`)から取り消し・やり直しが可能です。
816
+
817
+ ```javascript
818
+ const option = {
819
+ history: {
820
+ enabled: true, // 履歴管理を有効化 (デフォルト: true)
821
+ maxDepth: 50, // 保持する最大履歴数
822
+ keyboard: true, // ショートカットを有効化
823
+ },
824
+ }
825
+
826
+ // Undo / Redo の実行
827
+ if (chart.canUndo) {
828
+ await chart.undo()
829
+ }
830
+ if (chart.canRedo) {
831
+ await chart.redo()
832
+ }
833
+
834
+ // 履歴クリア
835
+ chart.clearHistory()
836
+
837
+ // 履歴状態の変更検知
838
+ chart.addEventListener('history-change', (e) => {
839
+ undoBtn.disabled = !e.detail.canUndo
840
+ redoBtn.disabled = !e.detail.canRedo
778
841
  })
779
842
  ```
780
843
 
844
+ #### 依存関係の削除 (triggerDependencyDelete)
845
+
846
+ プログラムから特定の依存関係線を削除できます。
847
+
848
+ ```javascript
849
+ chart.triggerDependencyDelete('task-1', 'task-2')
850
+ ```
851
+
781
852
  #### WBS・折りたたみ操作 (toggleRowCollapse / collapseAll / expandAll)
782
853
 
783
854
  ```javascript
@@ -847,7 +918,7 @@ const criticalTaskIds = computeCriticalPath(allTasks) // Set<string>
847
918
 
848
919
  ### キーボード操作
849
920
 
850
- ガントチャートにフォーカスがある状態で、キーボードによるタスクのナビゲーション・選択・移動・削除が可能です。
921
+ ガントチャートにフォーカスがある状態で、キーボードによるタスクのナビゲーション・選択・移動・削除・Undo/Redo・ズームが可能です。
851
922
 
852
923
  | キー | 動作 |
853
924
  | :--------------------- | :--------------------------- |
@@ -856,7 +927,13 @@ const criticalTaskIds = computeCriticalPath(allTasks) // Set<string>
856
927
  | `Enter` / `Space` | フォーカス中のタスクを選択 |
857
928
  | `Ctrl/Cmd + Enter` | 選択をトグル(複数選択) |
858
929
  | `Shift + ←` `→` | 選択中のタスクを移動 |
859
- | `Delete` / `Backspace` | `task-delete` イベントを発火 |
930
+ | `Delete` / `Backspace` | 選択中のタスクまたは依存関係線を削除 |
931
+ | `Ctrl+Z` / `Cmd+Z` | 直前の操作を取り消す (Undo) |
932
+ | `Ctrl+Y` / `Cmd+Shift+Z` | 直前の操作をやり直す (Redo) |
933
+ | `Ctrl/Cmd + +` | ズームイン(拡大) |
934
+ | `Ctrl/Cmd + -` | ズームアウト(縮小) |
935
+ | `Ctrl/Cmd + 0` | ズーム倍率を100%にリセット |
936
+ | `Ctrl/Cmd + ホイール` | ズームイン / ズームアウト |
860
937
  | `Escape` | 選択・フォーカスをクリア |
861
938
 
862
939
  ```javascript
@@ -865,6 +942,12 @@ const option = {
865
942
  enabled: true, // デフォルト: true
866
943
  moveStep: 60, // Shift+矢印キーでの移動量(分)
867
944
  },
945
+ history: {
946
+ keyboard: true, // Undo/Redo ショートカット (デフォルト: true)
947
+ },
948
+ zoom: {
949
+ shortcuts: true, // ズームショートカット (デフォルト: true)
950
+ },
868
951
  // ...
869
952
  }
870
953
  ```
package/README.md CHANGED
@@ -13,6 +13,8 @@ A lightweight yet feature-rich Gantt chart Web Component built with Lit. Works s
13
13
 
14
14
  - 🚀 **Framework-agnostic**: Built as standard Web Components (Custom Elements), easily integrated into any frontend framework.
15
15
  - ⚡ **Virtual Scrolling**: Smooth 60fps rendering even with extensive tasks and rows.
16
+ - ↩️ **Operation History (Undo / Redo)**: Command pattern-based history manager. Complete undo/redo support for task movement, duration resizing, progress adjustments, deletion, row reordering, and dependency editing (`Ctrl+Z` / `Ctrl+Y`).
17
+ - 🔍 **Comprehensive Zoom Controls**: Smooth magnification adjustments based on percentage (50% to 200%) and scale factors (0.5 to 2.0). Coordinated synchronization across calendar width, row header width, bar height, and font scale (`--moguchart-font-scale`). Keyboard shortcuts (`Ctrl/Cmd + + / - / 0`) and mouse wheel zoom.
16
18
  - 🖱️ **Rich Interactive Controls**:
17
19
  - Drag & drop task movement (with optional cross-row vertical movement)
18
20
  - Handle-based task duration resizing
@@ -27,9 +29,10 @@ A lightweight yet feature-rich Gantt chart Web Component built with Lit. Works s
27
29
  - Light / Dark / System theme switching + custom color palettes
28
30
  - 13 built-in task bar fill patterns (stripes, dots, checkerboard, grid, etc.)
29
31
  - Native CSS variable-driven styling
30
- - 🔗 **Dependency Visualization**:
31
- - Smooth curved lines with directional arrows showing task dependencies
32
- - Automatic S-curve calculation for reverse-direction dependencies
32
+ - 🔗 **Interactive Dependencies**:
33
+ - Direct task dependencies visualised with orthogonal segmented lines or Bezier curves
34
+ - Click-to-select dependency lines with dedicated highlight styling
35
+ - One-click deletion via on-line "×" button or `Delete` / `Backspace` key
33
36
  - Proximity connector toggle (`showConnectors`)
34
37
  - Automatic critical path detection and highlighted visualization (`showCriticalPath`)
35
38
  - 📅 **Flexible Calendar & Timeline**:
@@ -47,11 +50,12 @@ A lightweight yet feature-rich Gantt chart Web Component built with Lit. Works s
47
50
  - Task bar progress overlay (full, bottom, or top indicator styles)
48
51
  - Interactive drag-adjust handle for quick progress modification (with snap increments)
49
52
  - Configurable progress labels (custom positioning & formatters)
53
+ - Automatic progress label display for summary tasks and customizable summary progress bar color (`summaryColor`)
50
54
  - `task-progress-change` custom event
51
55
  - Progress calculation utility functions (simple & duration-weighted row/project averages)
52
56
  - Automatic progress visualization on the overview minimap
53
57
  - 🧩 **Plugin Architecture**: Modular architecture keeping the core bundle ultra-lightweight (tens of KBs) while allowing rich extensions like PNG/PDF exports.
54
- - 📷 **Export Plugin**: Full Gantt chart PNG image and multi-page PDF export powered by `@mogura/moguchart-plugin-export` (with scroll position preservation and auto-download support).
58
+ - 📷 **Export Plugin**: Full Gantt chart PNG image and multi-page PDF export powered by `@mogura/moguchart-plugin-export` (with automatic zoom normalization `normalizeZoom`, scroll position preservation, and auto-download support).
55
59
  - ✨ **Advanced Integration**:
56
60
  - External drag & drop for task creation
57
61
  - Task move / copy modes
@@ -69,7 +73,7 @@ A lightweight yet feature-rich Gantt chart Web Component built with Lit. Works s
69
73
  - Collapsing seamlessly integrated with virtual scrolling and overview minimap
70
74
  - Safe drag & drop reordering preserving hierarchy (prevents circular nesting, moves subtrees together)
71
75
  - Programmatic expand/collapse methods (`toggleRowCollapse`, `collapseAll`, `expandAll`)
72
- - ⌨️ **Keyboard Navigation**: Arrow key navigation & selection, Shift + Arrow task movement, Delete / Backspace deletion.
76
+ - ⌨️ **Keyboard Navigation & Shortcuts**: Arrow key navigation & selection, Shift + Arrow task movement, Delete / Backspace task & dependency deletion, Undo / Redo (`Ctrl+Z` / `Ctrl+Y`), and zoom controls.
73
77
 
74
78
  ## Packages (Ecosystem)
75
79
 
@@ -497,30 +501,47 @@ Font scaling is automatically applied to calendar headers (year/month, weeks, da
497
501
 
498
502
  ### Dependency Line Settings
499
503
 
500
- Configure task dependency curves with the `dependency` option:
504
+ Configure task dependency curves and interactive operations with the `dependency` option:
501
505
 
506
+ - `lineStyle`: `'orthogonal'` (rounded segmented lines, default) or `'curve'` (Bezier curves).
502
507
  - `showArrows`: Toggle directional arrow heads (default: `true`).
503
508
  - `arrowSize`: Arrow dimensions in pixels (default: `8`).
504
- - `showConnectors`: Control whether circular connection handles appear on hover (default: `true`). Set to `false` to prevent creating new dependencies.
505
- - `showCriticalPath`: Automatically detect the longest chain (critical path) and highlight connected tasks and lines in a distinct color (configurable via `theme.criticalPath`).
509
+ - `showConnectors`: Control whether circular connection handles appear on hover (default: `true`).
510
+ - `showCriticalPath`: Automatically detect the longest chain (critical path) and highlight connected tasks and lines.
511
+ - `creatable`: Allow creating links via connector drag (default: `true`).
512
+ - `deletable`: Allow deleting links via keyboard or button (default: `true`).
513
+ - `showDeleteButton`: Display "×" delete button on selected link (default: `true`).
506
514
 
507
- Reverse dependencies (right-to-left) automatically render smooth S-curves with perpendicular contact alignment.
515
+ Lines can be clicked to select (highlighted with distinct stroke & shadow), and deleted by clicking the "×" button or pressing `Delete` / `Backspace`.
508
516
 
509
517
  ```javascript
510
518
  const option = {
511
519
  dependency: {
520
+ lineStyle: 'orthogonal',
521
+ cornerRadius: 8,
512
522
  showArrows: true,
513
523
  arrowSize: 10,
514
524
  showConnectors: true,
515
- showCriticalPath: true, // Highlight critical path tasks and links
525
+ showCriticalPath: true,
526
+ creatable: true,
527
+ deletable: true,
528
+ showDeleteButton: true,
516
529
  },
517
530
  // ...
518
531
  }
532
+
533
+ // Dependency selection and deletion events
534
+ chart.addEventListener('dependency-select', (e) => {
535
+ console.log('Selected dependency:', e.detail.selected)
536
+ })
537
+ chart.addEventListener('dependency-delete', (e) => {
538
+ console.log('Deleted dependency:', e.detail.sourceTaskId, '->', e.detail.targetTaskId)
539
+ })
519
540
  ```
520
541
 
521
542
  ### Task Progress Management
522
543
 
523
- Visualize and interactively edit progress on task bars by specifying `progress` (`0` to `100`). Set `editable: true` to enable dragging the progress adjustment handle on the task bar.
544
+ Visualize and interactively edit progress on task bars by specifying `progress` (`0` to `100`). Set `editable: true` to enable dragging the progress adjustment handle on the task bar. When `showLabel: true` is enabled, summary tasks also display their aggregated progress labels automatically.
524
545
 
525
546
  ```javascript
526
547
  import {
@@ -534,8 +555,10 @@ const option = {
534
555
  progress: {
535
556
  enabled: true,
536
557
  editable: true, // Allow interactive handle dragging
558
+ color: '#3b82f6', // Progress bar color for normal tasks
559
+ summaryColor: 'rgba(255, 255, 255, 0.35)', // Progress bar color for summary tasks
537
560
  showLabel: true, // Display progress text (e.g. "50%")
538
- showSummaryLabel: false, // Whether to show progress label on summary tasks (default: false)
561
+ showSummaryLabel: true, // Show progress label on summary tasks (default: true)
539
562
  labelPosition: 'inside', // 'inside' | 'right' | 'left' | 'center'
540
563
  snapStep: 5, // Snap in 5% increments
541
564
  indicatorPosition: 'full', // 'full' | 'bottom' | 'top'
@@ -771,31 +794,80 @@ const { exportChart } = await import('@mogura/moguchart-plugin-export')
771
794
  await exportChart(chart, 'png', { download: true })
772
795
  ```
773
796
 
774
- #### Zoom Operations (`zoomTo`, `zoomToFit`, `resetZoom`)
797
+ #### Zoom Operations (`zoomIn`, `zoomOut`, `zoomToPercent`, `zoomToScale`, `zoomToFit`, `resetZoom`)
775
798
 
776
- Enable zoom via `option.zoom` (wheel zoom with Ctrl / Cmd key) and control zoom level programmatically:
799
+ Enable zoom via `option.zoom` (wheel zoom with Ctrl / Cmd key, keyboard shortcuts `Ctrl/Cmd + + / - / 0`) and control zoom level programmatically:
777
800
 
778
801
  ```javascript
779
802
  const option = {
780
803
  zoom: {
781
- enabled: true,
782
- min: 5,
783
- max: 150,
784
- step: 1.2,
804
+ enabled: true, // Enable zoom features (default: false)
805
+ minPercent: 50, // Minimum zoom percentage (default: 50)
806
+ maxPercent: 200, // Maximum zoom percentage (default: 200)
807
+ initialPercent: 100, // Initial zoom percentage (default: 100)
808
+ shortcuts: true, // Enable keyboard shortcuts (default: true)
809
+ scaleElements: {
810
+ calendar: true,
811
+ rowHeader: true,
812
+ barHeight: true,
813
+ fontScale: true,
814
+ },
785
815
  },
786
816
  }
787
817
 
788
818
  // Programmatic zoom control
789
- chart.zoomTo(50) // Set zoom level to 50px per day (or month)
819
+ chart.zoomIn() // Zoom in by one step (Chrome-compliant preset)
820
+ chart.zoomOut() // Zoom out by one step
821
+ chart.zoomToPercent(125) // Zoom to 125%
822
+ chart.zoomToScale(1.5) // Zoom to 1.5x
790
823
  chart.zoomToFit() // Auto-fit all tasks into the visible container width
791
- chart.resetZoom() // Reset to original configuration scale
824
+ chart.resetZoom() // Reset to 100% (default scale)
792
825
 
793
826
  // Listen to zoom level changes
794
827
  chart.addEventListener('zoom-change', (e) => {
795
- console.log('New zoom level:', e.detail.pxPerDay || e.detail.pxPerMonth)
828
+ console.log('Zoom changed:', e.detail.zoomPercent + '%', 'scale:', e.detail.zoomScale)
796
829
  })
797
830
  ```
798
831
 
832
+ #### Operation History / Undo & Redo (`undo`, `redo`, `clearHistory`)
833
+
834
+ User actions (task moving, resizing, progress editing, deleting, row reordering, dependency creation and deletion) are automatically recorded. You can undo and redo them programmatically or via keyboard shortcuts (`Ctrl+Z` / `Ctrl+Y` / `Cmd+Shift+Z`).
835
+
836
+ ```javascript
837
+ const option = {
838
+ history: {
839
+ enabled: true, // Enable history tracking (default: true)
840
+ maxDepth: 50, // Maximum history steps to retain (default: 50)
841
+ keyboard: true, // Enable undo/redo keyboard shortcuts (default: true)
842
+ },
843
+ }
844
+
845
+ // Perform Undo / Redo
846
+ if (chart.canUndo) {
847
+ await chart.undo()
848
+ }
849
+ if (chart.canRedo) {
850
+ await chart.redo()
851
+ }
852
+
853
+ // Clear history
854
+ chart.clearHistory()
855
+
856
+ // Listen to history state changes
857
+ chart.addEventListener('history-change', (e) => {
858
+ undoBtn.disabled = !e.detail.canUndo
859
+ redoBtn.disabled = !e.detail.canRedo
860
+ })
861
+ ```
862
+
863
+ #### Dependency Deletion (`triggerDependencyDelete`)
864
+
865
+ Programmatically remove a dependency connection between two tasks:
866
+
867
+ ```javascript
868
+ chart.triggerDependencyDelete('task-1', 'task-2')
869
+ ```
870
+
799
871
  #### WBS & Collapse Operations (`toggleRowCollapse`, `collapseAll`, `expandAll`)
800
872
 
801
873
  ```javascript
@@ -842,40 +914,40 @@ import {
842
914
 
843
915
  // 1. Calculate depth level for all rows
844
916
  const levels = computeRowLevels(rows) // Map<string, number> (rowId -> level: 0, 1, 2...)
845
-
846
917
  // 2. Generate WBS hierarchical numbering codes ("1", "1.1", "1.2", etc.)
847
918
  const wbsCodes = computeRowWbsCodes(rows) // Map<string, string> (rowId -> wbsCode)
848
-
849
919
  // 3. Get child / descendant row IDs for a row
850
920
  const allDescendants = computeChildRowIds('project-1', rows, true) // Recursively get all descendants
851
921
  const directChildren = computeChildRowIds('project-1', rows, false) // Direct children only
852
-
853
922
  // 4. Extract rows currently visible based on collapse states
854
923
  const visibleRows = computeVisibleTreeRows(rows)
855
-
856
924
  // 5. Aggregate child tasks into a summary task
857
925
  const summaryTask = computeSummaryTask(childTasks, 'project-1') // Min start, max end, weighted average progress
858
-
859
926
  // 6. Safe D&D check to prevent circular parent-child nesting
860
927
  const isDropAllowed = canDropRow('source-row-id', 'target-row-id', rows) // boolean
861
-
862
928
  // 7. Find longest task dependency chains (critical path)
863
929
  const criticalTaskIds = computeCriticalPath(allTasks) // Set<string>
864
930
  ```
865
931
 
866
932
  ### Keyboard Operations
867
933
 
868
- When the Gantt chart element is focused, keyboard shortcuts allow fast navigation, selection, movement, and deletion:
869
-
870
- | Key | Action |
871
- | :--------------------- | :------------------------------------- |
872
- | `←` `→` | Move focus between tasks |
873
- | `↑` `↓` | Move focus to another row |
874
- | `Enter` / `Space` | Select the focused task |
875
- | `Ctrl/Cmd + Enter` | Toggle selection state (multi-select) |
876
- | `Shift + ←` `→` | Move selected tasks backward / forward |
877
- | `Delete` / `Backspace` | Trigger `task-delete` event |
878
- | `Escape` | Clear current selection and focus |
934
+ When the Gantt chart element is focused, keyboard shortcuts allow fast navigation, task manipulation, undo/redo, and zooming:
935
+
936
+ | Key | Action |
937
+ | :--------------------- | :------------------------------------------ |
938
+ | `←` `→` | Move focus between tasks |
939
+ | `↑` `↓` | Move focus to another row |
940
+ | `Enter` / `Space` | Select the focused task |
941
+ | `Ctrl/Cmd + Enter` | Toggle selection state (multi-select) |
942
+ | `Shift + ←` `→` | Move selected tasks backward / forward |
943
+ | `Delete` / `Backspace` | Delete selected task or selected dependency |
944
+ | `Ctrl+Z` / `Cmd+Z` | Undo last operation |
945
+ | `Ctrl+Y` / `Cmd+Shift+Z` | Redo last undone operation |
946
+ | `Ctrl/Cmd + +` | Zoom in |
947
+ | `Ctrl/Cmd + -` | Zoom out |
948
+ | `Ctrl/Cmd + 0` | Reset zoom to 100% |
949
+ | `Ctrl/Cmd + Wheel` | Zoom in / Zoom out |
950
+ | `Escape` | Clear current selection and focus |
879
951
 
880
952
  ```javascript
881
953
  const option = {
@@ -883,7 +955,12 @@ const option = {
883
955
  enabled: true, // Default: true
884
956
  moveStep: 60, // Move distance per Shift+Arrow key press (minutes)
885
957
  },
886
- // ...
958
+ history: {
959
+ keyboard: true, // Enable Undo/Redo shortcuts (default: true)
960
+ },
961
+ zoom: {
962
+ shortcuts: true, // Enable Zoom shortcuts (default: true)
963
+ },
887
964
  }
888
965
  ```
889
966
 
@@ -0,0 +1,75 @@
1
+ import type { ReactiveController, ReactiveControllerHost } from 'lit';
2
+ import type { DependencyEndpoint, GanttChartOption, GanttRow } from '../../core/types';
3
+ import type { GanttCommandType } from '../../core/history';
4
+ export interface ConnectorDragState {
5
+ sourceTaskId: string;
6
+ sourceEndpoint: DependencyEndpoint;
7
+ startX: number;
8
+ startY: number;
9
+ currentClientX: number;
10
+ currentClientY: number;
11
+ targetTaskId: string | null;
12
+ targetEndpoint: DependencyEndpoint | null;
13
+ }
14
+ export interface DependencyControllerHost extends ReactiveControllerHost, HTMLElement {
15
+ option: GanttChartOption;
16
+ rows: GanttRow[];
17
+ displayRows: GanttRow[];
18
+ currentRowHeaderWidth: number;
19
+ calendarHeight: number;
20
+ selectedRows: Set<string>;
21
+ selectedTasks: Set<string>;
22
+ calculateLayout(): {
23
+ layouts: any;
24
+ taskCoords: Map<string, any>;
25
+ totalHeight: number;
26
+ };
27
+ applyRowsChangeWithCommand(previousRows: GanttRow[], newRows: GanttRow[], commandInfo: {
28
+ type: GanttCommandType;
29
+ description: string;
30
+ }): void;
31
+ clearTooltip(): void;
32
+ }
33
+ export declare class DependencyController implements ReactiveController {
34
+ private host;
35
+ selectedDependency: {
36
+ sourceTaskId: string;
37
+ targetTaskId: string;
38
+ } | null;
39
+ connectorDrag: ConnectorDragState | null;
40
+ constructor(host: DependencyControllerHost);
41
+ hostConnected(): void;
42
+ hostDisconnected(): void;
43
+ /**
44
+ * 依存関係線の選択状態を解除する
45
+ */
46
+ clearDependencySelection(): void;
47
+ /**
48
+ * 依存関係線を選択状態にする
49
+ */
50
+ selectDependency(sourceTaskId: string, targetTaskId: string): void;
51
+ /**
52
+ * 依存関係の削除リクエストイベントを発火する
53
+ */
54
+ triggerDependencyDelete(sourceTaskId: string, targetTaskId: string, originalEvent?: Event): void;
55
+ /**
56
+ * コネクタードラッグ開始ハンドラ
57
+ */
58
+ handleConnectorDragStart(e: CustomEvent): void;
59
+ /**
60
+ * コネクタードラッグ中ハンドラ
61
+ */
62
+ handleConnectorDragMove(e: CustomEvent): void;
63
+ /**
64
+ * コネクタードラッグ終了ハンドラ
65
+ */
66
+ handleConnectorDragEnd(e: CustomEvent): void;
67
+ /**
68
+ * 指定タスクIDのgantt-bar要素にconnectorDropTarget属性をセットする
69
+ */
70
+ setConnectorDropTarget(taskId: string, value: boolean): void;
71
+ /**
72
+ * 依存関係線クリックハンドラ
73
+ */
74
+ handleDependencyLineClick(event: MouseEvent, targetTaskId: string, sourceTaskId: string): void;
75
+ }
@@ -0,0 +1,84 @@
1
+ import type { ReactiveController, ReactiveControllerHost } from 'lit';
2
+ import type { GanttChartOption, GanttRow, GanttTask, GanttTaskMoveMode, TaskUpdateEventDetail } from '../../core/types';
3
+ import type { GanttCommandType } from '../../core/history';
4
+ import { type DragOverlayInfo, type DragPreviewState, type DraggingTaskState, type TaskDragControllerHost } from './task-drag-controller';
5
+ import { type RowReorderControllerHost } from './row-reorder-controller';
6
+ export type { DragOverlayInfo, DragPreviewState, DraggingTaskState };
7
+ export interface DragDropControllerHost extends ReactiveControllerHost, HTMLElement, TaskDragControllerHost, RowReorderControllerHost {
8
+ rows: GanttRow[];
9
+ displayRows: GanttRow[];
10
+ option: GanttChartOption;
11
+ theme: 'light' | 'dark';
12
+ selectedTasks: Set<string>;
13
+ selectedRows: Set<string>;
14
+ effectivePxPerDay: number;
15
+ effectivePxPerMonth: number | undefined;
16
+ effectiveBarHeight: number;
17
+ calendarHeight: number;
18
+ currentRowHeaderWidth: number;
19
+ externalDraggingTask: GanttTask | null;
20
+ _collapsedRowIds: Set<string>;
21
+ calculateLayout(): {
22
+ layouts: Array<{
23
+ top: number;
24
+ height: number;
25
+ }>;
26
+ totalHeight: number;
27
+ };
28
+ getDateX(date: Date): number;
29
+ applyRowsChangeWithCommand(previousRows: GanttRow[], newRows: GanttRow[], commandInfo: {
30
+ type: GanttCommandType;
31
+ description: string;
32
+ }): void;
33
+ clearTooltip?(): void;
34
+ }
35
+ /**
36
+ * @deprecated 後方互換性のためのファサードコントローラー。
37
+ * 個別には TaskDragController または RowReorderController を使用してください。
38
+ */
39
+ export declare class DragDropController implements ReactiveController {
40
+ private taskDrag;
41
+ private rowReorder;
42
+ constructor(host: DragDropControllerHost);
43
+ hostConnected(): void;
44
+ hostDisconnected(): void;
45
+ get draggingTask(): DraggingTaskState | null;
46
+ set draggingTask(val: DraggingTaskState | null);
47
+ get draggingTaskIds(): string[];
48
+ set draggingTaskIds(val: string[]);
49
+ get multiDragDx(): number;
50
+ set multiDragDx(val: number);
51
+ get multiDragDy(): number;
52
+ set multiDragDy(val: number);
53
+ get multiDragSameRow(): boolean;
54
+ set multiDragSameRow(val: boolean);
55
+ get dragTargetRowIndex(): number | null;
56
+ set dragTargetRowIndex(val: number | null);
57
+ get dragOverlayInfo(): DragOverlayInfo | null;
58
+ set dragOverlayInfo(val: DragOverlayInfo | null);
59
+ get dragPreview(): DragPreviewState | null;
60
+ set dragPreview(val: DragPreviewState | null);
61
+ get dragOverRowId(): string | null;
62
+ set dragOverRowId(val: string | null);
63
+ get dragOverPosition(): 'top' | 'bottom' | null;
64
+ set dragOverPosition(val: 'top' | 'bottom' | null);
65
+ get _draggingRowId(): string | null;
66
+ set _draggingRowId(val: string | null);
67
+ isMultiDrag(taskId: string): boolean;
68
+ isMultiDragSameRow(): boolean;
69
+ cleanupDragState(): void;
70
+ updateDragOverlay(): void;
71
+ hideDragOverlay(): void;
72
+ handleTaskUpdate(e: CustomEvent<TaskUpdateEventDetail & {
73
+ mode?: GanttTaskMoveMode;
74
+ }>): void;
75
+ handleExternalTaskDrop(e: DragEvent, taskJson: string): void;
76
+ reorderRows(sourceIds: string | string[], targetId: string, position: 'top' | 'bottom'): Promise<void>;
77
+ handleRowDragStart(e: CustomEvent<{
78
+ rowId: string;
79
+ }>): void;
80
+ handleRowDragEnd(): void;
81
+ handleContainerDragOver(e: DragEvent): void;
82
+ handleContainerDragLeave(e: DragEvent): void;
83
+ handleContainerDrop(e: DragEvent): void;
84
+ }