Source

135 chart lines · 2 files · 3.5 kBBenchmark harness excluded · shared/mount.ts

Flare package hierarchy252 records · CSV · 8.0 kB
@charts-poc/demo-data/flare

Selection: Complete published snapshot

name
string
size
number | null

Flare visualization toolkit@observablehq/sample-datasets@1.0.1 · revision 732c0148de74 · flare.csv · ISC distribution; upstream source credited · SHA-256 704349b51b70Pinned snapshot

cases/96-nested-donut/tanstack.ts64 lines · entry
cases/96-nested-donut/tanstack.ts
import { flare } from '@charts-poc/demo-data/flare'
import { defineChart } from '@tanstack/charts'
import { polar, radialArc } from '@tanstack/charts/polar'
import { pie } from 'd3-shape'
import { nestedFlareDonut } from './transform'
import { tanstackMount } from '../../shared/mount'
import type { FlareDonutSlice } from './transform'
import type { ConformanceInput } from '../../types'

const innerLayout = pie<FlareDonutSlice>()
  .sort(null)
  .value(({ size }) => size)
const outerLayout = pie<FlareDonutSlice>()
  .sort(null)
  .value(({ size }) => size)
const names = [
  'flare.animate',
  'flare.data',
  'flare.animate.core',
  'flare.animate.interpolate',
  'flare.data.core',
  'flare.data.converters',
]
const colors = [
  '#38bdf8',
  '#8b5cf6',
  '#0284c7',
  '#0ea5e9',
  '#7c3aed',
  '#a855f7',
]

const definition = (input: ConformanceInput) => {
  const sourceRows =
    input.revision % 2 === 0
      ? flare
      : flare.filter((row) => row.size === null || row.size >= 1_000)
  const data = nestedFlareDonut(sourceRows)
  const innerArcs = innerLayout([...data.inner])
  const outerArcs = outerLayout([...data.outer])

  return defineChart({
    marks: [
      polar({
        radiusRatio: 0.8,
        marks: [
          radialArc(innerArcs, {
            innerRadius: ({ radius }) => radius * 0.12,
            outerRadius: ({ radius }) => radius * 0.46,
            color: ({ data }) => data.name,
          }),
          radialArc(outerArcs, {
            innerRadius: ({ radius }) => radius * 0.56,
            color: ({ data }) => data.name,
          }),
        ],
      }),
    ],
    color: { domain: names, range: colors },
    margin: 0,
  })
}

export const mount = tanstackMount(definition, 'Nested Flare package sizes')
cases/96-nested-donut/transform.ts71 lines · support
cases/96-nested-donut/transform.ts
import type { FlareRow } from '@charts-poc/demo-data/flare'

export interface FlareDonutSlice {
  name: string
  size: number
}

export interface FlareDonutDetail extends FlareDonutSlice {
  family: string
}

export interface FlareDonutData {
  inner: readonly FlareDonutSlice[]
  outer: readonly FlareDonutDetail[]
}

interface DetailGroup {
  name: string
  family: string
  includes: (name: string) => boolean
}

const detailGroups: readonly DetailGroup[] = [
  {
    name: 'flare.animate.core',
    family: 'flare.animate',
    includes: (name) =>
      name.startsWith('flare.animate.') &&
      !name.startsWith('flare.animate.interpolate.'),
  },
  {
    name: 'flare.animate.interpolate',
    family: 'flare.animate',
    includes: (name) => name.startsWith('flare.animate.interpolate.'),
  },
  {
    name: 'flare.data.core',
    family: 'flare.data',
    includes: (name) =>
      name.startsWith('flare.data.') &&
      !name.startsWith('flare.data.converters.'),
  },
  {
    name: 'flare.data.converters',
    family: 'flare.data',
    includes: (name) => name.startsWith('flare.data.converters.'),
  },
]

export function nestedFlareDonut(rows: readonly FlareRow[]): FlareDonutData {
  const leaves = rows.filter(
    (row): row is FlareRow & { readonly size: number } => row.size !== null,
  )
  const outer = detailGroups.map((group) => ({
    name: group.name,
    family: group.family,
    size: leaves.reduce(
      (total, row) => total + (group.includes(row.name) ? row.size : 0),
      0,
    ),
  }))
  const inner = ['flare.animate', 'flare.data'].map((family) => ({
    name: family,
    size: outer.reduce(
      (total, detail) => total + (detail.family === family ? detail.size : 0),
      0,
    ),
  }))

  return { inner, outer }
}