{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tachograph",
  "type": "registry:component",
  "title": "Tachograph",
  "description": "A driver's day in driving, other work, rest and availability. Sample data: three drivers' days, R. Silva 8.0 h, T. Brandt 6.5 h, M. Kaya 8.5 h driving.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-tacho"
  ],
  "files": [
    {
      "path": "registry/chartory/components/tachograph.tsx",
      "type": "registry:component",
      "target": "components/chartory/tachograph.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Tachograph (Chartory chart 092): 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/tachograph\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/092-tachograph/data\"\nimport { def } from \"@/lib/chartory/charts/types/092-tachograph/layout\"\n\nregisterChart(def, sample)\n\nexport type TachographData = typeof sample\nexport type TachographProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: TachographData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: TachographData[]\n}\n\nexport function Tachograph(props: TachographProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/092-tachograph/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/092-tachograph/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 092 Tachograph · sample data (Figma chart/092, logistics: today's driver activity from the tachograph cards).\nimport type { TachoData } from \"../../plots/tacho\";\n\nexport const data: TachoData = {\n  kinds: { drive: \"data/primary\", work: \"status/warning\", rest: \"status/success\", avail: \"data/cat-2\" },\n  center: [[\"Label/Caps\", \"24 H\", \"label\"], [\"Label/Caps\", \"DISC\", \"label\"]],\n  drivers: [\n    { label: \"R. Silva\", segs: [[5.5, 6, \"work\"], [6, 10.5, \"drive\"], [10.5, 11.25, \"rest\"], [11.25, 14.75, \"drive\"], [14.75, 15.5, \"work\"]] },\n    { label: \"T. Brandt\", segs: [[5, 6, \"work\"], [6, 9, \"drive\"], [9, 9.75, \"rest\"], [9.75, 13.25, \"drive\"], [13.25, 14, \"avail\"]] },\n    { label: \"M. Kaya\", segs: [[6.5, 7, \"work\"], [7, 11.5, \"drive\"], [11.5, 12.25, \"rest\"], [12.25, 16.25, \"drive\"], [16.25, 17, \"work\"]] },\n  ],\n  rows: [\n    { label: \"R. Silva\", text: \"8.0 h\", pct: \"DRIVE\" },\n    { label: \"T. Brandt\", text: \"6.5 h\", pct: \"DRIVE\" },\n    { label: \"M. Kaya\", text: \"8.5 h\", pct: \"DRIVE\", tone: \"status/warning\" },\n  ],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/092-tachograph/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/092-tachograph/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 092 Tachograph (Figma chart/092): C.tacho on today's driver cards, with the drive-time list beside the disc.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { tacho } from \"../../plots/tacho\";\nimport { data } from \"./data\";\n\nconst KIND: Record<string, string> = { drive: \"Driving\", work: \"Other work\", rest: \"Rest\", avail: \"Available\" };\nconst clock = (h: number) => String(Math.floor(h)).padStart(2, \"0\") + \":\" + String(Math.round((h % 1) * 60)).padStart(2, \"0\");\n\n/** Another day: each activity boundary moves by up to a quarter hour; drive time and its warning (over 8 h) recomputed. */\nfunction update(d0: unknown, step: number): typeof data {\n  const d = d0 as typeof data;\n  // phase 3.6 keeps T. Brandt's value as wide as the sample's (no 7.x h): at S a narrower one brings back the DRIVE caps\n  let k = 0;\n  const drivers = d.drivers.map((dr) => {\n    let prev = -Infinity;\n    const b = [dr.segs[0][0], ...dr.segs.map((s) => s[1])].map((t) => {\n      const v = Math.max(prev + 0.25, t + 0.25 * Math.round(Math.sin(k++ * 2.1 + step * 1.7 + 3.6) * 1.4));\n      prev = v;\n      return v;\n    });\n    return { ...dr, segs: dr.segs.map((s, i): [number, number, string] => [b[i], b[i + 1], s[2]]) };\n  });\n  const rows = d.rows.map((r, i) => {\n    const h = drivers[i].segs.filter((s) => s[2] === \"drive\").reduce((a, s) => a + s[1] - s[0], 0);\n    const { tone, ...rest } = r;\n    void tone;\n    return h > 8 ? { ...rest, text: h.toFixed(1) + \" h\", tone: \"status/warning\" } : { ...rest, text: h.toFixed(1) + \" h\" };\n  });\n  return { ...d, drivers, rows };\n}\n\n/** Hover: one driver (their ring of activities): hours per activity, the shift total. */\nfunction tip(d0: unknown, g: number): TooltipSpec | null {\n  const d = d0 as typeof data, dr = d.drivers[g];\n  if (!dr) return null;\n  const hrs = (k: string) => dr.segs.filter((s) => s[2] === k).reduce((a, s) => a + s[1] - s[0], 0);\n  const rows = Object.keys(KIND).filter((k) => hrs(k) > 0).map((k) => ({ label: KIND[k], value: hrs(k).toFixed(1) + \" h\", swatch: d.kinds[k] }));\n  const a = dr.segs[0][0], b = dr.segs[dr.segs.length - 1][1];\n  return { kind: \"series\", caps: `${dr.label} · ${clock(a)}–${clock(b)}`.toUpperCase(), rows, total: { label: \"Shift\", value: (b - a).toFixed(1) + \" h\" } };\n}\n\nexport const def: ChartDef = {\n  no: 92,\n  slug: \"tachograph\",\n  legend: [[\"data/primary\", \"Driving\"], [\"status/warning\", \"Other work\"], [\"status/success\", \"Rest\"], [\"data/cat-2\", \"Available\"]],\n  // radius-bound like the other round types: Figma's XS legend=off keeps the legend-on plot height (150), centred\n  flatXs: true,\n  plot: (K, p, w, d) => tacho(K, p, w, (d as typeof data | undefined) ?? data),\n  tip,\n  update,\n  describe: {\n    title: \"Driver hours today\",\n    summary: `Activity of ${data.drivers.length} drivers over 24 hours: driving time ${data.rows.map((r) => `${r.label} ${r.text}`).join(\", \")}.`,\n    table: {\n      head: [\"Driver\", \"From\", \"To\", \"Activity\"],\n      rows: data.drivers.flatMap((d) => d.segs.map(([a, b, k]) => [d.label, clock(a), clock(b), KIND[k]])),\n    },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "schedule-and-status"
  ],
  "meta": {
    "access": "free",
    "no": 92,
    "family": "Schedule and status"
  }
}
