2017-08-30 97 views
8

我试图在Google图表中使用这个example。到re-frame框架,reagent。我想创建一个基于订阅的实时图表。我测试了一个简单的计数器= + - 1。Google Chart CLJS Clojure

我得到的错误: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

它看起来并不因为如果你有相当正确的方法。本教程应指导您进行必要的调整:https://github.com/Day8/re-frame/blob/master/docs/Using-Stateful-JS-Components.md –

+0

正如我发布..与d3一起工作。 JS,我只是想创建Google Chart版本。我不知道是什么问题,因为在d3.js版本中我找回了数据。没有问题。在谷歌图表案例..不。我从很多论坛回来的链接..只是我不明白为什么不与谷歌图表这种方法工作...哪里是我的身边的错误:s – RRR

回答

5

有几个挑战,使用谷歌API图表:

  1. 它异步加载,只能使用时准备好。

我建议使用一个标志来记录API是否准备就绪,这将允许它即使装载组件后的API加载也能够呈现。

(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))))) 
  • 需要调用一个draw HTML元素:
  • 如果组件具有安装在HTML元素将仅存在。您可以使用ref来方便地获取HTML元素(否则,您需要将引用保存为挂载或搜索)。

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

    你要重绘任何时候任何输入的变化(这上面ref例子做)的。

  • 设置数据源
  • 我建议一个方便的方法用于获取数据源:

    (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)))) 
    
  • 使用它
  • 现在你可以使用你的图表反应值!

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

    完整代码清单是 https://github.com/timothypratley/google-chart-example