# 画面設計書 19-メトリクスチャート

## 概要

本ドキュメントは、Apache Flink Web Dashboardの「メトリクスチャート」画面の設計仕様を記載したものである。選択した頂点（オペレーター）のメトリクスをチャート形式で時系列表示する画面。

### 本画面の処理概要

メトリクスチャート画面は、DAGグラフで選択された頂点（オペレーター）の利用可能なメトリクスをユーザーが選択し、時系列チャートとして可視化する画面である。複数のメトリクスを同時に選択でき、リアルタイムで値の推移を監視できる。

**業務上の目的・背景**：Apache Flinkのストリーム処理では、スループット、レイテンシ、バッファ使用率などの多様なメトリクスが収集される。これらのメトリクスを時系列チャートで可視化することで、運用担当者はオペレーターのパフォーマンス特性を把握し、ボトルネックの特定やキャパシティプランニングに活用できる。特にリアルタイムで値の変化を監視することで、異常の早期検知が可能になる。

**画面へのアクセス方法**：ジョブ詳細画面のOverviewタブでDAGグラフ上の頂点をクリックし、頂点詳細ドロワーが開いた後、「Metrics」タブを選択することでアクセスする。

**主要な操作・処理内容**：
1. 画面表示時に利用可能なメトリクス名一覧を取得
2. ユーザーがセレクトボックスからメトリクスを選択
3. 選択されたメトリクスの値を定期的に取得
4. JobChartComponentでチャートを描画・更新
5. チャートを閉じることでメトリクスの監視を停止

**画面遷移**：
- 遷移元：頂点詳細ドロワー（タブナビゲーション経由）
- 遷移先：なし（参照専用画面）

**権限による表示制御**：特になし。認証されたユーザーであれば閲覧可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | REST API | 主機能 | 頂点メトリクスの取得（/jobs/{jobid}/vertices/{vertexid}/metrics API） |
| 57 | メトリクスコア | 補助機能 | メトリクスのチャート描画・時系列表示 |

## 画面種別

チャート表示（参照専用）

## URL/ルーティング

- パス: `/job/running/:jid/overview/:vertexId/metrics` または `/job/completed/:jid/overview/:vertexId/metrics`
- ルートパラメータ:
  - `jid` - ジョブID
  - `vertexId` - 頂点（オペレーター）ID

## 入出力項目

### 入力項目

| 項目名 | 項目ID | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| 選択メトリクス | listOfSelectedMetric | string[] | 任意 | ユーザーが選択したメトリクス名のリスト |

### 出力項目（API取得）

| 項目名 | 項目ID | 型 | 説明 |
|--------|--------|-----|------|
| 利用可能メトリクス一覧 | listOfMetricName | string[] | 選択可能なメトリクス名の配列 |
| メトリクス値 | MetricMapWithTimestamp | object | タイムスタンプ付きのメトリクス値マップ |

## 表示項目

### メトリクスセレクター

| 表示項目 | 説明 |
|----------|------|
| No Available Metric | メトリクスが存在しない場合の表示 |
| Add Metric セレクトボックス | 未選択のメトリクスから選択するドロップダウン |

### メトリクスチャートエリア

| 表示項目 | 説明 |
|----------|------|
| JobChartComponent | 各選択メトリクスのチャートコンポーネント |

## イベント仕様

### 1-画面初期化（頂点変更時）

**トリガー**: コンポーネント初期化または頂点IDが変更された時

**処理フロー**:
1. JobLocalService.jobWithVertexChanges()を購読
2. distinctUntilChangedで頂点IDの変更を検出
3. loadMetricList(jobId, vertexId)を呼び出し
4. MetricsService.loadAllAvailableMetrics()で利用可能なメトリクス一覧を取得
5. JobLocalService.metricsCacheMapから以前の選択状態を復元
6. updateUnselectedMetricList()で未選択メトリクスリストを更新

### 2-メトリクス値の定期取得

**トリガー**: ジョブ・頂点変更イベント（選択メトリクスが存在する場合）

**処理フロー**:
1. JobLocalService.jobWithVertexChanges()を購読
2. listOfSelectedMetricが1件以上の場合、MetricsService.loadMetrics()を呼び出し
3. 取得した値をlistOfJobChartComponent.forEach()で各チャートに反映
4. chart.refresh(res)でチャートを更新

### 3-メトリクス追加

**トリガー**: セレクトボックスでメトリクスを選択した時

**処理フロー**:
1. updateMetric(metric)が呼び出される
2. listOfSelectedMetricにメトリクス名を追加
3. JobLocalService.metricsCacheMapに選択状態を保存
4. updateUnselectedMetricList()で未選択リストを更新

### 4-メトリクス削除（チャートクローズ）

**トリガー**: チャートコンポーネントのクローズボタンクリック

**処理フロー**:
1. closeMetric(metric)が呼び出される
2. listOfSelectedMetricからメトリクス名を除外
3. JobLocalService.metricsCacheMapに選択状態を保存
4. updateUnselectedMetricList()で未選択リストを更新

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | - | SELECT | REST API経由でメトリクス情報を取得 |

本画面は参照専用であり、データベースへの更新処理は発生しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| - | - | No Available Metric | 利用可能なメトリクスが存在しない場合 |

## 例外処理

| 例外状況 | 対応 | 表示 |
|---------|------|------|
| メトリクス一覧が空 | 空配列をセット | 「No Available Metric」表示 |

## 備考

- 選択状態はJobLocalService.metricsCacheMapでキャッシュされ、頂点を再選択した際に復元される
- キャッシュキーは「jobId/vertexId」形式
- @ViewChildrenでJobChartComponentのQueryListを取得し、全チャートを一括更新
- ng-zorro-antdのNzSelectModuleを使用したドロップダウン選択
- メトリクスは定期的（ポーリング）に取得され、チャートがリアルタイム更新される

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、メトリクス情報のデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | job-metrics.ts | `flink-runtime-web/web-dashboard/src/app/interfaces/job-metrics.ts` | JobMetric, MetricMap, MetricMapWithTimestampインターフェースの構造 |

**読解のコツ**: JobMetricは{id, value}の形式。MetricMapWithTimestampは{timestamp, values: MetricMap}の形式でチャート描画に使用される。

#### Step 2: エントリーポイントを理解する

処理の起点となるコンポーネントファイルを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | job-overview-drawer-chart.component.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/chart/job-overview-drawer-chart.component.ts` | 状態管理、メトリクスの選択/削除、チャート更新フロー |

**主要処理フロー**:
1. **53行目**: @ViewChildrenでJobChartComponentのリストを取得
2. **63-88行目**: ngOnInit()で頂点変更を監視し、メトリクス一覧を取得・チャートを更新
3. **95-103行目**: loadMetricList()で利用可能なメトリクス一覧を取得、キャッシュから選択状態を復元
4. **105-109行目**: updateMetric()でメトリクスを追加
5. **111-115行目**: closeMetric()でメトリクスを削除

#### Step 3: サービス層を理解する

API呼び出しを行うサービスクラスを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | metrics.service.ts | `flink-runtime-web/web-dashboard/src/app/services/metrics.service.ts` | loadAllAvailableMetrics()とloadMetrics()メソッドの実装 |

**主要処理フロー**:
- **40-58行目**: loadAllAvailableMetrics()が利用可能なメトリクス名一覧を取得
- **60-78行目**: loadMetrics()が指定メトリクスの値をタイムスタンプ付きで取得

### プログラム呼び出し階層図

```
JobOverviewDrawerChartComponent.ngOnInit()
    │
    ├─ jobWithVertexChanges() [distinctUntilChanged]
    │      └─ loadMetricList(jobId, vertexId)
    │             └─ MetricsService.loadAllAvailableMetrics()
    │                    └─ HttpClient.get(`/jobs/${jid}/vertices/${vid}/metrics`)
    │
    └─ jobWithVertexChanges() [filter: selectedMetric.length > 0]
           └─ MetricsService.loadMetrics(jid, vid, selectedMetrics)
                  └─ HttpClient.get(`/jobs/${jid}/vertices/${vid}/metrics`, {get: metrics})
                         │
                         ▼
                  listOfJobChartComponent.forEach(chart => chart.refresh(res))
```

### データフロー図

```
[入力]               [処理]                         [出力]

JobWithVertex ───▶ loadAllAvailableMetrics() ───▶ listOfMetricName
                          │
                          ▼
                   メトリクス名一覧
                          │
                          ▼
ユーザー選択 ───▶ updateMetric() ───▶ listOfSelectedMetric
                          │
                          ▼
定期ポーリング ───▶ loadMetrics() ───▶ MetricMapWithTimestamp
                          │
                          ▼
                   JobChartComponent.refresh()
                          │
                          ▼
                   チャート描画更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| job-overview-drawer-chart.component.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/chart/job-overview-drawer-chart.component.ts` | ソース | メインコンポーネント |
| job-overview-drawer-chart.component.html | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/chart/job-overview-drawer-chart.component.html` | テンプレート | 画面レイアウト定義 |
| job-overview-drawer-chart.component.less | `flink-runtime-web/web-dashboard/src/app/pages/job/overview/chart/job-overview-drawer-chart.component.less` | スタイル | スタイル定義 |
| job-chart.component.ts | `flink-runtime-web/web-dashboard/src/app/components/job-chart/job-chart.component.ts` | 共通コンポーネント | チャート描画 |
| metrics.service.ts | `flink-runtime-web/web-dashboard/src/app/services/metrics.service.ts` | サービス | メトリクスAPI呼び出し |
| job-local.service.ts | `flink-runtime-web/web-dashboard/src/app/pages/job/job-local.service.ts` | サービス | ジョブ・頂点状態管理、メトリクスキャッシュ |
