Micron fy2026-Q3ページに売上・売上原価・粗利と棚卸資産回転期間チャートを追加した
きっかけ: 「取った記憶があるのに、ページにない」
beat-monitoring の /beat-monitoring/MU/fy2026-Q3 を開いて、Micron の売上・売上原価・粗利の推移チャートを探した。ない。
前に取った記憶はあるのだが、どこに置いたか忘れていた。ページに置いてあるはずの情報が見当たらないので、まず所在を突き止めてから移植することにした。
記憶のデータを掘り起こす
Claude Code に「どこにあるか探して」と投げたら、/memory-makers/micron にセグメント別の粗利チャートが埋まっていた。ここまでは思い出せた。ただ、fy2026-Q3 ページに欲しいのは 連結ベースの売上・売上原価・粗利 と、それに紐づく 棚卸資産の内訳で、粒度が違う。
Koyfin の DB を覗いたら FY25 の4Qまでは揃っていた。Q1/Q2/Q3 FY26 の3四半期分だけ穴が開いていたので、SEC の 10-Q PDF から埋めることにした。10-Q は並列で取りに行かせて、棚卸資産の内訳(Finished goods / Work in process / Raw materials)まで拾ってきた。
最初のドラフト: mouseover で内訳表示
最初の実装では、積み上げ棒の内訳を mouseover の tooltip で見せる素直なパターンを組んだ。Chart.js のデフォルトに近い形で、canvas 3枚を並べる構成。
ここでユーザーからのちゃぶ台返しが入った。
mouseover して数字を内訳表示するのはやめてほしい。スマホで見た時にどうせわかんなくなるじゃないですか、クリックとかしないと。
指摘のとおりで、スマホで開いたら hover イベントが発火しない。指でタップして初めて数字が出る仕様は、スクロール中に読めない。ページを開いた瞬間、目で追える形にしないと意味がない。
方針を切り替えた。
- mouseover で見せるのをやめ、チャート内の各セグメントに数字を直書きする
- 粗利率は右軸に折れ線で乗せる(tooltip なしでも粗利率と絶対額を同じ画面で読める)
チャート内に数字を焼き込む
Chart.js には datalabels プラグインもあるが、外部依存を増やしたくなかったので カスタムプラグインを3種類書いた。
stackedBarSegmentLabelPlugin— 積み上げ棒の各セグメント内側に数値を白抜きで置く(セグメント高さが16px未満なら描かないガードあり)stackTotalLabelPlugin— 積み上げ棒の頂点に合計(=売上)を黒字で置くlinePointLabelPlugin— 折れ線の各点の上に値を置く(粗利率のライン用)
いずれも afterDatasetsDraw フックで canvas の ctx.fillText を呼ぶだけの素朴な作り。データセットの .data[i] を舐めて座標を計算する。
これで hover しなくても、開いた瞬間に売上・売上原価・粗利・粗利率の4値が全部読める画面になった。
粗利率の右軸を組む
右軸 (y1) は position: 'right' で追加し、max: 100・grid.drawOnChartArea: false にしてメインの左軸の格子線を邪魔しないようにした。
粗利率は revenue > 0 ? (grossProfit / revenue) * 100 : null の純粋関数で作った配列を渡すだけ。折れ線の yAxisID: 'y1' を刺せば右軸に紐づく。
これで積み上げ棒(絶対額)と折れ線(比率)が1枚のチャートで同居する。「売上27%が粗利」→「売上85%が粗利」の跳ね上がりが折れ線の傾きで一目で読める。
$ の二重表記に気付く
反映後、また指摘が来た。
チャートの中の数字に
が全部入ってる。単位のところ、左軸にドルって入ってるからわかるんですよ。だからチャートの中の数字、マークはいらない。
送ってもらったスクショを見たら、たしかに $4.1B $2.7B みたいに全数字に $ が付いている。左軸のタイトルに 売上・売上原価・粗利 (USD) と明示してあるので、セグメント内の $ は完全に冗長だった。
対応は分岐でなく フォーマッタを2つ用意して呼び分ける方針にした。
// 軸目盛用: $ を付ける
const formatUsdM = (v: number) => `$${(v / 1000).toFixed(1)}B` // 略
// チャート内側のラベル用: $ を付けない
const formatUsdMPlain = (v: number) => `${(v / 1000).toFixed(1)}B` // 略
軸ラベル (ticks.callback) には formatUsdM、プラグイン側には formatUsdMPlain を渡す。呼び出し側で単位表記の責務を分けたので、あとで軸表記だけ変えたくなっても片方だけ触れば済む。
下段に棚卸資産回転期間チャートを追加
「在庫の回転期間もチャートで見たい」と要求が追加された。棚卸資産の内訳(原材料・仕掛品・製品)はすでに用意していたので、それぞれを当期COGSで割って×3ヶ月した「四半期消費相当の月数」を折れ線で並べた。
厳密に言えば 原材料は購入額、仕掛品はCOGMを分母に取るのが会計テキスト的な正解だが、Micron はそれらを開示していない。開示されている値だけで作れる近似として、全部の分母をCOGSに揃えて「合計 = 棚卸資産 ÷ COGS × 3ヶ月」の恒等式を保つ形にした。近似の但し書きはチャート下のノートに明記して逃げた。
このチャートも同じく mouseover なしで、各点の上に月数を焼き込む。合計・原材料・仕掛品・製品の4本を色分けし、**「製品が0.8ヶ月分→0.3ヶ月分へ6割減」**が視覚的に飛び込んでくる。作った端から出荷される逼迫感の数字化。
実装ファイルの全体像
- コンポーネント:
apps/web/app/components/MicronFy26Q3FinancialsChart.vue - データ:
apps/web/app/data/tripleBeat/micronQuarterlyFinancials.ts(Koyfin + 10-Q 由来の9四半期) - 表示ページ:
apps/web/app/pages/beat-monitoring/MU/fy2026-Q3.vue
Chart.js は動的 import (await import('chart.js')) にして SSR に載せない構成。canvas への描画は onMounted のみで発火する。onBeforeUnmount で3つのチャートインスタンスを destroy して leak を防ぐ。
学び
- hover / tooltip でしか情報が出ないチャートはスマホで死ぬ。ページを開いた瞬間に指で追える情報密度に落とすのが基本。特にブログのように長時間かけて読まれる媒体では、hover 前提の情報は無いも同然になる
- 軸ラベルと数値ラベルで単位表記の役割を分ける。軸に
(USD)があれば数字側の$は削る。同じ情報を2箇所に書くと、読者が「何か違うのでは」と一瞬立ち止まる - Chart.js のプラグインは
afterDatasetsDrawに薄い関数を書けば canvas に直接描ける。外部プラグインを足さず素の Chart.js で完結できたので、依存の増加ゼロで済んだ - 近似の但し書きは逃げずに書く。棚卸資産回転期間の分母は教科書と違う近似だが、注釈で明示すれば読者は正しく減点しながら読める