@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 +45 -0
- package/CHANGELOG.md +45 -0
- package/README.ja.md +89 -0
- package/README.md +90 -2
- package/dist/components/gantt-calendar.d.ts +12 -1
- package/dist/components/gantt-chart.d.ts +23 -1
- package/dist/components/gantt-row.d.ts +12 -1
- package/dist/core/grid.d.ts +53 -0
- package/dist/core/history.d.ts +1 -1
- package/dist/core/i18n.d.ts +15 -0
- package/dist/core/types.d.ts +158 -0
- package/dist/index.d.ts +1 -0
- package/dist/moguchart-core.mjs +1319 -299
- package/dist/moguchart-core.umd.js +350 -66
- package/package.json +3 -3
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
|
-
|
|
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
|
|
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
|
+
};
|
package/dist/core/history.d.ts
CHANGED
|
@@ -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
|
*/
|
package/dist/core/i18n.d.ts
CHANGED
|
@@ -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
|
* 日本語ロケール (デフォルト)
|