{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "calendar-heatmap",
  "type": "registry:component",
  "title": "Calendar heatmap",
  "description": "Every day of a season in one grid. Sample data: production deploys per day, last 20 weeks, May to September.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-calendar"
  ],
  "files": [
    {
      "path": "registry/chartory/components/calendar-heatmap.tsx",
      "type": "registry:component",
      "target": "components/chartory/calendar-heatmap.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Calendar heatmap (Chartory chart 025): 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/calendar-heatmap\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/025-calendar-heatmap/data\"\nimport { def } from \"@/lib/chartory/charts/types/025-calendar-heatmap/layout\"\n\nregisterChart(def, sample)\n\nexport type CalendarHeatmapData = typeof sample\nexport type CalendarHeatmapProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: CalendarHeatmapData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: CalendarHeatmapData[]\n}\n\nexport function CalendarHeatmap(props: CalendarHeatmapProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/025-calendar-heatmap/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/025-calendar-heatmap/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 025 Calendar heatmap · sample data (Figma chart/025, dev tools: production deploys per day over 20 weeks, May → Sep;\n// one column per week, Mon → Sun; -1 = days still to come).\nimport type { CalendarData } from \"../../plots/calendar\";\n\nexport const data: CalendarData = {\n  vals: [\n    [0, 3, 2, 1, 0, 0, 0], [3, 3, 3, 2, 2, 0, 1], [3, 0, 1, 1, 2, 0, 0], [0, 0, 2, 0, 4, 1, 0], [1, 3, 2, 4, 1, 0, 0],\n    [3, 1, 2, 2, 3, 0, 0], [4, 2, 1, 3, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0], [4, 3, 1, 0, 0, 1, 0], [1, 1, 0, 2, 3, 0, 1],\n    [2, 2, 0, 3, 0, 1, 1], [2, 4, 1, 1, 1, 1, 0], [1, 0, 2, 4, 4, 0, 1], [5, 6, 2, 2, 2, 0, 1], [5, 2, 4, 6, 5, 0, 1],\n    [2, 6, 5, 3, 4, 1, 0], [3, 4, 6, 6, 2, 1, 0], [5, 5, 2, 2, 2, 0, 0], [6, 3, 3, 2, 3, 0, 1], [5, 5, 5, 4, -1, -1, -1],\n  ],\n  months: { 0: \"MAY\", 4: \"JUN\", 9: \"JUL\", 13: \"AUG\", 17: \"SEP\" },\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/025-calendar-heatmap/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/025-calendar-heatmap/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 025 Calendar heatmap (Figma chart/025): C.calendar; no legend (the plot carries its LESS → MORE scale).\nimport type { ChartDef } from \"../../core/shell\";\nimport { calendar } from \"../../plots/calendar\";\nimport { data } from \"./data\";\n\n/** Deterministic wave in [-1, 1] per index and update step (no randomness: the same step gives the same period). */\nconst wave = (i: number, step: number, f = 1.7) => Math.sin(step * 2.3 + i * f + 0.5);\nconst clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));\n\nconst DAYS = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\nconst days = data.vals.flat().filter((v) => v >= 0);\nconst busiest = Math.max(...days);\n\nexport const def: ChartDef = {\n  no: 25,\n  slug: \"calendar-heatmap\",\n  legend: null,\n  plot: (K, p, w, d) => calendar(K, p, w, (d as typeof data | undefined) ?? data),\n  update: (d, step) => {\n    const o = d as typeof data;\n    // a revised count per day: ±1 deploy (whole, 0–6); days still to come (−1) stay empty\n    return { ...o, vals: o.vals.map((wk, x) => wk.map((v, dd) => (v < 0 ? v : clamp(v + Math.round(1.2 * wave(x * 7 + dd, step, 2.3)), 0, 6)))) };\n  },\n  describe: {\n    title: \"Production deploys per day\",\n    summary: `Deploy intensity per day over ${data.vals.length} weeks, May to September, on a 0–6 scale: ${days.filter((v) => v === 0).length} of ${days.length} days had no deploys; the busiest days reach ${busiest}.`,\n    table: {\n      head: [\"Week\", ...DAYS],\n      rows: data.vals.map((wk, i) => [\"Week \" + (i + 1), ...wk.map((v) => (v < 0 ? \"–\" : v))]),\n    },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "change-over-time"
  ],
  "meta": {
    "access": "free",
    "no": 25,
    "family": "Change over time"
  }
}
