{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "punch-card",
  "type": "registry:component",
  "title": "Punch card",
  "description": "Activity by weekday and hour, as sized dots. Sample data: API calls by weekday and hour, Monday to Sunday, 00 to 23.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-punch-card"
  ],
  "files": [
    {
      "path": "registry/chartory/components/punch-card.tsx",
      "type": "registry:component",
      "target": "components/chartory/punch-card.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Punch card (Chartory chart 086): 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/punch-card\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/086-punch-card/data\"\nimport { def } from \"@/lib/chartory/charts/types/086-punch-card/layout\"\n\nregisterChart(def, sample)\n\nexport type PunchCardData = typeof sample\nexport type PunchCardProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: PunchCardData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: PunchCardData[]\n}\n\nexport function PunchCard(props: PunchCardProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/086-punch-card/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/086-punch-card/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 086 API calls by hour · sample data (Figma chart/086-punch-card-api).\nimport type { PunchCardData } from \"../../plots/punch-card\";\n\nexport const data: PunchCardData = {\n  rows: [\"MON\", \"TUE\", \"WED\", \"THU\", \"FRI\", \"SAT\", \"SUN\"],\n  vals: [[9, 7, 5, 5, 7, 10, 31, 52, 89, 113, 102, 78, 73, 69, 111, 103, 80, 59, 54, 36, 25, 21, 16, 13], [9, 7, 4, 4, 7, 14, 35, 62, 78, 98, 115, 93, 71, 74, 107, 104, 91, 84, 45, 37, 29, 22, 22, 13], [9, 6, 4, 4, 7, 10, 31, 49, 94, 85, 116, 94, 71, 76, 85, 100, 78, 72, 59, 37, 32, 26, 20, 14], [9, 5, 4, 4, 6, 14, 31, 55, 90, 91, 82, 74, 79, 72, 95, 108, 87, 74, 52, 43, 27, 21, 21, 14], [9, 7, 4, 3, 5, 12, 30, 54, 74, 77, 102, 92, 82, 76, 100, 107, 89, 62, 55, 39, 30, 28, 18, 14], [3, 2, 1, 1, 2, 4, 9, 20, 25, 36, 30, 38, 28, 26, 30, 34, 26, 23, 18, 15, 12, 10, 7, 4], [4, 2, 1, 1, 2, 4, 11, 15, 30, 28, 34, 38, 30, 27, 28, 35, 35, 25, 18, 12, 12, 9, 5, 4]],\n  xl: { 0: \"00\", 6: \"06\", 12: \"12\", 18: \"18\", 23: \"23\" },\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/086-punch-card/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/086-punch-card/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 086 Punch card (Figma chart/086-punch-card-api): C.punchCard, API calls per hour of the week.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { punchCard } from \"../../plots/punch-card\";\nimport { data } from \"./data\";\n\nconst mx = Math.max(...data.vals.flat());\nconst at = data.vals.findIndex((r) => r.includes(mx));\n\n/** A later week: every hour moves (whole thousands, at least 1), the busiest hours stay in the working day. */\nfunction update(d0: unknown, step: number): typeof data {\n  const d = d0 as typeof data;\n  return { ...d, vals: d.vals.map((row, r) => row.map((v, h) => Math.max(1, Math.round(v * (1 + 0.16 * Math.sin(r * 1.3 + h * 0.7 + step * 1.9)))))) };\n}\n\nconst hh = (h: number) => String(h).padStart(2, \"0\") + \":00\";\n/** Hover: one day (its row of hour dots): busiest hour, hourly average and quietest hour (calls in thousands). */\nfunction tip(d0: unknown, g: number): TooltipSpec | null {\n  const d = d0 as typeof data, row = d.vals[g];\n  if (!row) return null;\n  const wk = Math.max(...d.vals.flat()), tok = (v: number) => (v / wk > 0.75 ? \"data/primary\" : \"data/primary-soft\");\n  const hi = Math.max(...row), lo = Math.min(...row), sum = row.reduce((a, b) => a + b, 0), avg = Math.round(sum / row.length);\n  return {\n    kind: \"range\",\n    caps: `${d.rows[g]} · ${sum.toLocaleString(\"en-US\")}K CALLS`,\n    rows: [{ label: \"Busiest · \" + hh(row.indexOf(hi)), value: hi + \"K\", swatch: tok(hi) }, { label: \"Hourly average\", value: avg + \"K\", swatch: tok(avg) }, { label: \"Quietest · \" + hh(row.indexOf(lo)), value: lo + \"K\", swatch: tok(lo) }],\n  };\n}\n\nexport const def: ChartDef = {\n  no: 86,\n  slug: \"punch-card\",\n  legend: [[\"data/primary-soft\", \"Calls\"], [\"data/primary\", \"Peak hours\"]],\n  plot: (K, p, w, d) => punchCard(K, p, w, (d as typeof data | undefined) ?? data),\n  tip,\n  update,\n  describe: {\n    title: \"API calls by hour\",\n    summary: `API calls (thousands) per hour for each day of the last week: busiest ${data.rows[at]} ${String(data.vals[at].indexOf(mx)).padStart(2, \"0\")}:00 with ${mx}; weekends stay under ${Math.max(...data.vals[5], ...data.vals[6]) + 1}.`,\n    table: { head: [\"Day\", ...Array.from({ length: 24 }, (_, h) => String(h).padStart(2, \"0\"))], rows: data.rows.map((r, i) => [r, ...data.vals[i]]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "schedule-and-status"
  ],
  "meta": {
    "access": "free",
    "no": 86,
    "family": "Schedule and status"
  }
}
