packages feed

hgg-ihaskell (empty) → 0.1.0.0

raw patch · 6 files changed

+309/−0 lines, 6 filesdep +basedep +containersdep +hgg-core

Dependencies added: base, containers, hgg-core, hgg-frame, hgg-ihaskell, hgg-svg, ihaskell, text, vector

Files

+ CHANGELOG.md view
@@ -0,0 +1,7 @@+# Changelog for `hgg-ihaskell`++## 0.1.0.0 — 2026-07-18++First public release on Hackage.++- iHaskell (Jupyter) inline display backend.
+ LICENSE view
@@ -0,0 +1,30 @@+BSD 3-Clause License++Copyright (c) 2026, Toshiaki Honda+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice,+   this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+   this list of conditions and the following disclaimer in the documentation+   and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its+   contributors may be used to endorse or promote products derived from this+   software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ examples/DemoSvg.hs view
@@ -0,0 +1,55 @@+-- | Phase 12 A4: demo.ipynb の各セルが iHaskell 上で出力するのと同じ SVG を+-- ファイルに書き出す (= notebook の出力を環境非依存に確認するための具体物)。+--+-- @cabal run ihaskell-demo-svg@ → design/ihaskell/ に 3 枚の SVG を生成。+-- iHaskell セルでは @display@ がこの SVG を inline 表示する (= 同一描画経路)。+{-# LANGUAGE OverloadedStrings #-}+module Main (main) where++import           Graphics.Hgg.Backend.SVG (renderSVG, renderSVGWith)+import           Graphics.Hgg.Easy+import qualified Data.Text.IO             as TIO+import qualified Data.Vector              as V++outDir :: FilePath+outDir = "design/ihaskell/"++-- セル 1: inline 散布図 (Resolver 不要、 IHaskellDisplay VisualSpec が描く図)+cell1 :: VisualSpec+cell1 =+     layer (scatter (inline xs) (inline ys) <> size 5)+  <> title "Cell 1: inline scatter (y = x²)"+  <> xLabel "x" <> yLabel "y"+  where+    xs = [0, 1 .. 9] :: [Double]+    ys = map (\x -> x * x) xs++-- セル 2: Easy 層 + 折れ線の重畳 (overlay)+cell2 :: VisualSpec+cell2 =+     layer (points xs ys <> size 5)+  <> layer (lineXY xs fitY <> color (fromHex "#d62728") <> stroke 2)+  <> title "Cell 2: Easy points + line overlay"+  where+    xs   = [0, 1 .. 9] :: [Double]+    ys   = map (\x -> x * x) xs+    fitY = map (\x -> 8 * x - 12) xs++-- セル 3: ColByName 図 + Resolver (DisplayPlot が描く図)+cell3Spec :: VisualSpec+cell3Spec =+     layer (scatter (ColByName "x") (ColByName "y") <> size 5)+  <> title "Cell 3: ColByName + Resolver"+  <> xLabel "x" <> yLabel "y"++cell3Resolver :: Resolver+cell3Resolver "x" = Just (NumData (V.fromList [0, 1, 2, 3, 4]))+cell3Resolver "y" = Just (NumData (V.fromList [3, 1, 4, 1, 5]))+cell3Resolver _   = Nothing++main :: IO ()+main = do+  TIO.writeFile (outDir ++ "cell1-inline-scatter.svg") (renderSVG cell1)+  TIO.writeFile (outDir ++ "cell2-easy-overlay.svg")    (renderSVG cell2)+  TIO.writeFile (outDir ++ "cell3-colbyname.svg")       (renderSVGWith cell3Resolver cell3Spec)+  putStrLn "wrote 3 demo SVGs to design/ihaskell/"
+ hgg-ihaskell.cabal view
@@ -0,0 +1,63 @@+cabal-version:      3.0+name:               hgg-ihaskell+version:            0.1.0.0+extra-doc-files:    CHANGELOG.md+synopsis:           iHaskell (Jupyter) inline display backend for hgg+description:+  A thin wiring package that displays hgg figures inline in Jupyter+  cells running the IHaskell kernel. It simply passes the Text returned+  by the SVG backend ('renderSVG') to IHaskell's SVG display. The+  @ihaskell@ dependency is isolated here, keeping hgg-core / hgg-svg+  dependency-clean.+license:            BSD-3-Clause+homepage:           https://github.com/frenzieddoll/hgg+license-file:       LICENSE+author:             Toshiaki Honda+maintainer:         frenzieddoll@gmail.com+copyright:          2026 Aelysce Project (Toshiaki Honda)+category:           Graphics+build-type:         Simple++common warnings+  ghc-options:        -Wall -Wcompat -Widentities -Wincomplete-record-updates+                      -Wincomplete-uni-patterns -Wpartial-fields+                      -Wredundant-constraints++library+  import:           warnings+  exposed-modules:  Graphics.Hgg.IHaskell+  hs-source-dirs:   src+  build-depends:    base               >= 4.17 && < 5+                  , text               >= 2.0  && < 2.2+                  , ihaskell           >= 0.11 && < 0.14+                  , hgg-core  ^>= 0.1+                  , hgg-frame ^>= 0.1+                  , hgg-svg   ^>= 0.1+  default-language: Haskell2010++-- Writes out the SVGs produced by each cell of design/ihaskell/demo.ipynb (for output verification)+executable ihaskell-demo-svg+  import:           warnings+  main-is:          DemoSvg.hs+  hs-source-dirs:   examples+  build-depends:    base               >= 4.17 && < 5+                  , text+                  , vector+                  , hgg-core+                  , hgg-svg+  default-language: Haskell2010++test-suite hgg-ihaskell-tests+  import:           warnings+  type:             exitcode-stdio-1.0+  main-is:          Spec.hs+  hs-source-dirs:   test+  build-depends:    base               >= 4.17 && < 5+                  , text+                  , vector+                  , containers+                  , ihaskell+                  , hgg-core+                  , hgg-frame+                  , hgg-ihaskell+  default-language: Haskell2010
+ src/Graphics/Hgg/IHaskell.hs view
@@ -0,0 +1,87 @@+-- |+-- Module      : Graphics.Hgg.IHaskell+-- Description : iHaskell (Jupyter) inline display 配線 (Phase 12)+-- Copyright   : (c) 2026 Aelysce Project (Toshiaki Honda)+-- License     : BSD-3-Clause+--+-- Jupyter (iHaskell kernel) のセルで hgg の図をインライン描画する+-- ための薄い配線。 描画は SVG backend の純関数 'renderSVG' をそのまま使い、+-- iHaskell の 'svg' display helper に 'Text' を渡すだけ (新規描画コード無し)。+--+-- == 使い方 (Jupyter セル)+--+-- @+-- import Graphics.Hgg.Easy+-- import Graphics.Hgg.IHaskell ()   -- インスタンスを見せるだけで良い+--+-- layer (points [0,1,2,3] [0,1,4,9]) <> title \"demo\"   -- ← セル評価でインライン描画+-- @+--+-- 'ColByName' を含む図 (= Resolver 必須) は 'BoundPlot' (@df |>> spec@) を使う。+-- 旧 'DisplayPlot' は Phase 14 で 'BoundPlot' に統合され deprecated。++-- orphan instance を意図的に許可: 'IHaskellDisplay' (ihaskell) を 'VisualSpec' /+-- 'BoundPlot' (core / frame) に与えるのは、 ihaskell 依存を本 package に隔離する+-- 設計上必須。+{-# OPTIONS_GHC -Wno-orphans #-}+module Graphics.Hgg.IHaskell+  ( -- * df バインド済図 (= 'ColByName' を含む図、 Phase 14 で正規化)+    BoundPlot (..)+    -- * 旧 Resolver 同伴図 (deprecated → 'BoundPlot' へ)+  , DisplayPlot (..)+    -- * 明示 helper (インスタンスに頼らず関数で出す場合)+  , displaySVG+  ) where++import           Graphics.Hgg.Backend.SVG (renderSVG, renderSVGWith)+import           Graphics.Hgg.Frame       (BoundPlot (..))+import           Graphics.Hgg.Spec        (Resolver, VisualSpec)+import           IHaskell.Display         (Display (..), IHaskellDisplay (..),+                                           svg)++-- ============================================================================+-- inline 図 (Resolver 不要 = Easy 層 / tutorial 系)+-- ============================================================================++-- | inline 列のみで構成された図 ('ColByName' を含まない) をセル評価値として+-- 直接インライン描画する。 'renderSVG' に 'emptyResolver' を渡す。+--+-- orphan instance (型は core、 class は ihaskell) だが、 ihaskell 表示配線は+-- 本 package に隔離する設計上意図的なもの。+instance IHaskellDisplay VisualSpec where+  display spec = pure (Display [svg (renderSVG spec)])++-- ============================================================================+-- df バインド済図 (= ColByName を含む図、 Phase 14 で正規化)+-- ============================================================================++-- | 'BoundPlot' (= @df |>> spec@ の結果) をセル評価値として描画する。+-- 'bpResolver' で 'ColByName' を解決し 'renderSVG' で SVG 化する。+-- 検証診断 ('bpDiagnostics') はインライン表示では無視する (Jupyter の stderr+-- には出ない経路ゆえ。 必要なら利用者が 'bpDiagnostics' を直接見る)。+instance IHaskellDisplay BoundPlot where+  display (BoundPlot r spec _) = pure (Display [svg (renderSVGWith r spec)])++-- ============================================================================+-- 旧 Resolver 同伴図 (deprecated → BoundPlot)+-- ============================================================================++-- | 'Resolver' と 'VisualSpec' を束ねた表示用 newtype。+--+-- __Deprecated__: Phase 14 で 'BoundPlot' (@df |>> spec@) に統合された。+-- 新規コードは 'BoundPlot' を使うこと。 当面は前方互換のため併存する。+newtype DisplayPlot = DisplayPlot (Resolver, VisualSpec)+{-# DEPRECATED DisplayPlot+      "Phase 14 で BoundPlot (Graphics.Hgg.Frame、 df |>> spec) に統合されました。 BoundPlot を使ってください。" #-}++instance IHaskellDisplay DisplayPlot where+  display (DisplayPlot (r, spec)) = pure (Display [svg (renderSVGWith r spec)])++-- ============================================================================+-- 明示 helper+-- ============================================================================++-- | 'Resolver' を明示して図を 'Display' にする。 inline 図なら+-- @displaySVG emptyResolver spec@、 'ColByName' を含む図なら実 resolver を渡す。+displaySVG :: Resolver -> VisualSpec -> Display+displaySVG r spec = Display [svg (renderSVGWith r spec)]
+ test/Spec.hs view
@@ -0,0 +1,67 @@+-- | Phase 12 iHaskell backend の単体 test。+-- ghci 相当の確認: 'display' が SVG を含む 'Display' を返すこと。+-- DisplayPlot は Phase 14 で deprecated だが後方互換確認のため残す → 警告抑制。+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -Wno-deprecations #-}+module Main (main) where++import           Graphics.Hgg.Easy     (layer, points, scatter, title)+import           Graphics.Hgg.Frame    (BoundPlot, (|>>))+import           Graphics.Hgg.IHaskell (DisplayPlot (..))+import           Graphics.Hgg.Spec     (ColData (..), ColRef (..), Resolver,+                                        VisualSpec)+import           Control.Monad         (unless)+import           Data.Map.Strict       (Map)+import qualified Data.Map.Strict       as M+import           Data.Text             (Text)+import qualified Data.Vector           as V+import           IHaskell.Display      (Display (..), display)+import           System.Exit           (exitFailure)++-- inline 列のみの図 (Resolver 不要)+demoSpec :: VisualSpec+demoSpec = layer (points [0, 1, 2, 3] [0, 1, 4, 9]) <> title "demo"++-- ColByName を含む図 (= Resolver 必須)+namedSpec :: VisualSpec+namedSpec = layer (scatter (ColByName "x") (ColByName "y")) <> title "named"++-- 列名 → 実 Vector を返す Resolver+demoResolver :: Resolver+demoResolver "x" = Just (NumData (V.fromList [0, 1, 2, 3]))+demoResolver "y" = Just (NumData (V.fromList [0, 1, 4, 9]))+demoResolver _   = Nothing++-- df (Map) → BoundPlot (Phase 14 A6 の正規ルート)+demoDF :: Map Text ColData+demoDF = M.fromList+  [ ("x", NumData (V.fromList [0, 1, 2, 3]))+  , ("y", NumData (V.fromList [0, 1, 4, 9])) ]++boundPlot :: BoundPlot+boundPlot = demoDF |>> (layer (scatter (ColByName "x") (ColByName "y")) <> title "bound")++displayLen :: Display -> Int+displayLen (Display ds)    = length ds+displayLen (ManyDisplay _) = -1++main :: IO ()+main = do+  -- A2 完了条件: inline 図 display が Display [<one DisplayData>] を返す+  dInline <- display demoSpec+  check "inline: display returns Display with one DisplayData"+        (displayLen dInline == 1)+  -- Phase 14 A6: BoundPlot (df |>> spec) を display できる (正規ルート)+  dBound <- display boundPlot+  check "bound: BoundPlot display returns Display with one DisplayData"+        (displayLen dBound == 1)+  -- 後方互換: 旧 DisplayPlot も依然 display できる (deprecated だが機能維持)+  dNamed <- display (DisplayPlot (demoResolver, namedSpec))+  check "named: DisplayPlot (deprecated) display still returns one DisplayData"+        (displayLen dNamed == 1)+  putStrLn "hgg-ihaskell: all tests passed"++check :: String -> Bool -> IO ()+check label ok = unless ok $ do+  putStrLn ("FAIL: " ++ label)+  exitFailure