|
|
import React from 'react'; |
|
|
|
|
|
interface FeatureMapProps { |
|
|
size: number; |
|
|
data?: number[][]; |
|
|
highlightPosition?: { x: number; y: number } | null; |
|
|
className?: string; |
|
|
colorIntensity?: boolean; |
|
|
} |
|
|
|
|
|
const FeatureMap: React.FC<FeatureMapProps> = ({ |
|
|
size, |
|
|
data, |
|
|
highlightPosition = null, |
|
|
className = '', |
|
|
colorIntensity = false, |
|
|
}) => { |
|
|
|
|
|
const mapData = data || Array(size) |
|
|
.fill(0) |
|
|
.map(() => Array(size).fill(0).map(() => Math.random() * 0.8)); |
|
|
|
|
|
return ( |
|
|
<div className={`grid gap-[1px] ${className}`} style={{ gridTemplateColumns: `repeat(${size}, 1fr)` }}> |
|
|
{mapData.map((row, rowIndex) => |
|
|
row.map((value, colIndex) => { |
|
|
const isHighlighted = highlightPosition?.x === colIndex && highlightPosition?.y === rowIndex; |
|
|
|
|
|
// Determine cell color based on value |
|
|
let bgColor = 'bg-gray-800'; |
|
|
let borderColor = 'border-gray-700'; |
|
|
|
|
|
if (colorIntensity) { |
|
|
// For intensity values |
|
|
const intensity = Math.floor(value * 255); |
|
|
if (value > 0) { |
|
|
bgColor = `bg-blue-900/60`; |
|
|
const opacity = Math.max(20, Math.min(80, value * 100)); |
|
|
bgColor = `bg-blue-500/${Math.floor(opacity)}`; |
|
|
} else if (value < 0) { |
|
|
bgColor = `bg-red-900/60`; |
|
|
const opacity = Math.max(20, Math.min(80, Math.abs(value) * 100)); |
|
|
bgColor = `bg-red-500/${Math.floor(opacity)}`; |
|
|
} |
|
|
} |
|
|
|
|
|
return ( |
|
|
<div |
|
|
key={`${rowIndex}-${colIndex}`} |
|
|
className={` |
|
|
aspect-square ${bgColor} border ${borderColor} flex items-center justify-center text-[0.5rem] text-gray-400 |
|
|
${isHighlighted ? 'ring-2 ring-cyan-500 ring-offset-1 ring-offset-transparent z-10' : ''} |
|
|
`} |
|
|
> |
|
|
{value.toFixed(1)} |
|
|
</div> |
|
|
); |
|
|
}) |
|
|
)} |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|
|
|
export default FeatureMap; |