Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cytoscape-fcose

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cytoscape-fcose - npm Package Compare versions

Comparing version 2.1.0 to 2.2.0

CITATION.cff

360

cytoscape-fcose.js

@@ -10,3 +10,3 @@ (function webpackUniversalModuleDefinition(root, factory) {

root["cytoscapeFcose"] = factory(root["coseBase"]);
})(self, function(__WEBPACK_EXTERNAL_MODULE__281__) {
})(this, function(__WEBPACK_EXTERNAL_MODULE__140__) {
return /******/ (() => { // webpackBootstrap

@@ -44,2 +44,4 @@ /******/ "use strict";

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
/*

@@ -49,3 +51,3 @@ * Auxiliary functions

var LinkedList = __webpack_require__(281).layoutBase.LinkedList;
var LinkedList = __webpack_require__(140).layoutBase.LinkedList;

@@ -144,3 +146,3 @@ var auxiliary = {};

// has() is cheap
cmpt.merge(e); // forEach() only considers nodes -- sets N at call time
cmpt.merge(e);
}

@@ -188,2 +190,89 @@ });

// relocates componentResult to originalCenter if there is no fixedNodeConstraint
auxiliary.relocateComponent = function (originalCenter, componentResult, options) {
if (!options.fixedNodeConstraint) {
var minXCoord = Number.POSITIVE_INFINITY;
var maxXCoord = Number.NEGATIVE_INFINITY;
var minYCoord = Number.POSITIVE_INFINITY;
var maxYCoord = Number.NEGATIVE_INFINITY;
if (options.quality == "draft") {
// calculate current bounding box
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = componentResult.nodeIndexes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var _ref2 = _slicedToArray(_ref, 2);
var key = _ref2[0];
var value = _ref2[1];
var cyNode = options.cy.getElementById(key);
if (cyNode) {
var nodeBB = cyNode.boundingBox();
var leftX = componentResult.xCoords[value] - nodeBB.w / 2;
var rightX = componentResult.xCoords[value] + nodeBB.w / 2;
var topY = componentResult.yCoords[value] - nodeBB.h / 2;
var bottomY = componentResult.yCoords[value] + nodeBB.h / 2;
if (leftX < minXCoord) minXCoord = leftX;
if (rightX > maxXCoord) maxXCoord = rightX;
if (topY < minYCoord) minYCoord = topY;
if (bottomY > maxYCoord) maxYCoord = bottomY;
}
}
// find difference between current and original center
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var diffOnX = originalCenter.x - (maxXCoord + minXCoord) / 2;
var diffOnY = originalCenter.y - (maxYCoord + minYCoord) / 2;
// move component to original center
componentResult.xCoords = componentResult.xCoords.map(function (x) {
return x + diffOnX;
});
componentResult.yCoords = componentResult.yCoords.map(function (y) {
return y + diffOnY;
});
} else {
// calculate current bounding box
Object.keys(componentResult).forEach(function (item) {
var node = componentResult[item];
var leftX = node.getRect().x;
var rightX = node.getRect().x + node.getRect().width;
var topY = node.getRect().y;
var bottomY = node.getRect().y + node.getRect().height;
if (leftX < minXCoord) minXCoord = leftX;
if (rightX > maxXCoord) maxXCoord = rightX;
if (topY < minYCoord) minYCoord = topY;
if (bottomY > maxYCoord) maxYCoord = bottomY;
});
// find difference between current and original center
var _diffOnX = originalCenter.x - (maxXCoord + minXCoord) / 2;
var _diffOnY = originalCenter.y - (maxYCoord + minYCoord) / 2;
// move component to original center
Object.keys(componentResult).forEach(function (item) {
var node = componentResult[item];
node.setCenter(node.getCenterX() + _diffOnX, node.getCenterY() + _diffOnY);
});
}
}
};
auxiliary.calcBoundingBox = function (parentNode, xCoords, yCoords, nodeIndexes) {

@@ -235,2 +324,20 @@ // calculate bounds

// This function finds and returns parent nodes whose all children are hidden
auxiliary.calcParentsWithoutChildren = function (cy, eles) {
var parentsWithoutChildren = cy.collection();
eles.nodes(':parent').forEach(function (parent) {
var check = false;
parent.children().forEach(function (child) {
if (child.css('display') != 'none') {
check = true;
}
});
if (!check) {
parentsWithoutChildren.merge(parent);
}
});
return parentsWithoutChildren;
};
module.exports = auxiliary;

@@ -250,9 +357,9 @@

var aux = __webpack_require__(548);
var CoSELayout = __webpack_require__(281).CoSELayout;
var CoSENode = __webpack_require__(281).CoSENode;
var PointD = __webpack_require__(281).layoutBase.PointD;
var DimensionD = __webpack_require__(281).layoutBase.DimensionD;
var LayoutConstants = __webpack_require__(281).layoutBase.LayoutConstants;
var FDLayoutConstants = __webpack_require__(281).layoutBase.FDLayoutConstants;
var CoSEConstants = __webpack_require__(281).CoSEConstants;
var CoSELayout = __webpack_require__(140).CoSELayout;
var CoSENode = __webpack_require__(140).CoSENode;
var PointD = __webpack_require__(140).layoutBase.PointD;
var DimensionD = __webpack_require__(140).layoutBase.DimensionD;
var LayoutConstants = __webpack_require__(140).layoutBase.LayoutConstants;
var FDLayoutConstants = __webpack_require__(140).layoutBase.FDLayoutConstants;
var CoSEConstants = __webpack_require__(140).CoSEConstants;

@@ -262,2 +369,3 @@ // main function that cose layout is processed

var cy = options.cy;
var eles = options.eles;

@@ -292,2 +400,4 @@ var nodes = eles.nodes();

var parentsWithoutChildren = aux.calcParentsWithoutChildren(cy, eles);
// transfer cytoscape nodes to cose nodes

@@ -298,3 +408,6 @@ var processChildrenList = function processChildrenList(parent, children, layout, options) {

var theChild = children[i];
var children_of_children = theChild.children();
var children_of_children = null;
if (theChild.intersection(parentsWithoutChildren).length == 0) {
children_of_children = theChild.children();
}
var theNode = void 0;

@@ -312,3 +425,8 @@

var parentInfo = aux.calcBoundingBox(theChild, xCoords, yCoords, nodeIndexes);
theNode = parent.add(new CoSENode(layout.graphManager, new PointD(parentInfo.topLeftX, parentInfo.topLeftY), new DimensionD(parentInfo.width, parentInfo.height)));
if (theChild.intersection(parentsWithoutChildren).length == 0) {
theNode = parent.add(new CoSENode(layout.graphManager, new PointD(parentInfo.topLeftX, parentInfo.topLeftY), new DimensionD(parentInfo.width, parentInfo.height)));
} else {
// for the parentsWithoutChildren
theNode = parent.add(new CoSENode(layout.graphManager, new PointD(parentInfo.topLeftX, parentInfo.topLeftY), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));
}
}

@@ -367,3 +485,3 @@ } else {

var targetNode = idToLNode[edge.data("target")];
if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) {
if (sourceNode && targetNode && sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) {
var e1 = gm.add(layout.newEdge(), sourceNode, targetNode);

@@ -414,2 +532,4 @@ e1.id = edge.id();

if (options.tilingCompareBy != null) CoSEConstants.TILING_COMPARE_BY = options.tilingCompareBy;
if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 0;

@@ -556,2 +676,5 @@

tile: true,
// The function that specifies the criteria for comparing nodes while sorting them during tiling operation.
// Takes the node id as a parameter and the default tiling operation is perfomed when this option is not set.
tilingCompareBy: undefined,
// Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)

@@ -607,2 +730,3 @@ tilingPaddingVertical: 10,

var components = void 0;
var componentCenters = [];

@@ -647,4 +771,8 @@ // basic validity check for constraint inputs

if (!packingEnabled) {
// store component center
var boundingBox = options.eles.boundingBox();
componentCenters.push({ x: boundingBox.x1 + boundingBox.w / 2, y: boundingBox.y1 + boundingBox.h / 2 });
// apply spectral layout
if (options.randomize) {
var result = spectralLayout(options); // apply spectral layout
var result = spectralLayout(options);
spectralResult.push(result);

@@ -655,2 +783,5 @@ }

coseResult.push(coseLayout(options, spectralResult[0]));
aux.relocateComponent(componentCenters[0], coseResult[0], options); // relocate center to original position
} else {
aux.relocateComponent(componentCenters[0], spectralResult[0], options); // relocate center to original position
}

@@ -661,4 +792,9 @@ } else {

components = aux.connectComponents(cy, options.eles, topMostNodes);
// store component centers
components.forEach(function (component) {
var boundingBox = component.boundingBox();
componentCenters.push({ x: boundingBox.x1 + boundingBox.w / 2, y: boundingBox.y1 + boundingBox.h / 2 });
});
//send each component to spectral layout
//send each component to spectral layout if randomized
if (options.randomize) {

@@ -695,2 +831,4 @@ components.forEach(function (component) {

if (toBeTiledNodes.length > 1) {
var _boundingBox = toBeTiledNodes.boundingBox();
componentCenters.push({ x: _boundingBox.x1 + _boundingBox.w / 2, y: _boundingBox.y1 + _boundingBox.h / 2 });
components.push(toBeTiledNodes);

@@ -701,2 +839,3 @@ spectralResult.push(tempSpectralResult);

spectralResult.splice(indexesToBeDeleted[i], 1);
componentCenters.splice(indexesToBeDeleted[i], 1);
};

@@ -709,8 +848,17 @@ }

coseResult.push(coseLayout(options, spectralResult[index]));
aux.relocateComponent(componentCenters[index], coseResult[index], options); // relocate center to original position
});
} else {
components.forEach(function (component, index) {
aux.relocateComponent(componentCenters[index], spectralResult[index], options); // relocate center to original position
});
}
// packing
var componentsEvaluated = new Set();
if (components.length > 1) {
var subgraphs = [];
var hiddenEles = eles.filter(function (ele) {
return ele.css('display') == 'none';
});
components.forEach(function (component, index) {

@@ -721,49 +869,61 @@ var nodeIndexes = void 0;

}
var subgraph = {};
subgraph.nodes = [];
subgraph.edges = [];
var nodeIndex = void 0;
component.nodes().forEach(function (node) {
if (options.quality == "draft") {
if (!node.isParent()) {
nodeIndex = nodeIndexes.get(node.id());
subgraph.nodes.push({ x: spectralResult[index].xCoords[nodeIndex] - node.boundingbox().w / 2, y: spectralResult[index].yCoords[nodeIndex] - node.boundingbox().h / 2, width: node.boundingbox().w, height: node.boundingbox().h });
if (component.nodes().not(hiddenEles).length > 0) {
var subgraph = {};
subgraph.edges = [];
subgraph.nodes = [];
var nodeIndex = void 0;
component.nodes().not(hiddenEles).forEach(function (node) {
if (options.quality == "draft") {
if (!node.isParent()) {
nodeIndex = nodeIndexes.get(node.id());
subgraph.nodes.push({ x: spectralResult[index].xCoords[nodeIndex] - node.boundingbox().w / 2, y: spectralResult[index].yCoords[nodeIndex] - node.boundingbox().h / 2, width: node.boundingbox().w, height: node.boundingbox().h });
} else {
var parentInfo = aux.calcBoundingBox(node, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
subgraph.nodes.push({ x: parentInfo.topLeftX, y: parentInfo.topLeftY, width: parentInfo.width, height: parentInfo.height });
}
} else {
var parentInfo = aux.calcBoundingBox(node, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
subgraph.nodes.push({ x: parentInfo.topLeftX, y: parentInfo.topLeftY, width: parentInfo.width, height: parentInfo.height });
if (coseResult[index][node.id()]) {
subgraph.nodes.push({ x: coseResult[index][node.id()].getLeft(), y: coseResult[index][node.id()].getTop(), width: coseResult[index][node.id()].getWidth(), height: coseResult[index][node.id()].getHeight() });
}
}
} else {
subgraph.nodes.push({ x: coseResult[index][node.id()].getLeft(), y: coseResult[index][node.id()].getTop(), width: coseResult[index][node.id()].getWidth(), height: coseResult[index][node.id()].getHeight() });
}
});
component.edges().forEach(function (edge) {
var source = edge.source();
var target = edge.target();
if (options.quality == "draft") {
var sourceNodeIndex = nodeIndexes.get(source.id());
var targetNodeIndex = nodeIndexes.get(target.id());
var sourceCenter = [];
var targetCenter = [];
if (source.isParent()) {
var parentInfo = aux.calcBoundingBox(source, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
sourceCenter.push(parentInfo.topLeftX + parentInfo.width / 2);
sourceCenter.push(parentInfo.topLeftY + parentInfo.height / 2);
} else {
sourceCenter.push(spectralResult[index].xCoords[sourceNodeIndex]);
sourceCenter.push(spectralResult[index].yCoords[sourceNodeIndex]);
});
component.edges().forEach(function (edge) {
var source = edge.source();
var target = edge.target();
if (source.css("display") != "none" && target.css("display") != "none") {
if (options.quality == "draft") {
var sourceNodeIndex = nodeIndexes.get(source.id());
var targetNodeIndex = nodeIndexes.get(target.id());
var sourceCenter = [];
var targetCenter = [];
if (source.isParent()) {
var parentInfo = aux.calcBoundingBox(source, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
sourceCenter.push(parentInfo.topLeftX + parentInfo.width / 2);
sourceCenter.push(parentInfo.topLeftY + parentInfo.height / 2);
} else {
sourceCenter.push(spectralResult[index].xCoords[sourceNodeIndex]);
sourceCenter.push(spectralResult[index].yCoords[sourceNodeIndex]);
}
if (target.isParent()) {
var _parentInfo = aux.calcBoundingBox(target, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
targetCenter.push(_parentInfo.topLeftX + _parentInfo.width / 2);
targetCenter.push(_parentInfo.topLeftY + _parentInfo.height / 2);
} else {
targetCenter.push(spectralResult[index].xCoords[targetNodeIndex]);
targetCenter.push(spectralResult[index].yCoords[targetNodeIndex]);
}
subgraph.edges.push({ startX: sourceCenter[0], startY: sourceCenter[1], endX: targetCenter[0], endY: targetCenter[1] });
} else {
if (coseResult[index][source.id()] && coseResult[index][target.id()]) {
subgraph.edges.push({ startX: coseResult[index][source.id()].getCenterX(), startY: coseResult[index][source.id()].getCenterY(), endX: coseResult[index][target.id()].getCenterX(), endY: coseResult[index][target.id()].getCenterY() });
}
}
}
if (target.isParent()) {
var _parentInfo = aux.calcBoundingBox(target, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
targetCenter.push(_parentInfo.topLeftX + _parentInfo.width / 2);
targetCenter.push(_parentInfo.topLeftY + _parentInfo.height / 2);
} else {
targetCenter.push(spectralResult[index].xCoords[targetNodeIndex]);
targetCenter.push(spectralResult[index].yCoords[targetNodeIndex]);
}
subgraph.edges.push({ startX: sourceCenter[0], startY: sourceCenter[1], endX: targetCenter[0], endY: targetCenter[1] });
} else {
subgraph.edges.push({ startX: coseResult[index][source.id()].getCenterX(), startY: coseResult[index][source.id()].getCenterY(), endX: coseResult[index][target.id()].getCenterX(), endY: coseResult[index][target.id()].getCenterY() });
});
if (subgraph.nodes.length > 0) {
subgraphs.push(subgraph);
componentsEvaluated.add(index);
}
});
subgraphs.push(subgraph);
}
});

@@ -783,7 +943,9 @@ var shiftResult = layUtil.packComponents(subgraphs, options.randomize).shifts;

} else {
coseResult.forEach(function (result, index) {
Object.keys(result).forEach(function (item) {
var nodeRectangle = result[item];
nodeRectangle.setCenter(nodeRectangle.getCenterX() + shiftResult[index].dx, nodeRectangle.getCenterY() + shiftResult[index].dy);
var _count = 0;
componentsEvaluated.forEach(function (index) {
Object.keys(coseResult[index]).forEach(function (item) {
var nodeRectangle = coseResult[index][item];
nodeRectangle.setCenter(nodeRectangle.getCenterX() + shiftResult[_count].dx, nodeRectangle.getCenterY() + shiftResult[_count].dy);
});
_count++;
});

@@ -793,52 +955,2 @@ }

}
// move graph to its original position because spectral moves it to origin
if (options.randomize && !options.fixedNodeConstraint) {
var minXCoord = Number.POSITIVE_INFINITY;
var maxXCoord = Number.NEGATIVE_INFINITY;
var minYCoord = Number.POSITIVE_INFINITY;
var maxYCoord = Number.NEGATIVE_INFINITY;
if (options.quality == "draft") {
spectralResult.forEach(function (result) {
result.xCoords.forEach(function (value) {
if (value < minXCoord) minXCoord = value;
if (value > maxXCoord) maxXCoord = value;
});
result.yCoords.forEach(function (value) {
if (value < minYCoord) minYCoord = value;
if (value > maxYCoord) maxYCoord = value;
});
});
var boundingBox = options.eles.boundingBox();
var diffOnX = boundingBox.x1 + boundingBox.w / 2 - (maxXCoord + minXCoord) / 2;
var diffOnY = boundingBox.y1 + boundingBox.h / 2 - (maxYCoord + minYCoord) / 2;
spectralResult.forEach(function (result) {
result.xCoords = result.xCoords.map(function (x) {
return x + diffOnX;
});
result.yCoords = result.yCoords.map(function (y) {
return y + diffOnY;
});
});
} else {
coseResult.forEach(function (result) {
Object.keys(result).forEach(function (item) {
var node = result[item];
if (node.getCenterX() < minXCoord) minXCoord = node.getCenterX();
if (node.getCenterX() > maxXCoord) maxXCoord = node.getCenterX();
if (node.getCenterY() < minYCoord) minYCoord = node.getCenterY();
if (node.getCenterY() > maxYCoord) maxYCoord = node.getCenterY();
});
});
var _boundingBox = options.eles.boundingBox();
var _diffOnX = _boundingBox.x1 + _boundingBox.w / 2 - (maxXCoord + minXCoord) / 2;
var _diffOnY = _boundingBox.y1 + _boundingBox.h / 2 - (maxYCoord + minYCoord) / 2;
coseResult.forEach(function (result, index) {
Object.keys(result).forEach(function (item) {
var node = result[item];
node.setCenter(node.getCenterX() + _diffOnX, node.getCenterY() + _diffOnY);
});
});
}
}
}

@@ -877,2 +989,3 @@

}
if (pos == undefined) pos = { x: ele.position("x"), y: ele.position("y") };
return {

@@ -901,4 +1014,15 @@ x: pos.x,

// transfer calculated positions to nodes (positions of only simple nodes are evaluated, compounds are positioned automatically)
options.eles = eles;
eles.nodes().not(":parent").layoutPositions(layout, options, getPositions);
var parentsWithoutChildren = aux.calcParentsWithoutChildren(cy, eles);
var _hiddenEles = eles.filter(function (ele) {
return ele.css('display') == 'none';
});
options.eles = eles.not(_hiddenEles);
eles.nodes().not(":parent").not(_hiddenEles).layoutPositions(layout, options, getPositions);
if (parentsWithoutChildren.length > 0) {
parentsWithoutChildren.forEach(function (ele) {
ele.position(getPositions(ele));
});
}
} else {

@@ -927,4 +1051,4 @@ console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.");

var aux = __webpack_require__(548);
var Matrix = __webpack_require__(281).layoutBase.Matrix;
var SVD = __webpack_require__(281).layoutBase.SVD;
var Matrix = __webpack_require__(140).layoutBase.Matrix;
var SVD = __webpack_require__(140).layoutBase.SVD;

@@ -1409,6 +1533,6 @@ // main function that spectral layout is processed

/***/ 281:
/***/ 140:
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_MODULE__281__;
module.exports = __WEBPACK_EXTERNAL_MODULE__140__;

@@ -1415,0 +1539,0 @@ /***/ })

{
"name": "cytoscape-fcose",
"version": "2.1.0",
"version": "2.2.0",
"description": "The fCoSE layout for Cytoscape.js by Bilkent with fast compound node placement",

@@ -55,4 +55,4 @@ "main": "cytoscape-fcose.js",

"dependencies": {
"cose-base": "^2.0.0"
"cose-base": "^2.2.0"
}
}

@@ -27,7 +27,7 @@ cytoscape-fcose

Please cite the following when you use this layout until an fCoSE publication is available:
Please cite the following when you use this layout:
U. Dogrusoz, E. Giral, A. Cetintas, A. Civril, and E. Demir, "[A Layout Algorithm For Undirected Compound Graphs](http://www.sciencedirect.com/science/article/pii/S0020025508004799)", Information Sciences, 179, pp. 980-994, 2009.
H. Balci and U. Dogrusoz, "[fCoSE: A Fast Compound Graph Layout Algorithm with Constraint Support](https://doi.org/10.1109/TVCG.2021.3095303)," in IEEE Transactions on Visualization and Computer Graphics, 28(12), pp. 4582-4593, 2022.
A. Civril, M. Magdon-Ismail, and E. Bocek-Rivele, "[SSDE: Fast Graph Drawing Using Sampled Spectral Distance Embedding](https://link.springer.com/chapter/10.1007/978-3-540-70904-6_5)", International Symposium on Graph Drawing, pp. 30-41, 2006.
U. Dogrusoz, E. Giral, A. Cetintas, A. Civril and E. Demir, "[A Layout Algorithm For Undirected Compound Graphs](http://www.sciencedirect.com/science/article/pii/S0020025508004799)", Information Sciences, 179, pp. 980-994, 2009.

@@ -167,3 +167,10 @@ ## Dependencies

// For enabling tiling
tile: true,
tile: true,
// The comparison function to be used while sorting nodes during tiling operation.
// Takes the ids of 2 nodes that will be compared as a parameter and the default tiling operation is performed when this option is not set.
// It works similar to ``compareFunction`` parameter of ``Array.prototype.sort()``
// If node1 is less then node2 by some ordering criterion ``tilingCompareBy(nodeId1, nodeId2)`` must return a negative value
// If node1 is greater then node2 by some ordering criterion ``tilingCompareBy(nodeId1, nodeId2)`` must return a positive value
// If node1 is equal to node2 by some ordering criterion ``tilingCompareBy(nodeId1, nodeId2)`` must return 0
tilingCompareBy: undefined,
// Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)

@@ -170,0 +177,0 @@ tilingPaddingVertical: 10,

@@ -94,3 +94,3 @@ /*

if( cmpt.has(e.source()) && cmpt.has(e.target()) ){ // has() is cheap
cmpt.merge(e); // forEach() only considers nodes -- sets N at call time
cmpt.merge(e);
}

@@ -136,2 +136,67 @@ });

// relocates componentResult to originalCenter if there is no fixedNodeConstraint
auxiliary.relocateComponent = function(originalCenter, componentResult, options) {
if (!options.fixedNodeConstraint) {
let minXCoord = Number.POSITIVE_INFINITY;
let maxXCoord = Number.NEGATIVE_INFINITY;
let minYCoord = Number.POSITIVE_INFINITY;
let maxYCoord = Number.NEGATIVE_INFINITY;
if (options.quality == "draft") {
// calculate current bounding box
for (let [key, value] of componentResult.nodeIndexes) {
let cyNode = options.cy.getElementById(key);
if (cyNode) {
let nodeBB = cyNode.boundingBox();
let leftX = componentResult.xCoords[value] - nodeBB.w / 2;
let rightX = componentResult.xCoords[value] + nodeBB.w / 2;
let topY = componentResult.yCoords[value] - nodeBB.h / 2;
let bottomY = componentResult.yCoords[value] + nodeBB.h / 2;
if (leftX < minXCoord)
minXCoord = leftX;
if (rightX > maxXCoord)
maxXCoord = rightX;
if (topY < minYCoord)
minYCoord = topY;
if (bottomY > maxYCoord)
maxYCoord = bottomY;
}
}
// find difference between current and original center
let diffOnX = originalCenter.x - (maxXCoord + minXCoord) / 2;
let diffOnY = originalCenter.y - (maxYCoord + minYCoord) / 2;
// move component to original center
componentResult.xCoords = componentResult.xCoords.map(x => x + diffOnX);
componentResult.yCoords = componentResult.yCoords.map(y => y + diffOnY);
}
else {
// calculate current bounding box
Object.keys(componentResult).forEach(function (item) {
let node = componentResult[item];
let leftX = node.getRect().x;
let rightX = node.getRect().x + node.getRect().width;
let topY = node.getRect().y;
let bottomY = node.getRect().y + node.getRect().height;
if (leftX < minXCoord)
minXCoord = leftX;
if (rightX > maxXCoord)
maxXCoord = rightX;
if (topY < minYCoord)
minYCoord = topY;
if (bottomY > maxYCoord)
maxYCoord = bottomY;
});
// find difference between current and original center
let diffOnX = originalCenter.x - (maxXCoord + minXCoord) / 2;
let diffOnY = originalCenter.y - (maxYCoord + minYCoord) / 2;
// move component to original center
Object.keys(componentResult).forEach(function (item) {
let node = componentResult[item];
node.setCenter(node.getCenterX() + diffOnX, node.getCenterY() + diffOnY);
});
}
}
};
auxiliary.calcBoundingBox = function(parentNode, xCoords, yCoords, nodeIndexes){

@@ -188,2 +253,20 @@ // calculate bounds

// This function finds and returns parent nodes whose all children are hidden
auxiliary.calcParentsWithoutChildren = function(cy, eles){
let parentsWithoutChildren = cy.collection();
eles.nodes(':parent').forEach((parent) => {
let check = false;
parent.children().forEach((child) => {
if(child.css('display') != 'none') {
check = true;
}
});
if(!check) {
parentsWithoutChildren.merge(parent);
}
});
return parentsWithoutChildren;
}
module.exports = auxiliary;

@@ -16,3 +16,4 @@ /**

let coseLayout = function(options, spectralResult){
let cy = options.cy;
let eles = options.eles;

@@ -45,2 +46,4 @@ let nodes = eles.nodes();

let parentsWithoutChildren = aux.calcParentsWithoutChildren(cy, eles);
// transfer cytoscape nodes to cose nodes

@@ -51,3 +54,6 @@ let processChildrenList = function (parent, children, layout, options) {

let theChild = children[i];
let children_of_children = theChild.children();
let children_of_children = null;
if(theChild.intersection(parentsWithoutChildren).length == 0) {
children_of_children = theChild.children();
}
let theNode;

@@ -69,5 +75,12 @@

let parentInfo = aux.calcBoundingBox(theChild, xCoords, yCoords, nodeIndexes);
theNode = parent.add(new CoSENode(layout.graphManager,
new PointD(parentInfo.topLeftX, parentInfo.topLeftY),
new DimensionD(parentInfo.width, parentInfo.height)));
if(theChild.intersection(parentsWithoutChildren).length == 0) {
theNode = parent.add(new CoSENode(layout.graphManager,
new PointD(parentInfo.topLeftX, parentInfo.topLeftY),
new DimensionD(parentInfo.width, parentInfo.height)));
}
else { // for the parentsWithoutChildren
theNode = parent.add(new CoSENode(layout.graphManager,
new PointD(parentInfo.topLeftX, parentInfo.topLeftY),
new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));
}
}

@@ -130,3 +143,3 @@ }

let targetNode = idToLNode[edge.data("target")];
if(sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0){
if(sourceNode && targetNode && sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0){
let e1 = gm.add(layout.newEdge(), sourceNode, targetNode);

@@ -186,2 +199,5 @@ e1.id = edge.id();

CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental;
if (options.tilingCompareBy != null)
CoSEConstants.TILING_COMPARE_BY = options.tilingCompareBy;

@@ -188,0 +204,0 @@ if(options.quality == 'proof')

@@ -65,3 +65,6 @@ /**

// For enabling tiling
tile: true,
tile: true,
// The function that specifies the criteria for comparing nodes while sorting them during tiling operation.
// Takes the node id as a parameter and the default tiling operation is perfomed when this option is not set.
tilingCompareBy: undefined,
// Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)

@@ -113,2 +116,3 @@ tilingPaddingVertical: 10,

let components;
let componentCenters = [];

@@ -155,16 +159,29 @@ // basic validity check for constraint inputs

if(!packingEnabled){
// store component center
let boundingBox = options.eles.boundingBox();
componentCenters.push({x: boundingBox.x1 + boundingBox.w / 2, y: boundingBox.y1 + boundingBox.h / 2});
// apply spectral layout
if(options.randomize){
let result = spectralLayout(options); // apply spectral layout
let result = spectralLayout(options);
spectralResult.push(result);
}
// apply cose layout as postprocessing
if(options.quality == "default" || options.quality == "proof"){
if(options.quality == "default" || options.quality == "proof"){
coseResult.push(coseLayout(options, spectralResult[0]));
}
aux.relocateComponent(componentCenters[0], coseResult[0], options); // relocate center to original position
}
else{
aux.relocateComponent(componentCenters[0], spectralResult[0], options); // relocate center to original position
}
}
else{ // packing is enabled
let topMostNodes = aux.getTopMostNodes(options.eles.nodes());
components = aux.connectComponents(cy, options.eles, topMostNodes);
components = aux.connectComponents(cy, options.eles, topMostNodes);
// store component centers
components.forEach(function(component){
let boundingBox = component.boundingBox();
componentCenters.push({x: boundingBox.x1 + boundingBox.w / 2, y: boundingBox.y1 + boundingBox.h / 2});
});
//send each component to spectral layout
//send each component to spectral layout if randomized
if(options.randomize){

@@ -200,2 +217,4 @@ components.forEach(function(component){

if(toBeTiledNodes.length > 1){
let boundingBox = toBeTiledNodes.boundingBox();
componentCenters.push({x: boundingBox.x1 + boundingBox.w / 2, y: boundingBox.y1 + boundingBox.h / 2});
components.push(toBeTiledNodes);

@@ -206,2 +225,3 @@ spectralResult.push(tempSpectralResult);

spectralResult.splice(indexesToBeDeleted[i], 1);
componentCenters.splice(indexesToBeDeleted[i], 1);
};

@@ -213,8 +233,16 @@ }

coseResult.push(coseLayout(options, spectralResult[index]));
aux.relocateComponent(componentCenters[index], coseResult[index], options); // relocate center to original position
});
}
}
else {
components.forEach(function(component, index){
aux.relocateComponent(componentCenters[index], spectralResult[index], options); // relocate center to original position
});
}
// packing
let componentsEvaluated = new Set();
if(components.length > 1){
let subgraphs = [];
let hiddenEles = eles.filter((ele) => {return ele.css('display') == 'none'});
components.forEach(function(component, index){

@@ -225,54 +253,66 @@ let nodeIndexes;

}
let subgraph = {};
subgraph.nodes = [];
subgraph.edges = [];
let nodeIndex;
component.nodes().forEach(function (node) {
if(options.quality == "draft"){
if(!node.isParent()){
nodeIndex = nodeIndexes.get(node.id());
subgraph.nodes.push({x: spectralResult[index].xCoords[nodeIndex] - node.boundingbox().w/2, y: spectralResult[index].yCoords[nodeIndex] - node.boundingbox().h/2, width: node.boundingbox().w, height: node.boundingbox().h});
if(component.nodes().not(hiddenEles).length > 0) {
let subgraph = {};
subgraph.edges = [];
subgraph.nodes = [];
let nodeIndex;
component.nodes().not(hiddenEles).forEach(function (node) {
if(options.quality == "draft"){
if(!node.isParent()){
nodeIndex = nodeIndexes.get(node.id());
subgraph.nodes.push({x: spectralResult[index].xCoords[nodeIndex] - node.boundingbox().w/2, y: spectralResult[index].yCoords[nodeIndex] - node.boundingbox().h/2, width: node.boundingbox().w, height: node.boundingbox().h});
}
else{
let parentInfo = aux.calcBoundingBox(node, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
subgraph.nodes.push({x: parentInfo.topLeftX, y: parentInfo.topLeftY, width: parentInfo.width, height: parentInfo.height});
}
}
else{
let parentInfo = aux.calcBoundingBox(node, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
subgraph.nodes.push({x: parentInfo.topLeftX, y: parentInfo.topLeftY, width: parentInfo.width, height: parentInfo.height});
if(coseResult[index][node.id()]) {
subgraph.nodes.push({x: coseResult[index][node.id()].getLeft(), y: coseResult[index][node.id()].getTop(), width: coseResult[index][node.id()].getWidth(), height: coseResult[index][node.id()].getHeight()});
}
}
}
else{
subgraph.nodes.push({x: coseResult[index][node.id()].getLeft(), y: coseResult[index][node.id()].getTop(), width: coseResult[index][node.id()].getWidth(), height: coseResult[index][node.id()].getHeight()});
}
});
component.edges().forEach(function (edge) {
let source = edge.source();
let target = edge.target();
if(options.quality == "draft"){
let sourceNodeIndex = nodeIndexes.get(source.id());
let targetNodeIndex = nodeIndexes.get(target.id());
let sourceCenter = [];
let targetCenter = [];
if(source.isParent()){
let parentInfo = aux.calcBoundingBox(source, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
sourceCenter.push(parentInfo.topLeftX + parentInfo.width / 2);
sourceCenter.push(parentInfo.topLeftY + parentInfo.height / 2);
});
component.edges().forEach(function (edge) {
let source = edge.source();
let target = edge.target();
if(source.css("display") != "none" && target.css("display") != "none") {
if(options.quality == "draft"){
let sourceNodeIndex = nodeIndexes.get(source.id());
let targetNodeIndex = nodeIndexes.get(target.id());
let sourceCenter = [];
let targetCenter = [];
if(source.isParent()){
let parentInfo = aux.calcBoundingBox(source, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
sourceCenter.push(parentInfo.topLeftX + parentInfo.width / 2);
sourceCenter.push(parentInfo.topLeftY + parentInfo.height / 2);
}
else{
sourceCenter.push(spectralResult[index].xCoords[sourceNodeIndex]);
sourceCenter.push(spectralResult[index].yCoords[sourceNodeIndex]);
}
if(target.isParent()){
let parentInfo = aux.calcBoundingBox(target, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
targetCenter.push(parentInfo.topLeftX + parentInfo.width / 2);
targetCenter.push(parentInfo.topLeftY + parentInfo.height / 2);
}
else{
targetCenter.push(spectralResult[index].xCoords[targetNodeIndex]);
targetCenter.push(spectralResult[index].yCoords[targetNodeIndex]);
}
subgraph.edges.push({startX: sourceCenter[0], startY: sourceCenter[1], endX: targetCenter[0], endY: targetCenter[1]});
}
else{
if(coseResult[index][source.id()] && coseResult[index][target.id()]) {
subgraph.edges.push({startX: coseResult[index][source.id()].getCenterX(), startY: coseResult[index][source.id()].getCenterY(), endX: coseResult[index][target.id()].getCenterX(), endY: coseResult[index][target.id()].getCenterY()});
}
}
}
else{
sourceCenter.push(spectralResult[index].xCoords[sourceNodeIndex]);
sourceCenter.push(spectralResult[index].yCoords[sourceNodeIndex]);
}
if(target.isParent()){
let parentInfo = aux.calcBoundingBox(target, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);
targetCenter.push(parentInfo.topLeftX + parentInfo.width / 2);
targetCenter.push(parentInfo.topLeftY + parentInfo.height / 2);
}
else{
targetCenter.push(spectralResult[index].xCoords[targetNodeIndex]);
targetCenter.push(spectralResult[index].yCoords[targetNodeIndex]);
}
subgraph.edges.push({startX: sourceCenter[0], startY: sourceCenter[1], endX: targetCenter[0], endY: targetCenter[1]});
});
if(subgraph.nodes.length > 0) {
subgraphs.push(subgraph);
componentsEvaluated.add(index);
}
else{
subgraph.edges.push({startX: coseResult[index][source.id()].getCenterX(), startY: coseResult[index][source.id()].getCenterY(), endX: coseResult[index][target.id()].getCenterX(), endY: coseResult[index][target.id()].getCenterY()});
}
});
subgraphs.push(subgraph);
}
});

@@ -289,66 +329,13 @@ let shiftResult = layUtil.packComponents(subgraphs, options.randomize).shifts;

else{
coseResult.forEach(function(result, index){
Object.keys(result).forEach(function (item) {
let nodeRectangle = result[item];
nodeRectangle.setCenter(nodeRectangle.getCenterX() + shiftResult[index].dx, nodeRectangle.getCenterY() + shiftResult[index].dy);
let count = 0;
componentsEvaluated.forEach((index) => {
Object.keys(coseResult[index]).forEach(function (item) {
let nodeRectangle = coseResult[index][item];
nodeRectangle.setCenter(nodeRectangle.getCenterX() + shiftResult[count].dx, nodeRectangle.getCenterY() + shiftResult[count].dy);
});
});
count++;
})
}
}
}
// move graph to its original position because spectral moves it to origin
if(options.randomize && !options.fixedNodeConstraint) {
let minXCoord = Number.POSITIVE_INFINITY;
let maxXCoord = Number.NEGATIVE_INFINITY;
let minYCoord = Number.POSITIVE_INFINITY;
let maxYCoord = Number.NEGATIVE_INFINITY;
if(options.quality == "draft") {
spectralResult.forEach(function(result){
result.xCoords.forEach(function (value) {
if (value < minXCoord)
minXCoord = value;
if (value > maxXCoord)
maxXCoord = value;
});
result.yCoords.forEach(function (value) {
if (value < minYCoord)
minYCoord = value;
if (value > maxYCoord)
maxYCoord = value;
});
});
let boundingBox = options.eles.boundingBox();
let diffOnX = (boundingBox.x1 + boundingBox.w / 2) - (maxXCoord + minXCoord) / 2;
let diffOnY = (boundingBox.y1 + boundingBox.h / 2) - (maxYCoord + minYCoord) / 2;
spectralResult.forEach(function(result){
result.xCoords = result.xCoords.map(x => x + diffOnX);
result.yCoords = result.yCoords.map(y => y + diffOnY);
});
}
else {
coseResult.forEach(function(result){
Object.keys(result).forEach(function (item) {
let node = result[item];
if (node.getCenterX() < minXCoord)
minXCoord = node.getCenterX();
if (node.getCenterX() > maxXCoord)
maxXCoord = node.getCenterX();
if (node.getCenterY() < minYCoord)
minYCoord = node.getCenterY();
if (node.getCenterY() > maxYCoord)
maxYCoord = node.getCenterY();
});
});
let boundingBox = options.eles.boundingBox();
let diffOnX = (boundingBox.x1 + boundingBox.w / 2) - (maxXCoord + minXCoord) / 2;
let diffOnY = (boundingBox.y1 + boundingBox.h / 2) - (maxYCoord + minYCoord) / 2;
coseResult.forEach(function(result, index){
Object.keys(result).forEach(function (item) {
let node = result[item];
node.setCenter(node.getCenterX() + diffOnX, node.getCenterY() + diffOnY);
});
});
}
}
}

@@ -389,2 +376,4 @@

}
if(pos == undefined)
pos = {x: ele.position("x"), y: ele.position("y")};
return {

@@ -415,4 +404,13 @@ x: pos.x,

// transfer calculated positions to nodes (positions of only simple nodes are evaluated, compounds are positioned automatically)
options.eles = eles;
eles.nodes().not(":parent").layoutPositions(layout, options, getPositions);
let parentsWithoutChildren = aux.calcParentsWithoutChildren(cy, eles);
let hiddenEles = eles.filter((ele) => {return ele.css('display') == 'none'});
options.eles = eles.not(hiddenEles);
eles.nodes().not(":parent").not(hiddenEles).layoutPositions(layout, options, getPositions);
if(parentsWithoutChildren.length > 0){
parentsWithoutChildren.forEach((ele) => {
ele.position(getPositions(ele));
});
}
}

@@ -419,0 +417,0 @@ else{

@@ -18,3 +18,4 @@ const path = require('path');

library: camelcase( pkg.name ),
libraryTarget: 'umd'
libraryTarget: 'umd',
globalObject: 'this'
},

@@ -21,0 +22,0 @@ module: {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc