8000 [Sample List Graphical view ] Add Circular Display Mode for Single Cell in SampleFlexView by jbflo · Pull Request #1642 · mxcube/mxcubeweb · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[Sample List Graphical view ] Add Circular Display Mode for Single Cell in SampleFlexView #1642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions ui/src/components/SampleGrid/SampleCircleView.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { useEffect } from 'react';
import { Col } from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';

import { filterAction } from '../../actions/sampleGrid';

export default function SampleCircleView(props) {
const { displayPuckCellContextMenu, puckMenuID, type = 'Mockup' } = props;

const filterOptions = useSelector((state) => state.sampleGrid.filterOptions);

const pucks = useSelector((state) => state.sampleChanger.contents.children);

const cellID = 1;

const dispatch = useDispatch();

function handleClickOnCellPuck(event, puckID) {
dispatch(
filterAction({ cellFilter: `${cellID}`, puckFilter: `${puckID}` }),
);
event.stopPropagation();
}

useEffect(() => {
if (filterOptions.cellFilter === '') {
dispatch(filterAction({ cellFilter: '1', puckFilter: '1' }));
}
}, [filterOptions.cellFilter, dispatch]);

function handleDisplayPuckCellContextMenu(e, menuID, puckID) {
e.preventDefault();
handleClickOnCellPuck(e, cellID, puckID === null ? '' : puckID);
displayPuckCellContextMenu(e, menuID, cellID, puckID);
e.stopPropagation();
}

function getSingleCellAsCircle(centerX, centerY) {
const totalPucks = pucks.length;

// Adjust angle range based on puck count
const useFullCircle = totalPucks >= 8;
const angleRange = useFullCircle ? 2 * Math.PI : Math.PI * 1.5;
const startAngle = useFullCircle ? 0 : (Math.PI - angleRange) / 2;

// Circle size and spacing
const baseRadius = 4;
const placementRadius = baseRadius + Math.max(0, (totalPucks - 16) * 0.3);
const puckRadius = Math.min(
0.7,
(2 * Math.PI * placementRadius) / (totalPucks * 2),
);

// Fix angle spacing: avoid skipping puck 1 or overlapping at end
const angleDivisor = useFullCircle
? totalPucks
: Math.max(1, totalPucks - 1);

return pucks.map((_, i) => {
const angle = startAngle + (angleRange * i) / angleDivisor;
const x = centerX + placementRadius * Math.cos(angle);
const y = centerY + placementRadius * Math.sin(angle);
const puckID = i + 1;

const isPuckSelected =
Number(filterOptions.cellFilter) === cellID &&
Number(filterOptions.puckFilter) === puckID;

return (
<g
key={`single_cell_puck_${puckID}`}
=> handleClickOnCellPuck(e, puckID)}
=>
handleDisplayPuckCellContextMenu(e, puckMenuID, puckID)
}
fill={isPuckSelected ? '#015f9d' : '#cdced1'}
className="puck_cicle"
>
<circle
cx={x}
cy={y}
r={puckRadius}
stroke="#01011ba2"
strokeWidth="0.05"
/>
<text
x={x}
y={y}
fontSize="0.3"
textAnchor="middle"
dominantBaseline="middle"
fill={isPuckSelected ? 'white' : 'black'}
>
Puck {puckID}
</text>
<title>
Cell: {cellID}, Puck: {puckID}
</title>
</g>
);
});
}

return (
<Col sm={6}>
<div className="div-svg-flex">
<svg height="100%" width="100%" viewBox="0 1 20 20">
<circle fill="#6cb0f5" r="8" cx="10" cy="10" />
{getSingleCellAsCircle(10, 10)}
<text x="10" y="10" fontSize="0.5" textAnchor="middle" fill="black">
{type}
</text>
</svg>
</div>
</Col>
);
}
48 changes: 30 additions & 18 deletions ui/src/containers/SampleGridTableContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from '../actions/sampleGrid';
import { showTaskForm } from '../actions/taskForm';
import MXContextMenu from '../components/GenericContextMenu/MXContextMenu';
import SampleCircleView from '../components/SampleGrid/SampleCircleView';
import { SampleGridTableItem } from '../components/SampleGrid/SampleGridTableItem';
import { TaskItem } from '../components/SampleGrid/TaskItem';
import TooltipTrigger from '../components/TooltipTrigger';
Expand Down Expand Up @@ -129,8 +130,8 @@ function checkForOverlap(el1, el2) {
}

// Helper function to determine puck colsm value
function getColsm(singleCell, puckCount) {
if (singleCell) {
function getColsm(isSingleCell, puckCount) {
if (isSingleCell) {
return puckCount <= 4 ? 3 : true;
}
return puckCount === 1 ? 2 : puckCount === 2 ? 4 : puckCount === 3 ? 6 : true;
Expand Down Expand Up @@ -169,6 +170,10 @@ export default function SampleGridTableContainer(props) {

const [rubberBandVisible, setRubberBandVisible] = useState(false);

const isSingleCell = Object.values(sampleList).every(
(sample) => sample.cell_no === 1 || sample.cell_no === 0,
);

// this supose to replace old shouldComponentUpdate , not sure we need it
useEffect(() => {
console.log('Component Updated'); // eslint-disable-line no-console
Expand Down Expand Up @@ -479,16 +484,10 @@ export default function SampleGridTableContainer(props) {
e.stopPropagation();
}

function isSingleCell() {
return Object.values(sampleList).every(
(sample) => sample.cell_no === 1 || sample.cell_no === 0,
);
}

function getSampleItemCollapsibleHeaderActions(cellID) {
return (
<div className="sample-items-collapsible-header-actions">
<b className="me-2 mt-1">{isSingleCell() ? null : `Cell ${cellID}`}</b>
<b className="me-2 mt-1">{isSingleCell ? null : `Cell ${cellID}`}</b>
{sampleItemsControls(cellID, null)}
<span
title="Cell Options"
Expand Down Expand Up @@ -611,7 +610,7 @@ export default function SampleGridTableContainer(props) {
const puckFilterValue = Number(filterOptions.puckFilter); // Ensure numeric comparison

return scContent.children.filter((puck, puckidx) => {
const puckID = isSingleCell() ? Number(puck.name) : puckidx + 1;
const puckID = isSingleCell ? Number(puck.name) : puckidx + 1;
const [filterList] = getSampleListFilteredByCellPuck(cellID, puckID);

return (
Expand Down Expand Up @@ -681,7 +680,7 @@ export default function SampleGridTableContainer(props) {
<tr>
{puckList.map((puck) => {
const puckidx = cell.children.findIndex((p) => p.name === puck.name);
const puckID = isSingleCell() ? Number(puck.name) : puckidx + 1;
const puckID = isSingleCell ? Number(puck.name) : puckidx + 1;
return (
<td
key={`${cellID}-td-${puckID}`}
Expand All @@ -700,7 +699,7 @@ export default function SampleGridTableContainer(props) {
<tr>
{puckList.map((puck) => {
const puckidx = cell.children.findIndex((p) => p.name === puck.name);
const puckID = isSingleCell() ? Number(puck.name) : puckidx + 1;
const puckID = isSingleCell ? Number(puck.name) : puckidx + 1;

return (
<th
Expand Down Expand Up @@ -808,8 +807,7 @@ export default function SampleGridTableContainer(props) {
return null;
}

const singleCell = isSingleCell();
if (singleCell) {
if (isSingleCell) {
scContent = { children: [{ name: 1, children: scContent.children }] };
}

Expand All @@ -820,9 +818,9 @@ export default function SampleGridTableContainer(props) {
return null;
}

const colsm = getColsm(singleCell, puckList.length);
const colsm = getColsm(isSingleCell, puckList.length);

return singleCell
return isSingleCell
? getSingleCellPucks(cell, cellID, puckList, colsm)
: getMultipleCellPucks(cell, cellID, puckList, colsm);
});
Expand Down Expand Up @@ -967,11 +965,15 @@ export default function SampleGridTableContainer(props) {
}

function getSampleListAsDrawing() {
if (type.includes('CATS')) {
const isCATS = type.includes('CATS');
const isFLEX = type.includes('FLEX');
const isMOCK = type.includes('Mock');

if (isCATS) {
return <SampleIsaraView />;
}

if (type.includes('FLEX') || type.includes('Moc')) {
if (isFLEX) {
return (
<SampleFlexView
displayPuckCellContextMenu={displayPuckCellContextMenu}
Expand All @@ -981,6 +983,16 @@ export default function SampleGridTableContainer(props) {
/>
);
}
if (isSingleCell || isMOCK) {
return (
<SampleCircleView
displayPuckCellContextMenu={displayPuckCellContextMenu}
puckMenuID={PUCK_MENU_ID}
type={type}
/>
);
}

return null;
}

Expand Down
0