Google Chart CLJS Clojure

I tried to adapt this example to Google Chart. Framed re-frame , reagent . I would like to create a real-time chart based on subscriptions. I tested with a simple counter = + - 1.

I got the error: Assert failed: Render must be a function, not nil (ifn? render-fun) .

 (defn draw-demo-chart [d] (let [[columns vectors options chart] (r/children d) data (new js/google.visualization.DataTable)] (doall ;gotta keep the doall on maps. lazy sequence... (map (fn [[type name]] (.addColumn data type name)) columns)) (.addRows data vectors) (.draw chart data options) (.load js/google "visualization" "1" (clj->js {:packages ["corechart" "orgchart" "calendar" "map" "geochart"]})) (.setOnLoadCallback js/google draw-demo-chart) )) (defn draw-demo-chart-container [] (let [count (re-frame/subscribe [:count]) columns (reaction [["date" "X"] ["number" "Y"]]) vectors (reaction (clj->js [[(new js/Date "07/11/14") 145] [(new js/Date "07/12/14") 15] [(new js/Date "07/13/14") 23] [(new js/Date "07/14/14") 234]])) options (reaction (clj->js {:title (str @count)})) chart (reaction (new js/google.visualization.LineChart (.getElementById js/document "linechart"))) ] (fn [] [draw-demo-graph @columns @vectors @options @chart]))) (def draw-demo-graph (r/create-class {:reagent-render draw-demo-chart :component-did-mount draw-demo-chart :component-did-update draw-demo-chart})) 
+8
clojure clojurescript reagent re-frame
source share
1 answer

There are several problems using the Google Graphics API:

  • It loads asynchronously and can only be used when it is ready.

I suggest using a flag to record whether the API is ready or not, this will allow it to be displayed even if loading the API after installing the component.

 (defonce ready? (reagent/atom false)) (defonce initialize (do (js/google.charts.load (clj->js {:packages ["corechart"]})) (js/google.charts.setOnLoadCallback (fn google-visualization-loaded [] (reset! ready? true))))) 
  1. You need to call draw on the HTML element:

An HTML element will only exist if the component is installed. You can use ref to conveniently get the HTML element (otherwise you need to either save the mount link or find it).

 (defn draw-chart [chart-type data options] [:div (if @ready? [:div {:ref (fn [this] (when this (.draw (new (aget js/google.visualization chart-type) this) (data-table data) (clj->js options))))}] [:div "Loading..."])]) 

You want to redraw at any time when any of the inputs changes (as the example above ref ).

  1. Data Source Setup

I suggest a convenience method for getting a data source:

 (defn data-table [data] (cond (map? data) (js/google.visualization.DataTable. (clj->js data)) (string? data) (js/google.visualization.Query. data) (seqable? data) (js/google.visualization.arrayToDataTable (clj->js data)))) 
  1. Use it

Now you can use your chart with reactive values!

 [draw-chart "LineChart" @some-data {:title (str "Clicks as of day " @day)}] 

Full list of codes at https://github.com/timothypratley/google-chart-example

+5
source share

All Articles