{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "isotype",
  "type": "registry:component",
  "title": "Isotype",
  "description": "Counts drawn as rows of icons. Sample data: orders by channel, one box = 100, web 1,840, retail 310.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-isotype"
  ],
  "files": [
    {
      "path": "registry/chartory/components/isotype.tsx",
      "type": "registry:component",
      "target": "components/chartory/isotype.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Isotype (Chartory chart 097): 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/isotype\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/097-isotype/data\"\nimport { def } from \"@/lib/chartory/charts/types/097-isotype/layout\"\n\nregisterChart(def, sample)\n\nexport type IsotypeData = typeof sample\nexport type IsotypeProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: IsotypeData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: IsotypeData[]\n}\n\nexport function Isotype(props: IsotypeProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/097-isotype/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/097-isotype/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 097 Isotype · sample data (Figma chart/097, e-commerce: orders by channel this week, 1 box = 100 orders).\nimport type { IsotypeData } from \"../../plots/isotype\";\n\nexport const data: IsotypeData = {\n  unit: 100,\n  rows: [\n    { label: \"Web\", v: 1840, tok: \"data/cat-1\" },\n    { label: \"App\", v: 1260, tok: \"data/cat-2\" },\n    { label: \"Marketplace\", v: 760, tok: \"data/cat-3\" },\n    { label: \"Retail\", v: 310, tok: \"data/cat-5\" },\n  ],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/097-isotype/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/097-isotype/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 097 Isotype (Figma chart/097): C.isotype; the legend names the channels and the unit (1 box = 100).\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { isotype } from \"../../plots/isotype\";\nimport { data } from \"./data\";\n\nconst total = data.rows.reduce((a, r) => a + r.v, 0);\n\n/** Another week: orders per channel move inside the same box count (the last box stays partial). */\nfunction update(d0: unknown, step: number): typeof data {\n  const d = d0 as typeof data;\n  return {\n    ...d,\n    rows: d.rows.map((r, i) => {\n      const full = Math.floor(r.v / d.unit) * d.unit, part = r.v - full;\n      return { ...r, v: full + Math.min(d.unit - 5, Math.max(5, Math.round(part + 0.4 * d.unit * Math.sin(i * 2.1 + step * 1.7 + 0.4)))) };\n    }),\n  };\n}\n\n/** Hover: one channel (its row of boxes and count): orders and their share of the week. */\nfunction tip(d0: unknown, g: number): TooltipSpec | null {\n  const rows = (d0 as typeof data).rows, r = rows[g];\n  if (!r) return null;\n  const all = rows.reduce((a, x) => a + x.v, 0);\n  return { kind: \"value\", text: `${r.label} · ${r.v.toLocaleString(\"en-US\")} orders · ${Math.round((100 * r.v) / all)}%` };\n}\n\nexport const def: ChartDef = {\n  no: 97,\n  slug: \"isotype\",\n  legend: [[\"data/cat-1\", \"Web\"], [\"data/cat-2\", \"App\"], [\"data/cat-3\", \"Marketplace\"], [\"data/cat-5\", \"Retail · 1 box = 100\"]],\n  plot: (K, p, w, d) => isotype(K, p, w, (d as typeof data | undefined) ?? data),\n  tip,\n  update,\n  describe: {\n    title: \"Orders by channel\",\n    summary: `${total.toLocaleString(\"en-US\")} orders this week by channel, one box per ${data.unit}: ${data.rows.map((r) => `${r.label} ${r.v.toLocaleString(\"en-US\")}`).join(\", \")}.`,\n    table: { head: [\"Channel\", \"Orders\"], rows: data.rows.map((r) => [r.label, r.v]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "part-of-a-whole"
  ],
  "meta": {
    "access": "free",
    "no": 97,
    "family": "Part of a whole"
  }
}
