Skip to content

Commit a816751

Browse files
committed
WIP: web: show result graph
1 parent 37cef1f commit a816751

File tree

5 files changed

+91
-21
lines changed

5 files changed

+91
-21
lines changed

function-graph.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ library
3232
, pretty-show
3333
, stringsearch
3434
, deepseq
35+
, graphviz
3536
hs-source-dirs: src/lib
3637
default-language: Haskell2010
3738

shell.nix

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pkgs.mkShell {
55
release-21-05.cabal-install
66
pkgs.zlib
77
pkgs.git
8+
pkgs.graphviz
89
];
910

1011
shellHook = ''

src/lib/FunGraph.hs

+18-3
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@
55
{-# LANGUAGE LambdaCase #-}
66
{-# LANGUAGE FlexibleContexts #-}
77
module FunGraph
8-
( runQueryAll, runQueryAllST, runQueryTreeST, runQuery, runQueryTrace
8+
( -- * Queries
9+
runQueryAll, runQueryTree, runQueryAllST, runQueryTreeST, runQuery, runQueryTrace
10+
-- * Conversions
11+
, queryResultTreeToPaths
912
, spTreeToPaths, spTreePathsCount
1013
, renderComposedFunctions, renderComposedFunctionsStr, parseComposedFunctions
1114
, renderFunction, parseFunction, renderTypedFunction
15+
-- * Types
1216
, Function(..), TypedFunction, UntypedFunction, PrettyTypedFunction, functionPackageNoVersion
1317
, FullyQualifiedType(..), textToFullyQualifiedType, fullyQualifiedTypeToText
14-
, bsToStr
15-
, module Export
1618
-- * Re-exports
19+
, module Export
1720
, Json.FunctionType
1821
, DG.IDigraph, DG.Digraph
1922
, NE.NonEmpty
@@ -63,6 +66,7 @@ functionWeight (src, dst) function
6366
fnPkg = _function_package function
6467
(srcPkg, dstPkg) = (fqtPackage src, fqtPackage dst)
6568

69+
-- | Run 'runQueryAllST'
6670
runQueryAll
6771
:: Int
6872
-> (FullyQualifiedType, FullyQualifiedType)
@@ -73,6 +77,17 @@ runQueryAll maxCount (src, dst) graph =
7377
g <- DG.thaw graph
7478
runQueryAllST (Dijkstra.runDijkstra g) maxCount (src, dst)
7579

80+
-- | Run 'runQueryTreeST'
81+
runQueryTree
82+
:: Int
83+
-> (FullyQualifiedType, FullyQualifiedType)
84+
-> DG.IDigraph FullyQualifiedType (NE.NonEmpty TypedFunction)
85+
-> [([NE.NonEmpty TypedFunction], Double)]
86+
runQueryTree maxCount (src, dst) graph =
87+
ST.runST $ do
88+
g <- DG.thaw graph
89+
runQueryTreeST (Dijkstra.runDijkstra g) maxCount (src, dst)
90+
7691
-- | Passed to 'runQueryAllST' to run without tracing
7792
runQuery
7893
:: DG.Digraph s v meta

src/lib/FunGraph/Util.hs

+31
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ module FunGraph.Util
77
, showTypeSig
88
, graphFromQueryResult
99
, graphToDot
10+
, graphToDotGraphviz
11+
, graphVizRender
12+
-- * Re-exports
13+
, Data.GraphViz.Commands.GraphvizCommand(..)
14+
, Data.GraphViz.Commands.GraphvizOutput(..)
1015
)
1116
where
1217

@@ -21,6 +26,11 @@ import qualified Data.Text.Encoding as TE
2126
import qualified Data.Text.Lazy as LT
2227
import Control.Monad.ST (ST)
2328
import qualified Data.Set as Set
29+
import qualified Data.GraphViz.Types
30+
import qualified Data.GraphViz.Types.Generalised
31+
import qualified Data.GraphViz.Commands
32+
import qualified Data.Text.IO as TIO
33+
import qualified Data.Text as T
2434

2535
-- | Convert sequence of adjacent edges to vertices moved through
2636
toPathTypes
@@ -64,6 +74,27 @@ graphToDot name =
6474
(bsToLT . _function_name . DG.eMeta)
6575
(bsToLT name)
6676

77+
graphToDotGraphviz
78+
:: BSC8.ByteString
79+
-> DG.Digraph s FullyQualifiedType (NE.NonEmpty TypedFunction)
80+
-> ST s (Data.GraphViz.Types.Generalised.DotGraph LT.Text)
81+
graphToDotGraphviz name =
82+
fmap Data.GraphViz.Types.parseDotGraph . graphToDot name
83+
84+
graphVizRender
85+
:: Data.GraphViz.Commands.GraphvizCommand -- ^ Layout
86+
-> Data.GraphViz.Commands.GraphvizOutput -- ^ Output format
87+
-> Data.GraphViz.Types.Generalised.DotGraph LT.Text -- ^ Actual graph
88+
-> IO T.Text
89+
graphVizRender graphvizCommand graphvizOutput g =
90+
Data.GraphViz.Commands.graphvizWithHandle
91+
graphvizCommand
92+
g
93+
graphvizOutput
94+
extractFromHandle
95+
where
96+
extractFromHandle = TIO.hGetContents
97+
6798
-- | Build a graph from the output of 'FunGraph.runQueryTreeST'
6899
graphFromQueryResult
69100
:: [([NE.NonEmpty TypedFunction], Double)]

src/server/Server/Pages/Search.hs

+40-18
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,52 @@ import qualified FunGraph
1515
import Data.List (intersperse)
1616
import qualified Data.Text.Encoding as TE
1717
import Data.Containers.ListUtils (nubOrd)
18+
import qualified FunGraph.Util as Util
19+
import qualified Control.Monad.ST as ST
20+
import Control.Monad.IO.Class (liftIO)
1821

1922
page :: FunGraph.FrozenGraph -> T.Text -> T.Text -> Word -> Handler (Html ())
20-
page graph src dst maxCount = pure $ do
21-
p_ $ "Hi there, you entered src=" <> mono (toHtml src) <> ", dst=" <> mono (toHtml dst)
22-
table_ $ do
23-
thead_ $
24-
tr_ $ do
25-
td_ "Function composition"
26-
td_ "Dependencies"
27-
tbody_ $
28-
forM_ (map fst results) $ \result ->
23+
page graph src dst maxCount = do
24+
resultGraph <- liftIO renderResultGraphIO
25+
pure $ do
26+
p_ $ "Hi there, you entered src=" <> mono (toHtml src) <> ", dst=" <> mono (toHtml dst)
27+
table_ $ do
28+
thead_ $
2929
tr_ $ do
30-
td_ $ renderResult result
31-
td_ $
32-
mconcat $
33-
intersperse ", " $
34-
map (mono . toHtml . TE.decodeUtf8) $
35-
nubOrd $
36-
map FunGraph.functionPackageNoVersion result
30+
td_ "Function composition"
31+
td_ "Dependencies"
32+
tbody_ $
33+
forM_ (map fst results) $ \result ->
34+
tr_ $ do
35+
td_ $ renderResult result
36+
td_ $
37+
mconcat $
38+
intersperse ", " $
39+
map (mono . toHtml . TE.decodeUtf8) $
40+
nubOrd $
41+
map FunGraph.functionPackageNoVersion result
42+
h2_ "Result graph"
43+
svg_ $ toHtml resultGraph
3744
where
45+
srcDst =
46+
(FunGraph.textToFullyQualifiedType src, FunGraph.textToFullyQualifiedType dst)
47+
3848
results =
39-
take (fromIntegral maxCount) $ FunGraph.runQueryAll
49+
take (fromIntegral maxCount) $
50+
FunGraph.queryResultTreeToPaths srcDst query
51+
52+
renderResultGraphIO =
53+
ST.stToIO resultDotGraph
54+
>>= Util.graphVizRender Util.Circo Util.Svg
55+
56+
resultDotGraph =
57+
Util.graphFromQueryResult query
58+
>>= Util.graphToDotGraphviz ""
59+
60+
query =
61+
FunGraph.runQueryTree
4062
(fromIntegral maxCount)
41-
(FunGraph.textToFullyQualifiedType src, FunGraph.textToFullyQualifiedType dst)
63+
srcDst
4264
graph
4365

4466
renderResult :: [FunGraph.TypedFunction] -> Html ()

0 commit comments

Comments
 (0)