{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "drift-arrows",
  "type": "registry:component",
  "title": "Drift arrows",
  "description": "How far each part drifted from its target. Sample data: six assets against target, US equity +3.0 pt, intl equity −4.0 pt.",
  "registryDependencies": [
    "@chartory/core",
    "@chartory/plot-drift-arrows"
  ],
  "files": [
    {
      "path": "registry/chartory/components/drift-arrows.tsx",
      "type": "registry:component",
      "target": "components/chartory/drift-arrows.tsx",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// Drift arrows (Chartory chart 089): 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/drift-arrows\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/089-drift-arrows/data\"\nimport { def } from \"@/lib/chartory/charts/types/089-drift-arrows/layout\"\n\nregisterChart(def, sample)\n\nexport type DriftArrowsData = typeof sample\nexport type DriftArrowsProps = Omit<ChartViewProps, \"def\" | \"data\" | \"states\"> & {\n  /** the data to draw (default: the sample) */\n  data?: DriftArrowsData\n  /** further data states: the chart morphs to them (update) or ticks through them (live, with interval) */\n  states?: DriftArrowsData[]\n}\n\nexport function DriftArrows(props: DriftArrowsProps) {\n  return <ChartView def={def} {...props} />\n}\n"
    },
    {
      "path": "registry/chartory/charts/types/089-drift-arrows/data.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/089-drift-arrows/data.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 089 Allocation drift · sample data (Figma chart/089-drift-rebalance).\nimport type { DriftArrowsData } from \"../../plots/drift-arrows\";\n\nexport const data: DriftArrowsData = {\n  max: 40,\n  xt: [[0, \"0\"], [10, \"10%\"], [20, \"20%\"], [30, \"30%\"], [40, \"40%\"]],\n  rows: [{ label: \"US equity\", now: 38, target: 35 }, { label: \"Intl equity\", now: 14, target: 18 }, { label: \"Bonds\", now: 26, target: 28 }, { label: \"Real estate\", now: 8, target: 7 }, { label: \"Gold\", now: 6, target: 5 }, { label: \"Cash\", now: 8, target: 7 }],\n};\n"
    },
    {
      "path": "registry/chartory/charts/types/089-drift-arrows/layout.ts",
      "type": "registry:lib",
      "target": "lib/chartory/charts/types/089-drift-arrows/layout.ts",
      "content": "// SPDX-License-Identifier: MIT · Copyright (c) 2026 BEY AGENCY LTD · Chartory, usechartory.com\n// 089 Drift arrows (Figma chart/089-drift-rebalance): C.driftArrows, current weight to target per asset class.\nimport type { ChartDef, TooltipSpec } from \"../../core/shell\";\nimport { driftArrows } from \"../../plots/drift-arrows\";\nimport { data } from \"./data\";\n\nconst drift = (r: { now: number; target: number }) => (r.now - r.target > 0 ? \"+\" : \"−\") + Math.abs(r.now - r.target).toFixed(1);\n\n// drift (pt) per step for each asset class; they sum to 0 (targets and weights both sum to 100), and each stays in the\n// band where its arrow shows or hides at every size as in the sample (1 pt rows 0.7–0.9, the 2 pt row 1.9–2.0)\nconst DRIFT = [[3.7, -4.2, -1.9, 0.8, 0.7, 0.9], [4.4, -4.8, -2, 0.7, 0.9, 0.8], [2.9, -3.4, -1.9, 0.9, 0.8, 0.7]];\n/** A later month: the portfolio drifts again from the same targets. */\nfunction update(d0: unknown, step: number): typeof data {\n  const d = d0 as typeof data;\n  const dr = DRIFT[(step - 1) % DRIFT.length];\n  return { ...d, rows: d.rows.map((r, i) => ({ ...r, now: +(r.target + dr[i]).toFixed(1) })) };\n}\n\n/** Hover: one asset class (dot, arrow, drift): current weight against its target. */\nfunction tip(d0: unknown, g: number): TooltipSpec | null {\n  const r = (d0 as typeof data).rows[g];\n  if (!r) return null;\n  const dv = r.now - r.target;\n  return { kind: \"compare\", caps: r.label.toUpperCase(), value: r.now + \"%\", delta: { text: drift(r) + \" pt\", tone: Math.abs(dv) < 0.6 ? \"neutral\" : dv > 0 ? \"warning\" : \"info\" }, comparison: `VS TARGET ${r.target}%` };\n}\n\nexport const def: ChartDef = {\n  no: 89,\n  slug: \"drift-arrows\",\n  legend: [[\"status/warning\", \"Overweight\"], [\"status/info\", \"Underweight\"], [\"text/strong\", \"Target\"]],\n  plot: (K, p, w, d) => driftArrows(K, p, w, (d as typeof data | undefined) ?? data),\n  tip,\n  update,\n  describe: {\n    title: \"Allocation drift\",\n    summary: `Current weight against target for ${data.rows.length} asset classes: ${data.rows.map((r) => `${r.label} ${r.now}% (target ${r.target}%)`).join(\", \")}.`,\n    table: { head: [\"Asset\", \"Now (%)\", \"Target (%)\", \"Drift (pt)\"], rows: data.rows.map((r) => [r.label, r.now, r.target, drift(r)]) },\n  },\n};\n"
    }
  ],
  "categories": [
    "charts",
    "space-and-place"
  ],
  "meta": {
    "access": "free",
    "no": 89,
    "family": "Space and place"
  }
}
