style: replace dotted chart background with grid line pattern

Swap the old dot grid overlay inside the Recharts SVG for a GridPattern
component rendered behind the chart card. Uses a vertical mask gradient
to fade edges for a cleaner look.
This commit is contained in:
Usman Baig
2026-03-13 12:55:20 +01:00
parent 8c4bb8f861
commit eb0dc4a27b
3 changed files with 82 additions and 13 deletions

View File

@@ -11,6 +11,7 @@ import { Checkbox } from '@ciphera-net/ui'
import { ArrowUpRight, ArrowDownRight } from '@phosphor-icons/react'
import { motion } from 'framer-motion'
import { cn } from '@/lib/utils'
import { GridPattern } from '@/components/ui/grid-pattern'
const ANNOTATION_COLORS: Record<string, string> = {
deploy: '#3b82f6',
@@ -338,7 +339,14 @@ export default function Chart({
return (
<div ref={chartContainerRef} className="relative">
<Card className="w-full overflow-hidden rounded-2xl">
<Card className="w-full overflow-hidden rounded-2xl relative">
<GridPattern
width={30}
height={30}
x={-1}
y={-1}
className="fill-neutral-400/5 stroke-neutral-400/10 dark:fill-neutral-500/5 dark:stroke-neutral-500/10 [mask-image:linear-gradient(to_bottom,transparent,white_30%,white_70%,transparent)]"
/>
<CardHeader className="p-0 mb-0">
{/* Metrics Grid - 21st.dev style */}
<div className="grid grid-cols-2 md:grid-cols-4 grow w-full">
@@ -462,9 +470,6 @@ export default function Chart({
style={{ overflow: 'visible' }}
>
<defs>
<pattern id="dotGrid" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="1" fill="var(--chart-grid)" fillOpacity="1" />
</pattern>
<filter id="lineShadow" x="-100%" y="-100%" width="300%" height="300%">
<feDropShadow
dx="4"
@@ -501,15 +506,6 @@ export default function Chart({
<ChartTooltip content={<CustomTooltip metric={metric} />} cursor={{ strokeDasharray: '3 3', stroke: '#9ca3af' }} />
{/* Background dot grid pattern */}
<rect
x="60px"
y="-20px"
width="calc(100% - 75px)"
height="calc(100% - 10px)"
fill="url(#dotGrid)"
style={{ pointerEvents: 'none' }}
/>
{/* Annotation reference lines */}
{visibleAnnotationMarkers.map((marker) => {

View File

@@ -0,0 +1,72 @@
import { useId } from "react";
import { cn } from "@/lib/utils";
interface GridPatternProps {
width?: number;
height?: number;
x?: number;
y?: number;
squares?: Array<[x: number, y: number]>;
strokeDasharray?: string;
className?: string;
[key: string]: unknown;
}
function GridPattern({
width = 40,
height = 40,
x = -1,
y = -1,
strokeDasharray = "0",
squares,
className,
...props
}: GridPatternProps) {
const id = useId();
return (
<svg
aria-hidden="true"
className={cn(
"pointer-events-none absolute inset-0 h-full w-full fill-gray-400/30 stroke-gray-400/30",
className,
)}
{...props}
>
<defs>
<pattern
id={id}
width={width}
height={height}
patternUnits="userSpaceOnUse"
x={x}
y={y}
>
<path
d={`M.5 ${height}V.5H${width}`}
fill="none"
strokeDasharray={strokeDasharray}
/>
</pattern>
</defs>
<rect width="100%" height="100%" strokeWidth={0} fill={`url(#${id})`} />
{squares && (
<svg x={x} y={y} className="overflow-visible">
{squares.map(([x, y]) => (
<rect
strokeWidth="0"
key={`${x}-${y}`}
width={width - 1}
height={height - 1}
x={x * width + 1}
y={y * height + 1}
/>
))}
</svg>
)}
</svg>
);
}
export { GridPattern };