@mogura/moguchart-core 1.4.0 → 1.5.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/CHANGELOG.ja.md CHANGED
@@ -5,6 +5,51 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.5.0] - 2026-10-17
9
+
10
+ ### Added
11
+
12
+ - **マルチカラムデータグリッド対応(Multi-Column Data Grid / WBS テーブル)**:
13
+ - 行ヘッダー領域を本格的な複数カラムのテーブルとして表示・操作できる新オプション `option.grid` を追加
14
+ - **標準組み込みカラムプリセット**:
15
+ - `wbs`: WBS階層コード(例: 1, 1.1, 1.2.1)
16
+ - `name`: タスク名・行名(階層ツリーインデント+展開・折りたたみボタン内包)
17
+ - `startDate` / `startMonth` / `startDateTime`: タスク開始日・開始月・開始日時(単一タスクは開始日時、サマリー行・複数タスク行は最小開始日時を自動集計)
18
+ - `endDate` / `endMonth` / `endDateTime`: タスク終了日・終了月・終了日時(単一タスクは終了日時、サマリー行・複数タスク行は最大終了日時を自動集計)
19
+ - `duration`: 期間・工数(カレンダー日数スパン、時間単位モード時は時間・分フォーマット)
20
+ - `progress`: 進捗率(サマリー行・複数タスク行は期間加重平均進捗率を自動算出)
21
+ - **表示モードに応じた自動カラム適応**:
22
+ - 月単位モード(`pxPerMonth` 指定時)では `startDate` / `endDate` のヘッダーが自動的に「開始月」「終了月」(`Start Month` / `End Month`)に切り替わり、`YYYY/M` 形式で表示(終了月は前月表記に自動調整)
23
+ - 時間単位モード(`showTime: true` 時)では `startDate` / `endDate` のヘッダーが自動的に「開始日時」「終了日時」(`Start Date/Time` / `End Date/Time`)に切り替わり、時刻付き表示および時間単位の期間表示に連動
24
+ - **グリッドセルのインライン編集機能 (`option.grid.editable`, `cell-edit`)**:
25
+ - セルのダブルクリック(またはクリック:`editTrigger: 'dblclick' | 'click'`)による直感的なインライン編集に対応
26
+ - 組み込みエディタ種別(`text`, `number`, `date`, `datetime`, `month`, `select`)および独自の `HTMLElement` をマウントできるカスタムエディタ関数(`editor: (context) => HTMLElement`)をサポート
27
+ - セレクトボックス用選択肢(`editorOptions`)、数値入力の最小・最大・ステップ値(`editorMin`, `editorMax`, `editorStep`)、行・タスクごとの編集可否判定(`editable`)、カスタムセッター(`valueSetter`)に対応
28
+ - 単一タスクの `resizable`(`false` 時は日付・期間編集不可)、`movable`(`'none'` 時は日付・期間編集不可)、`progressResizable`(`false` 時は進捗率編集不可)の設定を考慮したセル編集可否判定に対応
29
+ - **編集可能セルと読み取り専用セルの視覚的区別**: インライン編集有効時、編集可能なセル(`.grid-cell-editable`: テキストカーソル・ホバーハイライト)と編集不可のセル(`.grid-cell-readonly`: サマリー行・複数タスク行の集計セルやWBS番号セル等のグレーアウト背景・半透明表示)を視覚的に区別(画像・PDFエクスポート時は自動的に通常表示へ正規化)
30
+ - グリッド有効時は行のドラッグ並び替えおよび行ヘッダーツールチップの表示対象をタスク名(ツリー)セル(`.grid-cell-name`, `.grid-tree-cell`)に限定し、インライン編集中は行のドラッグ並び替えを一時的に無効化することで入力欄内でのテキスト選択操作がスムーズに行えるよう改善
31
+ - 編集確定時に `cell-edit` および `rows-change` イベントを発火し、操作履歴(Undo / Redo: `command.type === 'cell-edit'`)と完全連動
32
+ - プログラムからセル編集を制御するパブリックメソッド `startCellEdit(rowId, columnId)`, `commitCellEdit(overrideValue?)`, `cancelCellEdit()` を追加
33
+ - **`cornerContent` とグリッドヘッダーの2段レイアウト共存**:
34
+ - グリッド有効時に `customRendering.cornerContent` が指定されている場合、左上コーナー領域を上段(`cornerContent`)と下段(グリッドカラムヘッダー)の2段構成で同時表示するよう対応
35
+ - **カスタムカラム & 自由なデータマッピング**:
36
+ - `field` による任意オブジェクトプロパティのバインド、および `valueGetter(row, tasks, wbsCode)` / `valueSetter(row, newValue, tasks, column)` による高度なカスタム値の取得・更新に対応
37
+ - `formatter` による文字列整形、および `renderCell(value, row, tasks, locale)` による `HTMLElement` / HTML 文字列のカスタムレンダリングに対応
38
+ - **カラム幅のドラッグリサイズ (`column-resize`)**:
39
+ - カラムヘッダー右端のドラッグ操作により、各カラムの幅を直感的に個別リサイズ可能。リサイズ中・完了時に `column-resize` カスタムイベントを発火し、行クリックやオプション更新時もユーザーのリサイズ幅を保持しつつ、`option.grid.columns` からの明示的な列幅変更にも追従
40
+ - **スプリッターリサイズ & グリッド内独立横スクロール同期**:
41
+ - グリッド領域とタイムライン領域を仕切るスプリッターリサイズを完全サポート
42
+ - カラム合計幅が表示枠を超える場合、トラックパッド横スワイプ、`Shift + ホイール`、またはグリッドヘッダー上のマウスホイール操作による独立横スクロールに対応。ヘッダーセルと各行セルが1pxのズレもなく同期して横スクロール
43
+ - **React / Vue ラッパーおよび公開ユーティリティの拡充**:
44
+ - `@mogura/moguchart-react` に `onColumnResize`, `onCellEdit`, `onRowsChange` イベント Props を追加
45
+ - `@mogura/moguchart-vue` に `@column-resize`, `@cell-edit`, `@rows-change` イベントおよび `startCellEdit`, `commitCellEdit`, `cancelCellEdit` 公開メソッドを追加
46
+ - グリッド計算・編集用ヘルパー関数(`calculateRowSummaryDates`, `normalizeGridColumns`, `getGridCellValue`, `formatGridCellValue`, `resolveColumnEditorType`, `isGridCellEditable`, `formatGridCellEditValue`, `applyGridCellEdit`)をエクスポート
47
+ - **多言語(i18n)自動連動 & 完全な後方互換性**:
48
+ - 日本語(`jaLocale`)および英語(`enLocale`)の言語切り替えと標準カラム名・期間単位が自動連動
49
+ - `option.grid` 未指定時は、従来の単一ヘッダー表示(`row.name`)として完全互換動作
50
+
51
+ ---
52
+
8
53
  ## [1.4.0] - 2026-10-11
9
54
 
10
55
  ### Added
package/CHANGELOG.md CHANGED
@@ -5,6 +5,51 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.5.0] - 2026-10-17
9
+
10
+ ### Added
11
+
12
+ - **Multi-Column Data Grid Support (WBS Table)**:
13
+ - Added new option `option.grid` to display and interact with the row header area as a full-featured multi-column data table.
14
+ - **Built-in Standard Columns**:
15
+ - `wbs`: WBS hierarchical numbering code (e.g. 1, 1.1, 1.2.1).
16
+ - `name`: Task / row title with embedded hierarchical tree indentation and expand/collapse toggle.
17
+ - `startDate` / `startMonth` / `startDateTime`: Task start date, month, or date/time (automatically computes earliest start date for summary rows and multi-task rows).
18
+ - `endDate` / `endMonth` / `endDateTime`: Task end date, month, or date/time (automatically computes latest end date for summary rows and multi-task rows).
19
+ - `duration`: Duration / work span in calendar days (or formatted hours/minutes in hourly view mode).
20
+ - `progress`: Task progress percentage (automatically computes duration-weighted average progress for summary rows and multi-task rows).
21
+ - **Automatic View-Mode Column Adaptation**:
22
+ - In Monthly mode (`pxPerMonth` specified), `startDate` / `endDate` headers automatically switch to `Start Month` / `End Month` (`開始月` / `終了月`) and format values as `YYYY/M` (automatically adjusting exclusive end boundary dates to display the previous month).
23
+ - In Hourly / Time mode (`showTime: true`), `startDate` / `endDate` headers automatically switch to `Start Date/Time` / `End Date/Time` (`開始日時` / `終了日時`), displaying timestamps and time-based duration spans.
24
+ - **Inline Cell Editing (`option.grid.editable`, `cell-edit`)**:
25
+ - Support interactive inline cell editing triggered by double-click or single-click (`editTrigger: 'dblclick' | 'click'`).
26
+ - Built-in editor types (`'text'`, `'number'`, `'date'`, `'datetime'`, `'month'`, `'select'`) as well as custom DOM editor factories (`editor: (context) => HTMLElement`).
27
+ - Configurable select options (`editorOptions`), numeric bounds (`editorMin`, `editorMax`, `editorStep`), per-row/task editability predicates (`editable`), and custom value setters (`valueSetter`).
28
+ - Automatic linkage with single-task editability settings (`task.resizable === false` or `task.movable === 'none'` disables date/duration editing; `task.progressResizable === false` disables progress editing).
29
+ - Visual distinction between editable cells (`.grid-cell-editable`: text cursor and hover highlight) and read-only cells (`.grid-cell-readonly`: dimmed background and semi-transparent text for summary/multi-task aggregated cells and WBS codes; automatically normalized during PNG/PDF export).
30
+ - Restricts row drag-and-drop reordering and row header tooltips in grid mode to the task name / tree cell (`.grid-cell-name`, `.grid-tree-cell`), and temporarily suppresses row reordering while inline cell editing is active to allow smooth mouse drag text selection.
31
+ - Dispatches `cell-edit` and `rows-change` custom events upon committing changes, with full Undo / Redo history integration (`command.type === 'cell-edit'`).
32
+ - Added programmatic editing control methods: `startCellEdit(rowId, columnId)`, `commitCellEdit(overrideValue?)`, and `cancelCellEdit()`.
33
+ - **Custom Columns & Flexible Data Mapping**:
34
+ - Bind arbitrary row properties using `field`, or extract and update custom values using `valueGetter(row, tasks, wbsCode)` and `valueSetter(row, newValue, tasks, column)`.
35
+ - Format text outputs with `formatter(value, row, tasks, locale)`, or render rich `HTMLElement` / HTML strings with `renderCell(value, row, tasks, locale)`.
36
+ - **Two-Tier Corner Header Coexistence**:
37
+ - When both `option.grid` and `customRendering.cornerContent` are configured, the top-left corner automatically renders in a 2-tier layout with `cornerContent` in the upper row and grid column headers in the lower row.
38
+ - **Interactive Column Drag Resizing (`column-resize`)**:
39
+ - Intuitive drag-to-resize handles on column headers. Fires `column-resize` custom events during and upon completing resize operations, preserving user-resized widths across row interactions while also tracking programmatic `option.grid.columns` width updates.
40
+ - **Splitter Resizing & Synchronized Independent Grid Horizontal Scrolling**:
41
+ - Seamlessly works with the split pane resizer dividing the grid and timeline areas.
42
+ - When column widths exceed the grid area width, independent horizontal scrolling activates via trackpad swipe, `Shift + wheel`, or vertical wheel scrolling over the grid header area, with pixel-perfect synchronization (`transform: translateX(-gridScrollLeft)`) across header and row cells.
43
+ - **React / Vue Wrapper & Exported Utility Enhancements**:
44
+ - Added `onColumnResize`, `onCellEdit`, and `onRowsChange` event props to `@mogura/moguchart-react`.
45
+ - Added `@column-resize`, `@cell-edit`, and `@rows-change` emits plus `startCellEdit`, `commitCellEdit`, and `cancelCellEdit` public methods to `@mogura/moguchart-vue`.
46
+ - Exported grid calculation and editing helper utilities (`calculateRowSummaryDates`, `normalizeGridColumns`, `getGridCellValue`, `formatGridCellValue`, `resolveColumnEditorType`, `isGridCellEditable`, `formatGridCellEditValue`, `applyGridCellEdit`).
47
+ - **Multi-language (i18n) Synchronization & Complete Backward Compatibility**:
48
+ - Built-in Japanese (`jaLocale`) and English (`enLocale`) column headers and duration units adapt automatically to the active chart locale.
49
+ - When `option.grid` is omitted or disabled, the chart operates in classic single-header row name mode with zero breaking changes.
50
+
51
+ ---
52
+
8
53
  ## [1.4.0] - 2026-10-11
9
54
 
10
55
  ### Added
package/README.ja.md CHANGED
@@ -79,6 +79,14 @@ Vue, React, Angular, Svelte など、どのフレームワークでも動作す
79
79
  - WBSサマリータスクにおける配下子タスクの計画日程・進捗率の自動集計
80
80
  - 全体鳥瞰ミニマップ(2D Canvas)との同期描画
81
81
  - タスク遅延計算(`calculateTaskDelay`)およびプロジェクト予実統計集計(`calculateProjectBaselineSummary`)関数
82
+ - 📋 **マルチカラムデータグリッド(WBS テーブル)**:
83
+ - 行ヘッダー領域を本格的な複数列のテーブルとして表示・操作
84
+ - 標準組み込みカラム(WBS番号 `wbs`、タスク名 `name`、開始日・開始月・開始日時 `startDate`/`startMonth`/`startDateTime`、終了日・終了月・終了日時 `endDate`/`endMonth`/`endDateTime`、期間 `duration`、進捗率 `progress`)および表示モード(日・週・月・時間)に応じた自動ヘッダー名・フォーマット切り替え
85
+ - サマリー行・複数タスク行の最小開始日〜最大終了日、カレンダー期間、加重平均進捗率を自動算出
86
+ - **インラインセル編集**(`option.grid.editable: true`):ダブルクリックまたはクリックによる直接編集、`text` / `number` / `date` / `datetime` / `month` / `select` の組み込みエディタおよびカスタムエディタ関数、単一タスクの `movable` / `resizable` / `progressResizable` 設定との自動連動、編集可能セル(`.grid-cell-editable`)と読み取り専用セル(`.grid-cell-readonly`)の視覚的区別、Undo/Redo 履歴連動、`cell-edit` イベントに対応
87
+ - カスタムカラム(`field`、`valueGetter`、`valueSetter`、`formatter`、`renderCell` によるHTML/DOMの直接描画)および `customRendering.cornerContent` との上下2段レイアウト共存
88
+ - カラム境界ドラッグによる幅のリサイズ(`column-resize` イベント)
89
+ - グリッド領域とタイムライン領域のスプリッターリサイズ&グリッド内独立横スクロール同期(トラックパッド横スワイプ、Shift+ホイール、ヘッダー上のホイールに対応)
82
90
  - ⌨️ **キーボード操作**: 矢印キーでのナビゲーション・選択・Shift+矢印キーでのタスク移動・Deleteキーでのタスク/依存関係線削除・Undo/Redo・ズームショートカット
83
91
 
84
92
  ## パッケージ一覧(エコシステム)
@@ -777,6 +785,72 @@ const summary = calculateProjectBaselineSummary(rows)
777
785
  console.log(`計画タスク数: ${summary.totalBaselineTasks}, 遅延タスク数: ${summary.delayedTasksCount}, 最大遅延: ${summary.maxDelayDays}日`)
778
786
  ```
779
787
 
788
+ ### マルチカラムデータグリッド(WBSテーブル & インライン編集)
789
+
790
+ 行ヘッダー領域を本格的な複数カラムのテーブルとして表示できます。WBS階層コード、タスク名、期間、進捗率、カスタム列を柔軟に構成できるほか、`editable: true` を設定することでセルのダブルクリック(またはクリック)によるインライン編集が可能です(編集可能セルには `.grid-cell-editable`、サマリー行や複数タスク行の集計セル・`wbs` 列などの読み取り専用セルには `.grid-cell-readonly` クラスが付与され視覚的に区別されます。単一タスク行の日付・期間・進捗セルはタスクの `movable` / `resizable` / `progressResizable` 設定とも自動連動します)。
791
+
792
+ 表示モードに応じて、`startDate` / `endDate` の列タイトルや表示フォーマット・エディタ種別は自動的に切り替わります(月単位モード時は「開始月」「終了月」、時間単位モード時は「開始日時」「終了日時」)。また、`customRendering.cornerContent` と併用した場合は、左上コーナー領域の上段に `cornerContent`、下段にグリッドカラムヘッダーが2段構成で表示されます。
793
+
794
+ ```javascript
795
+ const option = {
796
+ // グリッド表示設定
797
+ grid: {
798
+ enabled: true, // グリッド表示を有効化 (デフォルト: columns 指定時は true)
799
+ width: 700, // グリッド領域全体の初期幅 (px)
800
+ splitterResizable: true, // スプリッターによるグリッド幅変更を許可 (デフォルト: true)
801
+ showBorders: true, // セル罫線を表示 (デフォルト: true)
802
+ editable: true, // セルのインライン編集を有効化 (デフォルト: false)
803
+ editTrigger: 'dblclick', // 編集開始トリガー ('dblclick' | 'click'、デフォルト: 'dblclick')
804
+ columns: [
805
+ { id: 'wbs', width: 60 }, // WBS番号 (1, 1.1, 1.2 など)
806
+ { id: 'name', width: 220 }, // タスク名 (ツリー開閉トグル付き・テキスト編集)
807
+ { id: 'startDate', width: 125 }, // 開始日 (日/月/日時エディタに自動連動)
808
+ { id: 'endDate', width: 125 }, // 終了日 (日/月/日時エディタに自動連動)
809
+ { id: 'duration', width: 80 }, // 期間 (数値エディタ)
810
+ { id: 'progress', width: 70 }, // 進捗率 (0〜100% 数値エディタ)
811
+ {
812
+ id: 'assignee',
813
+ title: '担当者',
814
+ width: 100,
815
+ field: 'assignee', // row.assignee を参照・更新
816
+ editor: 'select', // 'text' | 'number' | 'date' | 'datetime' | 'month' | 'select' またはカスタム関数
817
+ editorOptions: [
818
+ { label: '山田', value: '山田' },
819
+ { label: '佐藤', value: '佐藤' },
820
+ { label: '鈴木', value: '鈴木' },
821
+ ],
822
+ renderCell: (value) => {
823
+ // カスタムDOM要素のレンダリング
824
+ const badge = document.createElement('span')
825
+ badge.className = 'badge'
826
+ badge.textContent = value || '未設定'
827
+ return badge
828
+ },
829
+ },
830
+ ],
831
+ },
832
+ }
833
+
834
+ // セルのインライン編集確定イベントの購読
835
+ chart.addEventListener('cell-edit', (event) => {
836
+ const { rowId, columnId, oldValue, newValue, row, rows } = event.detail
837
+ console.log(`行 ${rowId} の ${columnId} が更新されました:`, oldValue, '->', newValue)
838
+ })
839
+
840
+ // カラム幅リサイズイベントの購読
841
+ chart.addEventListener('column-resize', (event) => {
842
+ const { columnId, width, previousWidth, isFinal } = event.detail
843
+ if (isFinal) {
844
+ console.log(`カラム ${columnId} の幅が ${width}px に変更されました`)
845
+ }
846
+ })
847
+
848
+ // プログラムからのセル編集制御
849
+ chart.startCellEdit('row-1', 'name') // 編集開始
850
+ chart.commitCellEdit('新しいタスク名') // 編集確定
851
+ chart.cancelCellEdit() // 編集キャンセル
852
+ ```
853
+
780
854
  ### パブリックメソッド
781
855
 
782
856
  #### selectTask
@@ -1008,6 +1082,18 @@ import {
1008
1082
  calculateRowProgress,
1009
1083
  calculateWeightedRowProgress,
1010
1084
  calculateProjectProgress,
1085
+ // 予実管理(ベースライン)計算
1086
+ calculateTaskDelay,
1087
+ calculateProjectBaselineSummary,
1088
+ // マルチカラムグリッド計算・インライン編集ヘルパー
1089
+ calculateRowSummaryDates,
1090
+ normalizeGridColumns,
1091
+ getGridCellValue,
1092
+ formatGridCellValue,
1093
+ resolveColumnEditorType,
1094
+ isGridCellEditable,
1095
+ formatGridCellEditValue,
1096
+ applyGridCellEdit,
1011
1097
  } from '@mogura/moguchart-core'
1012
1098
 
1013
1099
  // 1. 各行のツリー階層レベル(深さ)の計算
@@ -1031,6 +1117,9 @@ const isSafe = canDropRow('source-row-id', 'target-row-id', rows) // boolean
1031
1117
 
1032
1118
  // 7. クリティカルパス(最長依存関係チェーン)の計算
1033
1119
  const criticalTaskIds = computeCriticalPath(allTasks) // Set<string>
1120
+
1121
+ // 8. 行内のタスク配列から最小開始日・最大終了日・期間日数を算出
1122
+ const summaryDates = calculateRowSummaryDates(rows[0].tasks) // { start, end, durationDays }
1034
1123
  ```
1035
1124
 
1036
1125
  ### キーボード操作
package/README.md CHANGED
@@ -84,6 +84,14 @@ A lightweight yet feature-rich Gantt chart Web Component built with Lit. Works s
84
84
  - WBS parent summary aggregation of descendant task baselines
85
85
  - Synchronized bird's-eye rendering on the overview minimap (2D Canvas)
86
86
  - Helper functions for individual task variance (`calculateTaskDelay`) and project-wide statistics (`calculateProjectBaselineSummary`)
87
+ - 📋 **Multi-Column Data Grid (WBS Table)**:
88
+ - Display and interact with the row header area as a full-featured multi-column data table
89
+ - Built-in standard columns: WBS code (`wbs`), task name (`name`), start date/month/datetime (`startDate`/`startMonth`/`startDateTime`), end date/month/datetime (`endDate`/`endMonth`/`endDateTime`), duration (`duration`), progress (`progress`), with automatic header title and format adaptation across Day, Week, Month, and Hourly view modes
90
+ - Automatic calculations for summary and multi-task rows (earliest start, latest end, calendar duration, weighted average progress)
91
+ - **Inline Cell Editing** (`option.grid.editable: true`): Direct editing via double-click or single-click, built-in editors (`text`, `number`, `date`, `datetime`, `month`, `select`) and custom DOM editor functions, automatic linkage with single-task `movable` / `resizable` / `progressResizable` settings, visual distinction between editable (`.grid-cell-editable`) and read-only (`.grid-cell-readonly`) cells, Undo/Redo history integration, and `cell-edit` events
92
+ - Custom column definitions with `field`, `valueGetter`, `valueSetter`, `formatter`, and `renderCell` (supports HTML strings and `HTMLElement` nodes) and 2-tier layout coexistence with `customRendering.cornerContent`
93
+ - Column header drag-resizing with `column-resize` custom events
94
+ - Splitter-based area resizing with synchronized independent horizontal scrolling within the grid area (via trackpad swipe, Shift+wheel, or wheel over grid headers)
87
95
  - ⌨️ **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.
88
96
 
89
97
  ## Packages (Ecosystem)
@@ -787,7 +795,7 @@ const option = {
787
795
  }
788
796
 
789
797
  // Calculate delay or early completion for an individual task
790
- const delayInfo = calculateTaskDelay(rows[0].tasks[0])
798
+ delayInfo = calculateTaskDelay(rows[0].tasks[0])
791
799
  console.log(`Is delayed: ${delayInfo.isDelayed}, Delay in days: ${delayInfo.delayDays}`)
792
800
 
793
801
  // Aggregate project-wide baseline statistics
@@ -795,6 +803,72 @@ const summary = calculateProjectBaselineSummary(rows)
795
803
  console.log(`Total: ${summary.totalBaselineTasks}, Delayed: ${summary.delayedTasksCount}, Max delay: ${summary.maxDelayDays} days`)
796
804
  ```
797
805
 
806
+ ### Multi-Column Data Grid (WBS Table & Inline Editing)
807
+
808
+ Display the row header area as an interactive multi-column data table. Configure built-in WBS hierarchy codes, task names, dates, durations, progress, and custom columns. Set `editable: true` to enable inline cell editing via double-click (or single-click) (editable cells receive `.grid-cell-editable`, while read-only cells such as summary/multi-task aggregated cells and the `wbs` column receive `.grid-cell-readonly` for visual distinction; single-task date, duration, and progress cells also automatically respect `task.movable`, `task.resizable`, and `task.progressResizable`).
809
+
810
+ Depending on the active view mode, `startDate` and `endDate` column titles, display formats, and editor types automatically adapt (`Start Month` / `End Month` in monthly mode; `Start Date/Time` / `End Date/Time` in hourly mode). When used together with `customRendering.cornerContent`, the top-left corner renders in a 2-tier layout with `cornerContent` in the upper row and grid column headers in the lower row.
811
+
812
+ ```javascript
813
+ const option = {
814
+ // Data Grid configuration
815
+ grid: {
816
+ enabled: true, // Enable grid mode (default: true if columns is defined)
817
+ width: 700, // Total initial width of grid area (px)
818
+ splitterResizable: true, // Allow resizing grid area width via splitter (default: true)
819
+ showBorders: true, // Display cell borders (default: true)
820
+ editable: true, // Enable inline cell editing (default: false)
821
+ editTrigger: 'dblclick', // Trigger to start editing ('dblclick' | 'click', default: 'dblclick')
822
+ columns: [
823
+ { id: 'wbs', width: 60 }, // WBS code (1, 1.1, 1.2, etc.)
824
+ { id: 'name', width: 220 }, // Task name (includes tree indent, collapse toggle, and text editing)
825
+ { id: 'startDate', width: 125 }, // Start date (adapts to date/month/datetime editor)
826
+ { id: 'endDate', width: 125 }, // End date (adapts to date/month/datetime editor)
827
+ { id: 'duration', width: 80 }, // Duration (numeric editor)
828
+ { id: 'progress', width: 70 }, // Progress (0–100% numeric editor)
829
+ {
830
+ id: 'assignee',
831
+ title: 'Assignee',
832
+ width: 100,
833
+ field: 'assignee', // binds to row.assignee for reading & writing
834
+ editor: 'select', // 'text' | 'number' | 'date' | 'datetime' | 'month' | 'select' or custom function
835
+ editorOptions: [
836
+ { label: 'Alice', value: 'Alice' },
837
+ { label: 'Bob', value: 'Bob' },
838
+ { label: 'Charlie', value: 'Charlie' },
839
+ ],
840
+ renderCell: (value) => {
841
+ // Custom DOM element rendering
842
+ const badge = document.createElement('span')
843
+ badge.className = 'badge'
844
+ badge.textContent = value || 'Unassigned'
845
+ return badge
846
+ },
847
+ },
848
+ ],
849
+ },
850
+ }
851
+
852
+ // Listen to inline cell edit commit events
853
+ chart.addEventListener('cell-edit', (event) => {
854
+ const { rowId, columnId, oldValue, newValue, row, rows } = event.detail
855
+ console.log(`Row ${rowId} column ${columnId} updated:`, oldValue, '->', newValue)
856
+ })
857
+
858
+ // Listen to column resize events
859
+ chart.addEventListener('column-resize', (event) => {
860
+ const { columnId, width, previousWidth, isFinal } = event.detail
861
+ if (isFinal) {
862
+ console.log(`Column ${columnId} resized to ${width}px`)
863
+ }
864
+ })
865
+
866
+ // Programmatic cell editing control
867
+ chart.startCellEdit('row-1', 'name') // Start editing
868
+ chart.commitCellEdit('Updated Task Name') // Commit edit
869
+ chart.cancelCellEdit() // Cancel edit
870
+ ```
871
+
798
872
  ### Public Methods
799
873
 
800
874
  #### selectTask
@@ -1008,7 +1082,7 @@ console.log('Row positions:', rowPositions)
1008
1082
 
1009
1083
  ### Utility Functions
1010
1084
 
1011
- `@mogura/moguchart-core` exports various helper utilities for hierarchical WBS calculations, critical path detection, and progress aggregations:
1085
+ `@mogura/moguchart-core` exports various helper utilities for hierarchical WBS calculations, critical path detection, progress aggregations, baseline variance, and multi-column grid operations:
1012
1086
 
1013
1087
  ```typescript
1014
1088
  import {
@@ -1026,6 +1100,18 @@ import {
1026
1100
  calculateRowProgress,
1027
1101
  calculateWeightedRowProgress,
1028
1102
  calculateProjectProgress,
1103
+ // Baseline (plan vs actual) calculations
1104
+ calculateTaskDelay,
1105
+ calculateProjectBaselineSummary,
1106
+ // Multi-Column Grid calculations & inline editing helpers
1107
+ calculateRowSummaryDates,
1108
+ normalizeGridColumns,
1109
+ getGridCellValue,
1110
+ formatGridCellValue,
1111
+ resolveColumnEditorType,
1112
+ isGridCellEditable,
1113
+ formatGridCellEditValue,
1114
+ applyGridCellEdit,
1029
1115
  } from '@mogura/moguchart-core'
1030
1116
 
1031
1117
  // 1. Calculate depth level for all rows
@@ -1043,6 +1129,8 @@ const summaryTask = computeSummaryTask(childTasks, 'project-1') // Min start, ma
1043
1129
  const isDropAllowed = canDropRow('source-row-id', 'target-row-id', rows) // boolean
1044
1130
  // 7. Find longest task dependency chains (critical path)
1045
1131
  const criticalTaskIds = computeCriticalPath(allTasks) // Set<string>
1132
+ // 8. Calculate earliest start, latest end, and calendar days across tasks in a row
1133
+ const summaryDates = calculateRowSummaryDates(rows[0].tasks) // { start, end, durationDays }
1046
1134
  ```
1047
1135
 
1048
1136
  ### Keyboard Operations
@@ -1,5 +1,5 @@
1
1
  import { LitElement } from 'lit';
2
- import type { GanttChartOption, CalendarMonthCellContext, CalendarDayCellContext, CalendarWeekCellContext, CalendarHourCellContext } from '../core/types';
2
+ import type { GanttChartOption, CalendarMonthCellContext, CalendarDayCellContext, CalendarWeekCellContext, CalendarHourCellContext, GanttColumn } from '../core/types';
3
3
  export declare class GanttCalendarElement extends LitElement {
4
4
  option: GanttChartOption;
5
5
  theme: 'light' | 'dark';
@@ -11,12 +11,23 @@ export declare class GanttCalendarElement extends LitElement {
11
11
  calendarDayContent?: (context: CalendarDayCellContext) => string | unknown;
12
12
  calendarWeekContent?: (context: CalendarWeekCellContext) => string | unknown;
13
13
  calendarHourContent?: (context: CalendarHourCellContext) => string | unknown;
14
+ gridScrollLeft: number;
15
+ gridColumns?: GanttColumn[];
14
16
  /**
15
17
  * カスタムレンダリング関数の返却値をターゲット要素に注入するヘルパー
16
18
  * HTMLElement の場合は appendChild、文字列の場合は innerHTML に設定する
17
19
  */
18
20
  private injectCustomContent;
21
+ private get isGridEnabled();
19
22
  protected updated(): void;
23
+ /**
24
+ * カラムヘッダー幅リサイズの開始ハンドラー
25
+ */
26
+ private handleColumnResizeStart;
27
+ /**
28
+ * マルチカラムグリッドのヘッダーを描画する
29
+ */
30
+ private renderGridHeaders;
20
31
  /**
21
32
  * カレンダーセルのカスタムレンダリングコンテンツを注入する
22
33
  */
@@ -1,4 +1,4 @@
1
- import type { GanttChartOption, GanttChartOptionZoom, GanttRow, GanttTask, GanttTaskMoveMode, TaskUpdateEventDetail } from '../core/types';
1
+ import type { GanttChartOption, GanttChartOptionZoom, GanttRow, GanttTask, GanttTaskMoveMode, TaskUpdateEventDetail, GanttColumn } from '../core/types';
2
2
  import { HistoryManager, type GanttCommand, type GanttCommandType } from '../core/history';
3
3
  import { LitElement, type PropertyValues } from 'lit';
4
4
  import './gantt-calendar';
@@ -89,6 +89,13 @@ export declare class GanttChartElement extends LitElement {
89
89
  get _dragDropController(): DragDropController;
90
90
  private _historyManager;
91
91
  private isExporting;
92
+ private currentGridColumns;
93
+ private currentGridScrollLeft;
94
+ private _userResizedHeaderWidth;
95
+ private _lastExplicitOptionWidth;
96
+ private _userColumnWidths;
97
+ private _lastExplicitColumnWidths;
98
+ get effectiveGridColumns(): GanttColumn[] | undefined;
92
99
  private _layoutCache;
93
100
  private resizeObserver;
94
101
  private _cachedSelectedTaskIds;
@@ -134,6 +141,8 @@ export declare class GanttChartElement extends LitElement {
134
141
  private setupCurrentTimeTimer;
135
142
  private stopCurrentTimeTimer;
136
143
  private handleHeaderResizeStart;
144
+ private handleColumnResize;
145
+ handleGridWheel: (e: WheelEvent) => boolean;
137
146
  private handleScroll;
138
147
  private handleMinimapScroll;
139
148
  private updateScrollTop;
@@ -275,6 +284,19 @@ export declare class GanttChartElement extends LitElement {
275
284
  toggleRowCollapse(rowId: string, collapsed?: boolean): boolean;
276
285
  collapseAll(): void;
277
286
  expandAll(): void;
287
+ private handleRowCellEdit;
288
+ /**
289
+ * 指定された行とカラムのインライン編集を開始する
290
+ */
291
+ startCellEdit(rowId: string, columnId: string): boolean;
292
+ /**
293
+ * 現在編集中のセルがあれば編集を確定する
294
+ */
295
+ commitCellEdit(overrideValue?: any): boolean;
296
+ /**
297
+ * 現在編集中のセルがあれば編集をキャンセルする
298
+ */
299
+ cancelCellEdit(): void;
278
300
  /**
279
301
  * スクロール位置を左上(0, 0)にリセットします。
280
302
  */
@@ -1,4 +1,4 @@
1
- import type { GanttChartOption, GanttRow, GanttTask, GanttTaskMoveMode } from '../core/types';
1
+ import type { GanttChartOption, GanttRow, GanttTask, GanttTaskMoveMode, GanttColumn } from '../core/types';
2
2
  import { LitElement, type PropertyValues } from 'lit';
3
3
  import './gantt-bar';
4
4
  import './gantt-row-background';
@@ -34,6 +34,11 @@ export declare class GanttRowElement extends LitElement {
34
34
  focusedTaskId: string | null;
35
35
  isExporting: boolean;
36
36
  criticalPathTaskIds: string[];
37
+ gridScrollLeft: number;
38
+ gridColumns?: GanttColumn[];
39
+ private _editingColumnId;
40
+ private _editingValue;
41
+ private _isCommittingEdit;
37
42
  private _cachedMonthGridLines;
38
43
  private _cachedMonthGridStartTime;
39
44
  private _cachedMonthGridEndTime;
@@ -74,6 +79,12 @@ export declare class GanttRowElement extends LitElement {
74
79
  private handleToggleMouseLeave;
75
80
  private handleToggleCollapse;
76
81
  private handleToggleDblClick;
82
+ get editingColumnId(): string | null;
83
+ startCellEdit(columnId: string): boolean;
84
+ commitCellEdit(overrideValue?: any): boolean;
85
+ cancelCellEdit(): void;
86
+ private _handleEditorKeyDown;
87
+ private _renderCellEditor;
77
88
  protected updated(changedProperties: PropertyValues): void;
78
89
  render(): import("lit").TemplateResult<1>;
79
90
  }
@@ -0,0 +1,53 @@
1
+ import type { GanttColumn, GanttBuiltinColumnId, GanttColumnEditorType, GanttRow, GanttTask } from './types';
2
+ import type { MoguchartLocale } from './i18n';
3
+ /**
4
+ * 組み込みカラムのデフォルト仕様定義
5
+ */
6
+ export declare const DEFAULT_GRID_COLUMN_CONFIGS: Record<GanttBuiltinColumnId, {
7
+ width: number;
8
+ minWidth: number;
9
+ align: 'left' | 'center' | 'right';
10
+ isTreeColumn?: boolean;
11
+ }>;
12
+ /**
13
+ * 複数タスク(またはサマリータスク)の日程・期間・加重平均進捗率を計算する
14
+ */
15
+ export declare function calculateRowSummaryDates(tasks: GanttTask[]): {
16
+ start: Date | null;
17
+ end: Date | null;
18
+ durationDays: number;
19
+ durationMs: number;
20
+ progress: number | undefined;
21
+ };
22
+ /**
23
+ * カラム定義配列を正規化し、デフォルト値やロケール文字列を補完する
24
+ */
25
+ export declare function normalizeGridColumns(columns?: GanttColumn[], locale?: MoguchartLocale, isMonthMode?: boolean, isTimeMode?: boolean): GanttColumn[];
26
+ /**
27
+ * 指定されたカラムのセル生値を行およびタスク群から取得する
28
+ */
29
+ export declare function getGridCellValue(column: GanttColumn, row: GanttRow, tasks: GanttTask[], wbsCode?: string): any;
30
+ /**
31
+ * セル値をフォーマットして表示用文字列にする
32
+ */
33
+ export declare function formatGridCellValue(column: GanttColumn, value: any, row: GanttRow, tasks: GanttTask[], locale?: MoguchartLocale, isMonthMode?: boolean, isTimeMode?: boolean): string;
34
+ /**
35
+ * カラムと現在の表示モードから使用するエディタ種別を解決する
36
+ */
37
+ export declare function resolveColumnEditorType(column: GanttColumn, isMonthMode?: boolean, isTimeMode?: boolean): GanttColumnEditorType;
38
+ /**
39
+ * 指定されたセルがインライン編集可能かどうかを判定する
40
+ */
41
+ export declare function isGridCellEditable(column: GanttColumn, row: GanttRow, tasks: GanttTask[], hasChildren?: boolean, gridEditable?: boolean): boolean;
42
+ /**
43
+ * インライン編集用入力コントロールの初期値文字列を生成する
44
+ */
45
+ export declare function formatGridCellEditValue(column: GanttColumn, value: any, _row: GanttRow, tasks: GanttTask[], isMonthMode?: boolean, isTimeMode?: boolean): string;
46
+ /**
47
+ * セルの編集結果を行データ(および単一タスク)に反映する
48
+ */
49
+ export declare function applyGridCellEdit(column: GanttColumn, row: GanttRow, rawInputValue: any, isMonthMode?: boolean, isTimeMode?: boolean, wbsCode?: string): {
50
+ changed: boolean;
51
+ oldValue: any;
52
+ newValue: any;
53
+ };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * ガントチャートのUndo/Redo(操作履歴)管理
3
3
  */
4
- export type GanttCommandType = 'task-move' | 'task-resize' | 'task-progress' | 'task-delete' | 'row-reorder' | 'dependency-create' | 'dependency-delete' | 'custom';
4
+ export type GanttCommandType = 'task-move' | 'task-resize' | 'task-progress' | 'task-delete' | 'row-reorder' | 'dependency-create' | 'dependency-delete' | 'cell-edit' | 'custom';
5
5
  /**
6
6
  * ガントチャートに対する単一の編集操作を表すコマンドインターフェース
7
7
  */
@@ -51,6 +51,21 @@ export interface MoguchartLocale {
51
51
  /** 複数タスク移動中の表示 (例: "3件のタスクを移動中" / "Moving 3 tasks") */
52
52
  movingTasks: (count: number) => string;
53
53
  };
54
+ /** マルチカラムデータグリッドの文字列 */
55
+ grid?: {
56
+ columns: {
57
+ wbs: string;
58
+ name: string;
59
+ startDate: string;
60
+ endDate: string;
61
+ startMonth?: string;
62
+ endMonth?: string;
63
+ startDateTime?: string;
64
+ endDateTime?: string;
65
+ duration: string;
66
+ progress: string;
67
+ };
68
+ };
54
69
  }
55
70
  /**
56
71
  * 日本語ロケール (デフォルト)