Notebooks 2.0 is here.

Public
Edited
Oct 26, 2022
2 stars
Insert cell
Insert cell
toc()
Insert cell
Insert cell
Insert cell
import { newDomTemplate, values, listen } from "@kotelnikov/reactive-templates"
Insert cell
Insert cell
rhtml = newDomTemplate(htl.html)
Insert cell
Insert cell
async function* timer(timeout = 1000, transform = (v) => v) {
try {
for (let counter = 0; true; counter++) {
yield transform(counter);
await new Promise((r) => setTimeout(r, timeout));
}
} finally {
console.log("TIMER STOPPED");
}
}
Insert cell
Insert cell
// Use generated values in templates:
rhtml`<p>Counter: <strong style=${{ color: "red" }}>${[
timer(10 * 1000),
" : ",
timer(1 * 1000)
]}</strong>!</p>`
Insert cell
Insert cell
rhtml`<p>GMT Time: ${timer(
1000,
(value) => formatCurrentTime() + " (" + value + ")"
)}</p>`
Insert cell
function formatCurrentTime() {
return new Date().toISOString().replace(/^.*T(\d\d:\d\d:\d\d).*$/, "$1")
}
Insert cell
Insert cell
Insert cell
{
const age = Inputs.range([0, 100], { label: "Age: ", step: 1, value: 42 });
const formatAge = (v) =>
v < 10
? "a baby"
: v < 20
? "a teen"
: v < 30
? "young"
: v < 60
? "in your best age"
: "a youngster again";
const name = Inputs.text({ label: "Name: ", value: "John Smith" });
return rhtml`<div style=${{
padding: "0.5em",
border: "1px solid #eee",
borderRadius: "0.5em",
maxWidth: "30em"
}}>
<div><strong>${values(name, (value) => value || "Anonymous")}</strong></div>
<p>Age: ${values(age)}yo. <em>You are ${values(age, formatAge)}!</em></p>
${name}
${age}
<p><em>Thank you for watching!</em></p>
</div>`;
}
Insert cell
Insert cell
{
const div = rhtml`<div style=${{
height: "300px",
width: "300px",
background: "#eee",
padding: "0.5em",
border: "1px solid gray",
borderRadius: "0.25em"
}}>
<p>Mouse Position ${listen(
() => div,
"pointermove",
(elm, ev) => {
const [offsetX, offsetY] = ev ? [ev.offsetX, ev.offsetY] : [0, 0];
return htl.html`<span style=${{
color: "blue"
}}>${Math.round(offsetX)} : ${Math.round(offsetY)}</span>`;
}
)}!</p>
</div>`;
return div;
}
Insert cell
Insert cell
rmd = newDomTemplate(md)
Insert cell
{
const currentTime = timer(1000, formatCurrentTime);
const slider = Inputs.range([0, 10], { step: 1 });
const formatSatisfaction = (v) => {
return v < 3 ? ":-(" : v < 5 ? ":-|" : v < 7 ? ":-)" : ":-*";
// return [v < 3 ? ":-(" : v < 5 ? ":-|" : v < 7 ? ":-)" : ":-*", " ", v];
};
const comment = Inputs.textarea({
rows: 10,
minlength: 40,
value: `**Useful Resources:**
- [ObservableHQ](https://www.observablehq.com)
- [d3](https://d3js.org/)
- [d3 Examples Gallery](https://observablehq.com/@d3/gallery)
`
});

return rmd`
This markdown cell shows how static markdown can be combined with dynamic values without cells reloading.

Current GMT Time: ${currentTime}

| Your satisfaction level is **${values(
slider,
formatSatisfaction
)}** (${values(slider)} from 10)
|-------------
| ${slider} | <big>${values(slider, formatSatisfaction)}</big>

|Please leave a comment: | Raw content of your comment:
|------------------------|-------------
| ${comment} | <pre style="max-height: 150px; overflow: auto; font-size: 0.5em;">${values(
comment
)}</pre>


|Your Formatted Comment Preview:
|-------------------------------------
| ${values(comment, (v) => md([v]))}

*Thank you for watching!*

---
`;
}
Insert cell
Insert cell
Insert cell
function* fromSignal(s, transform = (v) => v) {
yield* Generators.observe((notify) =>
SignalsCore.effect(() => notify(transform(s.value)))
);
}
Insert cell
Insert cell
counter = SignalsCore.signal(1)
Insert cell
Insert cell
{
let stop = false;
invalidation.then(() => (stop = true));
while (!stop) {
counter.value++;
await Promises.delay(1000);
}
}
Insert cell
Insert cell
fromSignal(counter)
Insert cell
Insert cell
rhtml`<ul>
<li>Signal value: <em>${fromSignal(counter)}</em></li>
<li>Timestamp: <em>${fromSignal(counter, () =>
Date.now()
)}</em> (transformed signal value)</li>
</ul>`
Insert cell
Insert cell
rmd`
* Signal Value: *${fromSignal(counter)}*
* Timestamp: *${fromSignal(counter, () =>
Date.now()
)}* (transformed signal value)
`
Insert cell
Insert cell
SignalsCore = import("@preact/signals-core")
Insert cell
import { toc } from "@nebrius/indented-toc"
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