diff --git a/client/app/scripts/charts/__tests__/node-layout-test.js b/client/app/scripts/charts/__tests__/nodes-layout-test.js similarity index 91% rename from client/app/scripts/charts/__tests__/node-layout-test.js rename to client/app/scripts/charts/__tests__/nodes-layout-test.js index 47ac7ab2a..ab21cee23 100644 --- a/client/app/scripts/charts/__tests__/node-layout-test.js +++ b/client/app/scripts/charts/__tests__/nodes-layout-test.js @@ -131,6 +131,18 @@ describe('NodesLayout', () => { edges: fromJS({ [edge('n1', 'n4')]: {id: edge('n1', 'n4'), source: 'n1', target: 'n4'} }) + }, + layoutProps: { + nodes: fromJS({ + n1: {id: 'n1', label: 'lold', labelMinor: 'lmold', rank: 'rold'}, + }), + edges: fromJS({}) + }, + layoutProps2: { + nodes: fromJS({ + n1: {id: 'n1', label: 'lnew', labelMinor: 'lmnew', rank: 'rnew', x: 111, y: 109}, + }), + edges: fromJS({}) } }; @@ -438,4 +450,29 @@ describe('NodesLayout', () => { resultCoords = getNodeCoordinates(result.nodes); expect(resultCoords).not.toEqual(coords); }); + + it('only caches layout-related properties', () => { + // populate cache by doing a full layout run, this stores layout values in cache + const first = NodesLayout.doLayout( + nodeSets.layoutProps.nodes, + nodeSets.layoutProps.edges, + { noCache: true } + ); + + // now pass updated nodes with modified values + const second = NodesLayout.doLayout( + nodeSets.layoutProps2.nodes, + nodeSets.layoutProps2.edges, + {} + ); + + // new labels should not be overwritten by cache + nodes = second.nodes.toJS(); + expect(nodes.n1.label).toEqual('lnew'); + expect(nodes.n1.labelMinor).toEqual('lmnew'); + // but layout values should be preferred from cache + expect(nodes.n1.rank).toEqual('rold'); + expect(nodes.n1.x).toEqual(first.nodes.getIn(['n1', 'x'])); + expect(nodes.n1.y).toEqual(first.nodes.getIn(['n1', 'y'])); + }); }); diff --git a/client/app/scripts/utils/__tests__/math-utils-test.js b/client/app/scripts/utils/__tests__/math-utils-test.js index 75697dcfc..70481c039 100644 --- a/client/app/scripts/utils/__tests__/math-utils-test.js +++ b/client/app/scripts/utils/__tests__/math-utils-test.js @@ -32,8 +32,8 @@ describe('MathUtils', () => { const entryF = { pointF: { x: 30, y: 0 } }; it('it should return the minimal distance between any two points in the collection', () => { - expect(f(fromJS({}))).toBe(0); - expect(f(fromJS({...entryA}))).toBe(0); + expect(f(fromJS({}))).toBe(Infinity); + expect(f(fromJS({...entryA}))).toBe(Infinity); expect(f(fromJS({...entryA, ...entryB}))).toBe(30); expect(f(fromJS({...entryA, ...entryC}))).toBe(40); expect(f(fromJS({...entryB, ...entryC}))).toBe(50); diff --git a/client/app/scripts/utils/math-utils.js b/client/app/scripts/utils/math-utils.js index 37ff46a94..7840f4110 100644 --- a/client/app/scripts/utils/math-utils.js +++ b/client/app/scripts/utils/math-utils.js @@ -28,14 +28,12 @@ function euclideanDistance(pointA, pointB) { // This could be solved in O(N log N) (see https://en.wikipedia.org/wiki/Closest_pair_of_points_problem), // but this brute-force O(N^2) should be good enough for a reasonable number of nodes. export function minEuclideanDistanceBetweenPoints(points) { - let minDistance = 0; - let foundPair = false; + let minDistance = Infinity; points.forEach((pointA, idA) => { points.forEach((pointB, idB) => { const distance = euclideanDistance(pointA, pointB); - if (idA !== idB && (distance < minDistance || !foundPair)) { + if (idA !== idB && distance < minDistance) { minDistance = distance; - foundPair = true; } }); });