• #Nuxt
  • #Vue
  • #UI実装
  • #ライフプラン
  • #ウォーターフォールチャート
開発misc-devメモ

Nuxt 4で人生計画シミュレーターのUIを実装する

Excelで作成していた人生計画シミュレーターをWebアプリに移植した。今回はUIコンポーネントをハードコードで実装し、後からロジックを接続する方針で進めた。

完成したUI構成

ミラーカラム(3段階ナビゲーション)

macOS Finderのミラーカラム形式を採用した。

┌─────────────┬────────────────┬────────────────┬───────────────────────┐
│ 大カテゴリ  │ 中カテゴリ     │ 小カテゴリ     │ プレビュー            │
│             │                │                │                       │
│ ▶ サマリー  │ (なし)         │ (なし)         │ サラリーマンの生涯年収 │
│   年次収支  │ ▶ まとめ       │ (なし)         │ テーブル表示          │
│   収入詳細  │   フロー詳細   │                │                       │
│             │   資産形成     │                │                       │
└─────────────┴────────────────┴────────────────┴───────────────────────┘

特徴:

  • 矢印キーでタブ内の全項目を順繰りに移動可能
  • ナビバーにパス形式でタイトルを表示(例:「表示 > サマリー | サラリーマンの生涯年収」)
  • クエリパラメータで表示状態をURLに反映

サマリー画面(段階損益形式)

当初はカード3枚(本人・配偶者・世帯合計)で表示していたが、Excelのようなマトリックス形式に変更した。

┌───────────────────────────────────────────────────────────────────────┐
│ サラリーマンの生涯年収                                               │
├───────────────────────────────────────────────────────────────────────┤
│ ウォーターフォールチャート                                           │
│ [生涯年収] → [-社会保障費] → [手取り] → [-生活費] → [-教育費] → [可処分所得] │
├─────────────┬─────────┬─────────┬─────────┬─────────┬─────────┬───────┤
│ 項目        │ 夫(48)  │ 妻(48)  │ 子供1   │ 子供2   │ 子供3   │ 合計  │
├─────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼───────┤
│ 生涯年収    │ 2.9億   │ 0.7億   │ -       │ -       │ -       │ 3.7億 │
│ 社会保障費  │ ▲0.6億  │ ▲0.1億  │ -       │ -       │ -       │▲0.8億 │
│ 手取り合計  │ 2.2億   │ 0.5億   │ -       │ -       │ -       │ 2.8億 │
│ 居住費・生活費│▲1.4億  │ -       │ -       │ -       │ -       │▲1.4億 │
│ 教育費      │ -       │ -       │▲1420万 │▲1420万 │▲1420万 │▲4263万│
│ 可処分所得  │ -       │ -       │ -       │ -       │ -       │ 1.0億 │
└─────────────┴─────────┴─────────┴─────────┴─────────┴─────────┴───────┘

ポイント:

  • 段階損益として手取り合計、生活費控除後が明確に表示される
  • ヘッダーに「夫(48)」のように現在年齢を表示
  • 合計行をstickyで固定

年次収支テーブル

42年分(2024〜2065年)の年次データを一覧表示。Excelのシミュレーション_sumシートを再現した。

┌──────┬──────┬────────────┬────────────┬────────────┬────────────┐
│ 年度 │ 年齢 │ 手取り合計 │ 居住費生活費│ 教育費    │ 収支累計   │
│      │      │            │            │            │(Σ年間収支) │
├──────┼──────┼────────────┼────────────┼────────────┼────────────┤
│ 2024 │ 46   │ 6,800,000  │ ▲3,408,000 │ ▲1,245,000│ 2,147,000  │
│ 2025 │ 47   │ 6,950,000  │ ▲3,408,000 │ ▲1,398,000│ 4,291,000  │
│ ...  │      │            │            │            │            │
│ 合計 │ -    │ 286,000,000│▲143,136,000│▲42,629,109│100,234,891 │
└──────┴──────┴────────────┴────────────┴────────────┴────────────┘

実装のポイント:

  • theadにposition: stickyを設定
  • 「収支累計」の下に「(Σ年間収支)」と注釈を表示し、利息なしの単純積み上げであることを明示

実装で苦労した点

stickyヘッダーが効かない問題

Flexboxレイアウト内でposition: stickyが効かなかった。解決策は以下。

/* 親コンテナにmin-height: 0を追加 */
.detail-pane {
  flex: 1;
  min-height: 0;  /* これが重要 */
  display: flex;
  flex-direction: column;
}

/* テーブルを包むコンテナをスクロールコンテナに */
.table-container {
  flex: 1;
  overflow: auto;
}

詳細は CSSでテーブルヘッダーを固定する を参照。

Nuxtのキャッシュ問題

CSSの変更がブラウザに反映されなかった。ハードリフレッシュでも直らず、.nuxtフォルダを削除してサーバー再起動で解決。

詳細は Nuxtでスタイルが反映されない時は.nuxtフォルダを削除する を参照。

技術選定

クエリパラメータによるナビゲーション状態の共有

URLでナビゲーション状態を共有できるようにした。

/life-plan?tab=display&l1=summary
/life-plan?tab=display&l1=yearly&l2=income

パスベースではなくクエリパラメータを選んだ理由:

  • 「別々のコンテンツ」ではなく「同じデータの異なるビュー」
  • 検索エンジンに個別ページとしてインデックスさせる必要がない
  • 実装がシンプル

詳細は URLルーティング設計:クエリパラメータとパスベースの使い分け を参照。

ウォーターフォールチャート

サマリー画面の冒頭に段階損益をビジュアル化したウォーターフォールチャートを追加した。

  • 生涯年収(夫妻の積み棒)
  • 社会保障費(マイナス)
  • 手取り合計
  • 居住費・生活費(マイナス)
  • 教育費(マイナス)
  • 可処分所得

夫と妻の内訳は積み棒で表示し、合計値がわかるようにした。

今後の予定

現在はハードコードでUIを作成している段階。次のステップは以下。

  1. Excelデータを読み込んでハードコード値を置き換え
  2. 入力フォームから値を変更できるようにする
  3. 計算ロジックの実装
  4. ローカルストレージへのデータ保存
  5. ユーザー登録・家族データ共有機能

まとめ

Excelの人生計画シミュレーターをWebアプリに移植する第一段階として、UIコンポーネントを実装した。ミラーカラム構成のナビゲーション、段階損益形式のサマリーテーブル、ウォーターフォールチャートなど、Excelの表現力をWebでも実現できた。

次はロジックの実装に進む。