-
Notifications
You must be signed in to change notification settings - Fork 12
/
core.cljs
184 lines (161 loc) · 5.98 KB
/
core.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
(ns clientex.core
(:require
[cljs.core.async
:as async
:refer (<! >! put! chan)
:refer-macros [go go-loop]]
[clojure.string :as cljstr]
[aerial.hanami.core
:as hmi
:refer [printchan user-msg
re-com-xref xform-recom
default-header-fn default-instrumentor-fn make-instrumentor start
update-adb get-adb
get-vspec update-vspecs
init-tabs
hanami-main]]
[aerial.hanami.common :as hc :refer [RMV]]
[aerial.hanami.templates :as ht]
[com.rpl.specter :as sp]
[reagent.core :as rgt]
[re-com.core
:as rcm
:refer [h-box v-box box gap line h-split v-split scroller
button row-button md-icon-button md-circle-icon-button info-button
input-text input-password input-textarea
label title p
single-dropdown
checkbox radio-button slider progress-bar throbber
horizontal-bar-tabs vertical-bar-tabs
modal-panel popover-content-wrapper popover-anchor-wrapper]
:refer-macros [handler-fn]]
[re-com.box
:refer [flex-child-style]]
[re-com.dropdown
:refer [filter-choices-by-keyword single-dropdown-args-desc]]
))
(defn setup [{:keys [uid title logo img opts]}]
(printchan "Registering " uid)
(update-adb [:main :uid] uid
[:main :title] title
[:main :logo] logo
[:main :img] img
[:main :opts] (hc/xform opts)
[:main :session-name] (rgt/atom "Test")
[:vspecs] (rgt/atom {}))
(init-tabs)
(rgt/render [hanami-main]
(get-adb :elem)))
(defmethod user-msg :app-init [msg]
(printchan "Got application initialization msg :app-init"))
(defn app-init [elem]
(let [instfn (make-instrumentor default-instrumentor-fn)]
(printchan "Element 'app' available ...")
(update-adb :elem elem
:instrumentor [instfn]
:header [default-header-fn])
(setup {:uid {:uuid "testing", :name "clientex"}
:title "Client only Hanami test example"
:logo "logo.png"
:img "Small-Himeji_sakura.png"
:opts hc/default-opts})))
;;; Startup ============================================================== ;;;
(when-let [elem (js/document.querySelector "#app")]
(hc/add-defaults
:HEIGHT 400 :WIDTH 450
:USERDATA {:tab {:id :TID, :label :TLBL, :opts :TOPTS}
:opts :OPTS
:vid :VID, :msgop :MSGOP, :session-name :SESSION-NAME}
:VID RMV, :MSGOP :tabs, :SESSION-NAME "Exploring"
:TID :expl1, :TLBL #(-> :TID % name cljstr/capitalize)
:OPTS (hc/default-opts :vgl)
:TOPTS {:order :row, :eltsper 2 :size "auto"})
(app-init elem))
;;; We will run this one visualization upon page load!
;;; From a clojureverse data-science comment/example
(->
(hc/xform ht/bar-chart
:TITLE "Top headline phrases"
:X :x-value :Y :y-value :YTYPE "nominal"
:DATA
[{:x-value 8961 :y-value "will make you"}
{:x-value 4099 :y-value "this is why"}
{ :x-value 3199 :y-value "can we guess"}
{:x-value 2398 :y-value "only X in"}
{:x-value 1610 :y-value "the reason is"}
{:x-value 1560 :y-value "are freaking out"}
{:x-value 1425 :y-value "X stunning photos"}
{:x-value 1388 :y-value "tears of joy"}
{:x-value 1337 :y-value "is what happens"}
{:x-value 1287 :y-value "make you cry"}])
hmi/sv!)
(comment
;; When running these make sure your current name space is clientex.core
;; From a clojureverse data-science comment/example
(->
(hc/xform ht/bar-chart
:TITLE "Top headline phrases"
:X :x-value :Y :y-value :YTYPE "nominal"
:DATA
[{:x-value 8961 :y-value "will make you"}
{:x-value 4099 :y-value "this is why"}
{ :x-value 3199 :y-value "can we guess"}
{:x-value 2398 :y-value "only X in"}
{:x-value 1610 :y-value "the reason is"}
{:x-value 1560 :y-value "are freaking out"}
{:x-value 1425 :y-value "X stunning photos"}
{:x-value 1388 :y-value "tears of joy"}
{:x-value 1337 :y-value "is what happens"}
{:x-value 1287 :y-value "make you cry"}])
hmi/sv!)
;; The stanard IDL simple car scatter plot
(-> (hc/xform ht/point-chart
:UDATA "data/cars.json"
:X "Horsepower" :Y "Miles_per_Gallon" :COLOR "Origin")
hmi/sv!)
;; Example where template is a vega-lite spec. But we do merge in
;; the :usermeta in order to use our tabs
(->
(hc/xform
{:usermeta :USERDATA
:width 500,
:height 300,
:data {:url "data/airports.csv"},
:projection {:type "albersUsa"},
:mark "circle",
:encoding {:longitude {:field "longitude", :type "quantitative"},
:latitude {:field "latitude", :type "quantitative"},
:tooltip [{:field "name", :type "nominal"}
{:field "longitude", :type "quantitative"}
{:field "latitude", :type "quantitative"}],
:size {:value 10}},
:config {:view {:stroke "transparent"}}}
:TID :geo)
hmi/sv!)
;; Some distributions
;;
(def obsdist
(let [obs [[0 9] [1 78] [2 305] [3 752] [4 1150] [5 1166]
[6 899] [7 460] [8 644] [9 533] [10 504]]
totcnt (->> obs (mapv second) (apply +))
pdist (map (fn[[k cnt]] [k (double (/ cnt totcnt))]) obs)]
pdist))
(->>
[(hc/xform ht/layer-chart
:TID :dists :TOPTS {:order :row, :size "auto"}
:TITLE "A Real (obvserved) distribution with incorrect simple mean"
:HEIGHT 400 :WIDTH 450
:LAYER
[(hc/xform ht/bar-layer :XTITLE "Count" :YTITLE "Probability")
(hc/xform ht/xrule-layer :AGG "mean")]
:DATA (mapv (fn[[x y]] {:x x :y y :m 5.7}) obsdist))
(hc/xform ht/layer-chart
:TID :dists
:TITLE "The same distribution with correct weighted mean"
:HEIGHT 400 :WIDTH 450
:LAYER
[(hc/xform ht/bar-layer :XTITLE "Count" :YTITLE "Probability")
(hc/xform ht/xrule-layer :X "m")]
:DATA (mapv (fn[[x y]] {:x x :y y :m 5.7}) obsdist))]
hmi/sv!)
)