import React, { useEffect, useState, useMemo } from 'react'; import { Numeric } from '../Numeric/Numeric'; import WindowLevelHistogram from './WindowLevelHistogram'; import { VOI, VOIRange, Histogram, Colormap } from './types'; interface WindowLevelProps { title?: string; step?: number; histogram: Histogram; voi: VOI; opacity?: number; showOpacitySlider?: boolean; colormap?: Colormap; style?: 'polygon' | 'bars'; fillColor?: string; lineColor?: string; containerClassName?: string; onVOIChange?: (voi: VOI) => void; onOpacityChange?: (opacity: number) => void; } const convertVOItoVOIRange = (voi: VOI): VOIRange => { return { min: voi.windowCenter - voi.windowWidth / 2, max: voi.windowCenter + voi.windowWidth / 2, }; }; const WindowLevel = ({ title, step = 1, histogram, voi: voiProp, opacity: opacityProp = 1, showOpacitySlider = false, colormap, style = 'polygon', fillColor = '#3f3f3f', lineColor = '#707070', containerClassName, onVOIChange, onOpacityChange, }: WindowLevelProps) => { // Define range from histogram const range = useMemo( () => ({ min: histogram.range.min, max: histogram.range.max, }), [histogram] ); // Initialize VOI range from props const [voiRange, setVOIRange] = useState( voiProp ? convertVOItoVOIRange(voiProp) : { min: range.min, max: range.max, } ); // Update VOI range when props change useEffect(() => { if (voiProp) { setVOIRange(convertVOItoVOIRange(voiProp)); } }, [voiProp]); // Handle VOI range changes (from slider) const handleVOIRangeChange = (newValues: [number, number]) => { const [min, max] = newValues; if (min === voiRange.min && max === voiRange.max) { return; } const windowWidth = max - min; const windowCenter = min + windowWidth / 2; setVOIRange({ min, max, }); if (onVOIChange) { onVOIChange({ windowWidth, windowCenter }); } }; // Handle opacity changes const handleOpacityChange = (value: number) => { if (onOpacityChange) { onOpacityChange(value); } }; return (
{title &&
{title}
}
{/* Range Labels */}
{range.min}
{range.max}
{/* Histogram Visualization */}
{/* Window Level Range Slider */} handleVOIRangeChange(values as [number, number])} > {/* Opacity Slider (optional) */} {showOpacitySlider && (
Opacity
handleOpacityChange(value as number)} >
)}
); }; export default WindowLevel;