Skip to content

Commit

Permalink
CELE-32 fix: Fix grouping highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
afonsobspinto committed Jul 31, 2024
1 parent 54d7894 commit f6ab386
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 69 deletions.
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, updateHighlighted} from "../../../helpers/twoD/twoDHelpers";
import {applyLayout} from "../../../helpers/twoD/twoDHelpers";
import {
CHEMICAL_THRESHOLD,
ELECTRICAL_THRESHOLD,
Expand All @@ -18,7 +18,7 @@ import TwoDLegend from "./TwoDLegend";
import {Box} from "@mui/material";
import {ColoringOptions, getColor} from "../../../helpers/twoD/coloringHelper";
import ContextMenu from "./ContextMenu";
import {computeGraphDifferences} from "../../../helpers/twoD/graphRendering.ts";
import {computeGraphDifferences, updateHighlighted} from "../../../helpers/twoD/graphRendering.ts";

cytoscape.use(fcose);
cytoscape.use(dagre);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from './twoDHelpers';
import {NeuronGroup, Workspace} from "../../models";
import {Connection} from "../../rest";
import {LegendType} from "../../settings/twoDSettings.tsx";


export const computeGraphDifferences = (
Expand Down Expand Up @@ -319,3 +320,71 @@ const shouldRemoveEdge = (
// (splitting, joining, and active neuron considerations).
return !expectedNodes.has(pre) || !expectedNodes.has(post);
};


export const updateHighlighted = (cy, inputIds, selectedIds, legendHighlights) => {
// Remove all highlights and return if nothing is selected and no legend item activated.
cy.elements().removeClass("faded");
if (selectedIds.length === 0 && legendHighlights.size === 0) {
return;
}

// Use selected nodes as source if present, otherwise use input nodes.
const sourceIds = selectedIds.length ? selectedIds : inputIds;
let sourceNodes = cy.collection();

sourceIds.forEach((id) => {
const node = cy.getElementById(id);

if (node.isParent()) {
sourceNodes = sourceNodes.union(node.children());
} else {
sourceNodes = sourceNodes.union(node);
}
});

// Filter network by edges, as set by legend.
let edgeSel = "edge";
legendHighlights.forEach((highlight, type) => {
if (type === LegendType.Connection) {
edgeSel += `[type="${highlight}"]`;
}else if(type == LegendType.Annotation) {
edgeSel += '.' + highlight;
}
});

let connectedNodes = sourceNodes.neighborhood(edgeSel).connectedNodes();

// Filter network by nodes, as set by legend.
legendHighlights.forEach((highlight, type) => {
if (type === LegendType.Node) {
connectedNodes = connectedNodes.filter("[?" + highlight + "]");
}
});

// Filter to the neighborhood of the selected nodes.
if (selectedIds.length > 0) {
let allowedNodes = cy.collection();

for (let i = 0; i < sourceNodes.length; i++) {
const sourceNode = sourceNodes[i];
const nodes = sourceNode.neighborhood(edgeSel).connectedNodes();

if (i === 0) {
allowedNodes = allowedNodes.union(nodes);
} else {
allowedNodes = allowedNodes.intersection(nodes);
}
}
connectedNodes = connectedNodes.intersection(allowedNodes);
}

// Fade out any nodes and edges that were filtered out.
let highlightedNodes = sourceNodes.union(connectedNodes);
highlightedNodes = highlightedNodes.union(highlightedNodes.parents());

let highlightedEdges = highlightedNodes.edgesWith(highlightedNodes);
highlightedEdges = highlightedEdges.filter(edgeSel);

cy.elements().not(highlightedNodes).not(highlightedEdges).addClass("faded");
};
67 changes: 0 additions & 67 deletions applications/visualizer/frontend/src/helpers/twoD/twoDHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,73 +82,6 @@ export function applyLayout(cyRef: React.MutableRefObject<Core | null>, layout:
}
}

export const updateHighlighted = (cy, inputIds, selectedIds, legendHighlights) => {
// Remove all highlights and return if nothing is selected and no legend item activated.
cy.elements().removeClass("faded");
if (selectedIds.length === 0 && legendHighlights.length === 0) {
return;
}

// Use selected nodes as source if present, otherwise use input nodes.
const sourceIds = selectedIds.length ? selectedIds : inputIds;
let sourceNodes = cy.collection();

sourceIds.forEach((id) => {
const node = cy.getElementById(id);

if (node.isParent()) {
sourceNodes = sourceNodes.union(node.children());
} else {
sourceNodes = sourceNodes.union(node);
}
});

// Filter network by edges, as set by legend.
let edgeSel = "edge";
legendHighlights.forEach((highlight, type) => {
if (type === LegendType.Connection) {
edgeSel += `[type="${highlight}"]`;
}else if(type == LegendType.Annotation) {
edgeSel += '.' + highlight;
}
});

let connectedNodes = sourceNodes.neighborhood(edgeSel).connectedNodes();

// Filter network by nodes, as set by legend.
legendHighlights.forEach((highlight, type) => {
if (type === LegendType.Node) {
connectedNodes = connectedNodes.filter("[?" + highlight + "]");
}
});

// Filter to the neighborhood of the selected nodes.
if (selectedIds.length > 0) {
let allowedNodes = cy.collection();

for (let i = 0; i < sourceNodes.length; i++) {
const sourceNode = sourceNodes[i];
const nodes = sourceNode.neighborhood(edgeSel).connectedNodes();

if (i === 0) {
allowedNodes = allowedNodes.union(nodes);
} else {
allowedNodes = allowedNodes.intersection(nodes);
}
}
connectedNodes = connectedNodes.intersection(allowedNodes);
}

// Fade out any nodes and edges that were filtered out.
let highlightedNodes = sourceNodes.union(connectedNodes);
highlightedNodes = highlightedNodes.union(highlightedNodes.parents());

let highlightedEdges = highlightedNodes.edgesWith(highlightedNodes);
highlightedEdges = highlightedEdges.filter(edgeSel);

cy.elements().not(highlightedNodes).not(highlightedEdges).addClass("faded");
};

// Helper functions
export const isNeuronCell = (neuronId: string, workspace: Workspace): boolean => {
const neuron = workspace.availableNeurons[neuronId];
Expand Down

0 comments on commit f6ab386

Please sign in to comment.