Skip to content

Instantly share code, notes, and snippets.

@nrfm
Created September 19, 2020 20:40
Show Gist options
  • Save nrfm/096fd6151d0e390ef56b3965922d7dc5 to your computer and use it in GitHub Desktop.
Save nrfm/096fd6151d0e390ef56b3965922d7dc5 to your computer and use it in GitHub Desktop.
(defn ->graph [g gr parent]
(let [l (or (:id g) (key g))
initial (or (:initial g) (-> g last :initial))
#_#__ (.log js/console "---- " initial (-> g last :initial))
n (name l)
{:keys [nodes edges]} gr
nodes' (conj nodes (let [] {:data {:id n :label n :parent parent}}))
edges' (into [] (concat edges
(if-let [on (:on (second g))]
(map
#(let [from n
type (first %)
to (last %)]
{:data {:id (str "" n type) :source from :target to :label type}})
(seq on))
[])))
]
(if-let [states (or (:states g) (:states (val g)))]
(reduce (fn [acc next] (->graph next acc n)) {:nodes (conj nodes' {:data {:id (str "$initial-" n) :label "$initial" :parent n}})
:edges (conj edges' {:data {:id (str "$initial-edge-" n)
:source (str "$initial-" n)
:target initial}})
} states)
{:nodes nodes' :edges edges'})
))
(defn gg
[{:keys [id graph style layout] :or {style {} layout {}}}]
(let [cy (r/atom nil)
opts {:style style
:layout layout}
on-update (fn [c] (js/console.log @cy))
on-mount (fn [c]
(js/setTimeout
(fn []
(reset! cy (js/cytoscape
(clj->js (merge {:container (.getElementById js/document (str "graph-view" id))
:elements {:nodes (:nodes graph)
:edges (:edges graph)}
:style
[{:selector "node"
:style {:label "data(id)"}}]
:layout {:name "random"
}
} opts))))
(on-update c))
1))
default-layout {:name "breadthfirst"
}
ids (atom 1)
add-node (fn []
(let [node-count (.-length (.nodes @cy))
node (.add @cy (clj->js [{:group "nodes"
:data {:id (swap! ids inc)}}
{:group "edges"
:data {:id (swap! ids inc)
:source (str (rand-int node-count))
:target (str (rand-int node-count))}}]))]
(.run (.layout (.elements @cy) (clj->js default-layout)))
)
)
]
(r/create-class
{:component-did-mount on-mount
:component-did-update on-update
:reagent-render (fn [props]
[:div
[:div
[ant/button {:on-click add-node} "add node"]]
[:div.w-full.h-screen
{:id (str "graph-view" id)
:style {}}
]]
)})))
[h/js-loader
{:scripts {#(exists? js/cytoscape) "https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.15.2/cytoscape.min.js"
#(exists? js/a) "https://cdn.jsdelivr.net/npm/cytoscape-cose-bilkent@4.1.0/cytoscape-cose-bilkent.min.js"}
:loading [:div "loading"]
:loaded [:div
[gg {:id "one"
:style
(str
"node[label != '$initial'] {
content: data(label);
text-valign: center;
text-halign: center;
shape: rectangle;
width: label;
height: label;
padding-left: 15px;
padding-right: 15px;
padding-top: 5px;
padding-bottom: 5px;
background-color: white;
font-size: 10px;
font-family: Helvetica Neue;
}
node:active {
overlay-color: black;
overlay-padding: 0;
overlay-opacity: 0.1;
}
.foo {
background-color: blue;
}
node[label = '$initial'] {
visibility: hidden;
}
$node > node {
padding-top: 1px;
padding-left: 15px;
padding-bottom: 15px;
padding-right: 15px;
text-valign: top;
text-halign: center;
background-color: #f5f5f5;
}
edge {
curve-style: bezier;
width: 1px;
target-arrow-shape: triangle;
label: data(label);
font-size: 5px;
font-weight: bold;
text-background-color: #fff;
text-background-padding: 3px;
line-color: black;
target-arrow-color: black;
z-index: 100;
text-wrap: wrap;
text-background-color: white;
text-background-opacity: 1;
target-distance-from-node: 2px;
}
edge[label = ''] {
source-arrow-shape: circle;
source-arrow-color: black;
}
node[label = 'loading']{
background-color: white;
}
")
:layout {:name "cose"}
:graph (->graph {:id "my-test/statechart"
:initial "initialising"
:states {:initialising {:on {:SYSTEM-START-SELECTED "not-casting"}}
:not-casting {:on {:USER-CAST-SELECTED "casting"}
:initial "nc-searching"
:states
{:nc-searching {:on {:USER-MOVIE-SELECTED "nc-detail-navigating"
:USER-SEARCH-SELECTED "nc-system-search-doing"}}
:nc-system-search-doing {:onEntry "do-movie-search"
:on {:SYSTEM-MOVIE-SEARCH-DONE "nc-searching"}}
:nc-detail-navigating {:onEntry "set-pre-selected-movie"
:on {:USER-BACK-SELECTED "nc-searching"
:USER-MOVIE-CONFIRMED "nc-playing"}}
:nc-playing {:onEntry "set-selected-movie"
:on {:USER-BACK-SELECTED "nc-detail-navigating"
:USER-STOP-SELECTED "nc-detail-navigating"
:USER-PAUSE-SELECTED "nc-pausing"}}
:nc-pausing {:on {:USER-RESUME-SELECTED "nc-playing"}}}}
:casting {:parallel true
:initial "mobile"
:on {:USER-STOP-CAST-SELECTED "not-casting"}
:states {:mobile {
:initial "searching"
:states {:searching {:on {:USER-MOVIE-SELECTED "detail-navigating"
:USER-SEARCH-SELECTED "system-search-doing"
:USER-PLAYING-DETAIL-SELECTED "playing-detail-navigation"}}
:system-search-doing {:onEntry "do-movie-search"
:on {:SYSTEM-MOVIE-SEARCH-DONE "searching"}}
:detail-navigating {:onEntry "set-pre-selected-movie"
:on {:USER-BACK-SELECTED "searching"
:USER-MOVIE-CONFIRMED "playing-detail-navigation"
:USER-PLAYING-DETAIL-SELECTED "playing-detail-navigation"}}
:playing-detail-navigation {:onEntry "set-selected-movie"
:on {
:USER-BACK_TO_SEARCHING_SELECTED "searching"
:USER-BACK_TO_DETAIL_SELECTED "detail-navigating"}}}
}
:external {
:initial "idling"
:states {:idling {:on {:USER-PLAY-SELECTED "playing"}}
:playing {:on {:USER-STOP-SELECTED "idling"
:USER-PAUSE-SELECTED "pausing"}}
:pausing {:on {:USER-RESUME-SELECTED "playing"
:USER-STOP-SELECTED "idling"}}}
}}
}}}
{:nodes [] :edges []} nil)}]]}]
@nrfm
Copy link
Author

nrfm commented Sep 19, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment