{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "shelf-planogram",
  "type": "registry:component",
  "title": "Shelf planogram",
  "description": "Shelves, facing by facing, with stock levels. Sample data: three dairy shelves, 15 products from OAT to MOZZ, healthy, low and out of stock.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-shelf"
  ],
  "files": [
    {
      "path": "registry/chartory/components/shelf-planogram.tsx",
      "type": "registry:component",
      "target": "components/chartory/shelf-planogram.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Shelf planogram (Chartory chart 059): 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/shelf-planogram\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/059-shelf-planogram/data\"\nimport { def } from \"@/lib/chartory/charts/types/059-shelf-planogram/layout\"\n\nregisterChart(def, sample)\n\nexport type ShelfPlanogramData = typeof sample\nexport type ShelfPlanogramProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: ShelfPlanogramData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: ShelfPlanogramData[]\n}\n\nexport function ShelfPlanogram(props: ShelfPlanogramProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/059-shelf-planogram/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/059-shelf-planogram/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 059 Shelf availability · sample data (Figma chart/059, from the Figma definition, seeded values expanded).\nimport type { ShelfData } from \"../../plots/shelf\";\n\nexport const data: ShelfData = {\n  low: 0.3,\n  out: 0.02,\n  shelves: [\n    [\n      { name: \"OAT\", w: 3, pct: 0 },\n      { name: \"SOY\", w: 2, pct: 0.7 },\n      { name: \"WHOLE\", w: 4, pct: 0.85 },\n      { name: \"SKIM\", w: 3, pct: 0.55 },\n      { name: \"A2\", w: 2, pct: 0.22 }\n    ],\n    [\n      { name: \"GREEK\", w: 3, pct: 0.64 },\n      { name: \"SKYR\", w: 3, pct: 0.9 },\n      { name: \"KEFIR\", w: 2, pct: 0 },\n      { name: \"PLAIN\", w: 4, pct: 0.76 },\n      { name: \"KIDS\", w: 2, pct: 0.18 }\n    ],\n    [\n      { name: \"BRIE\", w: 2, pct: 0.5 },\n      { name: \"FETA\", w: 2, pct: 0.81 },\n      { name: \"CHEDDAR\", w: 4, pct: 0.68 },\n      { name: \"GOUDA\", w: 3, pct: 0 },\n      { name: \"MOZZ\", w: 3, pct: 0.92 }\n    ]\n  ]\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/059-shelf-planogram/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/059-shelf-planogram/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 059 Shelf planogram (Figma chart/059, \"Shelf availability\"): C.shelf, three dairy shelves, stock per facing.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { shelf } from \"../../plots/shelf\";\nimport { data } from \"./data\";\n\nconst all = data.shelves.flat();\nconst status = (q: number) => (q <= data.out ? \"Out\" : q <= data.low ? \"Low\" : \"Healthy\");\nconst list = (s: string) => all.filter((q) => status(q.pct) === s).map((q) => q.name[0] + q.name.slice(1).toLowerCase()).join(\", \");\n\nconst r2 = (v: number) => Math.round(v * 100) / 100;\n\n// tooltip: one product facing (group = reading order over the shelves): stock level, swatch = its stock fill\nconst tip = (o: typeof data, g: number): TooltipSpec | null => {\n  let k = g;\n  for (let s = 0; s < o.shelves.length; s++) {\n    if (k >= o.shelves[s].length) { k -= o.shelves[s].length; continue; }\n    const q = o.shelves[s][k];\n    const out = q.pct <= o.out, low = q.pct <= o.low;\n    return {\n      kind: \"cell\",\n      caps: \"SHELF \" + (s + 1) + \" · \" + q.name,\n      value: Math.round(q.pct * 100) + \"%\",\n      unit: \"in stock\",\n      swatch: out ? \"status/danger\" : low ? \"status/warning\" : \"data/primary\",\n      share: (out ? \"OUT\" : low ? \"LOW\" : \"HEALTHY\") + \" · \" + q.w + (q.w === 1 ? \" FACING\" : \" FACINGS\"),\n    };\n  }\n  return null;\n};\n\nexport const def: ChartDef = {\n  no: 59,\n  slug: \"shelf-planogram\",\n  legend: [[\"data/primary\", \"Healthy\"], [\"status/warning\", \"Low\"], [\"status/danger\", \"Out\"]],\n  plot: (K, p, w, d) => shelf(K, p, w, (d as typeof data | undefined) ?? data),\n  tip: (d, g) => tip(d as typeof data, g),\n  // the shelf a few hours later: stock moves up to ±18 % per facing, every facing keeps its status (out / low / healthy)\n  update: (d, step) => {\n    const o = d as typeof data;\n    let i = 0;\n    const move = (q: number) => {\n      const v = r2(q * (1 + 0.18 * Math.sin(i++ * 1.7 + step * 2.3)));\n      return q <= o.out ? q : q <= o.low ? Math.min(o.low, Math.max(o.out + 0.04, v)) : Math.min(0.98, Math.max(o.low + 0.04, v));\n    };\n    return { ...o, shelves: o.shelves.map((r) => r.map((q) => ({ ...q, pct: move(q.pct) }))) };\n  },\n  describe: {\n    title: \"Shelf availability\",\n    summary: `Stock on ${all.length} products across ${data.shelves.length} shelves: out of stock ${list(\"Out\")}; low (30% or less) ${list(\"Low\")}; the rest healthy.`,\n    table: { head: [\"Shelf\", \"Product\", \"Facings\", \"Stock\", \"Status\"], rows: data.shelves.flatMap((r, s) => r.map((q) => [s + 1, q.name, q.w, Math.round(q.pct * 100) + \"%\", status(q.pct)])) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "space-and-place"
  ],
  "meta": {
    "access": "free",
    "no": 59,
    "family": "Space and place"
  }
}
