Published
Edited
Apr 19, 2022
Importers
34 stars
Insert cell
Insert cell
Insert cell
async function importCell(
cell, // e.g., "chart"
notebook, // e.g., "@d3/bar-chart" or "8d5ef3030dfd3bad"
injections = {} // e.g., {data: [{name, value}, …]}
) {

// Instantiate a new runtime, but reuse the existing runtime’s require.
// (This is ensures that any requires in imports still work.)
const library = Object.assign(new Library(), {require: () => require});
const runtime = new Runtime(library);

// Create the main module, including any injected values.
const main = runtime.module();
for (const name in injections) {
main.define(name, [], () => injections[name]);
}

// Load the requested notebook’s definition as an ES module.
const origin = `https://api.observablehq.com`;
const {default: define} = await import(
/^@[0-9a-z_-]+\/[0-9a-z_-]+(\/\d+)?([@~]|$)/.test(notebook += "") ? `${origin}/${notebook}.js?v=3`
: /^[0-9a-f]{16}([@~]|$)/.test(notebook) ? `${origin}/d/${notebook}.js?v=3`
: notebook);

// Create the imported notebook’s module, and then derive a module
// from it to inject the desired values. (If there are none, then
// this is basically a noop.)
const imported = runtime.module(define);
const derived = imported.derive([...Object.keys(injections)], main);

// In many cases the imported cell will only have a single value, but
// we must use the most generic representation (an async generator) as
// the imported cell may be an async generator, or may reference one.
return Generators.observe((notify) => {

// Create the primary variable with an observer that will report the
// desired cell’s fulfilled or rejected values.
main.variable({
fulfilled(value) { notify(value); },
rejected(value) { notify(Promise.reject(value)); }
}).import(cell, derived);

// Lastly, when this generator is disposed, dispose the runtime to
// ensure that any imported generators terminate.
return () => runtime.dispose();
});
}
Insert cell
Insert cell
Insert cell
importCell("chart", "@d3/bar-chart@268")
Insert cell
Insert cell
importCell("chart", "@d3/bar-chart@268", {height: 200, color: "brown"})
Insert cell
Insert cell
importCell(
"chart",
"@d3/horizontal-bar-chart@254",
{
margin: {
top: 20,
right: 20,
bottom: 0,
left: 40
},
data: (await FileAttachment("us-population-by-age.csv").csv())
.map(({years, population}) => ({name: years, value: +population}))
}
)
Insert cell
Insert cell
histogram = (data, options) => importCell("chart", "@d3/histogram@261", {...options, data})
Insert cell
histogram(Array.from({length: 1000}, Math.random))
Insert cell
Insert cell
observablehq = require("@observablehq/runtime@4")
Insert cell
Runtime = observablehq.Runtime
Insert cell
Library = observablehq.Library
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more