Notebooks Front End

by data-desk-eco

artdata

Use when editing docs/index.html, creating charts with Plot, adding SQL cells, loading data with FileAttachment, or building visualizations. Triggers on any editing of docs/index.html, Observable notebooks, or front-end visualization work.

Skill Details

Repository Files

1 file in this skill directory


name: notebooks-front-end description: Use when editing docs/index.html, creating charts with Plot, adding SQL cells, loading data with FileAttachment, or building visualizations. Triggers on any editing of docs/index.html, Observable notebooks, or front-end visualization work.

Observable Notebook Kit 2.0

Data Desk notebooks use Observable Notebook Kit 2.0 - standalone HTML pages with embedded JavaScript that compile to static sites.

Cell types

<!doctype html>
<notebook theme="midnight">
  <title>Research title</title>

  <!-- Markdown -->
  <script id="header" type="text/markdown">
    # Research title
  </script>

  <!-- JavaScript -->
  <script id="analysis" type="module">
    const data = await FileAttachment("../data/flows.csv").csv({typed: true});
    display(Inputs.table(data));
  </script>

  <!-- SQL (queries DuckDB) -->
  <script id="flows" output="flows" type="application/sql" database="../data/data.duckdb" hidden>
    SELECT * FROM flows ORDER BY date DESC
  </script>

  <!-- Raw HTML -->
  <script id="chart" type="text/html">
    <div id="map" style="height: 500px;"></div>
  </script>
</notebook>

Key points:

  • Each <script> has unique id
  • Cells are type="module" by default (ES6 syntax)
  • Use display() to render output (don't rely on return values)
  • Variables defined in one cell available to all others
  • Use sentence case for all titles, headings, and chart titles (e.g., "Outages by country" not "Outages By Country")
  • Keep the "last updated" date element - this is auto-populated from git and should not be removed

Loading data

FileAttachment API

Paths relative to notebook (docs/index.html):

  • Data files in root data/ → use ../data/
  • Assets in docs/assets/ → use assets/
  • Always await FileAttachment calls
// CSV with type inference
const flows = await FileAttachment("../data/flows.csv").csv({typed: true});

// JSON
const projects = await FileAttachment("../data/projects.json").json();

// Parquet
const tracks = await FileAttachment("../data/tracks.parquet").parquet();

// Images
const img = await FileAttachment("assets/photo.jpg").url();

DuckDB / SQL cells (preferred for data)

Always prefer SQL cells with a DuckDB database over loading CSV/JSON directly. SQL cells query at build time, embedding results in HTML.

<script id="query" output="flows" type="application/sql" database="../data/data.duckdb" hidden>
  SELECT * FROM flows WHERE year >= 2020
</script>

Attributes:

  • type="application/sql" - marks as SQL query
  • database="../data/data.duckdb" - path to database (relative to notebook)
  • output="flows" - variable name for results
  • hidden - don't display output (optional)

Results available as JS variable:

display(html`<p>Found ${flows.length} flows</p>`);

DuckDB client (for complex/dynamic queries)

const db = DuckDBClient.of();
const summary = await db.query(`
  SELECT year, count(*) as n, sum(volume_kt) as total
  FROM flows GROUP BY year ORDER BY year
`);
display(Inputs.table(summary));

Visualization with Observable Plot

display(Plot.plot({
  title: "Annual volumes by destination",
  x: {label: "Year"},
  y: {label: "Volume (Mt)", grid: true},
  color: {legend: true},
  marks: [
    Plot.barY(data, {x: "year", y: "volume", fill: "region", tip: true}),
    Plot.ruleY([0])
  ]
}));

Common marks: Plot.line(), Plot.barY(), Plot.areaY(), Plot.dot() Built-in: automatic scales, tooltips with tip: true, responsive layout

Interactive inputs

// Toggle
const show_all = view(Inputs.toggle({label: "Show all columns"}));

// Search
const searched = view(Inputs.search(data));

// Table
display(Inputs.table(searched, {
  rows: 25,
  columns: show_all ? undefined : ["name", "date", "value"]
}));

// Slider, select, etc.
const threshold = view(Inputs.range([0, 100], {step: 1, value: 50}));
const country = view(Inputs.select(["UK", "Norway", "Sweden"]));

view() makes input reactive - other cells auto-update when value changes.

External libraries

Load via dynamic imports or CDN:

<!-- CSS -->
<script type="text/html">
  <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet" />
</script>

<!-- JS library -->
<script type="module">
  const script = document.createElement('script');
  script.src = 'https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js';
  script.onload = () => initMap();
  document.head.appendChild(script);
</script>

Common patterns

Data aggregation

// Group by and sum
const annual = d3.rollup(flows, v => d3.sum(v, d => d.volume), d => d.year);

// Map to array
const data = Array.from(annual, ([year, volume]) => ({year, volume}))
  .sort((a, b) => a.year - b.year);

Formatting

const formatDate = d3.utcFormat("%B %Y");
const formatNumber = d3.format(",.1f");
const formatCurrency = d3.format("$,.0f");

Inline calculations in markdown

// Calculate stats
const total = d3.sum(flows, d => d.volume);
const maxYear = d3.max(flows, d => d.year);

Reference in markdown:

<script type="text/markdown">
  Analysis found ${total.toFixed(1)} Mt across ${flows.length} voyages,
  peaking in ${maxYear}.
</script>

Geospatial (DuckDB Spatial)

<script type="application/sql" database="../data/flows.duckdb" output="ports">
  SELECT port_name, ST_AsGeoJSON(geometry) as geojson, count(*) as visits
  FROM port_visits GROUP BY port_name, geometry
</script>

Use in Mapbox/Leaflet:

ports.forEach(p => {
  const coords = JSON.parse(p.geojson).coordinates;
  new mapboxgl.Marker().setLngLat(coords).addTo(map);
});

Building and previewing

Before building or previewing, always run yarn first to install dependencies (including DuckDB). Without this, SQL queries will fail silently.

# Install dependencies (required for DuckDB queries)
yarn

# Preview with hot reload (auto-kills existing servers first)
make preview

# Build for production
make build

# Kill any orphaned preview servers
make kill

For Claude Code: Run preview in background, then kill when done:

make preview &   # Start in background
# ... do work ...
make kill        # Clean up when finished

Resources

Related Skills

Xlsx

Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas

data

Clickhouse Io

ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.

datacli

Clickhouse Io

ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.

datacli

Analyzing Financial Statements

This skill calculates key financial ratios and metrics from financial statement data for investment analysis

data

Data Storytelling

Transform data into compelling narratives using visualization, context, and persuasive structure. Use when presenting analytics to stakeholders, creating data reports, or building executive presentations.

data

Team Composition Analysis

This skill should be used when the user asks to "plan team structure", "determine hiring needs", "design org chart", "calculate compensation", "plan equity allocation", or requests organizational design and headcount planning for a startup.

artdesign

Startup Financial Modeling

This skill should be used when the user asks to "create financial projections", "build a financial model", "forecast revenue", "calculate burn rate", "estimate runway", "model cash flow", or requests 3-5 year financial planning for a startup.

art

Kpi Dashboard Design

Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data visualization layouts.

designdata

Dbt Transformation Patterns

Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.

testingdocumenttool

Startup Metrics Framework

This skill should be used when the user asks about "key startup metrics", "SaaS metrics", "CAC and LTV", "unit economics", "burn multiple", "rule of 40", "marketplace metrics", or requests guidance on tracking and optimizing business performance metrics.

art

Skill Information

Category:Creative
Last Updated:12/30/2025