# 機能設計書 81-ヒストグラム

## 概要

本ドキュメントは、Nushellのヒストグラム（histogram）コマンドの機能設計について記述する。このコマンドは、データの出現頻度を視覚的に表現するヒストグラム（度数分布表）を生成する。

### 本機能の処理概要

histogramコマンドは、リストまたはテーブルデータの特定カラムの値を分析し、各値の出現回数（度数）をカウントして、アスタリスク（*）を使用した視覚的なバーチャートとともにテーブル形式で出力する機能を提供する。

**業務上の目的・背景**：データ分析において、値の分布を素早く把握することは重要である。ヒストグラムはデータの偏りや傾向を視覚的に理解するための基本的なツールであり、ファイルタイプの分布、数値データの傾向分析、カテゴリデータの集計などに活用される。シェル環境でこのような分析機能を提供することで、外部ツールを使用せずにデータの傾向を即座に把握できる。

**機能の利用シーン**：ファイルシステムの分析（ファイルタイプ別の個数確認）、ログデータの解析（エラーコード別の発生頻度）、数値データの分布確認、カテゴリデータの集計など、頻度分析が必要なあらゆる場面で利用される。

**主要な処理内容**：
1. 入力データ（リストまたはテーブル）の受け取り
2. 対象カラムの値をハッシュ可能な値に変換
3. 各値の出現回数をカウント（HashMapを使用）
4. パーセンテージ計算（normalize/relative方式）
5. 視覚的なバーチャート（アスタリスク）の生成
6. 出現回数順にソートしたテーブルの出力

**関連システム・外部連携**：なし（スタンドアロン機能）

**権限による制御**：なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIコマンドとして実行 |

## 機能種別

計算処理 / データ変換 / 可視化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| column-name | String | No | 頻度計算対象のカラム名（テーブル入力時に使用） | 存在しないカラムの場合はエラー |
| frequency-column-name | String | No | 出力のヒストグラム列の名前（デフォルト: frequency） | value, count, quantile, percentageは使用不可 |
| --percentage-type (-t) | String | No | パーセンテージ計算方式（normalize/relative） | normalize/relative以外はエラー |

### 入力データソース

- パイプライン入力（リスト型またはテーブル型）
- リスト入力時は各要素がハッシュ可能である必要がある
- テーブル入力時は指定カラムの値がハッシュ可能である必要がある

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| value（またはカラム名） | Any | 集計対象の値 |
| count | Int | 出現回数 |
| quantile | Float | 割合（0.0-1.0） |
| percentage | String | パーセンテージ文字列（例: "66.67%"） |
| frequency（またはカスタム名） | String | アスタリスクによるバーチャート |

### 出力先

標準出力（パイプライン出力）

## 処理フロー

### 処理シーケンス

```
1. 入力パラメータの解析
   └─ column-name, frequency-column-name, percentage-typeの取得
2. 入力データの変換
   └─ リスト/テーブルデータをHashableValueのベクタに変換
3. 度数カウント
   └─ HashMapを使用して各値の出現回数をカウント
4. 最大値・合計値の算出
   └─ percentage-typeに応じた基準値の決定
5. 結果テーブルの生成
   └─ quantile, percentage, frequencyバーの計算
6. ソートして出力
   └─ 出現回数の降順でソート
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{column-name指定?}
    B -->|Yes| C[テーブルから指定カラムの値を抽出]
    B -->|No| D[リストの各要素を取得]
    C --> E[HashableValueに変換]
    D --> E
    E --> F[HashMapで度数カウント]
    F --> G{percentage-type}
    G -->|normalize| H[合計値で割る]
    G -->|relative| I[最大値で割る]
    H --> J[バーチャート生成]
    I --> J
    J --> K[降順ソート]
    K --> L[テーブル出力]
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | ハッシュ可能性 | 集計対象の値はハッシュ可能である必要がある | 常時 |
| BR-81-02 | 禁止カラム名 | frequency-column-nameにvalue/count/quantile/percentageは使用不可 | frequency-column-name指定時 |
| BR-81-03 | パーセンテージ計算 | normalizeは合計比、relativeは最大値比 | 常時 |

### 計算ロジック

**normalize方式**: `quantile = count / total_count`
**relative方式**: `quantile = count / max_count`
**frequencyバー**: `"*".repeat((100.0 * quantile).floor() as usize)`

## データベース操作仕様

該当なし（メモリ内計算のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeMismatch | 型不一致 | 禁止されたカラム名を指定 | 別のカラム名を使用 |
| TypeMismatch | 型不一致 | 不正なpercentage-type値 | normalize/relativeを指定 |
| UnsupportedInput | 非対応入力 | ハッシュ不可能な値 | ハッシュ可能な値に変換 |
| CantFindColumn | カラム未検出 | 指定カラムが存在しない | 正しいカラム名を指定 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし（純粋関数的処理）

## パフォーマンス要件

- 入力データサイズに対してO(n)の時間計算量
- メモリ使用量は一意の値の数に比例

## セキュリティ考慮事項

特になし

## 備考

- itertools crateを使用してソート処理を実装
- HashableValueはhashable_value.rsで定義される内部型

---

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

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

### 推奨読解順序

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

ヒストグラム機能は、入力値をハッシュ可能な形式に変換して集計する。まずその変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | hashable_value.rs | `crates/nu-command/src/charting/hashable_value.rs` | HashableValue構造体の定義と、各種Value型からの変換ロジック |

**読解のコツ**: HashableValueは、RustのHashMapのキーとして使用するために、Valueをハッシュ可能な形式にラップする。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | histogram.rs | `crates/nu-command/src/charting/histogram.rs` | Histogramコマンドの実装全体 |

**主要処理フロー**:
1. **15-44行目**: Commandトレイトの実装とシグネチャ定義
2. **46-49行目**: コマンドの説明
3. **92-153行目**: runメソッドでの入力パラメータ解析とrun_histogram呼び出し
4. **156-234行目**: run_histogram関数での入力値変換とバリデーション
5. **236-283行目**: histogram_impl関数での実際の集計・バーチャート生成処理

#### Step 3: 集計ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | histogram.rs | `crates/nu-command/src/charting/histogram.rs` | histogram_impl関数の詳細 |

**主要処理フロー**:
- **245-254行目**: HashMapを使用した度数カウント
- **257行目**: MAX_FREQ_COUNT定数（バーの最大長100）
- **258-280行目**: ソート済みイテレータでの結果テーブル生成
- **281-282行目**: 出現回数での降順ソートとPipelineData変換

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

```
Histogram::run()
    │
    ├─ call.opt() / call.get_flag()
    │      └─ パラメータ解析
    │
    ├─ input.into_value()
    │      └─ パイプライン入力をValue化
    │
    └─ run_histogram()
           │
           ├─ HashableValue::from_value()
           │      └─ 各値をハッシュ可能に変換
           │
           └─ histogram_impl()
                  │
                  ├─ HashMap::insert()
                  │      └─ 度数カウント
                  │
                  └─ Value::record()
                         └─ 結果レコード生成
```

### データフロー図

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

リスト/テーブル ───▶ HashableValue変換 ───▶ 度数カウント ───▶ テーブル
  [1,2,1]              HashMap                  {1:2, 2:1}        value|count|quantile|percentage|frequency
                                                                    1  |  2  |  0.67  |  66.67%  | ****...
                                                                    2  |  1  |  0.33  |  33.33%  | ***...
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| histogram.rs | `crates/nu-command/src/charting/histogram.rs` | ソース | histogramコマンドの主実装 |
| hashable_value.rs | `crates/nu-command/src/charting/hashable_value.rs` | ソース | ハッシュ可能な値型の定義 |
| mod.rs | `crates/nu-command/src/charting/mod.rs` | ソース | chartingモジュールのエクスポート |
