Skip to content

Commit 5227779

Browse files
committed
[layout] fixed node for FA2
1 parent a13db8a commit 5227779

File tree

6 files changed

+47
-7
lines changed

6 files changed

+47
-7
lines changed

packages/gephi-lite/src/core/layouts/collection/forceAtlas2.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,12 @@ export const ForceAtlas2Layout = {
7676
},
7777
{ id: "slowDown", type: "number", defaultValue: FA2_DEFAULT_SETTINGS.slowDown, min: 1, step:"any"},
7878
{ id: "strongGravityMode", type: "boolean", defaultValue: FA2_DEFAULT_SETTINGS.strongGravityMode },
79+
{
80+
id: "getNodeFixedAttribut",
81+
type: "attribute",
82+
itemType: "nodes",
83+
restriction: ["boolean"],
84+
required: false,
85+
},
7986
],
8087
} as WorkerLayout<ForceAtlas2LayoutParameters>;

packages/gephi-lite/src/core/layouts/index.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ export const stopLayout = asyncAction(async (isForRestart = false) => {
5959
if (!isForRestart) layoutStateAtom.set((prev) => ({ ...prev, type: "idle" }));
6060
});
6161

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

66+
const dataset = graphDatasetAtom.get();
6667
const { setNodePositions } = graphDatasetActions;
6768

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

7677
// generate positions
77-
const dataset = graphDatasetAtom.get();
7878
const fullGraph = dataGraphToFullGraph(dataset);
7979
const positions = layout.run(fullGraph, { settings: params });
8080

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

9292
// Async layout
9393
if (layout.type === "worker") {
94-
const worker = new layout.supervisor(sigmaGraphAtom.get(), { settings: params });
94+
const graph = sigmaGraphAtom.get();
95+
96+
// Fixed node management
97+
// ---------------------
98+
// If layout parameter has a `getNodeFixedAttribut`, then we have to set the 'fixed' attribut in sigma's graph
99+
// On a layout restart, if parameter has been removed, we need to set to false
100+
// We also use the 'fixed' attribut for drag'n'drop
101+
graph.updateEachNodeAttributes((id, attrs) => {
102+
let fixed = attrs.dragging === true;
103+
if ("getNodeFixedAttribut" in params && params.getNodeFixedAttribut) {
104+
const fixedAttribut = `${params.getNodeFixedAttribut}`;
105+
if (dataset.nodeData[id][fixedAttribut] === true) {
106+
fixed = true;
107+
}
108+
}
109+
return {
110+
...attrs,
111+
fixed,
112+
};
113+
});
114+
115+
const worker = new layout.supervisor(graph, { settings: params });
95116
worker.start();
96117
layoutStateAtom.set((prev) => ({ ...prev, type: "running", layoutId: id, supervisor: worker }));
97118
}

packages/gephi-lite/src/locales/dev.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@
539539
"description": "Influence of the edge’s weights on the layout",
540540
"title": "Edge weight influence"
541541
},
542+
"getNodeFixedAttribut": {
543+
"title": "Attribute indicating whether the node’s position is fixed"
544+
},
542545
"gravity": {
543546
"description": "Strength of the layout’s gravity",
544547
"title": "Gravity"

packages/gephi-lite/src/locales/fr.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,9 @@
613613
"description": "Influence des poids des liens sur la spatialisation",
614614
"title": "Influence du poids des liens"
615615
},
616+
"getNodeFixedAttribut": {
617+
"title": "Attribut indiquant si la position du nœud est fixée"
618+
},
616619
"gravity": {
617620
"description": "Intensité de la gravité de la spatialisation",
618621
"title": "Gravité"

packages/gephi-lite/src/views/graphPage/controllers/EventsController.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ export const EventsController: FC = () => {
9696

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

132132
for (const node in dragState.initialNodesPosition) {
133133
const initialPosition = dragState.initialNodesPosition[node];
134-
graph.setNodeAttribute(node, "fixed", true);
134+
graph.setNodeAttribute(node, "dragging", true);
135135
graph.setNodeAttribute(node, "x", initialPosition.x + delta.x);
136136
graph.setNodeAttribute(node, "y", initialPosition.y + delta.y);
137137
}
@@ -162,7 +162,12 @@ export const EventsController: FC = () => {
162162
resetHoveredNode();
163163
resetHoveredEdge();
164164
}
165-
graph.forEachNode((node) => graph.setNodeAttribute(node, "fixed", false));
165+
// Remove the dragging state on each node
166+
graph.forEachNode((node) => graph.setNodeAttribute(node, "dragging", false));
167+
// Emit the last dragged event when the dragging prop is removed
168+
// so the algo can restart with the good data
169+
globalEmitter.emit(EVENTS.nodesDragged);
170+
// Update drag status
166171
dragStateRef.current = { type: "idle" };
167172
}
168173
};

packages/sdk/src/graph/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export type NodeRenderingData = Attributes &
4040
rawSize?: number;
4141
image?: string | null;
4242
fixed?: boolean;
43+
dragging?:boolean;
4344
};
4445

4546
export interface GraphMetadata {

0 commit comments

Comments
 (0)