Hi C2 users,
I have been toying with a C2 UI for which I use a two-pass rendering method.
My use case is a dataflow diagram in which device are connected to other devices via output and input slots. A picture will make this clearer:
Dataflow diagram
The devices ("boxes") are divs, input and output slots are nested divs, and the connections are rendered on a background SVG element.
Now, I cannot draw the connections until the slots positions are known (i.e. the elements have been added to the DOM), hence my current workaround,
bind-then!, that takes a callback function:
(defmacro bind-then!
"Similar to C2's bind!, but takes a callback function that
gets triggered after rendering"
[el hiccup-el cf]
`(let [co# (computed-observable ~hiccup-el)
$el# (c2.dom/->dom ~el)]
(singult.core/merge! $el# @co#)
(~cf)
(add-watch co# :update-dom
(fn []
(singult.core/merge! $el# @co#)
(~cf)))
co#))
I use this function with a callback that draws the connections.
The problem is that I currently resort to getting the slot elements by ID (generated in the first rendering pass from the original Clojure data) which brings all sorts of unpleaseant string manipulation, for instance I have functions like this
(defn in-elem
[in]
(.getElementById js/document (str "slotIn." in)))
That completely destroys the declarative awesomeness that is C2.
How can I do better?
Cheers!