[{"data":1,"prerenderedAt":329},["ShallowReactive",2],{"content-/korea-chip-export-flash-charts":3,"all-pages-for-dir":327,"og-image-/korea-chip-export-flash-charts":328},{"id":4,"title":5,"body":6,"category":308,"concepts":309,"description":310,"extension":311,"meta":312,"navigation":313,"ogImage":309,"path":314,"project_name":315,"published":316,"publishedAt":317,"seo":318,"stem":319,"tags":320,"todo":309,"unpublished":316,"updatedAt":309,"__hash__":326},"pages/2026-07/2026-07-04/korea-chip-export-flash-charts.md","韓国半導体輸出ページに速報値チャートを拡充した - DRAM/NAND単価・SSD/MCPをPDF速報から反映",{"type":7,"value":8,"toc":299},"minimark",[9,13,18,22,25,28,47,51,54,57,65,68,82,85,93,96,99,102,105,109,116,123,127,130,133,140,143,266,269,272,275,278,295],[10,11,12],"h1",{"id":12},"韓国半導体輸出ページに速報値チャートを拡充した",[14,15,17],"h2",{"id":16},"発端-pdfの速報単価は答え合わせの材料になる","発端: PDFの速報単価は「答え合わせ」の材料になる",[19,20,21],"p",{},"韓国の半導体輸出統計ページは、これまでKCS（関税庁）の確報ベースでDRAM/NAND輸出単価チャートを描いていた。朝、前日のデータ反映状況を確認していたら、単価チャートが更新されていないのは「7月15日頃の確報待ち」という仕様どおりの挙動だと分かった。",[19,23,24],{},"そこで逆に気づいた。月初に公表される政府の輸出統計PDF（速報）に載っている単価は、確報との突き合わせに使える重要な値だ。速報と確報の両方を並べれば、どちらかが間違っていても、何か違和感があっても気づける。既存チャートと同じ2024年1月起点で、速報単価のチャートを追加させることにした。",[19,26,27],{},"今日1日でページに入ったものを先にまとめておく。",[29,30,31,35,38,41,44],"ul",{},[32,33,34],"li",{},"DRAM/NAND輸出単価の速報値チャート（確報の長い線＋PDF先行値の重ね描き）",[32,36,37],{},"SSD・MCPの品目別チャートへの6月速報値の反映（KPIには速報ラベル）",[32,39,40],{},"全14チャートのモーダル拡大（クリックで開く、再クリックまたはEscで閉じる）",[32,42,43],{},"X軸の「24/1」形式への統一と、データ未着月の空ラベル表示",[32,45,46],{},"取得手順書の速報対応への更新と、テスト89件＋E2E 1本",[14,48,50],{"id":49},"過去号を掘ったら単価の行は最新号が初出だった","過去号を掘ったら、単価の行は最新号が初出だった",[19,52,53],{},"まず過去のPDFがどこまで遡れるかの調査から。前日に整えたPDF取得手順のドキュメントを読ませて、データ源と過去分の取得可否を確認するところから始めた。",[19,55,56],{},"アーカイブの一覧ページは1ページ目に直近2号しか出ない。ページングのパラメータ（ページ番号と件数）を調べさせ、まず検索したら総0件。検索語をEUC-KRにエンコードし直したらようやく48件ヒットした。今度はタイトル抽出のパターンが合わず、生HTMLの構造を見させて修正。コンソールのcp932問題で文字化けするので、一覧はJSONに書き出させて確認した。",[19,58,59,60,64],{},"そこから6体のエージェントを並列で派遣して、全号のPDFを機械抽出させた。すると重要な事実が判明した。",[61,62,63],"strong",{},"「半導体輸出単価（万ドル/kg）」の行は2026年6月号（7/1公表）が初出","で、2024年1月〜2026年5月の28号には存在しない。旧号に載っているのは市況の固定価格（ドル建て）で、輸出単価とは別物だった。つまりPDF先行の単価は、現時点では2026年4月〜6月の3点だけ。",[19,66,67],{},"「2024年から遡れるはず」という前提で頼んだが、データ自体が存在しなかった。チャートは予定どおり2024年1月起点にして、KCS確報から再計算した長い線に、PDF先行値の3点（今後毎月1点ずつ伸びる）を重ねる構成で作らせた。",[29,69,70,73,76,79],{},[32,71,72],{},"SSOTのデータファイルを新設し、ページに比較チャートのパネルを追加",[32,74,75],{},"出所・注記セクションに先行単価の出典を追記",[32,77,78],{},"取得手順書も速報単価の反映手順に合わせて更新",[32,80,81],{},"テストはヘルパー37件を含む89件が全部通り、devのSSRで新パネルと線の終端ラベル（各系列の最新値）を確認",[14,83,84],{"id":84},"モーダル拡大の統一とマゼンタ枠での目視確認",[19,86,87,88,92],{},"チャートの操作系は他ページと揃えたい。マウスオーバー→クリックでモーダル拡大、再クリックまたはEscで閉じる挙動を、他ページの実装を探させてこのページにも適用させた。モーダルラッパーを作る前に、他のチャートコンポーネントのルート要素の幅制約を確認させてから、ページ内の14チャートすべてを ",[89,90,91],"code",{},"ExpandableChartPanel"," で包む形にした。",[19,94,95],{},"作ってもらったチャートの表示が見切れていたので修正させ、凡例の座標がviewBox内に収まっているかまで検証させた。",[19,97,98],{},"今回どのチャートが新規なのか、外枠のグレーだけでは見分けがつかない。そこで新規追加分を一時的にマゼンタ枠で囲ませて、目視で1つずつ確認した。",[19,100,101],{},"途中、新規コンポーネント追加でdevサーバーの再起動が固まる既知パターンを踏んだ。issueに記録してからポート3000のプロセスを止めて再起動——のはずが、Bash側で変数が展開されてしまい、シングルクォートで再実行してようやく復旧。最後にモーダルの最小のE2Eスペックを1本書かせて通した（初回の失敗はハイドレーション完了前にクリックするテスト側のタイミング問題で、モーダル自体は正常だった）。",[19,103,104],{},"確認が済んだのでマゼンタ枠を外させて、「コミットしといて」と頼んだら、作業の区切りごとに既にコミット済みだった。積み残しもコード面はゼロを確認して、午前の部を締めた。",[14,106,108],{"id":107},"ssdとmcpも速報から更新できることに気づいた","SSDとMCPも速報から更新できることに気づいた",[19,110,111,112,115],{},"その後、速報PDFをHTMLテーブル化したものを眺めていて、もう一つ気づいた。単価はチャートに追加したのに、",[61,113,114],{},"SSDとMCPの品目別金額も速報から取れる","のにまだ入っていない。速報ベースで更新できるものは更新するフローに、スキル側を変えるよう指示した。",[19,117,118,119,122],{},"実装前に、指摘したHTML（PDF由来）の6月値の裏取りをさせてから着手。速報では埋まらないフィールドがあるので、ヘルパー関数をnullセーフに直させた上で、MCPとSSDのデータセットに6月の速報値を追加した。KPI表示には速報ラベルとフォールバックを付けさせ、",[89,120,121],{},"weightTons"," を参照する他の箇所がnullで壊れないかも横断確認。ページの品目別セクションのリード文にも速報の説明を反映させて、テスト全パス。トップページのカードは具体的な月次値を持たない文言だったので追従不要だった。",[14,124,126],{"id":125},"入ってない-入っていた-でも欠損月が分かりづらい","「入ってない？」→ 入っていた → でも欠損月が分かりづらい",[19,128,129],{},"devで画面を見て「結局チャートに入ってないと思うんですけど、入ってますか？」と伝えたら、devサーバーの描画そのもののSVGが2枚返ってきた。確かに入っていた。ごめんなさい、と返した。",[19,131,132],{},"ただ、見間違えたのには理由がある。DRAMなどの月次チャートはX軸の表記が他のチャートと違っていて、最新の棒が26年5月なのか6月なのか、画面を見ても判別できなかった。そこでX軸を「24/1」「26/6」の形式に変えさせた。",[19,134,135,136,139],{},"さらにもう一段。SSDのように6月分が埋まっている品目と、DRAMのように5月までしかない品目を並べて見比べたとき、「まだ入っていない」ことが分かるようにしたい。6月データがない品目にも ",[89,137,138],{},"'26/6"," の空ラベルを立てて、欠けている月を空カラムとして可視化させた。",[19,141,142],{},"実装は、系列の末尾を指定月までnullで埋める純粋関数をデータファイルに追加し、ページ側で全品目のバーチャートを最大月までパディングする方針。",[144,145,150],"pre",{"className":146,"code":147,"language":148,"meta":149,"style":149},"language-ts shiki shiki-themes vitesse-light vitesse-light","// {month, value} 系列の末尾を toMonth まで value: null で埋める。\n// 品目間で最新月が揃わないとき、X軸グリッドを揃えて\n// 「データがまだ無い月」を空カラムとして可視化する。\nexport const padSeriesToMonth = (\n  series: { month: string; value: number | null }[],\n  toMonth: string,\n) => { /* ... */ }\n","ts","",[89,151,152,161,167,173,195,235,248],{"__ignoreMap":149},[153,154,157],"span",{"class":155,"line":156},"line",1,[153,158,160],{"class":159},"sxvE3","// {month, value} 系列の末尾を toMonth まで value: null で埋める。\n",[153,162,164],{"class":155,"line":163},2,[153,165,166],{"class":159},"// 品目間で最新月が揃わないとき、X軸グリッドを揃えて\n",[153,168,170],{"class":155,"line":169},3,[153,171,172],{"class":159},"// 「データがまだ無い月」を空カラムとして可視化する。\n",[153,174,176,180,184,188,192],{"class":155,"line":175},4,[153,177,179],{"class":178},"sHkkW","export",[153,181,183],{"class":182},"stQ0i"," const ",[153,185,187],{"class":186},"senZ8","padSeriesToMonth",[153,189,191],{"class":190},"shFtX"," =",[153,193,194],{"class":190}," (\n",[153,196,198,202,205,208,211,215,218,221,223,226,229,232],{"class":155,"line":197},5,[153,199,201],{"class":200},"s4oTP","  series",[153,203,204],{"class":190},": { ",[153,206,207],{"class":200},"month",[153,209,210],{"class":190},": ",[153,212,214],{"class":213},"sSkh3","string",[153,216,217],{"class":190},"; ",[153,219,220],{"class":200},"value",[153,222,210],{"class":190},[153,224,225],{"class":213},"number",[153,227,228],{"class":190}," | ",[153,230,231],{"class":182},"null",[153,233,234],{"class":190}," }[],\n",[153,236,238,241,243,245],{"class":155,"line":237},6,[153,239,240],{"class":200},"  toMonth",[153,242,210],{"class":190},[153,244,214],{"class":213},[153,246,247],{"class":190},",\n",[153,249,251,254,257,260,263],{"class":155,"line":250},7,[153,252,253],{"class":190},")",[153,255,256],{"class":190}," =>",[153,258,259],{"class":190}," {",[153,261,262],{"class":159}," /* ... */",[153,264,265],{"class":190}," }\n",[19,267,268],{},"最新のデータがあるバーにはマゼンタの目印を付けさせた。テストも追加して全パス。",[14,270,271],{"id":271},"次の答え合わせ",[19,273,274],{},"7月15日頃にKCSの確報が出たら、今回入れた速報3点と初めて突き合わせられる。速報チャートは今後毎月1点ずつ伸びていくので、月初のPDF速報反映→月中の確報反映、という二段の運用がこのページの定常フローになる。",[14,276,277],{"id":277},"学び",[29,279,280,283,286,289,292],{},[32,281,282],{},"速報と確報の二重化は「答え合わせ」の仕組みとして効く。片方だけでは、間違っていても気づく手段がない",[32,284,285],{},"「過去に遡れるはず」という思い込みは危ない。単価の行は最新号が初出だと、28号を機械抽出して初めて確定した",[32,287,288],{},"「入っていない」と思ったら、まず描画そのものを出させて確認する。今回は入っていて、本当の問題は「欠損月が見えない」表示側にあった",[32,290,291],{},"確認用のマゼンタ枠は安上がりで確実だった。どれが新規か、どのバーが最新か、一目で追える",[32,293,294],{},"品目ごとに最新月がずれるデータは、揃っていないこと自体を表示に出す。空ラベルのパディングで「無い」が見えるようになった",[296,297,298],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}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 .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":149,"searchDepth":163,"depth":163,"links":300},[301,302,303,304,305,306,307],{"id":16,"depth":163,"text":17},{"id":49,"depth":163,"text":50},{"id":84,"depth":163,"text":84},{"id":107,"depth":163,"text":108},{"id":125,"depth":163,"text":126},{"id":271,"depth":163,"text":271},{"id":277,"depth":163,"text":277},"dev",null,"韓国の月次輸出統計PDF（速報）からDRAM/NAND輸出単価チャートを新設し、SSD・MCPの速報値も反映。モーダル拡大の統一、X軸表記の変更、欠損月の可視化まで進めた記録。","md",{},true,"/korea-chip-export-flash-charts","financial-data",false,"2026-07-04T00:00:00.000Z",{"title":5,"description":310},"2026-07/2026-07-04/korea-chip-export-flash-charts",[321,322,323,324,325],"韓国半導体輸出","速報値","データ可視化","チャート","Nuxt","bDUN4u-nH6f3cRKvubXQAudlZhyT8CufwwGpuL313GY",[],"https://log.eurekapu.com/og/blog/korea-chip-export-flash-charts.png?v=2026-07-04T00%3A00%3A00.000Z&title=%E9%9F%93%E5%9B%BD%E5%8D%8A%E5%B0%8E%E4%BD%93%E8%BC%B8%E5%87%BA%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AB%E9%80%9F%E5%A0%B1%E5%80%A4%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%92%E6%8B%A1%E5%85%85%E3%81%97%E3%81%9F%20-%20DRAM%2FNAND%E5%8D%98%E4%BE%A1%E3%83%BBSSD%2FMCP%E3%82%92PDF%E9%80%9F%E5%A0%B1%E3%81%8B%E3%82%89%E5%8F%8D%E6%98%A0&author=Kei%20Komatsu&sig=e8a325a0036138d3",1783483675580]