import { useState, useCallback, useEffect } from 'react' import Tree from 'react-d3-tree' import { ZoomIn, ZoomOut, Maximize2, Download } from 'lucide-react' import './PedigreeTree.css' const PedigreeTree = ({ dogId, pedigreeData, coi }) => { const [translate, setTranslate] = useState({ x: 0, y: 0 }) const [zoom, setZoom] = useState(0.8) const [dimensions, setDimensions] = useState({ width: 0, height: 0 }) useEffect(() => { const updateDimensions = () => { const container = document.getElementById('tree-container') if (container) { setDimensions({ width: container.offsetWidth, height: container.offsetHeight }) setTranslate({ x: container.offsetWidth / 4, y: container.offsetHeight / 2 }) } } updateDimensions() window.addEventListener('resize', updateDimensions) return () => window.removeEventListener('resize', updateDimensions) }, []) const handleZoomIn = () => setZoom(z => Math.min(z + 0.2, 2)) const handleZoomOut = () => setZoom(z => Math.max(z - 0.2, 0.2)) const handleReset = () => { setZoom(0.8) setTranslate({ x: dimensions.width / 4, y: dimensions.height / 2 }) } const renderCustomNode = ({ nodeDatum, toggleNode }) => { const isMale = nodeDatum.attributes?.sex === 'male' const nodeColor = isMale ? '#3b82f6' : '#ec4899' return ( { if (nodeDatum.attributes?.id) { window.location.href = `/dogs/${nodeDatum.attributes.id}` } }} /> {isMale ? '♂' : '♀'} {nodeDatum.name} {nodeDatum.attributes?.registration && ( {nodeDatum.attributes.registration} )} {nodeDatum.attributes?.birth_year && ( ({nodeDatum.attributes.birth_year}) )} ) } return (
{coi !== null && coi !== undefined && (
COI: 10 ? 'high' : coi > 5 ? 'medium' : 'low'}`}> {coi.toFixed(2)}%
)}
Male
Female
{pedigreeData && dimensions.width > 0 && ( { setZoom(zoom) setTranslate(translate) }} orientation="horizontal" pathFunc="step" separation={{ siblings: 1.5, nonSiblings: 2 }} nodeSize={{ x: 200, y: 150 }} renderCustomNodeElement={renderCustomNode} enableLegacyTransitions transitionDuration={300} /> )}
) } export default PedigreeTree