{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "marimekko",
  "type": "registry:component",
  "title": "Marimekko",
  "description": "Two splits in one block. Sample data: net sales by region (NA 38%, EU 30%, APAC 20%) and four categories inside each.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-marimekko"
  ],
  "files": [
    {
      "path": "registry/chartory/components/marimekko.tsx",
      "type": "registry:component",
      "target": "components/chartory/marimekko.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Marimekko (Chartory chart 047): 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/marimekko\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/047-marimekko/data\"\nimport { def } from \"@/lib/chartory/charts/types/047-marimekko/layout\"\n\nregisterChart(def, sample)\n\nexport type MarimekkoData = typeof sample\nexport type MarimekkoProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: MarimekkoData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: MarimekkoData[]\n}\n\nexport function Marimekko(props: MarimekkoProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/047-marimekko/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/047-marimekko/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 047 Marimekko · sample data (Figma chart/047, e-commerce: Q3 net sales by region (share) and category (parts)).\nimport type { MarimekkoData } from \"../../plots/marimekko\";\n\nexport const data: MarimekkoData = {\n  toks: [\"data/cat-1\", \"data/cat-2\", \"data/cat-3\", \"data/cat-5\"],\n  cols: [\n    { label: \"NA\", share: 38, parts: [34, 22, 28, 16] },\n    { label: \"EU\", share: 30, parts: [41, 25, 18, 16] },\n    { label: \"APAC\", share: 20, parts: [22, 14, 46, 18] },\n    { label: \"LATAM\", share: 12, parts: [38, 30, 12, 20] },\n  ],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/047-marimekko/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/047-marimekko/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 047 Marimekko (Figma chart/047): C.marimekko on the region × category sales sample.\nimport { buildVariant, type ChartDef, type Size, type TooltipSpec } from \"../../core/shell\";\nimport { marimekko } from \"../../plots/marimekko\";\nimport { data } from \"./data\";\n\nconst cats = [\"Apparel\", \"Home\", \"Electronics\", \"Beauty\"];\nconst pct = (v: number, of: number) => Math.round((v / of) * 100) + \"%\";\nconst tot = data.cols.reduce((a, c) => a + c.share, 0);\nconst sum = (a: number[]) => a.reduce((s, v) => s + v, 0);\n\n/** One set of whole points moved by up to ±3 (`seed` picks the pattern), still summing to the same total: the last\n *  entry takes the rest. */\nconst mix = (vs: number[], seed: number) => {\n  const out = vs.map((v, i) => (i === vs.length - 1 ? 0 : Math.max(2, Math.round(v + 3 * Math.sin(seed + i * 1.7)))));\n  out[vs.length - 1] = vs.reduce((s, v) => s + v, 0) - out.reduce((s, v) => s + v, 0);\n  return out;\n};\n\n// Percent labels show in cells of 20 × 40 px and up and column labels shorten when narrow, differently at every size\n// (several cells sit exactly on 20 px). The next quarter moves each region's category mix, then the region shares,\n// one set at a time: each takes the first pattern that keeps every variant's marks, or stays.\nconst shape = (d: unknown) => ([\"xs\", \"s\", \"m\", \"l\"] as Size[]).flatMap((s) => [true, false].map((lg) => buildVariant(def, s, lg, d).marks.map((m) => m.kind + \"|\" + (m.kind === \"text\" ? m.style : m.name)).join(\"\\n\"))).join(\"\\n\\n\");\nlet base: string | undefined;\nfunction later(o: typeof data, step: number): typeof data {\n  base ??= shape(data);\n  let cur = o;\n  const tryAll = (make: (seed: number) => typeof data) => {\n    for (let k = 0; k < 16; k++) { const c = make(step * 1.9 + k * 0.85); if (shape(c) === base) { cur = c; return; } }\n  };\n  for (let i = 0; i < o.cols.length; i++) tryAll((seed) => ({ ...cur, cols: cur.cols.map((c, j) => (j === i ? { ...c, parts: mix(c.parts, seed + i * 2.3) } : c)) }));\n  tryAll((seed) => { const sh = mix(cur.cols.map((c) => c.share), seed); return { ...cur, cols: cur.cols.map((c, j) => ({ ...c, share: sh[j] })) }; });\n  return cur;\n}\n\n/** Tooltip for one region (group = the region's column of cells): its share of sales and its category mix. */\nfunction tipOf(o: typeof data, g: number): TooltipSpec | null {\n  const c = o.cols[g];\n  if (!c) return null;\n  const all = o.cols.reduce((a, x) => a + x.share, 0), ps = sum(c.parts);\n  return { kind: \"series\", caps: `${c.label} · ${pct(c.share, all)} OF SALES`, rows: c.parts.map((v, j) => ({ label: cats[j] ?? \"Other\", value: pct(v, ps), swatch: o.toks[j] })) };\n}\n\nexport const def: ChartDef = {\n  no: 47,\n  slug: \"marimekko\",\n  legend: [[\"data/cat-1\", \"Apparel\"], [\"data/cat-2\", \"Home\"], [\"data/cat-3\", \"Electronics\"], [\"data/cat-5\", \"Beauty\"]],\n  // update: the next quarter (see later)\n  update: (d, step) => later(d as typeof data, step),\n  plot: (K, p, w, d) => marimekko(K, p, w, (d as typeof data | undefined) ?? data),\n  tip: (d, g) => tipOf(d as typeof data, g),\n  describe: {\n    title: \"Sales by region and category, Q3\",\n    summary: `Q3 net sales by region: ${data.cols.map((c) => `${c.label} ${pct(c.share, tot)}`).join(\", \")}; Electronics is ${pct(data.cols[2].parts[2], sum(data.cols[2].parts))} of APAC, Apparel ${pct(data.cols[1].parts[0], sum(data.cols[1].parts))} of EU.`,\n    table: { head: [\"Region\", \"Share of sales\", ...cats], rows: data.cols.map((c) => [c.label, pct(c.share, tot), ...c.parts.map((v) => pct(v, sum(c.parts)))]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "part-of-a-whole"
  ],
  "meta": {
    "access": "free",
    "no": 47,
    "family": "Part of a whole"
  }
}
