• #financial-quiz
  • #scatter-plot
  • #data-pipeline
未分類

散布図ページ (eps-per-scatter) 技術仕様

ページ概要

  • URL: /financial-quiz/eps-per-scatter
  • 機能: 100社のEPS成長率予想とPER(Forward)を散布図でプロット
  • 切り替え機能: 年度(2026-2029)、Adjusted/GAAP

ファイル構成

apps/web/
├── app/
│   ├── pages/
│   │   └── financial-quiz/
│   │       └── eps-per-scatter.vue    # ページ本体
│   └── composables/
│       └── scatter-data.ts            # 軽量データ(自動生成)
├── scripts/
│   └── generate-scatter-data.mjs      # データ生成スクリプト
└── data/
    └── koyfin.db                      # 元データ(SQLite)

データパイプライン

koyfin.db (SQLite)
    ↓
generate-scatter-data.mjs (スクリプト)
    ↓
scatter-data.ts (TypeScript静的データ)
    ↓
eps-per-scatter.vue (ページ)

データ更新方法

SQLiteのデータが更新された場合、以下のコマンドで再生成:

cd apps/web
node scripts/generate-scatter-data.mjs

出力例:

SQLite データベースを読み込み中...
企業数: 101
出力完了: app/composables/scatter-data.ts
ファイルサイズ: 52.6 KB

なぜ軽量データを使うのか

データファイルサイズ内容
actual-consensus-data.ts35MB全メトリクス(売上、利益、マージン、EPS、PER等)× 年次・四半期
scatter-data.ts52KBEPS成長率とPERのみ × 2026-2029年

問題: 35MBのファイルをインポートするとNuxtのSSR時にワーカーがメモリ不足でクラッシュ

解決: 散布図で使う4メトリクスだけを抽出 → 99.8%削減

scatter-data.ts のデータ構造

export interface ScatterYearData {
  epsGrowthAdj: number | null   // EPS成長率(Adjusted)
  epsGrowthGaap: number | null  // EPS成長率(GAAP)
  perAdj: number | null         // PER(Adjusted)
  perGaap: number | null        // PER(GAAP)
}

export interface ScatterCompanyData {
  name: string
  sector: string | null
  years: Record<number, ScatterYearData>  // 2026, 2027, 2028, 2029
}

export const scatterData: Record<string, ScatterCompanyData>
export const scatterCompanyList: string[]

関連ページ

  • /financial-quiz/actual-consensus - 個別企業の詳細データ(35MBのデータを使用)
  • 散布図からティッカーをクリックすると actual-consensus ページにリンク

トラブルシューティング

SSRエラー: "worker exited with code 0"

原因: 大きなデータファイルを使用している 対策:

  1. scatter-data.ts を使用しているか確認
  2. または <ClientOnly> でラップ

データが古い

cd apps/web
node scripts/generate-scatter-data.mjs

新しいメトリクスを追加したい

  1. scripts/generate-scatter-data.mjsMETRIC_KEYS を編集
  2. スクリプトを再実行
  3. eps-per-scatter.vue を更新