(ns foo.component.test-component
(:require [reagent.core :as r]))
(defn- draw-d3
[data]
(let [update (-> js/d3 (.select ".foo-component") (.selectAll "div.h-bar") (.data (clj->js @data)))
enter (-> update .enter)
exit (-> update .exit)]
(-> enter
(.append "div")
(.attr "class" "h-bar")
(.append "span"))
(-> update
(.style "width", (fn [d] (str (* d 3) "px")))
(.style "background-color", "lightgrey")
(.select "span" )
(.text (fn [d] d)))
(-> exit
.remove)))
(defn foo-component [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 perform our d3.
(draw-d3 args)))
: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 and
;; args r/atoms. Note: we don't render D3 at this point. We have
;; to wait for the update.
@dom-node
@args
[:div
[:div.foo-component]])})))
(def state
(r/atom [10 15 40 60 80 65 55 30 20 10 8]))
(defn component []
(let [necessary-state state]
[foo-component necessary-state]))