{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "uptime-bars",
  "type": "registry:component",
  "title": "Uptime bars",
  "description": "Each day of each service, as a bar. Sample data: three services over 63 days, API 99.98%, dashboard 99.99%, webhooks 99.91%.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-uptime"
  ],
  "files": [
    {
      "path": "registry/chartory/components/uptime-bars.tsx",
      "type": "registry:component",
      "target": "components/chartory/uptime-bars.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Uptime bars (Chartory chart 070): 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/uptime-bars\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/070-uptime-bars/data\"\nimport { def } from \"@/lib/chartory/charts/types/070-uptime-bars/layout\"\n\nregisterChart(def, sample)\n\nexport type UptimeBarsData = typeof sample\nexport type UptimeBarsProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: UptimeBarsData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: UptimeBarsData[]\n}\n\nexport function UptimeBars(props: UptimeBarsProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/070-uptime-bars/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/070-uptime-bars/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 070 Uptime bars · sample data (Figma chart/070, daily state of 3 services over the last 63 days, oldest first).\nimport type { UptimeData } from \"../../plots/uptime\";\n\nconst days = (f: (i: number) => string) => Array.from({ length: 63 }, (_, i) => f(i));\n\nexport const data: UptimeData = {\n  from: \"63 DAYS AGO\", to: \"TODAY\",\n  toks: { ok: \"status/success\", slow: \"status/warning\", down: \"status/danger\" },\n  rows: [\n    { label: \"API\", text: \"99.98%\", days: days((i) => (i === 21 ? \"slow\" : \"ok\")) },\n    { label: \"Dashboard\", text: \"99.99%\", days: days(() => \"ok\") },\n    { label: \"Webhooks\", text: \"99.91%\", days: days((i) => (i === 47 ? \"down\" : i === 48 || i === 12 ? \"slow\" : \"ok\")) },\n  ],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/070-uptime-bars/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/070-uptime-bars/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 070 Uptime bars (Figma chart/070, \"Service uptime\"): C.uptime, 63 days of 3 services.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { uptime } from \"../../plots/uptime\";\nimport { data } from \"./data\";\n\nconst count = (d: string[], s: string) => d.filter((x) => x === s).length;\nconst down = data.rows.find((r) => r.days.includes(\"down\"))!;\nconst ago = down.days.length - 1 - down.days.indexOf(\"down\");\n\n// uptime from the day states: 99.99 % less 0.01 per degraded day and 0.06 per outage day (the sample's own numbers)\nconst uptimeText = (d: string[]) => (99.99 - 0.01 * count(d, \"slow\") - 0.06 * count(d, \"down\")).toFixed(2) + \"%\";\n\n// tooltip: one service's row of days (group = service): days by state, the days shown as the total\nconst tip = (o: typeof data, g: number): TooltipSpec | null => {\n  const r = o.rows[g];\n  if (!r) return null;\n  return {\n    kind: \"series\",\n    caps: r.label.toUpperCase() + \" · \" + r.text + \" UPTIME\",\n    rows: [[\"ok\", \"Operational\"], [\"slow\", \"Degraded\"], [\"down\", \"Outage\"]].map(([s, label]) => ({ label, value: count(r.days, s) + (count(r.days, s) === 1 ? \" day\" : \" days\"), swatch: o.toks[s] })),\n    total: { label: \"Days shown\", value: r.days.length + \" days\" },\n  };\n};\n\nexport const def: ChartDef = {\n  no: 70,\n  slug: \"uptime-bars\",\n  legend: [[\"status/success\", \"Operational\"], [\"status/warning\", \"Degraded\"], [\"status/danger\", \"Outage\"]],\n  // live: a new day arrives on the right, the oldest leaves\n  tick: (d, step) => {\n    const o = d as typeof data;\n    return { ...o, rows: o.rows.map((r, i) => ({ ...r, days: [...r.days.slice(1), (step + i) % 9 === 4 ? \"slow\" : \"ok\"] })) };\n  },\n  plot: (K, p, w, d) => uptime(K, p, w, (d as typeof data | undefined) ?? data),\n  tip: (d, g) => tip(d as typeof data, g),\n  // a week later per step: seven new days arrive on the right (a degraded day on some), the oldest leave; the\n  // uptime figures are recomputed from the days shown\n  update: (d, step) => {\n    const o = d as typeof data, n = 7 * step;\n    return {\n      ...o,\n      rows: o.rows.map((r, k) => {\n        const days = [...r.days.slice(n), ...Array.from({ length: n }, (_, i) => ((i * 5 + k * 3) % 11 === 4 ? \"slow\" : \"ok\"))];\n        return { ...r, days, text: uptimeText(days) };\n      }),\n    };\n  },\n  describe: {\n    title: \"Status\",\n    summary: `Daily state of ${data.rows.length} services over the last 63 days: API 99.98%, Dashboard 99.99%, Webhooks 99.91% uptime; one outage day, on ${down.label} ${ago} days ago.`,\n    table: { head: [\"Service\", \"Uptime\", \"Operational days\", \"Degraded days\", \"Outage days\"], rows: data.rows.map((r) => [r.label, r.text, count(r.days, \"ok\"), count(r.days, \"slow\"), count(r.days, \"down\")]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "schedule-and-status"
  ],
  "meta": {
    "access": "free",
    "no": 70,
    "family": "Schedule and status"
  }
}
