diff --git a/lib/network/modules/LayoutEngine.js b/lib/network/modules/LayoutEngine.js index ccee1a438..ad907ebd8 100644 --- a/lib/network/modules/LayoutEngine.js +++ b/lib/network/modules/LayoutEngine.js @@ -1,4 +1,3 @@ -'use strict'; /** * There's a mix-up with terms in the code. Following are the formal definitions: * @@ -30,6 +29,8 @@ * The layout is a way to arrange the nodes in the view; this can be done * on non-hierarchical networks as well. The converse is also possible. */ +'use strict'; +var TimSort = require('timsort'); let util = require('../../util'); var NetworkUtil = require('../NetworkUtil').default; var {HorizontalStrategy, VerticalStrategy} = require('./components/DirectionStrategy.js'); @@ -1422,7 +1423,7 @@ class LayoutEngine { result.push(Number(size)); }); - result.sort(function(a, b) { + TimSort.sort(result, function(a, b) { return b - a; }); diff --git a/lib/network/modules/components/DirectionStrategy.js b/lib/network/modules/components/DirectionStrategy.js index b72e127eb..ac3151ce5 100644 --- a/lib/network/modules/components/DirectionStrategy.js +++ b/lib/network/modules/components/DirectionStrategy.js @@ -3,6 +3,7 @@ * * Strategy pattern for usage of direction methods for hierarchical layouts. */ +var TimSort = require('timsort'); /** @@ -87,6 +88,15 @@ class DirectionInterface { /** * Sort array of nodes on the unfixed coordinates. * + * **Note:** chrome has non-stable sorting implementation, which + * has a tendency to change the order of the array items, + * even if the custom sort function returns 0. + * + * For this reason, an external sort implementation is used, + * which has the added benefit of being faster than the standard + * platforms implementation. This has been verified on `node.js`, + * `firefox` and `chrome` (all linux). + * * @param {Array.} nodeArray array of nodes to sort */ sort(nodeArray) { this.fake_use(nodeArray); this.abstract(); } @@ -156,9 +166,7 @@ class VerticalStrategy extends DirectionInterface { /** @inheritdoc */ sort(nodeArray) { - nodeArray.sort(function(a, b) { - // Test on 'undefined' takes care of divergent behaviour in chrome - if (a.x === undefined || b.x === undefined) return 0; // THIS HAPPENS + TimSort.sort(nodeArray, function(a, b) { return a.x - b.x; }); } @@ -221,9 +229,7 @@ class HorizontalStrategy extends DirectionInterface { /** @inheritdoc */ sort(nodeArray) { - nodeArray.sort(function(a, b) { - // Test on 'undefined' takes care of divergent behaviour in chrome - if (a.y === undefined || b.y === undefined) return 0; // THIS HAPPENS + TimSort.sort(nodeArray, function(a, b) { return a.y - b.y; }); } diff --git a/package.json b/package.json index 867be4a80..de2515f54 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "hammerjs": "^2.0.8", "keycharm": "^0.2.0", "moment": "^2.18.1", - "propagating-hammerjs": "^1.4.6" + "propagating-hammerjs": "^1.4.6", + "timsort": "^0.3.0" }, "devDependencies": { "async": "^2.5.0",