10

我正在试验/学习 ClojureScript。以下代码片段与优秀的 d3.js 库接口以显示一些圆圈。发现它有点冗长,不求助于宏,有没有办法优化/最小化它?

(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)
)

谢谢

4

1 回答 1

12

要初始化刻度,您可以编写(.linear (.-scale js/d3)),这更简洁一些。此外,在此代码片段中,没有理由对数据使用 Atom。如果要更新可视化,可以将新数据作为参数传递给update而不是改变原子并调用无参数更新 fn。

用于链接的线程宏惯用语,所以你很好。

再说一次,没有比直接使用 Clojure 库更惯用的方法了。查看C2,D3 的 Clojure(Script) 实现。(当然,作为主要作者,我对那个有点偏见。)

如果您需要使用 D3 本身,您可能还想浏览现已弃用的cljs-d3包装器的源代码。

宏是获得更简洁接口的一种方式(例如,将映射文字扩展为多个(.attr "key" value)调用),但链接宏的语义允许您将任何 fn 注入到链中,这与 JavaScript 的情况非常不同。例如,您可以编写一个普通的 fn,它接受 d3 选择和一个属性映射,并用于doseq调用(.attr d3 k v)每个映射键/值。

实际上,去年 Clojure Conj 就这个主题(以 D3 为例)进行了40 分钟的演讲。

于 2012-05-26T04:04:56.497 回答