Files
PolyWeather/frontend/components/terminal/Sparkline.tsx

82 lines
2.0 KiB
TypeScript

"use client";
import React from "react";
interface SparklineProps {
data: number[];
color?: string;
height?: number;
width?: number;
strokeWidth?: number;
className?: string;
}
export function Sparkline({
data,
color = "#00E0A4",
height = 40,
width = 120,
strokeWidth = 2,
className = "",
}: SparklineProps) {
if (!data || data.length < 2) return <div style={{ width, height }} />;
const min = Math.min(...data);
const max = Math.max(...data);
const range = max - min || 1;
const points = data
.map((val, i) => {
const x = (i / (data.length - 1)) * width;
const y = height - ((val - min) / range) * height;
return `${x},${y}`;
})
.join(" ");
return (
<div className={className}>
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
className="overflow-visible"
>
<defs>
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="1.5" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
</defs>
<polyline
fill="none"
stroke={color}
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeLinejoin="round"
points={points}
filter="url(#glow)"
style={{ opacity: 0.8 }}
/>
{/* Fill Area */}
<path
d={`M 0 ${height} L ${points} L ${width} ${height} Z`}
fill={`url(#gradient-${color.replace("#", "")})`}
style={{ opacity: 0.1 }}
/>
<defs>
<linearGradient
id={`gradient-${color.replace("#", "")}`}
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop offset="0%" stopColor={color} />
<stop offset="100%" stopColor="transparent" />
</linearGradient>
</defs>
</svg>
</div>
);
}