Published
Edited
Nov 23, 2020
3 stars
Insert cell
Insert cell
Insert cell
function render(row = false) {
return function(data) {
return html`<div class="table" style="
flex-direction: ${row ? "row" : "column"};
/* font-size: 0.9em; */
">
${type(data, render(!row))}
</div>`;
};
}
Insert cell
function type(data, recur) {
if (data === null || data === undefined) {
return "";
} else if (data instanceof HTMLElement || data instanceof SVGElement) {
return data;
} else if (
Array.isArray(data) &&
!Array.isArray(data[0]) &&
!(data[0] instanceof HTMLElement || data[0] instanceof SVGElement) &&
typeof data[0] === "object"
) {
const keys = Object.keys(data[0]);
return [
keys.map(k => html`<b>${k}</b>`),
...data.map(d => keys.map(k => d[k]))
].map(recur);
} else if (Array.isArray(data)) {
return data.map(recur);
} else if (data instanceof Map) {
return Array.from(data).map(([key, value]) =>
recur([html`<b>${key}</b>`, value])
);
} else if (data instanceof Set) {
return Array.from(data).map(recur);
} else if (typeof data === "object") {
return Object.entries(data).map(([key, value]) =>
recur([html`<b>${key}</b>`, value])
);
} else if (typeof data === "number") {
return html`<div style="text-align: right;">${data.toFixed(2)}</div>`;
} else {
return data;
}
}
Insert cell
html`<style>
.table {
display: flex;
justify-content: space-between;
align-items: stretch;
border: 1px solid #eee;
padding: 1px;
font-size: 0.7rem;
font-family: sans-serif;
}
.table * {
flex: 1 0 0;
}
</style>`
Insert cell
Insert cell
render()([1, 2, 3])
Insert cell
render(true)([1, 2, 3])
Insert cell
render()([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
Insert cell
render(true)([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
Insert cell
render(true)([
[1, 2, 3],
[1, 2, 3, 4],
[1, 2, 3, 4, 5],
[
["alpha", "bravo"],
["charlie", "delta"],
["echo", "foxtrot"],
["golf", "hotel"]
]
])
Insert cell
render()([
{ first: "Toph", last: "Tucker", age: 30 },
{ first: "Willy", last: "Tucker", age: 28 },
{ first: "Toby", last: "Tucker", age: 12 },
{ first: "Grace", last: "Tucker", age: 6 }
])
Insert cell
render()({
name: "Toph",
numbers: new Set([1, 2, 3, 4, 5, 6, 7, 8, 9]),
props: new Map([["alive", true], ["height", `6'2"`], ["eyes", "blue"]]),
circle: svg`<svg width="10" height="10"><circle cx="5" cy="5" r="5" fill="black"/></svg>`
})
Insert cell
render()(await FileAttachment("flare-2.json").json())
Insert cell
render()(getRandomNested(5, 3, Math.random))
Insert cell
render()(
getRandomNested(4, 4, () =>
Math.random() > .5 ? Math.random() : Math.random() > .5 ? [1, 2, 3] : "Toph"
)
)
Insert cell
render()(
getRandomNested(4, 4, () =>
Math.random() > .5
? svg`<svg width="10" height="10"><circle r="5" cx="5" cy="5" fill="${"#" +
(((1 << 24) * Math.random()) | 0).toString(16)}"/></svg>`
: Math.random() > .5
? Array(Math.ceil(Math.random() * 4))
.fill(true)
.map(
() =>
svg`<svg width="20" height="20"><rect width="20" height="20" fill="${"#" +
(((1 << 24) * Math.random()) | 0).toString(16)}"/></svg>`
)
: svg`<svg width="20" height="20"><circle r="10" cx="10" cy="10" fill="${"#" +
(((1 << 24) * Math.random()) | 0).toString(16)}"/></svg>`
)
)
Insert cell
function getRandomNested(n, levels, fn) {
return Array(n)
.fill(true)
.map(levels ? () => getRandomNested(n, levels - 1, fn) : fn);
}
Insert cell
import {president} from "@tophtucker/election-2020-data"
Insert cell
render()(president.data.races[0])
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