Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG in Clojurescript

What's the best way to add SVG elements to the dom in Clojurescript ? The Twitterbuzz example uses Google Closure lib's Graphics objects, but say I didn't care about IE compatibility, is there a way I could add elements the way html is (dom/build [:svg [:g [:text "something like this ?"]]]) I tried Closure's graphics lib but I don't get to use a lot of handy SVG features. I tried Apogee, but that serializes the SVG code and I would prefer direct DOM manipulation.

like image 423
Hendekagon Avatar asked Jan 18 '23 13:01

Hendekagon


2 Answers

dom/build constructs DOM elements without the namespace. You need to either enhance dom/build or write one for SVG. I use the following code to create SVG elements.

(defn element-ns
  "Create a namespaced dom element"
  [namespace tag & args]
  (let [[tag attrs children] (normalize-args tag args)
        parent (. js/document createElementNS namespace (name tag))
        [parent children] (if (string? (first children))
                            [(set-text (element-ns namespace tag attrs) (first children))
                             (rest children)]
                            [parent children])]
    (doseq [[k v] attrs]
      (. parent setAttributeNS nil (name k) v))
    (apply append parent children)))

(defn build-svg
  "Build up a svg element from nested vectors."
  [x]
  (if (vector? x)
    (let [[parent children] (if (keyword? (first x))
                          [(apply element-ns "http://www.w3.org/2000/svg" (take-while element-arg? x))
                           (drop-while element-arg? x)]
                          [(first x) (rest x)])
       children (map build-svg children)]
       (apply append parent children))
    x))
like image 174
Synk Avatar answered Jan 21 '23 03:01

Synk


You might be interested in my cljs-d3 library, which is a ClojureScript wrapper for the D3 JavaScript library. D3 is an excellent tool for manipulating an SVG DOM.

like image 32
Kevin L. Avatar answered Jan 21 '23 03:01

Kevin L.