svg

Library for generating SVG programmatically and consistently within Jupyter Lab.

Screenshot of multiple rectangles expanding

Note that there are a few libraries that provide great SVG programmatic support:

Unfortunately, most of them require a DOM, and must be run client side - meaning that the results are lost on export.

The utility here is a wrapper for SVG.js, so SVGs can be rendered either Server-Side (within the Notebook) or Client Side (within the browser rendering the notebook - but lost on export)

(NOTE: embed is executed client side simply through ijs.htmlScript)

Screenshot of dark animation Screenshot of light animation

Note on Transforms

If you need to combine multiple transforms, we would recommend you use matrices instead, like the following:

utils.svg.render({ width: 400, height: 200,
    onReady: ({el, width, height, SVG }) => {
        const yellowTransition = new SVG.Color('#FF0000').to('#00FF00');
        for (let i = 0; i <=5; i++){
            el.rect(100, 100)
                .fill(yellowTransition.at(i * 0.2).toHex())
                .transform(
                    new SVG.Matrix()
                        .translate(i * 20, 0)
                        .rotate(45)
                        .translate(100, 0)
                );
        }
    }
})

Screenshot of multiple transforms

Alternatives

Since many of the libraries require a window or document instance, you can always do something similar to the following:

  • create a new jsdom window and document
  • store the window and document to the global or globalThis scope
  • create an instance of an svg element
  • THEN import the libraries (now window and document are available)
  • ... manipulate the svg with the library
  • FINALLY - capture the svg.outerHTML, and render to $$.svg() / mimetype

The goal with this library is to provide a simple alternative for common scenarios

P5

Note that other great SVG Libraries are always available:

The simplest is to run them with ijs.htmlScript and run in the browser, and pull requests are always welcome.

Here is an example running P5.js, without even using the svg module:

See here for more on instance mode

utils.ijs.htmlScript({
    scripts: [
        'https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.js'
    ],
    debug: true,
    onReady: ({rootEl}) => {
        const p5_Setup = (p) => {
            let x = 100;
            let y = 100;
            
            p.setup = function() {
                p.createCanvas(700, 410);
            }
            
            p.draw = function() {
                p.background(0);
                p.fill(255);
                p.rect(x,y,50,50);
            }
        };
        const myP5 = new p5(p5_Setup, rootEl);
    }
})

Screenshot with p5

Members

(static) utilityFunctions

Self-Contained functions - suitable to run client side when running svg.embed

Methods

(static) embed(options)

Renders an SVG through a browser side instance of SVG.js

This is a very nice library that generates, modifies and simplifies some aspects of creating your own SVGs.

Note: server side rendering is meant to be interchangable with the embed version, however there are some differences

Simple Example

//-- same instance as the svg.render example
utils.svg.render(({el, SVG, width, height}) => {
    const colorTransition = new SVG.Color('#FF00FF').to('#0FF');

    // draw a rectangle
    const firstRect = el.rect(100, 100)
        .fill('#0FF')
        .center(300, 100);
    
    // clone the rectangle, color it with the color range, and move it relative
    const secondRect = firstRect.clone()
        .fill(colorTransition.at(0))
        .dx(-200)
        .addTo(el);
    
    firstRect.clone()
        .fill(colorTransition.at(0.5))
        .dx(-100)
        .addTo(el);
});

Screenshot of the embed example

Animation Example

utils.svg.embed(({ el, SVG, width, height }) => {
    var rect1 = el.rect(100, 100)
        .move(width/2, 0);

    rect1.animate(1000, 0, 'absolute')
        .move(width/2, 100)
        .loop(true, true);
})

Screenshot of animation with SVG.js

With many other complex animations possible

Screenshot of dark animation

Parameters:
Name Type Description
options Object

options to use for drawing - or an onReady function

Properties
Name Type Description
onReady function

the function to call to generate the SVG

Properties
Name Type Description
el Element

the SVG.js primed element to use for drawing

data Object

the data object passed - now in javascript

SVG any

the SVG.js library instance

width Number

the options.width value passed, for positioning

height Number

the options.height value passed, for positioning

utilityFunctions Object

the options.utilityFunctions object

options Object

the options object passed

animate Object

alias to requestAnimationFrame with additional checks to avoid leaks

debug boolean

default: false - whether to print the svg result text

width Number

default: 400 - the width of the svg to generate

height Number

default 200 - ... height

utilityFunctions Object

optional object for self contained functions that can be used in onReady

(static) render(options)

Renders an SVG through a server side instance of SVG.js

This is a very nice library that generates, modifies and simplifies some aspects of creating your own SVGs.

Note: server side rendering is meant to be interchangable with the embed version, however there are some differences

Simple Example

utils.svg.render(({el, SVG, width, height}) => {
    const colorTransition = new SVG.Color('#FF00FF').to('#0FF');

    // draw a rectangle
    const firstRect = el.rect(100, 100)
        .fill('#0FF')
        .center(300, 100);
    
    // clone the rectangle, color it with the color range, and move it relative
    const secondRect = firstRect.clone()
        .fill(colorTransition.at(0))
        .dx(-200)
        .addTo(el);
    
    firstRect.clone()
        .fill(colorTransition.at(0.5))
        .dx(-100)
        .addTo(el);
});

Screenshot of three boxes

More Complex Example

//-- use loops and logic to create shapes
utils.svg.render({
    width: 400, height: 400, debug: false,
    onReady: ({ el, SVG, width, height }) => {
        const transition = new SVG.Color('#0d4fa6').to('#ffff00');
        const colorTransition = (val) => transition.at(val).toHex();
                
        const centerBox = el.rect(10, 10)
            .center(width / 2, height / 2)
            .fill(colorTransition(0));
        let currentBox = centerBox;
        let beforeBox = centerBox;
        
        const numSteps = 20;
        for (let i = 0; i < numSteps; i++) {
            beforeBox = currentBox;
            currentBox = beforeBox.clone()
                .insertBefore(beforeBox)
                .fill({ color: colorTransition((1/numSteps) * i) })
                .scale(1.2)
                .rotate(16)
        }
    }
})

Screenshot of multiple rectangles expanding

Parameters:
Name Type Description
options Object

options to use for drawing - or an onReady function

Properties
Name Type Attributes Default Description
onReady function

the function to call to generate the SVG

Properties
Name Type Description
el Element

the SVG.js primed element to use for drawing

SVG any

the SVG.js library instance

width Number

the options.width value passed, for positioning

height Number

the options.height value passed, for positioning

utilityFunctions Object

the options.utilityFunctions object

options Object

the options object passed

default boolean <optional>
false

whether to print the svg result text

width Number <optional>
400

the width of the svg to generate

height Number <optional>
200

... height

utilityFunctions Object <optional>
{}

an object for self contained functions that can be used in onReady