d3 перевод JavaScript в 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 не является функцией
2 ответа
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
это еще одна вещь взаимодействия, о которой вы можете забыть.
С другой стороны domain
а также range
не были необходимы, поэтому необходимо соблюдать правила взаимодействия.
В заключение - основная проблема решена в том, что scaleLinear
является функцией и как таковой на самом деле должен быть вызван!
Этот вопрос был задан в начале исследования работы с d3 через React Vis - см. https://medium.com/@cjmurphy/using-react-vis-from-clojurescript-787d02281f7c
С некоторой пробой и ошибкой я заставил это работать. Все они эквивалентны:
(-> (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]))