Google 图表 CLJS Clojure
Google Chart CLJS Clojure
我试图在 Google 图表中调整此 。到re-frame
框架,reagent
。我想创建一个基于订阅的实时图表。我用一个简单的计数器测试 =+-1.
我收到错误: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}))
使用 Google 图表有几个挑战 API:
- 它是异步加载的,只有在准备就绪时才能使用。
我建议使用一个flag来记录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)))))
- 您需要在 HTML 元素上调用
draw
:
HTML 元素只有在组件已安装后才会存在。您可以使用 ref
来方便地获取 HTML 元素(否则您需要在安装时保存对 in 的引用,或搜索它)。
(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
我试图在 Google 图表中调整此 re-frame
框架,reagent
。我想创建一个基于订阅的实时图表。我用一个简单的计数器测试 =+-1.
我收到错误: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}))
使用 Google 图表有几个挑战 API:
- 它是异步加载的,只有在准备就绪时才能使用。
我建议使用一个flag来记录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)))))
- 您需要在 HTML 元素上调用
draw
:
HTML 元素只有在组件已安装后才会存在。您可以使用 ref
来方便地获取 HTML 元素(否则您需要在安装时保存对 in 的引用,或搜索它)。
(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