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

cytoscape-cose-bilkent

Package Overview
Dependencies
Maintainers
7
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cytoscape-cose-bilkent - npm Package Compare versions

Comparing version 4.0.0 to 4.1.0

nbproject/private/private.properties

3

bower.json

@@ -6,3 +6,4 @@ {

"dependencies": {
"cytoscape": "^3.2.0"
"cytoscape": "^3.2.0",
"cose-base": "^1.0.0"
},

@@ -9,0 +10,0 @@ "repository": {

{
"name": "cytoscape-cose-bilkent",
"version": "4.0.0",
"version": "4.1.0",
"description": "The CoSE layout for Cytoscape.js by Bilkent with enhanced compound node placement",
"main": "cytoscape-cose-bilkent.js",
"scripts": {
"postpublish": "run-s gh-pages:demo gh-pages:deploy gh-pages:clean",
"gh-pages:demo": "cpy demo.html . --rename=index.html",
"gh-pages:deploy": "gh-pages -d .",
"gh-pages:clean": "rimraf index.html",
"postpublish": "run-s gh-pages",
"gh-pages": "gh-pages -d pages",
"copyright": "update license",
"lint": "eslint src",
"build": "cross-env NODE_ENV=production webpack",
"build:min": "cross-env NODE_ENV=production MIN=true webpack",
"build:release": "run-s build copyright",
"watch": "webpack --progress --watch",

@@ -37,11 +37,13 @@ "dev": "webpack-dev-server --open",

"chai": "4.0.2",
"cpy-cli": "^1.0.1",
"cross-env": "^5.0.0",
"eslint": "^3.9.1",
"gh-pages": "^1.0.0",
"mocha": "3.4.2",
"npm-run-all": "^4.1.2",
"rimraf": "^2.6.2",
"update": "^0.7.4",
"updater-license": "^1.0.0",
"webpack": "^2.6.1",
"webpack-dev-server": "^2.4.5",
"cpy-cli": "^1.0.1",
"npm-run-all": "^4.1.2",
"gh-pages": "^1.0.0",
"rimraf": "^2.6.2"
"webpack-dev-server": "^2.4.5"
},

@@ -51,3 +53,5 @@ "peerDependencies": {

},
"dependencies": {}
"dependencies": {
"cose-base": "^1.0.0"
}
}

@@ -8,3 +8,4 @@ cytoscape-cose-bilkent

The CoSE layout for Cytoscape.js by the [i-Vis Lab](http://cs.bilkent.edu.tr/~ivis/) in Bilkent University ([demo](https://cytoscape.github.io/cytoscape.js-cose-bilkent/demo.html), [compound demo](https://cytoscape.github.io/cytoscape.js-cose-bilkent/demo-compound.html))
The CoSE (Compound Spring Embedder) layout for Cytoscape.js developed by [i-Vis Lab](http://cs.bilkent.edu.tr/~ivis/) in Bilkent University is a spring embedder layout with support for compound graphs (nested structures) and varying (non-uniform) node dimensions.
([demo](https://raw.githack.com/cytoscape/cytoscape.js-cose-bilkent/master/demo.html), [compound demo](https://raw.githack.com/cytoscape/cytoscape.js-cose-bilkent/master/demo-compound.html))

@@ -18,2 +19,3 @@ Please cite the following when using this layout:

* Cytoscape.js ^3.2.0
* cose-base ^1.0.0

@@ -71,2 +73,7 @@

},
// 'draft', 'default' or 'proof"
// - 'draft' fast cooling rate
// - 'default' moderate cooling rate
// - "proof" slow cooling rate
quality: 'default',
// Whether to include labels in node dimensions. Useful for avoiding label overlap

@@ -98,2 +105,4 @@ nodeDimensionsIncludeLabels: false,

animate: 'end',
// Duration for animate:end
animationDuration: 500,
// Amount of vertical space to put between degree zero nodes during tiling (can also be a function)

@@ -114,3 +123,7 @@ tilingPaddingVertical: 10,

*Note that this extension supports only relatively modern browsers. Browsers like IE require significant shimming, for example with [core-js](https://www.npmjs.com/package/core-js).*
*Note that while running Cytoscape.js in headless mode, stylingEnabled option of Cytoscape.js should be set as true because this extension considers node dimensions and some other styling properties.*
## Build targets

@@ -131,3 +144,3 @@

1. Build the extension : `npm run build`
1. Build the extension : `npm run build:release`
1. Commit the build : `git commit -am "Build for release"`

@@ -134,0 +147,0 @@ 1. Bump the version number and tag: `npm version major|minor|patch`

'use strict';
// registers the extension on a cytoscape lib ref
var getLayout = require('./Layout');
var LayoutConstants = require('cose-base').layoutBase.LayoutConstants;
var FDLayoutConstants = require('cose-base').layoutBase.FDLayoutConstants;
var CoSEConstants = require('cose-base').CoSEConstants;
var CoSELayout = require('cose-base').CoSELayout;
var CoSENode = require('cose-base').CoSENode;
var PointD = require('cose-base').layoutBase.PointD;
var DimensionD = require('cose-base').layoutBase.DimensionD;
var defaults = {
// Called on `layoutready`
ready: function () {
},
// Called on `layoutstop`
stop: function () {
},
// '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 (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(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 () {
// Thigs to perform after nodes are repositioned on screen
var afterReposition = function() {
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( cytoscape ){
var Layout = getLayout( cytoscape );
// var Layout = getLayout( cytoscape );
cytoscape('layout', 'cose-bilkent', Layout);
cytoscape('layout', 'cose-bilkent', _CoSELayout);
};

@@ -11,0 +384,0 @@

@@ -25,3 +25,10 @@ const path = require('path');

},
externals: PROD ? Object.keys( pkg.dependencies || {} ) : [],
externals: PROD ? {
'cose-base': {
commonjs2: 'cose-base',
commonjs: 'cose-base',
amd: 'cose-base',
root: 'coseBase'
}
} : {},
plugins: MIN ? [

@@ -28,0 +35,0 @@ new webpack.optimize.UglifyJsPlugin({

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

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