{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "lollipop",
  "type": "registry:component",
  "title": "Lollipop",
  "description": "A slim bar with a marker at the value. Sample data: new deposits in four regions, South $596K, West $174K.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-lollipop"
  ],
  "files": [
    {
      "path": "registry/chartory/components/lollipop.tsx",
      "type": "registry:component",
      "target": "components/chartory/lollipop.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Lollipop (Chartory chart 009): 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/lollipop\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/009-lollipop/data\"\nimport { def } from \"@/lib/chartory/charts/types/009-lollipop/layout\"\n\nregisterChart(def, sample)\n\nexport type LollipopData = typeof sample\nexport type LollipopProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: LollipopData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: LollipopData[]\n}\n\nexport function Lollipop(props: LollipopProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/009-lollipop/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/009-lollipop/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 009 Lollipop · sample data (Figma chart/009-lollipop, fintech: new deposits in October by region, $K).\nimport type { LollipopData } from \"../../plots/lollipop\";\n\nexport const data: LollipopData = {\n  max: 650,\n  rows: [\n    [\"East\", 478, \"data/cat-2\", \"$478K\"],\n    [\"Midwest\", 386, \"data/cat-4\", \"$386K\"],\n    [\"South\", 596, \"data/cat-3\", \"$596K\"],\n    [\"West\", 174, \"data/cat-9\", \"$174K\"],\n  ],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/009-lollipop/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/009-lollipop/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 009 Lollipop (Figma chart/009-lollipop): C.lollipop on the regional deposits sample.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { lollipop } from \"../../plots/lollipop\";\nimport { frame, type Frame, type Text } from \"../../core/node\";\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/** A text is named by its characters, so an update state takes the sample's text names (same order): its value\n *  labels then stay the same marks and morph in place instead of reading as new ones. */\nfunction keepNames(pl: Frame, ref: Frame): Frame {\n  const texts = (f: Frame): Text[] => f.children.flatMap((c) => (c.removed ? [] : c.kind === \"text\" ? [c] : c.kind === \"frame\" ? texts(c) : []));\n  const a = texts(pl), b = texts(ref);\n  if (a.length === b.length) a.forEach((t, i) => { if (t.name === t.text.slice(0, 40)) t.name = b[i].name; });\n  return pl;\n}\n\nconst total = data.rows.reduce((a, r) => a + r[1], 0);\n\n/** Hover tooltip: one region's lollipop. */\nconst tip = (d: unknown, g: number): TooltipSpec => {\n  const [label, , , text] = (d as typeof data).rows[g];\n  return { kind: \"value\", text: `${label} · ${text}` };\n};\n\nexport const def: ChartDef = {\n  no: 9,\n  slug: \"lollipop\",\n  legend: [[\"data/cat-2\", \"East\"], [\"data/cat-4\", \"Midwest\"], [\"data/cat-3\", \"South\"], [\"data/cat-9\", \"West\"]],\n  plot: (K, p, w, d) => {\n    const o = (d as typeof data | undefined) ?? data;\n    const pl = lollipop(K, p, w, o);\n    return o === data ? pl : keepNames(pl, lollipop(K, frame(null, \"sample\"), w, data));\n  },\n  tip,\n  update: (d, step) => {\n    const o = d as typeof data;\n    // later months: deposits per region move ±12 %, inside the $650K scale\n    return {\n      ...o,\n      rows: o.rows.map(([label, v, tok], i) => {\n        const nv = clamp(Math.round(v * (1 + 0.12 * wave(i, step))), 60, 640);\n        return [label, nv, tok, \"$\" + nv + \"K\"] as (typeof o.rows)[number];\n      }),\n    };\n  },\n  describe: {\n    title: \"Deposits by region\",\n    summary: `New deposits in October by region, $${total}K in total: ${data.rows.map((r) => `${r[0]} ${r[3]}`).join(\", \")}.`,\n    table: { head: [\"Region\", \"Deposits\"], rows: data.rows.map((r) => [r[0], r[3]]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "compare-items"
  ],
  "meta": {
    "access": "free",
    "no": 9,
    "family": "Compare items"
  }
}
