(self["webpackChunk_JUPYTERLAB_CORE_OUTPUT"] = self["webpackChunk_JUPYTERLAB_CORE_OUTPUT"] || []).push([[4047],{ /***/ 43203: /***/ (function(module, __unused_webpack_exports, __webpack_require__) { (function webpackUniversalModuleDefinition(root, factory) { if(true) module.exports = factory(__webpack_require__(54899)); else {} })(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __nested_webpack_require_643__(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, __nested_webpack_require_643__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __nested_webpack_require_643__.m = modules; /******/ /******/ // expose the module cache /******/ __nested_webpack_require_643__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __nested_webpack_require_643__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __nested_webpack_require_643__.d = function(exports, name, getter) { /******/ if(!__nested_webpack_require_643__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __nested_webpack_require_643__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __nested_webpack_require_643__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __nested_webpack_require_643__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __nested_webpack_require_643__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __nested_webpack_require_643__(__nested_webpack_require_643__.s = 7); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_0__; /***/ }), /* 1 */ /***/ (function(module, exports, __nested_webpack_require_3185__) { "use strict"; var FDLayoutConstants = __nested_webpack_require_3185__(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, __nested_webpack_require_4002__) { "use strict"; var FDLayoutEdge = __nested_webpack_require_4002__(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, __nested_webpack_require_4409__) { "use strict"; var LGraph = __nested_webpack_require_4409__(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, __nested_webpack_require_4790__) { "use strict"; var LGraphManager = __nested_webpack_require_4790__(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, __nested_webpack_require_5205__) { "use strict"; var FDLayoutNode = __nested_webpack_require_5205__(0).FDLayoutNode; var IMath = __nested_webpack_require_5205__(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, __nested_webpack_require_8085__) { "use strict"; var FDLayout = __nested_webpack_require_8085__(0).FDLayout; var CoSEGraphManager = __nested_webpack_require_8085__(4); var CoSEGraph = __nested_webpack_require_8085__(3); var CoSENode = __nested_webpack_require_8085__(5); var CoSEEdge = __nested_webpack_require_8085__(2); var CoSEConstants = __nested_webpack_require_8085__(1); var FDLayoutConstants = __nested_webpack_require_8085__(0).FDLayoutConstants; var LayoutConstants = __nested_webpack_require_8085__(0).LayoutConstants; var Point = __nested_webpack_require_8085__(0).Point; var PointD = __nested_webpack_require_8085__(0).PointD; var Layout = __nested_webpack_require_8085__(0).Layout; var Integer = __nested_webpack_require_8085__(0).Integer; var IGeometry = __nested_webpack_require_8085__(0).IGeometry; var LGraph = __nested_webpack_require_8085__(0).LGraph; var Transform = __nested_webpack_require_8085__(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, __nested_webpack_require_45620__) { "use strict"; var coseBase = {}; coseBase.layoutBase = __nested_webpack_require_45620__(0); coseBase.CoSEConstants = __nested_webpack_require_45620__(1); coseBase.CoSEEdge = __nested_webpack_require_45620__(2); coseBase.CoSEGraph = __nested_webpack_require_45620__(3); coseBase.CoSEGraphManager = __nested_webpack_require_45620__(4); coseBase.CoSELayout = __nested_webpack_require_45620__(6); coseBase.CoSENode = __nested_webpack_require_45620__(5); module.exports = coseBase; /***/ }) /******/ ]); }); /***/ }), /***/ 35302: /***/ (function(module, __unused_webpack_exports, __webpack_require__) { (function webpackUniversalModuleDefinition(root, factory) { if(true) module.exports = factory(__webpack_require__(43203)); else {} })(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __nested_webpack_require_659__(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, __nested_webpack_require_659__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __nested_webpack_require_659__.m = modules; /******/ /******/ // expose the module cache /******/ __nested_webpack_require_659__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __nested_webpack_require_659__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __nested_webpack_require_659__.d = function(exports, name, getter) { /******/ if(!__nested_webpack_require_659__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __nested_webpack_require_659__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __nested_webpack_require_659__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __nested_webpack_require_659__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __nested_webpack_require_659__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __nested_webpack_require_659__(__nested_webpack_require_659__.s = 1); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_0__; /***/ }), /* 1 */ /***/ (function(module, exports, __nested_webpack_require_3201__) { "use strict"; var LayoutConstants = __nested_webpack_require_3201__(0).layoutBase.LayoutConstants; var FDLayoutConstants = __nested_webpack_require_3201__(0).layoutBase.FDLayoutConstants; var CoSEConstants = __nested_webpack_require_3201__(0).CoSEConstants; var CoSELayout = __nested_webpack_require_3201__(0).CoSELayout; var CoSENode = __nested_webpack_require_3201__(0).CoSENode; var PointD = __nested_webpack_require_3201__(0).layoutBase.PointD; var DimensionD = __nested_webpack_require_3201__(0).layoutBase.DimensionD; var defaults = { // Called on `layoutready` ready: function ready() {}, // Called on `layoutstop` stop: function stop() {}, // 'draft', 'default' or 'proof" // - 'draft' fast cooling rate // - 'default' moderate cooling rate // - "proof" slow cooling rate quality: 'default', // include labels in node dimensions nodeDimensionsIncludeLabels: false, // number of ticks per frame; higher is faster but more jerky refresh: 30, // Whether to fit the network view after when done fit: true, // Padding on fit padding: 10, // Whether to enable incremental mode randomize: true, // Node repulsion (non overlapping) multiplier nodeRepulsion: 4500, // Ideal edge (non nested) length idealEdgeLength: 50, // Divisor to compute edge forces edgeElasticity: 0.45, // Nesting factor (multiplier) to compute ideal edge length for nested edges nestingFactor: 0.1, // Gravity force (constant) gravity: 0.25, // Maximum number of iterations to perform numIter: 2500, // For enabling tiling tile: true, // Type of layout animation. The option set is {'during', 'end', false} animate: 'end', // Duration for animate:end animationDuration: 500, // Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function) tilingPaddingVertical: 10, // Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function) tilingPaddingHorizontal: 10, // Gravity range (constant) for compounds gravityRangeCompound: 1.5, // Gravity force (constant) for compounds gravityCompound: 1.0, // Gravity range (constant) gravityRange: 3.8, // Initial cooling factor for incremental layout initialEnergyOnIncremental: 0.5 }; function extend(defaults, options) { var obj = {}; for (var i in defaults) { obj[i] = defaults[i]; } for (var i in options) { obj[i] = options[i]; } return obj; }; function _CoSELayout(_options) { this.options = extend(defaults, _options); getUserOptions(this.options); } var getUserOptions = function getUserOptions(options) { if (options.nodeRepulsion != null) CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion; if (options.idealEdgeLength != null) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength; if (options.edgeElasticity != null) CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity; if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor; if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity; if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter; if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange; if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound; if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound; if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental; if (options.quality == 'draft') LayoutConstants.QUALITY = 0;else if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 1; CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels; CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize; CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate; CoSEConstants.TILE = options.tile; CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical; CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal; }; _CoSELayout.prototype.run = function () { var ready; var frameId; var options = this.options; var idToLNode = this.idToLNode = {}; var layout = this.layout = new CoSELayout(); var self = this; self.stopped = false; this.cy = this.options.cy; this.cy.trigger({ type: 'layoutstart', layout: this }); var gm = layout.newGraphManager(); this.gm = gm; var nodes = this.options.eles.nodes(); var edges = this.options.eles.edges(); this.root = gm.addRoot(); this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout); for (var i = 0; i < edges.length; i++) { var edge = edges[i]; var sourceNode = this.idToLNode[edge.data("source")]; var targetNode = this.idToLNode[edge.data("target")]; if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) { var e1 = gm.add(layout.newEdge(), sourceNode, targetNode); e1.id = edge.id(); } } var getPositions = function getPositions(ele, i) { if (typeof ele === "number") { ele = i; } var theId = ele.data('id'); var lNode = self.idToLNode[theId]; return { x: lNode.getRect().getCenterX(), y: lNode.getRect().getCenterY() }; }; /* * Reposition nodes in iterations animatedly */ var iterateAnimated = function iterateAnimated() { // Thigs to perform after nodes are repositioned on screen var afterReposition = function afterReposition() { if (options.fit) { options.cy.fit(options.eles, options.padding); } if (!ready) { ready = true; self.cy.one('layoutready', options.ready); self.cy.trigger({ type: 'layoutready', layout: self }); } }; var ticksPerFrame = self.options.refresh; var isDone; for (var i = 0; i < ticksPerFrame && !isDone; i++) { isDone = self.stopped || self.layout.tick(); } // If layout is done if (isDone) { // If the layout is not a sublayout and it is successful perform post layout. if (layout.checkLayoutSuccess() && !layout.isSubLayout) { layout.doPostLayout(); } // If layout has a tilingPostLayout function property call it. if (layout.tilingPostLayout) { layout.tilingPostLayout(); } layout.isLayoutFinished = true; self.options.eles.nodes().positions(getPositions); afterReposition(); // trigger layoutstop when the layout stops (e.g. finishes) self.cy.one('layoutstop', self.options.stop); self.cy.trigger({ type: 'layoutstop', layout: self }); if (frameId) { cancelAnimationFrame(frameId); } ready = false; return; } var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling // Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds) // use position of their ancestors or dummy ancestors options.eles.nodes().positions(function (ele, i) { if (typeof ele === "number") { ele = i; } // If ele is a compound node, then its position will be defined by its children if (!ele.isParent()) { var theId = ele.id(); var pNode = animationData[theId]; var temp = ele; // If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well) while (pNode == null) { pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')]; animationData[theId] = pNode; temp = temp.parent()[0]; if (temp == undefined) { break; } } if (pNode != null) { return { x: pNode.x, y: pNode.y }; } else { return { x: ele.position('x'), y: ele.position('y') }; } } }); afterReposition(); frameId = requestAnimationFrame(iterateAnimated); }; /* * Listen 'layoutstarted' event and start animated iteration if animate option is 'during' */ layout.addListener('layoutstarted', function () { if (self.options.animate === 'during') { frameId = requestAnimationFrame(iterateAnimated); } }); layout.runLayout(); // Run cose layout /* * If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed) */ if (this.options.animate !== "during") { self.options.eles.nodes().not(":parent").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter ready = false; } return this; // chaining }; //Get the top most ones of a list of nodes _CoSELayout.prototype.getTopMostNodes = function (nodes) { var nodesMap = {}; for (var i = 0; i < nodes.length; i++) { nodesMap[nodes[i].id()] = true; } var roots = nodes.filter(function (ele, i) { if (typeof ele === "number") { ele = i; } var parent = ele.parent()[0]; while (parent != null) { if (nodesMap[parent.id()]) { return false; } parent = parent.parent()[0]; } return true; }); return roots; }; _CoSELayout.prototype.processChildrenList = function (parent, children, layout) { var size = children.length; for (var i = 0; i < size; i++) { var theChild = children[i]; var children_of_children = theChild.children(); var theNode; var dimensions = theChild.layoutDimensions({ nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels }); if (theChild.outerWidth() != null && theChild.outerHeight() != null) { theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h)))); } else { theNode = parent.add(new CoSENode(this.graphManager)); } // Attach id to the layout node theNode.id = theChild.data("id"); // Attach the paddings of cy node to layout node theNode.paddingLeft = parseInt(theChild.css('padding')); theNode.paddingTop = parseInt(theChild.css('padding')); theNode.paddingRight = parseInt(theChild.css('padding')); theNode.paddingBottom = parseInt(theChild.css('padding')); //Attach the label properties to compound if labels will be included in node dimensions if (this.options.nodeDimensionsIncludeLabels) { if (theChild.isParent()) { var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w; var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h; var labelPos = theChild.css("text-halign"); theNode.labelWidth = labelWidth; theNode.labelHeight = labelHeight; theNode.labelPos = labelPos; } } // Map the layout node this.idToLNode[theChild.data("id")] = theNode; if (isNaN(theNode.rect.x)) { theNode.rect.x = 0; } if (isNaN(theNode.rect.y)) { theNode.rect.y = 0; } if (children_of_children != null && children_of_children.length > 0) { var theNewGraph; theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode); this.processChildrenList(theNewGraph, children_of_children, layout); } } }; /** * @brief : called on continuous layouts to stop them before they finish */ _CoSELayout.prototype.stop = function () { this.stopped = true; return this; // chaining }; var register = function register(cytoscape) { // var Layout = getLayout( cytoscape ); cytoscape('layout', 'cose-bilkent', _CoSELayout); }; // auto reg for globals if (typeof cytoscape !== 'undefined') { register(cytoscape); } module.exports = register; /***/ }) /******/ ]); }); /***/ }), /***/ 54899: /***/ (function(module) { (function webpackUniversalModuleDefinition(root, factory) { if(true) module.exports = factory(); else {} })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __nested_webpack_require_543__(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, __nested_webpack_require_543__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __nested_webpack_require_543__.m = modules; /******/ /******/ // expose the module cache /******/ __nested_webpack_require_543__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __nested_webpack_require_543__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __nested_webpack_require_543__.d = function(exports, name, getter) { /******/ if(!__nested_webpack_require_543__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __nested_webpack_require_543__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __nested_webpack_require_543__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __nested_webpack_require_543__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __nested_webpack_require_543__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __nested_webpack_require_543__(__nested_webpack_require_543__.s = 26); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function LayoutConstants() {} /** * Layout Quality: 0:draft, 1:default, 2:proof */ LayoutConstants.QUALITY = 1; /** * Default parameters */ LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED = false; LayoutConstants.DEFAULT_INCREMENTAL = false; LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT = true; LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT = false; LayoutConstants.DEFAULT_ANIMATION_PERIOD = 50; LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = false; // ----------------------------------------------------------------------------- // Section: General other constants // ----------------------------------------------------------------------------- /* * Margins of a graph to be applied on bouding rectangle of its contents. We * assume margins on all four sides to be uniform. */ LayoutConstants.DEFAULT_GRAPH_MARGIN = 15; /* * Whether to consider labels in node dimensions or not */ LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = false; /* * Default dimension of a non-compound node. */ LayoutConstants.SIMPLE_NODE_SIZE = 40; /* * Default dimension of a non-compound node. */ LayoutConstants.SIMPLE_NODE_HALF_SIZE = LayoutConstants.SIMPLE_NODE_SIZE / 2; /* * Empty compound node size. When a compound node is empty, its both * dimensions should be of this value. */ LayoutConstants.EMPTY_COMPOUND_NODE_SIZE = 40; /* * Minimum length that an edge should take during layout */ LayoutConstants.MIN_EDGE_LENGTH = 1; /* * World boundaries that layout operates on */ LayoutConstants.WORLD_BOUNDARY = 1000000; /* * World boundaries that random positioning can be performed with */ LayoutConstants.INITIAL_WORLD_BOUNDARY = LayoutConstants.WORLD_BOUNDARY / 1000; /* * Coordinates of the world center */ LayoutConstants.WORLD_CENTER_X = 1200; LayoutConstants.WORLD_CENTER_Y = 900; module.exports = LayoutConstants; /***/ }), /* 1 */ /***/ (function(module, exports, __nested_webpack_require_4947__) { "use strict"; var LGraphObject = __nested_webpack_require_4947__(2); var IGeometry = __nested_webpack_require_4947__(8); var IMath = __nested_webpack_require_4947__(9); function LEdge(source, target, vEdge) { LGraphObject.call(this, vEdge); this.isOverlapingSourceAndTarget = false; this.vGraphObject = vEdge; this.bendpoints = []; this.source = source; this.target = target; } LEdge.prototype = Object.create(LGraphObject.prototype); for (var prop in LGraphObject) { LEdge[prop] = LGraphObject[prop]; } LEdge.prototype.getSource = function () { return this.source; }; LEdge.prototype.getTarget = function () { return this.target; }; LEdge.prototype.isInterGraph = function () { return this.isInterGraph; }; LEdge.prototype.getLength = function () { return this.length; }; LEdge.prototype.isOverlapingSourceAndTarget = function () { return this.isOverlapingSourceAndTarget; }; LEdge.prototype.getBendpoints = function () { return this.bendpoints; }; LEdge.prototype.getLca = function () { return this.lca; }; LEdge.prototype.getSourceInLca = function () { return this.sourceInLca; }; LEdge.prototype.getTargetInLca = function () { return this.targetInLca; }; LEdge.prototype.getOtherEnd = function (node) { if (this.source === node) { return this.target; } else if (this.target === node) { return this.source; } else { throw "Node is not incident with this edge"; } }; LEdge.prototype.getOtherEndInGraph = function (node, graph) { var otherEnd = this.getOtherEnd(node); var root = graph.getGraphManager().getRoot(); while (true) { if (otherEnd.getOwner() == graph) { return otherEnd; } if (otherEnd.getOwner() == root) { break; } otherEnd = otherEnd.getOwner().getParent(); } return null; }; LEdge.prototype.updateLength = function () { var clipPointCoordinates = new Array(4); this.isOverlapingSourceAndTarget = IGeometry.getIntersection(this.target.getRect(), this.source.getRect(), clipPointCoordinates); if (!this.isOverlapingSourceAndTarget) { this.lengthX = clipPointCoordinates[0] - clipPointCoordinates[2]; this.lengthY = clipPointCoordinates[1] - clipPointCoordinates[3]; if (Math.abs(this.lengthX) < 1.0) { this.lengthX = IMath.sign(this.lengthX); } if (Math.abs(this.lengthY) < 1.0) { this.lengthY = IMath.sign(this.lengthY); } this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY); } }; LEdge.prototype.updateLengthSimple = function () { this.lengthX = this.target.getCenterX() - this.source.getCenterX(); this.lengthY = this.target.getCenterY() - this.source.getCenterY(); if (Math.abs(this.lengthX) < 1.0) { this.lengthX = IMath.sign(this.lengthX); } if (Math.abs(this.lengthY) < 1.0) { this.lengthY = IMath.sign(this.lengthY); } this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY); }; module.exports = LEdge; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function LGraphObject(vGraphObject) { this.vGraphObject = vGraphObject; } module.exports = LGraphObject; /***/ }), /* 3 */ /***/ (function(module, exports, __nested_webpack_require_8167__) { "use strict"; var LGraphObject = __nested_webpack_require_8167__(2); var Integer = __nested_webpack_require_8167__(10); var RectangleD = __nested_webpack_require_8167__(13); var LayoutConstants = __nested_webpack_require_8167__(0); var RandomSeed = __nested_webpack_require_8167__(16); var PointD = __nested_webpack_require_8167__(4); function LNode(gm, loc, size, vNode) { //Alternative constructor 1 : LNode(LGraphManager gm, Point loc, Dimension size, Object vNode) if (size == null && vNode == null) { vNode = loc; } LGraphObject.call(this, vNode); //Alternative constructor 2 : LNode(Layout layout, Object vNode) if (gm.graphManager != null) gm = gm.graphManager; this.estimatedSize = Integer.MIN_VALUE; this.inclusionTreeDepth = Integer.MAX_VALUE; this.vGraphObject = vNode; this.edges = []; this.graphManager = gm; if (size != null && loc != null) this.rect = new RectangleD(loc.x, loc.y, size.width, size.height);else this.rect = new RectangleD(); } LNode.prototype = Object.create(LGraphObject.prototype); for (var prop in LGraphObject) { LNode[prop] = LGraphObject[prop]; } LNode.prototype.getEdges = function () { return this.edges; }; LNode.prototype.getChild = function () { return this.child; }; LNode.prototype.getOwner = function () { // if (this.owner != null) { // if (!(this.owner == null || this.owner.getNodes().indexOf(this) > -1)) { // throw "assert failed"; // } // } return this.owner; }; LNode.prototype.getWidth = function () { return this.rect.width; }; LNode.prototype.setWidth = function (width) { this.rect.width = width; }; LNode.prototype.getHeight = function () { return this.rect.height; }; LNode.prototype.setHeight = function (height) { this.rect.height = height; }; LNode.prototype.getCenterX = function () { return this.rect.x + this.rect.width / 2; }; LNode.prototype.getCenterY = function () { return this.rect.y + this.rect.height / 2; }; LNode.prototype.getCenter = function () { return new PointD(this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2); }; LNode.prototype.getLocation = function () { return new PointD(this.rect.x, this.rect.y); }; LNode.prototype.getRect = function () { return this.rect; }; LNode.prototype.getDiagonal = function () { return Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height); }; /** * This method returns half the diagonal length of this node. */ LNode.prototype.getHalfTheDiagonal = function () { return Math.sqrt(this.rect.height * this.rect.height + this.rect.width * this.rect.width) / 2; }; LNode.prototype.setRect = function (upperLeft, dimension) { this.rect.x = upperLeft.x; this.rect.y = upperLeft.y; this.rect.width = dimension.width; this.rect.height = dimension.height; }; LNode.prototype.setCenter = function (cx, cy) { this.rect.x = cx - this.rect.width / 2; this.rect.y = cy - this.rect.height / 2; }; LNode.prototype.setLocation = function (x, y) { this.rect.x = x; this.rect.y = y; }; LNode.prototype.moveBy = function (dx, dy) { this.rect.x += dx; this.rect.y += dy; }; LNode.prototype.getEdgeListToNode = function (to) { var edgeList = []; var edge; var self = this; self.edges.forEach(function (edge) { if (edge.target == to) { if (edge.source != self) throw "Incorrect edge source!"; edgeList.push(edge); } }); return edgeList; }; LNode.prototype.getEdgesBetween = function (other) { var edgeList = []; var edge; var self = this; self.edges.forEach(function (edge) { if (!(edge.source == self || edge.target == self)) throw "Incorrect edge source and/or target"; if (edge.target == other || edge.source == other) { edgeList.push(edge); } }); return edgeList; }; LNode.prototype.getNeighborsList = function () { var neighbors = new Set(); var self = this; self.edges.forEach(function (edge) { if (edge.source == self) { neighbors.add(edge.target); } else { if (edge.target != self) { throw "Incorrect incidency!"; } neighbors.add(edge.source); } }); return neighbors; }; LNode.prototype.withChildren = function () { var withNeighborsList = new Set(); var childNode; var children; withNeighborsList.add(this); if (this.child != null) { var nodes = this.child.getNodes(); for (var i = 0; i < nodes.length; i++) { childNode = nodes[i]; children = childNode.withChildren(); children.forEach(function (node) { withNeighborsList.add(node); }); } } return withNeighborsList; }; LNode.prototype.getNoOfChildren = function () { var noOfChildren = 0; var childNode; if (this.child == null) { noOfChildren = 1; } else { var nodes = this.child.getNodes(); for (var i = 0; i < nodes.length; i++) { childNode = nodes[i]; noOfChildren += childNode.getNoOfChildren(); } } if (noOfChildren == 0) { noOfChildren = 1; } return noOfChildren; }; LNode.prototype.getEstimatedSize = function () { if (this.estimatedSize == Integer.MIN_VALUE) { throw "assert failed"; } return this.estimatedSize; }; LNode.prototype.calcEstimatedSize = function () { if (this.child == null) { return this.estimatedSize = (this.rect.width + this.rect.height) / 2; } else { this.estimatedSize = this.child.calcEstimatedSize(); this.rect.width = this.estimatedSize; this.rect.height = this.estimatedSize; return this.estimatedSize; } }; LNode.prototype.scatter = function () { var randomCenterX; var randomCenterY; var minX = -LayoutConstants.INITIAL_WORLD_BOUNDARY; var maxX = LayoutConstants.INITIAL_WORLD_BOUNDARY; randomCenterX = LayoutConstants.WORLD_CENTER_X + RandomSeed.nextDouble() * (maxX - minX) + minX; var minY = -LayoutConstants.INITIAL_WORLD_BOUNDARY; var maxY = LayoutConstants.INITIAL_WORLD_BOUNDARY; randomCenterY = LayoutConstants.WORLD_CENTER_Y + RandomSeed.nextDouble() * (maxY - minY) + minY; this.rect.x = randomCenterX; this.rect.y = randomCenterY; }; LNode.prototype.updateBounds = function () { if (this.getChild() == null) { throw "assert failed"; } if (this.getChild().getNodes().length != 0) { // wrap the children nodes by re-arranging the boundaries var childGraph = this.getChild(); childGraph.updateBounds(true); this.rect.x = childGraph.getLeft(); this.rect.y = childGraph.getTop(); this.setWidth(childGraph.getRight() - childGraph.getLeft()); this.setHeight(childGraph.getBottom() - childGraph.getTop()); // Update compound bounds considering its label properties if (LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS) { var width = childGraph.getRight() - childGraph.getLeft(); var height = childGraph.getBottom() - childGraph.getTop(); if (this.labelWidth > width) { this.rect.x -= (this.labelWidth - width) / 2; this.setWidth(this.labelWidth); } if (this.labelHeight > height) { if (this.labelPos == "center") { this.rect.y -= (this.labelHeight - height) / 2; } else if (this.labelPos == "top") { this.rect.y -= this.labelHeight - height; } this.setHeight(this.labelHeight); } } } }; LNode.prototype.getInclusionTreeDepth = function () { if (this.inclusionTreeDepth == Integer.MAX_VALUE) { throw "assert failed"; } return this.inclusionTreeDepth; }; LNode.prototype.transform = function (trans) { var left = this.rect.x; if (left > LayoutConstants.WORLD_BOUNDARY) { left = LayoutConstants.WORLD_BOUNDARY; } else if (left < -LayoutConstants.WORLD_BOUNDARY) { left = -LayoutConstants.WORLD_BOUNDARY; } var top = this.rect.y; if (top > LayoutConstants.WORLD_BOUNDARY) { top = LayoutConstants.WORLD_BOUNDARY; } else if (top < -LayoutConstants.WORLD_BOUNDARY) { top = -LayoutConstants.WORLD_BOUNDARY; } var leftTop = new PointD(left, top); var vLeftTop = trans.inverseTransformPoint(leftTop); this.setLocation(vLeftTop.x, vLeftTop.y); }; LNode.prototype.getLeft = function () { return this.rect.x; }; LNode.prototype.getRight = function () { return this.rect.x + this.rect.width; }; LNode.prototype.getTop = function () { return this.rect.y; }; LNode.prototype.getBottom = function () { return this.rect.y + this.rect.height; }; LNode.prototype.getParent = function () { if (this.owner == null) { return null; } return this.owner.getParent(); }; module.exports = LNode; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function PointD(x, y) { if (x == null && y == null) { this.x = 0; this.y = 0; } else { this.x = x; this.y = y; } } PointD.prototype.getX = function () { return this.x; }; PointD.prototype.getY = function () { return this.y; }; PointD.prototype.setX = function (x) { this.x = x; }; PointD.prototype.setY = function (y) { this.y = y; }; PointD.prototype.getDifference = function (pt) { return new DimensionD(this.x - pt.x, this.y - pt.y); }; PointD.prototype.getCopy = function () { return new PointD(this.x, this.y); }; PointD.prototype.translate = function (dim) { this.x += dim.width; this.y += dim.height; return this; }; module.exports = PointD; /***/ }), /* 5 */ /***/ (function(module, exports, __nested_webpack_require_17549__) { "use strict"; var LGraphObject = __nested_webpack_require_17549__(2); var Integer = __nested_webpack_require_17549__(10); var LayoutConstants = __nested_webpack_require_17549__(0); var LGraphManager = __nested_webpack_require_17549__(6); var LNode = __nested_webpack_require_17549__(3); var LEdge = __nested_webpack_require_17549__(1); var RectangleD = __nested_webpack_require_17549__(13); var Point = __nested_webpack_require_17549__(12); var LinkedList = __nested_webpack_require_17549__(11); function LGraph(parent, obj2, vGraph) { LGraphObject.call(this, vGraph); this.estimatedSize = Integer.MIN_VALUE; this.margin = LayoutConstants.DEFAULT_GRAPH_MARGIN; this.edges = []; this.nodes = []; this.isConnected = false; this.parent = parent; if (obj2 != null && obj2 instanceof LGraphManager) { this.graphManager = obj2; } else if (obj2 != null && obj2 instanceof Layout) { this.graphManager = obj2.graphManager; } } LGraph.prototype = Object.create(LGraphObject.prototype); for (var prop in LGraphObject) { LGraph[prop] = LGraphObject[prop]; } LGraph.prototype.getNodes = function () { return this.nodes; }; LGraph.prototype.getEdges = function () { return this.edges; }; LGraph.prototype.getGraphManager = function () { return this.graphManager; }; LGraph.prototype.getParent = function () { return this.parent; }; LGraph.prototype.getLeft = function () { return this.left; }; LGraph.prototype.getRight = function () { return this.right; }; LGraph.prototype.getTop = function () { return this.top; }; LGraph.prototype.getBottom = function () { return this.bottom; }; LGraph.prototype.isConnected = function () { return this.isConnected; }; LGraph.prototype.add = function (obj1, sourceNode, targetNode) { if (sourceNode == null && targetNode == null) { var newNode = obj1; if (this.graphManager == null) { throw "Graph has no graph mgr!"; } if (this.getNodes().indexOf(newNode) > -1) { throw "Node already in graph!"; } newNode.owner = this; this.getNodes().push(newNode); return newNode; } else { var newEdge = obj1; if (!(this.getNodes().indexOf(sourceNode) > -1 && this.getNodes().indexOf(targetNode) > -1)) { throw "Source or target not in graph!"; } if (!(sourceNode.owner == targetNode.owner && sourceNode.owner == this)) { throw "Both owners must be this graph!"; } if (sourceNode.owner != targetNode.owner) { return null; } // set source and target newEdge.source = sourceNode; newEdge.target = targetNode; // set as intra-graph edge newEdge.isInterGraph = false; // add to graph edge list this.getEdges().push(newEdge); // add to incidency lists sourceNode.edges.push(newEdge); if (targetNode != sourceNode) { targetNode.edges.push(newEdge); } return newEdge; } }; LGraph.prototype.remove = function (obj) { var node = obj; if (obj instanceof LNode) { if (node == null) { throw "Node is null!"; } if (!(node.owner != null && node.owner == this)) { throw "Owner graph is invalid!"; } if (this.graphManager == null) { throw "Owner graph manager is invalid!"; } // remove incident edges first (make a copy to do it safely) var edgesToBeRemoved = node.edges.slice(); var edge; var s = edgesToBeRemoved.length; for (var i = 0; i < s; i++) { edge = edgesToBeRemoved[i]; if (edge.isInterGraph) { this.graphManager.remove(edge); } else { edge.source.owner.remove(edge); } } // now the node itself var index = this.nodes.indexOf(node); if (index == -1) { throw "Node not in owner node list!"; } this.nodes.splice(index, 1); } else if (obj instanceof LEdge) { var edge = obj; if (edge == null) { throw "Edge is null!"; } if (!(edge.source != null && edge.target != null)) { throw "Source and/or target is null!"; } if (!(edge.source.owner != null && edge.target.owner != null && edge.source.owner == this && edge.target.owner == this)) { throw "Source and/or target owner is invalid!"; } var sourceIndex = edge.source.edges.indexOf(edge); var targetIndex = edge.target.edges.indexOf(edge); if (!(sourceIndex > -1 && targetIndex > -1)) { throw "Source and/or target doesn't know this edge!"; } edge.source.edges.splice(sourceIndex, 1); if (edge.target != edge.source) { edge.target.edges.splice(targetIndex, 1); } var index = edge.source.owner.getEdges().indexOf(edge); if (index == -1) { throw "Not in owner's edge list!"; } edge.source.owner.getEdges().splice(index, 1); } }; LGraph.prototype.updateLeftTop = function () { var top = Integer.MAX_VALUE; var left = Integer.MAX_VALUE; var nodeTop; var nodeLeft; var margin; var nodes = this.getNodes(); var s = nodes.length; for (var i = 0; i < s; i++) { var lNode = nodes[i]; nodeTop = lNode.getTop(); nodeLeft = lNode.getLeft(); if (top > nodeTop) { top = nodeTop; } if (left > nodeLeft) { left = nodeLeft; } } // Do we have any nodes in this graph? if (top == Integer.MAX_VALUE) { return null; } if (nodes[0].getParent().paddingLeft != undefined) { margin = nodes[0].getParent().paddingLeft; } else { margin = this.margin; } this.left = left - margin; this.top = top - margin; // Apply the margins and return the result return new Point(this.left, this.top); }; LGraph.prototype.updateBounds = function (recursive) { // calculate bounds var left = Integer.MAX_VALUE; var right = -Integer.MAX_VALUE; var top = Integer.MAX_VALUE; var bottom = -Integer.MAX_VALUE; var nodeLeft; var nodeRight; var nodeTop; var nodeBottom; var margin; var nodes = this.nodes; var s = nodes.length; for (var i = 0; i < s; i++) { var lNode = nodes[i]; if (recursive && lNode.child != null) { lNode.updateBounds(); } nodeLeft = lNode.getLeft(); nodeRight = lNode.getRight(); nodeTop = lNode.getTop(); nodeBottom = lNode.getBottom(); if (left > nodeLeft) { left = nodeLeft; } if (right < nodeRight) { right = nodeRight; } if (top > nodeTop) { top = nodeTop; } if (bottom < nodeBottom) { bottom = nodeBottom; } } var boundingRect = new RectangleD(left, top, right - left, bottom - top); if (left == Integer.MAX_VALUE) { this.left = this.parent.getLeft(); this.right = this.parent.getRight(); this.top = this.parent.getTop(); this.bottom = this.parent.getBottom(); } if (nodes[0].getParent().paddingLeft != undefined) { margin = nodes[0].getParent().paddingLeft; } else { margin = this.margin; } this.left = boundingRect.x - margin; this.right = boundingRect.x + boundingRect.width + margin; this.top = boundingRect.y - margin; this.bottom = boundingRect.y + boundingRect.height + margin; }; LGraph.calculateBounds = function (nodes) { var left = Integer.MAX_VALUE; var right = -Integer.MAX_VALUE; var top = Integer.MAX_VALUE; var bottom = -Integer.MAX_VALUE; var nodeLeft; var nodeRight; var nodeTop; var nodeBottom; var s = nodes.length; for (var i = 0; i < s; i++) { var lNode = nodes[i]; nodeLeft = lNode.getLeft(); nodeRight = lNode.getRight(); nodeTop = lNode.getTop(); nodeBottom = lNode.getBottom(); if (left > nodeLeft) { left = nodeLeft; } if (right < nodeRight) { right = nodeRight; } if (top > nodeTop) { top = nodeTop; } if (bottom < nodeBottom) { bottom = nodeBottom; } } var boundingRect = new RectangleD(left, top, right - left, bottom - top); return boundingRect; }; LGraph.prototype.getInclusionTreeDepth = function () { if (this == this.graphManager.getRoot()) { return 1; } else { return this.parent.getInclusionTreeDepth(); } }; LGraph.prototype.getEstimatedSize = function () { if (this.estimatedSize == Integer.MIN_VALUE) { throw "assert failed"; } return this.estimatedSize; }; LGraph.prototype.calcEstimatedSize = function () { var size = 0; var nodes = this.nodes; var s = nodes.length; for (var i = 0; i < s; i++) { var lNode = nodes[i]; size += lNode.calcEstimatedSize(); } if (size == 0) { this.estimatedSize = LayoutConstants.EMPTY_COMPOUND_NODE_SIZE; } else { this.estimatedSize = size / Math.sqrt(this.nodes.length); } return this.estimatedSize; }; LGraph.prototype.updateConnected = function () { var self = this; if (this.nodes.length == 0) { this.isConnected = true; return; } var queue = new LinkedList(); var visited = new Set(); var currentNode = this.nodes[0]; var neighborEdges; var currentNeighbor; var childrenOfNode = currentNode.withChildren(); childrenOfNode.forEach(function (node) { queue.push(node); visited.add(node); }); while (queue.length !== 0) { currentNode = queue.shift(); // Traverse all neighbors of this node neighborEdges = currentNode.getEdges(); var size = neighborEdges.length; for (var i = 0; i < size; i++) { var neighborEdge = neighborEdges[i]; currentNeighbor = neighborEdge.getOtherEndInGraph(currentNode, this); // Add unvisited neighbors to the list to visit if (currentNeighbor != null && !visited.has(currentNeighbor)) { var childrenOfNeighbor = currentNeighbor.withChildren(); childrenOfNeighbor.forEach(function (node) { queue.push(node); visited.add(node); }); } } } this.isConnected = false; if (visited.size >= this.nodes.length) { var noOfVisitedInThisGraph = 0; visited.forEach(function (visitedNode) { if (visitedNode.owner == self) { noOfVisitedInThisGraph++; } }); if (noOfVisitedInThisGraph == this.nodes.length) { this.isConnected = true; } } }; module.exports = LGraph; /***/ }), /* 6 */ /***/ (function(module, exports, __nested_webpack_require_27617__) { "use strict"; var LGraph; var LEdge = __nested_webpack_require_27617__(1); function LGraphManager(layout) { LGraph = __nested_webpack_require_27617__(5); // It may be better to initilize this out of this function but it gives an error (Right-hand side of 'instanceof' is not callable) now. this.layout = layout; this.graphs = []; this.edges = []; } LGraphManager.prototype.addRoot = function () { var ngraph = this.layout.newGraph(); var nnode = this.layout.newNode(null); var root = this.add(ngraph, nnode); this.setRootGraph(root); return this.rootGraph; }; LGraphManager.prototype.add = function (newGraph, parentNode, newEdge, sourceNode, targetNode) { //there are just 2 parameters are passed then it adds an LGraph else it adds an LEdge if (newEdge == null && sourceNode == null && targetNode == null) { if (newGraph == null) { throw "Graph is null!"; } if (parentNode == null) { throw "Parent node is null!"; } if (this.graphs.indexOf(newGraph) > -1) { throw "Graph already in this graph mgr!"; } this.graphs.push(newGraph); if (newGraph.parent != null) { throw "Already has a parent!"; } if (parentNode.child != null) { throw "Already has a child!"; } newGraph.parent = parentNode; parentNode.child = newGraph; return newGraph; } else { //change the order of the parameters targetNode = newEdge; sourceNode = parentNode; newEdge = newGraph; var sourceGraph = sourceNode.getOwner(); var targetGraph = targetNode.getOwner(); if (!(sourceGraph != null && sourceGraph.getGraphManager() == this)) { throw "Source not in this graph mgr!"; } if (!(targetGraph != null && targetGraph.getGraphManager() == this)) { throw "Target not in this graph mgr!"; } if (sourceGraph == targetGraph) { newEdge.isInterGraph = false; return sourceGraph.add(newEdge, sourceNode, targetNode); } else { newEdge.isInterGraph = true; // set source and target newEdge.source = sourceNode; newEdge.target = targetNode; // add edge to inter-graph edge list if (this.edges.indexOf(newEdge) > -1) { throw "Edge already in inter-graph edge list!"; } this.edges.push(newEdge); // add edge to source and target incidency lists if (!(newEdge.source != null && newEdge.target != null)) { throw "Edge source and/or target is null!"; } if (!(newEdge.source.edges.indexOf(newEdge) == -1 && newEdge.target.edges.indexOf(newEdge) == -1)) { throw "Edge already in source and/or target incidency list!"; } newEdge.source.edges.push(newEdge); newEdge.target.edges.push(newEdge); return newEdge; } } }; LGraphManager.prototype.remove = function (lObj) { if (lObj instanceof LGraph) { var graph = lObj; if (graph.getGraphManager() != this) { throw "Graph not in this graph mgr"; } if (!(graph == this.rootGraph || graph.parent != null && graph.parent.graphManager == this)) { throw "Invalid parent node!"; } // first the edges (make a copy to do it safely) var edgesToBeRemoved = []; edgesToBeRemoved = edgesToBeRemoved.concat(graph.getEdges()); var edge; var s = edgesToBeRemoved.length; for (var i = 0; i < s; i++) { edge = edgesToBeRemoved[i]; graph.remove(edge); } // then the nodes (make a copy to do it safely) var nodesToBeRemoved = []; nodesToBeRemoved = nodesToBeRemoved.concat(graph.getNodes()); var node; s = nodesToBeRemoved.length; for (var i = 0; i < s; i++) { node = nodesToBeRemoved[i]; graph.remove(node); } // check if graph is the root if (graph == this.rootGraph) { this.setRootGraph(null); } // now remove the graph itself var index = this.graphs.indexOf(graph); this.graphs.splice(index, 1); // also reset the parent of the graph graph.parent = null; } else if (lObj instanceof LEdge) { edge = lObj; if (edge == null) { throw "Edge is null!"; } if (!edge.isInterGraph) { throw "Not an inter-graph edge!"; } if (!(edge.source != null && edge.target != null)) { throw "Source and/or target is null!"; } // remove edge from source and target nodes' incidency lists if (!(edge.source.edges.indexOf(edge) != -1 && edge.target.edges.indexOf(edge) != -1)) { throw "Source and/or target doesn't know this edge!"; } var index = edge.source.edges.indexOf(edge); edge.source.edges.splice(index, 1); index = edge.target.edges.indexOf(edge); edge.target.edges.splice(index, 1); // remove edge from owner graph manager's inter-graph edge list if (!(edge.source.owner != null && edge.source.owner.getGraphManager() != null)) { throw "Edge owner graph or owner graph manager is null!"; } if (edge.source.owner.getGraphManager().edges.indexOf(edge) == -1) { throw "Not in owner graph manager's edge list!"; } var index = edge.source.owner.getGraphManager().edges.indexOf(edge); edge.source.owner.getGraphManager().edges.splice(index, 1); } }; LGraphManager.prototype.updateBounds = function () { this.rootGraph.updateBounds(true); }; LGraphManager.prototype.getGraphs = function () { return this.graphs; }; LGraphManager.prototype.getAllNodes = function () { if (this.allNodes == null) { var nodeList = []; var graphs = this.getGraphs(); var s = graphs.length; for (var i = 0; i < s; i++) { nodeList = nodeList.concat(graphs[i].getNodes()); } this.allNodes = nodeList; } return this.allNodes; }; LGraphManager.prototype.resetAllNodes = function () { this.allNodes = null; }; LGraphManager.prototype.resetAllEdges = function () { this.allEdges = null; }; LGraphManager.prototype.resetAllNodesToApplyGravitation = function () { this.allNodesToApplyGravitation = null; }; LGraphManager.prototype.getAllEdges = function () { if (this.allEdges == null) { var edgeList = []; var graphs = this.getGraphs(); var s = graphs.length; for (var i = 0; i < graphs.length; i++) { edgeList = edgeList.concat(graphs[i].getEdges()); } edgeList = edgeList.concat(this.edges); this.allEdges = edgeList; } return this.allEdges; }; LGraphManager.prototype.getAllNodesToApplyGravitation = function () { return this.allNodesToApplyGravitation; }; LGraphManager.prototype.setAllNodesToApplyGravitation = function (nodeList) { if (this.allNodesToApplyGravitation != null) { throw "assert failed"; } this.allNodesToApplyGravitation = nodeList; }; LGraphManager.prototype.getRoot = function () { return this.rootGraph; }; LGraphManager.prototype.setRootGraph = function (graph) { if (graph.getGraphManager() != this) { throw "Root not in this graph mgr!"; } this.rootGraph = graph; // root graph must have a root node associated with it for convenience if (graph.parent == null) { graph.parent = this.layout.newNode("Root node"); } }; LGraphManager.prototype.getLayout = function () { return this.layout; }; LGraphManager.prototype.isOneAncestorOfOther = function (firstNode, secondNode) { if (!(firstNode != null && secondNode != null)) { throw "assert failed"; } if (firstNode == secondNode) { return true; } // Is second node an ancestor of the first one? var ownerGraph = firstNode.getOwner(); var parentNode; do { parentNode = ownerGraph.getParent(); if (parentNode == null) { break; } if (parentNode == secondNode) { return true; } ownerGraph = parentNode.getOwner(); if (ownerGraph == null) { break; } } while (true); // Is first node an ancestor of the second one? ownerGraph = secondNode.getOwner(); do { parentNode = ownerGraph.getParent(); if (parentNode == null) { break; } if (parentNode == firstNode) { return true; } ownerGraph = parentNode.getOwner(); if (ownerGraph == null) { break; } } while (true); return false; }; LGraphManager.prototype.calcLowestCommonAncestors = function () { var edge; var sourceNode; var targetNode; var sourceAncestorGraph; var targetAncestorGraph; var edges = this.getAllEdges(); var s = edges.length; for (var i = 0; i < s; i++) { edge = edges[i]; sourceNode = edge.source; targetNode = edge.target; edge.lca = null; edge.sourceInLca = sourceNode; edge.targetInLca = targetNode; if (sourceNode == targetNode) { edge.lca = sourceNode.getOwner(); continue; } sourceAncestorGraph = sourceNode.getOwner(); while (edge.lca == null) { edge.targetInLca = targetNode; targetAncestorGraph = targetNode.getOwner(); while (edge.lca == null) { if (targetAncestorGraph == sourceAncestorGraph) { edge.lca = targetAncestorGraph; break; } if (targetAncestorGraph == this.rootGraph) { break; } if (edge.lca != null) { throw "assert failed"; } edge.targetInLca = targetAncestorGraph.getParent(); targetAncestorGraph = edge.targetInLca.getOwner(); } if (sourceAncestorGraph == this.rootGraph) { break; } if (edge.lca == null) { edge.sourceInLca = sourceAncestorGraph.getParent(); sourceAncestorGraph = edge.sourceInLca.getOwner(); } } if (edge.lca == null) { throw "assert failed"; } } }; LGraphManager.prototype.calcLowestCommonAncestor = function (firstNode, secondNode) { if (firstNode == secondNode) { return firstNode.getOwner(); } var firstOwnerGraph = firstNode.getOwner(); do { if (firstOwnerGraph == null) { break; } var secondOwnerGraph = secondNode.getOwner(); do { if (secondOwnerGraph == null) { break; } if (secondOwnerGraph == firstOwnerGraph) { return secondOwnerGraph; } secondOwnerGraph = secondOwnerGraph.getParent().getOwner(); } while (true); firstOwnerGraph = firstOwnerGraph.getParent().getOwner(); } while (true); return firstOwnerGraph; }; LGraphManager.prototype.calcInclusionTreeDepths = function (graph, depth) { if (graph == null && depth == null) { graph = this.rootGraph; depth = 1; } var node; var nodes = graph.getNodes(); var s = nodes.length; for (var i = 0; i < s; i++) { node = nodes[i]; node.inclusionTreeDepth = depth; if (node.child != null) { this.calcInclusionTreeDepths(node.child, depth + 1); } } }; LGraphManager.prototype.includesInvalidEdge = function () { var edge; var s = this.edges.length; for (var i = 0; i < s; i++) { edge = this.edges[i]; if (this.isOneAncestorOfOther(edge.source, edge.target)) { return true; } } return false; }; module.exports = LGraphManager; /***/ }), /* 7 */ /***/ (function(module, exports, __nested_webpack_require_38707__) { "use strict"; var LayoutConstants = __nested_webpack_require_38707__(0); function FDLayoutConstants() {} //FDLayoutConstants inherits static props in LayoutConstants for (var prop in LayoutConstants) { FDLayoutConstants[prop] = LayoutConstants[prop]; } FDLayoutConstants.MAX_ITERATIONS = 2500; FDLayoutConstants.DEFAULT_EDGE_LENGTH = 50; FDLayoutConstants.DEFAULT_SPRING_STRENGTH = 0.45; FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = 4500.0; FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = 0.4; FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = 1.0; FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = 3.8; FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = 1.5; FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION = true; FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION = true; FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = 0.3; FDLayoutConstants.COOLING_ADAPTATION_FACTOR = 0.33; FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT = 1000; FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT = 5000; FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL = 100.0; FDLayoutConstants.MAX_NODE_DISPLACEMENT = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL * 3; FDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0; FDLayoutConstants.CONVERGENCE_CHECK_PERIOD = 100; FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = 0.1; FDLayoutConstants.MIN_EDGE_LENGTH = 1; FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD = 10; module.exports = FDLayoutConstants; /***/ }), /* 8 */ /***/ (function(module, exports, __nested_webpack_require_40298__) { "use strict"; /** * This class maintains a list of static geometry related utility methods. * * * Copyright: i-Vis Research Group, Bilkent University, 2007 - present */ var Point = __nested_webpack_require_40298__(12); function IGeometry() {} /** * This method calculates *half* the amount in x and y directions of the two * input rectangles needed to separate them keeping their respective * positioning, and returns the result in the input array. An input * separation buffer added to the amount in both directions. We assume that * the two rectangles do intersect. */ IGeometry.calcSeparationAmount = function (rectA, rectB, overlapAmount, separationBuffer) { if (!rectA.intersects(rectB)) { throw "assert failed"; } var directions = new Array(2); this.decideDirectionsForOverlappingNodes(rectA, rectB, directions); overlapAmount[0] = Math.min(rectA.getRight(), rectB.getRight()) - Math.max(rectA.x, rectB.x); overlapAmount[1] = Math.min(rectA.getBottom(), rectB.getBottom()) - Math.max(rectA.y, rectB.y); // update the overlapping amounts for the following cases: if (rectA.getX() <= rectB.getX() && rectA.getRight() >= rectB.getRight()) { /* Case x.1: * * rectA * | | * | _________ | * | | | | * |________|_______|______| * | | * | | * rectB */ overlapAmount[0] += Math.min(rectB.getX() - rectA.getX(), rectA.getRight() - rectB.getRight()); } else if (rectB.getX() <= rectA.getX() && rectB.getRight() >= rectA.getRight()) { /* Case x.2: * * rectB * | | * | _________ | * | | | | * |________|_______|______| * | | * | | * rectA */ overlapAmount[0] += Math.min(rectA.getX() - rectB.getX(), rectB.getRight() - rectA.getRight()); } if (rectA.getY() <= rectB.getY() && rectA.getBottom() >= rectB.getBottom()) { /* Case y.1: * ________ rectA * | * | * ______|____ rectB * | | * | | * ______|____| * | * | * |________ * */ overlapAmount[1] += Math.min(rectB.getY() - rectA.getY(), rectA.getBottom() - rectB.getBottom()); } else if (rectB.getY() <= rectA.getY() && rectB.getBottom() >= rectA.getBottom()) { /* Case y.2: * ________ rectB * | * | * ______|____ rectA * | | * | | * ______|____| * | * | * |________ * */ overlapAmount[1] += Math.min(rectA.getY() - rectB.getY(), rectB.getBottom() - rectA.getBottom()); } // find slope of the line passes two centers var slope = Math.abs((rectB.getCenterY() - rectA.getCenterY()) / (rectB.getCenterX() - rectA.getCenterX())); // if centers are overlapped if (rectB.getCenterY() === rectA.getCenterY() && rectB.getCenterX() === rectA.getCenterX()) { // assume the slope is 1 (45 degree) slope = 1.0; } var moveByY = slope * overlapAmount[0]; var moveByX = overlapAmount[1] / slope; if (overlapAmount[0] < moveByX) { moveByX = overlapAmount[0]; } else { moveByY = overlapAmount[1]; } // return half the amount so that if each rectangle is moved by these // amounts in opposite directions, overlap will be resolved overlapAmount[0] = -1 * directions[0] * (moveByX / 2 + separationBuffer); overlapAmount[1] = -1 * directions[1] * (moveByY / 2 + separationBuffer); }; /** * This method decides the separation direction of overlapping nodes * * if directions[0] = -1, then rectA goes left * if directions[0] = 1, then rectA goes right * if directions[1] = -1, then rectA goes up * if directions[1] = 1, then rectA goes down */ IGeometry.decideDirectionsForOverlappingNodes = function (rectA, rectB, directions) { if (rectA.getCenterX() < rectB.getCenterX()) { directions[0] = -1; } else { directions[0] = 1; } if (rectA.getCenterY() < rectB.getCenterY()) { directions[1] = -1; } else { directions[1] = 1; } }; /** * This method calculates the intersection (clipping) points of the two * input rectangles with line segment defined by the centers of these two * rectangles. The clipping points are saved in the input double array and * whether or not the two rectangles overlap is returned. */ IGeometry.getIntersection2 = function (rectA, rectB, result) { //result[0-1] will contain clipPoint of rectA, result[2-3] will contain clipPoint of rectB var p1x = rectA.getCenterX(); var p1y = rectA.getCenterY(); var p2x = rectB.getCenterX(); var p2y = rectB.getCenterY(); //if two rectangles intersect, then clipping points are centers if (rectA.intersects(rectB)) { result[0] = p1x; result[1] = p1y; result[2] = p2x; result[3] = p2y; return true; } //variables for rectA var topLeftAx = rectA.getX(); var topLeftAy = rectA.getY(); var topRightAx = rectA.getRight(); var bottomLeftAx = rectA.getX(); var bottomLeftAy = rectA.getBottom(); var bottomRightAx = rectA.getRight(); var halfWidthA = rectA.getWidthHalf(); var halfHeightA = rectA.getHeightHalf(); //variables for rectB var topLeftBx = rectB.getX(); var topLeftBy = rectB.getY(); var topRightBx = rectB.getRight(); var bottomLeftBx = rectB.getX(); var bottomLeftBy = rectB.getBottom(); var bottomRightBx = rectB.getRight(); var halfWidthB = rectB.getWidthHalf(); var halfHeightB = rectB.getHeightHalf(); //flag whether clipping points are found var clipPointAFound = false; var clipPointBFound = false; // line is vertical if (p1x === p2x) { if (p1y > p2y) { result[0] = p1x; result[1] = topLeftAy; result[2] = p2x; result[3] = bottomLeftBy; return false; } else if (p1y < p2y) { result[0] = p1x; result[1] = bottomLeftAy; result[2] = p2x; result[3] = topLeftBy; return false; } else { //not line, return null; } } // line is horizontal else if (p1y === p2y) { if (p1x > p2x) { result[0] = topLeftAx; result[1] = p1y; result[2] = topRightBx; result[3] = p2y; return false; } else if (p1x < p2x) { result[0] = topRightAx; result[1] = p1y; result[2] = topLeftBx; result[3] = p2y; return false; } else { //not valid line, return null; } } else { //slopes of rectA's and rectB's diagonals var slopeA = rectA.height / rectA.width; var slopeB = rectB.height / rectB.width; //slope of line between center of rectA and center of rectB var slopePrime = (p2y - p1y) / (p2x - p1x); var cardinalDirectionA = void 0; var cardinalDirectionB = void 0; var tempPointAx = void 0; var tempPointAy = void 0; var tempPointBx = void 0; var tempPointBy = void 0; //determine whether clipping point is the corner of nodeA if (-slopeA === slopePrime) { if (p1x > p2x) { result[0] = bottomLeftAx; result[1] = bottomLeftAy; clipPointAFound = true; } else { result[0] = topRightAx; result[1] = topLeftAy; clipPointAFound = true; } } else if (slopeA === slopePrime) { if (p1x > p2x) { result[0] = topLeftAx; result[1] = topLeftAy; clipPointAFound = true; } else { result[0] = bottomRightAx; result[1] = bottomLeftAy; clipPointAFound = true; } } //determine whether clipping point is the corner of nodeB if (-slopeB === slopePrime) { if (p2x > p1x) { result[2] = bottomLeftBx; result[3] = bottomLeftBy; clipPointBFound = true; } else { result[2] = topRightBx; result[3] = topLeftBy; clipPointBFound = true; } } else if (slopeB === slopePrime) { if (p2x > p1x) { result[2] = topLeftBx; result[3] = topLeftBy; clipPointBFound = true; } else { result[2] = bottomRightBx; result[3] = bottomLeftBy; clipPointBFound = true; } } //if both clipping points are corners if (clipPointAFound && clipPointBFound) { return false; } //determine Cardinal Direction of rectangles if (p1x > p2x) { if (p1y > p2y) { cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 4); cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 2); } else { cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 3); cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 1); } } else { if (p1y > p2y) { cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 1); cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 3); } else { cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 2); cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 4); } } //calculate clipping Point if it is not found before if (!clipPointAFound) { switch (cardinalDirectionA) { case 1: tempPointAy = topLeftAy; tempPointAx = p1x + -halfHeightA / slopePrime; result[0] = tempPointAx; result[1] = tempPointAy; break; case 2: tempPointAx = bottomRightAx; tempPointAy = p1y + halfWidthA * slopePrime; result[0] = tempPointAx; result[1] = tempPointAy; break; case 3: tempPointAy = bottomLeftAy; tempPointAx = p1x + halfHeightA / slopePrime; result[0] = tempPointAx; result[1] = tempPointAy; break; case 4: tempPointAx = bottomLeftAx; tempPointAy = p1y + -halfWidthA * slopePrime; result[0] = tempPointAx; result[1] = tempPointAy; break; } } if (!clipPointBFound) { switch (cardinalDirectionB) { case 1: tempPointBy = topLeftBy; tempPointBx = p2x + -halfHeightB / slopePrime; result[2] = tempPointBx; result[3] = tempPointBy; break; case 2: tempPointBx = bottomRightBx; tempPointBy = p2y + halfWidthB * slopePrime; result[2] = tempPointBx; result[3] = tempPointBy; break; case 3: tempPointBy = bottomLeftBy; tempPointBx = p2x + halfHeightB / slopePrime; result[2] = tempPointBx; result[3] = tempPointBy; break; case 4: tempPointBx = bottomLeftBx; tempPointBy = p2y + -halfWidthB * slopePrime; result[2] = tempPointBx; result[3] = tempPointBy; break; } } } return false; }; /** * This method returns in which cardinal direction does input point stays * 1: North * 2: East * 3: South * 4: West */ IGeometry.getCardinalDirection = function (slope, slopePrime, line) { if (slope > slopePrime) { return line; } else { return 1 + line % 4; } }; /** * This method calculates the intersection of the two lines defined by * point pairs (s1,s2) and (f1,f2). */ IGeometry.getIntersection = function (s1, s2, f1, f2) { if (f2 == null) { return this.getIntersection2(s1, s2, f1); } var x1 = s1.x; var y1 = s1.y; var x2 = s2.x; var y2 = s2.y; var x3 = f1.x; var y3 = f1.y; var x4 = f2.x; var y4 = f2.y; var x = void 0, y = void 0; // intersection point var a1 = void 0, a2 = void 0, b1 = void 0, b2 = void 0, c1 = void 0, c2 = void 0; // coefficients of line eqns. var denom = void 0; a1 = y2 - y1; b1 = x1 - x2; c1 = x2 * y1 - x1 * y2; // { a1*x + b1*y + c1 = 0 is line 1 } a2 = y4 - y3; b2 = x3 - x4; c2 = x4 * y3 - x3 * y4; // { a2*x + b2*y + c2 = 0 is line 2 } denom = a1 * b2 - a2 * b1; if (denom === 0) { return null; } x = (b1 * c2 - b2 * c1) / denom; y = (a2 * c1 - a1 * c2) / denom; return new Point(x, y); }; /** * This method finds and returns the angle of the vector from the + x-axis * in clockwise direction (compatible w/ Java coordinate system!). */ IGeometry.angleOfVector = function (Cx, Cy, Nx, Ny) { var C_angle = void 0; if (Cx !== Nx) { C_angle = Math.atan((Ny - Cy) / (Nx - Cx)); if (Nx < Cx) { C_angle += Math.PI; } else if (Ny < Cy) { C_angle += this.TWO_PI; } } else if (Ny < Cy) { C_angle = this.ONE_AND_HALF_PI; // 270 degrees } else { C_angle = this.HALF_PI; // 90 degrees } return C_angle; }; /** * This method checks whether the given two line segments (one with point * p1 and p2, the other with point p3 and p4) intersect at a point other * than these points. */ IGeometry.doIntersect = function (p1, p2, p3, p4) { var a = p1.x; var b = p1.y; var c = p2.x; var d = p2.y; var p = p3.x; var q = p3.y; var r = p4.x; var s = p4.y; var det = (c - a) * (s - q) - (r - p) * (d - b); if (det === 0) { return false; } else { var lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; var gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1; } }; // ----------------------------------------------------------------------------- // Section: Class Constants // ----------------------------------------------------------------------------- /** * Some useful pre-calculated constants */ IGeometry.HALF_PI = 0.5 * Math.PI; IGeometry.ONE_AND_HALF_PI = 1.5 * Math.PI; IGeometry.TWO_PI = 2.0 * Math.PI; IGeometry.THREE_PI = 3.0 * Math.PI; module.exports = IGeometry; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function IMath() {} /** * This method returns the sign of the input value. */ IMath.sign = function (value) { if (value > 0) { return 1; } else if (value < 0) { return -1; } else { return 0; } }; IMath.floor = function (value) { return value < 0 ? Math.ceil(value) : Math.floor(value); }; IMath.ceil = function (value) { return value < 0 ? Math.floor(value) : Math.ceil(value); }; module.exports = IMath; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function Integer() {} Integer.MAX_VALUE = 2147483647; Integer.MIN_VALUE = -2147483648; module.exports = Integer; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var nodeFrom = function nodeFrom(value) { return { value: value, next: null, prev: null }; }; var add = function add(prev, node, next, list) { if (prev !== null) { prev.next = node; } else { list.head = node; } if (next !== null) { next.prev = node; } else { list.tail = node; } node.prev = prev; node.next = next; list.length++; return node; }; var _remove = function _remove(node, list) { var prev = node.prev, next = node.next; if (prev !== null) { prev.next = next; } else { list.head = next; } if (next !== null) { next.prev = prev; } else { list.tail = prev; } node.prev = node.next = null; list.length--; return node; }; var LinkedList = function () { function LinkedList(vals) { var _this = this; _classCallCheck(this, LinkedList); this.length = 0; this.head = null; this.tail = null; if (vals != null) { vals.forEach(function (v) { return _this.push(v); }); } } _createClass(LinkedList, [{ key: "size", value: function size() { return this.length; } }, { key: "insertBefore", value: function insertBefore(val, otherNode) { return add(otherNode.prev, nodeFrom(val), otherNode, this); } }, { key: "insertAfter", value: function insertAfter(val, otherNode) { return add(otherNode, nodeFrom(val), otherNode.next, this); } }, { key: "insertNodeBefore", value: function insertNodeBefore(newNode, otherNode) { return add(otherNode.prev, newNode, otherNode, this); } }, { key: "insertNodeAfter", value: function insertNodeAfter(newNode, otherNode) { return add(otherNode, newNode, otherNode.next, this); } }, { key: "push", value: function push(val) { return add(this.tail, nodeFrom(val), null, this); } }, { key: "unshift", value: function unshift(val) { return add(null, nodeFrom(val), this.head, this); } }, { key: "remove", value: function remove(node) { return _remove(node, this); } }, { key: "pop", value: function pop() { return _remove(this.tail, this).value; } }, { key: "popNode", value: function popNode() { return _remove(this.tail, this); } }, { key: "shift", value: function shift() { return _remove(this.head, this).value; } }, { key: "shiftNode", value: function shiftNode() { return _remove(this.head, this); } }, { key: "get_object_at", value: function get_object_at(index) { if (index <= this.length()) { var i = 1; var current = this.head; while (i < index) { current = current.next; i++; } return current.value; } } }, { key: "set_object_at", value: function set_object_at(index, value) { if (index <= this.length()) { var i = 1; var current = this.head; while (i < index) { current = current.next; i++; } current.value = value; } } }]); return LinkedList; }(); module.exports = LinkedList; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* *This class is the javascript implementation of the Point.java class in jdk */ function Point(x, y, p) { this.x = null; this.y = null; if (x == null && y == null && p == null) { this.x = 0; this.y = 0; } else if (typeof x == 'number' && typeof y == 'number' && p == null) { this.x = x; this.y = y; } else if (x.constructor.name == 'Point' && y == null && p == null) { p = x; this.x = p.x; this.y = p.y; } } Point.prototype.getX = function () { return this.x; }; Point.prototype.getY = function () { return this.y; }; Point.prototype.getLocation = function () { return new Point(this.x, this.y); }; Point.prototype.setLocation = function (x, y, p) { if (x.constructor.name == 'Point' && y == null && p == null) { p = x; this.setLocation(p.x, p.y); } else if (typeof x == 'number' && typeof y == 'number' && p == null) { //if both parameters are integer just move (x,y) location if (parseInt(x) == x && parseInt(y) == y) { this.move(x, y); } else { this.x = Math.floor(x + 0.5); this.y = Math.floor(y + 0.5); } } }; Point.prototype.move = function (x, y) { this.x = x; this.y = y; }; Point.prototype.translate = function (dx, dy) { this.x += dx; this.y += dy; }; Point.prototype.equals = function (obj) { if (obj.constructor.name == "Point") { var pt = obj; return this.x == pt.x && this.y == pt.y; } return this == obj; }; Point.prototype.toString = function () { return new Point().constructor.name + "[x=" + this.x + ",y=" + this.y + "]"; }; module.exports = Point; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function RectangleD(x, y, width, height) { this.x = 0; this.y = 0; this.width = 0; this.height = 0; if (x != null && y != null && width != null && height != null) { this.x = x; this.y = y; this.width = width; this.height = height; } } RectangleD.prototype.getX = function () { return this.x; }; RectangleD.prototype.setX = function (x) { this.x = x; }; RectangleD.prototype.getY = function () { return this.y; }; RectangleD.prototype.setY = function (y) { this.y = y; }; RectangleD.prototype.getWidth = function () { return this.width; }; RectangleD.prototype.setWidth = function (width) { this.width = width; }; RectangleD.prototype.getHeight = function () { return this.height; }; RectangleD.prototype.setHeight = function (height) { this.height = height; }; RectangleD.prototype.getRight = function () { return this.x + this.width; }; RectangleD.prototype.getBottom = function () { return this.y + this.height; }; RectangleD.prototype.intersects = function (a) { if (this.getRight() < a.x) { return false; } if (this.getBottom() < a.y) { return false; } if (a.getRight() < this.x) { return false; } if (a.getBottom() < this.y) { return false; } return true; }; RectangleD.prototype.getCenterX = function () { return this.x + this.width / 2; }; RectangleD.prototype.getMinX = function () { return this.getX(); }; RectangleD.prototype.getMaxX = function () { return this.getX() + this.width; }; RectangleD.prototype.getCenterY = function () { return this.y + this.height / 2; }; RectangleD.prototype.getMinY = function () { return this.getY(); }; RectangleD.prototype.getMaxY = function () { return this.getY() + this.height; }; RectangleD.prototype.getWidthHalf = function () { return this.width / 2; }; RectangleD.prototype.getHeightHalf = function () { return this.height / 2; }; module.exports = RectangleD; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function UniqueIDGeneretor() {} UniqueIDGeneretor.lastID = 0; UniqueIDGeneretor.createID = function (obj) { if (UniqueIDGeneretor.isPrimitive(obj)) { return obj; } if (obj.uniqueID != null) { return obj.uniqueID; } obj.uniqueID = UniqueIDGeneretor.getString(); UniqueIDGeneretor.lastID++; return obj.uniqueID; }; UniqueIDGeneretor.getString = function (id) { if (id == null) id = UniqueIDGeneretor.lastID; return "Object#" + id + ""; }; UniqueIDGeneretor.isPrimitive = function (arg) { var type = typeof arg === "undefined" ? "undefined" : _typeof(arg); return arg == null || type != "object" && type != "function"; }; module.exports = UniqueIDGeneretor; /***/ }), /* 15 */ /***/ (function(module, exports, __nested_webpack_require_64072__) { "use strict"; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var LayoutConstants = __nested_webpack_require_64072__(0); var LGraphManager = __nested_webpack_require_64072__(6); var LNode = __nested_webpack_require_64072__(3); var LEdge = __nested_webpack_require_64072__(1); var LGraph = __nested_webpack_require_64072__(5); var PointD = __nested_webpack_require_64072__(4); var Transform = __nested_webpack_require_64072__(17); var Emitter = __nested_webpack_require_64072__(27); function Layout(isRemoteUse) { Emitter.call(this); //Layout Quality: 0:draft, 1:default, 2:proof this.layoutQuality = LayoutConstants.QUALITY; //Whether layout should create bendpoints as needed or not this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; //Whether layout should be incremental or not this.incremental = LayoutConstants.DEFAULT_INCREMENTAL; //Whether we animate from before to after layout node positions this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT; //Whether we animate the layout process or not this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT; //Number iterations that should be done between two successive animations this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD; /** * Whether or not leaf nodes (non-compound nodes) are of uniform sizes. When * they are, both spring and repulsion forces between two leaf nodes can be * calculated without the expensive clipping point calculations, resulting * in major speed-up. */ this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES; /** * This is used for creation of bendpoints by using dummy nodes and edges. * Maps an LEdge to its dummy bendpoint path. */ this.edgeToDummyNodes = new Map(); this.graphManager = new LGraphManager(this); this.isLayoutFinished = false; this.isSubLayout = false; this.isRemoteUse = false; if (isRemoteUse != null) { this.isRemoteUse = isRemoteUse; } } Layout.RANDOM_SEED = 1; Layout.prototype = Object.create(Emitter.prototype); Layout.prototype.getGraphManager = function () { return this.graphManager; }; Layout.prototype.getAllNodes = function () { return this.graphManager.getAllNodes(); }; Layout.prototype.getAllEdges = function () { return this.graphManager.getAllEdges(); }; Layout.prototype.getAllNodesToApplyGravitation = function () { return this.graphManager.getAllNodesToApplyGravitation(); }; Layout.prototype.newGraphManager = function () { var gm = new LGraphManager(this); this.graphManager = gm; return gm; }; Layout.prototype.newGraph = function (vGraph) { return new LGraph(null, this.graphManager, vGraph); }; Layout.prototype.newNode = function (vNode) { return new LNode(this.graphManager, vNode); }; Layout.prototype.newEdge = function (vEdge) { return new LEdge(null, null, vEdge); }; Layout.prototype.checkLayoutSuccess = function () { return this.graphManager.getRoot() == null || this.graphManager.getRoot().getNodes().length == 0 || this.graphManager.includesInvalidEdge(); }; Layout.prototype.runLayout = function () { this.isLayoutFinished = false; if (this.tilingPreLayout) { this.tilingPreLayout(); } this.initParameters(); var isLayoutSuccessfull; if (this.checkLayoutSuccess()) { isLayoutSuccessfull = false; } else { isLayoutSuccessfull = this.layout(); } if (LayoutConstants.ANIMATE === 'during') { // If this is a 'during' layout animation. Layout is not finished yet. // We need to perform these in index.js when layout is really finished. return false; } if (isLayoutSuccessfull) { if (!this.isSubLayout) { this.doPostLayout(); } } if (this.tilingPostLayout) { this.tilingPostLayout(); } this.isLayoutFinished = true; return isLayoutSuccessfull; }; /** * This method performs the operations required after layout. */ Layout.prototype.doPostLayout = function () { //assert !isSubLayout : "Should not be called on sub-layout!"; // Propagate geometric changes to v-level objects if (!this.incremental) { this.transform(); } this.update(); }; /** * This method updates the geometry of the target graph according to * calculated layout. */ Layout.prototype.update2 = function () { // update bend points if (this.createBendsAsNeeded) { this.createBendpointsFromDummyNodes(); // reset all edges, since the topology has changed this.graphManager.resetAllEdges(); } // perform edge, node and root updates if layout is not called // remotely if (!this.isRemoteUse) { // update all edges var edge; var allEdges = this.graphManager.getAllEdges(); for (var i = 0; i < allEdges.length; i++) { edge = allEdges[i]; // this.update(edge); } // recursively update nodes var node; var nodes = this.graphManager.getRoot().getNodes(); for (var i = 0; i < nodes.length; i++) { node = nodes[i]; // this.update(node); } // update root graph this.update(this.graphManager.getRoot()); } }; Layout.prototype.update = function (obj) { if (obj == null) { this.update2(); } else if (obj instanceof LNode) { var node = obj; if (node.getChild() != null) { // since node is compound, recursively update child nodes var nodes = node.getChild().getNodes(); for (var i = 0; i < nodes.length; i++) { update(nodes[i]); } } // if the l-level node is associated with a v-level graph object, // then it is assumed that the v-level node implements the // interface Updatable. if (node.vGraphObject != null) { // cast to Updatable without any type check var vNode = node.vGraphObject; // call the update method of the interface vNode.update(node); } } else if (obj instanceof LEdge) { var edge = obj; // if the l-level edge is associated with a v-level graph object, // then it is assumed that the v-level edge implements the // interface Updatable. if (edge.vGraphObject != null) { // cast to Updatable without any type check var vEdge = edge.vGraphObject; // call the update method of the interface vEdge.update(edge); } } else if (obj instanceof LGraph) { var graph = obj; // if the l-level graph is associated with a v-level graph object, // then it is assumed that the v-level object implements the // interface Updatable. if (graph.vGraphObject != null) { // cast to Updatable without any type check var vGraph = graph.vGraphObject; // call the update method of the interface vGraph.update(graph); } } }; /** * This method is used to set all layout parameters to default values * determined at compile time. */ Layout.prototype.initParameters = function () { if (!this.isSubLayout) { this.layoutQuality = LayoutConstants.QUALITY; this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT; this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD; this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT; this.incremental = LayoutConstants.DEFAULT_INCREMENTAL; this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES; } if (this.animationDuringLayout) { this.animationOnLayout = false; } }; Layout.prototype.transform = function (newLeftTop) { if (newLeftTop == undefined) { this.transform(new PointD(0, 0)); } else { // create a transformation object (from Eclipse to layout). When an // inverse transform is applied, we get upper-left coordinate of the // drawing or the root graph at given input coordinate (some margins // already included in calculation of left-top). var trans = new Transform(); var leftTop = this.graphManager.getRoot().updateLeftTop(); if (leftTop != null) { trans.setWorldOrgX(newLeftTop.x); trans.setWorldOrgY(newLeftTop.y); trans.setDeviceOrgX(leftTop.x); trans.setDeviceOrgY(leftTop.y); var nodes = this.getAllNodes(); var node; for (var i = 0; i < nodes.length; i++) { node = nodes[i]; node.transform(trans); } } } }; Layout.prototype.positionNodesRandomly = function (graph) { if (graph == undefined) { //assert !this.incremental; this.positionNodesRandomly(this.getGraphManager().getRoot()); this.getGraphManager().getRoot().updateBounds(true); } else { var lNode; var childGraph; var nodes = graph.getNodes(); for (var i = 0; i < nodes.length; i++) { lNode = nodes[i]; childGraph = lNode.getChild(); if (childGraph == null) { lNode.scatter(); } else if (childGraph.getNodes().length == 0) { lNode.scatter(); } else { this.positionNodesRandomly(childGraph); lNode.updateBounds(); } } } }; /** * This method returns a list of trees where each tree is represented as a * list of l-nodes. The method returns a list of size 0 when: * - The graph is not flat or * - One of the component(s) of the graph is not a tree. */ Layout.prototype.getFlatForest = function () { var flatForest = []; var isForest = true; // Quick reference for all nodes in the graph manager associated with // this layout. The list should not be changed. var allNodes = this.graphManager.getRoot().getNodes(); // First be sure that the graph is flat var isFlat = true; for (var i = 0; i < allNodes.length; i++) { if (allNodes[i].getChild() != null) { isFlat = false; } } // Return empty forest if the graph is not flat. if (!isFlat) { return flatForest; } // Run BFS for each component of the graph. var visited = new Set(); var toBeVisited = []; var parents = new Map(); var unProcessedNodes = []; unProcessedNodes = unProcessedNodes.concat(allNodes); // Each iteration of this loop finds a component of the graph and // decides whether it is a tree or not. If it is a tree, adds it to the // forest and continued with the next component. while (unProcessedNodes.length > 0 && isForest) { toBeVisited.push(unProcessedNodes[0]); // Start the BFS. Each iteration of this loop visits a node in a // BFS manner. while (toBeVisited.length > 0 && isForest) { //pool operation var currentNode = toBeVisited[0]; toBeVisited.splice(0, 1); visited.add(currentNode); // Traverse all neighbors of this node var neighborEdges = currentNode.getEdges(); for (var i = 0; i < neighborEdges.length; i++) { var currentNeighbor = neighborEdges[i].getOtherEnd(currentNode); // If BFS is not growing from this neighbor. if (parents.get(currentNode) != currentNeighbor) { // We haven't previously visited this neighbor. if (!visited.has(currentNeighbor)) { toBeVisited.push(currentNeighbor); parents.set(currentNeighbor, currentNode); } // Since we have previously visited this neighbor and // this neighbor is not parent of currentNode, given // graph contains a component that is not tree, hence // it is not a forest. else { isForest = false; break; } } } } // The graph contains a component that is not a tree. Empty // previously found trees. The method will end. if (!isForest) { flatForest = []; } // Save currently visited nodes as a tree in our forest. Reset // visited and parents lists. Continue with the next component of // the graph, if any. else { var temp = [].concat(_toConsumableArray(visited)); flatForest.push(temp); //flatForest = flatForest.concat(temp); //unProcessedNodes.removeAll(visited); for (var i = 0; i < temp.length; i++) { var value = temp[i]; var index = unProcessedNodes.indexOf(value); if (index > -1) { unProcessedNodes.splice(index, 1); } } visited = new Set(); parents = new Map(); } } return flatForest; }; /** * This method creates dummy nodes (an l-level node with minimal dimensions) * for the given edge (one per bendpoint). The existing l-level structure * is updated accordingly. */ Layout.prototype.createDummyNodesForBendpoints = function (edge) { var dummyNodes = []; var prev = edge.source; var graph = this.graphManager.calcLowestCommonAncestor(edge.source, edge.target); for (var i = 0; i < edge.bendpoints.length; i++) { // create new dummy node var dummyNode = this.newNode(null); dummyNode.setRect(new Point(0, 0), new Dimension(1, 1)); graph.add(dummyNode); // create new dummy edge between prev and dummy node var dummyEdge = this.newEdge(null); this.graphManager.add(dummyEdge, prev, dummyNode); dummyNodes.add(dummyNode); prev = dummyNode; } var dummyEdge = this.newEdge(null); this.graphManager.add(dummyEdge, prev, edge.target); this.edgeToDummyNodes.set(edge, dummyNodes); // remove real edge from graph manager if it is inter-graph if (edge.isInterGraph()) { this.graphManager.remove(edge); } // else, remove the edge from the current graph else { graph.remove(edge); } return dummyNodes; }; /** * This method creates bendpoints for edges from the dummy nodes * at l-level. */ Layout.prototype.createBendpointsFromDummyNodes = function () { var edges = []; edges = edges.concat(this.graphManager.getAllEdges()); edges = [].concat(_toConsumableArray(this.edgeToDummyNodes.keys())).concat(edges); for (var k = 0; k < edges.length; k++) { var lEdge = edges[k]; if (lEdge.bendpoints.length > 0) { var path = this.edgeToDummyNodes.get(lEdge); for (var i = 0; i < path.length; i++) { var dummyNode = path[i]; var p = new PointD(dummyNode.getCenterX(), dummyNode.getCenterY()); // update bendpoint's location according to dummy node var ebp = lEdge.bendpoints.get(i); ebp.x = p.x; ebp.y = p.y; // remove the dummy node, dummy edges incident with this // dummy node is also removed (within the remove method) dummyNode.getOwner().remove(dummyNode); } // add the real edge to graph this.graphManager.add(lEdge, lEdge.source, lEdge.target); } } }; Layout.transform = function (sliderValue, defaultValue, minDiv, maxMul) { if (minDiv != undefined && maxMul != undefined) { var value = defaultValue; if (sliderValue <= 50) { var minValue = defaultValue / minDiv; value -= (defaultValue - minValue) / 50 * (50 - sliderValue); } else { var maxValue = defaultValue * maxMul; value += (maxValue - defaultValue) / 50 * (sliderValue - 50); } return value; } else { var a, b; if (sliderValue <= 50) { a = 9.0 * defaultValue / 500.0; b = defaultValue / 10.0; } else { a = 9.0 * defaultValue / 50.0; b = -8 * defaultValue; } return a * sliderValue + b; } }; /** * This method finds and returns the center of the given nodes, assuming * that the given nodes form a tree in themselves. */ Layout.findCenterOfTree = function (nodes) { var list = []; list = list.concat(nodes); var removedNodes = []; var remainingDegrees = new Map(); var foundCenter = false; var centerNode = null; if (list.length == 1 || list.length == 2) { foundCenter = true; centerNode = list[0]; } for (var i = 0; i < list.length; i++) { var node = list[i]; var degree = node.getNeighborsList().size; remainingDegrees.set(node, node.getNeighborsList().size); if (degree == 1) { removedNodes.push(node); } } var tempList = []; tempList = tempList.concat(removedNodes); while (!foundCenter) { var tempList2 = []; tempList2 = tempList2.concat(tempList); tempList = []; for (var i = 0; i < list.length; i++) { var node = list[i]; var index = list.indexOf(node); if (index >= 0) { list.splice(index, 1); } var neighbours = node.getNeighborsList(); neighbours.forEach(function (neighbour) { if (removedNodes.indexOf(neighbour) < 0) { var otherDegree = remainingDegrees.get(neighbour); var newDegree = otherDegree - 1; if (newDegree == 1) { tempList.push(neighbour); } remainingDegrees.set(neighbour, newDegree); } }); } removedNodes = removedNodes.concat(tempList); if (list.length == 1 || list.length == 2) { foundCenter = true; centerNode = list[0]; } } return centerNode; }; /** * During the coarsening process, this layout may be referenced by two graph managers * this setter function grants access to change the currently being used graph manager */ Layout.prototype.setGraphManager = function (gm) { this.graphManager = gm; }; module.exports = Layout; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function RandomSeed() {} // adapted from: https://stackoverflow.com/a/19303725 RandomSeed.seed = 1; RandomSeed.x = 0; RandomSeed.nextDouble = function () { RandomSeed.x = Math.sin(RandomSeed.seed++) * 10000; return RandomSeed.x - Math.floor(RandomSeed.x); }; module.exports = RandomSeed; /***/ }), /* 17 */ /***/ (function(module, exports, __nested_webpack_require_81860__) { "use strict"; var PointD = __nested_webpack_require_81860__(4); function Transform(x, y) { this.lworldOrgX = 0.0; this.lworldOrgY = 0.0; this.ldeviceOrgX = 0.0; this.ldeviceOrgY = 0.0; this.lworldExtX = 1.0; this.lworldExtY = 1.0; this.ldeviceExtX = 1.0; this.ldeviceExtY = 1.0; } Transform.prototype.getWorldOrgX = function () { return this.lworldOrgX; }; Transform.prototype.setWorldOrgX = function (wox) { this.lworldOrgX = wox; }; Transform.prototype.getWorldOrgY = function () { return this.lworldOrgY; }; Transform.prototype.setWorldOrgY = function (woy) { this.lworldOrgY = woy; }; Transform.prototype.getWorldExtX = function () { return this.lworldExtX; }; Transform.prototype.setWorldExtX = function (wex) { this.lworldExtX = wex; }; Transform.prototype.getWorldExtY = function () { return this.lworldExtY; }; Transform.prototype.setWorldExtY = function (wey) { this.lworldExtY = wey; }; /* Device related */ Transform.prototype.getDeviceOrgX = function () { return this.ldeviceOrgX; }; Transform.prototype.setDeviceOrgX = function (dox) { this.ldeviceOrgX = dox; }; Transform.prototype.getDeviceOrgY = function () { return this.ldeviceOrgY; }; Transform.prototype.setDeviceOrgY = function (doy) { this.ldeviceOrgY = doy; }; Transform.prototype.getDeviceExtX = function () { return this.ldeviceExtX; }; Transform.prototype.setDeviceExtX = function (dex) { this.ldeviceExtX = dex; }; Transform.prototype.getDeviceExtY = function () { return this.ldeviceExtY; }; Transform.prototype.setDeviceExtY = function (dey) { this.ldeviceExtY = dey; }; Transform.prototype.transformX = function (x) { var xDevice = 0.0; var worldExtX = this.lworldExtX; if (worldExtX != 0.0) { xDevice = this.ldeviceOrgX + (x - this.lworldOrgX) * this.ldeviceExtX / worldExtX; } return xDevice; }; Transform.prototype.transformY = function (y) { var yDevice = 0.0; var worldExtY = this.lworldExtY; if (worldExtY != 0.0) { yDevice = this.ldeviceOrgY + (y - this.lworldOrgY) * this.ldeviceExtY / worldExtY; } return yDevice; }; Transform.prototype.inverseTransformX = function (x) { var xWorld = 0.0; var deviceExtX = this.ldeviceExtX; if (deviceExtX != 0.0) { xWorld = this.lworldOrgX + (x - this.ldeviceOrgX) * this.lworldExtX / deviceExtX; } return xWorld; }; Transform.prototype.inverseTransformY = function (y) { var yWorld = 0.0; var deviceExtY = this.ldeviceExtY; if (deviceExtY != 0.0) { yWorld = this.lworldOrgY + (y - this.ldeviceOrgY) * this.lworldExtY / deviceExtY; } return yWorld; }; Transform.prototype.inverseTransformPoint = function (inPoint) { var outPoint = new PointD(this.inverseTransformX(inPoint.x), this.inverseTransformY(inPoint.y)); return outPoint; }; module.exports = Transform; /***/ }), /* 18 */ /***/ (function(module, exports, __nested_webpack_require_84747__) { "use strict"; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var Layout = __nested_webpack_require_84747__(15); var FDLayoutConstants = __nested_webpack_require_84747__(7); var LayoutConstants = __nested_webpack_require_84747__(0); var IGeometry = __nested_webpack_require_84747__(8); var IMath = __nested_webpack_require_84747__(9); function FDLayout() { Layout.call(this); this.useSmartIdealEdgeLengthCalculation = FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION; this.idealEdgeLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH; 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; this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100; this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; this.initialCoolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; this.totalDisplacement = 0.0; this.oldTotalDisplacement = 0.0; this.maxIterations = FDLayoutConstants.MAX_ITERATIONS; } FDLayout.prototype = Object.create(Layout.prototype); for (var prop in Layout) { FDLayout[prop] = Layout[prop]; } FDLayout.prototype.initParameters = function () { Layout.prototype.initParameters.call(this, arguments); this.totalIterations = 0; this.notAnimatedIterations = 0; this.useFRGridVariant = FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION; this.grid = []; }; FDLayout.prototype.calcIdealEdgeLengths = function () { var edge; var lcaDepth; var source; var target; var sizeOfSourceInLca; var sizeOfTargetInLca; var allEdges = this.getGraphManager().getAllEdges(); for (var i = 0; i < allEdges.length; i++) { edge = allEdges[i]; edge.idealLength = this.idealEdgeLength; if (edge.isInterGraph) { source = edge.getSource(); target = edge.getTarget(); sizeOfSourceInLca = edge.getSourceInLca().getEstimatedSize(); sizeOfTargetInLca = edge.getTargetInLca().getEstimatedSize(); if (this.useSmartIdealEdgeLengthCalculation) { edge.idealLength += sizeOfSourceInLca + sizeOfTargetInLca - 2 * LayoutConstants.SIMPLE_NODE_SIZE; } lcaDepth = edge.getLca().getInclusionTreeDepth(); edge.idealLength += FDLayoutConstants.DEFAULT_EDGE_LENGTH * FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR * (source.getInclusionTreeDepth() + target.getInclusionTreeDepth() - 2 * lcaDepth); } } }; FDLayout.prototype.initSpringEmbedder = function () { var s = this.getAllNodes().length; if (this.incremental) { if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) { this.coolingFactor = Math.max(this.coolingFactor * FDLayoutConstants.COOLING_ADAPTATION_FACTOR, this.coolingFactor - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * this.coolingFactor * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR)); } this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL; } else { if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) { this.coolingFactor = Math.max(FDLayoutConstants.COOLING_ADAPTATION_FACTOR, 1.0 - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR)); } else { this.coolingFactor = 1.0; } this.initialCoolingFactor = this.coolingFactor; this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT; } this.maxIterations = Math.max(this.getAllNodes().length * 5, this.maxIterations); this.totalDisplacementThreshold = this.displacementThresholdPerNode * this.getAllNodes().length; this.repulsionRange = this.calcRepulsionRange(); }; FDLayout.prototype.calcSpringForces = function () { var lEdges = this.getAllEdges(); var edge; for (var i = 0; i < lEdges.length; i++) { edge = lEdges[i]; this.calcSpringForce(edge, edge.idealLength); } }; FDLayout.prototype.calcRepulsionForces = function () { var gridUpdateAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; var forceToNodeSurroundingUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var i, j; var nodeA, nodeB; var lNodes = this.getAllNodes(); var processedNodeSet; if (this.useFRGridVariant) { if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed) { this.updateGrid(); } processedNodeSet = new Set(); // calculate repulsion forces between each nodes and its surrounding for (i = 0; i < lNodes.length; i++) { nodeA = lNodes[i]; this.calculateRepulsionForceOfANode(nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate); processedNodeSet.add(nodeA); } } else { for (i = 0; i < lNodes.length; i++) { nodeA = lNodes[i]; for (j = i + 1; j < lNodes.length; j++) { nodeB = lNodes[j]; // If both nodes are not members of the same graph, skip. if (nodeA.getOwner() != nodeB.getOwner()) { continue; } this.calcRepulsionForce(nodeA, nodeB); } } } }; FDLayout.prototype.calcGravitationalForces = function () { var node; var lNodes = this.getAllNodesToApplyGravitation(); for (var i = 0; i < lNodes.length; i++) { node = lNodes[i]; this.calcGravitationalForce(node); } }; FDLayout.prototype.moveNodes = function () { var lNodes = this.getAllNodes(); var node; for (var i = 0; i < lNodes.length; i++) { node = lNodes[i]; node.move(); } }; FDLayout.prototype.calcSpringForce = function (edge, idealLength) { var sourceNode = edge.getSource(); var targetNode = edge.getTarget(); var length; var springForce; var springForceX; var springForceY; // Update edge length if (this.uniformLeafNodeSizes && sourceNode.getChild() == null && targetNode.getChild() == null) { edge.updateLengthSimple(); } else { edge.updateLength(); if (edge.isOverlapingSourceAndTarget) { return; } } length = edge.getLength(); if (length == 0) return; // Calculate spring forces springForce = this.springConstant * (length - idealLength); // Project force onto x and y axes springForceX = springForce * (edge.lengthX / length); springForceY = springForce * (edge.lengthY / length); // Apply forces on the end nodes sourceNode.springForceX += springForceX; sourceNode.springForceY += springForceY; targetNode.springForceX -= springForceX; targetNode.springForceY -= springForceY; }; FDLayout.prototype.calcRepulsionForce = function (nodeA, nodeB) { var rectA = nodeA.getRect(); var rectB = nodeB.getRect(); var overlapAmount = new Array(2); var clipPoints = new Array(4); var distanceX; var distanceY; var distanceSquared; var distance; var repulsionForce; var repulsionForceX; var repulsionForceY; if (rectA.intersects(rectB)) // two nodes overlap { // calculate separation amount in x and y directions IGeometry.calcSeparationAmount(rectA, rectB, overlapAmount, FDLayoutConstants.DEFAULT_EDGE_LENGTH / 2.0); repulsionForceX = 2 * overlapAmount[0]; repulsionForceY = 2 * overlapAmount[1]; var childrenConstant = nodeA.noOfChildren * nodeB.noOfChildren / (nodeA.noOfChildren + nodeB.noOfChildren); // Apply forces on the two nodes nodeA.repulsionForceX -= childrenConstant * repulsionForceX; nodeA.repulsionForceY -= childrenConstant * repulsionForceY; nodeB.repulsionForceX += childrenConstant * repulsionForceX; nodeB.repulsionForceY += childrenConstant * repulsionForceY; } else // no overlap { // calculate distance if (this.uniformLeafNodeSizes && nodeA.getChild() == null && nodeB.getChild() == null) // simply base repulsion on distance of node centers { distanceX = rectB.getCenterX() - rectA.getCenterX(); distanceY = rectB.getCenterY() - rectA.getCenterY(); } else // use clipping points { IGeometry.getIntersection(rectA, rectB, clipPoints); distanceX = clipPoints[2] - clipPoints[0]; distanceY = clipPoints[3] - clipPoints[1]; } // No repulsion range. FR grid variant should take care of this. if (Math.abs(distanceX) < FDLayoutConstants.MIN_REPULSION_DIST) { distanceX = IMath.sign(distanceX) * FDLayoutConstants.MIN_REPULSION_DIST; } if (Math.abs(distanceY) < FDLayoutConstants.MIN_REPULSION_DIST) { distanceY = IMath.sign(distanceY) * FDLayoutConstants.MIN_REPULSION_DIST; } distanceSquared = distanceX * distanceX + distanceY * distanceY; distance = Math.sqrt(distanceSquared); repulsionForce = this.repulsionConstant * nodeA.noOfChildren * nodeB.noOfChildren / distanceSquared; // Project force onto x and y axes repulsionForceX = repulsionForce * distanceX / distance; repulsionForceY = repulsionForce * distanceY / distance; // Apply forces on the two nodes nodeA.repulsionForceX -= repulsionForceX; nodeA.repulsionForceY -= repulsionForceY; nodeB.repulsionForceX += repulsionForceX; nodeB.repulsionForceY += repulsionForceY; } }; FDLayout.prototype.calcGravitationalForce = function (node) { var ownerGraph; var ownerCenterX; var ownerCenterY; var distanceX; var distanceY; var absDistanceX; var absDistanceY; var estimatedSize; ownerGraph = node.getOwner(); ownerCenterX = (ownerGraph.getRight() + ownerGraph.getLeft()) / 2; ownerCenterY = (ownerGraph.getTop() + ownerGraph.getBottom()) / 2; distanceX = node.getCenterX() - ownerCenterX; distanceY = node.getCenterY() - ownerCenterY; absDistanceX = Math.abs(distanceX) + node.getWidth() / 2; absDistanceY = Math.abs(distanceY) + node.getHeight() / 2; if (node.getOwner() == this.graphManager.getRoot()) // in the root graph { estimatedSize = ownerGraph.getEstimatedSize() * this.gravityRangeFactor; if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) { node.gravitationForceX = -this.gravityConstant * distanceX; node.gravitationForceY = -this.gravityConstant * distanceY; } } else // inside a compound { estimatedSize = ownerGraph.getEstimatedSize() * this.compoundGravityRangeFactor; if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) { node.gravitationForceX = -this.gravityConstant * distanceX * this.compoundGravityConstant; node.gravitationForceY = -this.gravityConstant * distanceY * this.compoundGravityConstant; } } }; FDLayout.prototype.isConverged = function () { var converged; var oscilating = false; if (this.totalIterations > this.maxIterations / 3) { oscilating = Math.abs(this.totalDisplacement - this.oldTotalDisplacement) < 2; } converged = this.totalDisplacement < this.totalDisplacementThreshold; this.oldTotalDisplacement = this.totalDisplacement; return converged || oscilating; }; FDLayout.prototype.animate = function () { if (this.animationDuringLayout && !this.isSubLayout) { if (this.notAnimatedIterations == this.animationPeriod) { this.update(); this.notAnimatedIterations = 0; } else { this.notAnimatedIterations++; } } }; //This method calculates the number of children (weight) for all nodes FDLayout.prototype.calcNoOfChildrenForAllNodes = function () { var node; var allNodes = this.graphManager.getAllNodes(); for (var i = 0; i < allNodes.length; i++) { node = allNodes[i]; node.noOfChildren = node.getNoOfChildren(); } }; // ----------------------------------------------------------------------------- // Section: FR-Grid Variant Repulsion Force Calculation // ----------------------------------------------------------------------------- FDLayout.prototype.calcGrid = function (graph) { var sizeX = 0; var sizeY = 0; sizeX = parseInt(Math.ceil((graph.getRight() - graph.getLeft()) / this.repulsionRange)); sizeY = parseInt(Math.ceil((graph.getBottom() - graph.getTop()) / this.repulsionRange)); var grid = new Array(sizeX); for (var i = 0; i < sizeX; i++) { grid[i] = new Array(sizeY); } for (var i = 0; i < sizeX; i++) { for (var j = 0; j < sizeY; j++) { grid[i][j] = new Array(); } } return grid; }; FDLayout.prototype.addNodeToGrid = function (v, left, top) { var startX = 0; var finishX = 0; var startY = 0; var finishY = 0; startX = parseInt(Math.floor((v.getRect().x - left) / this.repulsionRange)); finishX = parseInt(Math.floor((v.getRect().width + v.getRect().x - left) / this.repulsionRange)); startY = parseInt(Math.floor((v.getRect().y - top) / this.repulsionRange)); finishY = parseInt(Math.floor((v.getRect().height + v.getRect().y - top) / this.repulsionRange)); for (var i = startX; i <= finishX; i++) { for (var j = startY; j <= finishY; j++) { this.grid[i][j].push(v); v.setGridCoordinates(startX, finishX, startY, finishY); } } }; FDLayout.prototype.updateGrid = function () { var i; var nodeA; var lNodes = this.getAllNodes(); this.grid = this.calcGrid(this.graphManager.getRoot()); // put all nodes to proper grid cells for (i = 0; i < lNodes.length; i++) { nodeA = lNodes[i]; this.addNodeToGrid(nodeA, this.graphManager.getRoot().getLeft(), this.graphManager.getRoot().getTop()); } }; FDLayout.prototype.calculateRepulsionForceOfANode = function (nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate) { if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed || forceToNodeSurroundingUpdate) { var surrounding = new Set(); nodeA.surrounding = new Array(); var nodeB; var grid = this.grid; for (var i = nodeA.startX - 1; i < nodeA.finishX + 2; i++) { for (var j = nodeA.startY - 1; j < nodeA.finishY + 2; j++) { if (!(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)) { for (var k = 0; k < grid[i][j].length; k++) { nodeB = grid[i][j][k]; // If both nodes are not members of the same graph, // or both nodes are the same, skip. if (nodeA.getOwner() != nodeB.getOwner() || nodeA == nodeB) { continue; } // check if the repulsion force between // nodeA and nodeB has already been calculated if (!processedNodeSet.has(nodeB) && !surrounding.has(nodeB)) { var distanceX = Math.abs(nodeA.getCenterX() - nodeB.getCenterX()) - (nodeA.getWidth() / 2 + nodeB.getWidth() / 2); var distanceY = Math.abs(nodeA.getCenterY() - nodeB.getCenterY()) - (nodeA.getHeight() / 2 + nodeB.getHeight() / 2); // if the distance between nodeA and nodeB // is less then calculation range if (distanceX <= this.repulsionRange && distanceY <= this.repulsionRange) { //then add nodeB to surrounding of nodeA surrounding.add(nodeB); } } } } } } nodeA.surrounding = [].concat(_toConsumableArray(surrounding)); } for (i = 0; i < nodeA.surrounding.length; i++) { this.calcRepulsionForce(nodeA, nodeA.surrounding[i]); } }; FDLayout.prototype.calcRepulsionRange = function () { return 0.0; }; module.exports = FDLayout; /***/ }), /* 19 */ /***/ (function(module, exports, __nested_webpack_require_100902__) { "use strict"; var LEdge = __nested_webpack_require_100902__(1); var FDLayoutConstants = __nested_webpack_require_100902__(7); function FDLayoutEdge(source, target, vEdge) { LEdge.call(this, source, target, vEdge); this.idealLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH; } FDLayoutEdge.prototype = Object.create(LEdge.prototype); for (var prop in LEdge) { FDLayoutEdge[prop] = LEdge[prop]; } module.exports = FDLayoutEdge; /***/ }), /* 20 */ /***/ (function(module, exports, __nested_webpack_require_101387__) { "use strict"; var LNode = __nested_webpack_require_101387__(3); function FDLayoutNode(gm, loc, size, vNode) { // alternative constructor is handled inside LNode LNode.call(this, gm, loc, size, vNode); //Spring, repulsion and gravitational forces acting on this node this.springForceX = 0; this.springForceY = 0; this.repulsionForceX = 0; this.repulsionForceY = 0; this.gravitationForceX = 0; this.gravitationForceY = 0; //Amount by which this node is to be moved in this iteration this.displacementX = 0; this.displacementY = 0; //Start and finish grid coordinates that this node is fallen into this.startX = 0; this.finishX = 0; this.startY = 0; this.finishY = 0; //Geometric neighbors of this node this.surrounding = []; } FDLayoutNode.prototype = Object.create(LNode.prototype); for (var prop in LNode) { FDLayoutNode[prop] = LNode[prop]; } FDLayoutNode.prototype.setGridCoordinates = function (_startX, _finishX, _startY, _finishY) { this.startX = _startX; this.finishX = _finishX; this.startY = _startY; this.finishY = _finishY; }; module.exports = FDLayoutNode; /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function DimensionD(width, height) { this.width = 0; this.height = 0; if (width !== null && height !== null) { this.height = height; this.width = width; } } DimensionD.prototype.getWidth = function () { return this.width; }; DimensionD.prototype.setWidth = function (width) { this.width = width; }; DimensionD.prototype.getHeight = function () { return this.height; }; DimensionD.prototype.setHeight = function (height) { this.height = height; }; module.exports = DimensionD; /***/ }), /* 22 */ /***/ (function(module, exports, __nested_webpack_require_103173__) { "use strict"; var UniqueIDGeneretor = __nested_webpack_require_103173__(14); function HashMap() { this.map = {}; this.keys = []; } HashMap.prototype.put = function (key, value) { var theId = UniqueIDGeneretor.createID(key); if (!this.contains(theId)) { this.map[theId] = value; this.keys.push(key); } }; HashMap.prototype.contains = function (key) { var theId = UniqueIDGeneretor.createID(key); return this.map[key] != null; }; HashMap.prototype.get = function (key) { var theId = UniqueIDGeneretor.createID(key); return this.map[theId]; }; HashMap.prototype.keySet = function () { return this.keys; }; module.exports = HashMap; /***/ }), /* 23 */ /***/ (function(module, exports, __nested_webpack_require_103901__) { "use strict"; var UniqueIDGeneretor = __nested_webpack_require_103901__(14); function HashSet() { this.set = {}; } ; HashSet.prototype.add = function (obj) { var theId = UniqueIDGeneretor.createID(obj); if (!this.contains(theId)) this.set[theId] = obj; }; HashSet.prototype.remove = function (obj) { delete this.set[UniqueIDGeneretor.createID(obj)]; }; HashSet.prototype.clear = function () { this.set = {}; }; HashSet.prototype.contains = function (obj) { return this.set[UniqueIDGeneretor.createID(obj)] == obj; }; HashSet.prototype.isEmpty = function () { return this.size() === 0; }; HashSet.prototype.size = function () { return Object.keys(this.set).length; }; //concats this.set to the given list HashSet.prototype.addAllTo = function (list) { var keys = Object.keys(this.set); var length = keys.length; for (var i = 0; i < length; i++) { list.push(this.set[keys[i]]); } }; HashSet.prototype.size = function () { return Object.keys(this.set).length; }; HashSet.prototype.addAll = function (list) { var s = list.length; for (var i = 0; i < s; i++) { var v = list[i]; this.add(v); } }; module.exports = HashSet; /***/ }), /* 24 */ /***/ (function(module, exports, __nested_webpack_require_105138__) { "use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * A classic Quicksort algorithm with Hoare's partition * - Works also on LinkedList objects * * Copyright: i-Vis Research Group, Bilkent University, 2007 - present */ var LinkedList = __nested_webpack_require_105138__(11); var Quicksort = function () { function Quicksort(A, compareFunction) { _classCallCheck(this, Quicksort); if (compareFunction !== null || compareFunction !== undefined) this.compareFunction = this._defaultCompareFunction; var length = void 0; if (A instanceof LinkedList) length = A.size();else length = A.length; this._quicksort(A, 0, length - 1); } _createClass(Quicksort, [{ key: '_quicksort', value: function _quicksort(A, p, r) { if (p < r) { var q = this._partition(A, p, r); this._quicksort(A, p, q); this._quicksort(A, q + 1, r); } } }, { key: '_partition', value: function _partition(A, p, r) { var x = this._get(A, p); var i = p; var j = r; while (true) { while (this.compareFunction(x, this._get(A, j))) { j--; }while (this.compareFunction(this._get(A, i), x)) { i++; }if (i < j) { this._swap(A, i, j); i++; j--; } else return j; } } }, { key: '_get', value: function _get(object, index) { if (object instanceof LinkedList) return object.get_object_at(index);else return object[index]; } }, { key: '_set', value: function _set(object, index, value) { if (object instanceof LinkedList) object.set_object_at(index, value);else object[index] = value; } }, { key: '_swap', value: function _swap(A, i, j) { var temp = this._get(A, i); this._set(A, i, this._get(A, j)); this._set(A, j, temp); } }, { key: '_defaultCompareFunction', value: function _defaultCompareFunction(a, b) { return b > a; } }]); return Quicksort; }(); module.exports = Quicksort; /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Needleman-Wunsch algorithm is an procedure to compute the optimal global alignment of two string * sequences by S.B.Needleman and C.D.Wunsch (1970). * * Aside from the inputs, you can assign the scores for, * - Match: The two characters at the current index are same. * - Mismatch: The two characters at the current index are different. * - Insertion/Deletion(gaps): The best alignment involves one letter aligning to a gap in the other string. */ var NeedlemanWunsch = function () { function NeedlemanWunsch(sequence1, sequence2) { var match_score = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; var mismatch_penalty = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1; var gap_penalty = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1; _classCallCheck(this, NeedlemanWunsch); this.sequence1 = sequence1; this.sequence2 = sequence2; this.match_score = match_score; this.mismatch_penalty = mismatch_penalty; this.gap_penalty = gap_penalty; // Just the remove redundancy this.iMax = sequence1.length + 1; this.jMax = sequence2.length + 1; // Grid matrix of scores this.grid = new Array(this.iMax); for (var i = 0; i < this.iMax; i++) { this.grid[i] = new Array(this.jMax); for (var j = 0; j < this.jMax; j++) { this.grid[i][j] = 0; } } // Traceback matrix (2D array, each cell is an array of boolean values for [`Diag`, `Up`, `Left`] positions) this.tracebackGrid = new Array(this.iMax); for (var _i = 0; _i < this.iMax; _i++) { this.tracebackGrid[_i] = new Array(this.jMax); for (var _j = 0; _j < this.jMax; _j++) { this.tracebackGrid[_i][_j] = [null, null, null]; } } // The aligned sequences (return multiple possibilities) this.alignments = []; // Final alignment score this.score = -1; // Calculate scores and tracebacks this.computeGrids(); } _createClass(NeedlemanWunsch, [{ key: "getScore", value: function getScore() { return this.score; } }, { key: "getAlignments", value: function getAlignments() { return this.alignments; } // Main dynamic programming procedure }, { key: "computeGrids", value: function computeGrids() { // Fill in the first row for (var j = 1; j < this.jMax; j++) { this.grid[0][j] = this.grid[0][j - 1] + this.gap_penalty; this.tracebackGrid[0][j] = [false, false, true]; } // Fill in the first column for (var i = 1; i < this.iMax; i++) { this.grid[i][0] = this.grid[i - 1][0] + this.gap_penalty; this.tracebackGrid[i][0] = [false, true, false]; } // Fill the rest of the grid for (var _i2 = 1; _i2 < this.iMax; _i2++) { for (var _j2 = 1; _j2 < this.jMax; _j2++) { // Find the max score(s) among [`Diag`, `Up`, `Left`] var diag = void 0; if (this.sequence1[_i2 - 1] === this.sequence2[_j2 - 1]) diag = this.grid[_i2 - 1][_j2 - 1] + this.match_score;else diag = this.grid[_i2 - 1][_j2 - 1] + this.mismatch_penalty; var up = this.grid[_i2 - 1][_j2] + this.gap_penalty; var left = this.grid[_i2][_j2 - 1] + this.gap_penalty; // If there exists multiple max values, capture them for multiple paths var maxOf = [diag, up, left]; var indices = this.arrayAllMaxIndexes(maxOf); // Update Grids this.grid[_i2][_j2] = maxOf[indices[0]]; this.tracebackGrid[_i2][_j2] = [indices.includes(0), indices.includes(1), indices.includes(2)]; } } // Update alignment score this.score = this.grid[this.iMax - 1][this.jMax - 1]; } // Gets all possible valid sequence combinations }, { key: "alignmentTraceback", value: function alignmentTraceback() { var inProcessAlignments = []; inProcessAlignments.push({ pos: [this.sequence1.length, this.sequence2.length], seq1: "", seq2: "" }); while (inProcessAlignments[0]) { var current = inProcessAlignments[0]; var directions = this.tracebackGrid[current.pos[0]][current.pos[1]]; if (directions[0]) { inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1] - 1], seq1: this.sequence1[current.pos[0] - 1] + current.seq1, seq2: this.sequence2[current.pos[1] - 1] + current.seq2 }); } if (directions[1]) { inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1]], seq1: this.sequence1[current.pos[0] - 1] + current.seq1, seq2: '-' + current.seq2 }); } if (directions[2]) { inProcessAlignments.push({ pos: [current.pos[0], current.pos[1] - 1], seq1: '-' + current.seq1, seq2: this.sequence2[current.pos[1] - 1] + current.seq2 }); } if (current.pos[0] === 0 && current.pos[1] === 0) this.alignments.push({ sequence1: current.seq1, sequence2: current.seq2 }); inProcessAlignments.shift(); } return this.alignments; } // Helper Functions }, { key: "getAllIndexes", value: function getAllIndexes(arr, val) { var indexes = [], i = -1; while ((i = arr.indexOf(val, i + 1)) !== -1) { indexes.push(i); } return indexes; } }, { key: "arrayAllMaxIndexes", value: function arrayAllMaxIndexes(array) { return this.getAllIndexes(array, Math.max.apply(null, array)); } }]); return NeedlemanWunsch; }(); module.exports = NeedlemanWunsch; /***/ }), /* 26 */ /***/ (function(module, exports, __nested_webpack_require_115611__) { "use strict"; var layoutBase = function layoutBase() { return; }; layoutBase.FDLayout = __nested_webpack_require_115611__(18); layoutBase.FDLayoutConstants = __nested_webpack_require_115611__(7); layoutBase.FDLayoutEdge = __nested_webpack_require_115611__(19); layoutBase.FDLayoutNode = __nested_webpack_require_115611__(20); layoutBase.DimensionD = __nested_webpack_require_115611__(21); layoutBase.HashMap = __nested_webpack_require_115611__(22); layoutBase.HashSet = __nested_webpack_require_115611__(23); layoutBase.IGeometry = __nested_webpack_require_115611__(8); layoutBase.IMath = __nested_webpack_require_115611__(9); layoutBase.Integer = __nested_webpack_require_115611__(10); layoutBase.Point = __nested_webpack_require_115611__(12); layoutBase.PointD = __nested_webpack_require_115611__(4); layoutBase.RandomSeed = __nested_webpack_require_115611__(16); layoutBase.RectangleD = __nested_webpack_require_115611__(13); layoutBase.Transform = __nested_webpack_require_115611__(17); layoutBase.UniqueIDGeneretor = __nested_webpack_require_115611__(14); layoutBase.Quicksort = __nested_webpack_require_115611__(24); layoutBase.LinkedList = __nested_webpack_require_115611__(11); layoutBase.LGraphObject = __nested_webpack_require_115611__(2); layoutBase.LGraph = __nested_webpack_require_115611__(5); layoutBase.LEdge = __nested_webpack_require_115611__(1); layoutBase.LGraphManager = __nested_webpack_require_115611__(6); layoutBase.LNode = __nested_webpack_require_115611__(3); layoutBase.Layout = __nested_webpack_require_115611__(15); layoutBase.LayoutConstants = __nested_webpack_require_115611__(0); layoutBase.NeedlemanWunsch = __nested_webpack_require_115611__(25); module.exports = layoutBase; /***/ }), /* 27 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; function Emitter() { this.listeners = []; } var p = Emitter.prototype; p.addListener = function (event, callback) { this.listeners.push({ event: event, callback: callback }); }; p.removeListener = function (event, callback) { for (var i = this.listeners.length; i >= 0; i--) { var l = this.listeners[i]; if (l.event === event && l.callback === callback) { this.listeners.splice(i, 1); } } }; p.emit = function (event, data) { for (var i = 0; i < this.listeners.length; i++) { var l = this.listeners[i]; if (event === l.event) { l.callback(data); } } }; module.exports = Emitter; /***/ }) /******/ ]); }); /***/ }), /***/ 34047: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ render: () => (/* binding */ render2) /* harmony export */ }); /* harmony import */ var _chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(74999); /* harmony import */ var cytoscape__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23207); /* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(35302); /* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(35321); // src/rendering-util/layout-algorithms/cose-bilkent/cytoscape-setup.ts cytoscape__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z.use((cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2___default())); function addNodes(nodes, cy) { nodes.forEach((node) => { const nodeData = { id: node.id, labelText: node.label, height: node.height, width: node.width, padding: node.padding ?? 0 }; Object.keys(node).forEach((key) => { if (!["id", "label", "height", "width", "padding", "x", "y"].includes(key)) { nodeData[key] = node[key]; } }); cy.add({ group: "nodes", data: nodeData, position: { x: node.x ?? 0, y: node.y ?? 0 } }); }); } (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(addNodes, "addNodes"); function addEdges(edges, cy) { edges.forEach((edge) => { const edgeData = { id: edge.id, source: edge.start, target: edge.end }; Object.keys(edge).forEach((key) => { if (!["id", "start", "end"].includes(key)) { edgeData[key] = edge[key]; } }); cy.add({ group: "edges", data: edgeData }); }); } (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(addEdges, "addEdges"); function createCytoscapeInstance(data) { return new Promise((resolve) => { const renderEl = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)("body").append("div").attr("id", "cy").attr("style", "display:none"); const cy = (0,cytoscape__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)({ container: document.getElementById("cy"), // container to render in style: [ { selector: "edge", style: { "curve-style": "bezier" } } ] }); renderEl.remove(); addNodes(data.nodes, cy); addEdges(data.edges, cy); cy.nodes().forEach(function(n) { n.layoutDimensions = () => { const nodeData = n.data(); return { w: nodeData.width, h: nodeData.height }; }; }); const layoutConfig = { name: "cose-bilkent", // @ts-ignore Types for cose-bilkent are not correct? quality: "proof", styleEnabled: false, animate: false }; cy.layout(layoutConfig).run(); cy.ready((e) => { _chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.info("Cytoscape ready", e); resolve(cy); }); }); } (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(createCytoscapeInstance, "createCytoscapeInstance"); function extractPositionedNodes(cy) { return cy.nodes().map((node) => { const data = node.data(); const position = node.position(); const positionedNode = { id: data.id, x: position.x, y: position.y }; Object.keys(data).forEach((key) => { if (key !== "id") { positionedNode[key] = data[key]; } }); return positionedNode; }); } (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(extractPositionedNodes, "extractPositionedNodes"); function extractPositionedEdges(cy) { return cy.edges().map((edge) => { const data = edge.data(); const rscratch = edge._private.rscratch; const positionedEdge = { id: data.id, source: data.source, target: data.target, startX: rscratch.startX, startY: rscratch.startY, midX: rscratch.midX, midY: rscratch.midY, endX: rscratch.endX, endY: rscratch.endY }; Object.keys(data).forEach((key) => { if (!["id", "source", "target"].includes(key)) { positionedEdge[key] = data[key]; } }); return positionedEdge; }); } (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(extractPositionedEdges, "extractPositionedEdges"); // src/rendering-util/layout-algorithms/cose-bilkent/layout.ts async function executeCoseBilkentLayout(data, _config) { _chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.debug("Starting cose-bilkent layout algorithm"); try { validateLayoutData(data); const cy = await createCytoscapeInstance(data); const positionedNodes = extractPositionedNodes(cy); const positionedEdges = extractPositionedEdges(cy); _chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.debug(`Layout completed: ${positionedNodes.length} nodes, ${positionedEdges.length} edges`); return { nodes: positionedNodes, edges: positionedEdges }; } catch (error) { _chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .log */ .cM.error("Error in cose-bilkent layout algorithm:", error); throw error; } } (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(executeCoseBilkentLayout, "executeCoseBilkentLayout"); function validateLayoutData(data) { if (!data) { throw new Error("Layout data is required"); } if (!data.config) { throw new Error("Configuration is required in layout data"); } if (!data.rootNode) { throw new Error("Root node is required"); } if (!data.nodes || !Array.isArray(data.nodes)) { throw new Error("No nodes found in layout data"); } if (!Array.isArray(data.edges)) { throw new Error("Edges array is required in layout data"); } return true; } (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(validateLayoutData, "validateLayoutData"); // src/rendering-util/layout-algorithms/cose-bilkent/render.ts var render = /* @__PURE__ */ (0,_chunk_AGHRB4JF_mjs__WEBPACK_IMPORTED_MODULE_0__/* .__name */ .eW)(async (data4Layout, svg, { insertCluster, insertEdge, insertEdgeLabel, insertMarkers, insertNode, log: log2, positionEdgeLabel }, { algorithm: _algorithm }) => { const nodeDb = {}; const clusterDb = {}; const element = svg.select("g"); insertMarkers(element, data4Layout.markers, data4Layout.type, data4Layout.diagramId); const subGraphsEl = element.insert("g").attr("class", "subgraphs"); const edgePaths = element.insert("g").attr("class", "edgePaths"); const edgeLabels = element.insert("g").attr("class", "edgeLabels"); const nodes = element.insert("g").attr("class", "nodes"); log2.debug("Inserting nodes into DOM for dimension calculation"); await Promise.all( data4Layout.nodes.map(async (node) => { if (node.isGroup) { const clusterNode = { ...node }; clusterDb[node.id] = clusterNode; nodeDb[node.id] = clusterNode; await insertCluster(subGraphsEl, node); } else { const nodeWithPosition = { ...node }; nodeDb[node.id] = nodeWithPosition; const nodeEl = await insertNode(nodes, node, { config: data4Layout.config, dir: data4Layout.direction || "TB" }); const boundingBox = nodeEl.node().getBBox(); nodeWithPosition.width = boundingBox.width; nodeWithPosition.height = boundingBox.height; nodeWithPosition.domId = nodeEl; log2.debug(`Node ${node.id} dimensions: ${boundingBox.width}x${boundingBox.height}`); } }) ); log2.debug("Running cose-bilkent layout algorithm"); const updatedLayoutData = { ...data4Layout, nodes: data4Layout.nodes.map((node) => { const nodeWithDimensions = nodeDb[node.id]; return { ...node, width: nodeWithDimensions.width, height: nodeWithDimensions.height }; }) }; const layoutResult = await executeCoseBilkentLayout(updatedLayoutData, data4Layout.config); log2.debug("Positioning nodes based on layout results"); layoutResult.nodes.forEach((positionedNode) => { const node = nodeDb[positionedNode.id]; if (node?.domId) { node.domId.attr( "transform", `translate(${positionedNode.x}, ${positionedNode.y})` ); node.x = positionedNode.x; node.y = positionedNode.y; log2.debug(`Positioned node ${node.id} at center (${positionedNode.x}, ${positionedNode.y})`); } }); layoutResult.edges.forEach((positionedEdge) => { const edge = data4Layout.edges.find((e) => e.id === positionedEdge.id); if (edge) { edge.points = [ { x: positionedEdge.startX, y: positionedEdge.startY }, { x: positionedEdge.midX, y: positionedEdge.midY }, { x: positionedEdge.endX, y: positionedEdge.endY } ]; } }); log2.debug("Inserting and positioning edges"); await Promise.all( data4Layout.edges.map(async (edge) => { const _edgeLabel = await insertEdgeLabel(edgeLabels, edge); const startNode = nodeDb[edge.start ?? ""]; const endNode = nodeDb[edge.end ?? ""]; if (startNode && endNode) { const positionedEdge = layoutResult.edges.find((e) => e.id === edge.id); if (positionedEdge) { log2.debug("APA01 positionedEdge", positionedEdge); const edgeWithPath = { ...edge }; const paths = insertEdge( edgePaths, edgeWithPath, clusterDb, data4Layout.type, startNode, endNode, data4Layout.diagramId ); positionEdgeLabel(edgeWithPath, paths); } else { const edgeWithPath = { ...edge, points: [ { x: startNode.x || 0, y: startNode.y || 0 }, { x: endNode.x || 0, y: endNode.y || 0 } ] }; const paths = insertEdge( edgePaths, edgeWithPath, clusterDb, data4Layout.type, startNode, endNode, data4Layout.diagramId ); positionEdgeLabel(edgeWithPath, paths); } } }) ); log2.debug("Cose-bilkent rendering completed"); }, "render"); // src/rendering-util/layout-algorithms/cose-bilkent/index.ts var render2 = render; /***/ }) }]); //# sourceMappingURL=4047.14d816f33b5d2f8ee675.js.map?v=14d816f33b5d2f8ee675