--- title: "SvgDiagram" slug: "creating-svg-diagrams" updated: 2025-10-09T11:07:00Z published: 2025-10-09T11:07:00Z canonical: "learn.servitly.com/creating-svg-diagrams" --- > ## Documentation Index > Fetch the complete documentation index at: https://learn.servitly.com/llms.txt > Use this file to discover all available pages before exploring further. # SvgDiagram Scalable Vector Graphics (SVG) is a powerful and flexible format for displaying complex and dynamic diagrams on the web. Unlike images, SVGs are resolution-independent and can be manipulated through CSS, JavaScript, and even create interactive and adaptive visualizations. This article explores how SVG can be used to build complex diagrams that update dynamically based on metric data, also in real-time. ## Adding SVG to widgets When defining a widget, you can leverage a built-in JavaScript `SvgDiagram` class based on the public [SVG.js (v3.2.4)](https://svgjs.dev/docs/3.2) library, which provides a rich set of functions for creating and manipulating SVG elements. To start using this class, you must include it in your widget’s [Dependencies](/docs/component-dependencies). ![](https://cdn.document360.io/6759e9c9-3ce3-49df-965a-7231d2d9a10a/Images/Documentation/image(721).png?sv=2026-02-06&spr=https&st=2026-10-16T17%3A17%3A52Z&se=2026-10-16T18%3A17%3A52Z&sr=c&sp=r&sig=%2BfVRMgBJcdNJ5Nw28B981BjyK%2Bh2Cc6%2Fj%2BcR%2Frtnhjo%3D) In the following widget code example, you can see how to use the `SvgDiagram` class to create and update an SVG diagram. ```javascript class MySchemaWidget extends AbstractWidget { constructor(config) { config = config || {}; config.height = config.height || "480px"; config.width = config.width || "640px";        super(config); } onInit(context) { let widget = this; this.svgDiagram = new SvgDiagram(); let promises = []; promises.push(super.onInit(context));        // load SVG.js resources promises.push(this.loadResources(this.svgDiagram.getSvgResources())); promises.push(this.loadMetricDefinitions(context)); return Promise.all(promises).then(function() { widget.createOrUpdateSchema(context); widget.setLoaderVisible(false); }).catch(error => { console.error(error); widget.showError({ "message": "Error initializing SVG diagram" }); widget.setLoaderVisible(false); }); }    createOrUpdateSchema(context) { let widget = this; let metricValue = parseInt(context.data[context.metrics[0].name].value) || 0;    let radius = metricValue * 10;        console.log(JSON.stringify(context.data));    console.log(context.metrics[0].name + ": " + radius);        if(!this.svgDiagram.draw){           // create the SVG root element                 let draw = this.svgDiagram.createSvg(context.htmlElement, { 'height': parseInt(widget.config.height), 'viewportWidth': parseInt(widget.config.width), 'viewportHeight': parseInt(widget.config.height) });     // add the SVG elements           draw.line(0, 240, 640, 240).stroke({ width: 5, color: "#28a745"});           this.circle = draw.circle(radius).cx(320).cy(240).stroke({ width: 2, color: "#28a745"}).fill("#ffc107");           this.text = draw.text(metricValue.toString()).font({size: 24, color: "#28a745"}).cx(320).cy(240);        } else {                     // update SVG elements           this.circle.radius(radius);           this.text.text(metricValue.toString()).cx(320).cy(240);        }   }   onDataUpdated(context) {       this.createOrUpdateSchema(context);   }   onInputUpdated(context) {   // handle inputs and update schema   }   onDestroy(context) {   super.onDestroy(context);   } } ``` Running the code above will result in an SVG as follows. ![](https://cdn.document360.io/6759e9c9-3ce3-49df-965a-7231d2d9a10a/Images/Documentation/image(722).png?sv=2026-02-06&spr=https&st=2026-10-16T17%3A17%3A52Z&se=2026-10-16T18%3A17%3A52Z&sr=c&sp=r&sig=%2BfVRMgBJcdNJ5Nw28B981BjyK%2Bh2Cc6%2Fj%2BcR%2Frtnhjo%3D) If your widget needs to be updated frequently on the page, we recommend that you cache the SVG elements instead of recreating them each time an update occurs. For instance, the method `createOrUpdateSchema()` creates a new SVG element the first time, but the next times it is invoked (e.g., a metric is updated), the elements are already available and can therefore be directly updated. If the widget is destroyed, e.g., by navigating to another page, the associated SVG elements are destroyed along with it. ## SvgDiagram Class Reference The `SvgDiagram` class has the following methods. | *createSvg(htmlElement, options)* | Creates a new SVG element attached to the given *htmlElement.* Into the options object, you can pass: - *height*: the height in pixels the SVG diagram will occupy vertically in the page. - *viewportWidth*: the width in pixels of the SVG viewport (default 1280). - *viewportHeight*: the height in pixels of the SVG viewport (default 720). The SVG element will horizontally fill the parent widget. This method returns the [SVG Draw](https://svgjs.dev/docs/3.2/) object instance, which you can use to create SVG elements. | | --- | --- | | *enableDrag(element, enabled)* | Enables or disables dragging on an SVG element. See `SvgDiagram.makeDraggable()` method*.* | | *foreignObject(id, x, y, w, h, html)* | Embeds an HTML element into an SVG element as a foreign object. Parameters: - *id*: the ID of the foreign object being created. - *x,y,w,h*: the coordinates and size of the foreign object. - *html*: the string representing the HTML element to append. When the HTML element is attached, you can manipulate it by using standard HTML functions or jQuery functions. | | *getById(id)* | Retrieves an SVG object by ID. If missing, null is returned. | | *getSvgResources()* | Returns the list of additional resources (SVG.js) to be loaded by the page when the widget is displayed for the very first time. You can use this array of URLs as input to the following method `AbstractWidget.loadResources(resources) ` | | *makeDraggable(element, onDragged)* | Add the draggable feature to an SVG element. When dragging terminates, the *onDragged* callback is invoked, passing the new X and Y coordinates. |