| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447 |
- (function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory(require("layout-base"));
- else if(typeof define === 'function' && define.amd)
- define(["layout-base"], factory);
- else if(typeof exports === 'object')
- exports["coseBase"] = factory(require("layout-base"));
- else
- root["coseBase"] = factory(root["layoutBase"]);
- })(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
- return /******/ (function(modules) { // webpackBootstrap
- /******/ // The module cache
- /******/ var installedModules = {};
- /******/
- /******/ // The require function
- /******/ function __webpack_require__(moduleId) {
- /******/
- /******/ // Check if module is in cache
- /******/ if(installedModules[moduleId]) {
- /******/ return installedModules[moduleId].exports;
- /******/ }
- /******/ // Create a new module (and put it into the cache)
- /******/ var module = installedModules[moduleId] = {
- /******/ i: moduleId,
- /******/ l: false,
- /******/ exports: {}
- /******/ };
- /******/
- /******/ // Execute the module function
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- /******/
- /******/ // Flag the module as loaded
- /******/ module.l = true;
- /******/
- /******/ // Return the exports of the module
- /******/ return module.exports;
- /******/ }
- /******/
- /******/
- /******/ // expose the modules object (__webpack_modules__)
- /******/ __webpack_require__.m = modules;
- /******/
- /******/ // expose the module cache
- /******/ __webpack_require__.c = installedModules;
- /******/
- /******/ // identity function for calling harmony imports with the correct context
- /******/ __webpack_require__.i = function(value) { return value; };
- /******/
- /******/ // define getter function for harmony exports
- /******/ __webpack_require__.d = function(exports, name, getter) {
- /******/ if(!__webpack_require__.o(exports, name)) {
- /******/ Object.defineProperty(exports, name, {
- /******/ configurable: false,
- /******/ enumerable: true,
- /******/ get: getter
- /******/ });
- /******/ }
- /******/ };
- /******/
- /******/ // getDefaultExport function for compatibility with non-harmony modules
- /******/ __webpack_require__.n = function(module) {
- /******/ var getter = module && module.__esModule ?
- /******/ function getDefault() { return module['default']; } :
- /******/ function getModuleExports() { return module; };
- /******/ __webpack_require__.d(getter, 'a', getter);
- /******/ return getter;
- /******/ };
- /******/
- /******/ // Object.prototype.hasOwnProperty.call
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
- /******/
- /******/ // __webpack_public_path__
- /******/ __webpack_require__.p = "";
- /******/
- /******/ // Load entry module and return exports
- /******/ return __webpack_require__(__webpack_require__.s = 7);
- /******/ })
- /************************************************************************/
- /******/ ([
- /* 0 */
- /***/ (function(module, exports) {
- module.exports = __WEBPACK_EXTERNAL_MODULE_0__;
- /***/ }),
- /* 1 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var FDLayoutConstants = __webpack_require__(0).FDLayoutConstants;
- function CoSEConstants() {}
- //CoSEConstants inherits static props in FDLayoutConstants
- for (var prop in FDLayoutConstants) {
- CoSEConstants[prop] = FDLayoutConstants[prop];
- }
- CoSEConstants.DEFAULT_USE_MULTI_LEVEL_SCALING = false;
- CoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH;
- CoSEConstants.DEFAULT_COMPONENT_SEPERATION = 60;
- CoSEConstants.TILE = true;
- CoSEConstants.TILING_PADDING_VERTICAL = 10;
- CoSEConstants.TILING_PADDING_HORIZONTAL = 10;
- CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = false; // make this true when cose is used incrementally as a part of other non-incremental layout
- module.exports = CoSEConstants;
- /***/ }),
- /* 2 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var FDLayoutEdge = __webpack_require__(0).FDLayoutEdge;
- function CoSEEdge(source, target, vEdge) {
- FDLayoutEdge.call(this, source, target, vEdge);
- }
- CoSEEdge.prototype = Object.create(FDLayoutEdge.prototype);
- for (var prop in FDLayoutEdge) {
- CoSEEdge[prop] = FDLayoutEdge[prop];
- }
- module.exports = CoSEEdge;
- /***/ }),
- /* 3 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var LGraph = __webpack_require__(0).LGraph;
- function CoSEGraph(parent, graphMgr, vGraph) {
- LGraph.call(this, parent, graphMgr, vGraph);
- }
- CoSEGraph.prototype = Object.create(LGraph.prototype);
- for (var prop in LGraph) {
- CoSEGraph[prop] = LGraph[prop];
- }
- module.exports = CoSEGraph;
- /***/ }),
- /* 4 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var LGraphManager = __webpack_require__(0).LGraphManager;
- function CoSEGraphManager(layout) {
- LGraphManager.call(this, layout);
- }
- CoSEGraphManager.prototype = Object.create(LGraphManager.prototype);
- for (var prop in LGraphManager) {
- CoSEGraphManager[prop] = LGraphManager[prop];
- }
- module.exports = CoSEGraphManager;
- /***/ }),
- /* 5 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var FDLayoutNode = __webpack_require__(0).FDLayoutNode;
- var IMath = __webpack_require__(0).IMath;
- function CoSENode(gm, loc, size, vNode) {
- FDLayoutNode.call(this, gm, loc, size, vNode);
- }
- CoSENode.prototype = Object.create(FDLayoutNode.prototype);
- for (var prop in FDLayoutNode) {
- CoSENode[prop] = FDLayoutNode[prop];
- }
- CoSENode.prototype.move = function () {
- var layout = this.graphManager.getLayout();
- this.displacementX = layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.noOfChildren;
- this.displacementY = layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.noOfChildren;
- if (Math.abs(this.displacementX) > layout.coolingFactor * layout.maxNodeDisplacement) {
- this.displacementX = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementX);
- }
- if (Math.abs(this.displacementY) > layout.coolingFactor * layout.maxNodeDisplacement) {
- this.displacementY = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementY);
- }
- // a simple node, just move it
- if (this.child == null) {
- this.moveBy(this.displacementX, this.displacementY);
- }
- // an empty compound node, again just move it
- else if (this.child.getNodes().length == 0) {
- this.moveBy(this.displacementX, this.displacementY);
- }
- // non-empty compound node, propogate movement to children as well
- else {
- this.propogateDisplacementToChildren(this.displacementX, this.displacementY);
- }
- layout.totalDisplacement += Math.abs(this.displacementX) + Math.abs(this.displacementY);
- this.springForceX = 0;
- this.springForceY = 0;
- this.repulsionForceX = 0;
- this.repulsionForceY = 0;
- this.gravitationForceX = 0;
- this.gravitationForceY = 0;
- this.displacementX = 0;
- this.displacementY = 0;
- };
- CoSENode.prototype.propogateDisplacementToChildren = function (dX, dY) {
- var nodes = this.getChild().getNodes();
- var node;
- for (var i = 0; i < nodes.length; i++) {
- node = nodes[i];
- if (node.getChild() == null) {
- node.moveBy(dX, dY);
- node.displacementX += dX;
- node.displacementY += dY;
- } else {
- node.propogateDisplacementToChildren(dX, dY);
- }
- }
- };
- CoSENode.prototype.setPred1 = function (pred1) {
- this.pred1 = pred1;
- };
- CoSENode.prototype.getPred1 = function () {
- return pred1;
- };
- CoSENode.prototype.getPred2 = function () {
- return pred2;
- };
- CoSENode.prototype.setNext = function (next) {
- this.next = next;
- };
- CoSENode.prototype.getNext = function () {
- return next;
- };
- CoSENode.prototype.setProcessed = function (processed) {
- this.processed = processed;
- };
- CoSENode.prototype.isProcessed = function () {
- return processed;
- };
- module.exports = CoSENode;
- /***/ }),
- /* 6 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var FDLayout = __webpack_require__(0).FDLayout;
- var CoSEGraphManager = __webpack_require__(4);
- var CoSEGraph = __webpack_require__(3);
- var CoSENode = __webpack_require__(5);
- var CoSEEdge = __webpack_require__(2);
- var CoSEConstants = __webpack_require__(1);
- var FDLayoutConstants = __webpack_require__(0).FDLayoutConstants;
- var LayoutConstants = __webpack_require__(0).LayoutConstants;
- var Point = __webpack_require__(0).Point;
- var PointD = __webpack_require__(0).PointD;
- var Layout = __webpack_require__(0).Layout;
- var Integer = __webpack_require__(0).Integer;
- var IGeometry = __webpack_require__(0).IGeometry;
- var LGraph = __webpack_require__(0).LGraph;
- var Transform = __webpack_require__(0).Transform;
- function CoSELayout() {
- FDLayout.call(this);
- this.toBeTiled = {}; // Memorize if a node is to be tiled or is tiled
- }
- CoSELayout.prototype = Object.create(FDLayout.prototype);
- for (var prop in FDLayout) {
- CoSELayout[prop] = FDLayout[prop];
- }
- CoSELayout.prototype.newGraphManager = function () {
- var gm = new CoSEGraphManager(this);
- this.graphManager = gm;
- return gm;
- };
- CoSELayout.prototype.newGraph = function (vGraph) {
- return new CoSEGraph(null, this.graphManager, vGraph);
- };
- CoSELayout.prototype.newNode = function (vNode) {
- return new CoSENode(this.graphManager, vNode);
- };
- CoSELayout.prototype.newEdge = function (vEdge) {
- return new CoSEEdge(null, null, vEdge);
- };
- CoSELayout.prototype.initParameters = function () {
- FDLayout.prototype.initParameters.call(this, arguments);
- if (!this.isSubLayout) {
- if (CoSEConstants.DEFAULT_EDGE_LENGTH < 10) {
- this.idealEdgeLength = 10;
- } else {
- this.idealEdgeLength = CoSEConstants.DEFAULT_EDGE_LENGTH;
- }
- this.useSmartIdealEdgeLengthCalculation = CoSEConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;
- this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;
- this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;
- this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;
- this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;
- this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;
- this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;
- // variables for tree reduction support
- this.prunedNodesAll = [];
- this.growTreeIterations = 0;
- this.afterGrowthIterations = 0;
- this.isTreeGrowing = false;
- this.isGrowthFinished = false;
- // variables for cooling
- this.coolingCycle = 0;
- this.maxCoolingCycle = this.maxIterations / FDLayoutConstants.CONVERGENCE_CHECK_PERIOD;
- this.finalTemperature = FDLayoutConstants.CONVERGENCE_CHECK_PERIOD / this.maxIterations;
- this.coolingAdjuster = 1;
- }
- };
- CoSELayout.prototype.layout = function () {
- var createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;
- if (createBendsAsNeeded) {
- this.createBendpoints();
- this.graphManager.resetAllEdges();
- }
- this.level = 0;
- return this.classicLayout();
- };
- CoSELayout.prototype.classicLayout = function () {
- this.nodesWithGravity = this.calculateNodesToApplyGravitationTo();
- this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity);
- this.calcNoOfChildrenForAllNodes();
- this.graphManager.calcLowestCommonAncestors();
- this.graphManager.calcInclusionTreeDepths();
- this.graphManager.getRoot().calcEstimatedSize();
- this.calcIdealEdgeLengths();
- if (!this.incremental) {
- var forest = this.getFlatForest();
- // The graph associated with this layout is flat and a forest
- if (forest.length > 0) {
- this.positionNodesRadially(forest);
- }
- // The graph associated with this layout is not flat or a forest
- else {
- // Reduce the trees when incremental mode is not enabled and graph is not a forest
- this.reduceTrees();
- // Update nodes that gravity will be applied
- this.graphManager.resetAllNodesToApplyGravitation();
- var allNodes = new Set(this.getAllNodes());
- var intersection = this.nodesWithGravity.filter(function (x) {
- return allNodes.has(x);
- });
- this.graphManager.setAllNodesToApplyGravitation(intersection);
- this.positionNodesRandomly();
- }
- } else {
- if (CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL) {
- // Reduce the trees in incremental mode if only this constant is set to true
- this.reduceTrees();
- // Update nodes that gravity will be applied
- this.graphManager.resetAllNodesToApplyGravitation();
- var allNodes = new Set(this.getAllNodes());
- var intersection = this.nodesWithGravity.filter(function (x) {
- return allNodes.has(x);
- });
- this.graphManager.setAllNodesToApplyGravitation(intersection);
- }
- }
- this.initSpringEmbedder();
- this.runSpringEmbedder();
- return true;
- };
- CoSELayout.prototype.tick = function () {
- this.totalIterations++;
- if (this.totalIterations === this.maxIterations && !this.isTreeGrowing && !this.isGrowthFinished) {
- if (this.prunedNodesAll.length > 0) {
- this.isTreeGrowing = true;
- } else {
- return true;
- }
- }
- if (this.totalIterations % FDLayoutConstants.CONVERGENCE_CHECK_PERIOD == 0 && !this.isTreeGrowing && !this.isGrowthFinished) {
- if (this.isConverged()) {
- if (this.prunedNodesAll.length > 0) {
- this.isTreeGrowing = true;
- } else {
- return true;
- }
- }
- this.coolingCycle++;
- if (this.layoutQuality == 0) {
- // quality - "draft"
- this.coolingAdjuster = this.coolingCycle;
- } else if (this.layoutQuality == 1) {
- // quality - "default"
- this.coolingAdjuster = this.coolingCycle / 3;
- }
- // cooling schedule is based on http://www.btluke.com/simanf1.html -> cooling schedule 3
- this.coolingFactor = Math.max(this.initialCoolingFactor - Math.pow(this.coolingCycle, Math.log(100 * (this.initialCoolingFactor - this.finalTemperature)) / Math.log(this.maxCoolingCycle)) / 100 * this.coolingAdjuster, this.finalTemperature);
- this.animationPeriod = Math.ceil(this.initialAnimationPeriod * Math.sqrt(this.coolingFactor));
- }
- // Operations while tree is growing again
- if (this.isTreeGrowing) {
- if (this.growTreeIterations % 10 == 0) {
- if (this.prunedNodesAll.length > 0) {
- this.graphManager.updateBounds();
- this.updateGrid();
- this.growTree(this.prunedNodesAll);
- // Update nodes that gravity will be applied
- this.graphManager.resetAllNodesToApplyGravitation();
- var allNodes = new Set(this.getAllNodes());
- var intersection = this.nodesWithGravity.filter(function (x) {
- return allNodes.has(x);
- });
- this.graphManager.setAllNodesToApplyGravitation(intersection);
- this.graphManager.updateBounds();
- this.updateGrid();
- this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;
- } else {
- this.isTreeGrowing = false;
- this.isGrowthFinished = true;
- }
- }
- this.growTreeIterations++;
- }
- // Operations after growth is finished
- if (this.isGrowthFinished) {
- if (this.isConverged()) {
- return true;
- }
- if (this.afterGrowthIterations % 10 == 0) {
- this.graphManager.updateBounds();
- this.updateGrid();
- }
- this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL * ((100 - this.afterGrowthIterations) / 100);
- this.afterGrowthIterations++;
- }
- var gridUpdateAllowed = !this.isTreeGrowing && !this.isGrowthFinished;
- var forceToNodeSurroundingUpdate = this.growTreeIterations % 10 == 1 && this.isTreeGrowing || this.afterGrowthIterations % 10 == 1 && this.isGrowthFinished;
- this.totalDisplacement = 0;
- this.graphManager.updateBounds();
- this.calcSpringForces();
- this.calcRepulsionForces(gridUpdateAllowed, forceToNodeSurroundingUpdate);
- this.calcGravitationalForces();
- this.moveNodes();
- this.animate();
- return false; // Layout is not ended yet return false
- };
- CoSELayout.prototype.getPositionsData = function () {
- var allNodes = this.graphManager.getAllNodes();
- var pData = {};
- for (var i = 0; i < allNodes.length; i++) {
- var rect = allNodes[i].rect;
- var id = allNodes[i].id;
- pData[id] = {
- id: id,
- x: rect.getCenterX(),
- y: rect.getCenterY(),
- w: rect.width,
- h: rect.height
- };
- }
- return pData;
- };
- CoSELayout.prototype.runSpringEmbedder = function () {
- this.initialAnimationPeriod = 25;
- this.animationPeriod = this.initialAnimationPeriod;
- var layoutEnded = false;
- // If aminate option is 'during' signal that layout is supposed to start iterating
- if (FDLayoutConstants.ANIMATE === 'during') {
- this.emit('layoutstarted');
- } else {
- // If aminate option is 'during' tick() function will be called on index.js
- while (!layoutEnded) {
- layoutEnded = this.tick();
- }
- this.graphManager.updateBounds();
- }
- };
- CoSELayout.prototype.calculateNodesToApplyGravitationTo = function () {
- var nodeList = [];
- var graph;
- var graphs = this.graphManager.getGraphs();
- var size = graphs.length;
- var i;
- for (i = 0; i < size; i++) {
- graph = graphs[i];
- graph.updateConnected();
- if (!graph.isConnected) {
- nodeList = nodeList.concat(graph.getNodes());
- }
- }
- return nodeList;
- };
- CoSELayout.prototype.createBendpoints = function () {
- var edges = [];
- edges = edges.concat(this.graphManager.getAllEdges());
- var visited = new Set();
- var i;
- for (i = 0; i < edges.length; i++) {
- var edge = edges[i];
- if (!visited.has(edge)) {
- var source = edge.getSource();
- var target = edge.getTarget();
- if (source == target) {
- edge.getBendpoints().push(new PointD());
- edge.getBendpoints().push(new PointD());
- this.createDummyNodesForBendpoints(edge);
- visited.add(edge);
- } else {
- var edgeList = [];
- edgeList = edgeList.concat(source.getEdgeListToNode(target));
- edgeList = edgeList.concat(target.getEdgeListToNode(source));
- if (!visited.has(edgeList[0])) {
- if (edgeList.length > 1) {
- var k;
- for (k = 0; k < edgeList.length; k++) {
- var multiEdge = edgeList[k];
- multiEdge.getBendpoints().push(new PointD());
- this.createDummyNodesForBendpoints(multiEdge);
- }
- }
- edgeList.forEach(function (edge) {
- visited.add(edge);
- });
- }
- }
- }
- if (visited.size == edges.length) {
- break;
- }
- }
- };
- CoSELayout.prototype.positionNodesRadially = function (forest) {
- // We tile the trees to a grid row by row; first tree starts at (0,0)
- var currentStartingPoint = new Point(0, 0);
- var numberOfColumns = Math.ceil(Math.sqrt(forest.length));
- var height = 0;
- var currentY = 0;
- var currentX = 0;
- var point = new PointD(0, 0);
- for (var i = 0; i < forest.length; i++) {
- if (i % numberOfColumns == 0) {
- // Start of a new row, make the x coordinate 0, increment the
- // y coordinate with the max height of the previous row
- currentX = 0;
- currentY = height;
- if (i != 0) {
- currentY += CoSEConstants.DEFAULT_COMPONENT_SEPERATION;
- }
- height = 0;
- }
- var tree = forest[i];
- // Find the center of the tree
- var centerNode = Layout.findCenterOfTree(tree);
- // Set the staring point of the next tree
- currentStartingPoint.x = currentX;
- currentStartingPoint.y = currentY;
- // Do a radial layout starting with the center
- point = CoSELayout.radialLayout(tree, centerNode, currentStartingPoint);
- if (point.y > height) {
- height = Math.floor(point.y);
- }
- currentX = Math.floor(point.x + CoSEConstants.DEFAULT_COMPONENT_SEPERATION);
- }
- this.transform(new PointD(LayoutConstants.WORLD_CENTER_X - point.x / 2, LayoutConstants.WORLD_CENTER_Y - point.y / 2));
- };
- CoSELayout.radialLayout = function (tree, centerNode, startingPoint) {
- var radialSep = Math.max(this.maxDiagonalInTree(tree), CoSEConstants.DEFAULT_RADIAL_SEPARATION);
- CoSELayout.branchRadialLayout(centerNode, null, 0, 359, 0, radialSep);
- var bounds = LGraph.calculateBounds(tree);
- var transform = new Transform();
- transform.setDeviceOrgX(bounds.getMinX());
- transform.setDeviceOrgY(bounds.getMinY());
- transform.setWorldOrgX(startingPoint.x);
- transform.setWorldOrgY(startingPoint.y);
- for (var i = 0; i < tree.length; i++) {
- var node = tree[i];
- node.transform(transform);
- }
- var bottomRight = new PointD(bounds.getMaxX(), bounds.getMaxY());
- return transform.inverseTransformPoint(bottomRight);
- };
- CoSELayout.branchRadialLayout = function (node, parentOfNode, startAngle, endAngle, distance, radialSeparation) {
- // First, position this node by finding its angle.
- var halfInterval = (endAngle - startAngle + 1) / 2;
- if (halfInterval < 0) {
- halfInterval += 180;
- }
- var nodeAngle = (halfInterval + startAngle) % 360;
- var teta = nodeAngle * IGeometry.TWO_PI / 360;
- // Make polar to java cordinate conversion.
- var cos_teta = Math.cos(teta);
- var x_ = distance * Math.cos(teta);
- var y_ = distance * Math.sin(teta);
- node.setCenter(x_, y_);
- // Traverse all neighbors of this node and recursively call this
- // function.
- var neighborEdges = [];
- neighborEdges = neighborEdges.concat(node.getEdges());
- var childCount = neighborEdges.length;
- if (parentOfNode != null) {
- childCount--;
- }
- var branchCount = 0;
- var incEdgesCount = neighborEdges.length;
- var startIndex;
- var edges = node.getEdgesBetween(parentOfNode);
- // If there are multiple edges, prune them until there remains only one
- // edge.
- while (edges.length > 1) {
- //neighborEdges.remove(edges.remove(0));
- var temp = edges[0];
- edges.splice(0, 1);
- var index = neighborEdges.indexOf(temp);
- if (index >= 0) {
- neighborEdges.splice(index, 1);
- }
- incEdgesCount--;
- childCount--;
- }
- if (parentOfNode != null) {
- //assert edges.length == 1;
- startIndex = (neighborEdges.indexOf(edges[0]) + 1) % incEdgesCount;
- } else {
- startIndex = 0;
- }
- var stepAngle = Math.abs(endAngle - startAngle) / childCount;
- for (var i = startIndex; branchCount != childCount; i = ++i % incEdgesCount) {
- var currentNeighbor = neighborEdges[i].getOtherEnd(node);
- // Don't back traverse to root node in current tree.
- if (currentNeighbor == parentOfNode) {
- continue;
- }
- var childStartAngle = (startAngle + branchCount * stepAngle) % 360;
- var childEndAngle = (childStartAngle + stepAngle) % 360;
- CoSELayout.branchRadialLayout(currentNeighbor, node, childStartAngle, childEndAngle, distance + radialSeparation, radialSeparation);
- branchCount++;
- }
- };
- CoSELayout.maxDiagonalInTree = function (tree) {
- var maxDiagonal = Integer.MIN_VALUE;
- for (var i = 0; i < tree.length; i++) {
- var node = tree[i];
- var diagonal = node.getDiagonal();
- if (diagonal > maxDiagonal) {
- maxDiagonal = diagonal;
- }
- }
- return maxDiagonal;
- };
- CoSELayout.prototype.calcRepulsionRange = function () {
- // formula is 2 x (level + 1) x idealEdgeLength
- return 2 * (this.level + 1) * this.idealEdgeLength;
- };
- // Tiling methods
- // Group zero degree members whose parents are not to be tiled, create dummy parents where needed and fill memberGroups by their dummp parent id's
- CoSELayout.prototype.groupZeroDegreeMembers = function () {
- var self = this;
- // array of [parent_id x oneDegreeNode_id]
- var tempMemberGroups = {}; // A temporary map of parent node and its zero degree members
- this.memberGroups = {}; // A map of dummy parent node and its zero degree members whose parents are not to be tiled
- this.idToDummyNode = {}; // A map of id to dummy node
- var zeroDegree = []; // List of zero degree nodes whose parents are not to be tiled
- var allNodes = this.graphManager.getAllNodes();
- // Fill zero degree list
- for (var i = 0; i < allNodes.length; i++) {
- var node = allNodes[i];
- var parent = node.getParent();
- // If a node has zero degree and its parent is not to be tiled if exists add that node to zeroDegres list
- if (this.getNodeDegreeWithChildren(node) === 0 && (parent.id == undefined || !this.getToBeTiled(parent))) {
- zeroDegree.push(node);
- }
- }
- // Create a map of parent node and its zero degree members
- for (var i = 0; i < zeroDegree.length; i++) {
- var node = zeroDegree[i]; // Zero degree node itself
- var p_id = node.getParent().id; // Parent id
- if (typeof tempMemberGroups[p_id] === "undefined") tempMemberGroups[p_id] = [];
- tempMemberGroups[p_id] = tempMemberGroups[p_id].concat(node); // Push node to the list belongs to its parent in tempMemberGroups
- }
- // If there are at least two nodes at a level, create a dummy compound for them
- Object.keys(tempMemberGroups).forEach(function (p_id) {
- if (tempMemberGroups[p_id].length > 1) {
- var dummyCompoundId = "DummyCompound_" + p_id; // The id of dummy compound which will be created soon
- self.memberGroups[dummyCompoundId] = tempMemberGroups[p_id]; // Add dummy compound to memberGroups
- var parent = tempMemberGroups[p_id][0].getParent(); // The parent of zero degree nodes will be the parent of new dummy compound
- // Create a dummy compound with calculated id
- var dummyCompound = new CoSENode(self.graphManager);
- dummyCompound.id = dummyCompoundId;
- dummyCompound.paddingLeft = parent.paddingLeft || 0;
- dummyCompound.paddingRight = parent.paddingRight || 0;
- dummyCompound.paddingBottom = parent.paddingBottom || 0;
- dummyCompound.paddingTop = parent.paddingTop || 0;
- self.idToDummyNode[dummyCompoundId] = dummyCompound;
- var dummyParentGraph = self.getGraphManager().add(self.newGraph(), dummyCompound);
- var parentGraph = parent.getChild();
- // Add dummy compound to parent the graph
- parentGraph.add(dummyCompound);
- // For each zero degree node in this level remove it from its parent graph and add it to the graph of dummy parent
- for (var i = 0; i < tempMemberGroups[p_id].length; i++) {
- var node = tempMemberGroups[p_id][i];
- parentGraph.remove(node);
- dummyParentGraph.add(node);
- }
- }
- });
- };
- CoSELayout.prototype.clearCompounds = function () {
- var childGraphMap = {};
- var idToNode = {};
- // Get compound ordering by finding the inner one first
- this.performDFSOnCompounds();
- for (var i = 0; i < this.compoundOrder.length; i++) {
- idToNode[this.compoundOrder[i].id] = this.compoundOrder[i];
- childGraphMap[this.compoundOrder[i].id] = [].concat(this.compoundOrder[i].getChild().getNodes());
- // Remove children of compounds
- this.graphManager.remove(this.compoundOrder[i].getChild());
- this.compoundOrder[i].child = null;
- }
- this.graphManager.resetAllNodes();
- // Tile the removed children
- this.tileCompoundMembers(childGraphMap, idToNode);
- };
- CoSELayout.prototype.clearZeroDegreeMembers = function () {
- var self = this;
- var tiledZeroDegreePack = this.tiledZeroDegreePack = [];
- Object.keys(this.memberGroups).forEach(function (id) {
- var compoundNode = self.idToDummyNode[id]; // Get the dummy compound
- tiledZeroDegreePack[id] = self.tileNodes(self.memberGroups[id], compoundNode.paddingLeft + compoundNode.paddingRight);
- // Set the width and height of the dummy compound as calculated
- compoundNode.rect.width = tiledZeroDegreePack[id].width;
- compoundNode.rect.height = tiledZeroDegreePack[id].height;
- });
- };
- CoSELayout.prototype.repopulateCompounds = function () {
- for (var i = this.compoundOrder.length - 1; i >= 0; i--) {
- var lCompoundNode = this.compoundOrder[i];
- var id = lCompoundNode.id;
- var horizontalMargin = lCompoundNode.paddingLeft;
- var verticalMargin = lCompoundNode.paddingTop;
- this.adjustLocations(this.tiledMemberPack[id], lCompoundNode.rect.x, lCompoundNode.rect.y, horizontalMargin, verticalMargin);
- }
- };
- CoSELayout.prototype.repopulateZeroDegreeMembers = function () {
- var self = this;
- var tiledPack = this.tiledZeroDegreePack;
- Object.keys(tiledPack).forEach(function (id) {
- var compoundNode = self.idToDummyNode[id]; // Get the dummy compound by its id
- var horizontalMargin = compoundNode.paddingLeft;
- var verticalMargin = compoundNode.paddingTop;
- // Adjust the positions of nodes wrt its compound
- self.adjustLocations(tiledPack[id], compoundNode.rect.x, compoundNode.rect.y, horizontalMargin, verticalMargin);
- });
- };
- CoSELayout.prototype.getToBeTiled = function (node) {
- var id = node.id;
- //firstly check the previous results
- if (this.toBeTiled[id] != null) {
- return this.toBeTiled[id];
- }
- //only compound nodes are to be tiled
- var childGraph = node.getChild();
- if (childGraph == null) {
- this.toBeTiled[id] = false;
- return false;
- }
- var children = childGraph.getNodes(); // Get the children nodes
- //a compound node is not to be tiled if all of its compound children are not to be tiled
- for (var i = 0; i < children.length; i++) {
- var theChild = children[i];
- if (this.getNodeDegree(theChild) > 0) {
- this.toBeTiled[id] = false;
- return false;
- }
- //pass the children not having the compound structure
- if (theChild.getChild() == null) {
- this.toBeTiled[theChild.id] = false;
- continue;
- }
- if (!this.getToBeTiled(theChild)) {
- this.toBeTiled[id] = false;
- return false;
- }
- }
- this.toBeTiled[id] = true;
- return true;
- };
- // Get degree of a node depending of its edges and independent of its children
- CoSELayout.prototype.getNodeDegree = function (node) {
- var id = node.id;
- var edges = node.getEdges();
- var degree = 0;
- // For the edges connected
- for (var i = 0; i < edges.length; i++) {
- var edge = edges[i];
- if (edge.getSource().id !== edge.getTarget().id) {
- degree = degree + 1;
- }
- }
- return degree;
- };
- // Get degree of a node with its children
- CoSELayout.prototype.getNodeDegreeWithChildren = function (node) {
- var degree = this.getNodeDegree(node);
- if (node.getChild() == null) {
- return degree;
- }
- var children = node.getChild().getNodes();
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- degree += this.getNodeDegreeWithChildren(child);
- }
- return degree;
- };
- CoSELayout.prototype.performDFSOnCompounds = function () {
- this.compoundOrder = [];
- this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes());
- };
- CoSELayout.prototype.fillCompexOrderByDFS = function (children) {
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- if (child.getChild() != null) {
- this.fillCompexOrderByDFS(child.getChild().getNodes());
- }
- if (this.getToBeTiled(child)) {
- this.compoundOrder.push(child);
- }
- }
- };
- /**
- * This method places each zero degree member wrt given (x,y) coordinates (top left).
- */
- CoSELayout.prototype.adjustLocations = function (organization, x, y, compoundHorizontalMargin, compoundVerticalMargin) {
- x += compoundHorizontalMargin;
- y += compoundVerticalMargin;
- var left = x;
- for (var i = 0; i < organization.rows.length; i++) {
- var row = organization.rows[i];
- x = left;
- var maxHeight = 0;
- for (var j = 0; j < row.length; j++) {
- var lnode = row[j];
- lnode.rect.x = x; // + lnode.rect.width / 2;
- lnode.rect.y = y; // + lnode.rect.height / 2;
- x += lnode.rect.width + organization.horizontalPadding;
- if (lnode.rect.height > maxHeight) maxHeight = lnode.rect.height;
- }
- y += maxHeight + organization.verticalPadding;
- }
- };
- CoSELayout.prototype.tileCompoundMembers = function (childGraphMap, idToNode) {
- var self = this;
- this.tiledMemberPack = [];
- Object.keys(childGraphMap).forEach(function (id) {
- // Get the compound node
- var compoundNode = idToNode[id];
- self.tiledMemberPack[id] = self.tileNodes(childGraphMap[id], compoundNode.paddingLeft + compoundNode.paddingRight);
- compoundNode.rect.width = self.tiledMemberPack[id].width;
- compoundNode.rect.height = self.tiledMemberPack[id].height;
- });
- };
- CoSELayout.prototype.tileNodes = function (nodes, minWidth) {
- var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL;
- var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL;
- var organization = {
- rows: [],
- rowWidth: [],
- rowHeight: [],
- width: 0,
- height: minWidth, // assume minHeight equals to minWidth
- verticalPadding: verticalPadding,
- horizontalPadding: horizontalPadding
- };
- // Sort the nodes in ascending order of their areas
- nodes.sort(function (n1, n2) {
- if (n1.rect.width * n1.rect.height > n2.rect.width * n2.rect.height) return -1;
- if (n1.rect.width * n1.rect.height < n2.rect.width * n2.rect.height) return 1;
- return 0;
- });
- // Create the organization -> tile members
- for (var i = 0; i < nodes.length; i++) {
- var lNode = nodes[i];
- if (organization.rows.length == 0) {
- this.insertNodeToRow(organization, lNode, 0, minWidth);
- } else if (this.canAddHorizontal(organization, lNode.rect.width, lNode.rect.height)) {
- this.insertNodeToRow(organization, lNode, this.getShortestRowIndex(organization), minWidth);
- } else {
- this.insertNodeToRow(organization, lNode, organization.rows.length, minWidth);
- }
- this.shiftToLastRow(organization);
- }
- return organization;
- };
- CoSELayout.prototype.insertNodeToRow = function (organization, node, rowIndex, minWidth) {
- var minCompoundSize = minWidth;
- // Add new row if needed
- if (rowIndex == organization.rows.length) {
- var secondDimension = [];
- organization.rows.push(secondDimension);
- organization.rowWidth.push(minCompoundSize);
- organization.rowHeight.push(0);
- }
- // Update row width
- var w = organization.rowWidth[rowIndex] + node.rect.width;
- if (organization.rows[rowIndex].length > 0) {
- w += organization.horizontalPadding;
- }
- organization.rowWidth[rowIndex] = w;
- // Update compound width
- if (organization.width < w) {
- organization.width = w;
- }
- // Update height
- var h = node.rect.height;
- if (rowIndex > 0) h += organization.verticalPadding;
- var extraHeight = 0;
- if (h > organization.rowHeight[rowIndex]) {
- extraHeight = organization.rowHeight[rowIndex];
- organization.rowHeight[rowIndex] = h;
- extraHeight = organization.rowHeight[rowIndex] - extraHeight;
- }
- organization.height += extraHeight;
- // Insert node
- organization.rows[rowIndex].push(node);
- };
- //Scans the rows of an organization and returns the one with the min width
- CoSELayout.prototype.getShortestRowIndex = function (organization) {
- var r = -1;
- var min = Number.MAX_VALUE;
- for (var i = 0; i < organization.rows.length; i++) {
- if (organization.rowWidth[i] < min) {
- r = i;
- min = organization.rowWidth[i];
- }
- }
- return r;
- };
- //Scans the rows of an organization and returns the one with the max width
- CoSELayout.prototype.getLongestRowIndex = function (organization) {
- var r = -1;
- var max = Number.MIN_VALUE;
- for (var i = 0; i < organization.rows.length; i++) {
- if (organization.rowWidth[i] > max) {
- r = i;
- max = organization.rowWidth[i];
- }
- }
- return r;
- };
- /**
- * This method checks whether adding extra width to the organization violates
- * the aspect ratio(1) or not.
- */
- CoSELayout.prototype.canAddHorizontal = function (organization, extraWidth, extraHeight) {
- var sri = this.getShortestRowIndex(organization);
- if (sri < 0) {
- return true;
- }
- var min = organization.rowWidth[sri];
- if (min + organization.horizontalPadding + extraWidth <= organization.width) return true;
- var hDiff = 0;
- // Adding to an existing row
- if (organization.rowHeight[sri] < extraHeight) {
- if (sri > 0) hDiff = extraHeight + organization.verticalPadding - organization.rowHeight[sri];
- }
- var add_to_row_ratio;
- if (organization.width - min >= extraWidth + organization.horizontalPadding) {
- add_to_row_ratio = (organization.height + hDiff) / (min + extraWidth + organization.horizontalPadding);
- } else {
- add_to_row_ratio = (organization.height + hDiff) / organization.width;
- }
- // Adding a new row for this node
- hDiff = extraHeight + organization.verticalPadding;
- var add_new_row_ratio;
- if (organization.width < extraWidth) {
- add_new_row_ratio = (organization.height + hDiff) / extraWidth;
- } else {
- add_new_row_ratio = (organization.height + hDiff) / organization.width;
- }
- if (add_new_row_ratio < 1) add_new_row_ratio = 1 / add_new_row_ratio;
- if (add_to_row_ratio < 1) add_to_row_ratio = 1 / add_to_row_ratio;
- return add_to_row_ratio < add_new_row_ratio;
- };
- //If moving the last node from the longest row and adding it to the last
- //row makes the bounding box smaller, do it.
- CoSELayout.prototype.shiftToLastRow = function (organization) {
- var longest = this.getLongestRowIndex(organization);
- var last = organization.rowWidth.length - 1;
- var row = organization.rows[longest];
- var node = row[row.length - 1];
- var diff = node.width + organization.horizontalPadding;
- // Check if there is enough space on the last row
- if (organization.width - organization.rowWidth[last] > diff && longest != last) {
- // Remove the last element of the longest row
- row.splice(-1, 1);
- // Push it to the last row
- organization.rows[last].push(node);
- organization.rowWidth[longest] = organization.rowWidth[longest] - diff;
- organization.rowWidth[last] = organization.rowWidth[last] + diff;
- organization.width = organization.rowWidth[instance.getLongestRowIndex(organization)];
- // Update heights of the organization
- var maxHeight = Number.MIN_VALUE;
- for (var i = 0; i < row.length; i++) {
- if (row[i].height > maxHeight) maxHeight = row[i].height;
- }
- if (longest > 0) maxHeight += organization.verticalPadding;
- var prevTotal = organization.rowHeight[longest] + organization.rowHeight[last];
- organization.rowHeight[longest] = maxHeight;
- if (organization.rowHeight[last] < node.height + organization.verticalPadding) organization.rowHeight[last] = node.height + organization.verticalPadding;
- var finalTotal = organization.rowHeight[longest] + organization.rowHeight[last];
- organization.height += finalTotal - prevTotal;
- this.shiftToLastRow(organization);
- }
- };
- CoSELayout.prototype.tilingPreLayout = function () {
- if (CoSEConstants.TILE) {
- // Find zero degree nodes and create a compound for each level
- this.groupZeroDegreeMembers();
- // Tile and clear children of each compound
- this.clearCompounds();
- // Separately tile and clear zero degree nodes for each level
- this.clearZeroDegreeMembers();
- }
- };
- CoSELayout.prototype.tilingPostLayout = function () {
- if (CoSEConstants.TILE) {
- this.repopulateZeroDegreeMembers();
- this.repopulateCompounds();
- }
- };
- // -----------------------------------------------------------------------------
- // Section: Tree Reduction methods
- // -----------------------------------------------------------------------------
- // Reduce trees
- CoSELayout.prototype.reduceTrees = function () {
- var prunedNodesAll = [];
- var containsLeaf = true;
- var node;
- while (containsLeaf) {
- var allNodes = this.graphManager.getAllNodes();
- var prunedNodesInStepTemp = [];
- containsLeaf = false;
- for (var i = 0; i < allNodes.length; i++) {
- node = allNodes[i];
- if (node.getEdges().length == 1 && !node.getEdges()[0].isInterGraph && node.getChild() == null) {
- prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner()]);
- containsLeaf = true;
- }
- }
- if (containsLeaf == true) {
- var prunedNodesInStep = [];
- for (var j = 0; j < prunedNodesInStepTemp.length; j++) {
- if (prunedNodesInStepTemp[j][0].getEdges().length == 1) {
- prunedNodesInStep.push(prunedNodesInStepTemp[j]);
- prunedNodesInStepTemp[j][0].getOwner().remove(prunedNodesInStepTemp[j][0]);
- }
- }
- prunedNodesAll.push(prunedNodesInStep);
- this.graphManager.resetAllNodes();
- this.graphManager.resetAllEdges();
- }
- }
- this.prunedNodesAll = prunedNodesAll;
- };
- // Grow tree one step
- CoSELayout.prototype.growTree = function (prunedNodesAll) {
- var lengthOfPrunedNodesInStep = prunedNodesAll.length;
- var prunedNodesInStep = prunedNodesAll[lengthOfPrunedNodesInStep - 1];
- var nodeData;
- for (var i = 0; i < prunedNodesInStep.length; i++) {
- nodeData = prunedNodesInStep[i];
- this.findPlaceforPrunedNode(nodeData);
- nodeData[2].add(nodeData[0]);
- nodeData[2].add(nodeData[1], nodeData[1].source, nodeData[1].target);
- }
- prunedNodesAll.splice(prunedNodesAll.length - 1, 1);
- this.graphManager.resetAllNodes();
- this.graphManager.resetAllEdges();
- };
- // Find an appropriate position to replace pruned node, this method can be improved
- CoSELayout.prototype.findPlaceforPrunedNode = function (nodeData) {
- var gridForPrunedNode;
- var nodeToConnect;
- var prunedNode = nodeData[0];
- if (prunedNode == nodeData[1].source) {
- nodeToConnect = nodeData[1].target;
- } else {
- nodeToConnect = nodeData[1].source;
- }
- var startGridX = nodeToConnect.startX;
- var finishGridX = nodeToConnect.finishX;
- var startGridY = nodeToConnect.startY;
- var finishGridY = nodeToConnect.finishY;
- var upNodeCount = 0;
- var downNodeCount = 0;
- var rightNodeCount = 0;
- var leftNodeCount = 0;
- var controlRegions = [upNodeCount, rightNodeCount, downNodeCount, leftNodeCount];
- if (startGridY > 0) {
- for (var i = startGridX; i <= finishGridX; i++) {
- controlRegions[0] += this.grid[i][startGridY - 1].length + this.grid[i][startGridY].length - 1;
- }
- }
- if (finishGridX < this.grid.length - 1) {
- for (var i = startGridY; i <= finishGridY; i++) {
- controlRegions[1] += this.grid[finishGridX + 1][i].length + this.grid[finishGridX][i].length - 1;
- }
- }
- if (finishGridY < this.grid[0].length - 1) {
- for (var i = startGridX; i <= finishGridX; i++) {
- controlRegions[2] += this.grid[i][finishGridY + 1].length + this.grid[i][finishGridY].length - 1;
- }
- }
- if (startGridX > 0) {
- for (var i = startGridY; i <= finishGridY; i++) {
- controlRegions[3] += this.grid[startGridX - 1][i].length + this.grid[startGridX][i].length - 1;
- }
- }
- var min = Integer.MAX_VALUE;
- var minCount;
- var minIndex;
- for (var j = 0; j < controlRegions.length; j++) {
- if (controlRegions[j] < min) {
- min = controlRegions[j];
- minCount = 1;
- minIndex = j;
- } else if (controlRegions[j] == min) {
- minCount++;
- }
- }
- if (minCount == 3 && min == 0) {
- if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[2] == 0) {
- gridForPrunedNode = 1;
- } else if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[3] == 0) {
- gridForPrunedNode = 0;
- } else if (controlRegions[0] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {
- gridForPrunedNode = 3;
- } else if (controlRegions[1] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {
- gridForPrunedNode = 2;
- }
- } else if (minCount == 2 && min == 0) {
- var random = Math.floor(Math.random() * 2);
- if (controlRegions[0] == 0 && controlRegions[1] == 0) {
- ;
- if (random == 0) {
- gridForPrunedNode = 0;
- } else {
- gridForPrunedNode = 1;
- }
- } else if (controlRegions[0] == 0 && controlRegions[2] == 0) {
- if (random == 0) {
- gridForPrunedNode = 0;
- } else {
- gridForPrunedNode = 2;
- }
- } else if (controlRegions[0] == 0 && controlRegions[3] == 0) {
- if (random == 0) {
- gridForPrunedNode = 0;
- } else {
- gridForPrunedNode = 3;
- }
- } else if (controlRegions[1] == 0 && controlRegions[2] == 0) {
- if (random == 0) {
- gridForPrunedNode = 1;
- } else {
- gridForPrunedNode = 2;
- }
- } else if (controlRegions[1] == 0 && controlRegions[3] == 0) {
- if (random == 0) {
- gridForPrunedNode = 1;
- } else {
- gridForPrunedNode = 3;
- }
- } else {
- if (random == 0) {
- gridForPrunedNode = 2;
- } else {
- gridForPrunedNode = 3;
- }
- }
- } else if (minCount == 4 && min == 0) {
- var random = Math.floor(Math.random() * 4);
- gridForPrunedNode = random;
- } else {
- gridForPrunedNode = minIndex;
- }
- if (gridForPrunedNode == 0) {
- prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() - nodeToConnect.getHeight() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getHeight() / 2);
- } else if (gridForPrunedNode == 1) {
- prunedNode.setCenter(nodeToConnect.getCenterX() + nodeToConnect.getWidth() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getWidth() / 2, nodeToConnect.getCenterY());
- } else if (gridForPrunedNode == 2) {
- prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() + nodeToConnect.getHeight() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getHeight() / 2);
- } else {
- prunedNode.setCenter(nodeToConnect.getCenterX() - nodeToConnect.getWidth() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getWidth() / 2, nodeToConnect.getCenterY());
- }
- };
- module.exports = CoSELayout;
- /***/ }),
- /* 7 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var coseBase = {};
- coseBase.layoutBase = __webpack_require__(0);
- coseBase.CoSEConstants = __webpack_require__(1);
- coseBase.CoSEEdge = __webpack_require__(2);
- coseBase.CoSEGraph = __webpack_require__(3);
- coseBase.CoSEGraphManager = __webpack_require__(4);
- coseBase.CoSELayout = __webpack_require__(6);
- coseBase.CoSENode = __webpack_require__(5);
- module.exports = coseBase;
- /***/ })
- /******/ ]);
- });
|