{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "multi-line",
  "type": "registry:component",
  "title": "Multi-line",
  "description": "A few series on one time axis. Sample data: P95 time to first token in four regions, last 24 hours.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-multi-line"
  ],
  "files": [
    {
      "path": "registry/chartory/components/multi-line.tsx",
      "type": "registry:component",
      "target": "components/chartory/multi-line.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Multi-line (Chartory chart 012): 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/multi-line\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/012-multi-line/data\"\nimport { def } from \"@/lib/chartory/charts/types/012-multi-line/layout\"\n\nregisterChart(def, sample)\n\nexport type MultiLineData = typeof sample\nexport type MultiLineProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: MultiLineData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: MultiLineData[]\n}\n\nexport function MultiLine(props: MultiLineProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/012-multi-line/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/012-multi-line/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 012 · sample data (Figma chart/012-multi-line, AI: p95 time to first token per region in ms, last 24 h; the seeded walk the Figma builder generated).\nimport type { MultiLineData } from \"../../plots/multi-line\";\n\nexport const data: MultiLineData = {\n  min: 0,\n  max: 900,\n  ticks: [\"900\", \"600\", \"300\", \"0\"],\n  xl: { 0: \"00:00\", 6: \"06:00\", 12: \"12:00\", 18: \"18:00\", 23: \"NOW\" },\n  series: [\n    { name: \"us\", tok: \"data/cat-1\", vals: [351.69, 367.5, 357.94, 361.84, 337.24, 361.54, 342.83, 364.52, 389.61, 418.61, 430.2, 396.31, 391.24, 369.37, 354.09, 325.58, 322.95, 302.92, 317.16, 349.13, 358.92, 344.78, 369.63, 360.24] },\n    { name: \"eu\", tok: \"data/cat-2\", vals: [296.83, 325.95, 341.03, 325.62, 314.92, 340.48, 351.92, 332, 344.06, 330.38, 337.84, 345.77, 370.13, 393.56, 420, 403.24, 420, 394.04, 379.41, 380.33, 364.37, 393.03, 402.58, 393.88] },\n    { name: \"ap\", tok: \"data/cat-3\", vals: [663.08, 699.42, 657.52, 684.85, 695.66, 713.27, 717.59, 724.3, 726.07, 705.34, 696.87, 657.23, 624.65, 652.78, 638.78, 654.54, 646.87, 669.83, 661.62, 637.87, 617.63, 583.02, 575.15, 593.59] },\n    { name: \"sa\", tok: \"data/cat-4\", vals: [515.36, 492.73, 479.32, 479.15, 506.08, 468.75, 494.95, 532.85, 507.85, 529.8, 540.16, 526.15, 516.91, 551.8, 515.93, 538.69, 512.88, 532.74, 505.54, 496.82, 516.13, 484.04, 521.46, 518.06] },\n  ],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/012-multi-line/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/012-multi-line/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 012 Multi-line (Figma chart/012-multi-line): C.multiLine on p95 latency per region.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { multiLine } from \"../../plots/multi-line\";\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));\nconst r2 = (v: number) => Math.round(v * 100) / 100;\n\nconst names = [\"US-East\", \"EU-West\", \"AP-South\", \"SA-East\"];\nconst ms = (v: number) => Math.round(v);\n\n/** Hover tooltip: one region's line over the 24 hours (now, peak, low). */\nconst tip = (d: unknown, g: number): TooltipSpec => {\n  const s = (d as typeof data).series[g];\n  return {\n    kind: \"range\",\n    caps: names[g].toUpperCase() + \" · P95 · 24 H\",\n    rows: [\n      { label: \"Now\", value: ms(s.vals[s.vals.length - 1]) + \" ms\", swatch: s.tok },\n      { label: \"Peak\", value: ms(Math.max(...s.vals)) + \" ms\", swatch: s.tok },\n      { label: \"Low\", value: ms(Math.min(...s.vals)) + \" ms\", swatch: s.tok },\n    ],\n  };\n};\n\nexport const def: ChartDef = {\n  no: 12,\n  slug: \"multi-line\",\n  legend: [[\"data/cat-1\", \"US-East\"], [\"data/cat-2\", \"EU-West\"], [\"data/cat-3\", \"AP-South\"], [\"data/cat-4\", \"SA-East\"]],\n  plot: (K, p, w, d) => multiLine(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: each region drifts ±8 % on a slow swell plus ±4 % per hour, inside the 900 ms axis\n    return { ...o, series: o.series.map((s, j) => ({ ...s, vals: s.vals.map((v, i) => clamp(r2(v * (1 + 0.08 * Math.sin(i * 0.4 + step * 1.9 + j * 1.3) + 0.04 * wave(i + j * 7, step))), 20, 880)) })) };\n  },\n  describe: {\n    title: \"Latency by region\",\n    summary: `P95 time to first token per hour over the last 24 hours, 4 regions; now: ${names.map((n, j) => `${n} ${ms(data.series[j].vals[23])} ms`).join(\", \")}.`,\n    table: { head: [\"Hour\", ...names.map((n) => n + \" (ms)\")], rows: data.series[0].vals.map((_, i) => [String(i).padStart(2, \"0\") + \":00\", ...data.series.map((s) => ms(s.vals[i]))]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "change-over-time"
  ],
  "meta": {
    "access": "free",
    "no": 12,
    "family": "Change over time"
  }
}
