Published
Edited
Aug 29, 2021
71 forks
Importers
78 stars
Insert cell
Insert cell
Insert cell
Insert cell
data = FileAttachment("palmer-penguins.csv").csv({typed: true})
Insert cell
Insert cell
Insert cell
Insert cell
Inputs.table(data)
Insert cell
Insert cell
Insert cell
Plot // Plot is available in Observable by default
Insert cell
Insert cell
Insert cell
Insert cell
// change the code to replace … by the field’s name, e.g. body_mass
Plot.dot(data, {x: "...", fill: "black", fillOpacity: 0.2}).plot()
Insert cell
Insert cell
Insert cell
// change the code to replace … by the field’s name, e.g. body_mass
Plot.dot(data, {x: "…", y: "…"}).plot()
Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
// type your question here


Insert cell
// type your code here


Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function answer({
title,
questions = [],
guides = [],
hints = [],
solutions = [],
open = !!showAll
}) {

const div = d3.create("div").classed("answer", true);

if (title) {
div.append("hr");
div.append("h2").html(title);
}

div.call(renderGroup, questions, "question", true, d => md`${d}`);
// div.call(renderGroup, guides, "guide", open, d => md`${d}`);
div.call(renderGuide, guides, "guide", open, d => md`${d}`);
div.call(renderGroup, hints, "hint", open, d => code(d, "hint"));
div.call(renderGroup, solutions, "solution", open, d => code(d, "solution", renderSnippet));

return div.node();
}
Insert cell
function Q(q) {
return Object.assign(answer({
...q,
guides: null,
hints: null,
solutions: null
}), {value: q})
}
Insert cell
function A(q) {
return answer({
...q,
title: null,
questions: null
})
}
Insert cell
function renderGroup(div, group, type, open, render) {
if (group?.length) {
const details = div.append(type==="question" ? "div" : "details");
if (open) details.attr("open", "open")
if (type !== "question") details.append("summary").append("strong").text(`${type}${group.length > 1 ? "s" : ""}`);
details.append("ul").selectAll().data(group).join("li").append(render);
}
}
Insert cell
function renderGuide(div, group, type, open, render) {
if (group?.length) {
const details = div.append("div");
if (open) details.attr("open", "open")
// details.append("span").append("strong").text(`${type}${group.length > 1 ? "s" : ""}`);
details.append("ul").selectAll().data(group).join("li").append(render);
}
}
Insert cell
function renderSnippet(str) {
try {
const func = new Function("data", "Plot", "d3", "width", `return ${str}`)
return func(data, Plot, d3, width);
}
catch(e) {}
}
Insert cell
function code(code, type, visual) {
return html`
<div class="copy">${Copier("Copy", {value: code})}</div>
<textarea class=${type} rows=${rows(code)}>${code}</textarea>
${visual ? visual(code) : ""}`;

}
Insert cell
function rows(code) {
const lines = code.trim().split("\n").length;
return Math.max(Math.min(lines, 15), 2);
}
Insert cell
styles = html`<style>
.answer {
font-family: system-ui, sans-serif;
font-size: 14px;
}
.answer summary strong {
text-transform: capitalize;
}
.answer li {
list-style: none;
position: relative;
}
.answer textarea {
font: var(--monospace-font);
font-size: 12px;
width: 100%;
padding: 5px;
border: 2px solid #3b5fc0;
background: #F6F9FF;
border-radius: 5px;
margin-bottom: 2em;
resize: none;
}
.answer .copy form {
position: absolute;
right: -4px;
top: 4px;
width: initial;
}
.answer summary {
display: inline-block;
padding: 2px 6px;
border: 2px solid #3b5fc0;
background: #F6F9FF;
border-radius: 5px;
margin: 2px 0;
outline-offset: -2px;
list-style: none;
cursor: pointer;
min-width: 62px;
text-align: center;
}

.answer details[open] > summary {
background: #3b5fc0;
color: white;
}

`
Insert cell
html = htl.html
Insert cell
import {Copier} from "@mbostock/pbcopy"
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