Skip to content

Commit 48c155e

Browse files
committed
[layout Quality] bug when applying sync layout
sync layout and isolated data manipulation synced through a custom event
1 parent b8c266b commit 48c155e

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

src/core/graph/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import EventEmitter from "events";
12
import { Attributes } from "graphology-types";
23
import { isNil, isString, keys, last, mapValues, omit, omitBy, values } from "lodash";
34
import { Coordinates } from "sigma/types";
@@ -205,6 +206,7 @@ export const sigmaGraphAtom = derivedAtom(
205206
if (graph) {
206207
graph.clear();
207208
graph.import(newGraph);
209+
(graph as EventEmitter).emit("graphImported");
208210

209211
return graph;
210212
}

src/core/layouts/index.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import EventEmitter from "events";
12
import { connectedCloseness } from "graphology-metrics/layout-quality";
23
import { debounce, identity, pick } from "lodash";
34
import seedrandom from "seedrandom";
@@ -36,8 +37,6 @@ export const layoutStateAtom = atom<LayoutState>(getLocalStorageLayoutState());
3637
export const startLayout = asyncAction(async (id: string, params: unknown) => {
3738
const { setNodePositions } = graphDatasetActions;
3839
const dataset = graphDatasetAtom.get();
39-
const { quality } = layoutStateAtom.get();
40-
const { computeLayoutQualityMetric } = layoutActions;
4140

4241
// search the layout
4342
const layout = LAYOUTS.find((l) => l.id === id);
@@ -56,7 +55,6 @@ export const startLayout = asyncAction(async (id: string, params: unknown) => {
5655
// To prevent resetting the camera before sigma receives new data, we
5756
// need to wait a frame, and also wait for it to trigger a refresh:
5857
setTimeout(() => {
59-
if (quality.enabled) computeLayoutQualityMetric();
6058
layoutStateAtom.set((prev) => ({ ...prev, type: "idle" }));
6159
resetCamera({ forceRefresh: false });
6260
}, 0);
@@ -94,7 +92,7 @@ export const setQuality: Producer<LayoutState, [LayoutQuality]> = (quality) => {
9492
return (state) => ({ ...state, quality });
9593
};
9694

97-
export const computeLayoutQualityMetric: Producer<LayoutState, []> = () => {
95+
const _computeLayoutQualityMetric: Producer<LayoutState, []> = () => {
9896
const sigmaGraph = sigmaGraphAtom.get();
9997
try {
10098
const metric = connectedCloseness(sigmaGraph, {
@@ -110,7 +108,7 @@ export const layoutActions = {
110108
startLayout,
111109
stopLayout,
112110
setQuality: producerToAction(setQuality, layoutStateAtom),
113-
computeLayoutQualityMetric: producerToAction(computeLayoutQualityMetric, layoutStateAtom),
111+
computeLayoutQualityMetric: producerToAction(_computeLayoutQualityMetric, layoutStateAtom),
114112
};
115113

116114
const gridEnabledAtom = derivedAtom(layoutStateAtom, (value) => pick(value.quality, "enabled"), {
@@ -125,10 +123,17 @@ gridEnabledAtom.bindEffect((enabled) => {
125123

126124
computeLayoutQualityMetric();
127125
const sigmaGraph = sigmaGraphAtom.get();
126+
// this event is triggered when sigma data are updated by the derived atom mechanism through a graph import
127+
// this is a custom event
128+
(sigmaGraph as EventEmitter).on("graphImported", fn);
129+
130+
// this event is triggered by user manually changing node positions by dragging node
128131
sigmaGraph.on("nodeAttributesUpdated", fn);
132+
// this event is triggered by async layout
129133
sigmaGraph.on("eachNodeAttributesUpdated", fn);
130134

131135
return () => {
136+
(sigmaGraph as EventEmitter).off("graphImported", fn);
132137
sigmaGraph.off("eachNodeAttributesUpdated", fn);
133138
sigmaGraph.off("nodeAttributesUpdated", fn);
134139
};

0 commit comments

Comments
 (0)