#054 Display Timeline HTML Functional Class

## 正式Class

一般利用の正式HTML Functional Classは `bf-display-timeline` 1件です。

**タイムバーとShape Commentに別々のHTML Classは作りません。**
`bf-display-timeline` をTimeline本体へ付け、`data-timeline-items` の各Itemで
`displayType: "bar"` または `displayType: "shapeComment"` を指定します。

## 必須読み込み

#054 Runtimeは #125 BoneBlend 1.0.0を使用します。

```html
<link rel="stylesheet" href="/boneflow/css/bone-display-timeline.css">
<script src="/boneflow/js/bone-blend.js"></script>
<script src="/boneflow/js/bone-display-timeline.js"></script>
<script src="/boneflow/js/bone-display-timeline-functional-class.js"></script>
```

#040 ColorPickerは、Property画面で色を選ぶConsumer UI用です。固定色をHTML属性へ記述して表示するだけなら、#040は表示Runtimeの必須依存ではありません。

## `data-timeline-items` の書き方

`data-timeline-items` は **JSON配列** です。1件ごとに Bar / Shape Comment のItem Objectを入れます。

```html
<div class="bf-display-timeline"
     data-timeline-items='[
       {"id":"work","label":"勤務時間","displayType":"bar","start":"09:00","end":"18:00"},
       {"id":"meeting","label":"打ち合わせ","displayType":"shapeComment","start":"10:00","end":"10:30"}
     ]'></div>
```

HTML属性全体はシングルクォート `'...'`、JSONのキー/文字列はダブルクォート `"..."` にすると、そのままJSONとして解釈できます。

## Timeline本体 Property

| HTML属性 | JavaScript Property | 型 / 許容値 | 既定値 | 何を設定するか |
|---|---|---|---|---|
| `data-timeline-orientation` | `orientation` | `horizontal / vertical` | `horizontal` | Timelineの向き。正式サンプルは `horizontal`。`vertical` はRuntimeのorientation/Drag軸を縦方向として扱う設定。 |
| `data-timeline-start` | `start` | `HH:mm` | `09:00` | Timeline全体の開始時刻。Itemの `start` はこの時刻以上である必要があります。 |
| `data-timeline-end` | `end` | `HH:mm` | `18:00` | Timeline全体の終了時刻。開始より後で、Itemの `end` はこの時刻以下である必要があります。 |
| `data-timeline-step` | `step` | 5–240分 | `60` | 時間軸/Gridの目盛間隔。例 `60`=1時間ごと、`30`=30分ごと。 |
| `data-timeline-snap` | `snap` | 1–240分 | `15` | BarをDrag/Resizeしたときに吸着する分単位。例 `15`=09:07を操作すると15分刻みに丸める。 |
| `data-timeline-bar-height` | `barHeight` | 24–160px | `64` | 1行分のBar高さ。`stack`時は各自動行の高さにも使います。 |
| — | `rowGap` | 0–48px | `8` | `stack`で複数行になったときの行間。**現HTML Functional Classには `data-timeline-row-gap` はありません。** `create()` / `setOptions()` で設定します。 |
| `data-timeline-bar-layout` | `barLayout` | `overlap / stack` | `overlap` | `overlap`=全Barを同じ行に重ねる。`stack`=時間が重なるBarを自動で別行へ送る。 |
| `data-timeline-axis-mode` | `timeAxisMode` | `all / group-first / none` | `all` | `all`=時間軸ラベルを表示、`group-first`=`groupIndex=0` の行だけ表示、`none`=非表示。 |
| `data-timeline-group-index` | `groupIndex` | 0–9999 | `0` | `group-first`判定用。週報なら月曜=0、火曜=1…のように設定。0の行だけ時間軸を表示します。 |
| `data-timeline-snap-parent` | `snapToParent` | Boolean | `false` | `true`=#054自身の外枠/padding/角丸/背景を外し、親の幅へ直接FIT。`false`=#054自身の通常フレームを表示。 |
| `data-timeline-parent-height` | `parentHeight` | 0–2000px | `0` | `snapToParent=true`時の高さ。`0`=内容に合わせた自動高さ、`1以上`=親をそのpx高さへ固定し#054を100%で埋める。 |
| `data-timeline-grid` | `showGrid` | Boolean | `true` | `true`=時間目盛のGrid線を描画、`false`=Grid線を描画しない。 |
| `data-timeline-labels` | `showLabels` | Boolean | `true` | **現Runtimeでは時間軸ラベル表示の共通ゲートです。** `false`にすると時間軸ラベルを隠します。Bar内の `label` 文字そのものを消すPropertyではありません。 |
| `data-timeline-editable` | `editable` | Boolean | `true` | `true`=BarのDrag/ResizeとShape CommentのDragを有効、`false`=それらの編集操作を無効。選択/表示は残ります。 |
| `data-timeline-theme` | `theme` | `light / dark / neon` | `light` | #054本体のTheme。印刷用はLight/白背景を基準とします。 |
| `aria-label` | `ariaLabel` | 文字列(最大120文字) | `Display Timeline` | Timelineルートのアクセシビリティ名。 |
| `data-timeline-items` | `items` | JSON配列 | `[]` | Bar / Shape CommentのItem一覧。下記Item Propertyを使用します。 |

### Boolean (`true / false`) の読み方

- HTML属性では `"true"` / `"false"` を使います。
- `true` は機能をON、`false` は機能をOFFにします。
- `data-timeline-snap-parent`, `data-timeline-grid`, `data-timeline-labels`, `data-timeline-editable` は未指定時それぞれ上表の既定値になります。
- `false / 0 / off / no` はFunctional Classでfalseとして解釈されます。それ以外の属性値はtrueとして解釈されるため、ガイドでは明示的に `true / false` を推奨します。

## `kind` の選択肢

`kind` はItemの用途分類です。Barでは `bone-display-timeline__item--{kind}` Classになり、`backgroundColor` を省略したときの標準アクセント色に使われます。

| `kind` | 用途の目安 | Bar標準アクセント | 例 |
|---|---|---|---|
| `work` | 勤務・作業時間 | 淡い緑 | 勤務時間、作業時間 |
| `break` | 休憩・中断 | 淡い青 | 昼休憩、休憩時間 |
| `meeting` | 会議・打合せ | 黄 | 会議、打ち合わせ |
| `info` | 一般予定・情報 | 黄橙 | 飲み会、イベント |
| `warning` | 注意を強調したい予定 | 淡い赤 | 締切、要注意時間帯 |
| `neutral` | 特別な分類を付けない | 灰 | その他、未分類 |

未指定時は `neutral` です。`backgroundColor` を指定した場合はその背景色が優先されます。Shape Commentでは `kind` は分類値として保持されますが、現在の見た目は `backgroundColor / textColor` とComment Theme色で決まり、`kind` 別のComment色分けは行いません。

## タイムバー Item Property

Barを使う場合は `displayType: "bar"` を明示することを推奨します。Runtime上の既定値も `bar` です。

| Property | 型 | 必須 / 既定値 | 許容値・範囲 | true / false・値の意味 |
|---|---|---|---|---|
| `id` | string | 任意 / `item-N`自動生成 | `[A-Za-z0-9_.:-]` 1–80文字、重複不可 | API更新・選択で使う識別子。実使用では明示指定を推奨。 |
| `label` | string | **必須** | 1–120文字 | Bar中央へ表示する名称。短いBarでは複数行化して全文表示します。 |
| `kind` | enum | 任意 / `neutral` | `work / break / meeting / info / warning / neutral` | 上の `kind` 表を参照。背景色未指定時のBar標準色にも使用。 |
| `displayType` | enum | 任意 / `bar` | `bar / shapeComment` | `bar` ならタイムバー。`shapeComment` にするとCommentとして扱います。 |
| `start` | time | **必須** | Timelineの `start` 以上、`HH:mm` | Bar左端/開始時刻。 |
| `end` | time | **必須** | `start`より後、Timelineの `end` 以下、`HH:mm` | Bar右端/終了時刻。 |
| `backgroundColor` | color | 任意 / 空 | `#RGB` または `#RRGGBB` | Bar背景。省略時は `kind` / Theme由来の標準背景を使用。 |
| `textColor` | color | 任意 / 空 | `#RGB` または `#RRGGBB` | Bar文字色。省略時はTheme文字色を使用。 |
| `blendMode` | enum | 任意 / `normal` | `normal / multiply / screen / overlay / darken / lighten / difference / add` | #125 Blendで重なったBarの合成方法を指定。下表参照。 |
| `fullHeight` | Boolean | 任意 / `false` | `true / false` | `true`=full-height扱い + 前面優先(z-index 4)。`false`=通常Bar(z-index 2)。**現在は両方とも高さ自体は `barHeight` を使用**します。 |
| `disabled` | Boolean | 任意 / `false` | `true / false` | Barでは `true`=Drag/Resize無効 + 半透明表示、`false`= `editable=true` のときDrag/Resize可。クリック選択は残ります。 |

### `blendMode` の意味

| 値 | 意味 |
|---|---|
| `normal` | 通常表示。合成なし。 |
| `multiply` | 重なりを暗く合成。勤務Bar上へ休憩Barを重ねる例など。 |
| `screen` | 重なりを明るく合成。 |
| `overlay` | 明暗差を強める合成。 |
| `darken` | 重なり部分で暗い側を優先。 |
| `lighten` | 重なり部分で明るい側を優先。 |
| `difference` | 色差を強調。重なり位置の確認向け。 |
| `add` | 加算系。#125側でCSS `plus-lighter` 相当へ変換。 |

### タイムバー最小サンプル

```html
<div class="bf-display-timeline"
     data-timeline-start="09:00"
     data-timeline-end="18:00"
     data-timeline-theme="light"
     data-timeline-items='[
       {
         "id":"work",
         "label":"勤務時間",
         "kind":"work",
         "displayType":"bar",
         "start":"09:00",
         "end":"18:00",
         "backgroundColor":"#d9e5cf",
         "textColor":"#102030",
         "blendMode":"normal",
         "fullHeight":true,
         "disabled":false
       }
     ]'></div>
```

この例の `fullHeight:true` は前面優先、`disabled:false` は `editable=true` の場合にDrag/Resize可能という意味です。

## Shape Comment Item Property

`displayType: "shapeComment"` を指定します。`start` がLeader線のAnchor時刻、`end` がCommentの終了時刻です。

| Property | 型 | 必須 / 既定値 | 許容値・範囲 | 値の意味 |
|---|---|---|---|---|
| `id` | string | 任意 / `item-N`自動生成 | Barと同じ | API更新・選択用識別子。明示指定推奨。 |
| `label` | string | **必須** | 1–120文字 | Item名称。`commentText`省略時の本文にも使います。 |
| `kind` | enum | 任意 / `neutral` | `work / break / meeting / info / warning / neutral` | 分類値として保持。現RuntimeのShape Comment見た目は `kind` ではなく色Propertyで決まります。 |
| `displayType` | enum | **`shapeComment`を指定** | `bar / shapeComment` | Shape Commentとして描画するスイッチ。省略すると既定値 `bar` になるため、Commentでは必ず明示します。 |
| `start` | time | **必須** | Timeline範囲内 `HH:mm` | Comment開始時刻かつLeader線Anchor位置。 |
| `end` | time | **必須** | `start`より後、Timeline範囲内 `HH:mm` | Comment終了時刻。Comment枠へ `start–end` を表示。 |
| `commentText` | string | 任意 / `label` | 1–240文字 | Comment枠に表示する本文。空の場合は `label` を使用。 |
| `commentPosition` | enum | 任意 / `bottom` | `top / bottom / left / right` | Anchorに対する初期配置。`top`=上、`bottom`=下、`left/right`=左右へずらす。 |
| `commentOffsetX` | number | 任意 / `0` | -1000～1000 | 初期位置からの横移動量(px)。実描画時はTrack内へ収まるようClampされます。 |
| `commentOffsetY` | number | 任意 / `0` | -1000～1000 | 初期位置からの縦移動量(px)。実描画時はTrack内へ収まるようClampされます。 |
| `commentWidth` | number | 任意 / `96` | 72–240px | Comment枠の幅。 |
| `backgroundColor` | color | 任意 / 空 | `#RGB` または `#RRGGBB` | Comment背景。省略時はThemeのComment背景色。 |
| `textColor` | color | 任意 / 空 | `#RGB` または `#RRGGBB` | Comment文字色。省略時はThemeのComment文字色。 |
| `blendMode` | enum | 任意 / `normal` | Barと同じ8種 | 契約上保持されますが、**現在の#125 Blend実描画はBarに適用され、Shape Commentの見た目にはblendを適用しません。** |
| `disabled` | Boolean | 任意 / `false` | `true / false` | 値は保持されます。**現RuntimeのShape Comment Drag停止はItem `disabled` ではなくTimeline全体の `editable:false` を使用します。** |

### Shape Comment最小サンプル

```html
<div class="bf-display-timeline"
     data-timeline-start="09:00"
     data-timeline-end="18:00"
     data-timeline-editable="true"
     data-timeline-theme="light"
     data-timeline-items='[
       {
         "id":"meeting",
         "label":"打ち合わせ",
         "kind":"meeting",
         "displayType":"shapeComment",
         "start":"10:00",
         "end":"10:30",
         "commentText":"打ち合わせ",
         "commentPosition":"bottom",
         "commentOffsetX":0,
         "commentOffsetY":0,
         "commentWidth":96,
         "backgroundColor":"#ffe500",
         "textColor":"#101010"
       }
     ]'></div>
```

## 実使用サンプル: 勤務時間 + 休憩 + 打ち合わせ + 飲み会

```html
<div id="schedule"
     class="bf-display-timeline"
     data-timeline-start="09:00"
     data-timeline-end="21:00"
     data-timeline-step="60"
     data-timeline-snap="15"
     data-timeline-bar-height="64"
     data-timeline-bar-layout="overlap"
     data-timeline-grid="true"
     data-timeline-labels="true"
     data-timeline-editable="true"
     data-timeline-theme="light"
     data-timeline-items='[
       {"id":"work","label":"勤務時間","kind":"work","displayType":"bar","start":"09:00","end":"18:00","backgroundColor":"#d9e5cf","textColor":"#102030","blendMode":"normal","fullHeight":true,"disabled":false},
       {"id":"break","label":"休憩時間","kind":"break","displayType":"bar","start":"12:00","end":"13:00","backgroundColor":"#d8e6f2","textColor":"#102030","blendMode":"multiply","fullHeight":false,"disabled":false},
       {"id":"meeting","label":"打ち合わせ","kind":"meeting","displayType":"shapeComment","start":"10:00","end":"10:30","commentText":"打ち合わせ","commentPosition":"bottom","commentOffsetX":0,"commentOffsetY":0,"commentWidth":96,"backgroundColor":"#ffe500","textColor":"#101010"},
       {"id":"party","label":"飲み会","kind":"info","displayType":"bar","start":"19:00","end":"21:00","backgroundColor":"#f2bd5d","textColor":"#102030","blendMode":"overlay","fullHeight":false,"disabled":false}
     ]'></div>
```

## JavaScriptでPropertyを設定する例

```html
<div id="schedule-js"></div>
<script>
const root = document.getElementById("schedule-js");

BoneDisplayTimeline.create(root, {
  orientation: "horizontal",
  start: "09:00",
  end: "21:00",
  step: 60,
  snap: 15,
  barHeight: 64,
  rowGap: 8,
  barLayout: "overlap",
  timeAxisMode: "all",
  groupIndex: 0,
  snapToParent: false,
  parentHeight: 0,
  showGrid: true,
  showLabels: true,
  editable: true,
  theme: "light",
  ariaLabel: "勤務予定"
}, [
  {
    id: "work",
    label: "勤務時間",
    kind: "work",
    displayType: "bar",
    start: "09:00",
    end: "18:00",
    backgroundColor: "#d9e5cf",
    textColor: "#102030",
    blendMode: "normal",
    fullHeight: true,
    disabled: false
  },
  {
    id: "meeting",
    label: "打ち合わせ",
    kind: "meeting",
    displayType: "shapeComment",
    start: "10:00",
    end: "10:30",
    commentText: "打ち合わせ",
    commentPosition: "bottom",
    commentOffsetX: 0,
    commentOffsetY: 0,
    commentWidth: 96,
    backgroundColor: "#ffe500",
    textColor: "#101010"
  }
]);
</script>
```

## HTML Functional Classから更新する例

```js
const root = document.querySelector("#schedule");

BoneDisplayTimelineFunctionalClass.setItems(root, [
  {
    id: "work",
    label: "勤務時間",
    kind: "work",
    displayType: "bar",
    start: "09:00",
    end: "17:30",
    backgroundColor: "#d9e5cf",
    textColor: "#102030",
    blendMode: "normal",
    fullHeight: false,
    disabled: false
  }
]);

BoneDisplayTimelineFunctionalClass.setOptions(root, {
  theme: "dark",
  barLayout: "stack",
  showGrid: true,
  editable: false
});
```

`editable:false` にするとBar Drag/ResizeとShape Comment Dragをまとめて停止します。

## 週報 / 月報で使う例

1行ごとに `bf-display-timeline` を配置し、最初の行だけ `data-timeline-group-index="0"`、2行目以降を `1,2...` にします。
`data-timeline-axis-mode="group-first"` を指定すると、時間ラベルはグループの一番上だけに表示されます。

```html
<div class="report-row">
  <div class="day">月</div>
  <div class="bf-display-timeline"
       data-timeline-axis-mode="group-first"
       data-timeline-group-index="0"
       data-timeline-start="09:00"
       data-timeline-end="21:00"
       data-timeline-items='[{"id":"mon-work","label":"勤務時間","kind":"work","displayType":"bar","start":"09:00","end":"18:00"}]'></div>
</div>
<div class="report-row">
  <div class="day">火</div>
  <div class="bf-display-timeline"
       data-timeline-axis-mode="group-first"
       data-timeline-group-index="1"
       data-timeline-start="09:00"
       data-timeline-end="21:00"
       data-timeline-items='[{"id":"tue-work","label":"勤務時間","kind":"work","displayType":"bar","start":"09:00","end":"18:00"}]'></div>
</div>
```

## 実行サンプルURL

Installer適用後: `http://localhost/boneflow/sample/054/`


## Runtime Property Schema API

#054はConsumerがProperty名を再定義しなくてよいように、Runtimeから正式Property Schemaを公開します。

```js
const schema = BoneDisplayTimeline.getPropertySchema();
const defaults = BoneDisplayTimeline.getPropertyDefaults();
const timeAxis = BoneDisplayTimeline.getPropertyDefinition("timeAxisMode");
```

`timeAxisMode` が正式な「時間ラベル表示」Propertyです。値は `all / group-first / none`。`showLabels` は既存互換の共通ゲートで、通常の表示選択には `timeAxisMode` を使用します。Bar内のItem `label` とは別責務です。

#048 TableなどのConsumerは、#054のPropertyを独自にハードコードせず `getPropertySchema()` を参照します。これにより#054のProperty追加・修正をConsumer側で再定義する事故を防ぎます。


### 縦表示 (orientation: vertical) / v1.0.27
- 時間は上から下へ進みます。時間目盛は左側、Gridは横線、バーは時間に応じた縦長の矩形です。
- barLayout=stack は複数の縦レーンを左右へ配置します。Drag/ResizeはY軸で動作します。
- orientation=horizontal は従来どおり横向きです。

## #048 Table を使う縦複数列Preview (v1.0.34)
縦表示では #048 Table の正式 `bf-table` / `data-table-columns` / `data-table-rows` を使用。列幅140px、7列（初期値）を #054 テスト画面で変更可能です。各列の `cellElement.renderer` に `054` を指定し、既設の `BoneTableHTMLClass.mount` および #048公式Cell Rendererを通じて #054 Runtimeを生成します。必要ファイルは `bone-table.js`, `bone-table-functional-class.js`, `bone-table.css`（#048 Frozen正本を参照し上書き禁止）。設定範囲：列数1〜31、列幅100〜480px。


### v1.0.34 縦表示／#048 Table 列幅仕様
縦表示の「タイムバー表示幅」は #054 の表示領域だけの幅です（既定140px）。列数既定7列。「グループ先頭だけ表示」は最左列にのみ時間軸ラベルを設け、その列幅にはラベル62pxを追加します。2列目以降の列幅は指定表示幅そのままです。例：7列・140px・先頭のみ表示では 202px + 140px × 6 = 1042px。表示しない場合は140px × 7 = 980px。各Timelineに表示する場合は202px × 7 = 1414px。#048 正式Runtimeは変更しません。


## 縦表示（v1.0.34）

縦表示では `displayType: "shapeComment"` をシェイプ吹き出しではなくタイムバーとして描画します。元データの `displayType` は保持するため、横表示では従来のシェイプコメントが使えます。縦表示ではタイムバーが #048 Table の各列のタイムバー領域幅に一致します。各 Item の `verticalCommentPosition` は `top-left`（既定・左上）、`center`（中央）、`bottom`（下）から選択し、文字はタイムバー内に表示します。


### タイムバー重なり（v1.0.34）

既定は `barLayout: "overlap"`（重ねて表示）。縦では `left` / `right`、横では `top` / `bottom` を使用します。重複するバーは **同じ時間軸／同じ#048 Tableセル内** で左右または上下に配置し、行を増やしません。過去の `stack` 入力は縦なら `left`、横なら `top` に移行します。設定画面から「自動で別行」は削除しました。


## v1.0.34 変更：項目別の重なり／時間ラベルの初期値
時間ラベルの初期値は縦横とも `group-first`（グループ先頭だけ表示）。縦表示では左端列だけに62pxを追加します。#048 Tableの設定列幅（既定140px）をタイムバー全体に使用し、重なるバーでも幅を縮小しません。各Itemの `verticalOverlap` は `overlap`／`left`／`right`、`horizontalOverlap` は `overlap`／`top`／`bottom`。左右上下の指定はそのItemの前面表示（z-index）を意味し、列幅を分割しません。旧 `barLayout` は互換入力として扱います。


## v1.0.34 重なり時の吸着（#054独自）

通常のタイムバーは、縦では#048 Tableの設定列幅いっぱい、横では設定バー高さ全体を使います。
重なり指定は各Itemの `verticalOverlap` (`overlap`/`left`/`right`) と `horizontalOverlap` (`overlap`/`top`/`bottom`) で設定します。
縦の `left` / `right` は対象バーのみ**幅50%**にして、左端／右端へ吸着・最前面に配置します。
横の `top` / `bottom` は対象バーのみ**高さ50%**にして、上端／下端へ吸着・最前面に配置します。
指定のない背面バーは全幅・全高を保持し、追加行は作りません。
右端吸着したバーの右辺は列内Timeline表示領域の右辺に揃います。
※ 方向の指定は従来の `z-index` 変更だけではなく実際のDOM座標を変更します。


### v1.0.36 — 縦表示の文字収まり・親要素吸着・別画面Preview
- `verticalTextFitMode`（HTML: `data-timeline-text-fit`）：`shrink` 初期値 / `expand-column`。縦向きで短時間バーを左右吸着した場合も、バー実測幅・高さと文字の実測長からフォントを12pxから必要サイズへ縮小（下限7px）。内容が下限でも入り切らない極端な短時間・長文では、`title` の全文Tooltipで参照可能。
- `expand-column` はConsumer側の#048 Table列幅を拡張する方式。今回の正式Previewではサンプルデータを置く左端列だけ自動拡張し、他列は既定幅140pxを保つ。設定幅最大480px。#048 Runtime/Frozenは変更しない。
- 本体Property画面のPreview枠は右下ドラッグの `resize: both` で変更可能。吸着ONのときPreview親の高さに追従（時間目盛が読める最低高さ624pxまではスクロール）。縦7列の幅は保持し、狭くしても列を押しつぶさず横スクロールを表示。
- `別画面で表示` は `/boneflow/test/bone-display-timeline-preview.html` にPreview専用ウィンドウを開き、同一Origin内でProperty変更を反映。別画面自身に再「別画面」ボタンや開発ログは付けない。ウィンドウを縮小してもタイムバーの幅と時間軸を維持しスクロールで表示。

### v1.0.38 compatibility
- Time-axis labels use `step`; grid minor lines use `snap`, with actual clock hours rendered as major lines.
- #040 Caller is an external prerequisite of the official test UI, not a change to the `bf-display-timeline` HTML class.


## v1.0.39 #026 TimePicker consumer integration

The #054 test UI uses the independently installed #026 `bf-timepicker` HTML Functional Class for Timeline and Item start/end inputs. It listens for `bone-timepicker:select`, commits the value in the #054 consumer, and redraws. #026 Runtime and Functional Class are not distributed or edited by this package.
