SVG drawing in Vaadin

I’ve been looking for an easy way to make data-driven drawings in Vaadin that scale nicely when zoomed. Below is a static polygon made using SVGGraphics2D, converted to SVG/XML with JFreeSVG and put in an AbsoluteLayout called weights. A similar pattern could be used for a more complex drawing refreshed with new data as desired.

        // initialize a drawing surface
        SVGGraphics2D drawing = new SVGGraphics2D(97, 163);
        
        // trace the polygon's outline
        GeneralPath aircraftOutline = new GeneralPath();        
        aircraftOutline.moveTo(.5, .5);
        aircraftOutline.lineTo(96.5, .5);
        aircraftOutline.lineTo(96.5, 65.5);
        aircraftOutline.lineTo(83, 162.5);
        aircraftOutline.lineTo(14.5, 162.5);
        aircraftOutline.lineTo(.5, 65.5);
        aircraftOutline.lineTo(.5, .5);
        
        // fill it with a grey colour
        drawing.setPaint(Color.decode("#C9C9C9"));
        drawing.fill(aircraftOutline);

        // define and draw the outline 
        drawing.setPaint(Color.decode("#808080"));
        drawing.setStroke(new BasicStroke(1));
        drawing.draw(aircraftOutline);        

        // create an xml string in svg format from the drawing
        String drawingSVG = drawing.getSVGElement();

        // create a StreamResource from the string provided with a unique file name 
        String filename = "polyoutline" + System.currentTimeMillis() + ".svg";
        StreamResource stream = new StreamResource( 
                () -> new ByteArrayInputStream(drawingSVG.getBytes(StandardCharsets.UTF_8)), filename);

        // make an embedded object from the StreamResource and lay it out
        Embedded planeOutline = new Embedded();
        planeOutline.setSource(stream);        
        weights.addComponent(planeOutline, "left: 101px; top: 50px;");

This works and looks like a good solution, but as always improvements from experts are welcome…

Hi,

Thats a perfectly valid solution. Another is using Batik to create the SVG.

cheers,
matti

Hi Steve, this looks great! and I’d second Matti: As long as you don’t need client interaction or animation: go for that…!

Dynamic, data driven drawing objects become clickable by taking the StreamResource output from the drawing and applying it to a button.

        button.setIcon(stream);

A shortcoming of the code above was the use of system time to create a filename
String filename = "polyoutline" + System.currentTimeMillis() + ".svg"; Multiple programatically created drawings can spawn in the same millisecond leading to non-unique file names so they interfere with each other. This substitute works:

        UUID unique = UUID.randomUUID();
        String filename = "fuelgauge" + unique + ".svg";

An example of the use in my application is a fuel gauge (attached) which looks sharp at any zoom level. The coloured quantities and flags change with fuel level, current and proposed flight duration, aircraft weights etc. The user clicks on the graphic to evoke a page where the fuel level can be updated.

15953.png

Can you give me some resource for drawing SVG file in vaadn 7?

There must be many, but one simple approach is to use
Google’s on-line tool
. You can draw using typical drawing tools and see the XML output, or you can input or tweak the XML and see the results to your drawing.

You can use the XML file (an .svg file) as a resource in Vaadin, or you can draw an svg element directly in your Java code as shown above, using the result in your Vaadin app.

Thanks Demy,
But I need to draw in vaadin application. Google’s on-line tool maybe developed by jquery. I want to develop that types of project in vaadin 7. Can I draw in vaadin 7 application? If possible Please give me vaadin resourse. It is great help for me.

Hi Bishwajit, I’m not sure what you want, but the example above shows how you’d use JFreeSVG to draw using the SVGGraphics2D class. Once you’re done with your drawing you make a string of the svg XML output. As shown above, that string can be made into a StreamResource, which can be used as a button image, for example, or can further be made into an Embedded object and placed in a Vaadin layout. It’s one option that satisfied my need to make data-driven drawings within Vaadin apps. You could use Apache Batic instead of JFreeSVG. It is bigger, slower and has more features. Take a look at those two and the example above and you should be drawing in Vaadin shortly.

Thanks Demy, I am trying with your instratution.

Best Regards,
Bishwajit Barua