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.

Revisions

  1. nrfm created this gist Sep 19, 2020.
    205 changes: 205 additions & 0 deletions bikent.cljs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,205 @@
    (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/[email protected]/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)}]]}]