I'm toggling on/off series in chart and was wondering if I was doing anything crazy.
Is the atom really a good idea here?
;; ================ Graph data ================
(def serie1 {:label "Bar" :data [[11 13] [19 11] [30 -7]]})
(def serie2 {:label "Foo" :data [[10 1] [17 -14] [30 5]]})
(def serie3 {:label "Zon" :data [[8 2] [18 7] [30 15]]})
(def series (for [serie [serie1 serie2 serie3]]
{:label (:label serie) :action "toggle-serie" :param serie}))
;; ============ Chart state ================
(def !chart
"Chart state"
(atom []))
(defn toggle-serie! [serie]
"Return the series collection minus/plus the given serie"
(swap! !chart #(if (some #{serie} %)
(remove #{serie} %)
(conj % serie))))
(defn reset-chart []
"Reset chart state"
(reset! !chart []))
;;================ Page population ================
; almost identical to ibdknox overtone example
(defpartial button [{:keys [label action param]}]
[:a.button {:href "#" :data-action action :data-param param} label])
(defn populate [container buttons]
(doseq [b buttons]
(append container (button b))))
(populate ($ :#series) series)
;; ================ Button functions ================
(defn plot
"Plot the given series and return the chart as an object."
[placeholder coll-data & options]
(js/jQuery.plot placeholder (clj->js coll-data) (clj->js options)))
(def chart ($ :#chart))
(defn toggle-serie-and-update-chart!
"Add or remove a serie form the chart atom and redraw the chart."
[serie]
(toggle-serie! serie) ;update the chart atom
(plot chart @!chart)) ; redraw the chart
(delegate ($ :#series) button :click
(fn [e]
(.preventDefault e)
(this-as me
(let [$me ($ me)
param (cljs.reader/read-string (data $me :param))]
(toggle-serie-and-update-chart! param)))))
1 Answer 1
If your dataset were coming from an outside source, like an API call, I'd say the atom would make sense. In this case, your dataset is static. In that case, I think I might find it more intuitive to use a var for the series and then select the items out that you want to plot. In that case, your state is really just a list of which series (you are selecting).
So, if you had all your series:
(def all-series
{:series1 :...series1
:series2 :...series2
:series3 :...series3})
!chart
might contain #{:series1 :series3}
and you could get all the values out using (select-keys all-series @!chart)
.
You might find you can avoid the atom altogether, but at the very least I'd always look for ways to keep that state as simple as