Javascript – Using SVG in GWT

gwthtmljavascriptsvg

I was wondering if it is possible to include SVG content inside a panel (or whatever would work in GWT), be able to add more to the SVG (like add a circle or a curve) programmatically , and handle mouse events (would this be in SVG or GWT?). I've tried creating an HTML object adding something along the lines of:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="50" cy="50" r="30" />
</svg>

That didn't work (nothing visible in output) but I'm not sure if it was because I did it wrong or it's not allowed.

I was able to do a simple example in GWT with Google Visualization's LineChart but I'd like to move away from Google Visualization and be able to generate the SVG myself and customize it further. I've looked around and many resources points to using Canvas but I'm not sure if that's the best route yet.

I'm also a bit baffled about the example here. I tried a simple copy-paste of it to try locally and it didn't seem to work at all. I was however able to get another sample working with just HTM (embed with src pointing to SVG file) L + separate SVG file but I haven't been able to access it using GWT using RootPanel.get(…).

EDIT:
I've read about SVG not working with Hosted Browser and compiling it does work but I am uncertain how to refer to the SVG (which I have placed into the HTML via ). If I can access it then presumably I can add to its innerHTML. I've tried in RootPanel.get("hi").getElement().setInnerHTML("…") but that doesn't seem to work or did I mess up? I guess the goal is to be able to manipulate a SVG file which I linked somehow (whether in GWT or in HTML) and be able to modify it based on user's input.

2nd EDIT
So far, I've been programming functionality inside of the actual SVG file. In our setup, our SVG is an embedded object and we passed 'document' to the embedded SVG. Passing information from an embed object to and from HTML is quite doable since the HTML has access to our SVG functions and the SVG has access to the 'document'.

There are more transparent ways of doing so (Rapahel) where FireBug could see the SVG directly which is nice but now not quite necessary. Thus far, I don't think any of the solutions I've looked at were IFrames but I could be wrong. A little warning, SVG can be pretty slow sometimes.

I would say my issue is solved (sort of?) but I'm not using Raphael, jQuery, nor GWT at the moment but the method I described in my answer should still work if I want to use GWT.

Best Answer

I don't entirely understand why, but the createElementNS JavaScript method allows you to create and correctly format xhtml within html.

Because there is no equivalent in explorer, GWT does not implement createElementNS, but you can with a quick native method :

private static native Element createElementNS(final String ns, 
        final String name)/*-{
    return document.createElementNS(ns, name);
}-*/;

It makes sense to put this into an SVGPanel class.

import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;

public class SVGPanel extends ComplexPanel{

    private static final String SVG_NAMESPACE = "http://www.w3.org/2000/svg";

    public SVGPanel() {
        setElement(createElementNS(SVG_NAMESPACE, "svg"));
        showcaseSVG(); //Demonstrate that SVG works! Inexplicably!
    }

    private void showcaseSVG(){
        Element svgElement = createElementNS(SVG_NAMESPACE, "circle");
        svgElement.setAttribute("cx", "50");
        svgElement.setAttribute("cy", "50");
        svgElement.setAttribute("r", "30");
        getElement().appendChild(svgElement);
    }
}

This should produce some simple SVG when added to your program. Congratulations! You are now sticking it to the xhtml man.