TypeScript icon, indicating that this package has built-in type declarations

    3.7.26 • Public • Published


    npm version npm downloads Twitter Follow

    This project is part of the @thi.ng/umbrella monorepo.


    SVG element functions for @thi.ng/hiccup & @thi.ng/hdom.


    The functions provided here do produce valid hiccup elements, but since none of them make use of (or support) the global hiccup / hdom context object, they can ONLY be invoked directly, i.e. they MUST be called like:

    // correct (direct invocation)
    svg.svg({}, svg.circle([0, 0], 100, { fill: "red" }));
    // incorrect / unsupported (lazy evaluation)
    [svg.svg, {}, [svg.circle, [0, 0], 100, { fill: "red" }]]

    SVG conversion of @thi.ng/geom & @thi.ng/hdom-canvas shape trees

    Since v2.0.0 this package provides a conversion utility to translate the more compact syntax used by @thi.ng/geom and @thi.ng/hdom-canvas shape trees (designed for more performant realtime / canvas drawing) into a SVG serializable hiccup format.

    The convertTree() function takes a pre-normalized hiccup tree of hdom-canvas shape definitions and recursively converts it into an hiccup flavor which is ready for SVG serialization (i.e. using stringified geometry attribs). This conversion also involves translation & re-organization of various attributes, as described below. This function returns a new tree. The original remains untouched, as will any unrecognized tree / shape nodes (those will be transferred as-is to the result tree). See example below.

    Since v3.7.0 tree conversion can be implicitly triggered by providing a convert: true attribute to the root svg() element.

    // create SVG root element and convert body
        { width: 100, height: 100, convert: true},
        ["rect", { fill: [1, 0, 0] }, [0,0], 100, 100]
    // [
    //   'svg',
    //   {
    //     version: '1.1',
    //     xmlns: 'http://www.w3.org/2000/svg',
    //     'xmlns:xlink': 'http://www.w3.org/1999/xlink',
    //     width: 100,
    //     height: 100
    //   },
    //   [ 'rect', { fill: '#ff0000', x: 0, y: 0, width: 100, height: 100 } ]
    // ]

    Automatic attribute conversions


    Since v3.1.0:

    Color conversions are only applied to fill and stroke attributes and color stops provided to linearGradient(), radialGradient()


    String color attribs prefixed with $ are replaced with url(#...) refs (e.g. to refer to gradients), else used as is (untransformed)


    Interpreted as ARGB hex value:

    { fill: 0xffaabbcc } => { fill: "#aabbcc" }


    Interpreted as float RGB(A):

    { fill: [1, 0.8, 0.6, 0.4] } => { fill: "rgba(255,204,153,0.40)" }

    @thi.ng/color values

    Converted to CSS color strings:

    { fill: hcya(0.1666, 1, 0.8859) } => { fill: "#ffff00" }


    (i.e. transform, rotate, scale, translate)

    If an element has a transform attrib, conversion of the other transformation attribs will be skipped, else the values are assumed to be either strings or:

    • transform: 6-element numeric array (2x3 matrix in column major order)
    • translate: 2-element array
    • rotate: number (angle in radians)
    • scale: number (uniform scale) or 2-elem array

    If no transform, but others are given, the resulting transformation order will always be TRS. Any string values will be used as-is and therefore need to be complete, e.g. { rotate: "rotate(60)" }


    STABLE - used in production

    Search or submit any issues for this package


    yarn add @thi.ng/hiccup-svg
    // ES module
    <script type="module" src="https://unpkg.com/@thi.ng/hiccup-svg?module" crossorigin></script>
    // UMD
    <script src="https://unpkg.com/@thi.ng/hiccup-svg/lib/index.umd.js" crossorigin></script>

    Package sizes (gzipped, pre-treeshake): ESM: 2.51 KB / CJS: 2.62 KB / UMD: 2.55 KB


    Usage examples

    Several demos in this repo's /examples directory are using this package.

    A selection:

    Screenshot Description Live demo Source
    Probabilistic color theme generator Demo Source
    Heatmap visualization of this mono-repo's commits Source
    Basic crypto-currency candle chart with multiple moving averages plots Demo Source
    Color palette generation via dominant color extraction from uploaded images Demo Source
    Various hdom-canvas shape drawing examples & SVG conversion / export Demo Source
    CLI util to visualize umbrella pkg stats Source
    Generate SVG using pointfree DSL Source
    Polygon to cubic curve conversion & visualization Demo Source
    Interactive grid generator, SVG generation & export, undo/redo support Demo Source
    Additive waveform synthesis & SVG visualization with undo/redo Demo Source


    Generated API docs

    import * as svg from "@thi.ng/hiccup-svg";
    import { serialize } from "@thi.ng/hiccup";
    import * as fs from "fs";
                {width: 100, height: 100},
                svg.defs(svg.linearGradient("grad", [0, 0], [0, 1], [[0, "red"], [1, "blue"]])),
                svg.circle([50, 50], 50, { fill: "url(#grad)" }),
                svg.text([50, 55], "Hello", { fill: "white", "text-anchor": "middle" })

    Minimal example showing SVG conversion of a hdom-canvas scene:

    // scene tree defined for hdom-canvas
    const scene = [
        ["defs", {},
                { id: "bg", from: [150, 280], to: [150, 300], r1: 300, r2: 100 },
                [[0, "#07f"], [0.5, "#0ef"], [0.8, "#efe"], [1, "#af0"]]],
                { id: "sun", from: [110, 120], to: [110, 120], r1: 5, r2: 50 },
                [[0, "#fff"], [1, "rgba(255,255,192,0)"]]]
        ["circle", { fill: "$bg" }, [150, 150], 130],
        ["circle", { fill: "$sun" }, [110, 120], 50],
            svg.svg({ width: 300, height: 300 }, svg.convertTree(scene))


    <svg version="1.1"
        xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300">
            <radialGradient id="bg" fx="150.00" fy="280.00" cx="150.00" cy="300.00" fr="300.00" r="100.00" gradientUnits="userSpaceOnUse">
                <stop offset="0" stop-color="#07f"/>
                <stop offset="0.5" stop-color="#0ef"/>
                <stop offset="0.8" stop-color="#efe"/>
                <stop offset="1" stop-color="#af0"/>
            <radialGradient id="sun" fx="110.00" fy="120.00" cx="110.00" cy="120.00" fr="5.00" r="50.00" gradientUnits="userSpaceOnUse">
                <stop offset="0" stop-color="#fff"/>
                <stop offset="1" stop-color="rgb(255,255,192)" stop-opacity="0"/>
        <circle cx="150.00" cy="150.00" r="130.00" fill="url(#bg)"/>
        <circle cx="110.00" cy="120.00" r="50.00" fill="url(#sun)"/>


    Karsten Schmidt

    If this project contributes to an academic publication, please cite it as:

      title = "@thi.ng/hiccup-svg",
      author = "Karsten Schmidt",
      note = "https://thi.ng/hiccup-svg",
      year = 2016


    © 2016 - 2021 Karsten Schmidt // Apache Software License 2.0


    npm i @thi.ng/hiccup-svg

    DownloadsWeekly Downloads






    Unpacked Size

    116 kB

    Total Files


    Last publish


    • avatar