Skip to content

Commit

Permalink
CELE-32 fix: Fix graph container resize
Browse files Browse the repository at this point in the history
  • Loading branch information
afonsobspinto committed Aug 1, 2024
1 parent 074b4c7 commit d29cea1
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import {
} from "@mui/material";
import {useState} from "react";
import {ColoringOptions} from "../../../helpers/twoD/coloringHelper.ts";
import {applyLayout} from "../../../helpers/twoD/twoDHelpers.ts";
import {GRAPH_LAYOUTS, ZOOM_DELTA} from "../../../settings/twoDSettings.tsx";
import {vars} from "../../../theme/variables.ts";
import CustomSwitch from "../../ViewerContainer/CustomSwitch.tsx";
import QuantityInput from "./NumberInput.tsx";
import {useSelectedWorkspace} from "../../../hooks/useSelectedWorkspace.ts";
import {applyLayout, refreshLayout} from "../../../helpers/twoD/twoDHelpers.ts";

const {gray500} = vars;

Expand Down Expand Up @@ -77,9 +77,7 @@ const TwoDMenu = ({
if (!cy) {
return;
}
cy.reset(); // Reset the zoom and pan positions
applyLayout(cy, layout);
cy.fit();
applyLayout(cy, layout)
};

const handleOpenSettings = (event) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import dagre from "cytoscape-dagre";
import {useSelectedWorkspace} from "../../../hooks/useSelectedWorkspace";
import {type Connection, ConnectivityService} from "../../../rest";
import {GRAPH_STYLES} from "../../../theme/twoDStyles";
import {applyLayout} from "../../../helpers/twoD/twoDHelpers";
import {applyLayout, refreshLayout} from "../../../helpers/twoD/twoDHelpers";
import {
CHEMICAL_THRESHOLD,
ELECTRICAL_THRESHOLD,
Expand Down Expand Up @@ -65,7 +65,7 @@ const TwoDViewer = () => {
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.target === cyContainer.current) {
updateLayout();
refreshLayout(cy);
}
}
});
Expand Down Expand Up @@ -285,7 +285,7 @@ const TwoDViewer = () => {

const updateLayout = () => {
if (cyRef.current) {
applyLayout(cyRef, layout);
applyLayout(cyRef.current, layout);
}
};

Expand Down
169 changes: 93 additions & 76 deletions applications/visualizer/frontend/src/helpers/twoD/twoDHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,96 +1,93 @@
import type { Core, ElementDefinition } from "cytoscape";
import type { Connection } from "../../rest";
import type { Workspace } from "../../models/workspace.ts";
import type {Core, ElementDefinition, Position} from "cytoscape";
import type {Connection} from "../../rest";
import type {Workspace} from "../../models/workspace.ts";
import {annotationLegend} from "../../settings/twoDSettings.tsx";
import {cellConfig, neurotransmitterConfig} from "./coloringHelper.ts";

export const createEdge = (id: string, conn: Connection, workspace: Workspace, includeAnnotations: boolean): ElementDefinition => {
const synapses = conn.synapses || {};
const annotations = conn.annotations || [];
const synapses = conn.synapses || {};
const annotations = conn.annotations || [];

const label = createEdgeLabel(workspace, synapses);
const longLabel = createEdgeLongLabel(workspace, synapses);
const label = createEdgeLabel(workspace, synapses);
const longLabel = createEdgeLongLabel(workspace, synapses);

let annotationClasses: string[] = [];
let annotationClasses: string[] = [];

if (includeAnnotations) {
annotationClasses = annotations.map(annotation => annotationLegend[annotation]?.id).filter(Boolean);
if (annotationClasses.length === 0) {
annotationClasses.push(annotationLegend.notClassified.id);
if (includeAnnotations) {
annotationClasses = annotations.map(annotation => annotationLegend[annotation]?.id).filter(Boolean);
if (annotationClasses.length === 0) {
annotationClasses.push(annotationLegend.notClassified.id);
}
} else {
annotationClasses.push(conn.type);
}
} else {
annotationClasses.push(conn.type);
}

const classes = annotationClasses.join(" ");

return {
group: "edges",
data: {
id: id,
source: conn.pre,
target: conn.post,
label: label,
longLabel: longLabel,
type: conn.type,
},
classes: classes,
};

const classes = annotationClasses.join(" ");

return {
group: "edges",
data: {
id: id,
source: conn.pre,
target: conn.post,
label: label,
longLabel: longLabel,
type: conn.type,
},
classes: classes,
};
};


// Helper functions to create edge labels
const createEdgeLabel = (workspace: Workspace, synapses: Record<string, number>) => {
const datasets = Object.values(workspace.activeDatasets).map(dataset => dataset.id);
return datasets.map(datasetId => synapses[datasetId] || 0).join(',');
const datasets = Object.values(workspace.activeDatasets).map(dataset => dataset.id);
return datasets.map(datasetId => synapses[datasetId] || 0).join(',');
};

const createEdgeLongLabel = (workspace: Workspace, synapses: Record<string, number>) => {
const datasets = Object.values(workspace.activeDatasets)
return datasets.map(dataset => {
const datasetLabel = synapses[dataset.id] || 0;
return `${dataset.name}: ${datasetLabel}`;
}).join('\n');
const datasets = Object.values(workspace.activeDatasets)
return datasets.map(dataset => {
const datasetLabel = synapses[dataset.id] || 0;
return `${dataset.name}: ${datasetLabel}`;
}).join('\n');
};

export const createNode = (
nodeId: string,
selected: boolean,
attributes: string[]
): ElementDefinition => {
const data = { id: nodeId, label: nodeId };

// Set each attribute in the data object to true
attributes.forEach(attr => {
data[attr] = true;
});

return {
group: "nodes",
data,
classes: selected ? "selected" : "",
};
export const createNode = (nodeId: string, selected: boolean, attributes: string[], position?: Position): ElementDefinition => {
const node: ElementDefinition = {
group: "nodes",
data: {id: nodeId, label: nodeId, ...attributes.reduce((acc, attr) => ({...acc, [attr]: true}), {})},
classes: selected ? "selected" : ""
};
if (position) {
node.position = position;
}
return node;
};

export function applyLayout(cyRef: React.MutableRefObject<Core | null>, layout: string) {
if (cyRef.current) {
cyRef.current
.layout({
export function applyLayout(cy: Core, layout: string) {
cy.layout({
name: layout,
})
.run();
}
}).run();

refreshLayout(cy)
}

export function refreshLayout(cy: Core) {
cy.resize(); // Adjust the viewport size
cy.center(); // Center the graph in the container
cy.fit(); // Fit the graph to the container
}

// Helper functions
export const isNeuronCell = (neuronId: string, workspace: Workspace): boolean => {
const neuron = workspace.availableNeurons[neuronId];
return neuron ? neuron.name !== neuron.nclass : false;
const neuron = workspace.availableNeurons[neuronId];
return neuron ? neuron.name !== neuron.nclass : false;
};

export const isNeuronClass = (neuronId: string, workspace: Workspace): boolean => {
const neuron = workspace.availableNeurons[neuronId];
return neuron ? neuron.name === neuron.nclass : false;
const neuron = workspace.availableNeurons[neuronId];
return neuron ? neuron.name === neuron.nclass : false;
};

export const getEdgeId = (conn: Connection, includeAnnotations: boolean): string => {
Expand All @@ -101,21 +98,41 @@ export const getEdgeId = (conn: Connection, includeAnnotations: boolean): string


export const extractNeuronAttributes = (neuron) => {
const cellAttributes = neuron.type.split('').map(char => cellConfig[char]?.type).filter(Boolean);
const neurotransmitterAttributes = neuron.neurotransmitter.split('').map(char => neurotransmitterConfig[char]?.type).filter(Boolean);
const cellAttributes = neuron.type.split('').map(char => cellConfig[char]?.type).filter(Boolean);
const neurotransmitterAttributes = neuron.neurotransmitter.split('').map(char => neurotransmitterConfig[char]?.type).filter(Boolean);

return [...cellAttributes, ...neurotransmitterAttributes];
return [...cellAttributes, ...neurotransmitterAttributes];
};

export const getNclassSet = (neuronIds: Set<string>, workspace: Workspace): Set<string> => {
const nclassSet = new Set<string>();
neuronIds.forEach(neuronId => {
const neuron = workspace.availableNeurons[neuronId];
if (neuron && neuron.nclass) {
nclassSet.add(neuron.nclass);
}
});
return nclassSet;
const nclassSet = new Set<string>();
neuronIds.forEach(neuronId => {
const neuron = workspace.availableNeurons[neuronId];
if (neuron && neuron.nclass) {
nclassSet.add(neuron.nclass);
}
});
return nclassSet;
};


export const calculateMeanPosition = (nodeIds: string[], cy: Core): Position => {
let totalX = 0;
let totalY = 0;
let count = 0;

nodeIds.forEach(nodeId => {
const node = cy.getElementById(nodeId);
if (node && node.position) {
const position = node.position();
totalX += position.x;
totalY += position.y;
count++;
}
});

return {
x: totalX / count,
y: totalY / count
};
};

0 comments on commit d29cea1

Please sign in to comment.