Public
Edited
Nov 11, 2023
Insert cell
Insert cell
example_markdown = ({
prompt: "Write an example markdown cell",
time: 1699221659348,
comment: "Example of a markdown cell"
} &&
md` This is a markdown cell. You can use **bold**, _italic_, and [links](http://example.com).`)
Insert cell
hexbin_heatmap = ({
prompt:
'Create a Hexbin heatmap of Olympic athletes aaccording to their weight and height which are filled with a color that encodes frequency. Use the inbuilt dataset "olympians" variable',
time: 1699296536008,
comment:
"Create a Hexbin heatmap of Olympic athletes according to their weight and height filled with a color that encodes frequency."
} &&
Plot.dot(
olympians,
Plot.hexbin({ fill: "count" }, { x: "weight", y: "height" })
).plot({ color: { scheme: "YlGnBu" } }))
Insert cell
blob_url = ({
prompt: "convert the hexbin_heatmap SVGElement to blob URL ",
time: 1699302857881,
comment: "Convert the hexbin_heatmap SVGElement to blob URL"
} &&
URL.createObjectURL(
new Blob([new XMLSerializer().serializeToString(hexbin_heatmap)], {
type: "image/svg+xml"
})
))
Insert cell
viewof form = ({
prompt:
'use the already imported view literal to make reactive form which has\n\n2 tabs name "first", "second", which switch between two text areas called "a", "b" with placehoders "A", "B" and a single "submit" button at the bottom. Pressing submit should update the cell bound to the form. The result should be an object shaped {a:..., b:...} where the values map to the text area values.\n',
time: 1699298358615,
comment:
"Create a reactive form with two tabs 'first' and 'second' switching between two text areas 'a' and 'b' with placeholders 'A' and 'B' and a submit button. On submit, it updates the cell bound to the form. The result will be an object shaped {a:..., b:...} where the values map to the text area values."
} &&
cautious(
(apply, reset) => view`
<input type="radio" name="tab" checked onclick=${() => {
document.getElementById("firstContent").style.display = "block";
document.getElementById("secondContent").style.display = "none";
}}>
<label for="first">First</label>
<input type="radio" name="tab" onclick=${() => {
document.getElementById("firstContent").style.display = "none";
document.getElementById("secondContent").style.display = "block";
}}>
<label for="second">Second</label>
<br>
<div id="firstContent">
${["a", Inputs.textarea({ placeholder: "A" })]}
</div>
<div id="secondContent" style="display: none;">
${["b", Inputs.textarea({ placeholder: "B" })]}
</div>
<br>
<button onClick=${apply}>Submit</button>`
))
Insert cell
form
Insert cell
THREE = ({
prompt: "Import threeJS with orbit controls as THREE",
time: 1699299731104,
comment: "Importing three.js with orbit controls as three"
} &&
Promise.all([
import("https://esm.sh/three"),
import("https://esm.sh/three/examples/jsm/controls/OrbitControls.js")
]).then(([THREE, { OrbitControls }]) => ({ ...THREE, OrbitControls })))
Insert cell
demo_scene = {
({
prompt: "create a THREE cool demo scene using blob_url as a texture",
time: 1699303031445,
comment:
"Creating a 3D scene with a rotating cube using three.js. The cube is textured with the blob URL of the hexbin heatmap SVG."
});
const height = 500;
// Create a scene
const scene = new THREE.Scene();

// Create a camera
const camera = new THREE.PerspectiveCamera(15, width / height, 0.1, 1000);
camera.position.z = 5;

// Create a renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);

// Create a cube
const geometry = new THREE.BoxGeometry(1, 1, 1);
const loader = new THREE.TextureLoader();
const material = new THREE.MeshBasicMaterial({ map: loader.load(blob_url) });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// Create an animation loop
const animate = () => {
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
animate();

// Enable orbit controls
const controls = new THREE.OrbitControls(camera, renderer.domElement);

return renderer.domElement;
}
Insert cell
relativity_derivation = ({
prompt:
"Using the tex literal (KaTeX) intermingled with markdown, write a derivation of relativity.",
time: 1699388874563,
comment: "Derivation of relativity equation using KaTeX and markdown"
} &&
md`The derivation of the relativity equation starts from the principle of relativity, which states that the laws of physics are the same in all inertial frames of reference.

From this principle, we derive the Lorentz transformation, which describes how measurements of space and time by two observers moving relative to each other are related. The Lorentz transformation in one dimension is:

${tex`
\begin{aligned}
x' &= \gamma (x - vt) \\
t' &= \gamma \left(t - \frac{vx}{c^2}\right)
\end{aligned}
`}

where:

- ${tex`x'`} and ${tex`t'`} are the space and time coordinates measured by the observer moving with velocity ${tex`v`},
- ${tex`x`} and ${tex`t`} are the space and time coordinates measured by the observer at rest,
- ${tex`gamma = \frac{1}{\sqrt{1 - v^2/c^2}}`} is the Lorentz factor, and
- ${tex`c`} is the speed of light.

From the Lorentz transformation, we can derive the famous equation of special relativity, which states that energy is equivalent to mass times the speed of light squared:

${tex`E = mc^2`}
`)
Insert cell
pong_game = {
({
prompt: "Create an automated retro looking game of pong",
time: 1699389743848,
comment: "Creating an automated retro-looking game of Pong"
});

const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = 200;
const context = canvas.getContext("2d");

const ball = { x: width / 2, y: 20, dx: 3, dy: 2, radius: 15 };
const paddle = { x: 5, y: canvas.height / 2, width: 20, height: 60 };

const drawBall = () => {
context.beginPath();
context.rect(
ball.x,
ball.y - ball.radius,
ball.radius * 2,
ball.radius * 2
);
context.fillStyle = "#FFFFFF";
context.fill();
context.closePath();
};

const drawPaddle = () => {
context.beginPath();
context.rect(paddle.x, paddle.y, paddle.width, paddle.height);
context.fillStyle = "#FFFFFF";
context.fill();
context.closePath();
};

const update = () => {
context.fillStyle = "#000000";
context.fillRect(0, 0, canvas.width, canvas.height);
drawBall();
drawPaddle();

if (
ball.x + ball.dx > canvas.width - ball.radius ||
ball.x + ball.dx < ball.radius + 10
) {
ball.dx = -ball.dx;
}

if (ball.y + ball.dy < ball.radius) {
ball.dy = -ball.dy;
} else if (ball.y + ball.dy > canvas.height - ball.radius) {
if (ball.x > paddle.x && ball.x < paddle.x + paddle.width) {
ball.dy = -ball.dy;
} else {
ball.dy = -ball.dy;
}
}
ball.x += ball.dx;
ball.y += ball.dy;
paddle.y = ball.y - 30;
};

const interval = setInterval(update, 10);

return canvas;
}
Insert cell
neon_tictactoe_game = {
({
prompt: "Create a tick tack toe game using neon colors",
time: 1699470230338,
comment: "Creating a tic-tac-toe game with neon colors"
});

// Create the canvas and get the 2D context
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");

// Define the size of the game board
canvas.width = 300;
canvas.height = 300;
const cellSize = 100;

// Initialize the game board
let board = Array(3)
.fill()
.map(() => Array(3).fill(""));
let currentPlayer = "X";

// Function to draw the game board
const drawBoard = () => {
context.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i <= 2; i++) {
for (let j = 0; j <= 2; j++) {
context.strokeStyle = "#00FF00"; // Neon green for the grid
context.strokeRect(i * cellSize, j * cellSize, cellSize, cellSize);
context.font = "50px sans-serif";
context.fillStyle = currentPlayer === "X" ? "#FF00FF" : "#00FFFF"; // Neon pink for player X, neon cyan for player O
context.fillText(
board[i][j],
i * cellSize + cellSize / 3,
j * cellSize + (2 * cellSize) / 3
);
}
}
};

// Function to handle click events
const handleClick = (event) => {
let x = Math.floor(event.offsetX / cellSize);
let y = Math.floor(event.offsetY / cellSize);
if (board[x][y] === "") {
board[x][y] = currentPlayer;
currentPlayer = currentPlayer === "X" ? "O" : "X";
}
drawBoard();
};

// Attach the click event listener to the canvas
canvas.addEventListener("click", handleClick);

// Draw the initial game board
drawBoard();

return canvas;
}
Insert cell
observable_explanation = ({"prompt":"explain what Observable notebooks are","time":1699564443487,"comment":"Explanation of what Observable notebooks are"}) && md`
Observable notebooks are interactive documents that allow you to write, analyze, visualize and share data and computations. They are built on JavaScript and web technologies, which makes them a powerful tool for everything from quick prototyping to producing complex data visualizations. Observable notebooks update in real-time, meaning that as you change the code, the output updates to reflect those changes. This makes Observable notebooks ideal for experimentation and exploration of data. You can also import code from other notebooks, allowing for easy code reuse and collaboration.
`
Insert cell
youtube_movie = ({
prompt: "pick a movie from youtube",
time: 1699688243950,
comment:
"Embedding a movie from YouTube. This is the trailer for 'Free Guy', a popular movie."
} &&
html`<iframe width="560" height="315" src="https://www.youtube.com/embed/YE7VzlLtp-4" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`)
Insert cell
dead_emoji = {
({
prompt: "draw a smiley emoji",
time: 1699688364300,
comment:
"Drawing a dead emoji using SVG and D3.js. The emoji has a yellow face, two eyes, and a curved mouth."
});

const svg = d3
.create("svg")
.attr("viewBox", [0, 0, 100, 100])
.attr("width", "20%");

const face = svg
.append("circle")
.attr("cx", 50)
.attr("cy", 50)
.attr("r", 45)
.style("fill", "#ffcc00")
.style("stroke", "black");

const leftEye = svg
.append("circle")
.attr("cx", 35)
.attr("cy", 35)
.attr("r", 5)
.style("fill", "black");

const rightEye = svg
.append("circle")
.attr("cx", 65)
.attr("cy", 35)
.attr("r", 5)
.style("fill", "black");

const mouth = svg
.append("path")
.attr("d", "M 30 70 q 20 20 40 0")
.style("fill", "none")
.style("stroke", "black")
.style("stroke-width", "2px");

return svg.node();
}
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
ndd = _ndd
Insert cell
formatted_instruction = {
if (response.action == "upsert_cell") {
let code = undefined;
const prompt = {
prompt: response.prompt,
time: response.time,
comment: response.comment
};
if (response.code.trim().startsWith("{")) {
code = `{ (${JSON.stringify(prompt)})\n${response.code.trim().slice(1)}`;
} else {
code = `(${JSON.stringify(prompt)}) && ${response.code}`;
}
return `${response.cell_name} = ${code}`;
}
return response.content;
}
Insert cell
response = on_prompt
Insert cell
on_prompt = {
return viewof ask.send([
...mutable context,
{
role: "user",
content: feedback_prompt + prompt
}
]);
}
Insert cell
mutable context = undefined
Insert cell
update_context = {
const context = cells
.filter((c) => c.prompt)
.sort((a, b) => a.time - b.time)
.flatMap((c) => [
{
role: "user",
content: c.prompt
},
{
role: "assistant",
content: null,
function_call: {
name: "upsert_cell",
arguments: JSON.stringify({
cell_name: c.cell_name,
code: c.code,
comment: c.comment
})
}
}
]);
if (!_.isEqual(mutable context, context)) {
mutable context = context;
}
}
Insert cell
Insert cell
Insert cell
observableDefinitionToCode = (source) => {
try {
const defn = "(" + source + ")";
const ast = acorn.parse(defn);
const functionExpression = ast.body[0].expression;
if (functionExpression.type !== "FunctionExpression")
throw functionExpression;
const block = defn.slice(
functionExpression.body.start,
functionExpression.body.end
);

const exprMatch = /{return\(\n([\s\S]*)\n\)}$/.exec(block);
if (exprMatch) return exprMatch[1].trim();
else return block;
} catch (e) {
return undefined;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
excludes = [
"viewof feedback_cells_selector",
"feedback_cells_selector",
"feedback_cells",
"feedback_prompt",
"find_prompt",
"viewof feedback_cells",
"null",
"viewof reset",
"reset",
"viewof prompt",
"prompt",
"suggestion",
"initial last_salient_summary",
"mutable last_salient_summary",
"initial context",
"mutable context",
"observableDefinitionToCode",
"viewof model",
"model",
"viewof OPENAI_API_KEY",
"OPENAI_API_KEY",
"settings",
"system_prompt",
"functions",
"viewof history",
"history",
"viewof ask",
"ask",
"openAiResponse",
"instruction",
"acorn",
"inspect",
"dirty_json",
"parseJSON",
"update_context",
"viewof suggestion",
"formatted_instruction",
"response",
"on_prompt",
"viewof context_viz",
"context_viz",
"context",
"code",
"cells",
"events",
"viz",
"vizUpdater",
"ndd",
"_ndd",
"excludes",
"_events",
"variables",
"_mainVariables",
"on_salient_event"
]
Insert cell
import {
_ndd,
events as _events, // Important to alias to avoid self-triggering loops when visualizing
mainVariables as _mainVariables
} with { excludes as excludes } from "@tomlarkworthy/ndd"
Insert cell
functions = [
{
name: "upsert_cell",
description: "Upsert a cell in notebook",
parameters: {
type: "object",
properties: {
cell_name: {
type: "string",
description: "Name of cell to add"
},
code: {
type: "string",
description: "Single expression or code block"
},
comment: {
type: "string",
description: "Explaination for code"
}
},
required: ["cell_name", "code", "comment"]
}
},
{
name: "wait",
description: "Wait for next user instruction",
parameters: { type: "object", properties: {} }
}
]
Insert cell
viewof history = Inputs.input([])
Insert cell
viewof ask = flowQueue({ timeout_ms: 90000 })
Insert cell
ask
Insert cell
openAiResponse = {
const response = await fetch(api_endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${OPENAI_API_KEY}`
},
body: JSON.stringify({
functions: functions,
function_call: { name: "upsert_cell" },
messages: [
{
role: "system",
content: system_prompt
},
...ask
],
...viewof settings.value
})
});

if (response.status !== 200)
throw new Error(`${response.status}: ${await response.text()}`);

return response.json();
}
Insert cell
parseJSON(openAiResponse.choices[0].message.function_call.arguments)
Insert cell
instruction = {
const message = openAiResponse.choices[0].message;
if (message.function_call === undefined)
return {
action: "reply",
content: message.content
};
return {
...parseJSON(message.function_call.arguments),
prompt: ask[ask.length - 1].content,
action: message.function_call.name,
time: Date.now()
};
}
Insert cell
viewof ask.resolve(instruction)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more