last month I helped a friend work through creating an svg element with reflexfrp. it would not show up in the browser so have been trying to figure out how to get this working.
First tried compiling ghcjs svg.hs
(below) with the following contents.
it compiles into a working webpage, however nothing shows up in the browser! whaaaaat??? time to delve into the svg docs from w3 to see what might be required when defining an svg tag properly
an svg document fragment can range from an empty fragment (i.e., no content inside of the ‘svg’ element), to a very simple svg document fragment containing a single svg graphics element such as a ‘rect’, to a complex, deeply nested collection of container elements and graphics elements. - w3.org
As I read further, they tell me my svg elements should look like this:
edited svg.hs
and tried again, using elattr
instead of el
to add attributes to the svg element but guess what, this also didn’t show anything in the browser.
Next, looked for working examples to see how others tackle this problem. In the course of this I found two places that posted examples.
Diagrams-Reflex
There are working examples of using the graphics diagrams library to render svg elements with reflex in the diagrams-reflex repo.
At this time there are three known examples with this repo: (1) Click counting, source; (2) Mouse position, source; and (3) Colors, source
No documentation found.
Rotating Cube
On another site, an example of a rotating cube. Note, to work with the try-reflex default install you’d need to add the matrix library to list of packages.
This was the one that made me see that both the "svg"
and "polygon"
tags call this one function that uses elDynAttrNS'
:
Bingo.
Summary
What I learned - when working with the xml namespace, there’s a specific function available in reflex-dom and this can also be used to produce dynamic svg elements. Is the dynamic version better than a static elAttr
? No clue, but using elDynAttrNS'
works and I’ll be scaling towards creating dynamic graphics in the browser I’ll probably stick to picking that option.
What is elDynAttrNS’?
From the Hackage docs we can read the type signature.
elDynAttrNS' :: forall t m a. MonadWidget t m => Maybe String -> String -> Dynamic t (Map String String) -> m a -> m (El t, a)
What this means: four inputs, the first is the xml namespace declaration, the 2nd the svg element, the third includes further attributes, and the last is a monad. This returns a monad, so you have to bind it to something~
Ahh success. Feels good to have figured out a working solution. I’ll update the sample svg.hs
file with the working code
Links