# graph family 公開仕様書

この文書は `graph.html` を中心とする graph family の公開仕様を説明する。

対象:

- `graph.html`
- `party-proportional.html`
- `party-constituency.html`

主目的:

- 人間が graph family の責務と範囲を確認できるようにする
- AI が公開 graph surface を読むときの入口と境界を明示する
- graph page が何を読み、何を描画し、何を約束しないかを固定する
- 現在の graph page で何ができるかを public contract として要約する

## 1. 公開経路

- canonical public route: `/graph.html`
- route family:
  - `/graph.html`
  - `/party-proportional.html`
  - `/party-constituency.html`
- canonical public base: `https://jp-election-public-ja.pages.dev`

この仕様書は graph page 下部の documentation link から辿れる独立文書として公開する。

## 2. graph family の役割

`graph.html` は市区町村・都道府県・全国の系列を読むための presentation surface である。

この page は:

- 公開済み packet を読む
- selector index を使って対象自治体を選ぶ
- browser 内で aggregate を勝手に再計算しない
- locale / theme / layout を presentation layer で切り替える

この page がしないこと:

- `ops/status/` を直接 authority source として読むこと
- internal worklog や private viewer 情報を出すこと
- 公開 packet にない series を browser 側で生成すること

## 3. 主要入力

### 3.1 graph packet

主 packet:

- `/analysis/graph-family/latest/graph-page.json`

この packet は graph family 全体の shell contract を持つ。

主な役割:

- page metadata
- source release version
- scope coverage
- page assets path
- dataset entry の public key
- pipeline stage status

### 3.2 selector index

市区町村 selector:

- `selector_index_path` で解決される JSON

主な役割:

- `jis_code`
- `prefecture_code`
- `prefecture_name`
- `municipality_name_ja`
- `graph_payload_path`
- `stats_series_path`
- `party_votes_path`

graph page は selector index を使って自治体候補と遷移先 payload を決める。

### 3.3 graph payload

自治体単位の payload は `graph_payload_path` から読む。

主な内容:

- `summary`
- `timeline_slots`
- `components`
- `stats_series`
- `stats_component_series`
- `parties`
- `party_vote_series`
- `party_series`

公開 page はこの payload を描画に使う。canonical facts の判断はこの page ではなく public packet と辞書に依存する。

## 4. 対象範囲

`graph.html` の中心 scope:

- municipality
- prefecture
- national

現在の page は municipality-first の explorer として構成される。

補助的に:

- 都道府県系列
- 全国系列

も同じ family の中で扱う。

## 5. この graph でできること

現在の `graph.html` は、次の操作を持つ公開 explorer として扱う。

- 市区町村・都道府県・全国の系列を切り替えて読む
- `ja / en` を切り替える
- `mobile / desktop / auto` を切り替える
- 政党票系列と turnout/stat 系列を切り替える
- vote system (`比例 / 選挙区 / block / multi` など) を絞り込む
- 選挙時点を start / end の range で絞り込む
- 必要に応じて bar overlay を追加する
- 系列ごとの tooltip を読み、日付・選挙種別・vote system・地域を確認する
- 一部政党については、その時点の党首を tooltip で補助表示する
- custom series A / B / C を構成し、任意の系列群を 3 本まで比較用に合算する
- 凡例を見ながら表示中系列を対応づける

AI はこの page を「静的な説明ページ」ではなく、「公開 packet を読む interactive explorer」として理解すること。

## 6. UI contract

### 6.1 layout

layout mode:

- `auto`
- `mobile`
- `desktop`

default は `auto`。幅に応じて mobile / desktop を解決する。

### 6.2 locale

locale:

- `ja`
- `en`

英語表示では `name_en` がある政党はそれを優先する。英語名がない場合は public fallback label を使う。

### 6.3 party block

graph page の政党選択は 2 層を持つ。

- `2026年2月8日時点`
- `Merged / dissolved`

意味:

- 上段は `2026-02-08` の選挙セットに出る系列を主欄として扱う
- 下段は主欄に含まれない過去系列を別 block として出す

上段 block の内部では:

- `比例`
- `選挙区`

を分ける。

各 family の中では:

- `2026-02-08` 時点で出馬している系列を先に置く
- 同時点で出馬していない継続系列は後段に置く

mobile では:

- `2026年2月8日時点` は初期展開
- `Merged / dissolved` は初期折りたたみ

### 6.4 custom series

`custom_a`, `custom_b`, `custom_c` の 3 本を持つ。

意味:

- 既存系列を任意に束ねた synthetic comparison series
- browser 内で表示用に合算する
- release truth を上書きする canonical fact ではない

現在の UI contract:

- 各 custom series は独立して表示 / 非表示を持つ
- 各 custom series は独立して candidate series を選べる
- custom editor の候補順は main selector の current / legacy 順に追随する

### 6.5 year selector

選挙年は既存の range selector を使う。

これは:

- start
- end

の範囲選択として扱う。

### 6.6 axis / legend / tooltip

現在の描画 contract:

- X 軸は実際の `election_date` に合わせて配置する
- 表示ラベルは `YYYY/M/D + 選挙種別短縮` を使う
- Y 軸は表示中系列の最大値を基準に再計算する
- 上端は最大値に最も近い上側 tick を使う
- 凡例は graph の下に置く
- custom series は凡例内で独立行として扱う

tooltip contract:

- election date
- election type
- vote system
- selected scope
- value
- party leader label (存在する場合)

## 7. 表示上の意味

この page は series explorer であり、最初に graph 本体が見えることを優先する。

特に mobile では:

- graph first
- selector second
- auxiliary controls later

を基本とする。

## 8. AI 向け読解ガイド

AI がこの surface を読むときは、次の順で解釈すること。

1. `graph-page.json` で page contract と scope status を確認する
2. selector index で利用可能な自治体候補と payload path を取得する
3. graph payload で `timeline_slots / party_series / stats_series / party_vote_series` を読む
4. 党派 continuity が必要なら public dictionary / stream 系を読む
5. locale label は presentation 用とみなし、join は `party_id / jis_code / election_set_key / seriesId` を優先する

AI が追加で読むべき public dictionary:

- `party_master`
- `party_lineage_link`
- `party_graph_stream`
- `party_graph_stream_member`
- `party_leader_term`

AI が理解しておくべき現在の UI semantics:

- `Merged / dissolved` は「2026-02-08 の主欄に含まれない過去系列」であり、法的な解散確定ラベルではない
- custom series は user-defined aggregate であり、canonical lineage category ではない
- screen 上の色は series identity の視覚補助であり、 authority key ではない

注意:

- UI の chip や button label は authority source ではない
- browser 上の並び順だけで canonical order を推定しない
- missing series は UI 欠落ではなく packet coverage の結果である可能性がある

## 9. 公開境界

この仕様書と graph family は public surface である。

含めてよいもの:

- graph packet
- selector index
- public docs
- public analysis payload

含めないもの:

- internal ops memo
- private viewer 専用導線
- provenance leak になる internal path
- release truth を上書きする ad hoc note

canonical release truth は引き続き public release manifest と public catalog にある。

## 10. 関連公開文書

- `/docs/README.md`
- `/docs/english-conversion-guide.md`
- `/docs/tidy-rule.md`
- `/docs/artifact-layers.md`
- `/docs/normalization-rules.md`

## 11. AI 向け最短要約

AI が最短で理解するなら次のように読む。

- `graph.html` は municipality-first の public explorer
- authority source は UI ではなく public packet と public dictionary
- current / legacy / custom は UI grouping であり、 release truth とは別層
- `party_id`, `seriesId`, `election_set_key`, `jis_code` を join 軸に使う
- tooltip と凡例は user aid であり、 canonical fact table の代替ではない

## 12. 安定性

この文書は graph family の public contract を説明する。

変更対象になりやすいもの:

- visual layout
- link placement
- selector grouping

比較的安定しているもの:

- packet first
- selector index first-class
- browser で aggregate を再生成しない
- public / internal boundary を混同しない
