Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,12 @@ export const ForceAtlas2Layout = {
},
{ id: "slowDown", type: "number", defaultValue: FA2_DEFAULT_SETTINGS.slowDown, min: 1, step:"any"},
{ id: "strongGravityMode", type: "boolean", defaultValue: FA2_DEFAULT_SETTINGS.strongGravityMode },
{
id: "getNodeFixedAttribut",
type: "attribute",
itemType: "nodes",
restriction: ["boolean"],
required: false,
},
],
} as WorkerLayout<ForceAtlas2LayoutParameters>;
27 changes: 24 additions & 3 deletions packages/gephi-lite/src/core/layouts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ export const stopLayout = asyncAction(async (isForRestart = false) => {
if (!isForRestart) layoutStateAtom.set((prev) => ({ ...prev, type: "idle" }));
});

export const startLayout = asyncAction(async (id: string, params: unknown, isForRestart = false) => {
export const startLayout = asyncAction(async (id: string, params: Record<string, unknown>, isForRestart = false) => {
// Stop the previous algo (the "if needed" is done in the function itself)
await stopLayout(isForRestart);

const dataset = graphDatasetAtom.get();
const { setNodePositions } = graphDatasetActions;

// search the layout
Expand All @@ -74,7 +75,6 @@ export const startLayout = asyncAction(async (id: string, params: unknown, isFor
layoutStateAtom.set((prev) => ({ ...prev, type: "running", layoutId: id, supervisor: undefined }));

// generate positions
const dataset = graphDatasetAtom.get();
const fullGraph = dataGraphToFullGraph(dataset);
const positions = layout.run(fullGraph, { settings: params });

Expand All @@ -91,7 +91,28 @@ export const startLayout = asyncAction(async (id: string, params: unknown, isFor

// Async layout
if (layout.type === "worker") {
const worker = new layout.supervisor(sigmaGraphAtom.get(), { settings: params });
const graph = sigmaGraphAtom.get();

// Fixed node management
// ---------------------
// If layout parameter has a `getNodeFixedAttribut`, then we have to set the 'fixed' attribut in sigma's graph
// On a layout restart, if parameter has been removed, we need to set to false
// We also use the 'fixed' attribut for drag'n'drop
graph.updateEachNodeAttributes((id, attrs) => {
let fixed = attrs.dragging === true;
if ("getNodeFixedAttribut" in params && params.getNodeFixedAttribut) {
const fixedAttribut = `${params.getNodeFixedAttribut}`;
if (dataset.nodeData[id][fixedAttribut] === true) {
fixed = true;
}
}
return {
...attrs,
fixed,
};
});

const worker = new layout.supervisor(graph, { settings: params });
worker.start();
layoutStateAtom.set((prev) => ({ ...prev, type: "running", layoutId: id, supervisor: worker }));
}
Expand Down
3 changes: 3 additions & 0 deletions packages/gephi-lite/src/locales/dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@
"description": "Influence of the edge’s weights on the layout",
"title": "Edge weight influence"
},
"getNodeFixedAttribut": {
"title": "Attribute indicating whether the node’s position is fixed"
},
"gravity": {
"description": "Strength of the layout’s gravity",
"title": "Gravity"
Expand Down
3 changes: 3 additions & 0 deletions packages/gephi-lite/src/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,9 @@
"description": "Influence des poids des liens sur la spatialisation",
"title": "Influence du poids des liens"
},
"getNodeFixedAttribut": {
"title": "Attribut indiquant si la position du nœud est fixée"
},
"gravity": {
"description": "Intensité de la gravité de la spatialisation",
"title": "Gravité"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ export const EventsController: FC = () => {

const initialNodesPosition: LayoutMapping = {};
nodes.forEach((node) => {
// Fixing the node position, it's needed while a layout is running
graph.setNodeAttribute(node, "fixed", true);
// Set dragging prop on node, which fix the node
graph.setNodeAttribute(node, "dragging", true);
const { x, y } = graph.getNodeAttributes(node);
initialNodesPosition[node] = { x, y };
});
Expand Down Expand Up @@ -131,7 +131,7 @@ export const EventsController: FC = () => {

for (const node in dragState.initialNodesPosition) {
const initialPosition = dragState.initialNodesPosition[node];
graph.setNodeAttribute(node, "fixed", true);
graph.setNodeAttribute(node, "dragging", true);
graph.setNodeAttribute(node, "x", initialPosition.x + delta.x);
graph.setNodeAttribute(node, "y", initialPosition.y + delta.y);
}
Expand Down Expand Up @@ -162,7 +162,12 @@ export const EventsController: FC = () => {
resetHoveredNode();
resetHoveredEdge();
}
graph.forEachNode((node) => graph.setNodeAttribute(node, "fixed", false));
// Remove the dragging state on each node
graph.forEachNode((node) => graph.setNodeAttribute(node, "dragging", false));
// Emit the last dragged event when the dragging prop is removed
// so the algo can restart with the good data
globalEmitter.emit(EVENTS.nodesDragged);
// Update drag status
dragStateRef.current = { type: "idle" };
}
};
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/graph/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export type NodeRenderingData = Attributes &
rawSize?: number;
image?: string | null;
fixed?: boolean;
dragging?:boolean;
};

export interface GraphMetadata {
Expand Down