Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 15 additions & 1 deletion API-FRICTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,11 @@ Each entry records:
two broad `import.meta.glob('./cases/*/*.ts')` registries. Its default entry
registered 584 implementation and raw-source imports, including every
comparison renderer, data/helper modules, and a `tanstack.test.ts` file.
Even after the production graph was narrowed, its public source entry was
still the conformance `tanstack.ts` adapter. Opening an example in the docs
therefore started on mount plumbing and followed shared harness modules
instead of showing the chart definition; some sandboxes contained source
from unrelated examples.
- Decision: give each chart type an isolated entry module and share only the
renderer-free host setup. Renderer-specific helpers with runtime imports
live in separate modules. Tier variants also use direct build-time globals;
Expand Down Expand Up @@ -883,7 +888,16 @@ Each entry records:
Every published TanStack root receives the same static-closure
comparison-package check. The schema-v3 artifact validator rejects
unreferenced files, unsafe paths, missing imports, invalid preloads, invalid
authored-source roles, and a comparison module not marked debug-only.
authored-source roles, and a comparison module not marked debug-only. The
source catalog now publishes one case-local `example.tsx` root per case.
Conformance adapters import that public definition, while the docs runtime
supplies its own hidden React mount entry and rejects any relative import
that leaves the case directory. `pnpm catalog:examples:check` validates all
188 public roots, their default exports, definition-first source order,
adapter ownership, unused source, and isolated relative source closures. The
largest public TypeScript closure contains four files. The shadcn generator
prunes unused variant helpers before writing each public example, while
hidden catalog adapters retain deterministic preview framing and focus.

### F-025 — Bundle maintenance clobbered the full comparison report

Expand Down
350 changes: 175 additions & 175 deletions benchmarks/conformance/DEFINITION-COVERAGE-AUDIT.md

Large diffs are not rendered by default.

348 changes: 174 additions & 174 deletions benchmarks/conformance/DEFINITION-COVERAGE-OVERVIEW.md

Large diffs are not rendered by default.

14 changes: 11 additions & 3 deletions benchmarks/conformance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ behavior select that renderer explicitly without creating a second harness.
Each case owns:

- one typed raw data fixture and intent;
- one self-contained public `example.tsx` with the chart definition;
- one isolated reference implementation;
- one isolated TanStack implementation;
- one thin TanStack conformance adapter that imports the public example;
- official source provenance;
- semantic geometry expectations;
- optional renderer-independent interaction scenarios;
Expand Down Expand Up @@ -58,6 +59,9 @@ pnpm dev:conformance
# Validate case metadata, source entries, ordering, and index drift
pnpm catalog:index:check

# Validate every public example and its case-local source closure
pnpm catalog:examples:check

# Render the checked-in source-derived catalog previews
pnpm catalog:previews

Expand Down Expand Up @@ -100,8 +104,12 @@ current boundary and case-local evidence for every case.

`catalog-index.json` is the checked-in metadata contract for consumers that load
source directly from the Charts repository. It contains every parsed
`case.json` field plus the TanStack and reference entry paths. The index does
`case.json` field plus the public `example.tsx` entry path. The index does
not embed compiled modules, source closures, previews, datasets, or assets.
Every public entry has a default React export and may import only files from its
own case directory. Conformance code imports the definition from that entry;
the adapter, driver, tests, and comparison renderer are not published to the
docs sandbox.

Every case also has a checked-in source-derived preview at
`benchmarks/conformance/previews/<caseId>.svg`. The generator mounts the actual
Expand Down Expand Up @@ -133,7 +141,7 @@ its source entries from that same revision.

The Vite application remains the local authoring and conformance surface at
`http://localhost:5194/`. TanStack.com owns the public catalog routes and chrome.
It reads `catalog-index.json`, case source, and the checked-in preview SVGs from
It reads `catalog-index.json`, each self-contained example source closure, and the checked-in preview SVGs from
one pinned Charts revision, then runs full examples in the site notebook
runtime. The site does not maintain parallel preview implementations or consume
a generated catalog branch or published renderable-catalog package.
Expand Down
48 changes: 48 additions & 0 deletions benchmarks/conformance/cases/01-line-gaps/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip as exampleTooltip } from '@tanstack/charts/tooltip'

import { aapl } from '@charts-poc/demo-data/aapl'
import { defineChart, lineY } from '@tanstack/charts'
import { scaleLinear, scaleUtc } from 'd3-scale'

export const definition = (input: ExampleOptions) => {
const rows = aapl.slice(Math.abs(input.revision) % 2)

return defineChart({
marks: [
lineY(rows, {
x: 'Date',
y: (row) => (row.Date.getUTCMonth() < 3 ? null : row.Close),
stroke: '#2563eb',
strokeWidth: 2.25,
}),
],
x: { scale: scaleUtc, axis: { label: 'Week' } },
y: { scale: scaleLinear, grid: true, axis: { label: 'Close (USD)' } },
})
}
export interface ExampleOptions {
width: number
height: number
revision: number
preview?: boolean
}

export const exampleAriaLabel = 'Apple closing price with first-quarter gaps'

export const createExampleChart = (options: ExampleOptions) =>
defineChart(definition(options), {
keyboard: true,
tooltip: exampleTooltip,
})

export const chart = createExampleChart({
width: 640,
height: 480,
revision: 0,
preview: false,
})

export default function Example() {
return <Chart ariaLabel={exampleAriaLabel} definition={chart} height={480} />
}
35 changes: 5 additions & 30 deletions benchmarks/conformance/cases/01-line-gaps/tanstack.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,8 @@
import { aapl } from '@charts-poc/demo-data/aapl'
import { defineChart, lineY } from '@tanstack/charts'
import { scaleLinear, scaleUtc } from 'd3-scale'
import type { ConformanceInput } from '../../types'
import { tanstackMount } from '../../shared/mount'
import { samplePreviewData } from '../../shared/preview'
import { createExampleChart, exampleAriaLabel } from './example'
import { tanstackExampleMount } from '../../shared/mount'

const definition = (input: ConformanceInput) => {
const rows = samplePreviewData(
aapl.slice(Math.abs(input.revision) % 2),
input,
80,
[(row) => row.Date.getTime(), (row) => row.Close],
)
export * from './example'

return defineChart({
marks: [
lineY(rows, {
x: 'Date',
y: (row) => (row.Date.getUTCMonth() < 3 ? null : row.Close),
stroke: '#2563eb',
strokeWidth: 2.25,
}),
],
x: { scale: scaleUtc, axis: { label: 'Week' } },
y: { scale: scaleLinear, grid: true, axis: { label: 'Close (USD)' } },
})
}
export const mount = tanstackExampleMount(createExampleChart, exampleAriaLabel)

export const mount = tanstackMount(
definition,
'Apple closing price with first-quarter gaps',
)
export const catalogCase = mount
85 changes: 85 additions & 0 deletions benchmarks/conformance/cases/02-multi-line-end-labels/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip as exampleTooltip } from '@tanstack/charts/tooltip'

import { defineChart, lineY, select, text } from '@tanstack/charts'
import { scaleLinear, scaleUtc } from 'd3-scale'
import { industries } from '@charts-poc/demo-data/industries'
import { selectMultiLineData } from './selection'
import type { MultiLineDatum } from './selection'

const colors = ['#2563eb', '#ea580c', '#059669']

export const multiLineEndLabelsDefinition = (
rows: readonly MultiLineDatum[],
preview = false,
) => {
const endpoints = select(rows, {
by: 'industry',
value: (datum) => datum.date.getTime(),
select: 'max',
})

return defineChart({
marks: [
lineY(rows, {
id: 'industry-lines',
x: 'date',
y: 'unemployed',
color: 'industry',
strokeWidth: 2.25,
}),
text(endpoints, {
id: 'industry-end-labels',
x: 'date',
y: 'unemployed',
text: 'industry',
color: 'industry',
anchor: preview ? 'end' : 'start',
dx: preview ? -5 : 5,
fontWeight: 600,
}),
],
x: { scale: scaleUtc, axis: { label: 'Week' } },
y: {
scale: scaleLinear,
grid: true,
axis: { label: 'Unemployed (thousands)' },
},
color: {
range: colors,
},
margin: { right: 112 },
})
}

export const definition = (input: ExampleOptions) =>
multiLineEndLabelsDefinition(
selectMultiLineData(industries, input.revision),
input.preview === true,
)
export interface ExampleOptions {
width: number
height: number
revision: number
preview?: boolean
}

export const exampleAriaLabel =
'Unemployment by industry with direct end labels'

export const createExampleChart = (options: ExampleOptions) =>
defineChart(definition(options), {
keyboard: true,
tooltip: exampleTooltip,
})

export const chart = createExampleChart({
width: 640,
height: 480,
revision: 0,
preview: false,
})

export default function Example() {
return <Chart ariaLabel={exampleAriaLabel} definition={chart} height={480} />
}
67 changes: 5 additions & 62 deletions benchmarks/conformance/cases/02-multi-line-end-labels/tanstack.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,8 @@
import { defineChart, lineY, select, text } from '@tanstack/charts'
import { scaleLinear, scaleUtc } from 'd3-scale'
import { industries } from '@charts-poc/demo-data/industries'
import type { ConformanceInput } from '../../types'
import { tanstackCase } from '../../shared/mount'
import { selectMultiLineData } from './selection'
import type { MultiLineDatum } from './selection'
import { createExampleChart, exampleAriaLabel } from './example'
import { tanstackExampleMount } from '../../shared/mount'

const colors = ['#2563eb', '#ea580c', '#059669']
export * from './example'

export const multiLineEndLabelsDefinition = (
rows: readonly MultiLineDatum[],
preview = false,
) => {
const endpoints = select(rows, {
by: 'industry',
value: (datum) => datum.date.getTime(),
select: 'max',
})
export const mount = tanstackExampleMount(createExampleChart, exampleAriaLabel)

return defineChart({
marks: [
lineY(rows, {
id: 'industry-lines',
x: 'date',
y: 'unemployed',
color: 'industry',
strokeWidth: 2.25,
}),
text(endpoints, {
id: 'industry-end-labels',
x: 'date',
y: 'unemployed',
text: 'industry',
color: 'industry',
anchor: preview ? 'end' : 'start',
dx: preview ? -5 : 5,
fontWeight: 600,
}),
],
x: { scale: scaleUtc, axis: { label: 'Week' } },
y: {
scale: scaleLinear,
grid: true,
axis: { label: 'Unemployed (thousands)' },
},
color: {
range: colors,
},
margin: { right: 112 },
})
}

const definition = (input: ConformanceInput) =>
multiLineEndLabelsDefinition(
selectMultiLineData(industries, input.revision),
input.preview === true,
)

export const catalogCase = tanstackCase(
definition,
'Unemployment by industry with direct end labels',
)

export const mount = catalogCase.mount
export const catalogCase = mount
64 changes: 64 additions & 0 deletions benchmarks/conformance/cases/03-temperature-range-band/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip as exampleTooltip } from '@tanstack/charts/tooltip'

import { areaY, defineChart, lineY } from '@tanstack/charts'
import { sfTemperatures } from '@charts-poc/demo-data/sf-temperatures'
import { scaleLinear, scaleUtc } from 'd3-scale'

export const definition = () => {
const rows = sfTemperatures
return defineChart({
marks: [
areaY(rows, {
x: 'date',
y1: 'low',
y2: 'high',
fill: '#60a5fa',
fillOpacity: 0.24,
}),
lineY(rows, {
x: 'date',
y: 'low',
stroke: '#2563eb',
strokeWidth: 1.75,
}),
lineY(rows, {
x: 'date',
y: 'high',
stroke: '#dc2626',
strokeWidth: 1.75,
}),
],
x: { scale: scaleUtc, axis: { label: 'Week' } },
y: { scale: scaleLinear, grid: true, axis: { label: 'Temperature (°F)' } },
})
}
export const exampleAriaLabel =
'San Francisco daily low-to-high temperature range'

export const createExampleChart = () =>
defineChart(definition(), {
keyboard: true,
tooltip: {
use: exampleTooltip,
...{
format: ({ datum }) =>
`${datum.date.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
timeZone: 'UTC',
})} · ${datum.low.toLocaleString('en-US', {
maximumFractionDigits: 1,
})}–${datum.high.toLocaleString('en-US', {
maximumFractionDigits: 1,
})} °F`,
},
},
})

export const chart = createExampleChart()

export default function Example() {
return <Chart ariaLabel={exampleAriaLabel} definition={chart} height={480} />
}
Loading