d3 JavaScript 翻译成 ClojureScript

d3 JavaScript translation to ClojureScript

我想将以下 JavaScript 翻译成 ClojureScript:

var myScale = d3.scaleLinear()
  .domain([0, 10])
  .range([0, 600]);

创建此函数后,您应该可以使用号码调用它:

myScale(3);   // returns 180 

我的尝试如下:

(:require ["d3-scale" :refer (scaleLinear)])

(let [f (-> scaleLinear
            (. (domain (clj->js [0 10])))
            (. (range (clj->js [0 600]))))]
      (f 3))

给出:

react-dom.development.js:16545 Uncaught TypeError: module$node_modules$d3_scale$dist$d3_scale.scaleLinear.domain is not a function

经过反复试验,我确实让它工作了。这些都是等价的:

(-> (new scaleLinear)
    (.domain (clj->js [0 10]))
    (.range (clj->js [0 600])))

(-> (new scaleLinear)
    (. (domain (clj->js [0 10])))
    (. (range (clj->js [0 600]))))

(-> (scaleLinear.)
    (.domain #js [0 10])
    (.range #js [0 600]))

scaleLinear是一个可以从d3调用的函数。它不是应该建造的东西。所以这是一个更好的答案:

(-> d3
    (.scaleLinear)
    (.domain #js [min-y max-y])
    (.range #js [1 0]))

我的要求有问题,所以这里是相关的:

["d3" :as d3]
["d3-scale" :refer (scaleLinear)]

这是使用 shadow-cljs 而不是 cljsjs。

要求 "d3" 的麻烦是你把整个库都拉进来了。所以 这是另一种方法:

(-> (scaleLinear)
    (.domain #js [min-y max-y])
    (.range #js [1 0]))

看来,无论何时你需要什么东西,你都可以直接使用它,而忘记了互操作点。

(:require ["d3" :as d3]) 意味着你将 d3 拉入本地范围。 js/d3 是全局范围,所以如果需要的话,只需使用 d3 即可。即 js 是另一个 'interop' 你可以忘记的东西。

另一方面,domainrange 不是必需的,因此需要遵守互操作规则。

总之 - 解决的主要问题是 scaleLinear 是一个函数,因此实际上需要调用它!

在开始探索通过 React Vis 使用 d3 时提出了这个问题 - 请参阅 https://medium.com/@cjmurphy/using-react-vis-from-clojurescript-787d02281f7c