-
-
Save rgm/0e75c4bf069a9136e98179d9596c4bae to your computer and use it in GitHub Desktop.
re-frame + d3 together, trying to mesh d3's enter|update|exit with react lifecycle methods and re-frame subs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns reagent-d3-test.core | |
(:require [reagent.core :as reagent] | |
[re-frame.core :as re-frame] | |
[cljsjs.d3])) | |
;;; -------------------- | |
;;; db | |
(def default-db | |
{:data '()}) | |
;;; -------------------- | |
;;; events | |
(re-frame/reg-event-db | |
::initialize-db | |
(fn [_ _] | |
default-db)) | |
(re-frame/reg-event-db | |
::add-one | |
(fn [db _] | |
(update db :data conj {:date (str (js/Date.))}))) | |
(re-frame/reg-event-db | |
::remove-one | |
(fn [db _] | |
(update db :data #(drop 1 %)))) | |
;;; subs | |
(re-frame/reg-sub | |
::data | |
(fn [db] | |
(:data db))) | |
;;; -------------------- | |
;;; views | |
;;; D3 | |
(defn d3-enter [dom-target data] | |
(-> (js/d3.select dom-target) | |
(.selectAll "li") | |
(.data (clj->js data)) | |
(.enter) | |
(.append "li"))) | |
(defn d3-update [dom-target data] | |
(-> (js/d3.select dom-target) | |
(.selectAll "li") | |
(.data (clj->js data)) | |
(.text #(.-date %)))) | |
(defn d3-exit [dom-target data] | |
(-> (js/d3.select dom-target) | |
(.selectAll "li") | |
(.data (clj->js data)) | |
(.exit) | |
(.remove))) | |
(defn inner-did-update [dom-target data] | |
(println "inner-did-update") | |
(d3-enter dom-target data) | |
(d3-update dom-target data) | |
(d3-exit dom-target data)) | |
(defn inner-did-mount [dom-target data] | |
(println "inner-did-mount") | |
;; already created <ul> in hiccup and saved off a ref, | |
;; no need to create the container here | |
(inner-did-update dom-target data)) | |
;;; reagent/reframe entry points | |
;;; per https://gadfly361.github.io/gadfly-blog/posts-output/2016-10-22-d3-in-reagent/ | |
(defn inner-d3 | |
"renders items into a <ul> to test D3 lifecycle" | |
[{:keys [data]}] | |
(let [dom-target (reagent/atom nil)] | |
(reagent/create-class | |
{:display-name | |
"d3-inner" | |
:component-did-mount | |
(fn [comp] | |
(let [{:keys [data]} (reagent/props comp)] | |
(inner-did-mount @dom-target data))) | |
:component-did-update | |
(fn [comp] | |
(let [{:keys [data]} (reagent/props comp)] | |
(inner-did-update @dom-target data))) | |
:reagent-render | |
(fn [{:keys [data]}] | |
(js/console.log "inner-d3 sees" (count data) "items") | |
[:div "d3 view:" | |
[:ul {:ref #(reset! dom-target %)}]])}))) | |
(defn outer-re-frame | |
"hold re-frameyness out here so we can use devcards with inner-d3" | |
[] | |
(let [data (re-frame/subscribe [::data])] | |
(js/console.log "outer-re-frame sees" (count @data) "items") | |
(fn [] | |
[:div | |
[inner-d3 {:data @data}] | |
[:hr] | |
[:button {:on-click #(re-frame/dispatch [::add-one])} "add one"] | |
[:button {:on-click #(re-frame/dispatch [::remove-one])} "remove one"] | |
[:div "sub returning: " | |
[:p [:code (str @data)]]]]))) | |
;;; -------------------- | |
;;; core | |
(defn dev-setup [] | |
(enable-console-print!) | |
(println "dev mode")) | |
(defn mount-root [] | |
(re-frame/clear-subscription-cache!) | |
(reagent/render [outer-re-frame] | |
(.getElementById js/document "app"))) | |
(defn ^:export init [] | |
(re-frame/dispatch-sync [::initialize-db]) | |
(dev-setup) | |
(mount-root)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defproject reagent-d3-test "0.1.0-SNAPSHOT" | |
:dependencies [[org.clojure/clojure "1.8.0"] | |
[org.clojure/clojurescript "1.9.908"] | |
[reagent "0.7.0"] | |
[re-frame "0.10.2"] | |
[cljsjs/d3 "4.12.0-0"]] | |
:plugins [[lein-cljsbuild "1.1.5"]] | |
:min-lein-version "2.5.3" | |
:source-paths ["src/clj"] | |
:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] | |
:figwheel {:css-dirs ["resources/public/css"] | |
:server-port 3450} | |
:profiles | |
{:dev | |
{:dependencies [[binaryage/devtools "0.9.4"]] | |
:plugins [[lein-figwheel "0.5.13"]]}} | |
:cljsbuild | |
{:builds | |
[{:id "dev" | |
:source-paths ["src/cljs"] | |
:figwheel {:on-jsload "reagent-d3-test.core/mount-root"} | |
:compiler {:main reagent-d3-test.core | |
:output-to "resources/public/js/compiled/app.js" | |
:output-dir "resources/public/js/compiled/out" | |
:asset-path "js/compiled/out" | |
:source-map-timestamp true | |
:preloads [devtools.preload] | |
:external-config {:devtools/config {:features-to-install :all}} | |
}} | |
{:id "min" | |
:source-paths ["src/cljs"] | |
:compiler {:main reagent-d3-test.core | |
:output-to "resources/public/js/compiled/app.js" | |
:optimizations :advanced | |
:closure-defines {goog.DEBUG false} | |
:pretty-print false}} | |
]} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment