{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "spiral-year",
  "type": "registry:component",
  "title": "Spiral year",
  "description": "A year of weeks, wound into one coil. Sample data: active workspaces per week over one year, with a 9-week streak above 2K.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-spiral"
  ],
  "files": [
    {
      "path": "registry/chartory/components/spiral-year.tsx",
      "type": "registry:component",
      "target": "components/chartory/spiral-year.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Spiral year (Chartory chart 051): sizes xs | s | m | l, laid out again from the data at each\n// size; collection \"hearth\" (default) or \"signal\" (with @chartory/signal, Code and Complete). Data in the type's shape (default: the sample). Docs:\n// https://usechartory.com/docs/charts/spiral-year\nimport { ChartView, type ChartViewProps } from \"@/lib/chartory/charts/chart-view\"\nimport { registerChart } from \"@/lib/chartory/charts/defs\"\nimport { data as sample } from \"@/lib/chartory/charts/types/051-spiral-year/data\"\nimport { def } from \"@/lib/chartory/charts/types/051-spiral-year/layout\"\n\nregisterChart(def, sample)\n\nexport type SpiralYearData = typeof sample\nexport type SpiralYearProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: SpiralYearData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: SpiralYearData[]\n}\n\nexport function SpiralYear(props: SpiralYearProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/051-spiral-year/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/051-spiral-year/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 051 Weekly active workspaces · sample data (Figma chart/051, from the Figma definition, seeded values expanded).\nimport type { SpiralData } from \"../../plots/spiral\";\n\nexport const data: SpiralData = {\n  vals: [0.05, 0.39, 0.42, 0.49, 0.51, 0.51, 0.57, 0.5, 0.5, 0.57, 0.89, 0.5, 0.47, 0.5, 0.39, 0.39, 0.44, 0.42, 0.43, 0.37, 0.4, 0.52, 0.39, 0.48, 0.57, 0.51, 0.58, 0.61, 0.64, 0.64, 0.79, 0.83, 0.85, 0.81, 0.82, 0.7, 0.74, 0.71, 0.64, 0.61, 0.69, 0.65, 0.68, 0.58, 0.56, 0.7, 0.66, 0.74, 0.77, 0.83, 0.76, 0.48],\n  turns: 2.5,\n  center: [\n    [\"Label/Caps\", \"W1\", \"label\"],\n    [\"Label/Caps\", \"START\", \"label\"]\n  ],\n  rows: [\n    { label: \"Busiest\", text: \"W11\", pct: \"LAUNCH\" },\n    { label: \"Quietest\", text: \"W1\", pct: \"NEW YEAR\" },\n    { label: \"Streak\", text: \"9 wks\", pct: \"ABOVE 2K\" }\n  ]\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/051-spiral-year/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/051-spiral-year/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 051 Spiral year (Figma chart/051, \"Weekly active workspaces\"): C.spiral, 52 weeks on 2.5 turns, the busiest ringed.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { spiral } from \"../../plots/spiral\";\nimport { data } from \"./data\";\n\nconst pct = (v: number) => Math.round(v * 100) + \"%\";\n\nconst r2 = (v: number) => Math.round(v * 100) / 100;\n\n// tooltip: one week dot (group = week index)\nconst tip = (o: typeof data, g: number): TooltipSpec | null => (o.vals[g] == null ? null : { kind: \"value\", text: \"W\" + (g + 1) + \" · \" + pct(o.vals[g]) });\n\nexport const def: ChartDef = {\n  no: 51,\n  slug: \"spiral-year\",\n  legend: [[\"data/seq-2\", \"Quiet week\"], [\"data/seq-4\", \"Typical\"], [\"data/seq-6\", \"Busy week\"]],\n  flatXs: true,\n  plot: (K, p, w, d) => spiral(K, p, w, (d as typeof data | undefined) ?? data),\n  tip: (d, g) => tip(d as typeof data, g),\n  // a later year: every week moves up to ±12 %; the busiest week (ringed) and the quietest keep their place\n  update: (d, step) => {\n    const o = d as typeof data, top = o.vals.indexOf(Math.max(...o.vals)), low = o.vals.indexOf(Math.min(...o.vals));\n    const lo = o.vals[low] + 0.05, hi = o.vals[top] - 0.03;\n    return { ...o, vals: o.vals.map((v, i) => (i === top || i === low ? v : Math.min(hi, Math.max(lo, r2(v * (1 + 0.12 * Math.sin(i * 0.9 + step * 1.7))))))) };\n  },\n  describe: {\n    title: \"Year in activity\",\n    summary: `Weekly active workspaces over ${data.vals.length} weeks as a share of the busiest week: week 11 (launch) is the busiest at ${pct(Math.max(...data.vals))}, week 1 (new year) the quietest at ${pct(Math.min(...data.vals))}, with a 9-week streak above 2K.`,\n    table: { head: [\"Week\", \"Share of busiest week\"], rows: data.vals.map((v, i) => [\"W\" + (i + 1), pct(v)]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "change-over-time"
  ],
  "meta": {
    "access": "free",
    "no": 51,
    "family": "Change over time"
  }
}
