2017-08-30 4 views
8

J'ai essayé d'adapter cette example dans Google Chart. Pour re-frame cadre, reagent. Je voudrais créer un graphique en temps réel, basé sur les abonnements. J'ai testé avec un simple compteur = + - 1.Google Chart CLJS Clojure

J'ai eu une erreur: 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})) 
+0

Il ne semble pas que si vous avez tout à fait la bonne approche. Ce tutoriel devrait vous guider vers les réglages nécessaires: https://github.com/Day8/re-frame/blob/master/docs/Using-Stateful-JS-Components.md –

+0

Comme je l'ai posté .. qui fonctionne avec d3. js, je veux juste créer la version Google Chart. Je ne sais pas quel est le problème, car à la version d3.js j'ai récupéré les données. Sans problème. Au cas de Google Chart .. pas. Je suis revenu de nombreux forum ce lien .. juste je ne comprends pas pourquoi ne fonctionne pas avec Google Chart cette méthode ... où est l'erreur de mon côté: s – RRR

Répondre

5

Il y a plusieurs défis à l'aide de l'API Google Charts:

  1. Il charge de façon asynchrone et ne peut être utilisé lorsque vous êtes prêt.

Je suggère d'utiliser un indicateur pour enregistrer si l'API est prête ou non, cela lui permettra de s'afficher même si l'API est chargée après le montage du composant.

(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. Vous devez appeler draw sur un élément HTML:

L'élément HTML n'existera si le composant est monté. Vous pouvez utiliser un ref pour obtenir facilement l'élément HTML (sinon, vous devrez soit enregistrer une référence dans le montage, soit le rechercher).

(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..."])]) 

Vous voulez redessiner tout moment l'un des changements des entrées (dont l'exemple ci-dessus ref fait).

  1. Configuration de la source de données

Je propose une méthode pratique pour obtenir la source de données:

(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. Utilisez-le

Maintenant vous pouvez utiliser votre graphique avec des valeurs réactives!

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

listing code complet est à https://github.com/timothypratley/google-chart-example