deptrack-dot-0.1.0.0: src/DepTrack/Dot.hs
-- | Module providing helpers to get a Dot representation of tracked
-- dependencies during a DepTrack computation.
--
-- This module currently uses 'Text.Dot' from 'dotgen' as a Dot generator, this
-- choice may change in the future.
module DepTrack.Dot (DotDescription(..), dotifyGraphWith, dotify) where
import DepTrack (DepTrackT, GraphData, buildGraph, evalDepForest1)
import Data.Graph (edges, vertices)
import qualified Text.Dot as Dot
-- | A type to hide a Dot program.
newtype DotDescription = DotDescription { getDotDescription :: String }
deriving (Eq, Ord, Show)
-- | Dotify some pre-calculed GraphData.
dotifyGraphWith
:: (x -> [(String,String)])
-- ^ Function to return a set of graphviz key-value attributes (e.g., ("shape","egg"))
-> GraphData x k
-- ^ The graph data to represent.
-> DotDescription
dotifyGraphWith attributes (g,lookupF,_) =
DotDescription $ Dot.showDot dotted
where
dotted :: Dot.Dot ()
dotted = do
let node v = y where (y,_,_) = lookupF v
let vs = vertices g
let es = filter (uncurry (/=)) $ edges g
mapM_ (\i -> Dot.userNode (Dot.userNodeId i) (attributes (node i))) vs
mapM_ (\(i,j) -> Dot.edge (Dot.userNodeId i) (Dot.userNodeId j) []) es
-- | Graphs the dependenciees of a DepTrack computation.
--
-- Throws away the result and only keep the DotDescription.
dotify
:: (Monad m, Ord k, Show x)
=> (x -> [(String,String)])
-- ^ Function to return a set of graphviz key-value attributes (e.g., ("shape","egg"))
-> (x -> k)
-- ^ Function to identify every node in the graph uniquely. If this function
-- is non injective you may confuse two distinct nodes as a same node.
-> DepTrackT x m a
-- ^ The computation to graph.
-> m DotDescription
dotify labelsF keyF x =
dotifyGraphWith labelsF . buildGraph keyF . snd <$> evalDepForest1 x