{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "candlestick",
  "type": "registry:component",
  "title": "Candlestick",
  "description": "Open, high, low and close, per period. Sample data: spot price in four-hour candles, Sep 30 to Oct 9.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-candles"
  ],
  "files": [
    {
      "path": "registry/chartory/components/candlestick.tsx",
      "type": "registry:component",
      "target": "components/chartory/candlestick.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Candlestick (Chartory chart 036): 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/candlestick\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/036-candlestick/data\"\nimport { def } from \"@/lib/chartory/charts/types/036-candlestick/layout\"\n\nregisterChart(def, sample)\n\nexport type CandlestickData = typeof sample\nexport type CandlestickProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: CandlestickData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: CandlestickData[]\n}\n\nexport function Candlestick(props: CandlestickProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/036-candlestick/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/036-candlestick/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 036 Candlestick · sample data (Figma chart/036, crypto: SOL / USD 4 h candles, Sep 30 to Oct 9; seeded sample,\n// expanded from the Figma definition: [open, high, low, close, volume]).\nimport type { CandlesData } from \"../../plots/candles\";\n\nexport const data: CandlesData = {\n  min: 128,\n  max: 152,\n  ticks: [\"152\", \"144\", \"136\", \"128\"],\n  vmax: 94.5043953203151,\n  xl: { 0: \"SEP 30\", 10: \"OCT 2\", 20: \"OCT 4\", 30: \"OCT 7\", 39: \"OCT 9\" },\n  c: [\n    [132.3561768619978, 132.4649168674112, 130.3556822545639, 130.94895323782833, 53.089245377615676],\n    [130.94895323782833, 132.29429187575465, 130.30721689411965, 131.19146318911552, 42.68837337507325],\n    [131.19146318911552, 132.55713487294744, 128.72567648504756, 129.96966664810745, 46.11445204639549],\n    [129.96966664810745, 131.09385857934592, 129.04943168717506, 130.9934289824541, 65.24235960340238],\n    [130.9934289824541, 132.49754916448032, 129.75318973969166, 132.16344788291653, 44.326561784523804],\n    [132.16344788291653, 134.1759922655765, 131.80186158293014, 133.77005654913097, 90.61188019374939],\n    [133.77005654913097, 134.23876549637075, 131.91053582870333, 133.1018120875814, 56.28926987586975],\n    [133.1018120875814, 135.59262008609466, 132.79388804433023, 134.56094828719876, 77.68835381497087],\n    [134.56094828719876, 135.22090818211106, 132.44233146767985, 133.58828525868444, 50.51566060190818],\n    [133.58828525868444, 134.76624628342046, 132.5772627265068, 134.1380311931288, 59.52992754966483],\n    [134.1380311931288, 135.47897106638317, 133.57456979946912, 134.8362886446902, 61.24185307009232],\n    [134.8362886446902, 135.19085596466198, 133.24598449464608, 134.05893126024256, 65.55525915024582],\n    [134.05893126024256, 134.844014968507, 132.99305790041623, 134.10375996324967, 88.58108290870724],\n    [134.10375996324967, 134.8347168324174, 133.69088368229887, 133.88298378419083, 49.703392772797216],\n    [133.88298378419083, 135.0412666206049, 132.47787656766263, 132.73750817900407, 92.64964923851642],\n    [132.73750817900407, 133.63380181089684, 131.46402371666767, 131.47109493875647, 93.40127056157274],\n    [131.47109493875647, 132.37658057918986, 131.12042332528364, 131.93799245093297, 88.76318447699919],\n    [131.93799245093297, 132.3387023151511, 131.01751813303193, 131.74820604695017, 94.5043953203151],\n    [131.74820604695017, 132.68639761755355, 131.15716916060504, 132.226720635529, 63.86923440912237],\n    [132.226720635529, 133.00036552866752, 130.5142130764081, 131.36393205524604, 92.58045696307926],\n    [131.36393205524604, 133.31626554150145, 130.67527381998266, 132.07540824048192, 60.52686021687782],\n    [132.07540824048192, 134.31970804716818, 130.92326431945304, 133.59752371064644, 69.26631710923571],\n    [133.59752371064644, 136.09977937919635, 133.27686598663445, 135.33574530662398, 69.75860584050352],\n    [135.33574530662398, 138.02453658887208, 134.88141582487776, 136.7484579115661, 53.52570180479702],\n    [136.7484579115661, 137.94043210238237, 136.26008829614895, 137.81887035015916, 92.63398497022408],\n    [137.81887035015916, 139.2190385193671, 136.55385342730852, 138.51142472648777, 71.68952931262997],\n    [138.51142472648777, 140.56226524328358, 137.28701617451895, 139.55244645298478, 41.479983144197604],\n    [139.55244645298478, 140.59590786101663, 138.68978947071255, 139.96187069453944, 51.824330693029026],\n    [139.96187069453944, 140.81987738575407, 138.65012919629277, 139.16858844060664, 46.193679276012666],\n    [139.16858844060664, 141.6429424218568, 138.95017584209617, 140.80952667766695, 42.594707087890576],\n    [140.80952667766695, 142.74489368706426, 140.67934399618738, 142.02776807376733, 90.58546973885292],\n    [142.02776807376733, 143.2920664522052, 141.92302528035225, 143.28589612181946, 66.23409688763046],\n    [143.28589612181946, 145.00398616268112, 142.59050138468785, 143.8227702767564, 52.8291558999704],\n    [143.8227702767564, 144.6984338635087, 142.47841213552766, 144.528008186223, 41.16912704946898],\n    [144.528008186223, 145.4972509525331, 144.24410874053842, 144.69431860889975, 52.770726602883414],\n    [144.69431860889975, 145.55906167681286, 143.888350308655, 144.2250927241841, 75.56190560365184],\n    [144.2250927241841, 145.30143285830013, 143.67011464345927, 144.36095835493364, 70.7115460889002],\n    [144.36095835493364, 145.76542932347274, 143.82203341121323, 145.56389788270738, 87.63696181943499],\n    [145.56389788270738, 147.32761629467998, 144.3084620356562, 147.05815384237755, 70.44063096420868],\n    [147.05815384237755, 148.88441238274072, 146.67923711910623, 148.62, 93.71577233714785],\n  ],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/036-candlestick/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/036-candlestick/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 036 Candlestick (Figma chart/036): C.candles; no legend (direction reads from colour, the average is dashed).\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { candles } from \"../../plots/candles\";\nimport { tickSeries } from \"../../core/vary\";\nimport { data } from \"./data\";\n\nconst f2 = (v: number) => v.toFixed(2);\nconst first = data.c[0], last = data.c[data.c.length - 1];\nconst hi = Math.max(...data.c.map((c) => c[1])), lo = Math.min(...data.c.map((c) => c[2]));\n\n/** Tooltip for one candle (group = the candle with its volume bar): open, high, low, close and volume. */\nfunction tipOf(o: typeof data, g: number): TooltipSpec | null {\n  const c = o.c[g];\n  if (!c) return null;\n  const [op, h, l, cl, vol] = c, swatch = cl >= op ? \"status/success\" : \"status/danger\", ch = ((cl - op) / op) * 100;\n  return {\n    kind: \"range\", caps: `CANDLE ${g + 1} OF ${o.c.length} · ${ch >= 0 ? \"+\" : \"−\"}${Math.abs(ch).toFixed(2)}%`,\n    rows: [[\"Open\", \"$\" + f2(op)], [\"High\", \"$\" + f2(h)], [\"Low\", \"$\" + f2(l)], [\"Close\", \"$\" + f2(cl)], [\"Volume\", vol.toFixed(1)]].map(([label, value]) => ({ label, value, swatch })),\n  };\n}\n\nexport const def: ChartDef = {\n  no: 36,\n  slug: \"candlestick\",\n  legend: null,\n  // update: a revised feed for the same window; prices stretch / shrink around the window's low (±12 %, kept inside\n  // the axis, every open still the previous close and every wick still spans its body) and volume moves ±15 %\n  update: (d, step) => {\n    const o = d as typeof data;\n    const lo = Math.min(...o.c.map((c) => c[2])), hi = Math.max(...o.c.map((c) => c[1]));\n    const k = Math.min(1 + 0.12 * Math.sin(step * 2.2 + 0.6), (o.max - 0.5 - lo) / (hi - lo)), sh = 0.6 * Math.sin(step * 1.4);\n    const p = (v: number) => Math.max(o.min + 0.2, lo + sh + (v - lo) * k);\n    return {\n      ...o,\n      c: o.c.map(([op, h, l, cl, vol], i) => [p(op), p(h), p(l), p(cl), Math.min(o.vmax, vol * (1 + 0.15 * Math.sin(step * 1.9 + i * 0.8)))] as typeof o.c[number]),\n    };\n  },\n  // live: a new 4 h candle opens at the last close; the oldest leaves\n  tick: (d, step) => {\n    const o = d as typeof data;\n    const last = o.c[o.c.length - 1][3];\n    const close = tickSeries([last], step + 1, o.min + 1, o.max - 1)[0];\n    const hi = Math.min(o.max, Math.max(last, close) + 0.6), lo = Math.max(o.min, Math.min(last, close) - 0.6);\n    return { ...o, c: [...o.c.slice(1), [last, hi, lo, close, o.vmax * (0.35 + 0.5 * ((step * 37) % 10) / 10)] as [number, number, number, number, number]] };\n  },\n  plot: (K, p, w, d) => candles(K, p, w, (d as typeof data | undefined) ?? data),\n  tip: (d, g) => tipOf(d as typeof data, g),\n  describe: {\n    title: \"SOL / USD · 4 h\",\n    summary: `${data.c.length} four-hour candles of SOL / USD from Sep 30 to Oct 9: open $${f2(first[0])}, last close $${f2(last[3])}, range $${f2(lo)} to $${f2(hi)}, with volume and a 7-period moving average.`,\n    table: { head: [\"Candle\", \"Open\", \"High\", \"Low\", \"Close\", \"Volume\"], rows: data.c.map((c, i) => [i + 1, f2(c[0]), f2(c[1]), f2(c[2]), f2(c[3]), c[4].toFixed(1)]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "change-over-time"
  ],
  "meta": {
    "access": "free",
    "no": 36,
    "family": "Change over time"
  }
}
