Notebooks 2.0 is here.
Read the preview announcement
Platform
Resources
Pricing
Sign in
Get started
Mikhail Kotelnikov
Workspace
Fork
Public
By
Mikhail Kotelnikov
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.
Try it for free
Learn more
Fork
View
Export
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
rhtml
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
timer
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
formatCurrentTime
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
rmd
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
fromSignal
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
counter
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
SignalsCore
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML