(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("webcola")); else if (typeof define === 'function' && define.amd) define(["webcola"], factory); else if (typeof exports === 'object') exports["cytoscapeCola"] = factory(require("webcola")); else root["cytoscapeCola"] = factory(root["webcola"]); })(this, function (__WEBPACK_EXTERNAL_MODULE_5__) { 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 = 3); /******/ }) /************************************************************************/ /******/([ /* 0 */ /***/ (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; }; var assign = __webpack_require__(1); var defaults = __webpack_require__(2); var cola = __webpack_require__(5) || (typeof window !== 'undefined' ? window.cola : null); var raf = __webpack_require__(4); var isString = function isString(o) { return (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === _typeof(''); }; var isNumber = function isNumber(o) { return (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === _typeof(0); }; var isObject = function isObject(o) { return o != null && (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === _typeof({}); }; var isFunction = function isFunction(o) { return o != null && (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === _typeof(function () { }); }; var nop = function nop() { }; var getOptVal = function getOptVal(val, ele) { if (isFunction(val)) { var fn = val; return fn.apply(ele, [ele]); } else { return val; } }; // constructor // options : object containing layout options function ColaLayout(options) { this.options = assign({}, defaults, options); } // runs the layout ColaLayout.prototype.run = function () { var layout = this; var options = this.options; layout.manuallyStopped = false; var cy = options.cy; // cy is automatically populated for us in the constructor var eles = options.eles; var nodes = eles.nodes(); var edges = eles.edges(); var ready = false; var isParent = function isParent(ele) { return ele.isParent(); }; var parentNodes = nodes.filter(isParent); var nonparentNodes = nodes.subtract(parentNodes); var bb = options.boundingBox || { x1: 0, y1: 0, w: cy.width(), h: cy.height() }; if (bb.x2 === undefined) { bb.x2 = bb.x1 + bb.w; } if (bb.w === undefined) { bb.w = bb.x2 - bb.x1; } if (bb.y2 === undefined) { bb.y2 = bb.y1 + bb.h; } if (bb.h === undefined) { bb.h = bb.y2 - bb.y1; } var updateNodePositions = function updateNodePositions() { for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; var dimensions = node.layoutDimensions(options); var scratch = node.scratch('cola'); // update node dims if (!scratch.updatedDims) { var padding = getOptVal(options.nodeSpacing, node); scratch.width = dimensions.w + 2 * padding; scratch.height = dimensions.h + 2 * padding; } } nodes.positions(function (node) { var scratch = node.scratch().cola; var retPos = void 0; if (!node.grabbed() && nonparentNodes.contains(node)) { retPos = { x: bb.x1 + scratch.x, y: bb.y1 + scratch.y }; if (!isNumber(retPos.x) || !isNumber(retPos.y)) { retPos = undefined; } } return retPos; }); nodes.updateCompoundBounds(); // because the way this layout sets positions is buggy for some reason; ref #878 if (!ready) { onReady(); ready = true; } if (options.fit) { cy.fit(options.padding); } }; var onDone = function onDone() { if (options.ungrabifyWhileSimulating) { grabbableNodes.grabify(); } cy.off('destroy', destroyHandler); nodes.off('grab free position', grabHandler); nodes.off('lock unlock', lockHandler); // trigger layoutstop when the layout stops (e.g. finishes) layout.one('layoutstop', options.stop); layout.trigger({ type: 'layoutstop', layout: layout }); }; var onReady = function onReady() { // trigger layoutready when each node has had its position set at least once layout.one('layoutready', options.ready); layout.trigger({ type: 'layoutready', layout: layout }); }; var ticksPerFrame = options.refresh; if (options.refresh < 0) { ticksPerFrame = 1; } else { ticksPerFrame = Math.max(1, ticksPerFrame); // at least 1 } var adaptor = layout.adaptor = cola.adaptor({ trigger: function trigger(e) { // on sim event var TICK = cola.EventType ? cola.EventType.tick : null; var END = cola.EventType ? cola.EventType.end : null; switch (e.type) { case 'tick': case TICK: if (options.animate) { updateNodePositions(); } break; case 'end': case END: updateNodePositions(); if (!options.infinite) { onDone(); } break; } }, kick: function kick() { // kick off the simulation //let skip = 0; var firstTick = true; var inftick = function inftick() { if (layout.manuallyStopped) { onDone(); return true; } var ret = adaptor.tick(); if (!options.infinite && !firstTick) { adaptor.convergenceThreshold(options.convergenceThreshold); } firstTick = false; if (ret && options.infinite) { // resume layout if done adaptor.resume(); // resume => new kick } return ret; // allow regular finish b/c of new kick }; var multitick = function multitick() { // multiple ticks in a row var ret = void 0; for (var i = 0; i < ticksPerFrame && !ret; i++) { ret = ret || inftick(); // pick up true ret vals => sim done } return ret; }; if (options.animate) { var frame = function frame() { if (multitick()) { return; } raf(frame); }; raf(frame); } else { while (!inftick()) { // keep going... } } }, on: nop, // dummy; not needed drag: nop // not needed for our case }); layout.adaptor = adaptor; // if set no grabbing during layout var grabbableNodes = nodes.filter(':grabbable'); if (options.ungrabifyWhileSimulating) { grabbableNodes.ungrabify(); } var destroyHandler = void 0; cy.one('destroy', destroyHandler = function destroyHandler() { layout.stop(); }); // handle node dragging var grabHandler = void 0; nodes.on('grab free position', grabHandler = function grabHandler(e) { var node = this; var scrCola = node.scratch().cola; var pos = node.position(); var nodeIsTarget = e.cyTarget === node || e.target === node; if (!nodeIsTarget) { return; } switch (e.type) { case 'grab': adaptor.dragstart(scrCola); break; case 'free': adaptor.dragend(scrCola); break; case 'position': // only update when different (i.e. manual .position() call or drag) so we don't loop needlessly if (scrCola.px !== pos.x - bb.x1 || scrCola.py !== pos.y - bb.y1) { scrCola.px = pos.x - bb.x1; scrCola.py = pos.y - bb.y1; } break; } }); var lockHandler = void 0; nodes.on('lock unlock', lockHandler = function lockHandler() { var node = this; var scrCola = node.scratch().cola; scrCola.fixed = node.locked(); if (node.locked()) { adaptor.dragstart(scrCola); } else { adaptor.dragend(scrCola); } }); // add nodes to cola adaptor.nodes(nonparentNodes.map(function (node, i) { var padding = getOptVal(options.nodeSpacing, node); var pos = node.position(); var dimensions = node.layoutDimensions(options); var struct = node.scratch().cola = { x: options.randomize && !node.locked() || pos.x === undefined ? Math.round(Math.random() * bb.w) : pos.x, y: options.randomize && !node.locked() || pos.y === undefined ? Math.round(Math.random() * bb.h) : pos.y, width: dimensions.w + 2 * padding, height: dimensions.h + 2 * padding, index: i, fixed: node.locked() }; return struct; })); // the constraints to be added on nodes var constraints = []; if (options.alignment) { // then set alignment constraints if (options.alignment.vertical) { var verticalAlignments = options.alignment.vertical; verticalAlignments.forEach(function (alignment) { var offsetsX = []; alignment.forEach(function (nodeData) { var node = nodeData.node; var scrCola = node.scratch().cola; var index = scrCola.index; offsetsX.push({ node: index, offset: nodeData.offset ? nodeData.offset : 0 }); }); constraints.push({ type: 'alignment', axis: 'x', offsets: offsetsX }); }); } if (options.alignment.horizontal) { var horizontalAlignments = options.alignment.horizontal; horizontalAlignments.forEach(function (alignment) { var offsetsY = []; alignment.forEach(function (nodeData) { var node = nodeData.node; var scrCola = node.scratch().cola; var index = scrCola.index; offsetsY.push({ node: index, offset: nodeData.offset ? nodeData.offset : 0 }); }); constraints.push({ type: 'alignment', axis: 'y', offsets: offsetsY }); }); } } // if gapInequalities variable is set add each inequality constraint to list of constraints if (options.gapInequalities) { options.gapInequalities.forEach(function (inequality) { // for the constraints to be passed to cola layout adaptor use indices of nodes, // not the nodes themselves var leftIndex = inequality.left.scratch().cola.index; var rightIndex = inequality.right.scratch().cola.index; constraints.push({ axis: inequality.axis, left: leftIndex, right: rightIndex, gap: inequality.gap, equality: inequality.equality }); }); } // add constraints if any if (constraints.length > 0) { adaptor.constraints(constraints); } // add compound nodes to cola adaptor.groups(parentNodes.map(function (node, i) { // add basic group incl leaf nodes var optPadding = getOptVal(options.nodeSpacing, node); var getPadding = function getPadding(d) { return parseFloat(node.style('padding-' + d)); }; var pleft = getPadding('left') + optPadding; var pright = getPadding('right') + optPadding; var ptop = getPadding('top') + optPadding; var pbottom = getPadding('bottom') + optPadding; node.scratch().cola = { index: i, padding: Math.max(pleft, pright, ptop, pbottom), // leaves should only contain direct descendants (children), // not the leaves of nested compound nodes or any nodes that are compounds themselves leaves: node.children().intersection(nonparentNodes).map(function (child) { return child[0].scratch().cola.index; }), fixed: node.locked() }; return node; }).map(function (node) { // add subgroups node.scratch().cola.groups = node.children().intersection(parentNodes).map(function (child) { return child.scratch().cola.index; }); return node.scratch().cola; })); // get the edge length setting mechanism var length = void 0; var lengthFnName = void 0; if (options.edgeLength != null) { length = options.edgeLength; lengthFnName = 'linkDistance'; } else if (options.edgeSymDiffLength != null) { length = options.edgeSymDiffLength; lengthFnName = 'symmetricDiffLinkLengths'; } else if (options.edgeJaccardLength != null) { length = options.edgeJaccardLength; lengthFnName = 'jaccardLinkLengths'; } else { length = 100; lengthFnName = 'linkDistance'; } var lengthGetter = function lengthGetter(link) { return link.calcLength; }; // add the edges to cola adaptor.links(edges.stdFilter(function (edge) { return nonparentNodes.contains(edge.source()) && nonparentNodes.contains(edge.target()); }).map(function (edge) { var c = edge.scratch().cola = { source: edge.source()[0].scratch().cola.index, target: edge.target()[0].scratch().cola.index }; if (length != null) { c.calcLength = getOptVal(length, edge); } return c; })); adaptor.size([bb.w, bb.h]); if (length != null) { adaptor[lengthFnName](lengthGetter); } // set the flow of cola if (options.flow) { var flow = void 0; var defAxis = 'y'; var defMinSep = 50; if (isString(options.flow)) { flow = { axis: options.flow, minSeparation: defMinSep }; } else if (isNumber(options.flow)) { flow = { axis: defAxis, minSeparation: options.flow }; } else if (isObject(options.flow)) { flow = options.flow; flow.axis = flow.axis || defAxis; flow.minSeparation = flow.minSeparation != null ? flow.minSeparation : defMinSep; } else { // e.g. options.flow: true flow = { axis: defAxis, minSeparation: defMinSep }; } adaptor.flowLayout(flow.axis, flow.minSeparation); } layout.trigger({ type: 'layoutstart', layout: layout }); adaptor.avoidOverlaps(options.avoidOverlap).handleDisconnected(options.handleDisconnected).start(options.unconstrIter, options.userConstIter, options.allConstIter, undefined, // gridSnapIterations = 0 undefined, // keepRunning = true options.centerGraph); if (!options.infinite) { setTimeout(function () { if (!layout.manuallyStopped) { adaptor.stop(); } }, options.maxSimulationTime); } return this; // chaining }; // called on continuous layouts to stop them before they finish ColaLayout.prototype.stop = function () { if (this.adaptor) { this.manuallyStopped = true; this.adaptor.stop(); } return this; // chaining }; module.exports = ColaLayout; /***/ }), /* 1 */ /***/ (function (module, exports, __webpack_require__) { "use strict"; // Simple, internal Object.assign() polyfill for options objects etc. module.exports = Object.assign != null ? Object.assign.bind(Object) : function (tgt) { for (var _len = arguments.length, srcs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { srcs[_key - 1] = arguments[_key]; } srcs.filter(function (src) { return src != null; }).forEach(function (src) { Object.keys(src).forEach(function (k) { return tgt[k] = src[k]; }); }); return tgt; }; /***/ }), /* 2 */ /***/ (function (module, exports, __webpack_require__) { "use strict"; // default layout options var defaults = { animate: true, // whether to show the layout as it's running refresh: 1, // number of ticks per frame; higher is faster but more jerky maxSimulationTime: 4000, // max length in ms to run the layout ungrabifyWhileSimulating: false, // so you can't drag nodes during layout fit: true, // on every layout reposition of nodes, fit the viewport padding: 30, // padding around the simulation boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } nodeDimensionsIncludeLabels: false, // whether labels should be included in determining the space used by a node // layout event callbacks ready: function ready() { }, // on layoutready stop: function stop() { }, // on layoutstop // positioning options randomize: false, // use random node positions at beginning of layout avoidOverlap: true, // if true, prevents overlap of node bounding boxes handleDisconnected: true, // if true, avoids disconnected components from overlapping convergenceThreshold: 0.01, // when the alpha value (system energy) falls below this value, the layout stops nodeSpacing: function nodeSpacing(node) { return 10; }, // extra spacing around nodes flow: undefined, // use DAG/tree flow layout if specified, e.g. { axis: 'y', minSeparation: 30 } alignment: undefined, // relative alignment constraints on nodes, e.g. function( node ){ return { x: 0, y: 1 } } gapInequalities: undefined, // list of inequality constraints for the gap between the nodes, e.g. [{"axis":"y", "left":node1, "right":node2, "gap":25}] centerGraph: true, // adjusts the node positions initially to center the graph (pass false if you want to start the layout from the current position) // different methods of specifying edge length // each can be a constant numerical value or a function like `function( edge ){ return 2; }` edgeLength: undefined, // sets edge length directly in simulation edgeSymDiffLength: undefined, // symmetric diff edge length in simulation edgeJaccardLength: undefined, // jaccard edge length in simulation // iterations of cola algorithm; uses default values on undefined unconstrIter: undefined, // unconstrained initial layout iterations userConstIter: undefined, // initial layout iterations with user-specified constraints allConstIter: undefined, // initial layout iterations with all constraints including non-overlap // infinite layout options infinite: false // overrides all other options for a forces-all-the-time mode }; module.exports = defaults; /***/ }), /* 3 */ /***/ (function (module, exports, __webpack_require__) { "use strict"; var impl = __webpack_require__(0); // registers the extension on a cytoscape lib ref var register = function register(cytoscape) { if (!cytoscape) { return; } // can't register if cytoscape unspecified cytoscape('layout', 'cola', impl); // register with cytoscape.js }; if (typeof cytoscape !== 'undefined') { // expose to global cytoscape (i.e. window.cytoscape) register(cytoscape); } module.exports = register; /***/ }), /* 4 */ /***/ (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; }; var raf = void 0; if ((typeof window === "undefined" ? "undefined" : _typeof(window)) !== (true ? "undefined" : _typeof(undefined))) { raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || function (fn) { return setTimeout(fn, 16); }; } else { // if not available, all you get is immediate calls raf = function raf(cb) { cb(); }; } module.exports = raf; /***/ }), /* 5 */ /***/ (function (module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_5__; /***/ }) /******/]); });