Temp working point

This commit is contained in:
Daniel Compton 2016-11-09 12:30:11 +13:00
parent 6bf1648187
commit b3d64dd7a8
No known key found for this signature in database
GPG Key ID: A6E4DC5283B5DCEC
5 changed files with 908 additions and 2 deletions

View File

@ -4,5 +4,7 @@
:license {:name "MIT"} :license {:name "MIT"}
:dependencies [[org.clojure/clojure "1.8.0"] :dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.9.227"] [org.clojure/clojurescript "1.9.227"]
[reagent "0.6.0"]] [reagent "0.6.0"]
) [re-frame "0.8.1-SNAPSHOT"]
[cljsjs/d3 "4.2.2-0"]]
:profiles {:dev {:dependencies [[binaryage/dirac "RELEASE"]]}})

View File

@ -0,0 +1,234 @@
(ns day8.re-frame.trace
(:require [day8.re-frame.trace.subvis :as subvis]
[re-frame.tracing :as trace :include-macros true]
[cljs.pprint :as pprint]
[clojure.string :as str]
[reagent.core :as r]
[reagent.interop :refer-macros [$ $!]]
[reagent.impl.util :as util]
[reagent.impl.component :as component]
[reagent.impl.batching :as batch]
[reagent.ratom :as ratom]
[re-frame.utils :as rutils]
[goog.object :as gob]
[re-frame.interop :as interop]))
(defn comp-name [c]
(let [n (or (component/component-path c)
(some-> c .-constructor util/fun-name))]
(if-not (empty? n)
n
"")))
(def static-fns
{:render
(fn render []
(this-as c
(trace/with-trace {:op-type :render
:tags {:component-path (reagent.impl.component/component-path c)}
:operation (last (str/split (reagent.impl.component/component-path c) #" > "))}
(if util/*non-reactive*
(reagent.impl.component/do-render c)
(let [rat ($ c :cljsRatom)
_ (batch/mark-rendered c)
res (if (nil? rat)
(ratom/run-in-reaction #(reagent.impl.component/do-render c) c "cljsRatom"
batch/queue-render reagent.impl.component/rat-opts)
(._run rat false))
cljs-ratom ($ c :cljsRatom)] ;; actually a reaction
(trace/merge-trace!
{:tags {:reaction (rutils/reagent-id cljs-ratom)
:input-signals (when cljs-ratom
(map rutils/reagent-id (gob/get cljs-ratom "watching" :none)))}})
res)))))})
(defn monkey-patch-reagent []
(let [#_#_real-renderer reagent.impl.component/do-render
real-custom-wrapper reagent.impl.component/custom-wrapper
real-next-tick reagent.impl.batching/next-tick
real-schedule reagent.impl.batching/schedule]
#_(set! reagent.impl.component/do-render
(fn [c]
(let [name (comp-name c)]
(js/console.log c)
(trace/with-trace {:op-type :render
:tags {:component-path (reagent.impl.component/component-path c)}
:operation (last (str/split name #" > "))}
(real-renderer c)
))))
(set! reagent.impl.component/static-fns static-fns)
(set! reagent.impl.component/custom-wrapper
(fn [key f]
(case key
:componentWillUnmount
(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)}})
(.call (real-custom-wrapper key f) c c)))
(real-custom-wrapper key f))))
#_(set! reagent.impl.batching/next-tick (fn [f]
(real-next-tick (fn []
(trace/with-trace {:op-type :raf}
(f))))))
#_(set! reagent.impl.batching/schedule schedule
#_(fn []
(reagent.impl.batching/do-after-render (fn [] (trace/with-trace {:op-type :raf-end})))
(real-schedule)))
))
(def traces (interop/ratom []))
(defn log-trace? [trace]
(let [render-type? (= (:type trace) :render)]
(not (and render-type?
(str/includes? (or (get-in trace [:tags :component-path]) "") "day8.re_frame.trace.devtools")))))
(defn init-tracing! []
(re-frame.tracing/register-trace-cb ::cb (fn [new-traces]
(let [new-traces (filter log-trace? new-traces)]
(swap! traces #(reduce conj % new-traces)))))
(monkey-patch-reagent)
)
(defn search-input [{:keys [title on-save on-stop]}]
(let [val (r/atom title)
save #(let [v (-> @val str clojure.string/trim)]
(on-save v))]
(fn [props]
[:input (merge props
{:type "text"
:value @val
:auto-focus true
:on-blur save
:on-change #(reset! val (-> % .-target .-value))
:on-key-down #(case (.-which %)
13 (save)
nil)})])))
(defn render-traces []
(let [search (r/atom "")
slower-than-ms (r/atom "")
slower-than-bold (r/atom "")]
(fn []
(let [slower-than-ms-int (js/parseInt @slower-than-ms)
slower-than-bold-int (js/parseInt @slower-than-bold)
op-filter (when-not (str/blank? @search)
(filter #(str/includes? (str (:operation %) " " (:type %)) @search)))
ms-filter (when-not (str/blank? @slower-than-ms)
(filter #(< slower-than-ms-int (:duration %))))
transducers (apply comp (remove nil? [ms-filter op-filter]))
showing-traces (sequence transducers @traces)
filter-msg (if (and (str/blank? @search) (str/blank? @slower-than-ms))
(str "Filter " (count @traces) " events: ")
(str "Filtering " (count showing-traces) " of " (count @traces) " events:"))
padding {:padding "0px 5px 0px 5px"}]
[:div
{:style {:padding "10px"}}
[:h1 "TRACES"]
[:span filter-msg [:button {:on-click #(do (trace/reset-tracing!) (reset! traces []))} " Clear traces"]] [:br]
[:span "Filter events " [search-input {:on-save #(reset! search %)}]] [:br]
[:span "Filter slower than " [search-input {:on-save #(reset! slower-than-ms %)}] "ms "] [:br]
[:span "Bold slower than " [search-input {:on-save #(reset! slower-than-bold %)}] "ms "]
[:table
{:cell-spacing "0" :width "100%"}
[:thead>tr
[:th "op"]
[:th "event"]
[:th "meta"]]
[: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)})]
(list [:tr {:key id
:style {:color (case type
:sub/create "green"
:sub/run "red"
:event "blue"
:render "purple"
:re-frame.router/fsm-trigger "red"
nil)}}
[:td {:style row-style} (str type)]
[:td {:style row-style} operation]
[:td
{:style (merge row-style {:font-weight (if (< slower-than-bold-int duration)
"bold"
"")})}
(.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)))]])))))]]]))))
(defn resizer-style [draggable-area]
{:position "absolute" :z-index 2 :opacity 0
:left (str (- (/ draggable-area 2)) "px") :width "10px" :top "0px" :height "100%" :cursor "col-resize"})
(def ease-transition "left 0.2s ease-out, top 0.2s ease-out, width 0.2s ease-out, height 0.2s ease-out")
(defn devtools []
;; Add clear button
;; Filter out different trace types
(let [position (r/atom :right)
size (r/atom 0.5)
showing? (r/atom true)
dragging? (r/atom false)
pin-to-bottom? (r/atom true)
selected-tab (r/atom :subvis)
_ (js/console.log "Rendering devtools")
handle-keys (fn [e]
(let [combo-key? (or (.-ctrlKey e) (.-metaKey e) (.-altKey e))
tag-name (.-tagName (.-target e))
key (.-key e)
entering-input? (contains? #{"INPUT" "SELECT" "TEXTAREA"} tag-name)]
(when (and (not entering-input?) combo-key?)
(cond
(and (= key "h") (.-ctrlKey e))
(do (swap! showing? not)
(.preventDefault e))))))]
(r/create-class
{:component-will-mount #(js/window.addEventListener "keydown" handle-keys)
:component-will-unmount #(js/window.removeEventListener "keydown" handle-keys)
:display-name "devtools outer"
:reagent-render (fn []
(let [draggable-area 10
full-width js/window.innerWidth
full-height js/window.innerHeight
left (if @showing? (str (* 100 (- 1 @size)) "%")
(str full-width "px"))
transition (if @showing?
ease-transition
(str ease-transition ", opacity 0.01s linear 0.2s"))]
[:div {:style {:position "fixed" :width "0px" :height "0px" :top "0px" :left "0px" :z-index 99999999}}
[:div {:style {:position "fixed" :z-index 1 :box-shadow "rgba(0, 0, 0, 0.298039) 0px 0px 4px" :background "white"
:left left :top "0px" :width (str (* 100 @size) "%") :height "100%"
:transition transition}}
[:div.resizer {:style (resizer-style draggable-area)
:on-mouse-down #(reset! dragging? true)
:on-mouse-up #(reset! dragging? false)
:on-mouse-move (fn [e]
(when @dragging?
(let [x (.-clientX e)
y (.-clientY e)]
(.preventDefault e)
(reset! size (/ (- full-width x)
full-width)))))}]
[:div {:style {:width "100%" :height "100%" :overflow "auto"}}
[:button {:on-click #(reset! selected-tab :traces)} "Traces"]
[:button {:on-click #(reset! selected-tab :subvis)} "SubVis"]
(case @selected-tab
:traces [render-traces]
:subvis [subvis/render-subvis traces]
[render-traces])]]]))})))

View File

@ -0,0 +1,110 @@
(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)))
(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
"
[{: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)}}
& 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}]
(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})

View File

@ -0,0 +1 @@
(ns day8.re-frame.trace.log)

View File

@ -0,0 +1,559 @@
(ns day8.re-frame.trace.subvis
(:require cljsjs.d3
[day8.re-frame.trace.d3 :as d3t]
[reagent.core :as r]
[re-frame.utils :as rutils]
[re-frame.db :as db]
[goog.object :as gob]
[clojure.set :as set]))
(def width 400)
(def height 200)
(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})))
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
otherwise returns min-val if x is less than min-val
and max-val if x is greater than max-val.
Essentially this provides a bounding box/clamp around x."
[min-val x max-val]
(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]
(fn []
(let [trace-graph (trace->sub-graph @traces-ratom)]
[force-inner trace-graph])))
(defonce desc (r/atom 1))
(defn render-subvis [traces-ratom]
(let [color-a (atom nil)
svg-a (atom nil)
simulation-a (atom nil)]
(fn []
[: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)
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))))
)
link-sel (.. svg
(selectAll ".links > line"))
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))))
circle-sel (.. svg
(selectAll ".node > circle"))
label (.. node
(append "text")
(attr "dy" ".35em")
(text #(gob/get % "title" "")))
label-sel (.. svg
(selectAll ".node > text"))
ticked (fn []
(.. 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
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" "")))
]
(.. simulation
(force "link")
(links links))
)
(println "D3 did enter"))}
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])))
;
;