hgg-core-0.1.0.0: src/Graphics/Hgg/Spec/Bake.hs
-- |
-- Module : Graphics.Hgg.Spec.Bake
-- Description : Resolver の焼き込み (ColByName → inline 解決、 Phase 8 B16)
-- Copyright : (c) 2026 Aelysce Project (Toshiaki Honda)
-- License : BSD-3-Clause
--
-- Phase 55: 'Graphics.Hgg.Spec' の module 分割で切り出し。 spec 内の全
-- 'ColByName' を 'Resolver' で inline ('ColNum' / 'ColTxt') 化する 'bakeSpec'
-- を持つ。 'VisualSpec' / 'Layer' 全体を走査する sink (被参照ゼロ・Phase 55 A1
-- 実測) ゆえ分割 module 群の最後段。 公開 API は従来どおり 'Graphics.Hgg.Spec'
-- (facade) が re-export する。 挙動・出力は完全に不変。
{-# LANGUAGE OverloadedStrings #-}
module Graphics.Hgg.Spec.Bake
( bakeSpec
) where
import Graphics.Hgg.Spec.Column
import Graphics.Hgg.Spec.Layer (Layer (..))
import Graphics.Hgg.Spec.Mark (ColorEnc (..))
import Graphics.Hgg.Spec.Visual (VisualSpec (..))
-- ===========================================================================
-- Resolver の焼き込み (Phase 8 B16): ColByName を inline (ColNum/ColTxt) に解決
-- ===========================================================================
-- PS canvas backend は Resolver を持たず spec JSON だけ受け取るため、 ColByName
-- (列名参照) のままだと PS で解決できず描画されない (= pairs/facet/legend が空)。
-- JSON 出力前に bakeSpec で全 ColRef を inline 化すると PS でも描ける。
-- | ColByName を Resolver で解決し ColNum/ColTxt に置換 (解決不能なら元のまま)。
bakeColRef :: Resolver -> ColRef -> ColRef
bakeColRef r cr@(ColByName n) = case r n of
Just (NumData v) -> ColNum v
Just (TxtData v) -> ColTxt v
Nothing -> cr
bakeColRef _ cr = cr
bakeColorEnc :: Resolver -> ColorEnc -> ColorEnc
bakeColorEnc r (ColorByCol cr) = ColorByCol (bakeColRef r cr)
-- Phase 9 A-5 fix: ColorByContinuous も inline 化しないと PS (emptyResolver) で色も
-- legend も出ない (= legend-continuous で発覚)。
bakeColorEnc r (ColorByContinuous cr) = ColorByContinuous (bakeColRef r cr)
bakeColorEnc _ ce = ce
bakeLayer :: Resolver -> Layer -> Layer
bakeLayer r l = l
{ lyEncX = bakeColRef r <$> lyEncX l
, lyEncY = bakeColRef r <$> lyEncY l
, lyEncY2 = bakeColRef r <$> lyEncY2 l
, lyErrorX = bakeColRef r <$> lyErrorX l
, lyErrorY = bakeColRef r <$> lyErrorY l
, lyChain = bakeColRef r <$> lyChain l
, lyShapeBy = bakeColRef r <$> lyShapeBy l
, lySizeBy = bakeColRef r <$> lySizeBy l
, lyAlphaBy = bakeColRef r <$> lyAlphaBy l
, lyLinetypeBy = bakeColRef r <$> lyLinetypeBy l
, lyLabel = bakeColRef r <$> lyLabel l
, lyColor = bakeColorEnc r <$> lyColor l
, lyOverlay = map (bakeLayer r) (lyOverlay l) -- ★ Phase 36 D2: sub-mark の inline 列も bake
}
-- | spec 内の全 ColByName を Resolver で inline 化 (layers + facet + subplots 再帰)。
-- JSON 出力前に呼ぶと PS でも Resolver 不要で描ける。
bakeSpec :: Resolver -> VisualSpec -> VisualSpec
bakeSpec r spec = spec
{ vsLayers = map (bakeLayer r) (vsLayers spec)
, vsFacet = bakeColRef r <$> vsFacet spec
, vsFacetRow = bakeColRef r <$> vsFacetRow spec
, vsFacetCol = bakeColRef r <$> vsFacetCol spec
, vsSubplots = map (bakeSpec r) (vsSubplots spec)
}