packages feed

vp-tree-0.1.0.0: src/Data/VPTree/Draw.hs

{-# LANGUAGE LambdaCase #-}
{-# options_ghc -Wno-unused-imports #-}
module Data.VPTree.Draw (
  draw, drawVT
  -- * helpers
  , toStringVT
  ) where

import Text.Printf (PrintfArg, printf)
import Data.VPTree.Internal (VPTree(..), VT(..))

-- boxes
import qualified Text.PrettyPrint.Boxes as B (Box, render, emptyBox, vcat, hcat, text, top, bottom, center1)

-- | Render a tree to stdout
--
-- Useful for debugging
--
-- This should be called only for small trees, otherwise the printed result quickly overflows the screen and becomes hard to read.
--
-- NB : prints distance information rounded to two decimal digits
draw :: (Show a, PrintfArg d) => VPTree d a -> IO ()
draw = drawVT . vpTree

drawVT :: (Show a, PrintfArg d) => VT d a -> IO ()
drawVT = putStrLn . toStringVT

toStringVT :: (Show a, PrintfArg d) => VT d a -> String
toStringVT = B.render . toBox

toBox :: (Show a, PrintfArg d) => VT d a -> B.Box
toBox = \case
  (Bin d x tl tr) ->
    txt (node x d) `stack` (toBox tl `byside` toBox tr)
  Tip x -> txt $ show x
  -- Nil   -> txt "*"
  where
    node x d = printf "%s,%5.2f" (show x) d
    -- nodeBox x d =
    --   txt (printf "%s,%5.2f" (show x) d)

txt :: String -> B.Box
txt t = spc `byside` B.text t `byside` spc
  where spc = B.emptyBox 1 1

byside :: B.Box -> B.Box -> B.Box
byside l r = B.hcat B.top [l, r]

stack :: B.Box -> B.Box -> B.Box
stack t b = B.vcat B.center1 [t, b]