How to create and manage SVG with JavaScript

Written by Richard Heyes, on 15th August 2018

This blog article tells shows you how to create SVG and SVG tags using JavaScript - instead of simply adding them to your HTML document. It shows you examples of the JavaScript code that you can use.

Since you can just embed an SVG tag in HTML many tutorials focus on that, or the use of an external SVG file (for example a file called myimage.svg) but for RGraphs needs it had to be created with JavaScript.

This way you could define a snippet of JavaScript - which most web developers are already quite familiar with - and the nitty-gritty of actually creating the SVG tags (which can sometimes be quite finicky) - is done for you.

How to create an SVG tag with JavaScript

The first thing that you'll want to do is create the sVG tag itself. With RGraph you add a DIV tag to your document, size it appropriately using CSS and the routine that creates the SVG tag picks up those sizes and sets the SVG tag to be the same size.

This way you can just add a familiar DIV tag to your document and then leave it to function to create an appropriately sized SVG tag.

This is the HTML that's necessary that results in the routine below creating an SVG tag:

<style>
    div#cc {
        width: 500px;
        height: 500px;
    }
</style>

<div id="cc"></div>

This is the JavaScript function that creates the SVG tag:

function createSVG (opt)
{
    // The container option should be the DIV tag or the ID of the DIV tag.
    var container = opt.container;

    // If it's a string get the DOM node
    if (typeof container === 'string') {
        container = document.getElementById(container);
    }

    // Create the SVG tag using standard API methods
    var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    
        // Set the positioning to absolute so the SVG tag is in the top
        // left corner of the DIV. We'll change the positioning of the DIV
        // tag further down
        svg.setAttribute('style', 'top: 0; left: 0; position: absolute');
        
        // Set the width and height of the SVG tag - which are the same as the
        // DIV tag so the SVG tag entirely fills the DIV tag
        svg.setAttribute('width', container.offsetWidth);
        svg.setAttribute('height', container.offsetHeight);

        // Add some necessary attributes to the SVG tag. The extra XLink
        // namespace allows you to have links in your SVG document
        svg.setAttribute('version', '1.1');
        svg.setAttributeNS("http://www.w3.org/2000/xmlns/", 'xmlns', 'http://www.w3.org/2000/svg');
        svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
        
        // Store a reference to the container on the SVG tag
        svg.__container__ = container;
    
    // Add the SVG tag to the document
    container.appendChild(svg);

    // Add a reference to the SVG tag to the container DIV element
    container.__svg__    = svg;

    // If the positionining of the container isn't absolute, fixed or sticky
    // then set it to relative. The SVG tag is positioned absolutely (above) and
    // thus it needs this so it's positioned in the top left corner of the DIV
    var style = getComputedStyle(container);
    if (style.position !== 'absolute' && style.position !== 'fixed' && style.position !== 'sticky') {
        container.style.position = 'relative';
    }

    // Return the SVG tag to the caller
    return svg;
};

And you would use this function when you first start with your SVG like this (there's not much to it as you can see):

// Create the SVG tag
svg = createSVG({
    container: 'cc'
});

How to create an SVG element with JavaScript

Once you've got an SVG tag added to your document you can start adding elements to it (for example <rect> or <circle> elements). To add the elements here's another function that can do that for you.

//
// Creates an SVG tag depending on the arguments that you give the function
//
//@param opt object The options for the function
//
function create (opt)
{
    // Stipulate the correct namespace and create the tag.
    var ns  = "http://www.w3.org/2000/svg",
        tag = doc.createElementNS(ns, opt.type);

    // Add the attributes to the new tag
    for (var o in opt.attr) {
        if (typeof o === 'string') {
        
             The name of the desired attribute
            var name = o;

            // If you want to add a CSS class to the tag then use "className"
            // instead of "class" like in CSS
            if (o === 'className') {
                name = 'class';
            }

            // Set the attribute on the tag using the DOM method .setAttribute()
            // unless the attribute is 'xlink:href' in which case the .setAttributeNS()
            // method must be used instead.
            if ( (opt.type === 'a' || opt.type === 'image') && o === 'xlink:href') {
                tag.setAttributeNS('http://www.w3.org/1999/xlink', o, String(opt.attr[o]));
            } else {
                tag.setAttribute(name, String(opt.attr[o]));
            }
        }
    }
    
    // Add any requested stylesheet information that has been stipulated
    for (var o in opt.style) {
        if (typeof o === 'string') {
            tag.style[o] = String(opt.style[o]);
        }
    }

    // If the parent option has been stipulated then add it as a child to
    // that element. Otherwise add it as a child of the SVG tag. This allows you
    // to add nested elements to your SVG document.
    if (opt.parent) {
        opt.parent.appendChild(tag);
    } else {
        opt.svg.appendChild(tag);
    }

    // Return the newly created tag object
    return tag;
};
And you would use this function when you want to add an SVG child element to your SVG document (for example a <rect> tag) like this:

        /*************************
         * Create a rect element *
         *************************/
        rect = create({
            svg: svg,
            type: 'rect',
            attr: {
                x: 5,            // The X coordinate of the rectangle
                y: 5,            // The Y coordinate of the rectangle
                width: 100,      // The width of the rectangle
                height: 100,     // The height of the rectangle
                fill: 'red',     // The fill colour of the rectangle
                stroke: 'black'  // The stroke colour of the rectangle
            }
        });

        /********************************
         * Create a g element (a group) *
         ********************************/
        g = create({
            svg: svg,
            type: 'g',
            attr: {
                // No attributes to give the group just yet
            }
        });

        /***************************
         * Create a circle element *
         ***************************/
        circle = create({
            svg: svg,
            type: 'circle',

            parent: g, // The circle is added as a child of the group that
                       // was just added
            attr: {
                cx: 200,        // The center X coordinate
                cy: 200,        // The center Y coordinate
                r: 50,          // The radius of the circle
                stroke: 'black' // The stroke of the circle. Because no fill has been
                                // specified it defaults to black (but is changed a
                                // few lines down)
            }
        });

        /***************************************************
         * Set the groups fill to blue which means all of  *
         * the sub-elements of the group inherit the       *
         * color too - ie the circle that was just added   *
         ***************************************************/
        g.setAttribute('fill','blue');

A standalone example

Here's a standalone example of the two functions and their usage. Feel free to take the code and add it to your own library of SVG related functions.

https://www.rgraph.net/blog/how-to-create-and-manage-svg-with-javascript-example.html