[{"data":1,"prerenderedAt":542},["ShallowReactive",2],{"content-/mu-fy26-q3-financials-chart":3,"all-pages-for-dir":540,"og-image-/mu-fy26-q3-financials-chart":541},{"id":4,"title":5,"body":6,"category":521,"description":522,"extension":523,"meta":524,"navigation":525,"ogImage":526,"path":527,"project_name":528,"published":529,"publishedAt":530,"seo":531,"stem":532,"tags":533,"todo":526,"unpublished":529,"updatedAt":526,"__hash__":539},"pages/2026-07/2026-07-01/mu-fy26-q3-financials-chart.md","Micron fy2026-Q3ページに売上・売上原価・粗利と棚卸資産回転期間チャートを追加した",{"type":7,"value":8,"toc":509},"minimark",[9,14,23,26,29,45,48,52,59,62,68,75,78,95,98,105,126,141,148,151,170,181,188,195,198,210,231,238,398,411,414,421,428,431,434,455,466,469,505],[10,11,13],"h2",{"id":12},"きっかけ-取った記憶があるのにページにない","きっかけ: 「取った記憶があるのに、ページにない」",[15,16,17,18,22],"p",{},"beat-monitoring の ",[19,20,21],"code",{},"/beat-monitoring/MU/fy2026-Q3"," を開いて、Micron の売上・売上原価・粗利の推移チャートを探した。ない。",[15,24,25],{},"前に取った記憶はあるのだが、どこに置いたか忘れていた。ページに置いてあるはずの情報が見当たらないので、まず所在を突き止めてから移植することにした。",[10,27,28],{"id":28},"記憶のデータを掘り起こす",[15,30,31,32,35,36,40,41,44],{},"Claude Code に「どこにあるか探して」と投げたら、",[19,33,34],{},"/memory-makers/micron"," にセグメント別の粗利チャートが埋まっていた。ここまでは思い出せた。ただ、fy2026-Q3 ページに欲しいのは ",[37,38,39],"strong",{},"連結ベースの売上・売上原価・粗利"," と、それに紐づく ",[37,42,43],{},"棚卸資産の内訳","で、粒度が違う。",[15,46,47],{},"Koyfin の DB を覗いたら FY25 の4Qまでは揃っていた。Q1/Q2/Q3 FY26 の3四半期分だけ穴が開いていたので、SEC の 10-Q PDF から埋めることにした。10-Q は並列で取りに行かせて、棚卸資産の内訳（Finished goods / Work in process / Raw materials）まで拾ってきた。",[10,49,51],{"id":50},"最初のドラフト-mouseover-で内訳表示","最初のドラフト: mouseover で内訳表示",[15,53,54,55,58],{},"最初の実装では、積み上げ棒の内訳を ",[37,56,57],{},"mouseover の tooltip"," で見せる素直なパターンを組んだ。Chart.js のデフォルトに近い形で、canvas 3枚を並べる構成。",[15,60,61],{},"ここでユーザーからのちゃぶ台返しが入った。",[63,64,65],"blockquote",{},[15,66,67],{},"mouseover して数字を内訳表示するのはやめてほしい。スマホで見た時にどうせわかんなくなるじゃないですか、クリックとかしないと。",[15,69,70,71,74],{},"指摘のとおりで、スマホで開いたら hover イベントが発火しない。",[37,72,73],{},"指でタップして初めて数字が出る仕様は、スクロール中に読めない","。ページを開いた瞬間、目で追える形にしないと意味がない。",[15,76,77],{},"方針を切り替えた。",[79,80,81,89],"ul",{},[82,83,84,85,88],"li",{},"mouseover で見せるのをやめ、",[37,86,87],{},"チャート内の各セグメントに数字を直書き","する",[82,90,91,94],{},[37,92,93],{},"粗利率は右軸に折れ線","で乗せる（tooltip なしでも粗利率と絶対額を同じ画面で読める）",[10,96,97],{"id":97},"チャート内に数字を焼き込む",[15,99,100,101,104],{},"Chart.js には datalabels プラグインもあるが、外部依存を増やしたくなかったので ",[37,102,103],{},"カスタムプラグイン","を3種類書いた。",[106,107,108,114,120],"ol",{},[82,109,110,113],{},[19,111,112],{},"stackedBarSegmentLabelPlugin"," — 積み上げ棒の各セグメント内側に数値を白抜きで置く（セグメント高さが16px未満なら描かないガードあり）",[82,115,116,119],{},[19,117,118],{},"stackTotalLabelPlugin"," — 積み上げ棒の頂点に合計（＝売上）を黒字で置く",[82,121,122,125],{},[19,123,124],{},"linePointLabelPlugin"," — 折れ線の各点の上に値を置く（粗利率のライン用）",[15,127,128,129,132,133,136,137,140],{},"いずれも ",[19,130,131],{},"afterDatasetsDraw"," フックで canvas の ",[19,134,135],{},"ctx.fillText"," を呼ぶだけの素朴な作り。データセットの ",[19,138,139],{},".data[i]"," を舐めて座標を計算する。",[15,142,143,144,147],{},"これで hover しなくても、",[37,145,146],{},"開いた瞬間に売上・売上原価・粗利・粗利率の4値が全部読める","画面になった。",[10,149,150],{"id":150},"粗利率の右軸を組む",[15,152,153,154,157,158,161,162,165,166,169],{},"右軸 (",[19,155,156],{},"y1",") は ",[19,159,160],{},"position: 'right'"," で追加し、",[19,163,164],{},"max: 100","・",[19,167,168],{},"grid.drawOnChartArea: false"," にしてメインの左軸の格子線を邪魔しないようにした。",[15,171,172,173,176,177,180],{},"粗利率は ",[19,174,175],{},"revenue > 0 ? (grossProfit / revenue) * 100 : null"," の純粋関数で作った配列を渡すだけ。折れ線の ",[19,178,179],{},"yAxisID: 'y1'"," を刺せば右軸に紐づく。",[15,182,183,184,187],{},"これで積み上げ棒（絶対額）と折れ線（比率）が1枚のチャートで同居する。",[37,185,186],{},"「売上27%が粗利」→「売上85%が粗利」の跳ね上がりが折れ線の傾きで一目で読める","。",[10,189,191,194],{"id":190},"の二重表記に気付く",[19,192,193],{},"$"," の二重表記に気付く",[15,196,197],{},"反映後、また指摘が来た。",[63,199,200],{},[15,201,202,203,209],{},"チャートの中の数字に ",[19,204,208],{"className":205},[206,207],"language-math","math-inline"," が全部入ってる。単位のところ、左軸にドルって入ってるからわかるんですよ。だからチャートの中の数字、","マークはいらない。",[15,211,212,213,216,217,220,221,223,224,227,228,230],{},"送ってもらったスクショを見たら、たしかに ",[19,214,215],{},"$4.1B"," ",[19,218,219],{},"$2.7B"," みたいに全数字に ",[19,222,193],{}," が付いている。左軸のタイトルに ",[19,225,226],{},"売上・売上原価・粗利 (USD)"," と明示してあるので、セグメント内の ",[19,229,193],{}," は完全に冗長だった。",[15,232,233,234,237],{},"対応は分岐でなく ",[37,235,236],{},"フォーマッタを2つ用意して呼び分ける","方針にした。",[239,240,245],"pre",{"className":241,"code":242,"language":243,"meta":244,"style":244},"language-ts shiki shiki-themes vitesse-light vitesse-light","// 軸目盛用: $ を付ける\nconst formatUsdM = (v: number) => `$${(v / 1000).toFixed(1)}B` // 略\n// チャート内側のラベル用: $ を付けない\nconst formatUsdMPlain = (v: number) => `${(v / 1000).toFixed(1)}B` // 略\n","ts","",[19,246,247,256,340,346],{"__ignoreMap":244},[248,249,252],"span",{"class":250,"line":251},"line",1,[248,253,255],{"class":254},"sxvE3","// 軸目盛用: $ を付ける\n",[248,257,259,263,267,271,274,278,281,285,288,291,295,298,302,305,308,311,315,318,321,323,326,328,331,334,337],{"class":250,"line":258},2,[248,260,262],{"class":261},"stQ0i","const ",[248,264,266],{"class":265},"senZ8","formatUsdM",[248,268,270],{"class":269},"shFtX"," =",[248,272,273],{"class":269}," (",[248,275,277],{"class":276},"s4oTP","v",[248,279,280],{"class":269},": ",[248,282,284],{"class":283},"sSkh3","number",[248,286,287],{"class":269},")",[248,289,290],{"class":269}," =>",[248,292,294],{"class":293},"sMJiu"," `",[248,296,193],{"class":297},"sdGka",[248,299,301],{"class":300},"sHkkW","${",[248,303,304],{"class":269},"(",[248,306,307],{"class":297},"v ",[248,309,310],{"class":261},"/",[248,312,314],{"class":313},"sM54T"," 1000",[248,316,317],{"class":269},").",[248,319,320],{"class":265},"toFixed",[248,322,304],{"class":269},[248,324,325],{"class":313},"1",[248,327,287],{"class":269},[248,329,330],{"class":300},"}",[248,332,333],{"class":297},"B",[248,335,336],{"class":293},"`",[248,338,339],{"class":254}," // 略\n",[248,341,343],{"class":250,"line":342},3,[248,344,345],{"class":254},"// チャート内側のラベル用: $ を付けない\n",[248,347,349,351,354,356,358,360,362,364,366,368,370,372,374,376,378,380,382,384,386,388,390,392,394,396],{"class":250,"line":348},4,[248,350,262],{"class":261},[248,352,353],{"class":265},"formatUsdMPlain",[248,355,270],{"class":269},[248,357,273],{"class":269},[248,359,277],{"class":276},[248,361,280],{"class":269},[248,363,284],{"class":283},[248,365,287],{"class":269},[248,367,290],{"class":269},[248,369,294],{"class":293},[248,371,301],{"class":300},[248,373,304],{"class":269},[248,375,307],{"class":297},[248,377,310],{"class":261},[248,379,314],{"class":313},[248,381,317],{"class":269},[248,383,320],{"class":265},[248,385,304],{"class":269},[248,387,325],{"class":313},[248,389,287],{"class":269},[248,391,330],{"class":300},[248,393,333],{"class":297},[248,395,336],{"class":293},[248,397,339],{"class":254},[15,399,400,401,404,405,407,408,410],{},"軸ラベル (",[19,402,403],{},"ticks.callback",") には ",[19,406,266],{},"、プラグイン側には ",[19,409,353],{}," を渡す。呼び出し側で単位表記の責務を分けたので、あとで軸表記だけ変えたくなっても片方だけ触れば済む。",[10,412,413],{"id":413},"下段に棚卸資産回転期間チャートを追加",[15,415,416,417,420],{},"「在庫の回転期間もチャートで見たい」と要求が追加された。棚卸資産の内訳（原材料・仕掛品・製品）はすでに用意していたので、",[37,418,419],{},"それぞれを当期COGSで割って×3ヶ月","した「四半期消費相当の月数」を折れ線で並べた。",[15,422,423,424,427],{},"厳密に言えば ",[37,425,426],{},"原材料は購入額、仕掛品はCOGMを分母に取るのが会計テキスト的な正解","だが、Micron はそれらを開示していない。開示されている値だけで作れる近似として、全部の分母をCOGSに揃えて「合計 = 棚卸資産 ÷ COGS × 3ヶ月」の恒等式を保つ形にした。近似の但し書きはチャート下のノートに明記して逃げた。",[15,429,430],{},"このチャートも同じく mouseover なしで、各点の上に月数を焼き込む。合計・原材料・仕掛品・製品の4本を色分けし、**「製品が0.8ヶ月分→0.3ヶ月分へ6割減」**が視覚的に飛び込んでくる。作った端から出荷される逼迫感の数字化。",[10,432,433],{"id":433},"実装ファイルの全体像",[79,435,436,442,449],{},[82,437,438,439],{},"コンポーネント: ",[19,440,441],{},"apps/web/app/components/MicronFy26Q3FinancialsChart.vue",[82,443,444,445,448],{},"データ: ",[19,446,447],{},"apps/web/app/data/tripleBeat/micronQuarterlyFinancials.ts","（Koyfin + 10-Q 由来の9四半期）",[82,450,451,452],{},"表示ページ: ",[19,453,454],{},"apps/web/app/pages/beat-monitoring/MU/fy2026-Q3.vue",[15,456,457,458,461,462,465],{},"Chart.js は動的 import (",[19,459,460],{},"await import('chart.js')",") にして SSR に載せない構成。canvas への描画は onMounted のみで発火する。",[19,463,464],{},"onBeforeUnmount"," で3つのチャートインスタンスを destroy して leak を防ぐ。",[10,467,468],{"id":468},"学び",[79,470,471,477,490,499],{},[82,472,473,476],{},[37,474,475],{},"hover / tooltip でしか情報が出ないチャートはスマホで死ぬ","。ページを開いた瞬間に指で追える情報密度に落とすのが基本。特にブログのように長時間かけて読まれる媒体では、hover 前提の情報は無いも同然になる",[82,478,479,482,483,486,487,489],{},[37,480,481],{},"軸ラベルと数値ラベルで単位表記の役割を分ける","。軸に ",[19,484,485],{},"(USD)"," があれば数字側の ",[19,488,193],{}," は削る。同じ情報を2箇所に書くと、読者が「何か違うのでは」と一瞬立ち止まる",[82,491,492,498],{},[37,493,494,495,497],{},"Chart.js のプラグインは ",[19,496,131],{}," に薄い関数を書けば canvas に直接描ける","。外部プラグインを足さず素の Chart.js で完結できたので、依存の増加ゼロで済んだ",[82,500,501,504],{},[37,502,503],{},"近似の但し書きは逃げずに書く","。棚卸資産回転期間の分母は教科書と違う近似だが、注釈で明示すれば読者は正しく減点しながら読める",[506,507,508],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sSkh3, html code.shiki .sSkh3{--shiki-default:#2E8F82;--shiki-dark:#2E8F82}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":244,"searchDepth":258,"depth":258,"links":510},[511,512,513,514,515,516,518,519,520],{"id":12,"depth":258,"text":13},{"id":28,"depth":258,"text":28},{"id":50,"depth":258,"text":51},{"id":97,"depth":258,"text":97},{"id":150,"depth":258,"text":150},{"id":190,"depth":258,"text":517},"$ の二重表記に気付く",{"id":413,"depth":258,"text":413},{"id":433,"depth":258,"text":433},{"id":468,"depth":258,"text":468},"dev","beat-monitoring の MU/fy2026-Q3 ページに、過去9四半期の P/L 積み上げ棒＋右軸粗利率、棚卸資産内訳、在庫回転期間の3チャートを組み込むまでの試行錯誤。スマホで指で追える数字の見せ方に落ち着くまでの流れを記録する。","md",{},true,null,"/mu-fy26-q3-financials-chart","financial-data",false,"2026-07-01T00:00:00.000Z",{"title":5,"description":522},"2026-07/2026-07-01/mu-fy26-q3-financials-chart",[534,535,536,537,538],"micron","beat-monitoring","chart.js","財務データ","可視化","b0owzORp0GlnhUzgtYsP6jfyyhkM2PdvlT1u1_MbGco",[],"https://log.eurekapu.com/og/blog/mu-fy26-q3-financials-chart.png?v=2026-07-01T00%3A00%3A00.000Z&title=Micron%20fy2026-Q3%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AB%E5%A3%B2%E4%B8%8A%E3%83%BB%E5%A3%B2%E4%B8%8A%E5%8E%9F%E4%BE%A1%E3%83%BB%E7%B2%97%E5%88%A9%E3%81%A8%E6%A3%9A%E5%8D%B8%E8%B3%87%E7%94%A3%E5%9B%9E%E8%BB%A2%E6%9C%9F%E9%96%93%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%97%E3%81%9F&author=Kei%20Komatsu&sig=e33ec29fffee6fa3",1782975568071]