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)))))
- 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 ).
- 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))))
- 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
Timothy pratley
source share