diff --git a/src/placing.js b/src/placing.js index 5e227a8..dddc3d0 100644 --- a/src/placing.js +++ b/src/placing.js @@ -92,23 +92,33 @@ module.exports = (options) => { * @returns {boolean} */ nodeBetween: (nodes, n1, n2) => { - const x1 = nodes[n1].x; - const y1 = nodes[n1].y; - const x2 = nodes[n2].x; - const y2 = nodes[n2].y; + let x1 = nodes[n1].x; + let y1 = nodes[n1].y; + let x2 = nodes[n2].x; + let y2 = nodes[n2].y; - const dx = Math.sign(x2 - x1); - const dy = Math.sign(y2 - y1); + const dx = x2 - x1; + const dy = y2 - y1; const samePos = (x, y) => n => n.x === x && n.y === y && n.name !== n1 && n.name !== n2; - if (dx >= dy) { + if (Math.abs(dx) >= Math.abs(dy)) { + if (x1 > x2) { + let tmp = x1; + x1 = x2; + x2 = tmp; + } for (let x = x1; x <= x2; x++) { let y = Math.round(y1 + dy * (x - x1) / dx); if (Object.values(nodes).find(samePos(x, y))) return true; } } else { + if (y1 > y2) { + let tmp = y1; + y1 = y2; + y2 = tmp; + } for (let y = y1; y <= y2; y++) { let x = Math.round(x1 + dx * (y - y1) / dy); if (Object.values(nodes).find(samePos(x, y))) @@ -368,9 +378,14 @@ module.exports = (options) => { nodes = self.applyLinks(nodes, links); - if (nodes) + if (nodes) { self.correctPlacing(nodes); + Object.values(nodes).forEach(node => { + delete node.const; + }); + } + return nodes; }, diff --git a/test/placing.test.js b/test/placing.test.js index e594c3c..8ef582a 100644 --- a/test/placing.test.js +++ b/test/placing.test.js @@ -112,6 +112,17 @@ describe('nodeBetween', () => { }, 'a', 'b'); expect(res).toBe(true); }); + test('between diagonal 3', () => { + const res = placing({debug: true}).nodeBetween({ + '1': {'name': '1', 'x': 1, 'y': 0}, + '2': {'name': '2', 'x': 2, 'y': 0}, + '3': {'name': '3', 'x': 1, 'y': 1}, + '4': {'name': '4', 'x': 2, 'y': 1}, + '5': {'name': '5', 'x': 0, 'y': 0}, + '6': {'name': '6', 'x': 0, 'y': 1} + }, '4', '5'); + expect(res).toBe(true); + }); }); describe('getPosition', () => { @@ -347,6 +358,65 @@ describe('isValid', () => { }); }); +describe('correctPlacing', () => { + test('no nodes', () => { + const nodes = {}; + placing({debug: true}).correctPlacing(nodes); + expect(nodes).toEqual({}); + }); + test('several nodes', () => { + const nodes = { + 'a': {x: 3, y: 2}, + 'b': {x: -2, y: 5}, + 'c': {x: -4, y: 3} + }; + placing({debug: true}).correctPlacing(nodes); + expect(nodes).toEqual({ + 'a': {x: 7, y: 0}, + 'b': {x: 2, y: 3}, + 'c': {x: 0, y: 1} + }); + }); +}); + +describe('compute', () => { + const createNodes = (n) => { + const nodes = {}; + new Array(n).fill(0).forEach((u, i) => nodes['' + (i + 1)] = {name: '' + (i + 1)}); + return nodes; + }; + + test('no nodes', () => { + const nodes = placing({'max-link-length': 2, 'expand': 'h', diagonals: false}).compute({}, []); + expect(nodes).toEqual({}); + }); + test('3 nodes no link', () => { + const nodes = placing({'max-link-length': 2, 'expand': 'h', diagonals: false}).compute(createNodes(3), []); + expect(nodes).toEqual({ + '1': {name: '1', x: 0, y: 0}, + '2': {name: '2', x: 1, y: 0}, + '3': {name: '3', x: 2, y: 0} + }); + }); + test('6 nodes 6 links', () => { + const nodes = placing({'max-link-length': 2, 'expand': 'h', diagonals: true}).compute(createNodes(6), [ + {from: '1', to: '2', direction: 'right'}, + {from: '1', to: '3', direction: 'down'}, + {from: '3', to: '4', direction: 'right'}, + {from: '4', to: '5', direction: 'up'}, + {from: '3', to: '6', direction: 'left'} + ]); + expect(nodes).toEqual({ + '1': {name: '1', x: 1, y: 1}, + '2': {name: '2', x: 2, y: 1}, + '3': {name: '3', x: 1, y: 2}, + '4': {name: '4', x: 3, y: 1}, + '5': {name: '5', x: 3, y: 0}, + '6': {name: '6', x: 0, y: 2} + }); + }); +}); + test('no debug (coverage)', () => { placing({'max-link-length': 2, 'expand': 'h', diagonals: false}).compute({ '1': {name: '1'}, '2': {name: '2'}, '3': {name: '3'}, '4': {name: '4'}, '5': {name: '5'}, '6': {name: '6'}