I’m currently working on a React component where I have two sets of boxes on the left and right sides of the screen. The user can select one box from each side and click a “Connect” button to draw a line between the selected boxes. However, I’m facing an issue where the line is not aligning properly between the selected boxes. Specifically, when I select the first box from the left side and the first box from the right side, the line is drawn between the boxes, but they are not aligned correctly – the starting and ending lines do not touch the edges of the boxes.
I’ve attempted to calculate and position the connection line, but it’s not working as expected. I’ve tried adjusting the positioning and calculations, but I’m still encountering the misalignment issue.
find Issue here
Issue 2
import React, { useState, useLayoutEffect, useRef } from 'react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Radio from '@mui/material/Radio';
import FormControlLabel from '@mui/material/FormControlLabel';
import RadioGroup from '@mui/material/RadioGroup';
import Button from '@mui/material/Button';
const theme = createTheme({
palette: {
primary: {
main: '#1976d2'
}
}
});
const UI_OPTIONS_LEFT = [ 'Protopie', 'Unity', 'QT', 'Figma' ];
const UI_OPTIONS_RIGHT = [ 'VRED', 'Unreal Engine' ];
export default function Flowchart() {
const [ leftSelected, setLeftSelected ] = useState('');
const [ rightSelected, setRightSelected ] = useState('');
const [ isConnectEnabled, setIsConnectEnabled ] = useState(false);
const [ showConnector, setShowConnector ] = useState(false);
const [ connectorPosition, setConnectorPosition ] = useState({ x1: 0, y1: 0, x2: 0, y2: 0 });
const connectorRef = useRef(null);
useLayoutEffect(
() => {
setIsConnectEnabled(!!leftSelected && !!rightSelected);
},
[ leftSelected, rightSelected ]
);
const handleLeftChange = (event) => {
setLeftSelected(event.target.value);
};
const handleRightChange = (event) => {
setRightSelected(event.target.value);
};
const handleConnectClick = () => {
if (isConnectEnabled) {
const leftBox = document.querySelector(`#left-${leftSelected.replace(/s+/g, '-')}`);
const rightBox = document.querySelector(`#right-${rightSelected.replace(/s+/g, '-')}`);
if (leftBox && rightBox) {
const leftBoxRect = leftBox.getBoundingClientRect();
const rightBoxRect = rightBox.getBoundingClientRect();
const containerRect = document.querySelector('#connector-container').getBoundingClientRect();
const x1 = leftBoxRect.right - containerRect.left;
const y1 = leftBoxRect.top + leftBoxRect.height / 2 - containerRect.top;
const x2 = rightBoxRect.left - containerRect.left;
const y2 = rightBoxRect.top + rightBoxRect.height / 2 - containerRect.top;
setConnectorPosition({ x1, y1, x2, y2 });
setShowConnector(true);
}
}
};
return (
<ThemeProvider theme={theme}>
<Box display="flex" flexDirection="column" alignItems="center" width="100%" position="relative">
<Typography variant="h5" mb={4}>
Select UI Flow
</Typography>
<Box id="connector-container" display="flex" flex={1} mb={4} position="relative" width="100%">
<OptionsBox
options={UI_OPTIONS_LEFT}
selected={leftSelected}
onChange={handleLeftChange}
idPrefix="left-"
/>
<OptionsBox
options={UI_OPTIONS_RIGHT}
selected={rightSelected}
onChange={handleRightChange}
idPrefix="right-"
/>
{showConnector && (
<ConnectorLine
ref={connectorRef}
x1={connectorPosition.x1}
y1={connectorPosition.y1}
x2={connectorPosition.x2}
y2={connectorPosition.y2}
/>
)}
</Box>
<Button variant="contained" color="primary" onClick= {handleConnectClick} disabled={!isConnectEnabled}>
Connect
</Button>
</Box>
</ThemeProvider>
);
}
function OptionsBox({ options, selected, onChange, idPrefix, alignRight }) {
return (
<Box display="flex" flexDirection="column" gap={4} flex={1}>
<RadioGroup value={selected} onChange={onChange}>
{options.map((name) => (
<Box key={name} display="flex" alignItems="center" mb={2}>
<FormControlLabel
value={name}
control={<Radio />}
label=""
id={`${idPrefix}${name.replace(/s+/g, '-')}`}
sx={{ marginRight: 2 }}
style={{ alignItems: alignRight ? 'flex-end' : 'flex-start' }}
/>
<Box
data-x-start={0} // Start point (0 = left, 1 = center, 2 = right)
data-y-start={1} // Start point (0 = top, 1 = center, 2 = bottom)
data-x-end={2} // End point (0 = left, 1 = center, 2 = right)
data-y-end={1} // End point (0 = top, 1 = center, 2 = bottom)
height={50}
width={100} // Increased width for better touch points
display="flex"
alignItems="center"
justifyContent="center"
p={1}
sx={{ border: '2px solid grey' }}
>
{name}
</Box>
</Box>
))}
</RadioGroup>
</Box>
);
}
const ConnectorLine = React.forwardRef(({ x1, y1, x2, y2 }, ref) => {
return (
<svg style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}>
<line ref={ref} x1={x1} y1={y1} x2={x2} y2={y2} style={{ stroke: 'black', strokeWidth: 2 }} />
</svg>
);
});