Playground for visualizing graphs using Cytoscape.js in Clojure.
We define the default graph options:
(def ^:dynamic *default-graph-options*
{:style [{:selector "node"
:style {:background-color "#666"
:label "data(label)"}}
{:selector "edge"
:style {"width" 2
:line-color "#ccc"
:target-arrow-color "#ccc"
:curve-style "bezier"
:target-arrow-shape "triangle"
:label "data(label)"}}]
:layout {:name "circle"}
:userZoomingEnabled false
:userPanningEnabled false
:boxSelectionEnabled false})
A function that renders the graph specified by elements
on the container whose id is container-id
:
(defn cytoscape-clj [elements container-id]
(js/cytoscape
(clj->js (merge *default-graph-options*
{:container (js/document.getElementById container-id)
:elements elements})))
nil)
Let’s render a graph with some nodes and edges:
(def elements [{:data {:id "a"}}
{:data {:id "b"}}
{:data {:id "c"}}
{:data {:id "d"}}
{:data {:id "e"}}
{:data {:id "ab" :source "a" :target "b"}}
{:data {:id "ad" :source "a" :target "d"}}
{:data {:id "be" :source "b" :target "e"}}
{:data {:id "cb" :source "c" :target "b"}}
{:data {:id "de" :source "d" :target "e"}}])
(cytoscape-clj elements "graph-2")
Now we write functions that create edges and nodes for a fully-connected graph:
(defn edge [a b] {:data {:source a :target b}})
(defn connect-all [ids]
(for [a ids
b ids
:when (< a b)]
(edge a b)))
(defn nodes [ids]
(for [id ids]
{:data {:id id}}))
(defn elements [ids]
(concat (nodes ids)
(connect-all ids)))
We render a fully-connected directed graph with 6 nodes:
(cytoscape-clj (elements (range 6)) "graph-3")
We render a fully-connected undirected graph with 6 nodes:
(binding [*default-graph-options* (assoc-in *default-graph-options*
[:style 1 :style :target-arrow-shape] nil)]
(cytoscape-clj (elements (range 6)) "graph-4"))