Directory

← Back

Svg Component

Allows the creation of SVG elements from the server side

Author

Rating

Popularity

400+

Overview

The Vaadin Component Factory SVG component is a wrapper around svg.js that allows creation of simple and complex SVGs from the Vaadin server-side code.

Usage

Add the dependency to your project (see sidebar in directory). Create a new Svg component and add an SvgElement element into it (see code examples)

Client-side implementation

This is the server-side (Java) API for the Vaadin Platform for the vcf-svg component. Looking for the client-side version? It can be found here: https://vaadin.com/directory/component/vaadin-component-factoryvcf-svg

License & Author

This Add-on is distributed under Apache 2.0

Component Factory Svg is written by Vaadin Ltd.

Major pieces of development of this add-on has been sponsored by multiple customers of Vaadin. Read more about Expert on Demand at: Support and Pricing

Sample code

        Svg draw = new Svg();
        Rect rect = new Rect("rect", 100, 100);
        Circle circle = new Circle("circle", 50);

        rect.move(75, 0);
        rect.size(150, 150);

        circle.center(150, 75);
        circle.setRadius(75);
        circle.setFillColor("#396");

        draw.add(rect);
        draw.add(circle);
        VerticalLayout demoContainer = new VerticalLayout();
        HorizontalLayout controlButtons = new HorizontalLayout();
        demoContainer.add(controlButtons);
        Span dragDetail = new Span();
        demoContainer.add(dragDetail);

        Svg svg = new Svg();
        svg.viewbox(0, 0, 380, 380);
        svg.setWidth("100%");
        svg.setHeight("500px");

        double size = 100;
        double space = size + 20;
        double x = 20;
        double y = 20;
        String fillColor = "#ff0066";

        //Rect
        Rect rect = new Rect("rect1", size, size);
        rect.setFillColor(fillColor);
        rect.move(x, y);
        svg.add(rect);

        //Circle
        double circleRadial = size / 2;
        Circle circle = new Circle("circle1", circleRadial);
        circle.setFillColor(fillColor);
        circle.move(x += space, y);
        svg.add(circle);

        //Ellipse
        Ellipse ellipse =
            new Ellipse("ellipse1", circleRadial, circleRadial * 0.5);
        ellipse.setFillColor(fillColor);
        ellipse.move(x += space, y);
        svg.add(ellipse);

        //Line
        Line line = new Line("line",
            new AbstractPolyElement.PolyCoordinatePair(x = 20, y += space),
            new AbstractPolyElement.PolyCoordinatePair(x + size,
                y + size));
        line.setStroke(fillColor, 10, Path.LINE_CAP.ROUND, null);
        svg.add(line);

        //Polyline
        List<AbstractPolyElement.PolyCoordinatePair> points = new ArrayList<>();
        points.add(new Polyline.PolyCoordinatePair(50, 0));
        points.add(new Polyline.PolyCoordinatePair(60, 40));
        points.add(new Polyline.PolyCoordinatePair(100, 50));
        points.add(new Polyline.PolyCoordinatePair(60, 60));
        points.add(new Polyline.PolyCoordinatePair(50, 100));
        points.add(new Polyline.PolyCoordinatePair(40, 60));
        points.add(new Polyline.PolyCoordinatePair(0, 50));
        points.add(new Polyline.PolyCoordinatePair(40, 40));

        Polyline polyline = new Polyline("polyline", points);
        polyline.setFillColor("none");
        polyline.setStroke(fillColor, 4, Path.LINE_CAP.ROUND,
            Path.LINE_JOIN.ROUND);
        polyline.move(x += space, y);
        svg.add(polyline);

        //Polygon
        Polygon polygon = new Polygon("polygon", points);
        polygon.setFillColor(fillColor);
        polygon.move(x += space, y);
        svg.add(polygon);

        //Path
        Path path = new Path("path",
            "M0 0 H50 A20 20 0 1 0 100 50 v25 C50 125 0 85 0 85 z");
        path.setFillColor("none");
        path.setStroke(fillColor, 4, Path.LINE_CAP.ROUND,
            Path.LINE_JOIN.ROUND);
        path.move(x = 20, y += space);
        svg.add(path);

        //Text
        Text text = new Text("text", "Sample text.");
        text.setFontFamily("'Roboto', 'Noto', sans-serif");
        text.setFillColor(fillColor);
        text.move(x += space, y);
        svg.add(text);

        //Image
        Image image = new Image("image",
            "https://vaadin.com/images/hero-reindeer.svg");
        image.size(size, size);
        image.move(x += space, y);
        image.setDraggable(false);
        svg.add(image);

        demoContainer.add(svg);

        //Add control buttons
        controlButtons.add(new Button("Toggle Zoom", e -> {
            svg.setZoomEnabled(!svg.isZoomEnabled());
        }));

        controlButtons.add(new Button("Toggle draggable", e -> {
            svg.getSvgElements().forEach(el ->
                el.setDraggable(!el.isDraggable()));

            svg.getSvgElements().forEach(el -> {

                // Due to the nature of how the polygons are written (M0 0),
                // if we do an update to them they will move back to 0,0.
                // Hence, we have to move them back to their desired
                // location when we do an update.
                if (el == polyline) {
                    el.move(20 + space, 20 + space);
                }

                if (el == polygon) {
                    el.move(20 + space * 2, 20 + space);
                }

                svg.update(el);
            });
        }));

        controlButtons.add(new Button("Stroke black", e -> {
            svg.getSvgElements().forEach(el ->
                el.setStroke("#000000", 4, Path.LINE_CAP.ROUND,
                    Path.LINE_JOIN.ROUND));
            svg.getSvgElements().forEach(el -> {

                // Due to the nature of how the polygons are written (M0 0),
                // if we do an update to them they will move back to 0,0.
                // Hence, we have to move them back to their desired
                // location when we do an update.
                if (el == polyline) {
                    el.move(20 + space, 20 + space);
                }

                if (el == polygon) {
                    el.move(20 + space * 2, 20 + space);
                }

                svg.update(el);
            });
        }));
        controlButtons.add(new Button("Display drag events", e -> {
            svg.addDragStartListener(event -> {
                Notification.show("Drag start: " +
                        event.getElement().getId(),2500,
                    Notification.Position.MIDDLE);
                dragDetail.setText("Drag Start for: " +
                    event.getElement().getId() +
                    " X: " + event.getElementX() +
                    " Y: " + event.getElementY());
            });

            svg.addDragEndListener(event -> {
                Notification.show("Drag End: " +
                    event.getElement().getId(), 2500,
                    Notification.Position.MIDDLE);
                dragDetail.setText("Drag End for: " +
                    event.getElement().getId() +
                    " X: " + event.getElementX() +
                    " Y: " + event.getElementY());
            });

              svg.addDragMoveListener(event -> {
                  dragDetail.setText("Drag Move for: " +
                      event.getElement().getId() +
                      " X: " + event.getElementX() +
                      " Y: " + event.getElementY());
//            });

            e.getSource().setEnabled(false);
        }));

        controlButtons.add(new Button("Remove Line", e -> {
            svg.remove(line);
            e.getSource().setEnabled(false);
        }));
 //Extend the rectangle to add a missing or new attribute 
    public class MyCustomSvg extends Rect {

        public MyCustomSvg(String id, double width, double height) {
            super(id, width, height);
        }

        // Ensure that the client-side actually knows how to handle
        // the attribute or if you made your own extension that
        // the attribute names match.
        // For existing client-side attributes look to
        // https://svgjs.com/docs/3.0/manipulating/#attributes
        public void setMyCustomAttribute(){
            setAttribute("theAttributeToSet", "theValueToSet");
        }

        public String getMyCustomAttribute(){
            return getStringAttribute("theAttributeISet");
        }
    }
@Route("ex")
public class ExView extends VerticalLayout {
    
    public ExView() {
        MyCustomSvgComponentWithExtendedEventListenerParams svg =
            new MyCustomSvgComponentWithExtendedEventListenerParams();
        add(svg);

        Circle circle = new Circle("c1", 50);
        circle.setDraggable(true);
        svg.add(circle);

        svg.addDragEndListener(event -> {
            System.out.println("The width on drag end was: " +
                event.getRawEventData()
                    .getNumber(
                        "event.detail.handler.el.node.instance.width()"));
        });
    }

    public static class MyCustomSvgComponentWithExtendedEventListenerParams 
        extends Svg {

        private static final Logger log =Logger.getLogger(
            MyCustomSvgComponentWithExtendedEventListenerParams.class.getName());
        private DomListenerRegistration dragendDomRegistration;

        @Override
        protected void ensureDomDragEndEventListenerRegistered() {
            //super.ensureDomDragEndEventListenerRegistered();

            /*
             * Copied default implementation from super.
             */
            if (dragendDomRegistration == null) {
                dragendDomRegistration = 
                    getElement().addEventListener("dragend", e -> {
                    onDragEndEvent(e.getEventData()
                        .getString("event.detail.handler.el.node.id"), 
                        e.getEventData());
                }).addEventData("event.detail.handler.el.node.id")
                    .addEventData("event.detail.handler.el.node.instance.x()")
                    .addEventData("event.detail.handler.el.node.instance.y()");
                /*
                 *   End of copied default implementation from super
                 */

                //Say we want to include the width of the element when the drag ends
                dragendDomRegistration
                    .addEventData("event.detail.handler.el.node.instance.width()");
            }
        }
    }
}

Compatibility

(Loading compatibility data...)

Was this helpful? Need more help?
Leave a comment or a question below. You can also join the chat on Discord or ask questions on StackOverflow.

Version

Update to Version 23

Released
2023-10-29
Maturity
STABLE
License
Apache License 2.0

Compatibility

Framework
Vaadin 23+
Vaadin 24 in 2.0.0
Vaadin 14+ in 1.1.2
Browser
Firefox
Safari
Google Chrome
Microsoft Edge

Svg Component - Vaadin Add-on Directory

Allows the creation of SVG elements from the server side Svg Component - Vaadin Add-on Directory
### Overview The Vaadin Component Factory SVG component is a wrapper around svg.js that allows creation of simple and complex SVGs from the Vaadin server-side code. ### Usage Add the dependency to your project (see sidebar in directory). Create a new Svg component and add an SvgElement element into it (see code examples) #### Client-side implementation This is the server-side (Java) API for the Vaadin Platform for the vcf-svg component. Looking for the client-side version? It can be found here: https://vaadin.com/directory/component/vaadin-component-factoryvcf-svg ## License & Author This Add-on is distributed under Apache 2.0 Component Factory Svg is written by Vaadin Ltd. ### Sponsored development Major pieces of development of this add-on has been sponsored by multiple customers of Vaadin. Read more about Expert on Demand at: [Support](https://vaadin.com/support) and [Pricing](https://vaadin.com/pricing)
Online Demo
View on GitHub
Issue tracker

Svg Component version 1.0.1
v 1.0.1: - Fixes issue with drag where the drag in some cases would never end - Fixes issue where calling setDraggable(true) before calling svg.add() and then calling svg.update() caused the component to not actually be draggable. v 1.0.0: Initial release: - Initial component API and Element APIs - Supports 9 SVG elements (see demo) - Drag and Drop listener support - Extendable server-side API

Svg Component version 1.0.2
Changes since __v1.0.1__: - Updated the web component to [__v1.0.4__](https://vaadin.com/directory/component/vaadin-component-factoryvcf-svg), fixes `viewbox` method. - Added `panTo` method.

Svg Component version 1.0.3
Update the license to Apache 2.0

Svg Component version 1.0.4
The license checker was still active in v1.0.3. Remove the license checker

Svg Component version 1.1.0
Add a click listener to the component

Svg Component version 1.1.1
Fix an error when the component was used in a dialog

Svg Component version 1.2.0
Update to Version 23

Svg Component version 1.2.1
Update to support Version 24

Svg Component version 1.1.2
* Update web component dependency to 1.0.9 to fix svgjs dependency issue.

Svg Component version 2.0.0
#### New Features: * Add tooltip support to Svg Elements ([#23](https://github.com/vaadin-component-factory/svg/issues/23))

Online