{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "histogram",
  "type": "registry:component",
  "title": "Histogram",
  "description": "How values spread across ranges. Sample data: response times from 0 to 900 ms, P50 250 ms, P95 475 ms.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-hist"
  ],
  "files": [
    {
      "path": "registry/chartory/components/histogram.tsx",
      "type": "registry:component",
      "target": "components/chartory/histogram.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Histogram (Chartory chart 006): 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/histogram\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/006-histogram/data\"\nimport { def } from \"@/lib/chartory/charts/types/006-histogram/layout\"\n\nregisterChart(def, sample)\n\nexport type HistogramData = typeof sample\nexport type HistogramProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: HistogramData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: HistogramData[]\n}\n\nexport function Histogram(props: HistogramProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/006-histogram/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/006-histogram/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 006 Histogram · sample data (Figma chart/006-histogram, AI: response latency in 25 ms bins over 24 h, requests per\n// bin; p50 and p95 marked). The bin counts are the series the Figma builder generated.\nimport type { HistData } from \"../../plots/hist\";\n\nexport const data: HistData = {\n  vals: [60, 60, 297, 1845, 4755, 7829, 9963, 10800, 10537, 9569, 8264, 6884, 5588, 4451, 3497, 2720, 2100, 1614, 1236, 944, 721, 550, 420, 321, 245, 188, 144, 111, 85, 66, 60, 60, 60, 60, 60, 60],\n  max: 15000,\n  ticks: [\"15K\", \"10K\", \"5K\", \"0\"],\n  tailFrom: 19,\n  p: [\n    {  i: 9, label: \"P50 250 MS\", tok: \"text/strong\", side: \"left\"  },\n    {  i: 18, label: \"P95 475 MS\", tok: \"data/primary-soft\"  },\n  ],\n  xl: [[0, \"0\"], [9, \"225 MS\"], [18, \"450 MS\"], [27, \"675 MS\"], [36, \"900 MS\"]],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/006-histogram/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/006-histogram/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 006 Histogram (Figma chart/006-histogram): C.hist on the latency sample, p50 and p95 marked.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { hist } from \"../../plots/hist\";\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);\n\nconst bin = (i: number) => `${i * 25}–${(i + 1) * 25} ms`;\nconst total = data.vals.reduce((a, b) => a + b, 0);\n\n/** Hover tooltip: one 25 ms bin and its request count. */\nconst tip = (d: unknown, g: number): TooltipSpec => {\n  const o = d as typeof data;\n  return { kind: \"value\", text: `${bin(g)} · ${o.vals[g].toLocaleString(\"en-US\")} requests` };\n};\n\nexport const def: ChartDef = {\n  no: 6,\n  slug: \"histogram\",\n  legend: [[\"data/primary\", \"Within p95\"], [\"data/seq-2\", \"Tail above p95\"]],\n  plot: (K, p, w, d) => hist(K, p, w, (d as typeof data | undefined) ?? data),\n  tip,\n  update: (d, step) => {\n    const o = d as typeof data;\n    // later days: the request count moves −7 … +13 % with ±3 % per bin; the shape (and so p50 / p95) holds\n    const f = [1, 1.08, 0.93, 1.13][((step - 1) % 3) + 1];\n    return { ...o, vals: o.vals.map((v, i) => Math.round(v * f * (1 + 0.03 * wave(i, step)))) };\n  },\n  describe: {\n    title: \"Response latency distribution\",\n    summary: `${total.toLocaleString(\"en-US\")} requests in 25 ms latency bins from 0 to 900 ms; p50 is 250 ms, p95 is 475 ms.`,\n    table: { head: [\"Latency\", \"Requests\"], rows: data.vals.map((v, i) => [bin(i), v.toLocaleString(\"en-US\")]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "distribution"
  ],
  "meta": {
    "access": "free",
    "no": 6,
    "family": "Distribution"
  }
}
