<div><div><div class="gmail_quote">Wed, Apr 1, 2009 at 11:20 PM, Claus Reinke <span dir="ltr">&lt;<a href="mailto:claus.reinke@talk21.com">claus.reinke@talk21.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">A platform-independent, open-source, 2d/3d graph layout engine<br></blockquote></div>
for incrementally updated graphs (where the graph after the update<br>
has to be similar enough to the one before that one can follow the<br>
animation and make sense of the data displayed) might be a good<br>
project for frp+opengl hackers - force equations between nodes,<br>
influenced by edges, and keeping the structure stable while adding<br>
nodes (parsed from an input stream).</blockquote><div><br></div>Something like this? <div><br></div><div><a href="http://en.wikipedia.org/wiki/Force-based_algorithms">http://en.wikipedia.org/wiki/Force-based_algorithms</a><br>
</div><div><br></div><div>Yes, I&#39;m all for it :-) The only problem is finding time to do it :-( Although QuickSilver might be able to pull this off easily?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888">Claus</font><div><div></div><div class="h5"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This cabalized project doesn&#39;t appear to be on hackage!<br>
<br>
gleb.alexeev:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Don Stewart wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I am pleased to announce the release of vacuum-cairo, a Haskell library<br>
for interactive rendering and display of values on the GHC heap using<br>
Matt Morrow&#39;s vacuum library.<br>
</blockquote>
<br>
Awesome stuff, kudos to you and Matt Morrow!<br>
<br>
I thought it&#39;d be fun to visualize data structures in three dimensions.<br>
Attached is quick and dirty hack based on your code and Ubigraph server<br>
(<a href="http://ubietylab.net/ubigraph/" target="_blank">http://ubietylab.net/ubigraph/</a>).<br>
<br>
The demo video (apologies for poor quality):<br>
<a href="http://www.youtube.com/watch?v=3mMH1cHWB6c" target="_blank">http://www.youtube.com/watch?v=3mMH1cHWB6c</a><br>
<br>
If someone finds it fun enough, I&#39;ll cabalize it and upload to Hackage.<br>
</blockquote>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
module Ubigraph where<br>
<br>
import Network.XmlRpc.Client<br>
<br>
type Url = String<br>
type VertexId = Int<br>
type EdgeId = Int<br>
<br>
defaultServer = &quot;<a href="http://127.0.0.1:20738/RPC2" target="_blank">http://127.0.0.1:20738/RPC2</a>&quot;<br>
<br>
void :: IO Int -&gt; IO ()<br>
void m = m &gt;&gt; return ()<br>
<br>
clear :: Url -&gt; IO ()<br>
clear url = void (remote url &quot;ubigraph.clear&quot;)<br>
<br>
newVertex :: Url -&gt; IO VertexId<br>
newVertex url = remote url &quot;ubigraph.new_vertex&quot;<br>
<br>
newEdge :: Url -&gt; VertexId -&gt; VertexId -&gt; IO EdgeId<br>
newEdge url = remote url &quot;ubigraph.new_edge&quot;<br>
<br>
removeVertex :: Url -&gt; VertexId -&gt; IO ()<br>
removeVertex url vid = void (remote url &quot;ubigraph.remove_vertex&quot; vid)<br>
<br>
removeEgde :: Url -&gt; EdgeId -&gt; IO ()<br>
removeEgde url eid= void (remote url &quot;ubigraph.remove_edge&quot; eid)<br>
<br>
<br>
zeroOnSuccess :: IO Int -&gt; IO Bool<br>
zeroOnSuccess = fmap (==0)<br>
<br>
newVertexWithId :: Url -&gt; VertexId -&gt; IO Bool<br>
newVertexWithId url vid = zeroOnSuccess (remote url &quot;ubigraph.new_vertex_w_id&quot; vid)<br>
<br>
newEdgeWithId :: Url -&gt; EdgeId -&gt; VertexId -&gt; VertexId -&gt; IO Bool<br>
newEdgeWithId url eid x y = zeroOnSuccess (remote url &quot;ubigraph.new_edge_w_id&quot; eid x y)<br>
<br>
setVertexAttribute :: Url -&gt; VertexId -&gt; String -&gt; String -&gt; IO Bool<br>
setVertexAttribute url vid attr val = zeroOnSuccess (remote url &quot;ubigraph.set_vertex_attribute&quot; vid attr val)<br>
<br>
setEdgeAttribute :: Url -&gt; VertexId -&gt; String -&gt; String -&gt; IO Bool<br>
setEdgeAttribute url eid attr val = zeroOnSuccess (remote url &quot;ubigraph.set_edge_attribute&quot; eid attr val)<br>
</blockquote>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
module VacuumUbigraph where<br>
<br>
import GHC.Vacuum<br>
import Data.Char<br>
import Text.Printf<br>
import Data.List<br>
<br>
import qualified Data.IntMap as IntMap<br>
import qualified Data.IntSet as IntSet<br>
<br>
import qualified Ubigraph as U<br>
<br>
nodeStyle n =<br>
    case nodeName n of<br>
      &quot;:&quot;  -&gt; (&quot;(:)&quot;, &quot;cube&quot;, &quot;#0000ff&quot;)<br>
<br>
      -- atomic stuff is special<br>
      k | k `elem` [&quot;S#&quot; ,&quot;I#&quot; ,&quot;W#&quot;<br>
                   ,&quot;I8#&quot; ,&quot;I16#&quot; ,&quot;I32#&quot; ,&quot;I64#&quot;<br>
                   ,&quot;W8#&quot; ,&quot;W16#&quot; ,&quot;W32#&quot; ,&quot;W64#&quot;] -&gt; (showLit n, &quot;sphere&quot;, &quot;#00ff00&quot;)<br>
      -- chars<br>
      &quot;C#&quot; -&gt; (show . chr . fromIntegral . head . nodeLits $ n, &quot;sphere&quot;, &quot;#00ff00&quot;)<br>
      &quot;D#&quot; -&gt; (&quot;Double&quot;, &quot;sphere&quot;, &quot;#009900&quot;)<br>
      &quot;F#&quot; -&gt; (&quot;Float&quot;, &quot;sphere&quot;, &quot;#009900&quot;)<br>
<br>
      -- bytestrings<br>
      &quot;PS&quot;    -&gt; (printf &quot;ByteString[%d,%d]&quot; (nodeLits n !! 1) (nodeLits n !! 2), &quot;cube&quot;, &quot;#ff0000&quot;)<br>
      &quot;Chunk&quot; -&gt; (printf &quot;Chunk[%d,%d]&quot; (nodeLits n !! 1) (nodeLits n !! 2), &quot;cube&quot;, &quot;#ff0000&quot;)<br>
<br>
      -- otherwise just the constructor and local fields<br>
      c   | z &gt; 0 -&gt;<br>
                    (c ++ show (take (fromIntegral z) $ nodeLits n), &quot;cube&quot;, &quot;#990000&quot;)<br>
          | otherwise -&gt; (c, &quot;cube&quot;, &quot;#990000&quot;)<br>
                    where z = itabLits (nodeInfo n)<br>
        where<br>
          showLit n = show (head $ nodeLits n)<br>
<br>
view a = do<br>
  U.clear srv<br>
  mapM_ renderNode nodes<br>
  mapM_ renderEdge edges<br>
    where<br>
      g = vacuum a<br>
      alist = toAdjList g<br>
      nodes = nub $ map fst alist ++ concatMap snd alist<br>
      edges = concatMap (\(n, ns) -&gt; map ((,) n) ns) alist<br>
<br>
      style nid = maybe (&quot;...&quot;, &quot;cube&quot;, &quot;#ff0000&quot;) nodeStyle (IntMap.lookup nid g)<br>
<br>
      renderNode nid = do<br>
           U.newVertexWithId srv nid<br>
           let (label, shape, color) = style nid<br>
           U.setVertexAttribute srv nid &quot;label&quot; label<br>
           U.setVertexAttribute srv nid &quot;shape&quot; shape<br>
           U.setVertexAttribute srv nid &quot;color&quot; color<br>
<br>
      renderEdge (a, b) = do<br>
           e &lt;- U.newEdge srv a b<br>
           U.setEdgeAttribute srv e &quot;stroke&quot; &quot;dotted&quot;<br>
           U.setEdgeAttribute srv e &quot;arrow&quot; &quot;true&quot;<br>
<br>
      srv = U.defaultServer<br>
<br>
</blockquote>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a> <br>
</blockquote>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div></div>