'use client' import React, { useRef, useEffect, useState } from 'react' import { createColorMap, ColorMapType } from '@/lib/color-maps' interface ColorbarProps { colorMapType: ColorMapType width?: number height?: number showLabels?: boolean minValue?: number maxValue?: number unit?: string orientation?: 'horizontal' | 'vertical' } export function Colorbar({ colorMapType, width = 200, height = 20, showLabels = true, minValue = 0, maxValue = 100, unit = '', orientation = 'horizontal' }: ColorbarProps) { const canvasRef = useRef(null) const [isHovered, setIsHovered] = useState(false) const [hoverValue, setHoverValue] = useState(null) useEffect(() => { const canvas = canvasRef.current if (!canvas) return const ctx = canvas.getContext('2d') if (!ctx) return // 设置canvas尺寸 canvas.width = width canvas.height = height // 获取色标数据 const colorMap = createColorMap(colorMapType) // 绘制色标 const imageData = ctx.createImageData(width, height) if (orientation === 'horizontal') { // 水平方向:从左到右 for (let x = 0; x < width; x++) { const t = x / (width - 1) // 归一化到 0-1 const colorIndex = Math.floor(t * 255) * 4 const r = colorMap[colorIndex] const g = colorMap[colorIndex + 1] const b = colorMap[colorIndex + 2] const a = colorMap[colorIndex + 3] for (let y = 0; y < height; y++) { const pixelIndex = (y * width + x) * 4 imageData.data[pixelIndex] = r imageData.data[pixelIndex + 1] = g imageData.data[pixelIndex + 2] = b imageData.data[pixelIndex + 3] = a } } } else { // 垂直方向:从下到上 for (let y = 0; y < height; y++) { const t = (height - 1 - y) / (height - 1) // 归一化到 0-1,颠倒方向 const colorIndex = Math.floor(t * 255) * 4 const r = colorMap[colorIndex] const g = colorMap[colorIndex + 1] const b = colorMap[colorIndex + 2] const a = colorMap[colorIndex + 3] for (let x = 0; x < width; x++) { const pixelIndex = (y * width + x) * 4 imageData.data[pixelIndex] = r imageData.data[pixelIndex + 1] = g imageData.data[pixelIndex + 2] = b imageData.data[pixelIndex + 3] = a } } } ctx.putImageData(imageData, 0, 0) // 添加边框 ctx.strokeStyle = '#666' ctx.lineWidth = 1 ctx.strokeRect(0, 0, width, height) }, [colorMapType, width, height, orientation]) const handleMouseMove = (e: React.MouseEvent) => { const canvas = canvasRef.current if (!canvas) return const rect = canvas.getBoundingClientRect() let t: number if (orientation === 'horizontal') { const x = e.clientX - rect.left t = x / width } else { const y = e.clientY - rect.top t = (height - y) / height // 垂直方向:从下到上 } const value = minValue + t * (maxValue - minValue) setHoverValue(value) setIsHovered(true) } const handleMouseLeave = () => { setIsHovered(false) setHoverValue(null) } const formatValue = (value: number) => { if (unit === '%') { return `${value.toFixed(1)}%` } else if (unit === 'dBZ') { return `${value.toFixed(1)} dBZ` } else if (unit === 'mm/h') { return `${value.toFixed(1)} mm/h` } else { return value.toFixed(1) } } return (
{showLabels && ( orientation === 'horizontal' ? (
{formatValue(minValue)} {formatValue(maxValue)}
) : (
{formatValue(maxValue)} {formatValue(minValue)}
) )} {isHovered && hoverValue !== null && (
{formatValue(hoverValue)}
)}
) }