Skip to content

How to load as ESM directly from the browser?

Jae Sung Park edited this page Mar 21, 2023 · 7 revisions

The ESM distribution's dependencies imports are pointed as "module-name".
billboard.js provides ESM distribution file (can be found at dist-esm folder) and all the necessary dependencies imports are defined at the top as:

import { timeParse, utcParse, timeFormat, utcFormat } from 'd3-time-format';
import { pointer, select, namespaces, selectAll } from 'd3-selection';
...

So, to execute it needs load those imports first. To be imported directly to the browser (w/o transpilation), the "module-name" location should be relative or some origin where browser could identify.

Option 1: Directly from online without installing any packages locally

In this case, import maps can be used.

<!-- specify importmaps to mapping dependencies modules and its location --->
<script type="importmap"> 
    {
      "imports": {
        "d3-time-format": "https://cdn.skypack.dev/d3-time-format",
        "d3-selection": "https://cdn.skypack.dev/d3-selection",
        "d3-brush": "https://cdn.skypack.dev/d3-brush",
        "d3-dsv": "https://cdn.skypack.dev/d3-dsv",
        "d3-drag": "https://cdn.skypack.dev/d3-drag",
        "d3-scale": "https://cdn.skypack.dev/d3-scale",
        "d3-transition": "https://cdn.skypack.dev/d3-transition",
        "d3-axis": "https://cdn.skypack.dev/d3-axis",
        "d3-ease": "https://cdn.skypack.dev/d3-ease",
        "d3-hierarchy": "https://cdn.skypack.dev/d3-hierarchy",
        "d3-interpolate": "https://cdn.skypack.dev/d3-interpolate",
        "d3-shape": "https://cdn.skypack.dev/d3-shape",
        "d3-zoom": "https://cdn.skypack.dev/d3-zoom"
      }
    }
</script>
<script type="module">
import bb, {area, line} from "https://unpkg.com/billboard.js/dist-esm/billboard.js";

bb.generate( ... );
</script>

Working online demo:

Option 2: From local installation

Step 1

## don't need to install other packages
$ npm i billboard.js

Step 2

Create a HTML file and specify import maps of all necessary modules.

Project's structure will be similar as follows.

/ (project's root)
├── node_modules/
│   ├── billboard.js/
│   ├── ...
│   └── ...
└── chart.html
<script type="importmap"> 
  {
    "imports": {
        "d3-array": "./node_modules/d3-array/src/index.js",
        "d3-axis": "./node_modules/d3-axis/src/index.js",
        "d3-brush": "./node_modules/d3-brush/src/index.js",
        "d3-color": "./node_modules/d3-color/src/index.js",
        "d3-dispatch": "./node_modules/d3-dispatch/src/index.js",
        "d3-drag": "./node_modules/d3-drag/src/index.js",
        "d3-dsv": "./node_modules/d3-dsv/src/index.js",
        "d3-ease": "./node_modules/d3-ease/src/index.js",
        "d3-format": "./node_modules/d3-format/src/index.js",
        "d3-hierarchy": "./node_modules/d3-hierarchy/src/index.js",
        "d3-interpolate": "./node_modules/d3-interpolate/src/index.js",
        "d3-path": "./node_modules/d3-path/src/index.js",
        "d3-scale": "./node_modules/d3-scale/src/index.js",
        "d3-selection": "./node_modules/d3-selection/src/index.js",
        "d3-shape": "./node_modules/d3-shape/src/index.js",
        "d3-time": "./node_modules/d3-time/src/index.js",
        "d3-time-format": "./node_modules/d3-time-format/src/index.js",
        "d3-timer": "./node_modules/d3-timer/src/index.js",
        "d3-transition": "./node_modules/d3-transition/src/index.js",
        "d3-zoom": "./node_modules/d3-zoom/src/index.js",
        "internmap": "./node_modules/internmap/src/index.js",
        "billboard.js": "./node_modules/billboard.js/dist-esm/billboard.js"
    }
  }
</script>

Step 3

Place generation code

<script type="module">
import bb, {area, line} from "billboard.js";

bb.generate({
    data: {
        columns: [
            ["data1", 300, 350, 300, 0, 0, 0],
            ["data2", 130, 100, 140, 200, 150, 50]
        ],
        types: {
            data1: area(),
            data2: line()
        }
    }
});
</script>

Tested on latest chrome and worked without issue.

For convenience, here's the whole HTML code.

<!doctype html>
<html>
<head>
<title>billboard.js</title>
<link rel="stylesheet" href="./node_modules/billboard.js/dist/billboard.css">
<body>
<div id="chart"></div>
<script type="importmap"> 
  {
    "imports": {
        "d3-array": "./node_modules/d3-array/src/index.js",
        "d3-axis": "./node_modules/d3-axis/src/index.js",
        "d3-brush": "./node_modules/d3-brush/src/index.js",
        "d3-color": "./node_modules/d3-color/src/index.js",
        "d3-dispatch": "./node_modules/d3-dispatch/src/index.js",
        "d3-drag": "./node_modules/d3-drag/src/index.js",
        "d3-dsv": "./node_modules/d3-dsv/src/index.js",
        "d3-ease": "./node_modules/d3-ease/src/index.js",
        "d3-format": "./node_modules/d3-format/src/index.js",
        "d3-hierarchy": "./node_modules/d3-hierarchy/src/index.js",
        "d3-interpolate": "./node_modules/d3-interpolate/src/index.js",
        "d3-path": "./node_modules/d3-path/src/index.js",
        "d3-scale": "./node_modules/d3-scale/src/index.js",
        "d3-selection": "./node_modules/d3-selection/src/index.js",
        "d3-shape": "./node_modules/d3-shape/src/index.js",
        "d3-time": "./node_modules/d3-time/src/index.js",
        "d3-time-format": "./node_modules/d3-time-format/src/index.js",
        "d3-timer": "./node_modules/d3-timer/src/index.js",
        "d3-transition": "./node_modules/d3-transition/src/index.js",
        "d3-zoom": "./node_modules/d3-zoom/src/index.js",
        "internmap": "./node_modules/internmap/src/index.js",
        "billboard.js": "./node_modules/billboard.js/dist-esm/billboard.js"
    }
  }
</script>
<script type="module">
import bb, {area, line} from "billboard.js";

bb.generate({
    data: {
        columns: [
            ["data1", 300, 350, 300, 0, 0, 0],
            ["data2", 130, 100, 140, 200, 150, 50]
        ],
        types: {
            data1: area(),
            data2: line()
        }
    }
});
</script>
</body>
</html>