Public
Edited
May 22
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// grab all the bad tokens (to mark particular inputs as disabled)
editedInconsistentTokens = d3.group(editedColorPairs,)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
problemPairs.filter((d) => d.fgKey === "tertiary").view()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
isMobile = window.matchMedia("(max-width: 600px)").matches
Insert cell
function entriesToFlat(acc, [key, value], i, arr, ctx = "") {
if (typeof value === "string") acc.push({ key: `${ctx}${key}`, value });
else if (typeof value === "object") {
acc = acc.concat(
Object.entries(value).reduce(
(...args) => entriesToFlat(...args, `${ctx}${key}.`),
[]
)
);
}

return acc;
}
Insert cell
// see "@observablehq/text-color-annotations-in-markdown
function textColor(content, { theme, ...style }) {
theme = themes.get(theme);

function yiq(color) {
const { r, g, b } = d3.rgb(color);
return (r * 299 + g * 587 + b * 114) / 1000 / 255; // returns values between 0 and 1
}
const {
background = theme.get(content) ?? content,
color = yiq(background) >= 0.6 ? "#111" : "white",
padding = "0 5px",
borderRadius = "4pxf",
fontWeight = 800,
...rest
} = Object.entries(style).reduce((obj, [k, v]) => {
// if value is a valid design token, use it
obj[k] = theme.get(v) ?? v;
return obj;
}, {});
return htl.html`<span style=${{
background,
color,
padding,
borderRadius,
fontWeight,
...rest
}}>${content}</span>`;
}
Insert cell
import { textcolor } from "@observablehq/text-color-annotations-in-markdown"
Insert cell
utils = (await import("https://cdn.skypack.dev/@visa/visa-charts-utils"))
.default
Insert cell
function shuffle(array) {
let currentIndex = array.length,
randomIndex;

// While there remain elements to shuffle.
while (currentIndex != 0) {
// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;

// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex]
];
}

return array;
}
Insert cell
Insert cell
Insert cell
import { notice, toc } from "@sgregson/components"
Insert cell
import { aq, op } from "@uwdata/arquero"
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