Commit changes

This commit is contained in:
Daniel Compton 2016-11-15 15:06:10 +13:00
parent c6384dcd74
commit 6b8b961d13
5 changed files with 259 additions and 572 deletions

View File

@ -11,7 +11,10 @@
[reagent.ratom :as ratom]
[re-frame.utils :as rutils]
[goog.object :as gob]
[re-frame.interop :as interop]))
[re-frame.interop :as interop]
[devtools.formatters.core :as devtools]
))
(defn comp-name [c]
(let [n (or (component/component-path c)
@ -72,7 +75,8 @@
(fn [] (this-as c
(trace/with-trace {:op-type key
:operation (last (str/split (comp-name c) #" > "))
:tags {:component-path (reagent.impl.component/component-path c)}})
:tags {:component-path (reagent.impl.component/component-path c)
:reaction (rutils/reagent-id ($ c :cljsRatom))}})
(.call (real-custom-wrapper key f) c c)))
(real-custom-wrapper key f))))
@ -151,7 +155,9 @@
[:tbody
(doall
(for [{:keys [type id operation tags duration] :as trace} showing-traces]
(let [row-style (merge padding {:border-top (case type :event "1px solid lightgrey" nil)})]
(let [row-style (merge padding {:border-top (case type :event "1px solid lightgrey" nil)})
_ (js/console.log (devtools/header-api-call tags))
]
(list [:tr {:key id
:style {:color (case type
:sub/create "green"
@ -169,7 +175,8 @@
(.toFixed duration 1) " ms"]]
(when true
[:tr {:key (str id "-details")}
[:td {:col-span 3} (with-out-str (pprint/pprint (dissoc tags :query-v :event :duration)))]])))))]]]))))
[:td {:col-span 3} (with-out-str (pprint/pprint (dissoc tags :query-v :event :duration)))]])
))))]]]))))
(defn resizer-style [draggable-area]
{:position "absolute" :z-index 2 :opacity 0

View File

@ -1,110 +1,37 @@
(ns day8.re-frame.trace.d3
(:require [reagent.core :as r]))
(defn component-did-update [{:keys [d3-enter d3-update d3-exit]} ratoms]
(apply d3-enter ratoms)
(apply d3-update ratoms)
(apply d3-exit ratoms))
(defn component-did-mount [{:keys [d3-did-mount] :as lifecycle-fns} ratoms]
(apply d3-did-mount ratoms)
(component-did-update lifecycle-fns ratoms))
(defn no-op [desc]
(fn [& args]
(println "No-op" desc)))
(fn [& args] nil))
(defn component-did-update [{:keys [d3-update]} ratoms]
(apply d3-update ratoms))
(defn component-did-mount [{:keys [d3-once] :as lifecycle-fns} ratoms]
(apply d3-once ratoms)
(component-did-update lifecycle-fns ratoms))
(defn create-d3
"Creates a bridging component from Reagent to D3. Takes a map of
lifecycle functions, and reactive data sources.
:render-component - Render the outer Reagent component, and a place for your D3 component to mount to (probably an SVG element)
:d3-did-mount - Function called after the component has been rendered, for you to setup anything you need in D3 (e.g. adding <g> or classes)
:d3-enter, :d3-update, :d3-exit - correspond to functions in the D3 general update pattern: https://bl.ocks.org/mbostock/3808218
:d3-once - Function called after the component has been rendered, for you to setup anything you need in D3 (e.g. adding <g> or classes)
:d3-update - Run the D3 general update pattern: https://bl.ocks.org/mbostock/3808218
"
[{:keys [render-component d3-did-mount d3-enter d3-update d3-exit]
:or {render-component no-op
d3-did-mount (no-op :d3-did-mount)
d3-enter (no-op :d3-enter)
d3-update (no-op :d3-update)
d3-exit (no-op :d3-exit)}}
[{:keys [render-component d3-once d3-update]
:or {render-component (no-op :render)
d3-once (no-op :d3-did-mount)
d3-update (no-op :d3-update)}}
& ratoms]
(let [lifecycle-fns {:render-component render-component
:d3-did-mount d3-did-mount
:d3-enter d3-enter
:d3-update d3-update
:d3-exit d3-exit}]
:d3-once d3-once
:d3-update d3-update}]
(r/create-class
{:reagent-render (fn []
(doseq [r ratoms] (deref r))
(apply render-component ratoms))
:component-did-mount (fn [this] (component-did-mount lifecycle-fns ratoms))
:component-did-update (fn [this old-argv] (component-did-update lifecycle-fns ratoms))}))
)
;;;;
;;;;
;;; app
;
;
;(def data (r/atom {}))
;
;(defn my-render [ratom]
; (let [width 100
; height 100]
; [:div
; {:id "barchart"}
; [:svg
; {:width width
; :height height}]]))
;
;(defn bars-did-mount [ratom]
; (-> (js/d3.select "#barchart svg")
; (.append "g")
; (.attr "class" "container")
; (.append "g")
; (.attr "class" "bars")))
;
;(defn bars-enter [ratom]
; (let [data (get-data ratom)]
; (-> (js/d3.select "#barchart svg .container .bars")
; (.selectAll "rect")
; (.data (clj->js data))
; .enter
; (.append "rect"))))
;
;(defn bars-update [ratom]
; (let [width (get-width ratom)
; height (get-height ratom)
; data (get-data ratom)
; data-n (count data)
; rect-height (/ height data-n)
; x-scale (-> js/d3
; .scaleLinear
; (.domain #js [0 5])
; (.range #js [0 width]))]
; (-> (js/d3.select "#barchart svg .container .bars")
; (.selectAll "rect")
; (.data (clj->js data))
; (.attr "fill" "green")
; (.attr "x" (x-scale 0))
; (.attr "y" (fn [_ i]
; (* i rect-height)))
; (.attr "height" (- rect-height 1))
; (.attr "width" (fn [d]
; (x-scale (aget d "x")))))))
;
;(defn bars-exit [ratom]
; (let [data (get-data ratom)]
; (-> (js/d3.select "#barchart svg .container .bars")
; (.selectAll "rect")
; (.data (clj->js data))
; .exit
; .remove)))
;
;(create-d3 data {:reagent-render my-render
; :d3-did-mount bars-did-mount
; :d3-enter bars-enter
; :d3-update bars-update
; :d3-exit bars-exit})
:component-did-mount (fn [this]
(component-did-mount lifecycle-fns ratoms))
:component-did-update (fn [this old-argv]
(component-did-update lifecycle-fns ratoms))})))

View File

@ -0,0 +1,86 @@
(ns day8.re-frame.trace.graph
(:require [clojure.set :as set]))
(defn select-type [type traces]
(filter #(= type (:type %)) traces))
(defn get-reaction [trace]
(get-in trace [:tags :reaction]))
(defn distinct-k
"Returns a lazy sequence of the elements of coll with duplicates removed."
([key-fn coll]
(let [step (fn step [xs seen]
(lazy-seq
((fn [[f :as xs] seen]
(when-let [s (seq xs)]
(let [f-fn (key-fn f)]
(if (contains? seen f-fn)
(recur (rest s) seen)
(cons f (step (rest s) (conj seen f-fn)))))))
xs seen)))]
(step coll #{}))))
(defn select-links [traces type disposed-ids link-val]
(->> traces
(select-type type)
(remove #(contains? disposed-ids (get-reaction %)))
(mapcat (fn [trace]
(for [input-signal (get-in trace [:tags :input-signals])
:let [reaction (get-reaction trace)]
:when (every? some? [input-signal reaction])]
{:source input-signal :target reaction :value link-val
:id (str input-signal "|" reaction)})))
(into {} (map (fn [trace] [(:id trace) trace])))
(vals)))
(defn select-sub-nodes [traces type disposed-ids r]
(->> traces
(select-type type)
(remove #(contains? disposed-ids (get-reaction %)))
(remove #(get-in % [:tags :cached?]))
(map (fn [trace]
{:id (get-reaction trace)
:title (str (:operation trace))
:group 2
:r r
:data trace}))
(into {} (map (fn [trace] [(:id trace) trace])))
(vals)))
(defn select-view-nodes [traces type unmounted-components r]
(->> traces
(select-type type)
(remove #(contains? unmounted-components (:id %)))
(map (fn [trace]
{:id (get-reaction trace)
:title (str (get-reaction trace) " " (:operation trace))
:group 3
:r r
:data trace
:fx 250}))
(remove #(nil? (:id %))) ;; remove reactions that are null (mostly from input fields???)
(into {} (map (fn [trace] [(:id trace) trace])))
(vals)
))
(defn trace->sub-graph [traces extra-nodes]
(let [disposed-ids (->> (select-type :sub/dispose traces)
(map get-reaction)
set)
unmounted-components (->> (select-type :componentWillUnmount traces)
(map get-reaction)
set)
sub-nodes (select-sub-nodes traces :sub/create disposed-ids 10)
view-nodes (select-view-nodes traces :render unmounted-components 5)
sub-links (select-links traces :sub/run disposed-ids 1)
view-links (select-links traces :render unmounted-components 0.5)
all-nodes (concat extra-nodes sub-nodes view-nodes)
node-ids (set (map :id all-nodes))
nodes-links (->> (mapcat (fn [{:keys [source target]}] [source target]) view-links) set)
missing-nodes (set/difference nodes-links node-ids) ;; These are local ratoms
view-links (->> view-links
(remove #(get missing-nodes (:source %))))
all-links (concat sub-links view-links)]
{:nodes all-nodes
:links all-links}))

View File

@ -1,6 +1,7 @@
(ns day8.re-frame.trace.subvis
(:require cljsjs.d3
[day8.re-frame.trace.d3 :as d3t]
[day8.re-frame.trace.graph :as graph]
[reagent.core :as r]
[re-frame.utils :as rutils]
[re-frame.db :as db]
@ -8,80 +9,20 @@
[clojure.set :as set]))
(def width 400)
(def height 200)
(def height 400)
(def mygraph (r/atom {:nodes [{:id 1 :group 1}
{:id 2 :group 1}
{:id 3 :group 2}]
:links [{:source 1 :target 2 :value 1}]}))
(defn trace->sub-graph [traces]
(let [disposed (->> traces
(filter #(#{:sub/dispose} (:type %)))
(map #(get-in % [:tags :reaction]))
set)
sub-nodes (->> traces
(filter #(#{:sub/create} (:type %)))
(remove #(contains? disposed (get-in % [:tags :reaction])))
(remove #(get-in % [:tags :cached?]))
(map (fn [trace]
{:id (get-in trace [:tags :reaction])
:title (str (:operation trace))
:group (mod (:id trace) 20)
:r 10
:data trace})))
(def app-db-node {:id (rutils/reagent-id db/app-db)
:title "app-db"
:group 1
:r 20
:fx 15
:fy (/ height 2)})
unmounted-components #{}
view-nodes (->> traces
(filter #(#{:render} (:type %)))
(remove #(contains? unmounted-components (:id %))) ;; todo
(map (fn [trace]
{:id (get-in trace [:tags :reaction])
:title (:operation trace)
:group (mod (:id trace) 20)
:r 5
:data trace}))
)
sub-links (->> traces
(filter #(#{:sub/run} (:type %)))
(remove #(contains? disposed (get-in % [:tags :reaction])))
(mapcat (fn [trace]
(for [input-signal (get-in trace [:tags :input-signals])
:let [reaction (get-in trace [:tags :reaction])]
:when (every? some? [input-signal reaction])]
{:source input-signal :target reaction :value 1}))))
view-links (->> traces
(filter #(#{:render} (:type %)))
(remove #(contains? unmounted-components (get-in % [:tags :reaction])))
(mapcat (fn [trace]
(for [input-signal (get-in trace [:tags :input-signals])
:let [reaction (get-in trace [:tags :reaction])]
:when (every? some? [input-signal reaction])]
{:source input-signal :target reaction :value 0.5}))))
app-db {:id (rutils/reagent-id db/app-db)
:title "app-db"
:group 1
:r 20
:fx (/ width 2)
:fy 30}
all-nodes (concat sub-nodes [app-db] view-nodes)
node-ids (set (map :id all-nodes))
nodes-links (->> (mapcat (fn [{:keys [source target]}] [source target]) view-links)
set)
missing-nodes (set/difference nodes-links node-ids) ;; These are local ratoms
view-links (->> view-links
(remove #(get missing-nodes (:source %))))
]
{:nodes all-nodes
:links (concat sub-links view-links)}))
(defn min-max
"Returns x if it is within min-val and max-val
@ -93,267 +34,76 @@
(assert (<= min-val max-val))
(cljs.core/max min-val (cljs.core/min x max-val)))
(defn force-inner [graph]
(r/create-class
{:reagent-render (fn [] [:div [:svg {:width width :height height}]])
:component-did-mount (fn []
(let [nodes (clj->js (:nodes graph))
links (clj->js (:links graph))
color (.scaleOrdinal js/d3 (.-schemeCategory20 js/d3))
svg (. js/d3 select "svg")
simulation (.. js/d3
(forceSimulation)
(force "link" (.. js/d3 (forceLink)
(id #(.-id %))
(distance (constantly 100))))
(force "charge" (.. js/d3 (forceManyBody)
(strength (constantly -100))))
(force "center" (. js/d3 forceCenter (/ width 2) (/ height 2))))
dragstarted (fn [d]
(when (zero? (.. js/d3 -event -active))
(.. simulation
(alphaTarget 0.3)
(restart)))
(set! (.-fx d) (.-x d))
(set! (.-fy d) (.-y d)))
dragged (fn [d]
(set! (.-fx d) (.. js/d3 -event -x))
(set! (.-fy d) (.. js/d3 -event -y)))
dragended (fn [d]
(when (zero? (.. js/d3 -event -active))
(.. simulation
(alphaTarget 0.0)))
(set! (.-fx d) nil)
(set! (.-fy d) nil))
link (.. (. svg append "g")
(attr "class" "links")
(selectAll "line")
(data links)
(enter)
(append "line")
(attr "stroke-width" (fn [d] (Math/sqrt (.-value d)))))
node (.. (. svg append "g")
(attr "class" "nodes")
(selectAll "circle")
(data nodes)
(enter)
(append "g")
(attr "class" "node"))
circle (.. node
(append "circle")
(attr "r" #(or (gob/get % "r" 10)))
(attr "fill" (fn [d] (color (.-group d))))
(call (.. (. js/d3 drag)
(on "start" dragstarted)
(on "drag" dragged)
(on "end" dragended))))
label (.. node
(append "text")
(attr "dy" ".35em")
(text #(gob/get % "title" "")))
ticked (fn []
(.. link
(attr "x1" (fn [d] (.. d -source -x)))
(attr "y1" (fn [d] (.. d -source -y)))
(attr "x2" (fn [d] (.. d -target -x)))
(attr "y2" (fn [d] (.. d -target -y))))
(.. circle
(attr "cx" (fn [d] (min-max (.. d -r) (.. d -x) (- width (.. d -r)))))
(attr "cy" (fn [d] (min-max (.. d -r) (.. d -y) (- height (.. d -r))))))
(.. label
(attr "x" #(+ (.-x %) 2 (.-r %)))
(attr "y" #(+ (.-y %))))
nil)
]
(.. simulation
(nodes nodes)
(on "tick" ticked))
(.. simulation
(force "link")
(links links))))
:component-did-update (fn [this]
#_(let [[_ data] (r/argv this)
d3data (clj->js data)
circles (.. js/d3
(select "svg")
(selectAll "circle")
(data d3data (fn [d i] (when d (.-name d)))))]
(.. circles
;(attr "cx" (fn [d] (.-x d)))
;(attr "cy" (fn [d] (.-y d)))
;(attr "r" (fn [d] (.-r d)))
enter
(append "circle")
(attr "cx" 200)
(attr "cy" 200)
(attr "r" 500)
(transition)
(attr "cx" (fn [d] (.-x d)))
(attr "cy" (fn [d] (.-y d)))
(attr "r" (fn [d] (.-r d)))
(attr "fill" (fn [d] (.-color d))))
(.. circles
exit
remove)))}))
(defn force-outer [traces-ratom]
(defn ticked [selector]
(fn []
(let [trace-graph (trace->sub-graph @traces-ratom)]
[force-inner trace-graph])))
(defonce desc (r/atom 1))
;(println "ticked")
(let [link-sel (.. selector
(selectAll "g.links > line"))
circle-sel (.. selector
(selectAll "g.node > circle"))
label-sel (.. selector
(selectAll "g.node > text"))]
(.. link-sel
(attr "x1" (fn [d] (.. d -source -x)))
(attr "y1" (fn [d] (.. d -source -y)))
(attr "x2" (fn [d] (.. d -target -x)))
(attr "y2" (fn [d] (.. d -target -y))))
(.. circle-sel
(attr "cx" (fn [d] (set! (.-x d) (min-max (.. d -r) (.. d -x) (- width (.. d -r))))))
(attr "cy" (fn [d] (set! (.-y d) (min-max (.. d -r) (.. d -y) (- height (.. d -r)))))))
(.. label-sel
(attr "x" (fn [d] (+ 2 (.-x d) (.-r d))))
(attr "y" #(+ (.-y %)))))))
(defn render-subvis [traces-ratom]
(let [color-a (atom nil)
svg-a (atom nil)
simulation-a (atom nil)]
simulation-a (atom nil)
run? (atom false)]
(fn []
(println "Render subvis")
[:div
{:style {:padding "10px"}}
[:h1 "SUBVIS"]
[force-outer traces-ratom]
[:hr]
[:h2 {:on-click #(swap! desc inc)} "Click"]
[(d3t/create-d3
{:render-component (fn [ratom]
[:div
[:h1 (str "SVG")]
[:svg#d3cmp {:width width :height height}]])
:d3-did-mount (fn [ratom]
(let [graph (trace->sub-graph @ratom)
[d3t/create-d3
{:render-component (fn [ratom]
[:svg#d3cmp {:width width :height height}])
:d3-once (fn [ratom]
(let [color (reset! color-a (.scaleOrdinal js/d3 (.-schemeCategory20 js/d3)))
svg (reset! svg-a (. js/d3 select "#d3cmp"))
simulation (reset! simulation-a
(.. js/d3
(forceSimulation)
(force "link" (.. js/d3 (forceLink)
(id #(.-id %))
(distance (constantly 100))))
(force "charge" (.. js/d3 (forceManyBody)
(strength (constantly -100))))
(force "center" (. js/d3 forceCenter (/ width 2) (/ height 2)))))
link (.. (. svg append "g")
(attr "class" "links"))
node (.. (. svg append "g")
(attr "class" "nodes"))]))
:d3-update (fn [ratom]
(when-not false #_@run?
#_(reset! run? true)
(let [graph (graph/trace->sub-graph @ratom [app-db-node])
nodes (clj->js (:nodes graph))
links (clj->js (:links graph))
color (reset! color-a (.scaleOrdinal js/d3 (.-schemeCategory20 js/d3)))
svg (reset! svg-a (. js/d3 select "#d3cmp"))
simulation (reset! simulation-a
(.. js/d3
(forceSimulation)
(force "link" (.. js/d3 (forceLink)
(id #(.-id %))
(distance (constantly 100))))
(force "charge" (.. js/d3 (forceManyBody)
(strength (constantly -100))))
(force "center" (. js/d3 forceCenter (/ width 2) (/ height 2)))))
dragstarted (fn [d]
(when (zero? (.. js/d3 -event -active))
(.. simulation
(alphaTarget 0.3)
(restart)))
(set! (.-fx d) (.-x d))
(set! (.-fy d) (.-y d)))
dragged (fn [d]
(set! (.-fx d) (.. js/d3 -event -x))
(set! (.-fy d) (.. js/d3 -event -y)))
dragended (fn [d]
(when (zero? (.. js/d3 -event -active))
(.. simulation
(alphaTarget 0.0)))
(set! (.-fx d) nil)
(set! (.-fy d) nil))
link (.. (. svg append "g")
(attr "class" "links")
(selectAll "line")
(data links)
(enter)
(append "line")
(attr "stroke-width" (fn [d] (Math/sqrt (.-value d))))
)
node (.. (. svg append "g")
(attr "class" "nodes")
(selectAll "circle")
(data nodes)
(enter)
(append "g")
(attr "class" "node"))
circle (.. node
(append "circle")
(attr "r" #(or (gob/get % "r" 10)))
(attr "fill" (fn [d] (color (.-group d))))
(call (.. (. js/d3 drag)
(on "start" dragstarted)
(on "drag" dragged)
(on "end" dragended))))
label (.. node
(append "text")
(attr "dy" ".35em")
(text #(gob/get % "title" "")))
ticked (fn []
(let [link-sel (.. svg
(selectAll ".links > line"))
circle-sel (.. svg
(selectAll ".node > circle"))
label-sel (.. svg
(selectAll ".node > text"))]
(.. link-sel
(attr "x1" (fn [d] (.. d -source -x)))
(attr "y1" (fn [d] (.. d -source -y)))
(attr "x2" (fn [d] (.. d -target -x)))
(attr "y2" (fn [d] (.. d -target -y))))
(.. circle-sel
(attr "cx" (fn [d] (min-max (.. d -r) (.. d -x) (- width (.. d -r)))))
(attr "cy" (fn [d] (min-max (.. d -r) (.. d -y) (- height (.. d -r))))))
(.. label-sel
(attr "x" #(+ (.-x %) 2 (.-r %)))
(attr "y" #(+ (.-y %)))))
nil)
]
(.. simulation
(nodes nodes)
(on "tick" ticked))
(.. simulation
(force "link")
(links links))
))
:d3-enter (fn [ratom]
(let [graph (trace->sub-graph @ratom)
nodes (clj->js (:nodes graph))
links (clj->js (:links graph))
svg @svg-a
color @color-a
simulation @simulation-a
_ (js/console.log "d3ent" (.. svg
(selectAll ".links > line")
size))
dragstarted (fn [d]
(when (zero? (.. js/d3 -event -active))
(.. simulation
(alphaTarget 0.3)
(restart)))
(set! (.-fx d) (.-x d))
(set! (.-fy d) (.-y d)))
#_(set! (.-fx d) (.. js/d3 -event -x)) ; (.-x d)
#_(set! (.-fy d) (.. js/d3 -event -y)))
dragged (fn [d]
(set! (.-fx d) (.. js/d3 -event -x))
@ -366,23 +116,27 @@
(set! (.-fx d) nil)
(set! (.-fy d) nil))
link (.. (. svg append "g")
(attr "class" "links")
link (.. svg
(select ".links")
(selectAll "line")
(data links)
(data links (fn [d] (.-id d))))
new-link (.. link
(enter)
(append "line")
(attr "stroke-width" (fn [d] (Math/sqrt (.-value d)))))
node (.. (. svg append "g")
(attr "class" "nodes")
node (.. svg
(select ".nodes")
(selectAll "circle")
(data nodes)
(data nodes))
new-node (.. node
(enter)
(append "g")
(attr "class" "node"))
circle (.. node
circle (.. new-node
(append "circle")
(attr "r" #(or (gob/get % "r" 10)))
(attr "fill" (fn [d] (color (.-group d))))
@ -391,174 +145,34 @@
(on "drag" dragged)
(on "end" dragended))))
label (.. node
label (.. new-node
(append "text")
(attr "dy" ".35em")
(text #(gob/get % "title" "")))
]
exit-node (.. node
(exit)
(remove "g"))
exit-link (.. link
(exit)
(remove "line"))
]
(println "Nodes count" (count nodes))
(println "Links count" (count links))
(.. simulation
(nodes nodes)
(on "tick" (ticked svg)))
(.. simulation
(force "link")
(links links))
(println "D3 did enter")
(js/console.log "d3 ent done" (.. svg
(selectAll ".links > line")
size))))}
traces-ratom)]
(.. simulation
(alphaTarget 0.3)
(restart))
)))}
traces-ratom]
[:hr]])))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;(ns todomvc.subvis2
; (:require [reagent.core :as r]))
;
;(defn prep-parent [parent]
; (-> parent
; (.selectAll "*")
; .remove)
; (.append parent "g"))
;
;(defn draw-circle [parent]
; (let [OUTER_WIDTH 208
; OUTER_HEIGHT 208
; parent (-> (js/d3.select parent)
; (.select "svg")
; (.attr "width" OUTER_WIDTH)
; (.attr "height" OUTER_HEIGHT))]
;
; ; Clear everything under the parent node so we can re-render it.
; (prep-parent parent)
;
; (let [top-node (.select parent "g")
; COLOR_CIRCLE "#fdb74a"]
; (.attr top-node
; "transform"
; (str "translate("
; (/ OUTER_WIDTH 2.0)
; ","
; (/ OUTER_HEIGHT 2.0)
; ")"))
;
; (-> top-node
; (.append "circle")
; (.attr "cx" 0)
; (.attr "cy" 0)
; (.attr "r" 100)
; (.style "stroke" COLOR_CIRCLE)))))
;
;(defn d3-gauge [args]
; (let [dom-node (r/atom nil)]
; (r/create-class
; {:component-did-update
; (fn [this old-argv]
; (let [[_ args] (r/argv this)]
; ;; This is where we get to actually draw the D3 gauge.
; (draw-circle @dom-node)))
;
; :component-did-mount
; (fn [this]
; (let [node (r/dom-node this)]
; ;; This will trigger a re-render of the component.
; (reset! dom-node node)))
;
; :reagent-render
; (fn [args]
; ;; Necessary for Reagent to see that we depend on the dom-node r/atom.
; ;; Note: we don't actually use any of the args here. This is because
; ;; we cannot render D3 at this point. We have to wait for the update.
; @dom-node
; [:div.gauge [:svg]])})))
;
;
;(def circles (r/atom [{:name "circle 1"
; :x 10
; :y 10
; :r 20
; :color "black"}
; {:name "circle 2"
; :x 35
; :y 35
; :r 15
; :color "red"}
; {:name "circle 3"
; :x 100
; :y 100
; :r 30
; :color "blue"}
; {:name "circle 4" :x 55 :y 55 :r 10 :color "red"}]))
;
;(defn new-circle []
; {:name (str (gensym "circle"))
; :x (rand-int 400)
; :y (rand-int 400)
; :r (+ 10 (rand-int 20))
; :color (str "hsl(" (rand-int 360) ", 100%, 50%)")})
;
;(defn add-new [n]
; (swap! circles conj (new-circle)))
;
;(defn d3-inner [data]
; (r/create-class
; {:reagent-render (fn [] [:div [:svg {:width 400 :height 800}]])
;
; :component-did-mount (fn []
; (let [d3data (clj->js data)]
; (.interval js/d3 add-new 1000)
; (.. js/d3
; (select "svg")
; (selectAll "circle")
; (data d3data (fn [d i] (.-name d)))
; enter
; (append "circle")
; (attr "cx" (fn [d] (.-x d)))
; (attr "cy" (fn [d] (.-y d)))
; (attr "r" (fn [d] (.-r d)))
; (attr "fill" (fn [d] (.-color d))))))
;
; :component-did-update (fn [this]
; (let [[_ data] (r/argv this)
; d3data (clj->js data)
; circles (.. js/d3
; (select "svg")
; (selectAll "circle")
; (data d3data (fn [d i] (when d (.-name d)))))]
; (.. circles
; ;(attr "cx" (fn [d] (.-x d)))
; ;(attr "cy" (fn [d] (.-y d)))
; ;(attr "r" (fn [d] (.-r d)))
; enter
; (append "circle")
; (attr "cx" 200)
; (attr "cy" 200)
; (attr "r" 500)
; (transition)
; (attr "cx" (fn [d] (.-x d)))
; (attr "cy" (fn [d] (.-y d)))
; (attr "r" (fn [d] (.-r d)))
; (attr "fill" (fn [d] (.-color d))))
; (.. circles
; exit
; remove)))}))
;
;(defn outer []
; (let [data circles #_(subscribe [:circles])]
; (fn []
; [d3-inner @data])))
;
;

View File

@ -0,0 +1,53 @@
(ns day8.re-frame.trace.graph-test
(:require [day8.re-frame.trace.graph :as graph]
[clojure.test :refer :all]))
(def t1
'({:id 1, :operation :initialise-db, :type :event, :tags {:event [:initialise-db]}, :child-of nil}
{:id 2, :operation "todomvc.core.wrapper", :type :render, :tags {:component-path "todomvc.core.wrapper", :reaction "rx2", :input-signals ("ra18")}, :child-of nil}
{:id 5, :operation :sorted-todos, :type :sub/create, :tags {:query-v [:sorted-todos], :cached? false, :reaction "rx3"}, :child-of 4}
{:id 4, :operation :todos, :type :sub/create, :tags {:query-v [:todos], :cached? false, :reaction "rx4"}, :child-of 3}
{:id 7, :operation :sorted-todos, :type :sub/run, :tags {:query-v [:sorted-todos], :reaction "rx3", :input-signals ["ra5"]}, :child-of 6}
{:id 6, :operation :todos, :type :sub/run, :tags {:query-v [:todos], :reaction "rx4", :input-signals ["rx3"]}, :child-of 3}
{:id 3, :operation "todomvc.views.todo_app", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app", :reaction "rx6", :input-signals ("rx4")}, :child-of nil}
{:id 8, :operation "todomvc.views.task_entry", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.task_entry", :reaction nil, :input-signals nil}, :child-of nil}
{:id 9, :operation "todomvc.views.todo_input", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.task_entry > todomvc.views.todo_input", :reaction "rx7", :input-signals ("ra19")}, :child-of nil}
{:id 10, :operation "ReagentInput", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.task_entry > todomvc.views.todo_input > ReagentInput", :reaction nil, :input-signals nil}, :child-of nil}
{:id 13, :operation :todos, :type :sub/create, :tags {:query-v [:todos], :cached? true, :reaction "rx4"}, :child-of 12}
{:id 14, :operation :showing, :type :sub/create, :tags {:query-v [:showing], :cached? false, :reaction "rx8"}, :child-of 12}
{:id 12, :operation :visible-todos, :type :sub/create, :tags {:query-v [:visible-todos], :cached? false, :reaction "rx9"}, :child-of 11}
{:id 16, :operation :todos, :type :sub/create, :tags {:query-v [:todos], :cached? true, :reaction "rx4"}, :child-of 15}
{:id 15, :operation :all-complete?, :type :sub/create, :tags {:query-v [:all-complete?], :cached? false, :reaction "rx10"}, :child-of 11}
{:id 17, :operation :all-complete?, :type :sub/run, :tags {:query-v [:all-complete?], :reaction "rx10", :input-signals ["rx4"]}, :child-of 11}
{:id 19, :operation :showing, :type :sub/run, :tags {:query-v [:showing], :reaction "rx8", :input-signals ["ra5"]}, :child-of 18}
{:id 18, :operation :visible-todos, :type :sub/run, :tags {:query-v [:visible-todos], :reaction "rx9", :input-signals ("rx4" "rx8")}, :child-of 11}
{:id 11, :operation "todomvc.views.task_list", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.task_list", :reaction "rx11", :input-signals ("rx10" "rx9")}, :child-of nil}
{:id 20, :operation "ReagentInput", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.task_list > ReagentInput", :reaction nil, :input-signals nil}, :child-of nil}
{:id 21, :operation "todomvc.views.todo_item", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.task_list > todomvc.views.todo_item", :reaction "rx12", :input-signals ("ra20" "ra20")}, :child-of nil}
{:id 22, :operation "ReagentInput", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.task_list > todomvc.views.todo_item > ReagentInput", :reaction nil, :input-signals nil}, :child-of nil}
{:id 24, :operation :footer-counts, :type :sub/create, :tags {:query-v [:footer-counts], :cached? false, :reaction "rx13"}, :child-of 23}
{:id 25, :operation :showing, :type :sub/create, :tags {:query-v [:showing], :cached? true, :reaction "rx8"}, :child-of 23}
{:id 27, :operation :todos, :type :sub/create, :tags {:query-v [:todos], :cached? true, :reaction "rx4"}, :child-of 26}
{:id 29, :operation :todos, :type :sub/create, :tags {:query-v [:todos], :cached? true, :reaction "rx4"}, :child-of 28}
{:id 28, :operation :completed-count, :type :sub/create, :tags {:query-v [:completed-count], :cached? false, :reaction "rx14"}, :child-of 26}
{:id 30, :operation :completed-count, :type :sub/run, :tags {:query-v [:completed-count], :reaction "rx14", :input-signals ["rx4"]}, :child-of 26}
{:id 26, :operation :footer-counts, :type :sub/run, :tags {:query-v [:footer-counts], :reaction "rx13", :input-signals ("rx4" "rx14")}, :child-of 23}
{:id 23, :operation "todomvc.views.footer_controls", :type :render, :tags {:component-path "todomvc.core.wrapper > todomvc.views.todo_app > todomvc.views.footer_controls", :reaction "rx15", :input-signals ("rx13" "rx8" "rx8" "rx8")}, :child-of nil}))
(deftest sub-graph-test
(is (= {:links []
:nodes [{:id "rx4"
:r 10
:title ""
:group 2
:data {:id 1
:tags {:cached? false
:reaction "rx4"}
:type :sub/create}}]}
(graph/trace->sub-graph [{:id 1 :type :sub/create :tags {:cached? false :reaction "rx4"}}] []))))
(deftest dispose-view-test
(is (= {:links []
:nodes []}
(graph/trace->sub-graph [{:id 1 :type :render :tags {:cached? false :reaction "rx4"}}
{:id 2 :type :componentWillUnmount :tags {:reaction "rx4"}}] []))))