Inge Solvoll's blog

Menu

  • Home
  • Archives
  • Tags
  • About me
  • RSS
December 4, 2018

Revisited: How to use a charting library in reagent

Improved advice

I wrote a blog post about this subject a couple of years ago and a lot of people read it. Unfortunately it contains some advice that has been proven wrong/not optimal. The re-frame explanation of this concept is nice and understandable, but I wanted to make an interactive example so it's even clearer.

Requirements

We'll be purely practical in this walkthrough, so let's get right to it.

(require '[reagent.core :as r])
(require '[cljsjs.highcharts])

We'll use a regular reagent atom as our mutable data container. It could be anything with a "ratom" behaviour, like a re-frame subscription. This reference will hold the configuration and data for the chart.

(def config-atom (r/atom nil))

Inner/outer

Now for the interesting bit. The trick here, as described in the re-frame docs, is to split the integration in two.

  • An outer component that closes over the Clojure reactive reference
  • An inner component that accepts a React props map derived from the reactive reference

The inner component

For this example the mount-chart and update-chart functions are identical. In less trivial cases they are likely different, and you probably want to call the update-chart function at the end of your mount-chart function.


(defn mount-chart [comp]
    (.chart js/Highcharts (r/dom-node comp) (clj->js (r/props comp))))

(defn update-chart [comp]
    (mount-chart comp))

(defn chart-inner []
  (r/create-class
    {:component-did-mount   mount-chart
     :component-did-update  update-chart
     :reagent-render        (fn [comp] [:div])}))

The outer component

This one handles the mutable state from the clojurescript side. Dereference the atom/subscription/reaction and pass the necessary information on to the inner component. The inner component will re-render on changes to these props, giving us the behaviour we want.

(defn chart-outer [config]
    [chart-inner @config])

The configuration

The following renders a simple chart below. Feel free to play around with the config to see what happens!

(reset! config-atom {:chart {:type   :bar}
                             :title  {:text "Chart title here"}
                             :xAxis  {:categories ["Apples", "Bananas", "Oranges"]}
                             :yAxis  {:title {:text "Fruit eaten"}}
                             :series [{:name "Jane" :data [1, 0, 4]}
                                      {:name "John" :data [5, 7, 3]}]})
nil
[chart-outer config-atom]

Tags: reagent klipse clojurescript

« A la carte specs for your re-frame subs and events Kee-frame controller tricks »

Copyright © 2021 Inge Solvoll

Powered by Cryogen | Free Website Template by Download Website Templates