{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "isometric-bar-chart",
  "description": "Bar chart with isometric 3D-extruded bars and a highlighted max value",
  "dependencies": [
    "recharts",
    "motion"
  ],
  "registryDependencies": [
    "@evilcharts/recharts-chart"
  ],
  "files": [
    {
      "path": "src/registry/blocks/recharts/b-isometric-bar-chart.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Bar, BarChart, XAxis, YAxis } from \"recharts\";\nimport { motion } from \"motion/react\";\nimport { type ChartConfig, ChartContainer } from \"@/registry/ui/recharts-chart\";\nimport { ChartTooltip, ChartTooltipContent } from \"@/registry/ui/recharts-tooltip\";\n\nconst chartData = [\n  { month: \"January\", revenue: 28 },\n  { month: \"February\", revenue: 34 },\n  { month: \"March\", revenue: 22 },\n  { month: \"April\", revenue: 41 },\n  { month: \"May\", revenue: 47 },\n  { month: \"June\", revenue: 31 },\n  { month: \"July\", revenue: 38 },\n];\n\nconst chartConfig = {\n  revenue: {\n    label: \"Revenue\",\n    colors: {\n      light: [\"#18181b\"],\n      dark: [\"#fafafa\"],\n    },\n  },\n} satisfies ChartConfig;\n\nconst DX = 10;\nconst DY = 10;\n\nconst BEVEL_OPACITY = 0.55;\n\nconst FILLED = true;\n\nconst DIRECTION: \"left\" | \"right\" = \"right\";\n\nconst HIGHLIGHT_COLOR = \"#22c55e\";\nconst HIGHLIGHT_COLOR_DARK = \"#15803d\";\n\ninterface ShapeProps {\n  x?: number;\n  y?: number;\n  width?: number;\n  height?: number;\n  index?: number;\n  payload?: { month: string; revenue: number };\n}\n\nfunction IsoBar({\n  x,\n  y,\n  width,\n  height,\n  index,\n  payload,\n  maxValue,\n  idPrefix,\n}: ShapeProps & { maxValue: number; idPrefix: string }) {\n  const bx = Number(x ?? 0);\n  const by = Number(y ?? 0);\n  const bw = Number(width ?? 0);\n  const bh = Number(height ?? 0);\n\n  if (bh <= 0) return null;\n\n  const highlight = payload?.revenue === maxValue;\n  const dx = DIRECTION === \"left\" ? -DX : DX;\n  const sideX = DIRECTION === \"left\" ? bx : bx + bw;\n  const topPoints = `${bx},${by} ${bx + bw},${by} ${bx + bw + dx},${by - DY} ${bx + dx},${by - DY}`;\n  const sidePoints = `${sideX},${by} ${sideX + dx},${by - DY} ${sideX + dx},${by + bh - DY} ${sideX},${by + bh}`;\n\n  // Gradient/pattern ids are namespaced per chart instance so multiple\n  // charts on the same page don't share (and clobber) each other's <defs>.\n  const url = (name: string) => `url(#${idPrefix}-${name})`;\n\n  const strokeColor = highlight ? HIGHLIGHT_COLOR_DARK : \"var(--color-accent)\";\n\n  const frontFill = FILLED\n    ? highlight\n      ? url(\"iso-front-accent\")\n      : url(\"iso-front-base\")\n    : \"none\";\n  const topFill = FILLED\n    ? highlight\n      ? url(\"iso-top-accent\")\n      : url(\"iso-top-base\")\n    : \"none\";\n  const rightFill = FILLED\n    ? highlight\n      ? url(\"iso-right-accent\")\n      : url(\"iso-right-base\")\n    : \"none\";\n  const hatchFill = highlight ? url(\"iso-hatch-accent\") : url(\"iso-hatch-base\");\n\n  return (\n    <motion.g\n      initial={{ scaleY: 0, opacity: 0 }}\n      animate={{ scaleY: 1, opacity: 1 }}\n      transition={{\n        duration: 0.7,\n        delay: (index ?? 0) * 0.08,\n        ease: [0.16, 1, 0.3, 1],\n      }}\n      style={{ transformBox: \"fill-box\", transformOrigin: \"50% 100%\" }}\n    >\n      <polygon\n        points={sidePoints}\n        fill={rightFill}\n        stroke={strokeColor}\n        strokeWidth={FILLED ? 0 : 1}\n      />\n      <polygon\n        points={topPoints}\n        fill={topFill}\n        stroke={strokeColor}\n        strokeWidth={FILLED ? 0 : 1}\n      />\n      <rect\n        x={bx}\n        y={by}\n        width={bw}\n        height={bh}\n        fill={frontFill}\n        stroke={strokeColor}\n        strokeWidth={FILLED ? 0 : 1}\n      />\n      {FILLED && (\n        <rect x={bx} y={by} width={bw} height={bh} fill={hatchFill} />\n      )}\n      {FILLED && highlight && (\n        <rect x={bx} y={by} width={2} height={bh} fill=\"rgba(0,0,0,0.15)\" />\n      )}\n    </motion.g>\n  );\n}\n\nfunction IsoBarDefs({ idPrefix }: { idPrefix: string }) {\n  return (\n    <defs>\n      <linearGradient id={`${idPrefix}-iso-front-base`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n        <stop offset=\"0%\" stopColor=\"var(--color-accent)\" stopOpacity={1} />\n        <stop offset=\"100%\" stopColor=\"var(--color-accent)\" stopOpacity={0.8} />\n      </linearGradient>\n      <linearGradient id={`${idPrefix}-iso-top-base`} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\">\n        <stop offset=\"0%\" stopColor=\"var(--color-accent)\" stopOpacity={BEVEL_OPACITY} />\n        <stop offset=\"100%\" stopColor=\"var(--color-accent)\" stopOpacity={BEVEL_OPACITY * 0.9} />\n      </linearGradient>\n      <linearGradient id={`${idPrefix}-iso-right-base`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n        <stop offset=\"0%\" stopColor=\"var(--color-accent)\" stopOpacity={BEVEL_OPACITY * 0.7} />\n        <stop offset=\"100%\" stopColor=\"var(--color-accent)\" stopOpacity={BEVEL_OPACITY * 0.55} />\n      </linearGradient>\n\n      <linearGradient id={`${idPrefix}-iso-front-accent`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n        <stop offset=\"0%\" stopColor={HIGHLIGHT_COLOR} stopOpacity={1} />\n        <stop offset=\"100%\" stopColor={HIGHLIGHT_COLOR_DARK} stopOpacity={0.95} />\n      </linearGradient>\n      <linearGradient id={`${idPrefix}-iso-top-accent`} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\">\n        <stop offset=\"0%\" stopColor={HIGHLIGHT_COLOR} stopOpacity={BEVEL_OPACITY + 0.15} />\n        <stop offset=\"100%\" stopColor={HIGHLIGHT_COLOR} stopOpacity={BEVEL_OPACITY} />\n      </linearGradient>\n      <linearGradient id={`${idPrefix}-iso-right-accent`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n        <stop offset=\"0%\" stopColor={HIGHLIGHT_COLOR_DARK} stopOpacity={BEVEL_OPACITY + 0.05} />\n        <stop offset=\"100%\" stopColor={HIGHLIGHT_COLOR_DARK} stopOpacity={BEVEL_OPACITY * 0.7} />\n      </linearGradient>\n\n      <pattern\n        id={`${idPrefix}-iso-hatch-base`}\n        patternUnits=\"userSpaceOnUse\"\n        width=\"6\"\n        height=\"6\"\n        patternTransform=\"rotate(45)\"\n      >\n        <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"6\" stroke=\"currentColor\" strokeWidth=\"1\" strokeOpacity=\"0.15\" />\n      </pattern>\n      <pattern\n        id={`${idPrefix}-iso-hatch-accent`}\n        patternUnits=\"userSpaceOnUse\"\n        width=\"6\"\n        height=\"6\"\n        patternTransform=\"rotate(45)\"\n      >\n        <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"6\" stroke={HIGHLIGHT_COLOR_DARK} strokeWidth=\"1\" strokeOpacity=\"0.15\" />\n      </pattern>\n    </defs>\n  );\n}\n\nexport function EvilIsometricBarChart() {\n  // Namespaces this instance's <defs> ids so several charts can coexist on a page.\n  const idPrefix = React.useId().replace(/:/g, \"\");\n\n  const maxValue = React.useMemo(\n    () => chartData.reduce((m, d) => (d.revenue > m ? d.revenue : m), 0),\n    [],\n  );\n  const total = chartData.reduce((sum, d) => sum + d.revenue, 0);\n  const peak = chartData.find((d) => d.revenue === maxValue)!;\n\n  return (\n    <div className=\"flex h-full w-full flex-col p-4\">\n      <div className=\"flex flex-row justify-between\">\n        <div className=\"flex flex-row\">\n          <div className=\"flex flex-col gap-2\">\n            <span className=\"text-muted-foreground font-mono text-xs\">{\"[$] Total\"}</span>\n            <span className=\"text-primary font-mono text-3xl\">\n              <span className=\"text-muted-foreground text-xl font-normal\">$</span>\n              <span className=\"tracking-tighter\">{total}K</span>\n            </span>\n          </div>\n          <hr className=\"mx-4 h-full border-l border-dashed\" />\n          <div className=\"flex flex-col gap-2\">\n            <span className=\"text-muted-foreground font-mono text-xs\">{\"[⬆] Peak\"}</span>\n            <span className=\"text-primary font-mono text-3xl tracking-tighter\">\n              {peak.month.slice(0, 3)}\n            </span>\n          </div>\n        </div>\n        <div className=\"flex flex-col justify-end gap-1\">\n          <span className=\"text-muted-foreground font-mono text-[10px]\">\n            {\"// PROJECTION: \"}\n            <span className=\"text-primary\">ISOMETRIC</span>\n          </span>\n          <span className=\"text-muted-foreground font-mono text-[10px]\">\n            {\"// HIGHLIGHT: \"}\n            <span className=\"text-primary\">MAX</span>\n          </span>\n        </div>\n      </div>\n      <hr className=\"my-4 border-t border-dashed\" />\n      <ChartContainer config={chartConfig}>\n        <BarChart\n          accessibilityLayer\n          data={chartData}\n          margin={{ top: 30, right: 30, left: 0, bottom: 0 }}\n          barCategoryGap=\"25%\"\n        >\n          <IsoBarDefs idPrefix={idPrefix} />\n          <XAxis\n            dataKey=\"month\"\n            tickLine={false}\n            tickMargin={10}\n            axisLine={false}\n            tickFormatter={(value: string) => value.slice(0, 3)}\n          />\n          <YAxis hide domain={[0, \"dataMax + 10\"]} />\n          <ChartTooltip\n            cursor={false}\n            content={\n              <ChartTooltipContent\n                formatter={(value, name) => (\n                  <div className=\"flex flex-1 items-center gap-2\">\n                    <div\n                      className=\"size-2.5 shrink-0 rounded-[2px]\"\n                      style={{ background: \"var(--color-revenue-0)\" }}\n                    />\n                    <span className=\"text-muted-foreground flex-1 capitalize\">{name}</span>\n                    <span className=\"text-foreground font-mono font-medium tabular-nums\">\n                      ${value}K\n                    </span>\n                  </div>\n                )}\n              />\n            }\n          />\n          <Bar\n            dataKey=\"revenue\"\n            isAnimationActive={false}\n            shape={(props: unknown) => (\n              <IsoBar {...(props as ShapeProps)} maxValue={maxValue} idPrefix={idPrefix} />\n            )}\n          />\n        </BarChart>\n      </ChartContainer>\n    </div>\n  );\n}\n",
      "type": "registry:block",
      "target": "components/evilcharts/blocks/isometric-bar-chart.tsx"
    }
  ],
  "type": "registry:block"
}