Skip to content

Commit

Permalink
VT-23. Refactor to fix styleling problems
Browse files Browse the repository at this point in the history
  • Loading branch information
romina1601 committed Sep 12, 2024
1 parent 76a1ef2 commit 8e575d2
Show file tree
Hide file tree
Showing 10 changed files with 9,296 additions and 12,389 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"jest": "^29.2.0",
"mkdirp": "^1.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^3.0.0",
"prettier": "^3.3.3",
"rimraf": "^5.0.1",
"source-map-loader": "^1.0.2",
"style-loader": "^3.3.1",
Expand Down
26 changes: 20 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { IWorkspaceState } from './components/interfaces/WorkspaceInterfaces';
import TreeViewComponent from './components/TreeView';

const App: React.FC = () => {
const [selectedNode, setSelectedNode] = useState<ISelectedNodeType | null>(null);
const [selectedNode, setSelectedNode] = useState<ISelectedNodeType | null>(
null
);

const initialWorkspaceState: IWorkspaceState = {
model: null,
Expand All @@ -18,7 +20,9 @@ const App: React.FC = () => {
noise: null,
integrationMethod: null
};
const [workspace, setWorkspace] = useState<IWorkspaceState>(initialWorkspaceState);
const [workspace, setWorkspace] = useState<IWorkspaceState>(
initialWorkspaceState
);

const addToWorkspace = (node: ISelectedNodeType) => {
setWorkspace(prevWorkspace => {
Expand All @@ -37,12 +41,15 @@ const App: React.FC = () => {
});
};

const updateConnectivityOptions = (optionType: 'parcellation' | 'tractogram', value: string) => {
const updateConnectivityOptions = (
optionType: 'parcellation' | 'tractogram',
value: string
) => {
setWorkspace(prev => {
return {
...prev,
parcellation: optionType === 'parcellation' ? value : prev.parcellation,
tractogram: optionType === 'tractogram' ? value : prev.tractogram,
tractogram: optionType === 'tractogram' ? value : prev.tractogram
};
});
};
Expand All @@ -53,8 +60,15 @@ const App: React.FC = () => {

return (
<div className="layout">
<InfoBoxComponent selectedNode={selectedNode} addToWorkspace={addToWorkspace} />
<WorkspaceComponent workspace={workspace} updateConnectivityOptions={updateConnectivityOptions} resetWorkspace={resetWorkspace}/>
<InfoBoxComponent
selectedNode={selectedNode}
addToWorkspace={addToWorkspace}
/>
<WorkspaceComponent
workspace={workspace}
updateConnectivityOptions={updateConnectivityOptions}
resetWorkspace={resetWorkspace}
/>
<TreeViewComponent selectedNode={selectedNode} />
<GraphViewComponent setSelectedNode={setSelectedNode} />
</div>
Expand Down
27 changes: 22 additions & 5 deletions src/components/GaphView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import ForceGraph2D, { ForceGraphMethods, LinkObject, NodeObject } from 'react-force-graph-2d';
import ForceGraph2D, {
ForceGraphMethods,
LinkObject,
NodeObject
} from 'react-force-graph-2d';
import { fetchNodeByLabel, fetchNodeChildren } from '../handler';
import { ISelectedNodeType } from './interfaces/InfoBoxInterfaces';
import { ILinkType, INodeType } from './interfaces/GraphViewInterfaces';
Expand All @@ -11,11 +15,15 @@ interface IGraphViewProps {
export const GraphViewComponent: React.FC<IGraphViewProps> = ({
setSelectedNode
}) => {
const [data, setData] = useState<{ nodes: INodeType[]; links: ILinkType[]; }>({ nodes: [], links: [] });
const [data, setData] = useState<{ nodes: INodeType[]; links: ILinkType[] }>({
nodes: [],
links: []
});
const [searchLabel, setSearchLabel] = useState<string>('');
const [highlightNode, setHighlightNode] = useState<INodeType | null>(null);
const NODE_RADIUS = 4;
const fgRef = useRef<ForceGraphMethods<NodeObject<INodeType>, LinkObject<ILinkType>>>();
const fgRef =
useRef<ForceGraphMethods<NodeObject<INodeType>, LinkObject<ILinkType>>>();
const [isInitialRender, setIsInitialRender] = useState<boolean>(true);

useEffect(() => {
Expand Down Expand Up @@ -89,7 +97,14 @@ export const GraphViewComponent: React.FC<IGraphViewProps> = ({
(node: INodeType, ctx: CanvasRenderingContext2D) => {
if (highlightNode && node.id === highlightNode.id) {
ctx.beginPath();
ctx.arc(node.x as number, node.y as number, NODE_RADIUS, 0, 2 * Math.PI, false);
ctx.arc(
node.x as number,
node.y as number,
NODE_RADIUS,
0,
2 * Math.PI,
false
);
ctx.strokeStyle = 'red';
ctx.lineWidth = 1.5;
ctx.stroke();
Expand Down Expand Up @@ -153,7 +168,9 @@ export const GraphViewComponent: React.FC<IGraphViewProps> = ({

paintRing(node, ctx);
}}
nodeCanvasObjectMode={(node) => (highlightNode && node.id === highlightNode.id ? 'before' : 'after')}
nodeCanvasObjectMode={node =>
highlightNode && node.id === highlightNode.id ? 'before' : 'after'
}
linkDirectionalArrowLength={3.5}
linkDirectionalArrowRelPos={1}
/>
Expand Down
25 changes: 20 additions & 5 deletions src/components/InfoBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ interface IInfoBoxProps {
addToWorkspace: (node: ISelectedNodeType) => void;
}

const InfoBoxComponent: React.FC<IInfoBoxProps> = ({ selectedNode, addToWorkspace }) => {
const InfoBoxComponent: React.FC<IInfoBoxProps> = ({
selectedNode,
addToWorkspace
}) => {
// Valid types for adding objects to workspace
// TODO: add valid type for connectivity
const validTypes = ['Neural Mass Model', 'Noise', 'Coupling', 'Integrator'];
Expand All @@ -29,20 +32,28 @@ const InfoBoxComponent: React.FC<IInfoBoxProps> = ({ selectedNode, addToWorkspac

// check requirements of selected node
if (selectedNode.requires && selectedNode.requires.length > 0) {
const requiredNodePromises = selectedNode.requires.map(label => fetchNodeByLabel(label));
const requiredNodePromises = selectedNode.requires.map(label =>
fetchNodeByLabel(label)
);
const requiredNodesResponses = await Promise.all(requiredNodePromises);

requiredNodesResponses.forEach(response => {
const { nodes } = response; // Extract nodes from the response
nodes.forEach(node => {
if (validTypes.includes(node.type) && (node.type !== selectedNode.type)) { // check for same type as selected node to not overwrite it
if (
validTypes.includes(node.type) &&
node.type !== selectedNode.type
) {
// check for same type as selected node to not overwrite it
addToWorkspace(node);
}
});
});
}
} else {
console.warn(`Node type "${selectedNode.type}" is not allowed in the workspace.`);
console.warn(
`Node type "${selectedNode.type}" is not allowed in the workspace.`
);
}
};

Expand All @@ -65,7 +76,11 @@ const InfoBoxComponent: React.FC<IInfoBoxProps> = ({ selectedNode, addToWorkspac
</p>
<p>
<strong>IRI:</strong>{' '}
<a href={selectedNode.iri} target="_blank" rel="noopener noreferrer">
<a
href={selectedNode.iri}
target="_blank"
rel="noopener noreferrer"
>
{selectedNode.iri}
</a>
</p>
Expand Down
28 changes: 23 additions & 5 deletions src/components/TreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ const TreeViewComponent: React.FC<ITreeViewProps> = ({ selectedNode }) => {

const fetchAndSetParents = async () => {
try {
const { nodes, links } = await fetchNodeParents(selectedNode.label, selectedNode.id);
const parentData = processNodeRelations(nodes, links, selectedNode.id, 'parents');
const { nodes, links } = await fetchNodeParents(
selectedNode.label,
selectedNode.id
);
const parentData = processNodeRelations(
nodes,
links,
selectedNode.id,
'parents'
);
setParents(parentData);
} catch (error) {
console.error('Failed to fetch parents:', error);
Expand All @@ -36,8 +44,16 @@ const TreeViewComponent: React.FC<ITreeViewProps> = ({ selectedNode }) => {

const fetchAndSetChildren = async () => {
try {
const { nodes, links } = await fetchNodeChildren(selectedNode.label, selectedNode.id);
const childData = processNodeRelations(nodes, links, selectedNode.id, 'children');
const { nodes, links } = await fetchNodeChildren(
selectedNode.label,
selectedNode.id
);
const childData = processNodeRelations(
nodes,
links,
selectedNode.id,
'children'
);
setChildren(childData);
} catch (error) {
console.error('Failed to fetch children:', error);
Expand All @@ -62,7 +78,9 @@ const TreeViewComponent: React.FC<ITreeViewProps> = ({ selectedNode }) => {
): INodeRelation[] => {
return links
.filter((link: ILinkType) =>
type === 'parents' ? link.target === currentNodeId : link.source === currentNodeId
type === 'parents'
? link.target === currentNodeId
: link.source === currentNodeId
)
.map((link: ILinkType) => {
const relatedNode = nodes.find((node: INodeType) =>
Expand Down
58 changes: 43 additions & 15 deletions src/components/Workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@ import React, { useEffect, useState } from 'react';
import { IWorkspaceProps } from './interfaces/WorkspaceInterfaces';
import { exportWorkspace, runSimulation } from '../handler';

const WorkspaceComponent: React.FC<IWorkspaceProps> = ({ workspace, updateConnectivityOptions, resetWorkspace }) => {
const WorkspaceComponent: React.FC<IWorkspaceProps> = ({
workspace,
updateConnectivityOptions,
resetWorkspace
}) => {
const [exportType, setExportType] = useState('py');
const [message, setMessage] = useState<string | null>(null);
const [directory, setDirectory] = useState('');

const parcellationOptions = ['DesikanKilliany', 'Destrieux', 'Schaefer1000', 'hcpmmp1', 'virtualdbs'];
const parcellationOptions = [
'DesikanKilliany',
'Destrieux',
'Schaefer1000',
'hcpmmp1',
'virtualdbs'
];
const tractogramOptions = ['MghUscHcp32', 'PPMI85', 'dTOR'];

const constructNodeData = () => {
Expand All @@ -17,7 +27,9 @@ const WorkspaceComponent: React.FC<IWorkspaceProps> = ({ workspace, updateConnec
tractogram: workspace.tractogram ? workspace.tractogram : 'None',
coupling: workspace.coupling ? workspace.coupling.label : 'None',
noise: workspace.noise ? workspace.noise.label : 'None',
integrationMethod: workspace.integrationMethod ? workspace.integrationMethod.label : 'None',
integrationMethod: workspace.integrationMethod
? workspace.integrationMethod.label
: 'None'
};

return nodeData;
Expand Down Expand Up @@ -78,7 +90,9 @@ const WorkspaceComponent: React.FC<IWorkspaceProps> = ({ workspace, updateConnec
<div className="workspace">
<div className="workspace-header">
<h3>Workspace</h3>
<button className="reset-button" onClick={resetWorkspace}>Reset Workspace</button>
<button className="reset-button" onClick={resetWorkspace}>
Reset Workspace
</button>
</div>
<div>
<h4>Model</h4>
Expand All @@ -92,9 +106,13 @@ const WorkspaceComponent: React.FC<IWorkspaceProps> = ({ workspace, updateConnec
<select
id="parcellation"
value={workspace.parcellation || ''}
onChange={(e) => updateConnectivityOptions('parcellation', e.target.value)} // Update state on change
onChange={e =>
updateConnectivityOptions('parcellation', e.target.value)
} // Update state on change
>
<option value="" disabled>Select a parcellation</option>
<option value="" disabled>
Select a parcellation
</option>
{parcellationOptions.map((option, index) => (
<option key={index} value={option}>
{option}
Expand All @@ -109,9 +127,13 @@ const WorkspaceComponent: React.FC<IWorkspaceProps> = ({ workspace, updateConnec
<select
id="tractogram"
value={workspace.tractogram || ''}
onChange={(e) => updateConnectivityOptions('tractogram', e.target.value)} // Update state on change
onChange={e =>
updateConnectivityOptions('tractogram', e.target.value)
} // Update state on change
>
<option value="" disabled>Select a tractogram</option>
<option value="" disabled>
Select a tractogram
</option>
{tractogramOptions.map((option, index) => (
<option key={index} value={option}>
{option}
Expand All @@ -131,7 +153,11 @@ const WorkspaceComponent: React.FC<IWorkspaceProps> = ({ workspace, updateConnec
</div>
<div>
<h4>Integration Method</h4>
<p>{workspace.integrationMethod ? workspace.integrationMethod.label : 'None'}</p>
<p>
{workspace.integrationMethod
? workspace.integrationMethod.label
: 'None'}
</p>
</div>

{/* Export controls */}
Expand All @@ -142,29 +168,31 @@ const WorkspaceComponent: React.FC<IWorkspaceProps> = ({ workspace, updateConnec
<select
id="export-type"
value={exportType}
onChange={(e) => setExportType(e.target.value)}
onChange={e => setExportType(e.target.value)}
>
<option value="py">Simulation code (.py)</option>
<option value="xml">Model specification (.xml)</option>
<option value="yaml">Metadata (.yaml)</option>
</select>
</div>
</div>

<div className="export-control">
<label htmlFor="directory">Save Directory Path: </label>
<input
id="directory"
type="text"
value={directory}
onChange={(e) => setDirectory(e.target.value)}
onChange={e => setDirectory(e.target.value)}
placeholder="/home/user/downloads"
/>
</div>

<div className="button-container">
<button className="export-button" onClick={handleExport}>Export</button>
<button className="export-button" onClick={handleRunSimulation}>Run Simulation</button>
<button className="export-button" onClick={handleExport}>
Export
</button>
<button className="export-button" onClick={handleRunSimulation}>
Run Simulation
</button>
</div>
{message && <p>{message}</p>} {/* Display success/error message */}
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/components/interfaces/WorkspaceInterfaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { ISelectedNodeType } from './InfoBoxInterfaces';

export interface IWorkspaceProps {
workspace: IWorkspaceState;
updateConnectivityOptions: (optionType: 'parcellation' | 'tractogram', value: string) => void;
updateConnectivityOptions: (
optionType: 'parcellation' | 'tractogram',
value: string
) => void;
resetWorkspace: () => void;
}

Expand Down
6 changes: 3 additions & 3 deletions src/custom.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare module '*.svg' {
const script: string;
export default script;
}
const script: string;
export default script;
}
Loading

0 comments on commit 8e575d2

Please sign in to comment.