{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"c-chart-11","type":"registry:block","title":"Animated monochrome bar chart","description":"Animated monochrome bar chart","dependencies":["cn","motion","recharts"],"registryDependencies":["@reui/badge","card","chart"],"files":[{"path":"c-chart-11.tsx","type":"registry:block","content":"\"use client\"\n\nimport { CSSProperties, SVGProps, useMemo, useState } from \"react\"\nimport { Badge } from \"@/components/reui/badge\"\nimport { motion } from \"motion/react\"\nimport { Bar, BarChart, XAxis } from \"recharts\"\n\nimport { cn } from \"cn\"\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ui/card\"\nimport {\n  ChartConfig,\n  ChartContainer,\n  ChartTooltip,\n  ChartTooltipContent,\n} from \"@/components/ui/chart\"\nimport { IconPlaceholder } from \"@/app/(create)/components/icon-placeholder\"\n\ninterface CustomBarProps extends SVGProps<SVGSVGElement> {\n  setActiveIndex: (index?: number) => void\n  index?: number\n  activeIndex?: number\n  value?: string\n}\n\nconst CustomBar = (props: CustomBarProps) => {\n  const { fill, x, y, width, height, index, activeIndex, value } = props\n\n  // Custom variables\n  const xPos = Number(x || 0)\n  const realWidth = Number(width || 0)\n  const isActive = index === activeIndex\n  const collapsedWidth = 6\n  // centered bar x-position\n  const barX = isActive ? xPos : xPos + (realWidth - collapsedWidth) / 2\n  // centered text x-position\n  const textX = xPos + realWidth / 2\n\n  // Custom bar shape\n  return (\n    <g onMouseEnter={() => props.setActiveIndex(index)}>\n      {/* rendering the bar with custom position and animated width */}\n      <motion.rect\n        style={{\n          willChange: \"transform, width\", // helps with performance\n        }}\n        y={y}\n        initial={{ width: collapsedWidth, x: barX }}\n        animate={{ width: isActive ? realWidth : collapsedWidth, x: barX }}\n        transition={{\n          duration: activeIndex === index ? 0.5 : 1,\n          type: \"spring\",\n        }}\n        height={height}\n        fill={fill}\n        rx=\"3\"\n      />\n      {/* Render value text on top of bar */}\n      {isActive && (\n        <motion.text\n          style={{\n            willChange: \"transform, opacity\", // helps with performance\n          }}\n          className=\"font-mono\"\n          key={index}\n          initial={{ opacity: 0, y: -10, filter: \"blur(3px)\" }}\n          animate={{ opacity: 1, y: 0, filter: \"blur(0px)\" }}\n          exit={{ opacity: 0, y: -10, filter: \"blur(3px)\" }}\n          transition={{ duration: 0.1 }}\n          x={textX}\n          y={Number(y) - 5}\n          textAnchor=\"middle\"\n          fill={fill}\n        >\n          {value}\n        </motion.text>\n      )}\n    </g>\n  )\n}\n\nconst chartData = [\n  { month: \"January\", desktop: 289 },\n  { month: \"February\", desktop: 345 },\n  { month: \"March\", desktop: 412 },\n  { month: \"April\", desktop: 478 },\n  { month: \"May\", desktop: 534 },\n  { month: \"June\", desktop: 456 },\n  { month: \"July\", desktop: 523 },\n  { month: \"August\", desktop: 589 },\n  { month: \"September\", desktop: 467 },\n  { month: \"October\", desktop: 398 },\n  { month: \"November\", desktop: 356 },\n  { month: \"December\", desktop: 423 },\n]\n\nconst chartConfig = {\n  desktop: {\n    label: \"Desktop\",\n    color: \"var(--chart-4)\",\n  },\n} satisfies ChartConfig\n\nexport function Pattern() {\n  const [activeIndex, setActiveIndex] = useState<number | undefined>(undefined)\n\n  const activeData = useMemo(() => {\n    if (activeIndex === undefined) return null\n    return chartData[activeIndex]\n  }, [activeIndex])\n\n  return (\n    <Card className=\"w-full max-w-md\">\n      <CardHeader>\n        <CardTitle className=\"flex items-center gap-2\">\n          Conversion Rates\n          <span className={cn(\"ml-auto font-mono text-xl tracking-tighter\")}>\n            ${activeData ? activeData.desktop : \"123\"}\n          </span>\n          <Badge variant=\"success-light\">\n            <IconPlaceholder\n              lucide=\"TrendingUpIcon\"\n              tabler=\"IconTrendingUp\"\n              hugeicons=\"TradeUpIcon\"\n              phosphor=\"TrendUpIcon\"\n              remixicon=\"RiArrowRightUpLongLine\"\n              aria-hidden=\"true\"\n            />\n            <span>5.2%</span>\n          </Badge>\n        </CardTitle>\n        <CardDescription>Real-time funnel conversion tracking</CardDescription>\n      </CardHeader>\n      <CardContent>\n        <ChartContainer config={chartConfig}>\n          <BarChart\n            accessibilityLayer\n            data={chartData}\n            onMouseLeave={() => setActiveIndex(undefined)}\n            margin={{\n              top: 20,\n              right: 12,\n              bottom: 12,\n              left: 12,\n            }}\n          >\n            <XAxis\n              dataKey=\"month\"\n              tickLine={false}\n              tickMargin={10}\n              axisLine={false}\n              tickFormatter={(value) => value.slice(0, 3)}\n            />\n            <ChartTooltip\n              cursor={false}\n              content={\n                <ChartTooltipContent\n                  indicator=\"dot\"\n                  className=\"min-w-40 gap-2.5\"\n                  labelFormatter={(value) => {\n                    return (\n                      <div className=\"border-border/50 mb-0.5 flex flex-col gap-0.5 border-b pb-2\">\n                        <span className=\"text-xs font-medium\">\n                          {value} 2024\n                        </span>\n                      </div>\n                    )\n                  }}\n                  formatter={(value, name) => (\n                    <div className=\"flex w-full items-center justify-between gap-2\">\n                      <div className=\"flex items-center gap-1.5\">\n                        <div\n                          className=\"h-2.5 w-2.5 shrink-0 rounded-xs bg-(--color-bg)\"\n                          style={\n                            {\n                              \"--color-bg\": `var(--color-${name})`,\n                            } as CSSProperties\n                          }\n                        />\n                        <span className=\"text-muted-foreground\">\n                          {chartConfig[name as keyof typeof chartConfig]\n                            ?.label || name}\n                        </span>\n                      </div>\n                      <span className=\"text-foreground font-semibold\">\n                        {Number(value).toLocaleString()}\n                      </span>\n                    </div>\n                  )}\n                />\n              }\n            />\n            <Bar\n              dataKey=\"desktop\"\n              fill=\"var(--color-desktop)\"\n              shape={\n                <CustomBar\n                  setActiveIndex={setActiveIndex}\n                  activeIndex={activeIndex}\n                />\n              }\n            />\n          </BarChart>\n        </ChartContainer>\n      </CardContent>\n    </Card>\n  )\n}","target":"components/examples/c-chart-11.tsx"}],"meta":{"order":11}}