Source

78 chart lines · 3 files · 2.5 kBBenchmark harness excluded · shared/mount.ts

English letter frequencies26 records · CSV · 275 B
@charts-poc/demo-data/alphabet

Selection: Complete published snapshot

letter
string
frequency
number

Cryptographical Mathematics by Robert Edward Lewand@observablehq/sample-datasets@1.0.1 · revision 732c0148de74 · alphabet.csv · ISC distribution; upstream source credited · SHA-256 d62ce74dad83Pinned snapshot

cases/100-radial-bars/tanstack.ts56 lines · entry
cases/100-radial-bars/tanstack.ts
import { defineChart } from '@tanstack/charts'
import { polar, radialArc } from '@tanstack/charts/polar'
import { alphabet } from '@charts-poc/demo-data/alphabet'
import { arc } from 'd3-shape'
import { selectRadialBarData } from './selection'
import { radialBarLayout } from './transform'
import { tanstackMount } from '../../shared/mount'
import type { RadialBarLayoutDatum } from './transform'
import type { ConformanceInput } from '../../types'

const innerRadiusRatio = 0.2
const barRatio = 0.62
const colors = ['#7c3aed', '#0ea5e9', '#14b8a6', '#f59e0b']
const maximumFrequency = alphabet[0]?.frequency ?? 1

const definition = (input: ConformanceInput) => {
  const data = radialBarLayout(selectRadialBarData(alphabet, input.revision))

  return defineChart({
    marks: [
      polar({
        radiusRatio: 0.84,
        marks: [
          radialArc(data, {
            className: 'ts-chart__radial-bars',
            generator: ({ radius }) => {
              const innerRadius = radius * innerRadiusRatio
              const band = (radius - innerRadius) / data.length
              const barSize = band * barRatio
              const offset = Math.round((band - barSize) / 2)

              return arc<unknown, RadialBarLayoutDatum>()
                .startAngle(0)
                .endAngle(
                  (row) => (row.frequency / maximumFrequency) * Math.PI * 2,
                )
                .innerRadius((row) => innerRadius + row.ring * band + offset)
                .outerRadius(
                  (row) => innerRadius + row.ring * band + offset + barSize,
                )
                .cornerRadius(barSize / 2)
            },
            color: 'letter',
          }),
        ],
      }),
    ],
    color: { range: colors },
    margin: 0,
  })
}

export const mount = tanstackMount(
  definition,
  'Concentric letter frequency bars',
)
cases/100-radial-bars/selection.ts11 lines · support
cases/100-radial-bars/selection.ts
import type { AlphabetRow } from '@charts-poc/demo-data/alphabet'

const sliceSize = 4

export function selectRadialBarData(
  rows: readonly AlphabetRow[],
  revision = 0,
) {
  const start = Math.abs(revision % 2) * sliceSize
  return rows.slice(start, start + sliceSize)
}
cases/100-radial-bars/transform.ts11 lines · support
cases/100-radial-bars/transform.ts
import type { AlphabetRow } from '@charts-poc/demo-data/alphabet'

export interface RadialBarLayoutDatum extends AlphabetRow {
  ring: number
}

export function radialBarLayout(
  rows: readonly AlphabetRow[],
): readonly RadialBarLayoutDatum[] {
  return rows.map((row, ring) => ({ ...row, ring }))
}