2012-05-25 6 views
10

Estoy experimentando/aprendiendo ClojureScript. El siguiente fragmento de código interactúa con la excelente d3.js lib para mostrar algunos círculos. Encontrar que es un poco detallado, sin recurrir a macros, ¿hay alguna forma de optimizarlo/minimizarlo?¿Esto se consideraría idiomático ClojureScript?

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

Gracias

Respuesta

12

para inicializar la balanza se puede escribir (.linear (.-scale js/d3)), que es un poco más concisa. Además, en este fragmento de código no hay ninguna razón para usar un Atom para los datos. Si desea actualizar la visualización, puede pasar datos nuevos como argumento al update en lugar de mutar el átomo y llamar a una actualización no-arg fn.

El enhebrado macro idiomático para encadenar, por lo que eres bueno allí.

Por otra parte, no puede ser más idiomático que usar una biblioteca Clojure recta arriba; echa un vistazo a C2, una implementación Clojure (Script) de D3. (Por supuesto, como el autor principal Soy un poco parcial en que uno.)

Si es necesario utilizar sí D3, también puede que quiera a rozar la fuente de la ya obsoleta-cljs-d3 envoltura.

Las macros son una forma de obtener una interfaz más concisa (por ejemplo, ampliar los literales de los mapas en múltiples (.attr "key" value) llamadas), pero la semántica del macro de encadenamiento le permite inyectar cualquier fn en la cadena, que es muy diferente del caso de JavaScript . Podría, por ejemplo, escribir un simple fn que tome la selección d3 y un mapa de atributos y use doseq para llamar al (.attr d3 k v) para cada clave/valor del mapa.

En realidad, hay un 40 minute talk sobre este tema exacto (utilizando D3 como ejemplo) de Clojure Conj el año pasado.

+1

Gracias Kevin por los comentarios y se dirige a C2 y d3-cljs. C2 parece interesante, estoy buscando una implementación puramente del lado del cliente, ¿es posible hacer esto con C2/ClojureScript? – user922621

+0

En cuanto a Atom para datos, desea evolucionar el código a un panel con los datos que se envían al cliente de forma incremental ... ¿no sé si Atom es el enfoque correcto? – user922621

+0

Atom es un gran enfoque para manejar el estado. Sin embargo, trataría de aislarlo: defina el átomo hacia arriba, pero desreferencia lo menos posible, prefiera pasar los datos explícitamente a través de argumentos fn. –