Public
Edited
Nov 11, 2022
Importers
Insert cell
Insert cell
dallE20221112114332ANetworkOfNodesConnectedByArrow = FileAttachment("DALL·E 2022-11-12 11.43.32 - a network of nodes connected by arrows forming a directed acyclic graph in 3d, looking as if viewed from a microscope in grainy monochrome. The arrow.png").image()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// TODO: Should rename to cell
define = (text, processor = undefined) => {
const expr = /^(?<name>\w+)?(:((?<single>\w+(,\w+)*)|\[(?<list>\w+(,\w+)*)\]|\{(?<map>\w+(,\w+)*)\})?)?$/;
const match = expr.exec(text);
if (match && match.groups) {
const { name, single, list, map } = match.groups;
return {
name,
processor,
input: single
? single.split(",")
: list
? [list.split(",")]
: map
? [
map.split(",").reduce((r, v) => {
r[v] = v;
return r;
}, {})
]
: []
};
} else {
return null;
}
}
Insert cell
define("myCell:other,someOther")
Insert cell
Insert cell
class Cells {
constructor(definition, state = null) {
this.network =
definition instanceof Network ? definition : network(definition);
this.cycles = {};
this.defaults = this.network.defaults;
this.state = Object.assign({}, this.defaults, state);
}
init(overrides = undefined) {
const initial = overrides
? Object.assign({}, this.defaults, overrides)
: this.state;
return this.update(initial);
}
update(update = this.state) {
this.state = apply(this.network, update, this.state);
return this.state;
}
}
Insert cell
Insert cell
new Cells({ a: 10, b: 20, "c:a,b": (a, b) => a + b }).state
Insert cell
Insert cell
Insert cell
Insert cell
evaluate(
define(":a,b", (a, b) => a + b),
{ a: 10, b: 1 }
)
Insert cell
extract = (input, state) => map(input, (_) =>
typeof _ === "string" ? state[_] : map(_, (_) => state[_])
);
Insert cell
extract(["counter"], { counter: 0 })
Insert cell
evaluate = ({ input, processor }, state) => {
if (processor === undefined || typeof processor === "function") {
const args = extract(input, state);
return processor ? processor(...args) : args;
} else {
return processor;
}
}
Insert cell
Insert cell
Insert cell
network({
a: 10,
b: 20,
"c:[a,b]": ([a, b]) => a + b
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
predecessors({ a: ["b", "c"], x: ["a"] })
Insert cell
Insert cell
Insert cell
Insert cell
ranks({ a: [], b: [], c: ["a", "b"], d: ["c"] })
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
descendants("a", { a: ["b"], b: ["c"], c: [] })
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
strand(network(["a", "b", "c", "d:[a,b]", "e:[a,d]", "f:c"]), { a: 0, c: 10 })
Insert cell
Insert cell
Insert cell
Insert cell
apply(network({ a: 0, b: 0, "c:a,b": (a, b) => a + b }), { a: 10, b: 10 })
Insert cell
apply = (network, update, state = {}, continuation = undefined) => {
const impacted = strand(network, update);
state = Object.assign(state, update);
let i = 0;
while ((i = step(network, state, impacted, i)) !== false) {}
return state;
}
Insert cell
step = (network, state, strand, position = 0) => {
if (position >= strand.length) {
return false;
}
const name = strand[position];
const value = evaluate(network.cells[name], state);
if (value instanceof Promise) {
// TODO: Async operation
return false;
} else {
state[name] = value;
return position < strand.length - 1 ? position + 1 : false;
}
}
Insert cell
Insert cell
class Continuation {
constructor(network, state, strand, position){
this.network = network;
this.state = state;
this.strand = strand;
this.position = position;
}
step() {
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
update = (network, delta, cycles = {}) => {
// We get the keys sorted by rank. This is the order in which we can/should apply the updates.
// Note that the update may be from a cell that had its value provided.
const k = sorted(keys(delta), (_) => ranks[_]);
const res = [];
each(k, (cell) => {
const cycle = (cycles[cell] =
cycles[cell] === undefined ? 0 : cycles[cell] + 1);
res.push({ cell, value: delta[cell], cycle });
});
return res;
}
Insert cell
Insert cell
A = cells({
"label:counter": (counter) => `Counted ${counter || 0} times`,
counter: 0
})
Insert cell
A.defaults
Insert cell
A.init()
Insert cell
A.update({ counter: 1 })
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {
len,
map,
reduce,
filter,
bool,
values,
each,
append,
sorted,
keys,
idem
} from "@sebastien/boilerplate"
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more