SVG Drawing Module Reference

Table of contents


Introduction

The SVG drawing module contains the SvgScene class and the svgDraw object. Together they build an SVG document as a string for assignment to a node's innerHTML, typically from the draw callback of an svg state variable.

The API mirrors the retired 2D canvas drawing helpers, so drawing code written for a canvas converts as a near transliteration:

The rendered <svg> element is given a width and height of 100%, so the wrapper node is sized by CSS (typically a width or height plus an aspect-ratio matching the viewBox) and the drawing scales to it, staying crisp at any display resolution.

A typical draw callback:

import {svgDraw, SvgScene} from '../option/svgDraw.js';

io.wb_diagram.value = (node) => {
	const scene = new SvgScene({viewBox:[width, height]});
	scene.rect(10, 10, 50, 20, {fill:'grey'});
	scene.text(35, 40, 'label', {font:'bold 29px sans-serif', anchor:'center'});
	node.innerHTML = scene.toString();
};

Attribute objects

Most SvgScene methods take a trailing attrs object. Each property becomes an attribute on the emitted element, exactly as written (e.g., {fill:'red', 'stroke-width':2}). Numeric values are shortened with svgDraw.n(), string values are escaped, and properties with undefined or null values are skipped. Because attributes are emitted verbatim, SVG attribute names with hyphens (stroke-width, stroke-dasharray, text-anchor, ...) must be quoted.

Stroked shapes have no default stroke; pass stroke and 'stroke-width' explicitly (the canvas context state they used to inherit does not exist).


Exported identifiers

svgDraw

Syntax

import {svgDraw} from 'common/option/svgDraw.js';

The svgDraw object contains stateless helper functions used by SvgScene and by drawing code directly.

SvgScene

Syntax

import {SvgScene} from 'common/option/svgDraw.js';

The SvgScene class accumulates SVG elements and definitions and serializes them with toString().


svgDraw methods

svgDraw.arcD()

Syntax

svgDraw.arcD(cx, cy, r, a1, a2)
svgDraw.arcD(cx, cy, r, a1, a2, opts)

Return a path d fragment for a circular or elliptical arc, using canvas arc() conventions: angles are in radians, 0 is the positive X axis, and increasing angles sweep clockwise in the y-down coordinate space. An arc from a1 to a2 with a2 < a1 sweeps counterclockwise.

A circle drawn under a non-uniform scale(1, s) transform is exactly the ellipse [r, r*s] with unchanged parametric angles, so arcs drawn in a scaled canvas frame convert by passing ellipse radii instead of reproducing the transform.

Parameters

Return value

A path data string, e.g. 'M10 0A10 10 0 0 1 0 10', suitable for concatenation into a larger d string for SvgScene.path().


svgDraw.attrs()

Syntax

svgDraw.attrs(attrObj)

Build an attribute string from an object, following the attribute object rules.

Parameters

Return value

A string of name="value" pairs with a leading space, or an empty string.


svgDraw.esc()

Syntax

svgDraw.esc(str)

Escape a string for use as SVG text content or an attribute value (&, <, >, and " are replaced with entities). SvgScene.text() and attribute emission escape automatically; use this when building raw element strings for SvgScene.elt() or SvgScene.def().

Parameters

Return value

The escaped string.


svgDraw.n()

Syntax

svgDraw.n(x)

Format a number as a short string, rounded to 2 decimal places with no trailing zeros. This keeps generated SVG strings small. Non-finite numbers return '0'.

Parameters

Return value

The number as a short string.


svgDraw.textWidth()

Syntax

svgDraw.textWidth(text, fontProp)

Return the rendered width of text in pixels, measured with an offscreen <div> so the metrics come from the same engine that renders SVG text.

Parameters

Return value

The rendered width of the text in pixels.


SvgScene constructor

new SvgScene()

Syntax

new SvgScene({viewBox})
new SvgScene({viewBox, ...attrs})

Create an empty scene.

Parameters


SvgScene methods

The shape methods (line, polyline, polygon, rect, circle, ellipse, path, image) each emit one SVG element of the same name; their positional parameters map to the element's geometry attributes and the trailing attrs object supplies the rest. Only behavior beyond that is called out below.

SvgScene.annularSector()

Syntax

scene.annularSector(cx, cy, rInner, rOuter, a1, a2, attrs)

Emit a filled annular sector (the band between two concentric arcs) from angle a1 to a2. This replaces canvas tricks such as stroking an arc with a very large lineWidth. An rInner of 0 draws a simple wedge from the center.

Parameters


SvgScene.arc()

Syntax

scene.arc(cx, cy, r, a1, a2, attrs)

Emit a stroked circular or elliptical arc as a <path> with fill="none". The parameters are those of svgDraw.arcD().


SvgScene.arrow()

Syntax

scene.arrow(startX, startY, angle, length, width, attrs)

Draw an arrow from (startX, startY) at angle radians (clockwise from the positive X axis), length long, with an arrowhead width wide.

Parameters


SvgScene.circle()

Syntax

scene.circle(cx, cy, r, attrs)

Emit a <circle>.


SvgScene.def()

Syntax

scene.def(str)

Add <defs> content (patterns, clipPaths, filters, ...) as a raw string. Identical strings are only added once. Element ids inside defs must be created with uid() because the rendered scenes share the page's DOM, where ids are global.

Parameters


SvgScene.dottedLine()

Syntax

scene.dottedLine(startX, startY, endX, endY, opts)

Draw a dotted or dashed line from (startX, startY) to (endX, endY) using stroke-dasharray.

Parameters


SvgScene.ellipse()

Syntax

scene.ellipse(cx, cy, rx, ry, attrs)

Emit an <ellipse>. An axis-aligned ellipse replaces the canvas trick of building a circular path under a non-uniform scale(); note that its stroke is uniform, where the canvas stroke was distorted by the scale.


SvgScene.elt()

Syntax

scene.elt(tag, attrs)
scene.elt(tag, attrs, content)

Add one element. This is the low-level emitter the shape methods are built on.

Parameters


SvgScene.group()

Syntax

scene.group(opts, fn)

Add a <g> group, replacing canvas save()/translate()/rotate()/scale()/restore(). fn is called to draw the group's content into the scene; groups nest.

Parameters


SvgScene.image()

Syntax

scene.image(href, x, y, width, height, attrs)

Emit an <image> displaying the image at href.


SvgScene.line()

Syntax

scene.line(x1, y1, x2, y2, attrs)

Emit a <line>.


SvgScene.mask()

Syntax

scene.mask(name, fn)

Define a luminance mask and return its mask URL, for use as a group attribute:

scene.group({mask: scene.mask('clip', (scene) => {...})}, (scene) => {...});

White areas of the mask content keep the masked content and black areas erase it. This replaces canvas globalCompositeOperation 'destination-out' erasing.

Parameters

Return value

A 'url(#id)' string for use as a mask attribute.


SvgScene.path()

Syntax

scene.path(d, attrs)

Emit a <path> with path data d. svgDraw.arcD() builds arc segments for concatenation into d.


SvgScene.pattern()

Syntax

scene.pattern(name, width, height, content)

Define a fill pattern and return its fill URL. The pattern uses patternUnits="userSpaceOnUse", which anchors the tile to the referencing element's user space, matching canvas pattern behavior.

Parameters

Return value

A 'url(#id)' string for use as a fill attribute.


SvgScene.polygon()

Syntax

scene.polygon(points, attrs)

Emit a <polygon>. points is an array of 2-element [x, y] arrays.


SvgScene.polyline()

Syntax

scene.polyline(points, attrs)

Emit a <polyline> with a default of fill="none". points is an array of 2-element [x, y] arrays.


SvgScene.rect()

Syntax

scene.rect(x, y, width, height, attrs)

Emit a <rect>. Negative width/height are normalized, as with canvas fillRect().


SvgScene.text()

Syntax

scene.text(x, y, text, opts)

Draw text starting at (x, y) going right and down. A \n in text starts a new line, lineHeight apart. [c color]text[/c] in the string draws that text in the specified color using a <tspan>. Text content is escaped automatically.

Parameters


SvgScene.toString()

Syntax

scene.toString()

Serialize the scene.

Return value

The complete <svg>...</svg> document string, ready for assignment to a node's innerHTML.


SvgScene.uid()

Syntax

scene.uid(name)

Return an element id unique to this scene. Scenes are inserted into the shared document DOM, where ids are global, so definitions referenced by url(#id) must not collide between scenes.

Parameters

Return value

The id string, e.g. 'svg12_darken'.