(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("cose-base")); else if(typeof define === 'function' && define.amd) define(["cose-base"], factory); else if(typeof exports === 'object') exports["cytoscapeCoseBilkent"] = factory(require("cose-base")); else root["cytoscapeCoseBilkent"] = factory(root["coseBase"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 1); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_0__; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var LayoutConstants = __webpack_require__(0).layoutBase.LayoutConstants; var FDLayoutConstants = __webpack_require__(0).layoutBase.FDLayoutConstants; var CoSEConstants = __webpack_require__(0).CoSEConstants; var CoSELayout = __webpack_require__(0).CoSELayout; var CoSENode = __webpack_require__(0).CoSENode; var PointD = __webpack_require__(0).layoutBase.PointD; var DimensionD = __webpack_require__(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; /***/ }) /******/ ]); });