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]))
Другие вопросы по тегам