我正在试验/学习ClojureScript。下面的代码片段与优秀的d3.js lib接口,以显示一些圆圈。发现它有点冗长,没有求助于宏,有没有办法优化/最小化它?
(def rdata (atom (array 3 10 12 16 19)))
(defn update []
(let [em (.selectAll (.select js/d3 "svg") "circle")
data (.data em @rdata d3/String)
enter (.append (.enter data) "circle")
yscale (.linear (. js/d3 -scale))
xscale (.linear (. js/d3 -scale))
rscale (.linear (. js/d3 -scale))
]
(-> yscale
(.domain (array 0 20))
(.range (array 100 200)))
(-> xscale
(.domain (array 0 20))
(.range (array 100 800)))
(-> rscale
(.domain (array 0 20))
(.range (array 50 100)))
(-> enter
(.attr "cx" xscale)
(.attr "cy" yscale)
(.attr "r" rscale)
(.style "fill" "steelblue")
(.style "stroke" "black")
(.style "stroke-width" "2")
)
)
(.info js/console "rdata: " @rdata)
)
由于
答案 0 :(得分:12)
要初始化比例,您可以编写(.linear (.-scale js/d3))
,这样更简洁。
此外,在此代码段中,没有理由使用Atom作为数据。
如果要更新可视化,可以将新数据作为参数传递给update
,而不是改变原子并调用no-arg update fn。
用于链接的线程宏惯用语,所以你在那里很好。
然后再次,你不能比使用直接的Clojure库更习惯;查看C2,即D3的Clojure(脚本)实现。 (当然,作为主要作者,我对这一点有点偏见。)
如果您需要使用D3本身,您可能还想浏览现已弃用的cljs-d3包装器的来源。
宏是获得更简洁接口的一种方法(例如,将地图文字扩展为多个(.attr "key" value)
调用),但链接宏的语义允许您将任何fn注入链中,这与JavaScript案例。
例如,您可以编写一个简单的fn,它接受d3选择和属性映射,并使用doseq
为每个映射键/值调用(.attr d3 k v)
。
实际上,去年Clojure Conj对这个确切的主题(使用D3作为例子)有一个40 minute talk。