import React from 'react' ; import { almostShallowEqual } from '../utils' ; import { fromRmfCoords } from '../utils/geometry' ; import { useAutoScale } from './hooks' ; import { SVGOverlay , SVGOverlayProps } from './svg-overlay' ; import { viewBoxFromLeafletBounds } from './utils' ; import { withLabel } from './with-label' ; import { WorkcellMarker as WorkcellMarker_ , WorkcellMarkerProps } from './workcell-marker' ; interface BoundedMarkerProps extends Omit < WorkcellMarkerProps , 'onClick' > { guid : string ; onClick ? : ( ev : React . MouseEvent , guid : string ) => void ; } /**
 * Bind a marker to include the guid in the click event.
 * This is needed to avoid re-rendering all markers when only one of them changes.
 */ function bindMarker ( MarkerComponent ) { return ( { guid , onClick , ... otherProps } ) => { const handleClick = React . useCallback ( ( ev ) => onClick && onClick ( ev , guid ) , [ onClick , guid ] ) ; return < MarkerComponent onClick = { onClick && handleClick } { ... otherProps } />; } ; } const WorkcellMarker = React . memo ( withLabel ( bindMarker ( WorkcellMarker_ ) ) , ( prev , next ) => almostShallowEqual ( prev , next , [ 'style' ] ) ) ; export interface WorkcellData { guid : string ; location : [ x : number , y : number ] ; iconPath ? : string ; } export interface WorkcellsOverlayProps extends Omit < SVGOverlayProps , 'viewBox' > { workcells : WorkcellData [ ] ; actualSizeMinZoom ? : number ; hideLabels ? : boolean ; onWorkcellClick ? : ( event : React . MouseEvent , guid : string ) => void ; } export const WorkcellsOverlay = ( { workcells , hideLabels = false , onWorkcellClick , ... otherProps } ) : JSX . Element => { const viewBox = viewBoxFromLeafletBounds ( otherProps . bounds ) ; const scale = useAutoScale ( 40 ) ; return ( < SVGOverlay viewBox = { viewBox } { ... otherProps } > { workcells . map ( ( workcell ) => { const [ x , y ] = fromRmfCoords ( workcell . location ) ; return ( < g key = { workcell . guid } > < WorkcellMarker cx = { x } cy = { y } size = { 1 } guid = { workcell . guid } iconPath = { workcell . iconPath } onClick = { onWorkcellClick } aria - label = { workcell . guid } style = { { transform : `scale(${ scale })` , transformOrigin : `${ x }px ${ y }px` } } labelText = { workcell . guid } labelSourceX = { x } labelSourceY = { y } labelSourceRadius = { 0.5 * scale } hideLabel = { hideLabels } / > < /g>); } ) } < /SVGOverlay>); } ; export default WorkcellsOverlay ;