cytoscape = function ( options ){ // jshint ignore:line
// if no options specified, use default
if( options === undefined ){
options = {};
}
// create instance
if( is.plainObject( options ) ){
return new Core( options );
}
// allow for registration of extensions
else if( is.string( options ) ){
return extension.apply( extension, arguments );
}
}n/a
Stylesheet = function (){
if( !(this instanceof Stylesheet) ){
return new Stylesheet();
}
this.length = 0;
}n/a
animation = function ( target, opts, opts2 ){
if( !(this instanceof Animation) ){
return new Animation( target, opts, opts2 );
}
var _p = this._private = util.extend( {
duration: 1000
}, opts, opts2 );
_p.target = target;
_p.style = _p.style || _p.css;
_p.started = false;
_p.playing = false;
_p.hooked = false;
_p.applying = false;
_p.progress = 0;
_p.completes = [];
_p.frames = [];
if( _p.complete && is.fn( _p.complete ) ){
_p.completes.push( _p.complete );
}
// for future timeline/animations impl
this.length = 1;
this[0] = this;
}...
fnParams = util.extend( {}, defaults, fnParams );
return function delayAnimationImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animation( {
delay: time,
duration: time,
complete: complete
} );
};
}, // delay
...function apply() { [native code] }...
// this is just a wrapper alias of .on()
p.pon = p.promiseOn = function( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
...function BreadthFirstLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
function CircleLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
function ConcentricLayout( options ){
this.options = util.extend( {}, defaults, options );
}...
var maxNodeSize = 0;
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var value;
// calculate the node value
value = options.concentric( node );
nodeValues.push( {
value: value,
node: node
} );
// for style mapping
node._private.scratch.concentric = value;
...function CoseLayout( options ){
this.options = util.extend( {}, defaults, options );
this.options.layout = this;
}n/a
element = function ( cy, params, restore ){
var self = this;
restore = (restore === undefined || restore ? true : false);
if( cy === undefined || params === undefined || !is.core( cy ) ){
util.error( 'An element must have a core reference and parameters set' );
return;
}
var group = params.group;
// try to automatically infer the group if unspecified
if( group == null ){
if( params.data && params.data.source != null && params.data.target != null ){
group = 'edges';
} else {
group = 'nodes';
}
}
// validate group
if( group !== 'nodes' && group !== 'edges' ){
util.error( 'An element must be of type `nodes` or `edges`; you specified `' + group + '`' );
return;
}
// make the element array-like, just like a collection
this.length = 1;
this[0] = this;
// NOTE: when something is added here, add also to ele.json()
this._private = {
cy: cy,
single: true, // indicates this is an element
data: params.data || {}, // data object
position: params.position || {}, // (x, y) position pair
autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value
autoHeight: undefined,
listeners: [], // array of bound listeners
group: group, // string; 'nodes' or 'edges'
style: {}, // properties as set by the style
rstyle: {}, // properties for style sent from the renderer to the core
styleCxts: [], // applied style contexts from the styler
removed: true, // whether it's inside the vis; true if removed (set true here since we call restore)
selected: params.selected ? true : false, // whether it's selected
selectable: params.selectable === undefined ? true : ( params.selectable ? true : false ), // whether it's selectable
locked: params.locked ? true : false, // whether the element is locked (cannot be moved)
grabbed: false, // whether the element is grabbed by the mouse; renderer sets this privately
grabbable: params.grabbable === undefined ? true : ( params.grabbable ? true : false ), // whether the element can be grabbed
active: false, // whether the element is active from user interaction
classes: {}, // map ( className => true )
animation: { // object for currently-running animations
current: [],
queue: []
},
rscratch: {}, // object in which the renderer can store information
scratch: params.scratch || {}, // scratch objects
edges: [], // array of connected edges
children: [], // array of children
traversalCache: {} // cache of output of traversal functions
};
// renderedPosition overrides if specified
if( params.renderedPosition ){
var rpos = params.renderedPosition;
var pan = cy.pan();
var zoom = cy.zoom();
this._private.position = {
x: (rpos.x - pan.x) / zoom,
y: (rpos.y - pan.y) / zoom
};
}
if( is.string( params.classes ) ){
var classes = params.classes.split( /\s+/ );
for( var i = 0, l = classes.length; i < l; i++ ){
var cls = classes[ i ];
if( !cls || cls === '' ){ continue; }
self._private.classes[ cls ] = true;
}
}
if( params.style || params.css ){
cy.style().applyBypass( this, params.style || params.css );
}
if( restore === undefined || restore ){
this.restore();
}
}...
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
...event = function ( src, props ){
// Allow instantiation without the 'new' keyword
if( !(this instanceof Event) ){
return new Event( src, props );
}
// Event object
if( src && src.type ){
this.originalEvent = src;
this.type = src.type;
// Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = ( src.defaultPrevented ) ? returnTrue : returnFalse;
// Event type
} else {
this.type = src;
}
// Put explicitly provided properties onto the event object
if( props ){
// util.extend( this, props );
// more efficient to manually copy fields we use
this.type = props.type !== undefined ? props.type : this.type;
this.cy = props.cy;
this.target = props.target;
this.position = props.position;
this.renderedPosition = props.renderedPosition;
this.namespace = props.namespace;
this.layout = props.layout;
this.message = props.message;
}
// Create a timestamp if incoming event doesn't have one
this.timeStamp = src && src.timeStamp || Date.now();
}...
return function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
...function GridLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
function Heap( cmp ){
this.cmp = cmp != null ? cmp : defaultCmp;
this.nodes = [];
}n/a
index = function ( cy, elements, options ){
if( cy === undefined || !is.core( cy ) ){
util.error( 'A collection must have a reference to the core' );
return;
}
var ids = {};
var indexes = {};
var createdElements = false;
if( !elements ){
elements = [];
} else if( elements.length > 0 && is.plainObject( elements[0] ) && !is.element( elements[0] ) ){
createdElements = true;
// make elements from json and restore all at once later
var eles = [];
var elesIds = {};
for( var i = 0, l = elements.length; i < l; i++ ){
var json = elements[ i ];
if( json.data == null ){
json.data = {};
}
var data = json.data;
// make sure newly created elements have valid ids
if( data.id == null ){
data.id = idFactory.generate( cy, json );
} else if( cy.hasElementWithId( data.id ) || elesIds[ data.id ] ){
continue; // can't create element if prior id already exists
}
var ele = new Element( cy, json, false );
eles.push( ele );
elesIds[ data.id ] = true;
}
elements = eles;
}
this.length = 0;
for( var i = 0, l = elements.length; i < l; i++ ){
var element = elements[ i ];
if( !element ){ continue; }
var id = element._private.data.id;
if( !options || (options.unique && !ids[ id ] ) ){
ids[ id ] = element;
indexes[ id ] = this.length;
this[ this.length ] = element;
this.length++;
}
}
this._private = {
cy: cy,
ids: ids,
indexes: indexes
};
// restore the elements if we created them from json
if( createdElements ){
this.restore();
}
}n/a
function NullLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
function PresetLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
function RandomLayout( options ){
this.options = util.extend( {}, defaults, options );
}...
sizeLimit ){
// Stop condition
if( size <= sizeLimit ){
return remainingEdges;
}
// Choose an edge randomly
var edgeIndex = Math.floor( (Math.random() * remainingEdges.length) );
// Colapse graph based on edge
var newEdges = colapse( edgeIndex, metaNodeMap, remainingEdges );
return contractUntil( metaNodeMap,
newEdges,
size - 1,
...selector = function ( selector ){
if( !(this instanceof Selector) ){
return new Selector( selector );
}
var self = this;
self._private = {
selectorText: null,
invalid: true
};
// storage for parsed queries
var newQuery = function(){
return {
classes: [],
colonSelectors: [],
data: [],
group: null,
ids: [],
meta: [],
// fake selectors
collection: null, // a collection to match against
filter: null, // filter function
// these are defined in the upward direction rather than down (e.g. child)
// because we need to go up in Selector.filter()
parent: null, // parent query obj
ancestor: null, // ancestor query obj
subject: null, // defines subject in compound query (subject query obj; points to self if subject)
// use these only when subject has been defined
child: null,
descendant: null
};
};
if( !selector || ( is.string( selector ) && selector.match( /^\s*$/ ) ) ){
self.length = 0;
} else if( selector === '*' || selector === 'edge' || selector === 'node' ){
// make single, group-only selectors cheap to make and cheap to filter
self[0] = newQuery();
self[0].group = selector === '*' ? selector : selector + 's';
self[0].groupOnly = true;
self._private.invalid = false;
self._private.selectorText = selector;
self.length = 1;
} else if( is.elementOrCollection( selector ) ){
var collection = selector.collection();
self[0] = newQuery();
self[0].collection = collection;
self.length = 1;
} else if( is.fn( selector ) ){
self[0] = newQuery();
self[0].filter = selector;
self.length = 1;
} else if( is.string( selector ) ){
// the current subject in the query
var currentSubject = null;
// tokens in the query language
var tokens = {
metaChar: '[\\!\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]', // chars we need to
escape in var names, etc
comparatorOp: '=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=', // binary comparison op (used in data selectors)
boolOp: '\\?|\\!|\\^', // boolean (unary) operators (used in data selectors)
string: '"(?:\\\\"|[^"])*"' + '|' + "'(?:\\\\'|[^'])*'", // string literals (used in data selectors) -- doublequotes | singlequotes
number: util.regex.number, // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123
meta: 'degree|indegree|outdegree', // allowed metadata fields (i.e. allowed functions to use from Collection)
separator: '\\s*,\\s*', // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass
descendant: '\\s+',
child: '\\s+>\\s+',
subject: '\\$'
};
tokens.variable = '(?:[\\w-]|(?:\\\\' + tokens.metaChar + '))+'; // a variable name
tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number
tokens.className = tokens.variable; // a class name (follows variable conventions)
tokens.id = tokens.variable; // an element id (follows variable conventions)
// when a token like a variable has escaped meta characters, we need to clean the backslashes out
// so that values get compared properly in Selector.filter()
var cleanMetaChars = function( str ){
return str.replace( new RegExp( '\\\\(' + tokens.metaChar + ')', 'g' ), function( match, $1, offset, original ){
return $1;
} );
};
// add @ variants to comparatorOp
var ops = tokens.comparatorOp.split( '|' );
for( var i = 0; i < ops.length; i++ ){
var op = ops[ i ];
tokens.comparatorOp += '|@' + op;
}
// add ! variants to comparatorOp
var ops = tokens.comparatorOp.split( '|' );
for( var i = 0; i < ops.length; i++ ){
var op = ops[ i ];
if( op.indexOf( '!' ) >= 0 ){ continue; } // skip ops that explicitly contain !
if( op === '=' ){ continue; } // skip = b/c != is explicitly defined
tokens.comparatorOp += '|\\!' + op;
}
// NOTE: add new expression syntax here ......
for( var i = 0; i < json.length; i++ ){
var context = json[ i ];
var selector = context.selector;
var props = context.style || context.css;
var names = Object.keys( props );
style.selector( selector ); // apply selector
for( var j = 0; j < names.length; j++ ){
var name = names[j];
var value = props[ name ];
style.css( name, value ); // apply property
}
...stylesheet = function (){
if( !(this instanceof Stylesheet) ){
return new Stylesheet();
}
this.length = 0;
}n/a
use = function ( ext ){
var args = Array.prototype.slice.call( arguments, 1 ); // args to pass to ext
args.unshift( cytoscape ); // cytoscape is first arg to ext
ext.apply( null, args );
}n/a
Stylesheet = function (){
if( !(this instanceof Stylesheet) ){
return new Stylesheet();
}
this.length = 0;
}n/a
css = function ( name, value ){
var i = this.length - 1;
if( is.string( name ) ){
this[ i ].properties.push( {
name: name,
value: value
} );
} else if( is.plainObject( name ) ){
var map = name;
for( var j = 0; j < Style.properties.length; j++ ){
var prop = Style.properties[ j ];
var mapVal = map[ prop.name ];
if( mapVal === undefined ){ // also try camel case name
mapVal = map[ util.dash2camel( prop.name ) ];
}
if( mapVal !== undefined ){
var name = prop.name;
var value = mapVal;
this[ i ].properties.push( {
name: name,
value: value
} );
}
}
}
return this; // chaining
}...
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
},
show: function(){
this.css( 'display', 'element' );
return this; // chaining
},
hide: function(){
this.css( 'display', 'none' );
return this; // chaining
},
...generateStyle = function ( cy ){
var style = new Style( cy );
for( var i = 0; i < this.length; i++ ){
var context = this[ i ];
var selector = context.selector;
var props = context.properties;
style.selector( selector ); // apply selector
for( var j = 0; j < props.length; j++ ){
var prop = props[ j ];
style.css( prop.name, prop.value ); // apply property
}
}
return style;
}n/a
instanceString = function (){
return 'stylesheet';
}...
var typeofstr = typeof '';
var typeofobj = typeof {};
var typeoffn = typeof function(){};
var typeofhtmlele = typeof HTMLElement;
var instanceStr = function( obj ){
return obj && obj.instanceString && is.fn( obj.instanceString ) ? obj.instanceString
() : null;
};
var is = {
defined: function( obj ){
return obj != null; // not undefined or null
},
...selector = function ( selector ){
var i = this.length++;
this[ i ] = {
selector: selector,
properties: []
};
return this; // chaining
}...
for( var i = 0; i < json.length; i++ ){
var context = json[ i ];
var selector = context.selector;
var props = context.style || context.css;
var names = Object.keys( props );
style.selector( selector ); // apply selector
for( var j = 0; j < names.length; j++ ){
var name = names[j];
var value = props[ name ];
style.css( name, value ); // apply property
}
...style = function ( name, value ){
var i = this.length - 1;
if( is.string( name ) ){
this[ i ].properties.push( {
name: name,
value: value
} );
} else if( is.plainObject( name ) ){
var map = name;
for( var j = 0; j < Style.properties.length; j++ ){
var prop = Style.properties[ j ];
var mapVal = map[ prop.name ];
if( mapVal === undefined ){ // also try camel case name
mapVal = map[ util.dash2camel( prop.name ) ];
}
if( mapVal !== undefined ){
var name = prop.name;
var value = mapVal;
this[ i ].properties.push( {
name: name,
value: value
} );
}
}
}
return this; // chaining
}...
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
var isCore = !selfIsArrayLike;
var isEles = !isCore;
if( !cy.styleEnabled() ){ return this; }
var style = cy.style();
properties = util.extend( {}, properties, params );
if( properties.duration === undefined ){
properties.duration = 400;
}
...aStar = function ( options ){
var eles = this;
options = options || {};
// Reconstructs the path from Start to End, acumulating the result in pathAcum
var reconstructPath = function( start, end, cameFromMap, pathAcum ){
// Base case
if( start == end ){
pathAcum.push( cy.getElementById( end ) );
return pathAcum;
}
if( end in cameFromMap ){
// We know which node is before the last one
var previous = cameFromMap[ end ];
var previousEdge = cameFromEdge[ end ];
pathAcum.push( cy.getElementById( end ) );
pathAcum.push( cy.getElementById( previousEdge ) );
return reconstructPath( start,
previous,
cameFromMap,
pathAcum );
}
// We should not reach here!
return undefined;
};
// Returns the index of the element in openSet which has minimum fScore
var findMin = function( openSet, fScore ){
if( openSet.length === 0 ){
// Should never be the case
return undefined;
}
var minPos = 0;
var tempScore = fScore[ openSet[0] ];
for( var i = 1; i < openSet.length; i++ ){
var s = fScore[ openSet[ i ] ];
if( s < tempScore ){
tempScore = s;
minPos = i;
}
}
return minPos;
};
var cy = this._private.cy;
// root - mandatory!
if( options != null && options.root != null ){
var source = is.string( options.root ) ?
// use it as a selector, e.g. "#rootID
this.filter( options.root )[0] :
options.root[0];
} else {
return undefined;
}
// goal - mandatory!
if( options.goal != null ){
var target = is.string( options.goal ) ?
// use it as a selector, e.g. "#goalID
this.filter( options.goal )[0] :
options.goal[0];
} else {
return undefined;
}
// Heuristic function - optional
if( options.heuristic != null && is.fn( options.heuristic ) ){
var heuristic = options.heuristic;
} else {
var heuristic = function(){ return 0; }; // use constant if unspecified
}
// Weight function - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var closedSet = [];
var openSet = [ source.id() ];
var cameFrom = {};
var cameFromEdge = {};
var gScore = {};
var fScore = {};
gScore[ source.id() ] = 0;
fScore[ source.id() ] = heuristic( source );
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
// Counter
var steps = 0;
// Main loop
while( openSet.length > 0 ){
var minPos = findMin( openSet, fScore );
var cMin = cy.getElementById( openSet[ minPos ] );
steps++;
// If we've found our goal, then we are done
if( cMin.id() == target.id() ){
var rPath = reconstructPath( source.id(), target.id(), cameFrom, [] );
rPath.reverse();
return {
found: true,
distance: gScore[ cMin.id() ],
path: eles.spawn( rPath ),
steps: steps
};
}
// Add cMin to processed nodes
closedSet.push( cMin.id() );
// Remove cMin from boundary nodes
openSet.splice( minPos, 1 );
// Update scores for neighbors of cMin
// Take into account if graph is directed or not
var vwEdges = cMin.connectedEdges();
if( directed ){ vwEdges = vwEdges.stdFilter( function( ele ){ return ele.data( 'source' ) === cMin.id(); } ); }
vwEdges = vwEdges.intersect( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes().stdFilter( function( n ){ return n.id() !== cMin.id(); } ).intersect( nodes );
// if node is in closedSet, ignore it
if( closedSet.indexOf( w.id() ) != -1 ){
continue;
}
// New tentative score for node w
var tempScore = gS ...n/a
add = function ( opts ){
var elements;
var cy = this;
// add the elements
if( is.elementOrCollection( opts ) ){
var eles = opts;
if( eles._private.cy === cy ){ // same instance => just restore
elements = eles.restore();
} else { // otherwise, copy from json
var jsons = [];
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
jsons.push( ele.json() );
}
elements = new Collection( cy, jsons );
}
}
// specify an array of options
else if( is.array( opts ) ){
var jsons = opts;
elements = new Collection( cy, jsons );
}
// specify via opts.nodes and opts.edges
else if( is.plainObject( opts ) && (is.array( opts.nodes ) || is.array( opts.edges )) ){
var elesByGroup = opts;
var jsons = [];
var grs = [ 'nodes', 'edges' ];
for( var i = 0, il = grs.length; i < il; i++ ){
var group = grs[ i ];
var elesArray = elesByGroup[ group ];
if( is.array( elesArray ) ){
for( var j = 0, jl = elesArray.length; j < jl; j++ ){
var json = util.extend( { group: group }, elesArray[ j ] );
jsons.push( json );
}
}
}
elements = new Collection( cy, jsons );
}
// specify options for one element
else {
var json = opts;
elements = (new Element( cy, json )).collection();
}
return elements;
}...
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
...remove = function ( collection ){
if( is.elementOrCollection( collection ) ){
// already have right ref
} else if( is.string( collection ) ){
var selector = collection;
collection = this.$( selector );
}
return collection.remove();
}...
var tgtId = struct.target;
var srcExists = cy.hasElementWithId( srcId );
var tgtExists = cy.hasElementWithId( tgtId );
if( srcExists || tgtExists ){
var jsons = this.jsons();
this.remove();
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
if( json.group === 'edges' ){
if( srcExists ){ json.data.source = srcId; }
...animation = function ( target, opts, opts2 ){
if( !(this instanceof Animation) ){
return new Animation( target, opts, opts2 );
}
var _p = this._private = util.extend( {
duration: 1000
}, opts, opts2 );
_p.target = target;
_p.style = _p.style || _p.css;
_p.started = false;
_p.playing = false;
_p.hooked = false;
_p.applying = false;
_p.progress = 0;
_p.completes = [];
_p.frames = [];
if( _p.complete && is.fn( _p.complete ) ){
_p.completes.push( _p.complete );
}
// for future timeline/animations impl
this.length = 1;
this[0] = this;
}...
fnParams = util.extend( {}, defaults, fnParams );
return function delayAnimationImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animation( {
delay: time,
duration: time,
complete: complete
} );
};
}, // delay
...apply = function (){
var _p = this._private;
_p.applying = true;
_p.started = false; // needs to be started by animation loop
_p.stopped = false;
this.hook();
// the animation loop will apply the animation at this progress
return this;
}...
// this is just a wrapper alias of .on()
p.pon = p.promiseOn = function( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
...applying = function (){
return this._private.applying;
}n/a
complete = function (){
return this._private.progress === 1;
}n/a
completed = function (){
return this._private.progress === 1;
}n/a
fastforward = function (){
return this.progress( 1 );
}n/a
hook = function (){
var _p = this._private;
if( !_p.hooked ){
// add to target's animation queue
var q;
var tAni = _p.target._private.animation;
if( _p.queue ){
q = tAni.queue;
} else {
q = tAni.current;
}
q.push( this );
// add to the animation loop pool
if( is.elementOrCollection( _p.target ) ){
_p.target.cy().addToAnimationPool( _p.target );
}
_p.hooked = true;
}
return this;
}...
_p.progress = 0;
}
_p.playing = true;
_p.started = false; // needs to be started by animation loop
_p.stopped = false;
this.hook();
// the animation loop will start the animation...
return this;
},
playing: function(){
...instanceString = function (){ return 'animation'; }...
var typeofstr = typeof '';
var typeofobj = typeof {};
var typeoffn = typeof function(){};
var typeofhtmlele = typeof HTMLElement;
var instanceStr = function( obj ){
return obj && obj.instanceString && is.fn( obj.instanceString ) ? obj.instanceString
() : null;
};
var is = {
defined: function( obj ){
return obj != null; // not undefined or null
},
...pause = function (){
var _p = this._private;
_p.playing = false;
_p.started = false;
return this;
}...
var _p = this._private;
var wasPlaying = _p.playing;
if( p === undefined ){
return _p.progress;
} else {
if( wasPlaying ){
this.pause();
}
_p.progress = p;
_p.started = false;
if( wasPlaying ){
this.play();
...play = function (){
var _p = this._private;
// autorewind
if( _p.progress === 1 ){
_p.progress = 0;
}
_p.playing = true;
_p.started = false; // needs to be started by animation loop
_p.stopped = false;
this.hook();
// the animation loop will start the animation...
return this;
}...
this.pause();
}
_p.progress = p;
_p.started = false;
if( wasPlaying ){
this.play();
}
}
return this;
},
completed: function(){
...playing = function (){
return this._private.playing;
}n/a
progress = function ( p ){
var _p = this._private;
var wasPlaying = _p.playing;
if( p === undefined ){
return _p.progress;
} else {
if( wasPlaying ){
this.pause();
}
_p.progress = p;
_p.started = false;
if( wasPlaying ){
this.play();
}
}
return this;
}...
_p.started = false;
_p.stopped = true; // to be removed from animation queues
return this;
},
rewind: function(){
return this.progress( 0 );
},
fastforward: function(){
return this.progress( 1 );
},
time: function( t ){
...promise = function ( type ){
var _p = this._private;
var arr;
switch( type ){
case 'frame':
arr = _p.frames;
break;
default:
case 'complete':
case 'completed':
arr = _p.completes;
}
return new Promise( function( resolve, reject ){
arr.push( function(){
resolve();
} );
} );
}...
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
return ani.promise();
}) ).then(function(){
cy.off('step.*', onStep);
if( options.zoom != null ){
cy.zoom( options.zoom );
}
...reverse = function (){
var _p = this._private;
var wasPlaying = _p.playing;
if( wasPlaying ){
this.pause();
}
_p.progress = 1 - _p.progress;
_p.started = false;
var swap = function( a, b ){
var _pa = _p[ a ];
_p[ a ] = _p[ b ];
_p[ b ] = _pa;
};
swap( 'zoom', 'startZoom' );
swap( 'pan', 'startPan' );
swap( 'position', 'startPosition' );
// swap styles
for( var i = 0; i < _p.style.length; i++ ){
var prop = _p.style[ i ];
var name = prop.name;
var startStyleProp = _p.startStyle[ name ];
_p.startStyle[ name ] = prop;
_p.style[ i ] = startStyleProp;
}
if( wasPlaying ){
this.play();
}
return this;
}...
if( cmp == null ){
cmp = defaultCmp;
}
_ref1 = (function(){
_results1 = [];
for( var _j = 0, _ref = floor( array.length / 2 ); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ :
_j-- ){ _results1.push( _j ); }
return _results1;
}).apply( this ).reverse();
_results = [];
for( _i = 0, _len = _ref1.length; _i < _len; _i++ ){
i = _ref1[ _i ];
_results.push( _siftup( array, i, cmp ) );
}
return _results;
};
...rewind = function (){
return this.progress( 0 );
}n/a
stop = function (){
var _p = this._private;
_p.playing = false;
_p.started = false;
_p.stopped = true; // to be removed from animation queues
return this;
}...
var opts = this.options;
if( opts && opts.animate ){
var anis = this.animations;
if( anis ){
for( var i = 0; i < anis.length; i++ ){
anis[ i ].stop();
}
}
}
if( regStop ){
regStop.call( this );
} else {
...time = function ( t ){
var _p = this._private;
if( t === undefined ){
return _p.progress * _p.duration;
} else {
return this.progress( t / _p.duration );
}
}n/a
apply = function ( eles ){
var self = this;
var _p = self._private;
if( _p.newStyle ){ // clear style caches
_p.contextStyles = {};
_p.propDiffs = {};
self.cleanElements( eles, true );
}
for( var ie = 0; ie < eles.length; ie++ ){
var ele = eles[ ie ];
var cxtMeta = self.getContextMeta( ele );
var cxtStyle = self.getContextStyle( cxtMeta );
var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );
self.updateTransitions( ele, app.diffProps );
self.updateStyleHints( ele );
} // for elements
_p.newStyle = false;
}...
// this is just a wrapper alias of .on()
p.pon = p.promiseOn = function( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
...applyContextStyle = function ( cxtMeta, cxtStyle, ele ){
var self = this;
var diffProps = cxtMeta.diffPropNames;
var retDiffProps = {};
for( var i = 0; i < diffProps.length; i++ ){
var diffPropName = diffProps[ i ];
var cxtProp = cxtStyle[ diffPropName ];
var eleProp = ele.pstyle( diffPropName );
if( !cxtProp ){ // no context prop means delete
if( !eleProp ){
continue; // no existing prop means nothing needs to be removed
// nb affects initial application on mapped values like control-point-distances
} else if( eleProp.bypass ){
cxtProp = { name: diffPropName, deleteBypassed: true };
} else {
cxtProp = { name: diffPropName, delete: true };
}
}
// save cycles when the context prop doesn't need to be applied
if( eleProp === cxtProp ){ continue; }
var retDiffProp = retDiffProps[ diffPropName ] = {
prev: eleProp
};
self.applyParsedProperty( ele, cxtProp );
retDiffProp.next = ele.pstyle( diffPropName );
if( retDiffProp.next && retDiffProp.next.bypass ){
retDiffProp.next = retDiffProp.next.bypassed;
}
}
return {
diffProps: retDiffProps
};
}...
}
for( var ie = 0; ie < eles.length; ie++ ){
var ele = eles[ ie ];
var cxtMeta = self.getContextMeta( ele );
var cxtStyle = self.getContextStyle( cxtMeta );
var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );
self.updateTransitions( ele, app.diffProps );
self.updateStyleHints( ele );
} // for elements
_p.newStyle = false;
...applyParsedProperty = function ( ele, parsedProp ){
var self = this;
var prop = parsedProp;
var style = ele._private.style;
var fieldVal, flatProp;
var types = self.types;
var type = self.properties[ prop.name ].type;
var propIsBypass = prop.bypass;
var origProp = style[ prop.name ];
var origPropIsBypass = origProp && origProp.bypass;
var _p = ele._private;
// edges connected to compound nodes can not be haystacks
if(
parsedProp.name === 'curve-style'
&& parsedProp.value === 'haystack'
&& ele.isEdge()
&& ( ele.isLoop() || ele.source().isParent() || ele.target().isParent() )
){
prop = parsedProp = this.parse( parsedProp.name, 'bezier', propIsBypass );
}
if( prop.delete ){ // delete the property and use the default value on falsey value
style[ prop.name ] = undefined;
return true;
}
if( prop.deleteBypassed ){ // delete the property that the
if( !origProp ){
return true; // can't delete if no prop
} else if( origProp.bypass ){ // delete bypassed
origProp.bypassed = undefined;
return true;
} else {
return false; // we're unsuccessful deleting the bypassed
}
}
// check if we need to delete the current bypass
if( prop.deleteBypass ){ // then this property is just here to indicate we need to delete
if( !origProp ){
return true; // property is already not defined
} else if( origProp.bypass ){ // then replace the bypass property with the original
// because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary
)
style[ prop.name ] = origProp.bypassed;
return true;
} else {
return false; // we're unsuccessful deleting the bypass
}
}
var printMappingErr = function(){
util.error( 'Do not assign mappings to elements without corresponding data (e.g. ele `' + ele.id() + '` for property `' + prop
.name + '` with data field `' + prop.field + '`); try a `[' + prop.field + ']` selector to limit scope to elements with `' + prop
.field + '` defined' );
};
// put the property in the style objects
switch( prop.mapped ){ // flatten the property if mapped
case types.mapData:
// flatten the field (e.g. data.foo.bar)
var fields = prop.field.split( '.' );
var fieldVal = _p.data;
for( var i = 0; i < fields.length && fieldVal; i++ ){
var field = fields[ i ];
fieldVal = fieldVal[ field ];
}
var percent;
if( !is.number( fieldVal ) ){ // then keep the mapping but assume 0% for now
percent = 0;
} else {
percent = (fieldVal - prop.fieldMin) / (prop.fieldMax - prop.fieldMin);
}
// make sure to bound percent value
if( percent < 0 ){
percent = 0;
} else if( percent > 1 ){
percent = 1;
}
if( type.color ){
var r1 = prop.valueMin[0];
var r2 = prop.valueMax[0];
var g1 = prop.valueMin[1];
var g2 = prop.valueMax[1];
var b1 = prop.valueMin[2];
var b2 = prop.valueMax[2];
var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3];
var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3];
var clr = [
Math.round( r1 + (r2 - r1) * percent ),
Math.round( g1 + (g2 - g1) * percent ),
Math.round( b1 + (b2 - b1) * percent ),
Math.round( a1 + (a2 - a1) * percent )
];
flatProp = { // colours are simple, so just create the flat property instead of expensive string parsing
bypass: prop.bypass, // we're a bypass if the mapping property is a bypass
name: prop.name,
value: clr,
strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')'
};
} else if( type.number ){
var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent;
flatProp = this.parse( prop.name, calcValue, prop.bypass, true );
} else {
return false; // can only map to colours and numbers
}
if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself
flatProp = this.p ......
// save cycles when the context prop doesn't need to be applied
if( eleProp === cxtProp ){ continue; }
var retDiffProp = retDiffProps[ diffPropName ] = {
prev: eleProp
};
self.applyParsedProperty( ele, cxtProp );
retDiffProp.next = ele.pstyle( diffPropName );
if( retDiffProp.next && retDiffProp.next.bypass ){
retDiffProp.next = retDiffProp.next.bypassed;
}
}
...cleanElements = function ( eles, keepBypasses ){
var self = this;
var props = self.properties;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[i];
if( !keepBypasses ){
ele._private.style = {};
} else {
var style = ele._private.style;
for( var j = 0; j < props.length; j++ ){
var prop = props[j];
var eleProp = style[ prop.name ];
if( eleProp ){
if( eleProp.bypass ){
eleProp.bypassed = null;
} else {
style[ prop.name ] = null;
}
}
}
}
}
}...
var self = this;
var _p = self._private;
if( _p.newStyle ){ // clear style caches
_p.contextStyles = {};
_p.propDiffs = {};
self.cleanElements( eles, true );
}
for( var ie = 0; ie < eles.length; ie++ ){
var ele = eles[ ie ];
var cxtMeta = self.getContextMeta( ele );
var cxtStyle = self.getContextStyle( cxtMeta );
...getContextMeta = function ( ele ){
var self = this;
var cxtKey = '';
var diffProps;
var prevKey = ele._private.styleCxtKey || '';
if( self._private.newStyle ){
prevKey = ''; // since we need to apply all style if a fresh stylesheet
}
// get the cxt key
for( var i = 0; i < self.length; i++ ){
var context = self[ i ];
var contextSelectorMatches = context.selector && context.selector.matches( ele ); // NB: context.selector may be null for 'core
'
if( contextSelectorMatches ){
cxtKey += 't';
} else {
cxtKey += 'f';
}
} // for context
diffProps = self.getPropertiesDiff( prevKey, cxtKey );
ele._private.styleCxtKey = cxtKey;
return {
key: cxtKey,
diffPropNames: diffProps
};
}...
self.cleanElements( eles, true );
}
for( var ie = 0; ie < eles.length; ie++ ){
var ele = eles[ ie ];
var cxtMeta = self.getContextMeta( ele );
var cxtStyle = self.getContextStyle( cxtMeta );
var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );
self.updateTransitions( ele, app.diffProps );
self.updateStyleHints( ele );
} // for elements
...getContextStyle = function ( cxtMeta ){
var cxtKey = cxtMeta.key;
var self = this;
var cxtStyles = this._private.contextStyles = this._private.contextStyles || {};
// if already computed style, returned cached copy
if( cxtStyles[ cxtKey ] ){ return cxtStyles[ cxtKey ]; }
var style = {
_private: {
key: cxtKey
}
};
for( var i = 0; i < self.length; i++ ){
var cxt = self[ i ];
var hasCxt = cxtKey[ i ] === 't';
if( !hasCxt ){ continue; }
for( var j = 0; j < cxt.properties.length; j++ ){
var prop = cxt.properties[ j ];
var styProp = style[ prop.name ] = prop;
styProp.context = cxt;
}
}
cxtStyles[ cxtKey ] = style;
return style;
}...
self.cleanElements( eles, true );
}
for( var ie = 0; ie < eles.length; ie++ ){
var ele = eles[ ie ];
var cxtMeta = self.getContextMeta( ele );
var cxtStyle = self.getContextStyle( cxtMeta );
var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );
self.updateTransitions( ele, app.diffProps );
self.updateStyleHints( ele );
} // for elements
...getPropertiesDiff = function ( oldCxtKey, newCxtKey ){
var self = this;
var cache = self._private.propDiffs = self._private.propDiffs || {};
var dualCxtKey = oldCxtKey + '-' + newCxtKey;
var cachedVal = cache[ dualCxtKey ];
if( cachedVal ){
return cachedVal;
}
var diffProps = [];
var addedProp = {};
for( var i = 0; i < self.length; i++ ){
var cxt = self[ i ];
var oldHasCxt = oldCxtKey[ i ] === 't';
var newHasCxt = newCxtKey[ i ] === 't';
var cxtHasDiffed = oldHasCxt !== newHasCxt;
var cxtHasMappedProps = cxt.mappedProperties.length > 0;
if( cxtHasDiffed || cxtHasMappedProps ){
var props;
if( cxtHasDiffed && cxtHasMappedProps ){
props = cxt.properties; // suffices b/c mappedProperties is a subset of properties
} else if( cxtHasDiffed ){
props = cxt.properties; // need to check them all
} else if( cxtHasMappedProps ){
props = cxt.mappedProperties; // only need to check mapped
}
for( var j = 0; j < props.length; j++ ){
var prop = props[ j ];
var name = prop.name;
// if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter
// (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result
// is cached)
var laterCxtOverrides = false;
for( var k = i + 1; k < self.length; k++ ){
var laterCxt = self[ k ];
var hasLaterCxt = newCxtKey[ k ] === 't';
if( !hasLaterCxt ){ continue; } // can't override unless the context is active
laterCxtOverrides = laterCxt.properties[ prop.name ] != null;
if( laterCxtOverrides ){ break; } // exit early as long as one later context overrides
}
if( !addedProp[ name ] && !laterCxtOverrides ){
addedProp[ name ] = true;
diffProps.push( name );
}
} // for props
} // if
} // for contexts
cache[ dualCxtKey ] = diffProps;
return diffProps;
}...
if( contextSelectorMatches ){
cxtKey += 't';
} else {
cxtKey += 'f';
}
} // for context
diffProps = self.getPropertiesDiff( prevKey, cxtKey );
ele._private.styleCxtKey = cxtKey;
return {
key: cxtKey,
diffPropNames: diffProps
};
...update = function (){
var cy = this._private.cy;
var eles = cy.mutableElements();
eles.updateStyle();
}n/a
updateMappers = function ( eles ){
var self = this;
for( var i = 0; i < eles.length; i++ ){ // for each ele
var ele = eles[ i ];
var style = ele._private.style;
for( var j = 0; j < self.properties.length; j++ ){ // for each prop
var prop = self.properties[ j ];
var propInStyle = style[ prop.name ];
if( propInStyle && propInStyle.mapping ){
var mapping = propInStyle.mapping;
this.applyParsedProperty( ele, mapping ); // reapply the mapping property
}
}
this.updateStyleHints( ele );
}
}...
updateMappers: function( notifyRenderer ){
var cy = this._private.cy;
var style = cy.style();
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( !cy.styleEnabled() ){ return this; }
style.updateMappers( this );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
if( notifyRenderer ){
toNotify.rtrigger( 'style' ); // let renderer know we changed style
} else {
...updateStyleHints = function (ele){
var _p = ele._private;
var self = this;
if( ele.removed() ){ return; }
// set whether has pie or not; for greater efficiency
var hasPie = false;
if( _p.group === 'nodes' ){
for( var i = 1; i <= self.pieBackgroundN; i++ ){ // 1..N
var size = ele.pstyle( 'pie-' + i + '-background-size' ).value;
if( size > 0 ){
hasPie = true;
break;
}
}
}
_p.hasPie = hasPie;
var transform = ele.pstyle( 'text-transform' ).strValue;
var content = ele.pstyle( 'label' ).strValue;
var srcContent = ele.pstyle( 'source-label' ).strValue;
var tgtContent = ele.pstyle( 'target-label' ).strValue;
var fStyle = ele.pstyle( 'font-style' ).strValue;
var size = ele.pstyle( 'font-size' ).pfValue + 'px';
var family = ele.pstyle( 'font-family' ).strValue;
// var variant = style['font-variant'].strValue;
var weight = ele.pstyle( 'font-weight' ).strValue;
var valign = ele.pstyle( 'text-valign' ).strValue;
var halign = ele.pstyle( 'text-valign' ).strValue;
var oWidth = ele.pstyle( 'text-outline-width' ).pfValue;
var wrap = ele.pstyle( 'text-wrap' ).strValue;
var wrapW = ele.pstyle( 'text-max-width' ).pfValue;
var labelStyleKey = fStyle + '$' + size + '$' + family + '$' + weight + '$' + transform + '$' + valign + '$' + halign + '$' +
oWidth + '$' + wrap + '$' + wrapW;
_p.labelStyleKey = labelStyleKey;
_p.sourceLabelKey = labelStyleKey + '$' + srcContent;
_p.targetLabelKey = labelStyleKey + '$' + tgtContent;
_p.labelKey = labelStyleKey + '$' + content;
_p.fontKey = fStyle + '$' + weight + '$' + size + '$' + family;
_p.styleKey = Date.now();
}...
var ele = eles[ ie ];
var cxtMeta = self.getContextMeta( ele );
var cxtStyle = self.getContextStyle( cxtMeta );
var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );
self.updateTransitions( ele, app.diffProps );
self.updateStyleHints( ele );
} // for elements
_p.newStyle = false;
};
styfn.getPropertiesDiff = function( oldCxtKey, newCxtKey ){
...updateTransitions = function ( ele, diffProps, isBypass ){
var self = this;
var _p = ele._private;
var props = ele.pstyle( 'transition-property' ).value;
var duration = ele.pstyle( 'transition-duration' ).pfValue;
var delay = ele.pstyle( 'transition-delay' ).pfValue;
if( props.length > 0 && duration > 0 ){
var css = {};
// build up the style to animate towards
var anyPrev = false;
for( var i = 0; i < props.length; i++ ){
var prop = props[ i ];
var styProp = ele.pstyle( prop );
var diffProp = diffProps[ prop ];
if( !diffProp ){ continue; }
var prevProp = diffProp.prev;
var fromProp = prevProp;
var toProp = diffProp.next != null ? diffProp.next : styProp;
var diff = false;
var initVal;
var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity)
if( !fromProp ){ continue; }
// consider px values
if( is.number( fromProp.pfValue ) && is.number( toProp.pfValue ) ){
diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy
initVal = fromProp.pfValue + initDt * diff;
// consider numerical values
} else if( is.number( fromProp.value ) && is.number( toProp.value ) ){
diff = toProp.value - fromProp.value; // nonzero is truthy
initVal = fromProp.value + initDt * diff;
// consider colour values
} else if( is.array( fromProp.value ) && is.array( toProp.value ) ){
diff = fromProp.value[0] !== toProp.value[0]
|| fromProp.value[1] !== toProp.value[1]
|| fromProp.value[2] !== toProp.value[2]
;
initVal = fromProp.strValue;
}
// the previous value is good for an animation only if it's different
if( diff ){
css[ prop ] = toProp.strValue; // to val
this.applyBypass( ele, prop, initVal ); // from val
anyPrev = true;
}
} // end if props allow ani
// can't transition if there's nothing previous to transition from
if( !anyPrev ){ return; }
_p.transitioning = true;
ele.stop();
if( delay > 0 ){
ele.delay( delay );
}
ele.animate( {
css: css
}, {
duration: duration,
easing: ele.pstyle( 'transition-timing-function' ).value,
queue: false,
complete: function(){
if( !isBypass ){
self.removeBypasses( ele, props );
}
_p.transitioning = false;
}
} );
} else if( _p.transitioning ){
ele.stop();
this.removeBypasses( ele, props );
_p.transitioning = false;
}
}...
for( var ie = 0; ie < eles.length; ie++ ){
var ele = eles[ ie ];
var cxtMeta = self.getContextMeta( ele );
var cxtStyle = self.getContextStyle( cxtMeta );
var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );
self.updateTransitions( ele, app.diffProps );
self.updateStyleHints( ele );
} // for elements
_p.newStyle = false;
};
...bellmanFord = function ( options ){
var eles = this;
options = options || {};
// Weight function - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
// root - mandatory!
if( options.root != null ){
if( is.string( options.root ) ){
// use it as a selector, e.g. "#rootID
var source = this.filter( options.root )[0];
} else {
var source = options.root[0];
}
} else {
return undefined;
}
var cy = this._private.cy;
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
// mapping: node id -> position in nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Initializations
var cost = [];
var predecessor = [];
var predEdge = [];
for( var i = 0; i < numNodes; i++ ){
if( nodes[ i ].id() === source.id() ){
cost[ i ] = 0;
} else {
cost[ i ] = Infinity;
}
predecessor[ i ] = undefined;
}
// Edges relaxation
var flag = false;
for( var i = 1; i < numNodes; i++ ){
flag = false;
for( var e = 0; e < edges.length; e++ ){
var sourceIndex = id2position[ edges[ e ].source().id() ];
var targetIndex = id2position[ edges[ e ].target().id() ];
var weight = weightFn( edges[ e ] );
var temp = cost[ sourceIndex ] + weight;
if( temp < cost[ targetIndex ] ){
cost[ targetIndex ] = temp;
predecessor[ targetIndex ] = sourceIndex;
predEdge[ targetIndex ] = edges[ e ];
flag = true;
}
// If undirected graph, we need to take into account the 'reverse' edge
if( !directed ){
var temp = cost[ targetIndex ] + weight;
if( temp < cost[ sourceIndex ] ){
cost[ sourceIndex ] = temp;
predecessor[ sourceIndex ] = targetIndex;
predEdge[ sourceIndex ] = edges[ e ];
flag = true;
}
}
}
if( !flag ){
break;
}
}
if( flag ){
// Check for negative weight cycles
for( var e = 0; e < edges.length; e++ ){
var sourceIndex = id2position[ edges[ e ].source().id() ];
var targetIndex = id2position[ edges[ e ].target().id() ];
var weight = weightFn( edges[ e ] );
if( cost[ sourceIndex ] + weight < cost[ targetIndex ] ){
util.error( 'Graph contains a negative weight cycle for Bellman-Ford' );
return { pathTo: undefined,
distanceTo: undefined,
hasNegativeWeightCycle: true};
}
}
}
// Build result object
var position2id = [];
for( var i = 0; i < numNodes; i++ ){
position2id.push( nodes[ i ].id() );
}
var res = {
distanceTo: function( to ){
if( is.string( to ) ){
// to is a selector string
var toId = (cy.filter( to )[0]).id();
} else {
// to is a node
var toId = to.id();
}
return cost[ id2position[ toId ] ];
},
pathTo: function( to ){
var reconstructPathAux = function( predecessor, fromPos, toPos, position2id, acumPath, predEdge ){
for( ;; ){
// Add toId to path
acumPath.push( cy.getElementById( position2id[ toPos ] ) );
acumPath.push( predEdge[ toPos ] );
if( fromPos === toPos ){
// reached starting node
return acumPath;
}
// If no path exists, discart acumulated path and return undefined
var predPos = predecessor[ toPos ];
if( typeof predPos === 'undefined' ){
return undefined;
}
toPos = predPos;
}
};
if( is.string( to ) ){
// to is a selector string
var toId = (cy.filter( to )[0]).id();
} else { ...n/a
bc = function ( options ){
options = options || {};
// Weight - optional
var weighted, weightFn;
if( is.fn( options.weight ) ){
weightFn = options.weight;
weighted = true;
} else {
weighted = false;
}
// Directed - default false
var directed = options.directed != null ? options.directed : false;
var cy = this._private.cy;
// starting
var V = this.nodes();
var A = {};
var _C = {};
var max = 0;
var C = {
set: function( key, val ){
_C[ key ] = val;
if( val > max ){ max = val; }
},
get: function( key ){ return _C[ key ]; }
};
// A contains the neighborhoods of every node
for( var i = 0; i < V.length; i++ ){
var v = V[ i ];
var vid = v.id();
if( directed ){
A[ vid ] = v.outgoers().nodes(); // get outgoers of every node
} else {
A[ vid ] = v.openNeighborhood().nodes(); // get neighbors of every node
}
C.set( vid, 0 );
}
for( var s = 0; s < V.length; s++ ){
var sid = V[s].id();
var S = []; // stack
var P = {};
var g = {};
var d = {};
var Q = new Heap(function( a, b ){
return d[a] - d[b];
}); // queue
// init dictionaries
for( var i = 0; i < V.length; i++ ){
var vid = V[ i ].id();
P[ vid ] = [];
g[ vid ] = 0;
d[ vid ] = Infinity;
}
g[ sid ] = 1; // sigma
d[ sid ] = 0; // distance to s
Q.push( sid );
while( !Q.empty() ){
var v = Q.pop();
S.push( v );
if( weighted ){
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j];
var vEle = cy.getElementById( v );
var edge;
if( vEle.edgesTo( w ).length > 0 ){
edge = vEle.edgesTo( w )[0];
} else {
edge = w.edgesTo( vEle )[0];
}
var edgeWeight = weightFn( edge );
w = w.id();
if( d[w] > d[v] + edgeWeight ){
d[w] = d[v] + edgeWeight;
if( Q.nodes.indexOf( w ) < 0 ){ //if w is not in Q
Q.push( w );
} else { // update position if w is in Q
Q.updateItem( w );
}
g[w] = 0;
P[w] = [];
}
if( d[w] == d[v] + edgeWeight ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
} else {
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j].id();
if( d[w] == Infinity ){
Q.push( w );
d[w] = d[v] + 1;
}
if( d[w] == d[v] + 1 ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
}
}
var e = {};
for( var i = 0; i < V.length; i++ ){
e[ V[ i ].id() ] = 0;
}
while( S.length > 0 ){
var w = S.pop();
for( var j = 0; j < P[w].length; j++ ){
var v = P[w][j];
e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]);
if( w != V[s].id() ){
C.set( w, C.get( w ) + e[w] );
}
}
}
}
var ret = {
betweenness: function( node ){
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node );
},
betweennessNormalized: function( node ){
if ( max == 0 )
return 0;
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node ) / max;
}
};
// alias
ret.betweennessNormalised = ret.betweennessNormalized;
return ret;
}n/a
betweennessCentrality = function ( options ){
options = options || {};
// Weight - optional
var weighted, weightFn;
if( is.fn( options.weight ) ){
weightFn = options.weight;
weighted = true;
} else {
weighted = false;
}
// Directed - default false
var directed = options.directed != null ? options.directed : false;
var cy = this._private.cy;
// starting
var V = this.nodes();
var A = {};
var _C = {};
var max = 0;
var C = {
set: function( key, val ){
_C[ key ] = val;
if( val > max ){ max = val; }
},
get: function( key ){ return _C[ key ]; }
};
// A contains the neighborhoods of every node
for( var i = 0; i < V.length; i++ ){
var v = V[ i ];
var vid = v.id();
if( directed ){
A[ vid ] = v.outgoers().nodes(); // get outgoers of every node
} else {
A[ vid ] = v.openNeighborhood().nodes(); // get neighbors of every node
}
C.set( vid, 0 );
}
for( var s = 0; s < V.length; s++ ){
var sid = V[s].id();
var S = []; // stack
var P = {};
var g = {};
var d = {};
var Q = new Heap(function( a, b ){
return d[a] - d[b];
}); // queue
// init dictionaries
for( var i = 0; i < V.length; i++ ){
var vid = V[ i ].id();
P[ vid ] = [];
g[ vid ] = 0;
d[ vid ] = Infinity;
}
g[ sid ] = 1; // sigma
d[ sid ] = 0; // distance to s
Q.push( sid );
while( !Q.empty() ){
var v = Q.pop();
S.push( v );
if( weighted ){
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j];
var vEle = cy.getElementById( v );
var edge;
if( vEle.edgesTo( w ).length > 0 ){
edge = vEle.edgesTo( w )[0];
} else {
edge = w.edgesTo( vEle )[0];
}
var edgeWeight = weightFn( edge );
w = w.id();
if( d[w] > d[v] + edgeWeight ){
d[w] = d[v] + edgeWeight;
if( Q.nodes.indexOf( w ) < 0 ){ //if w is not in Q
Q.push( w );
} else { // update position if w is in Q
Q.updateItem( w );
}
g[w] = 0;
P[w] = [];
}
if( d[w] == d[v] + edgeWeight ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
} else {
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j].id();
if( d[w] == Infinity ){
Q.push( w );
d[w] = d[v] + 1;
}
if( d[w] == d[v] + 1 ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
}
}
var e = {};
for( var i = 0; i < V.length; i++ ){
e[ V[ i ].id() ] = 0;
}
while( S.length > 0 ){
var w = S.pop();
for( var j = 0; j < P[w].length; j++ ){
var v = P[w][j];
e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]);
if( w != V[s].id() ){
C.set( w, C.get( w ) + e[w] );
}
}
}
}
var ret = {
betweenness: function( node ){
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node );
},
betweennessNormalized: function( node ){
if ( max == 0 )
return 0;
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node ) / max;
}
};
// alias
ret.betweennessNormalised = ret.betweennessNormalized;
return ret;
}n/a
function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}...
do {
var component = cy.collection();
components.push( component );
var root = unvisited[0];
visitInComponent( root, component );
self.bfs({
directed: false,
roots: root,
visit: function( v, e, u, i, depth ){
visitInComponent( v, component );
}
} );
...function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}n/a
function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}n/a
function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}n/a
function BreadthFirstLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
run = function (){
var params = this.options;
var options = params;
var cy = params.cy;
var eles = options.eles;
var nodes = eles.nodes().not( ':parent' );
var graph = eles;
var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} );
var roots;
if( is.elementOrCollection( options.roots ) ){
roots = options.roots;
} else if( is.array( options.roots ) ){
var rootsArray = [];
for( var i = 0; i < options.roots.length; i++ ){
var id = options.roots[ i ];
var ele = cy.getElementById( id );
rootsArray.push( ele );
}
roots = cy.collection( rootsArray );
} else if( is.string( options.roots ) ){
roots = cy.$( options.roots );
} else {
if( options.directed ){
roots = nodes.roots();
} else {
var components = [];
var unhandledNodes = nodes;
while( unhandledNodes.length > 0 ){
var currComp = cy.collection();
eles.bfs( {
roots: unhandledNodes[0],
visit: function( node, edge, pNode, i, depth ){
currComp = currComp.add( node );
},
directed: false
} );
unhandledNodes = unhandledNodes.not( currComp );
components.push( currComp );
}
roots = cy.collection();
for( var i = 0; i < components.length; i++ ){
var comp = components[ i ];
var maxDegree = comp.maxDegree( false );
var compRoots = comp.filter( function( ele ){
return ele.degree( false ) === maxDegree;
} );
roots = roots.add( compRoots );
}
}
}
var depths = [];
var foundByBfs = {};
var id2depth = {};
var prevNode = {};
var prevEdge = {};
var successors = {};
// find the depths of the nodes
graph.bfs( {
roots: roots,
directed: options.directed,
visit: function( node, edge, pNode, i, depth ){
var ele = node[0];
var id = ele.id();
if( !depths[ depth ] ){
depths[ depth ] = [];
}
depths[ depth ].push( ele );
foundByBfs[ id ] = true;
id2depth[ id ] = depth;
prevNode[ id ] = pNode;
prevEdge[ id ] = edge;
if( pNode ){
var prevId = pNode.id();
var succ = successors[ prevId ] = successors[ prevId ] || [];
succ.push( node );
}
}
} );
// check for nodes not found by bfs
var orphanNodes = [];
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
if( foundByBfs[ ele.id() ] ){
continue;
} else {
orphanNodes.push( ele );
}
}
// assign orphan nodes a depth from their neighborhood
var maxChecks = orphanNodes.length * 3;
var checks = 0;
while( orphanNodes.length !== 0 && checks < maxChecks ){
var node = orphanNodes.shift();
var neighbors = node.neighborhood().nodes();
var assignedDepth = false;
for( var i = 0; i < neighbors.length; i++ ){
var depth = id2depth[ neighbors[ i ].id() ];
if( depth !== undefined ){
depths[ depth ].push( node );
assignedDepth = true;
break;
}
}
if( !assignedDepth ){
orphanNodes.push( node );
}
checks++;
}
// assign orphan nodes that are still left to the depth of their subgraph
while( orphanNodes.length !== 0 ){
var node = orphanNodes.shift();
//var subgraph = graph.bfs( node ).path;
var assignedDepth = false;
// for( var i = 0; i < subgraph.length; i++ ){
// var depth = id2depth[ subgraph[i].id() ];
// if( depth !== undefined ){
// depths[depth].push( node );
// assignedDepth = true;
// break;
// }
// }
if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0
if( depths.length === 0 ){
depths.push( [] );
}
depths[0].push( node );
}
}
// assign the nodes a depth and index
var assignDepthsToEles = function(){
for( var i = 0; i < depths.length; i++ ){
var eles = depths[ i ];
for( var j = 0; j < ......
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...applyBypass = function ( eles, name, value, updateTransitions ){
var self = this;
var props = [];
var isBypass = true;
// put all the properties (can specify one or many) in an array after parsing them
if( name === '*' || name === '**' ){ // apply to all property names
if( value !== undefined ){
for( var i = 0; i < self.properties.length; i++ ){
var prop = self.properties[ i ];
var name = prop.name;
var parsedProp = this.parse( name, value, true );
if( parsedProp ){
props.push( parsedProp );
}
}
}
} else if( is.string( name ) ){ // then parse the single property
var parsedProp = this.parse( name, value, true );
if( parsedProp ){
props.push( parsedProp );
}
} else if( is.plainObject( name ) ){ // then parse each property
var specifiedProps = name;
updateTransitions = value;
for( var i = 0; i < self.properties.length; i++ ){
var prop = self.properties[ i ];
var name = prop.name;
var value = specifiedProps[ name ];
if( value === undefined ){ // try camel case name too
value = specifiedProps[ util.dash2camel( name ) ];
}
if( value !== undefined ){
var parsedProp = this.parse( name, value, true );
if( parsedProp ){
props.push( parsedProp );
}
}
}
} else { // can't do anything without well defined properties
return false;
}
// we've failed if there are no valid properties
if( props.length === 0 ){ return false; }
// now, apply the bypass properties on the elements
var ret = false; // return true if at least one succesful bypass applied
for( var i = 0; i < eles.length; i++ ){ // for each ele
var ele = eles[ i ];
var diffProps = {};
var diffProp;
for( var j = 0; j < props.length; j++ ){ // for each prop
var prop = props[ j ];
if( updateTransitions ){
var prevProp = ele.pstyle( prop.name );
diffProp = diffProps[ prop.name ] = { prev: prevProp };
}
ret = this.applyParsedProperty( ele, prop ) || ret;
if( updateTransitions ){
diffProp.next = ele.pstyle( prop.name );
}
} // for props
if( ret ){
this.updateStyleHints( ele );
}
if( updateTransitions ){
this.updateTransitions( ele, diffProps, isBypass );
}
} // for eles
return ret;
}...
if( !cls || cls === '' ){ continue; }
self._private.classes[ cls ] = true;
}
}
if( params.style || params.css ){
cy.style().applyBypass( this, params.style || params.css );
}
if( restore === undefined || restore ){
this.restore();
}
};
...overrideBypass = function ( eles, name, value ){
name = util.camel2dash( name );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var prop = ele._private.style[ name ];
var type = this.properties[ name ].type;
var isColor = type.color;
var isMulti = type.mutiple;
if( !prop || !prop.bypass ){ // need a bypass if one doesn't exist
this.applyBypass( ele, name, value );
continue;
}
prop.value = value;
if( prop.pfValue != null ){
prop.pfValue = value;
}
if( isColor ){
prop.strValue = 'rgb(' + value.join( ',' ) + ')';
} else if( isMulti ){
prop.strValue = value.join( ' ' );
} else {
prop.strValue = '' + value;
}
}
}n/a
removeAllBypasses = function ( eles, updateTransitions ){
return this.removeBypasses( eles, this.propertyNames, updateTransitions );
}...
var style = cy.style();
var eles = this;
if( names === undefined ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeAllBypasses( ele, updateTransitions );
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
...removeBypasses = function ( eles, props, updateTransitions ){
var isBypass = true;
for( var j = 0; j < eles.length; j++ ){
var ele = eles[ j ];
var diffProps = {};
for( var i = 0; i < props.length; i++ ){
var name = props[ i ];
var prop = this.properties[ name ];
var prevProp = ele.pstyle( prop.name );
if( !prevProp || !prevProp.bypass ){
// if a bypass doesn't exist for the prop, nothing needs to be removed
continue;
}
var value = ''; // empty => remove bypass
var parsedProp = this.parse( name, value, true );
var diffProp = diffProps[ prop.name ] = { prev: prevProp };
this.applyParsedProperty( ele, parsedProp );
diffProp.next = ele.pstyle( prop.name );
} // for props
this.updateStyleHints( ele );
if( updateTransitions ){
this.updateTransitions( ele, diffProps, isBypass );
}
} // for eles
}...
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeBypasses( ele, names, updateTransitions );
}
}
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
...function CircleLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
run = function (){
var params = this.options;
var options = params;
var cy = params.cy;
var eles = options.eles;
var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;
var nodes = eles.nodes().not( ':parent' );
if( options.sort ){
nodes = nodes.sort( options.sort );
}
var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} );
var center = {
x: bb.x1 + bb.w / 2,
y: bb.y1 + bb.h / 2
};
var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / nodes.length : options.sweep;
var dTheta = sweep / ( Math.max( 1, nodes.length - 1 ) );
var r;
var minDistance = 0;
for( var i = 0; i < nodes.length; i++ ){
var n = nodes[ i ];
var nbb = n.boundingBox();
var w = nbb.w;
var h = nbb.h;
minDistance = Math.max( minDistance, w, h );
}
if( is.number( options.radius ) ){
r = options.radius;
} else if( nodes.length <= 1 ){
r = 0;
} else {
r = Math.min( bb.h, bb.w ) / 2 - minDistance;
}
// calculate the radius
if( nodes.length > 1 && options.avoidOverlap ){ // but only if more than one node (can't overlap)
minDistance *= 1.75; // just to have some nice spacing
var dcos = Math.cos( dTheta ) - Math.cos( 0 );
var dsin = Math.sin( dTheta ) - Math.sin( 0 );
var rMin = Math.sqrt( minDistance * minDistance / ( dcos * dcos + dsin * dsin ) ); // s.t. no nodes overlapping
r = Math.max( rMin, r );
}
var getPos = function( ele, i ){
var theta = options.startAngle + i * dTheta * ( clockwise ? 1 : -1 );
var rx = r * Math.cos( theta );
var ry = r * Math.sin( theta );
var pos = {
x: center.x + rx,
y: center.y + ry
};
return pos;
};
nodes.layoutPositions( this, options, getPos );
return this; // chaining
}...
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...addClass = function ( classes ){
return this.toggleClass( classes, true );
}...
if( duration == null ){
duration = 250;
} else if( duration === 0 ){
return self; // nothing to do really
}
self.addClass( classes );
setTimeout( function(){
self.removeClass( classes );
}, duration );
return self;
}
});
...classes = function ( classes ){
classes = ( classes || '' ).match( /\S+/g ) || [];
var self = this;
var changed = [];
var classesMap = {};
// fill in classes map
for( var i = 0; i < classes.length; i++ ){
var cls = classes[ i ];
classesMap[ cls ] = true;
}
// check and update each ele
for( var j = 0; j < self.length; j++ ){
var ele = self[ j ];
var _p = ele._private;
var eleClasses = _p.classes;
var changedEle = false;
// check if ele has all of the passed classes
for( var i = 0; i < classes.length; i++ ){
var cls = classes[ i ];
var eleHasClass = eleClasses[ cls ];
if( !eleHasClass ){
changedEle = true;
break;
}
}
// check if ele has classes outside of those passed
if( !changedEle ){
var classes = Object.keys( eleClasses );
for( var i = 0; i < classes.length; i++ ){
var eleCls = classes[i];
var eleHasClass = eleClasses[ eleCls ];
var specdClass = classesMap[ eleCls ]; // i.e. this class is passed to the function
if( eleHasClass && !specdClass ){
changedEle = true;
break;
}
}
}
if( changedEle ){
_p.classes = util.copy( classesMap );
changed.push( ele );
}
}
// trigger update style on those eles that had class changes
if( changed.length > 0 ){
this.spawn( changed )
.updateStyle()
.trigger( 'class' )
;
}
return self;
}...
checkSwitch( 'selectable', 'selectify', 'unselectify' );
checkSwitch( 'locked', 'lock', 'unlock' );
checkSwitch( 'grabbable', 'grabify', 'ungrabify' );
if( obj.classes != null ){
ele.classes( obj.classes );
}
cy.endBatch();
return this;
} else if( obj === undefined ){ // get
...flashClass = function ( classes, duration ){
var self = this;
if( duration == null ){
duration = 250;
} else if( duration === 0 ){
return self; // nothing to do really
}
self.addClass( classes );
setTimeout( function(){
self.removeClass( classes );
}, duration );
return self;
}n/a
hasClass = function ( className ){
var ele = this[0];
return ( ele != null && ele._private.classes[ className ] ) ? true : false;
}...
if( !allIdsMatch ) return false;
// check classes
var allClassesMatch = true;
for( var k = 0; k < query.classes.length; k++ ){
var cls = query.classes[ k ];
allClassesMatch = allClassesMatch && ele.hasClass( cls );
if( !allClassesMatch ) break;
}
if( !allClassesMatch ) return false;
// generic checking for data/metadata
var operandsMatch = function( params ){
...removeClass = function ( classes ){
return this.toggleClass( classes, false );
}...
duration = 250;
} else if( duration === 0 ){
return self; // nothing to do really
}
self.addClass( classes );
setTimeout( function(){
self.removeClass( classes );
}, duration );
return self;
}
});
module.exports = elesfn;
...toggleClass = function ( classesStr, toggle ){
var classes = classesStr.match( /\S+/g ) || [];
var self = this;
var changed = []; // eles who had classes changed
for( var i = 0, il = self.length; i < il; i++ ){
var ele = self[ i ];
var changedEle = false;
for( var j = 0; j < classes.length; j++ ){
var cls = classes[ j ];
var eleClasses = ele._private.classes;
var hasClass = eleClasses[ cls ];
var shouldAdd = toggle || (toggle === undefined && !hasClass);
if( shouldAdd ){
eleClasses[ cls ] = true;
if( !hasClass && !changedEle ){
changed.push( ele );
changedEle = true;
}
} else { // then remove
eleClasses[ cls ] = false;
if( hasClass && !changedEle ){
changed.push( ele );
changedEle = true;
}
}
} // for j classes
} // for i eles
// trigger update style on those eles that had class changes
if( changed.length > 0 ){
this.spawn( changed )
.updateStyle()
.trigger( 'class' )
;
}
return self;
}...
;
}
return self;
},
addClass: function( classes ){
return this.toggleClass( classes, true );
},
hasClass: function( className ){
var ele = this[0];
return ( ele != null && ele._private.classes[ className ] ) ? true : false;
},
...cc = function ( options ){
options = options || {};
// root - mandatory!
if( options.root != null ){
if( is.string( options.root ) ){
// use it as a selector, e.g. "#rootID
var root = this.filter( options.root )[0];
} else {
var root = options.root[0];
}
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weight = options.weight;
} else {
var weight = function(){return 1;};
}
// directed - optional
if( options.directed != null && is.bool( options.directed ) ){
var directed = options.directed;
} else {
var directed = false;
}
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
// we need distance from this node to every other node
var dijkstra = this.dijkstra( {
root: root,
weight: weight,
directed: directed
} );
var totalDistance = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
if( nodes[ i ].id() != root.id() ){
var d = dijkstra.distanceTo( nodes[ i ] );
if( harmonic ){
totalDistance += 1 / d;
} else {
totalDistance += d;
}
}
}
return harmonic ? totalDistance : 1 / totalDistance;
}n/a
ccn = function ( options ){
options = options || {};
var cy = this.cy();
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
if( harmonic ){
currCloseness += 1 / d;
} else {
currCloseness += d;
}
}
}
if( !harmonic ){
currCloseness = 1 / currCloseness;
}
if( maxCloseness < currCloseness ){
maxCloseness = currCloseness;
}
closenesses[ nodes[ i ].id() ] = currCloseness;
}
return {
closeness: function( node ){
if( maxCloseness == 0 ){ return 0; }
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return closenesses[ node ] / maxCloseness;
}
};
}n/a
closenessCentrality = function ( options ){
options = options || {};
// root - mandatory!
if( options.root != null ){
if( is.string( options.root ) ){
// use it as a selector, e.g. "#rootID
var root = this.filter( options.root )[0];
} else {
var root = options.root[0];
}
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weight = options.weight;
} else {
var weight = function(){return 1;};
}
// directed - optional
if( options.directed != null && is.bool( options.directed ) ){
var directed = options.directed;
} else {
var directed = false;
}
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
// we need distance from this node to every other node
var dijkstra = this.dijkstra( {
root: root,
weight: weight,
directed: directed
} );
var totalDistance = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
if( nodes[ i ].id() != root.id() ){
var d = dijkstra.distanceTo( nodes[ i ] );
if( harmonic ){
totalDistance += 1 / d;
} else {
totalDistance += d;
}
}
}
return harmonic ? totalDistance : 1 / totalDistance;
}n/a
closenessCentralityNormalised = function ( options ){
options = options || {};
var cy = this.cy();
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
if( harmonic ){
currCloseness += 1 / d;
} else {
currCloseness += d;
}
}
}
if( !harmonic ){
currCloseness = 1 / currCloseness;
}
if( maxCloseness < currCloseness ){
maxCloseness = currCloseness;
}
closenesses[ nodes[ i ].id() ] = currCloseness;
}
return {
closeness: function( node ){
if( maxCloseness == 0 ){ return 0; }
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return closenesses[ node ] / maxCloseness;
}
};
}n/a
closenessCentralityNormalized = function ( options ){
options = options || {};
var cy = this.cy();
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
if( harmonic ){
currCloseness += 1 / d;
} else {
currCloseness += d;
}
}
}
if( !harmonic ){
currCloseness = 1 / currCloseness;
}
if( maxCloseness < currCloseness ){
maxCloseness = currCloseness;
}
closenesses[ nodes[ i ].id() ] = currCloseness;
}
return {
closeness: function( node ){
if( maxCloseness == 0 ){ return 0; }
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return closenesses[ node ] / maxCloseness;
}
};
}n/a
color2tuple = function ( color ){
return ( is.array( color ) ? color : null )
|| this.colorname2tuple( color )
|| this.hex2tuple( color )
|| this.rgb2tuple( color )
|| this.hsl2tuple( color );
}...
name: name,
value: props,
strValue: props.length === 0 ? 'none' : props.join( ', ' ),
bypass: propIsBypass
};
} else if( type.color ){
var tuple = util.color2tuple( value );
if( !tuple ){ return null; }
return {
name: name,
value: tuple,
strValue: '' + value,
...colorname2tuple = function ( color ){
return this.colors[ color.toLowerCase() ];
}...
colorname2tuple: function( color ){
return this.colors[ color.toLowerCase() ];
},
color2tuple: function( color ){
return ( is.array( color ) ? color : null )
|| this.colorname2tuple( color )
|| this.hex2tuple( color )
|| this.rgb2tuple( color )
|| this.hsl2tuple( color );
},
colors: {
// special colour names
...hex2tuple = function ( hex ){
if( !(hex.length === 4 || hex.length === 7) || hex[0] !== '#' ){ return; }
var shortHex = hex.length === 4;
var r, g, b;
var base = 16;
if( shortHex ){
r = parseInt( hex[1] + hex[1], base );
g = parseInt( hex[2] + hex[2], base );
b = parseInt( hex[3] + hex[3], base );
} else {
r = parseInt( hex[1] + hex[2], base );
g = parseInt( hex[3] + hex[4], base );
b = parseInt( hex[5] + hex[6], base );
}
return [ r, g, b ];
}...
colorname2tuple: function( color ){
return this.colors[ color.toLowerCase() ];
},
color2tuple: function( color ){
return ( is.array( color ) ? color : null )
|| this.colorname2tuple( color )
|| this.hex2tuple( color )
|| this.rgb2tuple( color )
|| this.hsl2tuple( color );
},
colors: {
// special colour names
transparent: [0, 0, 0, 0], // NB alpha === 0
...hsl2tuple = function ( hsl ){
var ret;
var h, s, l, a, r, g, b;
function hue2rgb( p, q, t ){
if( t < 0 ) t += 1;
if( t > 1 ) t -= 1;
if( t < 1 / 6 ) return p + (q - p) * 6 * t;
if( t < 1 / 2 ) return q;
if( t < 2 / 3 ) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
var m = new RegExp( '^' + this.regex.hsla + '$' ).exec( hsl );
if( m ){
// get hue
h = parseInt( m[1] );
if( h < 0 ){
h = ( 360 - (-1 * h % 360) ) % 360;
} else if( h > 360 ){
h = h % 360;
}
h /= 360; // normalise on [0, 1]
s = parseFloat( m[2] );
if( s < 0 || s > 100 ){ return; } // saturation is [0, 100]
s = s / 100; // normalise on [0, 1]
l = parseFloat( m[3] );
if( l < 0 || l > 100 ){ return; } // lightness is [0, 100]
l = l / 100; // normalise on [0, 1]
a = m[4];
if( a !== undefined ){
a = parseFloat( a );
if( a < 0 || a > 1 ){ return; } // alpha is [0, 1]
}
// now, convert to rgb
// code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
if( s === 0 ){
r = g = b = Math.round( l * 255 ); // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = Math.round( 255 * hue2rgb( p, q, h + 1 / 3 ) );
g = Math.round( 255 * hue2rgb( p, q, h ) );
b = Math.round( 255 * hue2rgb( p, q, h - 1 / 3 ) );
}
ret = [ r, g, b, a ];
}
return ret;
}...
},
color2tuple: function( color ){
return ( is.array( color ) ? color : null )
|| this.colorname2tuple( color )
|| this.hex2tuple( color )
|| this.rgb2tuple( color )
|| this.hsl2tuple( color );
},
colors: {
// special colour names
transparent: [0, 0, 0, 0], // NB alpha === 0
// regular colours
...rgb2tuple = function ( rgb ){
var ret;
var m = new RegExp( '^' + this.regex.rgba + '$' ).exec( rgb );
if( m ){
ret = [];
var isPct = [];
for( var i = 1; i <= 3; i++ ){
var channel = m[ i ];
if( channel[ channel.length - 1 ] === '%' ){
isPct[ i ] = true;
}
channel = parseFloat( channel );
if( isPct[ i ] ){
channel = channel / 100 * 255; // normalise to [0, 255]
}
if( channel < 0 || channel > 255 ){ return; } // invalid channel value
ret.push( Math.floor( channel ) );
}
var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3];
var allArePct = isPct[1] && isPct[2] && isPct[3];
if( atLeastOneIsPct && !allArePct ){ return; } // must all be percent values if one is
var alpha = m[4];
if( alpha !== undefined ){
alpha = parseFloat( alpha );
if( alpha < 0 || alpha > 1 ){ return; } // invalid alpha value
ret.push( alpha );
}
}
return ret;
}...
return this.colors[ color.toLowerCase() ];
},
color2tuple: function( color ){
return ( is.array( color ) ? color : null )
|| this.colorname2tuple( color )
|| this.hex2tuple( color )
|| this.rgb2tuple( color )
|| this.hsl2tuple( color );
},
colors: {
// special colour names
transparent: [0, 0, 0, 0], // NB alpha === 0
...allAre = function ( selector ){
return this.filter( selector ).length === this.length;
}n/a
allAreNeighbors = function ( collection ){
collection = this.cy().collection( collection );
return this.neighborhood().intersect( collection ).length === collection.length;
}n/a
allAreNeighbours = function ( collection ){
collection = this.cy().collection( collection );
return this.neighborhood().intersect( collection ).length === collection.length;
}n/a
anySame = function ( collection ){
collection = this.cy().collection( collection );
return this.intersect( collection ).length > 0;
}...
}
} );
} while( unvisited.length > 0 );
return components.map(function( component ){
var connectedEdges = component.connectedEdges().stdFilter(function( edge ){
return component.anySame( edge.source() ) && component.anySame( edge
.target() );
});
return component.union( connectedEdges );
});
}
} );
...every = function ( fn, thisArg ){
for( var i = 0; i < this.length; i++ ){
var ret = !thisArg ? fn( this[ i ], i, this ) : fn.apply( thisArg, [ this[ i ], i, this ] );
if( !ret ){
return false;
}
}
return true;
}n/a
is = function ( selector ){
return this.filter( selector ).length > 0;
}n/a
same = function ( collection ){
collection = this.cy().collection( collection );
// cheap extra check
if( this.length !== collection.length ){
return false;
}
return this.intersect( collection ).length === this.length;
}...
return;
}
};
}
util.extend( elesfn, {
degree: defineDegreeFunction( function( node, edge ){
if( edge.source().same( edge.target() ) ){
return 2;
} else {
return 1;
}
} ),
indegree: defineDegreeFunction( function( node, edge ){
...some = function ( fn, thisArg ){
for( var i = 0; i < this.length; i++ ){
var ret = !thisArg ? fn( this[ i ], i, this ) : fn.apply( thisArg, [ this[ i ], i, this ] );
if( ret ){
return true;
}
}
return false;
}n/a
ancestors = function ( selector ){
var parents = [];
var eles = this.parent();
while( eles.nonempty() ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
parents.push( ele );
}
eles = eles.parent();
}
return this.spawn( parents, { unique: true } ).filter( selector );
}n/a
children = function ( selector ){
var children = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
children = children.concat( ele._private.children );
}
return this.spawn( children, { unique: true } ).filter( selector );
}...
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
case ':unanimated':
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
...commonAncestors = function ( selector ){
var ancestors;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parents = ele.parents();
ancestors = ancestors || parents;
ancestors = ancestors.intersect( parents ); // current list must be common with current ele parents set
}
return ancestors.filter( selector );
}n/a
descendants = function ( selector ){
var elements = [];
function add( eles ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
elements.push( ele );
if( ele.children().nonempty() ){
add( ele.children() );
}
}
}
add( this.children() );
return this.spawn( elements, { unique: true } ).filter( selector );
}...
} ) ){ return false; }
if( !confirmRelations( query.child, function(){
return ele.children();
} ) ){ return false; }
if( !confirmRelations( query.descendant, function(){
return ele.descendants();
} ) ){ return false; }
// we've reached the end, so we've matched everything for this query
return true;
}; // queryMatches
// filter an existing collection
...isChild = function (){
var ele = this[0];
if( ele ){
return ele._private.data.parent !== undefined && ele.parent().length !== 0;
}
}n/a
isParent = function (){
var ele = this[0];
if( ele ){
return ele._private.children.length !== 0;
}
}...
allowGetting: true,
validKeys: [ 'x', 'y' ],
onSet: function( eles ){
var updatedEles = eles.updateCompoundBounds();
updatedEles.rtrigger( 'position' );
},
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
// position but no notification to renderer
silentPosition: define.data( {
field: 'position',
bindingEvent: 'position',
...nonorphans = function ( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().nonempty();
} ).filter( selector );
}n/a
orphans = function ( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().empty();
} ).filter( selector );
}n/a
parent = function ( selector ){
var parents = [];
var cy = this._private.cy;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parent = cy.getElementById( ele._private.data.parent );
if( parent.size() > 0 ){
parents.push( parent );
}
}
return this.spawn( parents, { unique: true } ).filter( selector );
}...
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
break;
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) === ele.data( 'target' );
break;
...parents = function ( selector ){
var parents = [];
var eles = this.parent();
while( eles.nonempty() ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
parents.push( ele );
}
eles = eles.parent();
}
return this.spawn( parents, { unique: true } ).filter( selector );
}...
};
if( !confirmRelations( query.parent, function(){
return ele.parent();
} ) ){ return false; }
if( !confirmRelations( query.ancestor, function(){
return ele.parents();
} ) ){ return false; }
if( !confirmRelations( query.child, function(){
return ele.children();
} ) ){ return false; }
if( !confirmRelations( query.descendant, function(){
...siblings = function ( selector ){
return this.parent().children().not( this ).filter( selector );
}n/a
function ConcentricLayout( options ){
this.options = util.extend( {}, defaults, options );
}...
var maxNodeSize = 0;
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var value;
// calculate the node value
value = options.concentric( node );
nodeValues.push( {
value: value,
node: node
} );
// for style mapping
node._private.scratch.concentric = value;
...run = function (){
var params = this.options;
var options = params;
var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;
var cy = params.cy;
var eles = options.eles;
var nodes = eles.nodes().not( ':parent' );
var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} );
var center = {
x: bb.x1 + bb.w / 2,
y: bb.y1 + bb.h / 2
};
var nodeValues = []; // { node, value }
var theta = options.startAngle;
var maxNodeSize = 0;
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var value;
// calculate the node value
value = options.concentric( node );
nodeValues.push( {
value: value,
node: node
} );
// for style mapping
node._private.scratch.concentric = value;
}
// in case we used the `concentric` in style
nodes.updateStyle();
// calculate max size now based on potentially updated mappers
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var nbb = node.boundingBox();
maxNodeSize = Math.max( maxNodeSize, nbb.w, nbb.h );
}
// sort node values in descreasing order
nodeValues.sort( function( a, b ){
return b.value - a.value;
} );
var levelWidth = options.levelWidth( nodes );
// put the values into levels
var levels = [ [] ];
var currentLevel = levels[0];
for( var i = 0; i < nodeValues.length; i++ ){
var val = nodeValues[ i ];
if( currentLevel.length > 0 ){
var diff = Math.abs( currentLevel[0].value - val.value );
if( diff >= levelWidth ){
currentLevel = [];
levels.push( currentLevel );
}
}
currentLevel.push( val );
}
// create positions from levels
var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes
if( !options.avoidOverlap ){ // then strictly constrain to bb
var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1;
var maxR = ( Math.min( bb.w, bb.h ) / 2 - minDist );
var rStep = maxR / ( levels.length + firstLvlHasMulti ? 1 : 0 );
minDist = Math.min( minDist, rStep );
}
// find the metrics for each level
var r = 0;
for( var i = 0; i < levels.length; i++ ){
var level = levels[ i ];
var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / level.length : options.sweep;
var dTheta = level.dTheta = sweep / ( Math.max( 1, level.length - 1 ) );
// calculate the radius
if( level.length > 1 && options.avoidOverlap ){ // but only if more than one node (can't overlap)
var dcos = Math.cos( dTheta ) - Math.cos( 0 );
var dsin = Math.sin( dTheta ) - Math.sin( 0 );
var rMin = Math.sqrt( minDist * minDist / ( dcos * dcos + dsin * dsin ) ); // s.t. no nodes overlapping
r = Math.max( rMin, r );
}
level.r = r;
r += minDist;
}
if( options.equidistant ){
var rDeltaMax = 0;
var r = 0;
for( var i = 0; i < levels.length; i++ ){
var level = levels[ i ];
var rDelta = level.r - r;
rDeltaMax = Math.max( rDeltaMax, rDelta );
}
r = 0;
for( var i = 0; i < levels.length; i++ ){
var level = levels[ i ];
if( i === 0 ){
r = level.r;
}
level.r = r;
r += rDeltaMax;
}
}
// calculate the node positions
var pos = {}; // id => position
for( var i = 0; i < levels.length; i++ ){
var level = levels[ i ];
var dTheta = level.dTheta;
var r = level.r;
for( var j = 0; j < level.length; j++ ){
var val = level[ j ];
var theta = options.startAngle + (clockwise ? 1 : -1) * dTheta * j;
var p = {
x: center.x + r * Math.cos( theta ),
y: center.y + r * Math.sin( theta )
};
pos[ val.node.id() ] = p;
}
}
// position the nodes
nodes.layoutPositions( this, options, function( ele ){
var id = ele.id();
return pos[ id ];
} );
return this; // chaining
}...
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...containerCss = function ( propName ){
var cy = this._private.cy;
var domElement = cy.container();
if( window && domElement && window.getComputedStyle ){
return window.getComputedStyle( domElement ).getPropertyValue( propName );
}
}...
var window = require( '../window' );
var styfn = {};
// gets what an em size corresponds to in pixels relative to a dom element
styfn.getEmSizeInPixels = function(){
var px = this.containerCss( 'font-size' );
if( px != null ){
return parseFloat( px );
} else {
return 1; // for headless
}
};
...getEmSizeInPixels = function (){
var px = this.containerCss( 'font-size' );
if( px != null ){
return parseFloat( px );
} else {
return 1; // for headless
}
}...
bypass: propIsBypass
};
// normalise value in pixels
if( type.unitless || (units !== 'px' && units !== 'em') ){
ret.pfValue = value;
} else {
ret.pfValue = ( units === 'px' || !units ? (value) : (this.getEmSizeInPixels() * value) );
}
// normalise value in ms
if( units === 'ms' || units === 's' ){
ret.pfValue = units === 'ms' ? value : 1000 * value;
}
...function CoseLayout( options ){
this.options = util.extend( {}, defaults, options );
this.options.layout = this;
}n/a
destroy = function (){
if( this.thread ){
this.thread.stop();
}
return this; // chaining
}n/a
run = function (){
var options = this.options;
var cy = options.cy;
var layout = this;
var thread = this.thread;
var Thread = options.weaver ? options.weaver.Thread : null;
var falseThread = { // use false thread as polyfill
listeners: [],
on: function(e, cb){
this.listeners.push({ event: e, callback: cb });
return this;
},
trigger: function(e){
if( is.string(e) ){
e = { type: e };
}
var matchesEvent = function( l ){ return l.event === e.type; };
var trigger = function( l ){ l.callback(e); };
this.listeners.filter( matchesEvent ).forEach( trigger );
return this;
},
pass: function( data ){
this.pass = data;
return this;
},
run: function( cb ){
var pass = this.pass;
return new Promise(function( resolve ){
resolve( cb( pass ) );
});
},
stop: function(){
return this;
}
};
function broadcast( message ){ // for false thread
var e = { type: 'message', message: message };
falseThread.trigger( e );
}
if( !thread || thread.stopped() ){
thread = this.thread = Thread ? new Thread() : falseThread;
}
layout.stopped = false;
layout.trigger( { type: 'layoutstart', layout: layout } );
// Set DEBUG - Global variable
if( true === options.debug ){
DEBUG = true;
} else {
DEBUG = false;
}
// Initialize layout info
var layoutInfo = createLayoutInfo( cy, layout, options );
// Show LayoutInfo contents if debugging
if( DEBUG ){
printLayoutInfo( layoutInfo );
}
// If required, randomize node positions
if (options.randomize) {
randomizePositions( layoutInfo, cy );
}
var startTime = Date.now();
var refreshRequested = false;
var refresh = function( rOpts ){
rOpts = rOpts || {};
if( refreshRequested && !rOpts.next ){
return;
}
if( !rOpts.force && Date.now() - startTime < options.animationThreshold ){
return;
}
refreshRequested = true;
util.requestAnimationFrame( function(){
refreshPositions( layoutInfo, cy, options );
// Fit the graph if necessary
if( true === options.fit ){
cy.fit( options.padding );
}
refreshRequested = false;
if( rOpts.next ){ rOpts.next(); }
});
};
thread.on( 'message', function( e ){
var layoutNodes = e.message;
layoutInfo.layoutNodes = layoutNodes;
refresh();
} );
thread.pass( {
layoutInfo: layoutInfo,
options: {
animate: options.animate,
refresh: options.refresh,
componentSpacing: options.componentSpacing,
nodeOverlap: options.nodeOverlap,
nestingFactor: options.nestingFactor,
gravity: options.gravity,
numIter: options.numIter,
initialTemp: options.initialTemp,
coolingFactor: options.coolingFactor,
minTemp: options.minTemp
}
} ).run( function( pass ){
var layoutInfo = pass.layoutInfo;
var options = pass.options;
var stopped = false;
/**
* @brief : Performs one iteration of the physical simulation
* @arg layoutInfo : LayoutInfo object already initialized
* @arg cy : Cytoscape object
* @arg options : Layout options
*/
var step = function( layoutInfo, options, step ){
// var s = "\n\n###############################";
// s += "\nSTEP: " + step;
// s += "\n###############################\n";
// logDebug(s);
// Calculate node repulsions
calculateNodeForces( layoutInfo, options );
// Calculate edge forces
calculateEdgeForces( layoutInfo, options );
// Calculate gravity forces
calculateGravityForces( layoutInfo, options );
// Propagate forces from parent to child
propagateForces( layoutInfo, options );
// Update positions based on calculated forces
updatePositions( layoutInfo, options );
};
/**
* @brief : Computes the node repulsion forces
*/
var calculateNodeForces = function( layoutInfo, options ){
// Go through each of the gr ......
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...stop = function (){
this.stopped = true;
if( this.thread ){
this.thread.stop();
}
this.trigger( 'layoutstop' );
return this; // chaining
}...
var opts = this.options;
if( opts && opts.animate ){
var anis = this.animations;
if( anis ){
for( var i = 0; i < anis.length; i++ ){
anis[ i ].stop();
}
}
}
if( regStop ){
regStop.call( this );
} else {
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}...
return function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
id = function (){
var ele = this[0];
if( ele ){
return ele._private.data.id;
}
}...
if( !allMetaMatches ){
return false;
}
// check collection
if( query.collection != null ){
var matchesAny = query.collection.hasElementWithId( ele.id() );
if( !matchesAny ){
return false;
}
}
// check filter function
...function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}n/a
function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}...
return function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
...function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}n/a
function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}n/a
function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
animate = function ( fnParams ){
var defaults = {};
fnParams = util.extend( {}, defaults, fnParams );
return function animateImpl( properties, params ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
if( params ){
properties = util.extend( {}, properties, params );
}
// manually hook and run the animation
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
var queue = ele.animated() && (properties.queue === undefined || properties.queue);
var ani = ele.animation( properties, (queue ? { queue: true } : undefined) );
ani.play();
}
return this; // chaining
};
}...
fnParams = util.extend( {}, defaults, fnParams );
return function delayImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animate( {
delay: time,
duration: time,
complete: complete
} );
};
}, // delay
...animated = function ( fnParams ){
var defaults = {};
fnParams = util.extend( {}, defaults, fnParams );
return function animatedImpl(){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return false; }
var ele = all[0];
if( ele ){
return ele._private.animation.current.length > 0;
}
};
}...
if( params ){
properties = util.extend( {}, properties, params );
}
// manually hook and run the animation
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
var queue = ele.animated() && (properties.queue === undefined || properties
.queue);
var ani = ele.animation( properties, (queue ? { queue: true } : undefined) );
ani.play();
}
return this; // chaining
...animation = function ( fnParams ){
var defaults = {};
fnParams = util.extend( {}, defaults, fnParams );
return function animationImpl( properties, params ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
var isCore = !selfIsArrayLike;
var isEles = !isCore;
if( !cy.styleEnabled() ){ return this; }
var style = cy.style();
properties = util.extend( {}, properties, params );
if( properties.duration === undefined ){
properties.duration = 400;
}
switch( properties.duration ){
case 'slow':
properties.duration = 600;
break;
case 'fast':
properties.duration = 200;
break;
}
var propertiesEmpty = Object.keys( properties ).length === 0;
if( propertiesEmpty ){
return new Animation( all[0], properties ); // nothing to animate
}
if( isEles ){
properties.style = style.getPropsList( properties.style || properties.css );
properties.css = undefined;
}
if( properties.renderedPosition && isEles ){
var rpos = properties.renderedPosition;
var pan = cy.pan();
var zoom = cy.zoom();
properties.position = {
x: ( rpos.x - pan.x ) / zoom,
y: ( rpos.y - pan.y ) / zoom
};
}
// override pan w/ panBy if set
if( properties.panBy && isCore ){
var panBy = properties.panBy;
var cyPan = cy.pan();
properties.pan = {
x: cyPan.x + panBy.x,
y: cyPan.y + panBy.y
};
}
// override pan w/ center if set
var center = properties.center || properties.centre;
if( center && isCore ){
var centerPan = cy.getCenterPan( center.eles, properties.zoom );
if( centerPan ){
properties.pan = centerPan;
}
}
// override pan & zoom w/ fit if set
if( properties.fit && isCore ){
var fit = properties.fit;
var fitVp = cy.getFitViewport( fit.eles || fit.boundingBox, fit.padding );
if( fitVp ){
properties.pan = fitVp.pan;
properties.zoom = fitVp.zoom;
}
}
return new Animation( all[0], properties );
};
}...
fnParams = util.extend( {}, defaults, fnParams );
return function delayAnimationImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animation( {
delay: time,
duration: time,
complete: complete
} );
};
}, // delay
...clearQueue = function ( fnParams ){
var defaults = {};
fnParams = util.extend( {}, defaults, fnParams );
return function clearQueueImpl(){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
ele._private.animation.queue = [];
}
return this;
};
}n/a
data = function ( params ){
var defaults = {
field: 'data',
bindingEvent: 'data',
allowBinding: false,
allowSetting: false,
allowGetting: false,
settingEvent: 'data',
settingTriggersEvent: false,
triggerFnName: 'trigger',
immutableKeys: {}, // key => true if immutable
updateStyle: false,
onSet: function( self ){},
canSet: function( self ){ return true; }
};
params = util.extend( {}, defaults, params );
return function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}; // function
}...
return function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
...delay = function ( fnParams ){
var defaults = {};
fnParams = util.extend( {}, defaults, fnParams );
return function delayImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animate( {
delay: time,
duration: time,
complete: complete
} );
};
}...
if( !anyPrev ){ return; }
_p.transitioning = true;
ele.stop();
if( delay > 0 ){
ele.delay( delay );
}
ele.animate( {
css: css
}, {
duration: duration,
easing: ele.pstyle( 'transition-timing-function' ).value,
...delayAnimation = function ( fnParams ){
var defaults = {};
fnParams = util.extend( {}, defaults, fnParams );
return function delayAnimationImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animation( {
delay: time,
duration: time,
complete: complete
} );
};
}n/a
eventAliasesOn = function ( proto ){
var p = proto;
p.addListener = p.listen = p.bind = p.on;
p.removeListener = p.unlisten = p.unbind = p.off;
p.emit = p.trigger;
// this is just a wrapper alias of .on()
p.pon = p.promiseOn = function( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
self.on.apply( self, onArgs );
} );
};
}...
layoutProto.on = define.on( { layout: true } );
layoutProto.one = define.on( { layout: true, unbindSelfOnTrigger: true } );
layoutProto.once = define.on( { layout: true, unbindAllBindersOnTrigger: true } );
layoutProto.off = define.off( { layout: true } );
layoutProto.trigger = define.trigger( { layout: true } );
define.eventAliasesOn( layoutProto );
ext = Layout; // replace with our wrapped layout
} else if( type === 'renderer' && name !== 'null' && name !== 'base' ){
// user registered renderers inherit from base
var BaseRenderer = getExtension( 'renderer', 'base' );
...function offImpl( params ){
var defaults = {
};
params = util.extend( {}, defaults, params );
return function( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}; // function
}...
return this;
};
}
layoutProto.on = define.on( { layout: true } );
layoutProto.one = define.on( { layout: true, unbindSelfOnTrigger: true } );
layoutProto.once = define.on( { layout: true, unbindAllBindersOnTrigger: true } );
layoutProto.off = define.off( { layout: true } );
layoutProto.trigger = define.trigger( { layout: true } );
define.eventAliasesOn( layoutProto );
ext = Layout; // replace with our wrapped layout
} else if( type === 'renderer' && name !== 'null' && name !== 'base' ){
...on = function ( params ){
var defaults = {
unbindSelfOnTrigger: false,
unbindAllBindersOnTrigger: false
};
params = util.extend( {}, defaults, params );
return function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}; // function
}...
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
...removeData = function ( params ){
var defaults = {
field: 'data',
event: 'data',
triggerFnName: 'trigger',
triggerEvent: false,
immutableKeys: {} // key => true if immutable
};
params = util.extend( {}, defaults, params );
return function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}; // function
}...
return function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
...stop = function ( fnParams ){
var defaults = {};
fnParams = util.extend( {}, defaults, fnParams );
return function stopImpl( clearQueue, jumpToEnd ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
var _p = ele._private;
var anis = _p.animation.current;
for( var j = 0; j < anis.length; j++ ){
var ani = anis[ j ];
var ani_p = ani._private;
if( jumpToEnd ){
// next iteration of the animation loop, the animation
// will go straight to the end and be removed
ani_p.duration = 0;
}
}
// clear the queue of future animations
if( clearQueue ){
_p.animation.queue = [];
}
if( !jumpToEnd ){
_p.animation.current = [];
}
}
// we have to notify (the animation loop doesn't do it for us on `stop`)
cy.notify( {
eles: this,
type: 'draw'
} );
return this;
};
}...
var opts = this.options;
if( opts && opts.animate ){
var anis = this.animations;
if( anis ){
for( var i = 0; i < anis.length; i++ ){
anis[ i ].stop();
}
}
}
if( regStop ){
regStop.call( this );
} else {
...trigger = function ( params ){
var defaults = {};
params = util.extend( {}, defaults, params );
return function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
events.push( {
type: type,
namespace: namespace
} );
}
} else if( eventsIsObject ){ // put in length 1 array
var eventArgObj = events;
events = [ eventArgObj ];
}
if( extraParams ){
if( !is.array( extraParams ) ){ // make sure extra params are in an array if specified
extraParams = [ extraParams ];
}
} else { // otherwise, we've got nothing
extraParams = [];
}
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
evt.target = evt.target || triggerer;
evt.cy = evt.cy || cy;
} else { // then we have to make one
evt = new Event( evtObj, {
target: triggerer,
cy: cy,
namespace: evtObj.namespace
} );
}
// if a layout was specified, then put it in the typed event
if( evtObj.layout ){
evt.layout = evtObj.layout;
}
// if triggered by layout, put in event
if( params.layout ){
evt.layout = triggerer;
}
// create a rendered position based on the passed position
if( evt.position ){
var pos = evt.position;
var zoom = cy.zoom();
var pan = cy.pan();
evt.renderedPosition = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
}
if( fnToTrigger ){ // then override the listeners list with just the one we specified
listeners = [ {
namespace: evt.namespace,
type: evt.type,
callback: fnToTrigger
} ];
}
for( var k = 0; k < listeners.length; k++ ){ // check each listener
var lis = listeners[ k ];
var nsMatches = !lis.namespace || lis.namespace === evt.namespace || lis.namespace === define.event.universalNamespace
;
var typeMatches = lis.type === evt.type;
var targetMatches = lis.delegated ? ( triggerer !== evt.target && is.element( evt.target ) && lis.selObj.matches( evt.
target ) ) : (true); // we're not going to validate the hierarchy; that's too expensive
var listenerMatches = nsMatches && typeMatches && targetMatches;
if( listenerMatches ){ // then trigger it
var args = [ evt ];
args = args.concat( extraParams ); // add extra params to args list
if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener ......
// bubble up event for elements
if( bubbleUp ){
var parent = hasCompounds ? triggerer._private.parent : null;
var hasParent = parent != null && parent.length !== 0;
if( hasParent ){ // then bubble up to parent
parent = parent[0];
parent.trigger( evt );
} else { // otherwise, bubble up to the core
cy.trigger( evt );
}
}
} // for each of all
} // for each event
...degree = function ( includeLoops ){
var self = this;
if( includeLoops === undefined ){
includeLoops = true;
}
if( self.length === 0 ){ return; }
if( self.isNode() && !self.removed() ){
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
} else {
return;
}
}...
util.extend( elesfn, {
totalDegree: function( includeLoops ){
var total = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
total += nodes[ i ].degree( includeLoops );
}
return total;
}
} );
module.exports = elesfn;
...indegree = function ( includeLoops ){
var self = this;
if( includeLoops === undefined ){
includeLoops = true;
}
if( self.length === 0 ){ return; }
if( self.isNode() && !self.removed() ){
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
} else {
return;
}
}n/a
maxDegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}...
unhandledNodes = unhandledNodes.not( currComp );
components.push( currComp );
}
roots = cy.collection();
for( var i = 0; i < components.length; i++ ){
var comp = components[ i ];
var maxDegree = comp.maxDegree( false );
var compRoots = comp.filter( function( ele ){
return ele.degree( false ) === maxDegree;
} );
roots = roots.add( compRoots );
}
...maxIndegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
maxOutdegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
minDegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
minIndegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
minOutdegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
outdegree = function ( includeLoops ){
var self = this;
if( includeLoops === undefined ){
includeLoops = true;
}
if( self.length === 0 ){ return; }
if( self.isNode() && !self.removed() ){
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
} else {
return;
}
}n/a
totalDegree = function ( includeLoops ){
var total = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
total += nodes[ i ].degree( includeLoops );
}
return total;
}n/a
dc = function ( options ){
options = options || {};
var callingEles = this;
// root - mandatory!
if( options != null && options.root != null ){
var root = is.string( options.root ) ? this.filter( options.root )[0] : options.root[0];
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){
return 1;
};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
// alpha - optional
if( options.alpha != null && is.number( options.alpha ) ){
var alpha = options.alpha;
} else {
alpha = 0;
}
if( !directed ){
var connEdges = root.connectedEdges().intersection( callingEles );
var k = connEdges.length;
var s = 0;
// Now, sum edge weights
for( var i = 0; i < connEdges.length; i++ ){
var edge = connEdges[ i ];
s += weightFn( edge );
}
return {
degree: Math.pow( k, 1 - alpha ) * Math.pow( s, alpha )
};
} else {
var incoming = root.connectedEdges( 'edge[target = "' + root.id() + '"]' ).intersection( callingEles );
var outgoing = root.connectedEdges( 'edge[source = "' + root.id() + '"]' ).intersection( callingEles );
var k_in = incoming.length;
var k_out = outgoing.length;
var s_in = 0;
var s_out = 0;
// Now, sum incoming edge weights
for( var i = 0; i < incoming.length; i++ ){
var edge = incoming[ i ];
s_in += weightFn( edge );
}
// Now, sum outgoing edge weights
for( var i = 0; i < outgoing.length; i++ ){
var edge = outgoing[ i ];
s_out += weightFn( edge );
}
return {
indegree: Math.pow( k_in, 1 - alpha ) * Math.pow( s_in, alpha ),
outdegree: Math.pow( k_out, 1 - alpha ) * Math.pow( s_out, alpha )
};
}
}n/a
dcn = function ( options ){
options = options || {};
var cy = this.cy();
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var nodes = this.nodes();
var numNodes = nodes.length;
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
degree: function( node ){
if( maxDegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return degrees[ node ] / maxDegree;
}
};
} else {
var indegrees = {};
var outdegrees = {};
var maxIndegree = 0;
var maxOutdegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxIndegree < currDegree.indegree )
maxIndegree = currDegree.indegree;
if( maxOutdegree < currDegree.outdegree )
maxOutdegree = currDegree.outdegree;
indegrees[ node.id() ] = currDegree.indegree;
outdegrees[ node.id() ] = currDegree.outdegree;
}
return {
indegree: function( node ){
if ( maxIndegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return indegrees[ node ] / maxIndegree;
},
outdegree: function( node ){
if ( maxOutdegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return outdegrees[ node ] / maxOutdegree;
}
};
}
}n/a
degreeCentrality = function ( options ){
options = options || {};
var callingEles = this;
// root - mandatory!
if( options != null && options.root != null ){
var root = is.string( options.root ) ? this.filter( options.root )[0] : options.root[0];
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){
return 1;
};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
// alpha - optional
if( options.alpha != null && is.number( options.alpha ) ){
var alpha = options.alpha;
} else {
alpha = 0;
}
if( !directed ){
var connEdges = root.connectedEdges().intersection( callingEles );
var k = connEdges.length;
var s = 0;
// Now, sum edge weights
for( var i = 0; i < connEdges.length; i++ ){
var edge = connEdges[ i ];
s += weightFn( edge );
}
return {
degree: Math.pow( k, 1 - alpha ) * Math.pow( s, alpha )
};
} else {
var incoming = root.connectedEdges( 'edge[target = "' + root.id() + '"]' ).intersection( callingEles );
var outgoing = root.connectedEdges( 'edge[source = "' + root.id() + '"]' ).intersection( callingEles );
var k_in = incoming.length;
var k_out = outgoing.length;
var s_in = 0;
var s_out = 0;
// Now, sum incoming edge weights
for( var i = 0; i < incoming.length; i++ ){
var edge = incoming[ i ];
s_in += weightFn( edge );
}
// Now, sum outgoing edge weights
for( var i = 0; i < outgoing.length; i++ ){
var edge = outgoing[ i ];
s_out += weightFn( edge );
}
return {
indegree: Math.pow( k_in, 1 - alpha ) * Math.pow( s_in, alpha ),
outdegree: Math.pow( k_out, 1 - alpha ) * Math.pow( s_out, alpha )
};
}
}...
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
...degreeCentralityNormalised = function ( options ){
options = options || {};
var cy = this.cy();
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var nodes = this.nodes();
var numNodes = nodes.length;
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
degree: function( node ){
if( maxDegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return degrees[ node ] / maxDegree;
}
};
} else {
var indegrees = {};
var outdegrees = {};
var maxIndegree = 0;
var maxOutdegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxIndegree < currDegree.indegree )
maxIndegree = currDegree.indegree;
if( maxOutdegree < currDegree.outdegree )
maxOutdegree = currDegree.outdegree;
indegrees[ node.id() ] = currDegree.indegree;
outdegrees[ node.id() ] = currDegree.outdegree;
}
return {
indegree: function( node ){
if ( maxIndegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return indegrees[ node ] / maxIndegree;
},
outdegree: function( node ){
if ( maxOutdegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return outdegrees[ node ] / maxOutdegree;
}
};
}
}n/a
degreeCentralityNormalized = function ( options ){
options = options || {};
var cy = this.cy();
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var nodes = this.nodes();
var numNodes = nodes.length;
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
degree: function( node ){
if( maxDegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return degrees[ node ] / maxDegree;
}
};
} else {
var indegrees = {};
var outdegrees = {};
var maxIndegree = 0;
var maxOutdegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxIndegree < currDegree.indegree )
maxIndegree = currDegree.indegree;
if( maxOutdegree < currDegree.outdegree )
maxOutdegree = currDegree.outdegree;
indegrees[ node.id() ] = currDegree.indegree;
outdegrees[ node.id() ] = currDegree.outdegree;
}
return {
indegree: function( node ){
if ( maxIndegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return indegrees[ node ] / maxIndegree;
},
outdegree: function( node ){
if ( maxOutdegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return outdegrees[ node ] / maxOutdegree;
}
};
}
}n/a
dijkstra = function ( root, weightFn, directed ){
var options;
if( is.plainObject( root ) && !is.elementOrCollection( root ) ){
options = root;
root = options.root;
weightFn = options.weight;
directed = options.directed;
}
var cy = this._private.cy;
weightFn = is.fn( weightFn ) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)
var source = is.string( root ) ? this.filter( root )[0] : root[0];
var dist = {};
var prev = {};
var knownDist = {};
var edges = this.edges().filter( function( ele ){ return !ele.isLoop(); } );
var nodes = this.nodes();
var getDist = function( node ){
return dist[ node.id() ];
};
var setDist = function( node, d ){
dist[ node.id() ] = d;
Q.updateItem( node );
};
var Q = new Heap( function( a, b ){
return getDist( a ) - getDist( b );
} );
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
dist[ node.id() ] = node.same( source ) ? 0 : Infinity;
Q.push( node );
}
var distBetween = function( u, v ){
var uvs = ( directed ? u.edgesTo( v ) : u.edgesWith( v ) ).intersect( edges );
var smallestDistance = Infinity;
var smallestEdge;
for( var i = 0; i < uvs.length; i++ ){
var edge = uvs[ i ];
var weight = weightFn( edge );
if( weight < smallestDistance || !smallestEdge ){
smallestDistance = weight;
smallestEdge = edge;
}
}
return {
edge: smallestEdge,
dist: smallestDistance
};
};
while( Q.size() > 0 ){
var u = Q.pop();
var smalletsDist = getDist( u );
var uid = u.id();
knownDist[ uid ] = smalletsDist;
if( smalletsDist === Math.Infinite ){
break;
}
var neighbors = u.neighborhood().intersect( nodes );
for( var i = 0; i < neighbors.length; i++ ){
var v = neighbors[ i ];
var vid = v.id();
var vDist = distBetween( u, v );
var alt = smalletsDist + vDist.dist;
if( alt < getDist( v ) ){
setDist( v, alt );
prev[ vid ] = {
node: u,
edge: vDist.edge
};
}
} // for
} // while
return {
distanceTo: function( node ){
var target = is.string( node ) ? nodes.filter( node )[0] : node[0];
return knownDist[ target.id() ];
},
pathTo: function( node ){
var target = is.string( node ) ? nodes.filter( node )[0] : node[0];
var S = [];
var u = target;
if( target.length > 0 ){
S.unshift( target );
while( prev[ u.id() ] ){
var p = prev[ u.id() ];
S.unshift( p.edge );
S.unshift( p.node );
u = p.node;
}
}
return cy.collection( S );
}
};
}...
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
// we need distance from this node to every other node
var dijkstra = this.dijkstra( {
root: root,
weight: weight,
directed: directed
} );
var totalDistance = 0;
var nodes = this.nodes();
...boundingBox = function ( options ){
// the main usecase is ele.boundingBox() for a single element with no/def options
// specified s.t. the cache is used, so check for this case to make it faster by
// avoiding the overhead of the rest of the function
if( this.length === 1 && this[0]._private.bbCache && (options === undefined || options.useCache === undefined || options.useCache
=== true) ){
if( options === undefined ){
options = defBbOpts;
} else {
options = filledBbOpts( options );
}
return cachedBoundingBoxImpl( this[0], options );
}
var bounds = {
x1: Infinity,
y1: Infinity,
x2: -Infinity,
y2: -Infinity
};
options = options || util.staticEmptyObject();
var opts = filledBbOpts( options );
var eles = this;
var cy = eles.cy();
var styleEnabled = cy.styleEnabled();
if( styleEnabled ){
this.recalculateRenderedStyle( opts.useCache );
}
for( var i = 0; i < eles.length; i++ ){
var ele = eles[i];
if( styleEnabled && ele.isEdge() && ele.pstyle('curve-style').strValue === 'bezier' ){
ele.parallelEdges().recalculateRenderedStyle( opts.useCache ); // n.b. ele.parallelEdges() single is cached
}
updateBoundsFromBox( bounds, cachedBoundingBoxImpl( ele, opts ) );
}
bounds.x1 = noninf( bounds.x1 );
bounds.y1 = noninf( bounds.y1 );
bounds.x2 = noninf( bounds.x2 );
bounds.y2 = noninf( bounds.y2 );
bounds.w = noninf( bounds.x2 - bounds.x1 );
bounds.h = noninf( bounds.y2 - bounds.y1 );
return bounds;
}...
return undefined; // for empty collection case
}
return this; // chaining
},
renderedBoundingBox: function( options ){
var bb = this.boundingBox( options );
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var x1 = bb.x1 * zoom + pan.x;
var x2 = bb.x2 * zoom + pan.x;
var y1 = bb.y1 * zoom + pan.y;
...boundingbox = function ( options ){
// the main usecase is ele.boundingBox() for a single element with no/def options
// specified s.t. the cache is used, so check for this case to make it faster by
// avoiding the overhead of the rest of the function
if( this.length === 1 && this[0]._private.bbCache && (options === undefined || options.useCache === undefined || options.useCache
=== true) ){
if( options === undefined ){
options = defBbOpts;
} else {
options = filledBbOpts( options );
}
return cachedBoundingBoxImpl( this[0], options );
}
var bounds = {
x1: Infinity,
y1: Infinity,
x2: -Infinity,
y2: -Infinity
};
options = options || util.staticEmptyObject();
var opts = filledBbOpts( options );
var eles = this;
var cy = eles.cy();
var styleEnabled = cy.styleEnabled();
if( styleEnabled ){
this.recalculateRenderedStyle( opts.useCache );
}
for( var i = 0; i < eles.length; i++ ){
var ele = eles[i];
if( styleEnabled && ele.isEdge() && ele.pstyle('curve-style').strValue === 'bezier' ){
ele.parallelEdges().recalculateRenderedStyle( opts.useCache ); // n.b. ele.parallelEdges() single is cached
}
updateBoundsFromBox( bounds, cachedBoundingBoxImpl( ele, opts ) );
}
bounds.x1 = noninf( bounds.x1 );
bounds.y1 = noninf( bounds.y1 );
bounds.x2 = noninf( bounds.x2 );
bounds.y2 = noninf( bounds.y2 );
bounds.w = noninf( bounds.x2 - bounds.x1 );
bounds.h = noninf( bounds.y2 - bounds.y1 );
return bounds;
}n/a
function dimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
if( ele.isParent() ){
return _p[ opts.autoName ] || 0;
}
var d = ele.pstyle( opts.name );
switch( d.strValue ){
case 'label':
return _p.rstyle[ opts.labelName ] || 0;
default:
return d.pfValue;
}
} else {
return 1;
}
}
}...
};
}
var eleTakesUpSpace = function( ele ){
return (
ele.pstyle( 'display' ).value === 'element'
&& ele.width() !== 0
&& ( ele.isNode() ? ele.height() !== 0 : true )
);
};
elesfn.takesUpSpace = defineDerivedStateFunction({
ok: eleTakesUpSpace
});
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
modelPositions = function ( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var pos = fn( ele, i );
if( pos && !ele.locked() && !ele.isParent() ){
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
return this; // chaining
}n/a
function outerDimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
var dim = ele[ opts.name ]();
var border = ele.pstyle( 'border-width' ).pfValue; // n.b. 1/2 each side
var padding = 2 * ele.pstyle( 'padding' ).pfValue;
return dim + border + padding;
} else {
return 1;
}
}
}...
if( isNode && options.includeNodes ){
var pos = _p.position;
x = pos.x;
y = pos.y;
var w = ele.outerWidth();
var halfW = w / 2;
var h = ele.outerHeight();
var halfH = h / 2;
// handle node dimensions
/////////////////////////
ex1 = x - halfW - overlayPadding;
ex2 = x + halfW + overlayPadding;
...function outerDimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
var dim = ele[ opts.name ]();
var border = ele.pstyle( 'border-width' ).pfValue; // n.b. 1/2 each side
var padding = 2 * ele.pstyle( 'padding' ).pfValue;
return dim + border + padding;
} else {
return 1;
}
}
}...
wHalf = w / 2;
}
if( isNode && options.includeNodes ){
var pos = _p.position;
x = pos.x;
y = pos.y;
var w = ele.outerWidth();
var halfW = w / 2;
var h = ele.outerHeight();
var halfH = h / 2;
// handle node dimensions
/////////////////////////
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
points = function ( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var pos = fn( ele, i );
if( pos && !ele.locked() && !ele.isParent() ){
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
return this; // chaining
}n/a
function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}...
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
positions: function( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
...positions = function ( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var pos = fn( ele, i );
if( pos && !ele.locked() && !ele.isParent() ){
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
return this; // chaining
}...
}
}
return this; // chaining
},
silentPositions: function( pos ){
return this.positions( pos, true );
},
// get/set the rendered (i.e. on screen) positon of the element
renderedPosition: function( dim, val ){
var ele = this[0];
var cy = this.cy();
var zoom = cy.zoom();
...recalculateRenderedStyle = function ( useCache ){
var cy = this.cy();
var renderer = cy.renderer();
var styleEnabled = cy.styleEnabled();
if( renderer && styleEnabled ){
renderer.recalculateRenderedStyle( this, useCache );
}
return this;
}...
elesfn.recalculateRenderedStyle = function( useCache ){
var cy = this.cy();
var renderer = cy.renderer();
var styleEnabled = cy.styleEnabled();
if( renderer && styleEnabled ){
renderer.recalculateRenderedStyle( this, useCache );
}
return this;
};
function filledBbOpts( options ){
return {
...relativePoint = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var ppos = is.plainObject( dim ) ? dim : undefined;
var setting = ppos !== undefined || ( val !== undefined && is.string( dim ) );
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = val + origin[ dim ];
} else if( ppos !== undefined ){ // set whole position
ele._private.position = {
x: ppos.x + origin.x,
y: ppos.y + origin.y
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
ppos = {
x: pos.x - origin.x,
y: pos.y - origin.y
};
if( dim === undefined ){ // then return the whole rendered position
return ppos;
} else { // then return the specified dimension
return ppos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
relativePosition = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var ppos = is.plainObject( dim ) ? dim : undefined;
var setting = ppos !== undefined || ( val !== undefined && is.string( dim ) );
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = val + origin[ dim ];
} else if( ppos !== undefined ){ // set whole position
ele._private.position = {
x: ppos.x + origin.x,
y: ppos.y + origin.y
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
ppos = {
x: pos.x - origin.x,
y: pos.y - origin.y
};
if( dim === undefined ){ // then return the whole rendered position
return ppos;
} else { // then return the specified dimension
return ppos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
renderedBoundingBox = function ( options ){
var bb = this.boundingBox( options );
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var x1 = bb.x1 * zoom + pan.x;
var x2 = bb.x2 * zoom + pan.x;
var y1 = bb.y1 * zoom + pan.y;
var y2 = bb.y2 * zoom + pan.y;
return {
x1: x1,
x2: x2,
y1: y1,
y2: y2,
w: x2 - x1,
h: y2 - y1
};
}n/a
renderedBoundingbox = function ( options ){
var bb = this.boundingBox( options );
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var x1 = bb.x1 * zoom + pan.x;
var x2 = bb.x2 * zoom + pan.x;
var y1 = bb.y1 * zoom + pan.y;
var y2 = bb.y2 * zoom + pan.y;
return {
x1: x1,
x2: x2,
y1: y1,
y2: y2,
w: x2 - x1,
h: y2 - y1
};
}n/a
function renderedDimImpl(){
var ele = this[0];
if( ele ){
var d = ele[ opts.name ]();
return d * this.cy().zoom();
}
}n/a
function renderedOuterDimImpl(){
var ele = this[0];
if( ele ){
var od = ele[ opts.outerName ]();
return od * this.cy().zoom();
}
}n/a
function renderedOuterDimImpl(){
var ele = this[0];
if( ele ){
var od = ele[ opts.outerName ]();
return od * this.cy().zoom();
}
}n/a
renderedPoint = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var rpos = is.plainObject( dim ) ? dim : undefined;
var setting = rpos !== undefined || ( val !== undefined && is.string( dim ) );
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = ( val - pan[ dim ] ) / zoom;
} else if( rpos !== undefined ){ // set whole position
ele._private.position = {
x: ( rpos.x - pan.x ) / zoom,
y: ( rpos.y - pan.y ) / zoom
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
rpos = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
if( dim === undefined ){ // then return the whole rendered position
return rpos;
} else { // then return the specified dimension
return rpos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
renderedPosition = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var rpos = is.plainObject( dim ) ? dim : undefined;
var setting = rpos !== undefined || ( val !== undefined && is.string( dim ) );
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = ( val - pan[ dim ] ) / zoom;
} else if( rpos !== undefined ){ // set whole position
ele._private.position = {
x: ( rpos.x - pan.x ) / zoom,
y: ( rpos.y - pan.y ) / zoom
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
rpos = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
if( dim === undefined ){ // then return the whole rendered position
return rpos;
} else { // then return the specified dimension
return rpos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
function renderedDimImpl(){
var ele = this[0];
if( ele ){
var d = ele[ opts.name ]();
return d * this.cy().zoom();
}
}n/a
function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}...
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var newPos = fn( node, i );
var pos = node.position();
if( !is.number( pos.x ) || !is.number( pos.y ) ){
node.silentPosition( { x: 0, y: 0 } );
}
var ani = node.animation( {
position: newPos,
duration: options.animationDuration,
easing: options.animationEasing
} );
...silentPositions = function ( pos ){
return this.positions( pos, true );
}n/a
updateCompoundBounds = function (){
var cy = this.cy();
// save cycles for non compound graphs or when style disabled
if( !cy.styleEnabled() || !cy.hasCompoundNodes() ){ return cy.collection(); }
var updated = [];
function update( parent ){
if( !parent.isParent() ){ return; }
var _p = parent._private;
var children = parent.children();
var includeLabels = parent.pstyle( 'compound-sizing-wrt-labels' ).value === 'include';
var bb = children.boundingBox( {
includeLabels: includeLabels,
includeOverlays: false,
// updating the compound bounds happens outside of the regular
// cache cycle (i.e. before fired events)
useCache: false
} );
var pos = _p.position;
_p.autoWidth = bb.w;
pos.x = (bb.x1 + bb.x2) / 2;
_p.autoHeight = bb.h;
pos.y = (bb.y1 + bb.y2) / 2;
updated.push( parent );
}
// go up, level by level
var eles = this;
while( eles.nonempty() ){
// update each parent node in this level
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
update( ele );
}
// next level
eles = eles.parent();
}
// return changed
return this.spawn( updated );
}...
allowSetting: true,
settingEvent: 'position',
settingTriggersEvent: true,
triggerFnName: 'rtrigger',
allowGetting: true,
validKeys: [ 'x', 'y' ],
onSet: function( eles ){
var updatedEles = eles.updateCompoundBounds();
updatedEles.rtrigger( 'position' );
},
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
...function dimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
if( ele.isParent() ){
return _p[ opts.autoName ] || 0;
}
var d = ele.pstyle( opts.name );
switch( d.strValue ){
case 'label':
return _p.rstyle[ opts.labelName ] || 0;
default:
return d.pfValue;
}
} else {
return 1;
}
}
}...
}
};
}
var eleTakesUpSpace = function( ele ){
return (
ele.pstyle( 'display' ).value === 'element'
&& ele.width() !== 0
&& ( ele.isNode() ? ele.height() !== 0 : true )
);
};
elesfn.takesUpSpace = defineDerivedStateFunction({
ok: eleTakesUpSpace
});
...element = function ( cy, params, restore ){
var self = this;
restore = (restore === undefined || restore ? true : false);
if( cy === undefined || params === undefined || !is.core( cy ) ){
util.error( 'An element must have a core reference and parameters set' );
return;
}
var group = params.group;
// try to automatically infer the group if unspecified
if( group == null ){
if( params.data && params.data.source != null && params.data.target != null ){
group = 'edges';
} else {
group = 'nodes';
}
}
// validate group
if( group !== 'nodes' && group !== 'edges' ){
util.error( 'An element must be of type `nodes` or `edges`; you specified `' + group + '`' );
return;
}
// make the element array-like, just like a collection
this.length = 1;
this[0] = this;
// NOTE: when something is added here, add also to ele.json()
this._private = {
cy: cy,
single: true, // indicates this is an element
data: params.data || {}, // data object
position: params.position || {}, // (x, y) position pair
autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value
autoHeight: undefined,
listeners: [], // array of bound listeners
group: group, // string; 'nodes' or 'edges'
style: {}, // properties as set by the style
rstyle: {}, // properties for style sent from the renderer to the core
styleCxts: [], // applied style contexts from the styler
removed: true, // whether it's inside the vis; true if removed (set true here since we call restore)
selected: params.selected ? true : false, // whether it's selected
selectable: params.selectable === undefined ? true : ( params.selectable ? true : false ), // whether it's selectable
locked: params.locked ? true : false, // whether the element is locked (cannot be moved)
grabbed: false, // whether the element is grabbed by the mouse; renderer sets this privately
grabbable: params.grabbable === undefined ? true : ( params.grabbable ? true : false ), // whether the element can be grabbed
active: false, // whether the element is active from user interaction
classes: {}, // map ( className => true )
animation: { // object for currently-running animations
current: [],
queue: []
},
rscratch: {}, // object in which the renderer can store information
scratch: params.scratch || {}, // scratch objects
edges: [], // array of connected edges
children: [], // array of children
traversalCache: {} // cache of output of traversal functions
};
// renderedPosition overrides if specified
if( params.renderedPosition ){
var rpos = params.renderedPosition;
var pan = cy.pan();
var zoom = cy.zoom();
this._private.position = {
x: (rpos.x - pan.x) / zoom,
y: (rpos.y - pan.y) / zoom
};
}
if( is.string( params.classes ) ){
var classes = params.classes.split( /\s+/ );
for( var i = 0, l = classes.length; i < l; i++ ){
var cls = classes[ i ];
if( !cls || cls === '' ){ continue; }
self._private.classes[ cls ] = true;
}
}
if( params.style || params.css ){
cy.style().applyBypass( this, params.style || params.css );
}
if( restore === undefined || restore ){
this.restore();
}
}...
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
...aStar = function ( options ){
var eles = this;
options = options || {};
// Reconstructs the path from Start to End, acumulating the result in pathAcum
var reconstructPath = function( start, end, cameFromMap, pathAcum ){
// Base case
if( start == end ){
pathAcum.push( cy.getElementById( end ) );
return pathAcum;
}
if( end in cameFromMap ){
// We know which node is before the last one
var previous = cameFromMap[ end ];
var previousEdge = cameFromEdge[ end ];
pathAcum.push( cy.getElementById( end ) );
pathAcum.push( cy.getElementById( previousEdge ) );
return reconstructPath( start,
previous,
cameFromMap,
pathAcum );
}
// We should not reach here!
return undefined;
};
// Returns the index of the element in openSet which has minimum fScore
var findMin = function( openSet, fScore ){
if( openSet.length === 0 ){
// Should never be the case
return undefined;
}
var minPos = 0;
var tempScore = fScore[ openSet[0] ];
for( var i = 1; i < openSet.length; i++ ){
var s = fScore[ openSet[ i ] ];
if( s < tempScore ){
tempScore = s;
minPos = i;
}
}
return minPos;
};
var cy = this._private.cy;
// root - mandatory!
if( options != null && options.root != null ){
var source = is.string( options.root ) ?
// use it as a selector, e.g. "#rootID
this.filter( options.root )[0] :
options.root[0];
} else {
return undefined;
}
// goal - mandatory!
if( options.goal != null ){
var target = is.string( options.goal ) ?
// use it as a selector, e.g. "#goalID
this.filter( options.goal )[0] :
options.goal[0];
} else {
return undefined;
}
// Heuristic function - optional
if( options.heuristic != null && is.fn( options.heuristic ) ){
var heuristic = options.heuristic;
} else {
var heuristic = function(){ return 0; }; // use constant if unspecified
}
// Weight function - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var closedSet = [];
var openSet = [ source.id() ];
var cameFrom = {};
var cameFromEdge = {};
var gScore = {};
var fScore = {};
gScore[ source.id() ] = 0;
fScore[ source.id() ] = heuristic( source );
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
// Counter
var steps = 0;
// Main loop
while( openSet.length > 0 ){
var minPos = findMin( openSet, fScore );
var cMin = cy.getElementById( openSet[ minPos ] );
steps++;
// If we've found our goal, then we are done
if( cMin.id() == target.id() ){
var rPath = reconstructPath( source.id(), target.id(), cameFrom, [] );
rPath.reverse();
return {
found: true,
distance: gScore[ cMin.id() ],
path: eles.spawn( rPath ),
steps: steps
};
}
// Add cMin to processed nodes
closedSet.push( cMin.id() );
// Remove cMin from boundary nodes
openSet.splice( minPos, 1 );
// Update scores for neighbors of cMin
// Take into account if graph is directed or not
var vwEdges = cMin.connectedEdges();
if( directed ){ vwEdges = vwEdges.stdFilter( function( ele ){ return ele.data( 'source' ) === cMin.id(); } ); }
vwEdges = vwEdges.intersect( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes().stdFilter( function( n ){ return n.id() !== cMin.id(); } ).intersect( nodes );
// if node is in closedSet, ignore it
if( closedSet.indexOf( w.id() ) != -1 ){
continue;
}
// New tentative score for node w
var tempScore = gS ...n/a
abscomp = function (){
var cy = this._private.cy;
return cy.mutableElements().not( this );
}n/a
absoluteComplement = function (){
var cy = this._private.cy;
return cy.mutableElements().not( this );
}n/a
activate = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
active = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) === ele.data( 'target' );
break;
case ':simple':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) !== ele.data( 'target' );
break;
case ':active':
allColonSelectorsMatch = ele.active();
break;
case ':inactive':
allColonSelectorsMatch = !ele.active();
break;
case ':backgrounding':
allColonSelectorsMatch = ele.backgrounding();
break;
...add = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}...
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
...addClass = function ( classes ){
return this.toggleClass( classes, true );
}...
if( duration == null ){
duration = 250;
} else if( duration === 0 ){
return self; // nothing to do really
}
self.addClass( classes );
setTimeout( function(){
self.removeClass( classes );
}, duration );
return self;
}
});
...function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}n/a
allAre = function ( selector ){
return this.filter( selector ).length === this.length;
}n/a
allAreNeighbors = function ( collection ){
collection = this.cy().collection( collection );
return this.neighborhood().intersect( collection ).length === collection.length;
}n/a
allAreNeighbours = function ( collection ){
collection = this.cy().collection( collection );
return this.neighborhood().intersect( collection ).length === collection.length;
}n/a
ancestors = function ( selector ){
var parents = [];
var eles = this.parent();
while( eles.nonempty() ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
parents.push( ele );
}
eles = eles.parent();
}
return this.spawn( parents, { unique: true } ).filter( selector );
}n/a
and = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}n/a
function animateImpl( properties, params ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
if( params ){
properties = util.extend( {}, properties, params );
}
// manually hook and run the animation
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
var queue = ele.animated() && (properties.queue === undefined || properties.queue);
var ani = ele.animation( properties, (queue ? { queue: true } : undefined) );
ani.play();
}
return this; // chaining
}...
fnParams = util.extend( {}, defaults, fnParams );
return function delayImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animate( {
delay: time,
duration: time,
complete: complete
} );
};
}, // delay
...function animatedImpl(){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return false; }
var ele = all[0];
if( ele ){
return ele._private.animation.current.length > 0;
}
}...
if( params ){
properties = util.extend( {}, properties, params );
}
// manually hook and run the animation
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
var queue = ele.animated() && (properties.queue === undefined || properties
.queue);
var ani = ele.animation( properties, (queue ? { queue: true } : undefined) );
ani.play();
}
return this; // chaining
...function animationImpl( properties, params ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
var isCore = !selfIsArrayLike;
var isEles = !isCore;
if( !cy.styleEnabled() ){ return this; }
var style = cy.style();
properties = util.extend( {}, properties, params );
if( properties.duration === undefined ){
properties.duration = 400;
}
switch( properties.duration ){
case 'slow':
properties.duration = 600;
break;
case 'fast':
properties.duration = 200;
break;
}
var propertiesEmpty = Object.keys( properties ).length === 0;
if( propertiesEmpty ){
return new Animation( all[0], properties ); // nothing to animate
}
if( isEles ){
properties.style = style.getPropsList( properties.style || properties.css );
properties.css = undefined;
}
if( properties.renderedPosition && isEles ){
var rpos = properties.renderedPosition;
var pan = cy.pan();
var zoom = cy.zoom();
properties.position = {
x: ( rpos.x - pan.x ) / zoom,
y: ( rpos.y - pan.y ) / zoom
};
}
// override pan w/ panBy if set
if( properties.panBy && isCore ){
var panBy = properties.panBy;
var cyPan = cy.pan();
properties.pan = {
x: cyPan.x + panBy.x,
y: cyPan.y + panBy.y
};
}
// override pan w/ center if set
var center = properties.center || properties.centre;
if( center && isCore ){
var centerPan = cy.getCenterPan( center.eles, properties.zoom );
if( centerPan ){
properties.pan = centerPan;
}
}
// override pan & zoom w/ fit if set
if( properties.fit && isCore ){
var fit = properties.fit;
var fitVp = cy.getFitViewport( fit.eles || fit.boundingBox, fit.padding );
if( fitVp ){
properties.pan = fitVp.pan;
properties.zoom = fitVp.zoom;
}
}
return new Animation( all[0], properties );
}...
fnParams = util.extend( {}, defaults, fnParams );
return function delayAnimationImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animation( {
delay: time,
duration: time,
complete: complete
} );
};
}, // delay
...anySame = function ( collection ){
collection = this.cy().collection( collection );
return this.intersect( collection ).length > 0;
}...
}
} );
} while( unvisited.length > 0 );
return components.map(function( component ){
var connectedEdges = component.connectedEdges().stdFilter(function( edge ){
return component.anySame( edge.source() ) && component.anySame( edge
.target() );
});
return component.union( connectedEdges );
});
}
} );
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
backgrounding = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return false; }
var ele = this[0];
return ele._private.backgrounding ? true : false;
}...
case ':active':
allColonSelectorsMatch = ele.active();
break;
case ':inactive':
allColonSelectorsMatch = !ele.active();
break;
case ':backgrounding':
allColonSelectorsMatch = ele.backgrounding();
break;
case ':nonbackgrounding':
allColonSelectorsMatch = !ele.backgrounding();
break;
}
if( !allColonSelectorsMatch ) break;
...bc = function ( options ){
options = options || {};
// Weight - optional
var weighted, weightFn;
if( is.fn( options.weight ) ){
weightFn = options.weight;
weighted = true;
} else {
weighted = false;
}
// Directed - default false
var directed = options.directed != null ? options.directed : false;
var cy = this._private.cy;
// starting
var V = this.nodes();
var A = {};
var _C = {};
var max = 0;
var C = {
set: function( key, val ){
_C[ key ] = val;
if( val > max ){ max = val; }
},
get: function( key ){ return _C[ key ]; }
};
// A contains the neighborhoods of every node
for( var i = 0; i < V.length; i++ ){
var v = V[ i ];
var vid = v.id();
if( directed ){
A[ vid ] = v.outgoers().nodes(); // get outgoers of every node
} else {
A[ vid ] = v.openNeighborhood().nodes(); // get neighbors of every node
}
C.set( vid, 0 );
}
for( var s = 0; s < V.length; s++ ){
var sid = V[s].id();
var S = []; // stack
var P = {};
var g = {};
var d = {};
var Q = new Heap(function( a, b ){
return d[a] - d[b];
}); // queue
// init dictionaries
for( var i = 0; i < V.length; i++ ){
var vid = V[ i ].id();
P[ vid ] = [];
g[ vid ] = 0;
d[ vid ] = Infinity;
}
g[ sid ] = 1; // sigma
d[ sid ] = 0; // distance to s
Q.push( sid );
while( !Q.empty() ){
var v = Q.pop();
S.push( v );
if( weighted ){
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j];
var vEle = cy.getElementById( v );
var edge;
if( vEle.edgesTo( w ).length > 0 ){
edge = vEle.edgesTo( w )[0];
} else {
edge = w.edgesTo( vEle )[0];
}
var edgeWeight = weightFn( edge );
w = w.id();
if( d[w] > d[v] + edgeWeight ){
d[w] = d[v] + edgeWeight;
if( Q.nodes.indexOf( w ) < 0 ){ //if w is not in Q
Q.push( w );
} else { // update position if w is in Q
Q.updateItem( w );
}
g[w] = 0;
P[w] = [];
}
if( d[w] == d[v] + edgeWeight ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
} else {
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j].id();
if( d[w] == Infinity ){
Q.push( w );
d[w] = d[v] + 1;
}
if( d[w] == d[v] + 1 ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
}
}
var e = {};
for( var i = 0; i < V.length; i++ ){
e[ V[ i ].id() ] = 0;
}
while( S.length > 0 ){
var w = S.pop();
for( var j = 0; j < P[w].length; j++ ){
var v = P[w][j];
e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]);
if( w != V[s].id() ){
C.set( w, C.get( w ) + e[w] );
}
}
}
}
var ret = {
betweenness: function( node ){
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node );
},
betweennessNormalized: function( node ){
if ( max == 0 )
return 0;
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node ) / max;
}
};
// alias
ret.betweennessNormalised = ret.betweennessNormalized;
return ret;
}n/a
bellmanFord = function ( options ){
var eles = this;
options = options || {};
// Weight function - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
// root - mandatory!
if( options.root != null ){
if( is.string( options.root ) ){
// use it as a selector, e.g. "#rootID
var source = this.filter( options.root )[0];
} else {
var source = options.root[0];
}
} else {
return undefined;
}
var cy = this._private.cy;
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
// mapping: node id -> position in nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Initializations
var cost = [];
var predecessor = [];
var predEdge = [];
for( var i = 0; i < numNodes; i++ ){
if( nodes[ i ].id() === source.id() ){
cost[ i ] = 0;
} else {
cost[ i ] = Infinity;
}
predecessor[ i ] = undefined;
}
// Edges relaxation
var flag = false;
for( var i = 1; i < numNodes; i++ ){
flag = false;
for( var e = 0; e < edges.length; e++ ){
var sourceIndex = id2position[ edges[ e ].source().id() ];
var targetIndex = id2position[ edges[ e ].target().id() ];
var weight = weightFn( edges[ e ] );
var temp = cost[ sourceIndex ] + weight;
if( temp < cost[ targetIndex ] ){
cost[ targetIndex ] = temp;
predecessor[ targetIndex ] = sourceIndex;
predEdge[ targetIndex ] = edges[ e ];
flag = true;
}
// If undirected graph, we need to take into account the 'reverse' edge
if( !directed ){
var temp = cost[ targetIndex ] + weight;
if( temp < cost[ sourceIndex ] ){
cost[ sourceIndex ] = temp;
predecessor[ sourceIndex ] = targetIndex;
predEdge[ sourceIndex ] = edges[ e ];
flag = true;
}
}
}
if( !flag ){
break;
}
}
if( flag ){
// Check for negative weight cycles
for( var e = 0; e < edges.length; e++ ){
var sourceIndex = id2position[ edges[ e ].source().id() ];
var targetIndex = id2position[ edges[ e ].target().id() ];
var weight = weightFn( edges[ e ] );
if( cost[ sourceIndex ] + weight < cost[ targetIndex ] ){
util.error( 'Graph contains a negative weight cycle for Bellman-Ford' );
return { pathTo: undefined,
distanceTo: undefined,
hasNegativeWeightCycle: true};
}
}
}
// Build result object
var position2id = [];
for( var i = 0; i < numNodes; i++ ){
position2id.push( nodes[ i ].id() );
}
var res = {
distanceTo: function( to ){
if( is.string( to ) ){
// to is a selector string
var toId = (cy.filter( to )[0]).id();
} else {
// to is a node
var toId = to.id();
}
return cost[ id2position[ toId ] ];
},
pathTo: function( to ){
var reconstructPathAux = function( predecessor, fromPos, toPos, position2id, acumPath, predEdge ){
for( ;; ){
// Add toId to path
acumPath.push( cy.getElementById( position2id[ toPos ] ) );
acumPath.push( predEdge[ toPos ] );
if( fromPos === toPos ){
// reached starting node
return acumPath;
}
// If no path exists, discart acumulated path and return undefined
var predPos = predecessor[ toPos ];
if( typeof predPos === 'undefined' ){
return undefined;
}
toPos = predPos;
}
};
if( is.string( to ) ){
// to is a selector string
var toId = (cy.filter( to )[0]).id();
} else { ...n/a
betweennessCentrality = function ( options ){
options = options || {};
// Weight - optional
var weighted, weightFn;
if( is.fn( options.weight ) ){
weightFn = options.weight;
weighted = true;
} else {
weighted = false;
}
// Directed - default false
var directed = options.directed != null ? options.directed : false;
var cy = this._private.cy;
// starting
var V = this.nodes();
var A = {};
var _C = {};
var max = 0;
var C = {
set: function( key, val ){
_C[ key ] = val;
if( val > max ){ max = val; }
},
get: function( key ){ return _C[ key ]; }
};
// A contains the neighborhoods of every node
for( var i = 0; i < V.length; i++ ){
var v = V[ i ];
var vid = v.id();
if( directed ){
A[ vid ] = v.outgoers().nodes(); // get outgoers of every node
} else {
A[ vid ] = v.openNeighborhood().nodes(); // get neighbors of every node
}
C.set( vid, 0 );
}
for( var s = 0; s < V.length; s++ ){
var sid = V[s].id();
var S = []; // stack
var P = {};
var g = {};
var d = {};
var Q = new Heap(function( a, b ){
return d[a] - d[b];
}); // queue
// init dictionaries
for( var i = 0; i < V.length; i++ ){
var vid = V[ i ].id();
P[ vid ] = [];
g[ vid ] = 0;
d[ vid ] = Infinity;
}
g[ sid ] = 1; // sigma
d[ sid ] = 0; // distance to s
Q.push( sid );
while( !Q.empty() ){
var v = Q.pop();
S.push( v );
if( weighted ){
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j];
var vEle = cy.getElementById( v );
var edge;
if( vEle.edgesTo( w ).length > 0 ){
edge = vEle.edgesTo( w )[0];
} else {
edge = w.edgesTo( vEle )[0];
}
var edgeWeight = weightFn( edge );
w = w.id();
if( d[w] > d[v] + edgeWeight ){
d[w] = d[v] + edgeWeight;
if( Q.nodes.indexOf( w ) < 0 ){ //if w is not in Q
Q.push( w );
} else { // update position if w is in Q
Q.updateItem( w );
}
g[w] = 0;
P[w] = [];
}
if( d[w] == d[v] + edgeWeight ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
} else {
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j].id();
if( d[w] == Infinity ){
Q.push( w );
d[w] = d[v] + 1;
}
if( d[w] == d[v] + 1 ){
g[w] = g[w] + g[v];
P[w].push( v );
}
}
}
}
var e = {};
for( var i = 0; i < V.length; i++ ){
e[ V[ i ].id() ] = 0;
}
while( S.length > 0 ){
var w = S.pop();
for( var j = 0; j < P[w].length; j++ ){
var v = P[w][j];
e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]);
if( w != V[s].id() ){
C.set( w, C.get( w ) + e[w] );
}
}
}
}
var ret = {
betweenness: function( node ){
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node );
},
betweennessNormalized: function( node ){
if ( max == 0 )
return 0;
if( is.string( node ) ){
var node = cy.filter( node ).id();
} else {
var node = node.id();
}
return C.get( node ) / max;
}
};
// alias
ret.betweennessNormalised = ret.betweennessNormalized;
return ret;
}n/a
function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}...
do {
var component = cy.collection();
components.push( component );
var root = unvisited[0];
visitInComponent( root, component );
self.bfs({
directed: false,
roots: root,
visit: function( v, e, u, i, depth ){
visitInComponent( v, component );
}
} );
...function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}...
this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */
this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */
this.onFulfilled = []; /* initial handlers */
this.onRejected = []; /* initial handlers */
/* provide optional information-hiding proxy */
this.proxy = {
then: this.then.bind( this )
};
/* support optional executor function */
if( typeof executor === 'function' )
executor.call( this, this.fulfill.bind( this ), this.reject.bind( this ) );
};
...boundingBox = function ( options ){
// the main usecase is ele.boundingBox() for a single element with no/def options
// specified s.t. the cache is used, so check for this case to make it faster by
// avoiding the overhead of the rest of the function
if( this.length === 1 && this[0]._private.bbCache && (options === undefined || options.useCache === undefined || options.useCache
=== true) ){
if( options === undefined ){
options = defBbOpts;
} else {
options = filledBbOpts( options );
}
return cachedBoundingBoxImpl( this[0], options );
}
var bounds = {
x1: Infinity,
y1: Infinity,
x2: -Infinity,
y2: -Infinity
};
options = options || util.staticEmptyObject();
var opts = filledBbOpts( options );
var eles = this;
var cy = eles.cy();
var styleEnabled = cy.styleEnabled();
if( styleEnabled ){
this.recalculateRenderedStyle( opts.useCache );
}
for( var i = 0; i < eles.length; i++ ){
var ele = eles[i];
if( styleEnabled && ele.isEdge() && ele.pstyle('curve-style').strValue === 'bezier' ){
ele.parallelEdges().recalculateRenderedStyle( opts.useCache ); // n.b. ele.parallelEdges() single is cached
}
updateBoundsFromBox( bounds, cachedBoundingBoxImpl( ele, opts ) );
}
bounds.x1 = noninf( bounds.x1 );
bounds.y1 = noninf( bounds.y1 );
bounds.x2 = noninf( bounds.x2 );
bounds.y2 = noninf( bounds.y2 );
bounds.w = noninf( bounds.x2 - bounds.x1 );
bounds.h = noninf( bounds.y2 - bounds.y1 );
return bounds;
}...
return undefined; // for empty collection case
}
return this; // chaining
},
renderedBoundingBox: function( options ){
var bb = this.boundingBox( options );
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var x1 = bb.x1 * zoom + pan.x;
var x2 = bb.x2 * zoom + pan.x;
var y1 = bb.y1 * zoom + pan.y;
...boundingbox = function ( options ){
// the main usecase is ele.boundingBox() for a single element with no/def options
// specified s.t. the cache is used, so check for this case to make it faster by
// avoiding the overhead of the rest of the function
if( this.length === 1 && this[0]._private.bbCache && (options === undefined || options.useCache === undefined || options.useCache
=== true) ){
if( options === undefined ){
options = defBbOpts;
} else {
options = filledBbOpts( options );
}
return cachedBoundingBoxImpl( this[0], options );
}
var bounds = {
x1: Infinity,
y1: Infinity,
x2: -Infinity,
y2: -Infinity
};
options = options || util.staticEmptyObject();
var opts = filledBbOpts( options );
var eles = this;
var cy = eles.cy();
var styleEnabled = cy.styleEnabled();
if( styleEnabled ){
this.recalculateRenderedStyle( opts.useCache );
}
for( var i = 0; i < eles.length; i++ ){
var ele = eles[i];
if( styleEnabled && ele.isEdge() && ele.pstyle('curve-style').strValue === 'bezier' ){
ele.parallelEdges().recalculateRenderedStyle( opts.useCache ); // n.b. ele.parallelEdges() single is cached
}
updateBoundsFromBox( bounds, cachedBoundingBoxImpl( ele, opts ) );
}
bounds.x1 = noninf( bounds.x1 );
bounds.y1 = noninf( bounds.y1 );
bounds.x2 = noninf( bounds.x2 );
bounds.y2 = noninf( bounds.y2 );
bounds.w = noninf( bounds.x2 - bounds.x1 );
bounds.h = noninf( bounds.y2 - bounds.y1 );
return bounds;
}n/a
function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}n/a
bypass = function ( name, value ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
if( is.plainObject( name ) ){ // then extend the bypass
var props = name;
style.applyBypass( this, props, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
} else if( is.string( name ) ){
if( value === undefined ){ // then get the property from the style
var ele = this[0];
if( ele ){
return style.getStylePropertyValue( ele, name );
} else { // empty collection => can't get any value
return;
}
} else { // then set the bypass with the property value
style.applyBypass( this, name, value, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
}
} else if( name === undefined ){
var ele = this[0];
if( ele ){
return style.getRawStyle( ele );
} else { // empty collection => can't get any value
return;
}
}
return this; // chaining
}n/a
cc = function ( options ){
options = options || {};
// root - mandatory!
if( options.root != null ){
if( is.string( options.root ) ){
// use it as a selector, e.g. "#rootID
var root = this.filter( options.root )[0];
} else {
var root = options.root[0];
}
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weight = options.weight;
} else {
var weight = function(){return 1;};
}
// directed - optional
if( options.directed != null && is.bool( options.directed ) ){
var directed = options.directed;
} else {
var directed = false;
}
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
// we need distance from this node to every other node
var dijkstra = this.dijkstra( {
root: root,
weight: weight,
directed: directed
} );
var totalDistance = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
if( nodes[ i ].id() != root.id() ){
var d = dijkstra.distanceTo( nodes[ i ] );
if( harmonic ){
totalDistance += 1 / d;
} else {
totalDistance += d;
}
}
}
return harmonic ? totalDistance : 1 / totalDistance;
}n/a
ccn = function ( options ){
options = options || {};
var cy = this.cy();
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
if( harmonic ){
currCloseness += 1 / d;
} else {
currCloseness += d;
}
}
}
if( !harmonic ){
currCloseness = 1 / currCloseness;
}
if( maxCloseness < currCloseness ){
maxCloseness = currCloseness;
}
closenesses[ nodes[ i ].id() ] = currCloseness;
}
return {
closeness: function( node ){
if( maxCloseness == 0 ){ return 0; }
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return closenesses[ node ] / maxCloseness;
}
};
}n/a
children = function ( selector ){
var children = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
children = children.concat( ele._private.children );
}
return this.spawn( children, { unique: true } ).filter( selector );
}...
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
case ':unanimated':
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
...classes = function ( classes ){
classes = ( classes || '' ).match( /\S+/g ) || [];
var self = this;
var changed = [];
var classesMap = {};
// fill in classes map
for( var i = 0; i < classes.length; i++ ){
var cls = classes[ i ];
classesMap[ cls ] = true;
}
// check and update each ele
for( var j = 0; j < self.length; j++ ){
var ele = self[ j ];
var _p = ele._private;
var eleClasses = _p.classes;
var changedEle = false;
// check if ele has all of the passed classes
for( var i = 0; i < classes.length; i++ ){
var cls = classes[ i ];
var eleHasClass = eleClasses[ cls ];
if( !eleHasClass ){
changedEle = true;
break;
}
}
// check if ele has classes outside of those passed
if( !changedEle ){
var classes = Object.keys( eleClasses );
for( var i = 0; i < classes.length; i++ ){
var eleCls = classes[i];
var eleHasClass = eleClasses[ eleCls ];
var specdClass = classesMap[ eleCls ]; // i.e. this class is passed to the function
if( eleHasClass && !specdClass ){
changedEle = true;
break;
}
}
}
if( changedEle ){
_p.classes = util.copy( classesMap );
changed.push( ele );
}
}
// trigger update style on those eles that had class changes
if( changed.length > 0 ){
this.spawn( changed )
.updateStyle()
.trigger( 'class' )
;
}
return self;
}...
checkSwitch( 'selectable', 'selectify', 'unselectify' );
checkSwitch( 'locked', 'lock', 'unlock' );
checkSwitch( 'grabbable', 'grabify', 'ungrabify' );
if( obj.classes != null ){
ele.classes( obj.classes );
}
cy.endBatch();
return this;
} else if( obj === undefined ){ // get
...function clearQueueImpl(){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
ele._private.animation.queue = [];
}
return this;
}n/a
clone = function (){
var cy = this.cy();
var elesArr = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var json = ele.json();
var clone = new Element( cy, json, false ); // NB no restore
elesArr.push( clone );
}
return new Collection( cy, elesArr );
}n/a
closedNeighborhood = function ( selector ){
return this.neighborhood().add( this ).filter( selector );
}n/a
closedNeighbourhood = function ( selector ){
return this.neighborhood().add( this ).filter( selector );
}n/a
closenessCentrality = function ( options ){
options = options || {};
// root - mandatory!
if( options.root != null ){
if( is.string( options.root ) ){
// use it as a selector, e.g. "#rootID
var root = this.filter( options.root )[0];
} else {
var root = options.root[0];
}
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weight = options.weight;
} else {
var weight = function(){return 1;};
}
// directed - optional
if( options.directed != null && is.bool( options.directed ) ){
var directed = options.directed;
} else {
var directed = false;
}
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
// we need distance from this node to every other node
var dijkstra = this.dijkstra( {
root: root,
weight: weight,
directed: directed
} );
var totalDistance = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
if( nodes[ i ].id() != root.id() ){
var d = dijkstra.distanceTo( nodes[ i ] );
if( harmonic ){
totalDistance += 1 / d;
} else {
totalDistance += d;
}
}
}
return harmonic ? totalDistance : 1 / totalDistance;
}n/a
closenessCentralityNormalised = function ( options ){
options = options || {};
var cy = this.cy();
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
if( harmonic ){
currCloseness += 1 / d;
} else {
currCloseness += d;
}
}
}
if( !harmonic ){
currCloseness = 1 / currCloseness;
}
if( maxCloseness < currCloseness ){
maxCloseness = currCloseness;
}
closenesses[ nodes[ i ].id() ] = currCloseness;
}
return {
closeness: function( node ){
if( maxCloseness == 0 ){ return 0; }
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return closenesses[ node ] / maxCloseness;
}
};
}n/a
closenessCentralityNormalized = function ( options ){
options = options || {};
var cy = this.cy();
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
if( harmonic ){
currCloseness += 1 / d;
} else {
currCloseness += d;
}
}
}
if( !harmonic ){
currCloseness = 1 / currCloseness;
}
if( maxCloseness < currCloseness ){
maxCloseness = currCloseness;
}
closenesses[ nodes[ i ].id() ] = currCloseness;
}
return {
closeness: function( node ){
if( maxCloseness == 0 ){ return 0; }
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return closenesses[ node ] / maxCloseness;
}
};
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}n/a
collection = function (){
if( is.collection( this ) ){
return this;
} else { // an element
return new Collection( this._private.cy, [ this ] );
}
}...
return undefined;
} else {
return null != obj && obj instanceof HTMLElement;
}
},
elementOrCollection: function( obj ){
return is.element( obj ) || is.collection( obj );
},
element: function( obj ){
return instanceStr( obj ) === 'collection' && obj._private.single;
},
collection: function( obj ){
...commonAncestors = function ( selector ){
var ancestors;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parents = ele.parents();
ancestors = ancestors || parents;
ancestors = ancestors.intersect( parents ); // current list must be common with current ele parents set
}
return ancestors.filter( selector );
}n/a
complement = function (){
var cy = this._private.cy;
return cy.mutableElements().not( this );
}n/a
components = function (){
var self = this;
var cy = self.cy();
var visited = self.spawn();
var unvisited = self.nodes().spawnSelf();
var components = [];
var visitInComponent = function( node, component ){
visited.merge( node );
unvisited.unmerge( node );
component.merge( node );
};
if( unvisited.empty() ){ return self.spawn(); }
do {
var component = cy.collection();
components.push( component );
var root = unvisited[0];
visitInComponent( root, component );
self.bfs({
directed: false,
roots: root,
visit: function( v, e, u, i, depth ){
visitInComponent( v, component );
}
} );
} while( unvisited.length > 0 );
return components.map(function( component ){
var connectedEdges = component.connectedEdges().stdFilter(function( edge ){
return component.anySame( edge.source() ) && component.anySame( edge.target() );
});
return component.union( connectedEdges );
});
}...
clientWidth: cy.width(),
clientHeight: cy.width(),
boundingBox: math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} )
};
var components = options.eles.components();
var id2cmptId = {};
for( var i = 0; i < components.length; i++ ){
var component = components[ i ];
for( var j = 0; j < component.length; j++ ){
var node = component[ j ];
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
} else if( struct.parent !== undefined ){ // move node to new parent
var parentId = struct.parent;
var parentExists = parentId === null || cy.hasElementWithId( parentId );
if( parentExists ){
var jsons = this.jsons();
var descs = this.descendants();
var descsEtcJsons = descs.union( descs.union( this ).connectedEdges() ).jsons();
this.remove(); // NB: also removes descendants and their connected edges
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
ele.source()[0]._private.traversalCache = null;
ele.target()[0]._private.traversalCache = null;
}
var toUpdateStyle;
if( cy_p.hasCompoundNodes ){
toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() );
} else {
toUpdateStyle = restored;
}
toUpdateStyle.updateStyle( notifyRenderer );
if( notifyRenderer ){
...copy = function (){
var cy = this.cy();
var elesArr = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var json = ele.json();
var clone = new Element( cy, json, false ); // NB no restore
elesArr.push( clone );
}
return new Collection( cy, elesArr );
}...
changedEle = true;
break;
}
}
}
if( changedEle ){
_p.classes = util.copy( classesMap );
changed.push( ele );
}
}
// trigger update style on those eles that had class changes
if( changed.length > 0 ){
...createLayout = function ( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}n/a
css = function ( name, value ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
if( is.plainObject( name ) ){ // then extend the bypass
var props = name;
style.applyBypass( this, props, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
} else if( is.string( name ) ){
if( value === undefined ){ // then get the property from the style
var ele = this[0];
if( ele ){
return style.getStylePropertyValue( ele, name );
} else { // empty collection => can't get any value
return;
}
} else { // then set the bypass with the property value
style.applyBypass( this, name, value, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
}
} else if( name === undefined ){
var ele = this[0];
if( ele ){
return style.getRawStyle( ele );
} else { // empty collection => can't get any value
return;
}
}
return this; // chaining
}...
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
},
show: function(){
this.css( 'display', 'element' );
return this; // chaining
},
hide: function(){
this.css( 'display', 'none' );
return this; // chaining
},
...cy = function (){
return this._private.cy;
}...
} else {
q = tAni.current;
}
q.push( this );
// add to the animation loop pool
if( is.elementOrCollection( _p.target ) ){
_p.target.cy().addToAnimationPool( _p.target );
}
_p.hooked = true;
}
return this;
},
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}...
return function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
...dc = function ( options ){
options = options || {};
var callingEles = this;
// root - mandatory!
if( options != null && options.root != null ){
var root = is.string( options.root ) ? this.filter( options.root )[0] : options.root[0];
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){
return 1;
};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
// alpha - optional
if( options.alpha != null && is.number( options.alpha ) ){
var alpha = options.alpha;
} else {
alpha = 0;
}
if( !directed ){
var connEdges = root.connectedEdges().intersection( callingEles );
var k = connEdges.length;
var s = 0;
// Now, sum edge weights
for( var i = 0; i < connEdges.length; i++ ){
var edge = connEdges[ i ];
s += weightFn( edge );
}
return {
degree: Math.pow( k, 1 - alpha ) * Math.pow( s, alpha )
};
} else {
var incoming = root.connectedEdges( 'edge[target = "' + root.id() + '"]' ).intersection( callingEles );
var outgoing = root.connectedEdges( 'edge[source = "' + root.id() + '"]' ).intersection( callingEles );
var k_in = incoming.length;
var k_out = outgoing.length;
var s_in = 0;
var s_out = 0;
// Now, sum incoming edge weights
for( var i = 0; i < incoming.length; i++ ){
var edge = incoming[ i ];
s_in += weightFn( edge );
}
// Now, sum outgoing edge weights
for( var i = 0; i < outgoing.length; i++ ){
var edge = outgoing[ i ];
s_out += weightFn( edge );
}
return {
indegree: Math.pow( k_in, 1 - alpha ) * Math.pow( s_in, alpha ),
outdegree: Math.pow( k_out, 1 - alpha ) * Math.pow( s_out, alpha )
};
}
}n/a
dcn = function ( options ){
options = options || {};
var cy = this.cy();
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var nodes = this.nodes();
var numNodes = nodes.length;
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
degree: function( node ){
if( maxDegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return degrees[ node ] / maxDegree;
}
};
} else {
var indegrees = {};
var outdegrees = {};
var maxIndegree = 0;
var maxOutdegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxIndegree < currDegree.indegree )
maxIndegree = currDegree.indegree;
if( maxOutdegree < currDegree.outdegree )
maxOutdegree = currDegree.outdegree;
indegrees[ node.id() ] = currDegree.indegree;
outdegrees[ node.id() ] = currDegree.outdegree;
}
return {
indegree: function( node ){
if ( maxIndegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return indegrees[ node ] / maxIndegree;
},
outdegree: function( node ){
if ( maxOutdegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return outdegrees[ node ] / maxOutdegree;
}
};
}
}n/a
degree = function ( includeLoops ){
var self = this;
if( includeLoops === undefined ){
includeLoops = true;
}
if( self.length === 0 ){ return; }
if( self.isNode() && !self.removed() ){
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
} else {
return;
}
}...
util.extend( elesfn, {
totalDegree: function( includeLoops ){
var total = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
total += nodes[ i ].degree( includeLoops );
}
return total;
}
} );
module.exports = elesfn;
...degreeCentrality = function ( options ){
options = options || {};
var callingEles = this;
// root - mandatory!
if( options != null && options.root != null ){
var root = is.string( options.root ) ? this.filter( options.root )[0] : options.root[0];
} else {
return undefined;
}
// weight - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){
return 1;
};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
// alpha - optional
if( options.alpha != null && is.number( options.alpha ) ){
var alpha = options.alpha;
} else {
alpha = 0;
}
if( !directed ){
var connEdges = root.connectedEdges().intersection( callingEles );
var k = connEdges.length;
var s = 0;
// Now, sum edge weights
for( var i = 0; i < connEdges.length; i++ ){
var edge = connEdges[ i ];
s += weightFn( edge );
}
return {
degree: Math.pow( k, 1 - alpha ) * Math.pow( s, alpha )
};
} else {
var incoming = root.connectedEdges( 'edge[target = "' + root.id() + '"]' ).intersection( callingEles );
var outgoing = root.connectedEdges( 'edge[source = "' + root.id() + '"]' ).intersection( callingEles );
var k_in = incoming.length;
var k_out = outgoing.length;
var s_in = 0;
var s_out = 0;
// Now, sum incoming edge weights
for( var i = 0; i < incoming.length; i++ ){
var edge = incoming[ i ];
s_in += weightFn( edge );
}
// Now, sum outgoing edge weights
for( var i = 0; i < outgoing.length; i++ ){
var edge = outgoing[ i ];
s_out += weightFn( edge );
}
return {
indegree: Math.pow( k_in, 1 - alpha ) * Math.pow( s_in, alpha ),
outdegree: Math.pow( k_out, 1 - alpha ) * Math.pow( s_out, alpha )
};
}
}...
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
...degreeCentralityNormalised = function ( options ){
options = options || {};
var cy = this.cy();
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var nodes = this.nodes();
var numNodes = nodes.length;
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
degree: function( node ){
if( maxDegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return degrees[ node ] / maxDegree;
}
};
} else {
var indegrees = {};
var outdegrees = {};
var maxIndegree = 0;
var maxOutdegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxIndegree < currDegree.indegree )
maxIndegree = currDegree.indegree;
if( maxOutdegree < currDegree.outdegree )
maxOutdegree = currDegree.outdegree;
indegrees[ node.id() ] = currDegree.indegree;
outdegrees[ node.id() ] = currDegree.outdegree;
}
return {
indegree: function( node ){
if ( maxIndegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return indegrees[ node ] / maxIndegree;
},
outdegree: function( node ){
if ( maxOutdegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return outdegrees[ node ] / maxOutdegree;
}
};
}
}n/a
degreeCentralityNormalized = function ( options ){
options = options || {};
var cy = this.cy();
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var nodes = this.nodes();
var numNodes = nodes.length;
if( !directed ){
var degrees = {};
var maxDegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxDegree < currDegree.degree )
maxDegree = currDegree.degree;
degrees[ node.id() ] = currDegree.degree;
}
return {
degree: function( node ){
if( maxDegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return degrees[ node ] / maxDegree;
}
};
} else {
var indegrees = {};
var outdegrees = {};
var maxIndegree = 0;
var maxOutdegree = 0;
for( var i = 0; i < numNodes; i++ ){
var node = nodes[ i ];
// add current node to the current options object and call degreeCentrality
var currDegree = this.degreeCentrality( util.extend( {}, options, {root: node} ) );
if( maxIndegree < currDegree.indegree )
maxIndegree = currDegree.indegree;
if( maxOutdegree < currDegree.outdegree )
maxOutdegree = currDegree.outdegree;
indegrees[ node.id() ] = currDegree.indegree;
outdegrees[ node.id() ] = currDegree.outdegree;
}
return {
indegree: function( node ){
if ( maxIndegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return indegrees[ node ] / maxIndegree;
},
outdegree: function( node ){
if ( maxOutdegree == 0 )
return 0;
if( is.string( node ) ){
// from is a selector string
var node = (cy.filter( node )[0]).id();
} else {
// from is a node
var node = node.id();
}
return outdegrees[ node ] / maxOutdegree;
}
};
}
}n/a
function delayImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animate( {
delay: time,
duration: time,
complete: complete
} );
}...
if( !anyPrev ){ return; }
_p.transitioning = true;
ele.stop();
if( delay > 0 ){
ele.delay( delay );
}
ele.animate( {
css: css
}, {
duration: duration,
easing: ele.pstyle( 'transition-timing-function' ).value,
...function delayAnimationImpl( time, complete ){
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
return this.animation( {
delay: time,
duration: time,
complete: complete
} );
}n/a
function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}n/a
descendants = function ( selector ){
var elements = [];
function add( eles ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
elements.push( ele );
if( ele.children().nonempty() ){
add( ele.children() );
}
}
}
add( this.children() );
return this.spawn( elements, { unique: true } ).filter( selector );
}...
} ) ){ return false; }
if( !confirmRelations( query.child, function(){
return ele.children();
} ) ){ return false; }
if( !confirmRelations( query.descendant, function(){
return ele.descendants();
} ) ){ return false; }
// we've reached the end, so we've matched everything for this query
return true;
}; // queryMatches
// filter an existing collection
...deselect = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
function searchFn( roots, fn, directed ){
var options;
if( is.plainObject( roots ) && !is.elementOrCollection( roots ) ){
options = roots;
roots = options.roots || options.root;
fn = options.visit;
directed = options.directed;
}
directed = arguments.length === 2 && !is.fn( fn ) ? fn : directed;
fn = is.fn( fn ) ? fn : function(){};
var cy = this._private.cy;
var v = roots = is.string( roots ) ? this.filter( roots ) : roots;
var Q = [];
var connectedNodes = [];
var connectedBy = {};
var id2depth = {};
var V = {};
var j = 0;
var found;
var nodes = this.nodes();
var edges = this.edges();
// enqueue v
for( var i = 0; i < v.length; i++ ){
if( v[ i ].isNode() ){
Q.unshift( v[ i ] );
if( params.bfs ){
V[ v[ i ].id() ] = true;
connectedNodes.push( v[ i ] );
}
id2depth[ v[ i ].id() ] = 0;
}
}
while( Q.length !== 0 ){
var v = params.bfs ? Q.shift() : Q.pop();
if( params.dfs ){
if( V[ v.id() ] ){ continue; }
V[ v.id() ] = true;
connectedNodes.push( v );
}
var depth = id2depth[ v.id() ];
var prevEdge = connectedBy[ v.id() ];
var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];
var ret;
ret = fn( v, prevEdge, prevNode, j++, depth );
if( ret === true ){
found = v;
break;
}
if( ret === false ){
break;
}
var vwEdges = v.connectedEdges( directed ? function( ele ){ return ele.data( 'source' ) === v.id(); } : undefined ).intersect
( edges );
for( var i = 0; i < vwEdges.length; i++ ){
var e = vwEdges[ i ];
var w = e.connectedNodes( function( n ){ return n.id() !== v.id(); } ).intersect( nodes );
if( w.length !== 0 && !V[ w.id() ] ){
w = w[0];
Q.push( w );
if( params.bfs ){
V[ w.id() ] = true;
connectedNodes.push( w );
}
connectedBy[ w.id() ] = e;
id2depth[ w.id() ] = id2depth[ v.id() ] + 1;
}
}
}
var connectedEles = [];
for( var i = 0; i < connectedNodes.length; i++ ){
var node = connectedNodes[ i ];
var edge = connectedBy[ node.id() ];
if( edge ){
connectedEles.push( edge );
}
connectedEles.push( node );
}
return {
path: cy.collection( connectedEles, { unique: true } ),
found: cy.collection( found )
};
}n/a
diff = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var left = [];
var right = [];
var both = [];
var col1 = this;
var col2 = other;
var add = function( col, other, retEles ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( inOther ){
both.push( ele );
} else {
retEles.push( ele );
}
}
};
add( col1, col2, left );
add( col2, col1, right );
return {
left: this.spawn( left, { unique: true } ),
right: this.spawn( right, { unique: true } ),
both: this.spawn( both, { unique: true } )
};
}n/a
difference = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}n/a
dijkstra = function ( root, weightFn, directed ){
var options;
if( is.plainObject( root ) && !is.elementOrCollection( root ) ){
options = root;
root = options.root;
weightFn = options.weight;
directed = options.directed;
}
var cy = this._private.cy;
weightFn = is.fn( weightFn ) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)
var source = is.string( root ) ? this.filter( root )[0] : root[0];
var dist = {};
var prev = {};
var knownDist = {};
var edges = this.edges().filter( function( ele ){ return !ele.isLoop(); } );
var nodes = this.nodes();
var getDist = function( node ){
return dist[ node.id() ];
};
var setDist = function( node, d ){
dist[ node.id() ] = d;
Q.updateItem( node );
};
var Q = new Heap( function( a, b ){
return getDist( a ) - getDist( b );
} );
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
dist[ node.id() ] = node.same( source ) ? 0 : Infinity;
Q.push( node );
}
var distBetween = function( u, v ){
var uvs = ( directed ? u.edgesTo( v ) : u.edgesWith( v ) ).intersect( edges );
var smallestDistance = Infinity;
var smallestEdge;
for( var i = 0; i < uvs.length; i++ ){
var edge = uvs[ i ];
var weight = weightFn( edge );
if( weight < smallestDistance || !smallestEdge ){
smallestDistance = weight;
smallestEdge = edge;
}
}
return {
edge: smallestEdge,
dist: smallestDistance
};
};
while( Q.size() > 0 ){
var u = Q.pop();
var smalletsDist = getDist( u );
var uid = u.id();
knownDist[ uid ] = smalletsDist;
if( smalletsDist === Math.Infinite ){
break;
}
var neighbors = u.neighborhood().intersect( nodes );
for( var i = 0; i < neighbors.length; i++ ){
var v = neighbors[ i ];
var vid = v.id();
var vDist = distBetween( u, v );
var alt = smalletsDist + vDist.dist;
if( alt < getDist( v ) ){
setDist( v, alt );
prev[ vid ] = {
node: u,
edge: vDist.edge
};
}
} // for
} // while
return {
distanceTo: function( node ){
var target = is.string( node ) ? nodes.filter( node )[0] : node[0];
return knownDist[ target.id() ];
},
pathTo: function( node ){
var target = is.string( node ) ? nodes.filter( node )[0] : node[0];
var S = [];
var u = target;
if( target.length > 0 ){
S.unshift( target );
while( prev[ u.id() ] ){
var p = prev[ u.id() ];
S.unshift( p.edge );
S.unshift( p.node );
u = p.node;
}
}
return cy.collection( S );
}
};
}...
var harmonic = options.harmonic;
if( harmonic === undefined ){
harmonic = true;
}
// we need distance from this node to every other node
var dijkstra = this.dijkstra( {
root: root,
weight: weight,
directed: directed
} );
var totalDistance = 0;
var nodes = this.nodes();
...each = function ( fn, thisArg ){
if( is.fn( fn ) ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var ret = thisArg ? fn.apply( thisArg, [ ele, i, this ] ) : fn( ele, i, this );
if( ret === false ){ break; } // exit each early on return false
}
}
return this;
}n/a
edges = function ( selector ){
return this.filter( function( ele, i ){
return ele.isEdge();
} ).filter( selector );
}...
var defaults = {
codirected: false
};
params = util.extend( {}, defaults, params );
return function parallelEdgesImpl( selector ){ // micro-optimised for renderer
var elements = [];
var edges = this.edges();
var p = params;
// look at all the edges in the collection
for( var i = 0; i < edges.length; i++ ){
var edge1 = edges[ i ];
var edge1_p = edge1._private;
var src1 = edge1_p.source;
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
if( weighted ){
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j];
var vEle = cy.getElementById( v );
var edge;
if( vEle.edgesTo( w ).length > 0 ){
edge = vEle.edgesTo( w )[0];
} else {
edge = w.edgesTo( vEle )[0];
}
var edgeWeight = weightFn( edge );
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
var node = nodes[ i ];
dist[ node.id() ] = node.same( source ) ? 0 : Infinity;
Q.push( node );
}
var distBetween = function( u, v ){
var uvs = ( directed ? u.edgesTo( v ) : u.edgesWith( v ) ).intersect( edges );
var smallestDistance = Infinity;
var smallestEdge;
for( var i = 0; i < uvs.length; i++ ){
var edge = uvs[ i ];
var weight = weightFn( edge );
...effectiveOpacity = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return 1; }
var hasCompoundNodes = cy.hasCompoundNodes();
var ele = this[0];
if( ele ){
var _p = ele._private;
var parentOpacity = ele.pstyle( 'opacity' ).value;
if( !hasCompoundNodes ){ return parentOpacity; }
var parents = !_p.data.parent ? null : ele.parents();
if( parents ){
for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
var opacity = parent.pstyle( 'opacity' ).value;
parentOpacity = opacity * parentOpacity;
}
}
return parentOpacity;
}
}...
var ele = this[0];
var hasCompoundNodes = ele.cy().hasCompoundNodes();
if( ele ){
if( !hasCompoundNodes ){
return ele.pstyle( 'opacity' ).value === 0;
} else {
return ele.effectiveOpacity() === 0;
}
}
},
backgrounding: function(){
var cy = this.cy();
if( !cy.styleEnabled() ){ return false; }
...element = function (){
return this[0];
}...
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
...function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
events.push( {
type: type,
namespace: namespace
} );
}
} else if( eventsIsObject ){ // put in length 1 array
var eventArgObj = events;
events = [ eventArgObj ];
}
if( extraParams ){
if( !is.array( extraParams ) ){ // make sure extra params are in an array if specified
extraParams = [ extraParams ];
}
} else { // otherwise, we've got nothing
extraParams = [];
}
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
evt.target = evt.target || triggerer;
evt.cy = evt.cy || cy;
} else { // then we have to make one
evt = new Event( evtObj, {
target: triggerer,
cy: cy,
namespace: evtObj.namespace
} );
}
// if a layout was specified, then put it in the typed event
if( evtObj.layout ){
evt.layout = evtObj.layout;
}
// if triggered by layout, put in event
if( params.layout ){
evt.layout = triggerer;
}
// create a rendered position based on the passed position
if( evt.position ){
var pos = evt.position;
var zoom = cy.zoom();
var pan = cy.pan();
evt.renderedPosition = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
}
if( fnToTrigger ){ // then override the listeners list with just the one we specified
listeners = [ {
namespace: evt.namespace,
type: evt.type,
callback: fnToTrigger
} ];
}
for( var k = 0; k < listeners.length; k++ ){ // check each listener
var lis = listeners[ k ];
var nsMatches = !lis.namespace || lis.namespace === evt.namespace || lis.namespace === define.event.universalNamespace;
var typeMatches = lis.type === evt.type;
var targetMatches = lis.delegated ? ( triggerer !== evt.target && is.element( evt.target ) && lis.selObj.matches( evt.target
) ) : (true); // we're not going to validate the hierarchy; that's too expensive
var listenerMatches = nsMatches && typeMatches && targetMatches;
if( listenerMatches ){ // then trigger it
var args = [ evt ];
args = args.concat( extraParams ); // add extra params to args list
if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener
listeners.splice( k, 1 );
k--;
}
if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders
var binders = lis.binders;
for( var l = 0; l < binders.length; l++ ){
var binder = b ...n/a
empty = function (){
return this.length === 0;
}...
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
break;
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) === ele.data( 'target' );
break;
case ':simple':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) !== ele.data( 'target' );
break;
...eq = function ( i ){
return this[ i ] || this.spawn();
}n/a
every = function ( fn, thisArg ){
for( var i = 0; i < this.length; i++ ){
var ret = !thisArg ? fn( this[ i ], i, this ) : fn.apply( thisArg, [ this[ i ], i, this ] );
if( !ret ){
return false;
}
}
return true;
}n/a
filter = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}...
meta: [],
// fake selectors
collection: null, // a collection to match against
filter: null, // filter function
// these are defined in the upward direction rather than down (e.g. child)
// because we need to go up in Selector.filter()
parent: null, // parent query obj
ancestor: null, // ancestor query obj
subject: null, // defines subject in compound query (subject query obj; points to self if subject)
// use these only when subject has been defined
child: null,
descendant: null
...filterFn = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}n/a
first = function (){
return this[0] || this.spawn();
}n/a
flashClass = function ( classes, duration ){
var self = this;
if( duration == null ){
duration = 250;
} else if( duration === 0 ){
return self; // nothing to do really
}
self.addClass( classes );
setTimeout( function(){
self.removeClass( classes );
}, duration );
return self;
}n/a
floydWarshall = function ( options ){
options = options || {};
var cy = this.cy();
// Weight function - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
// mapping: node id -> position in nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Initialize distance matrix
var dist = [];
for( var i = 0; i < numNodes; i++ ){
var newRow = new Array( numNodes );
for( var j = 0; j < numNodes; j++ ){
if( i == j ){
newRow[ j ] = 0;
} else {
newRow[ j ] = Infinity;
}
}
dist.push( newRow );
}
// Initialize matrix used for path reconstruction
// Initialize distance matrix
var next = [];
var edgeNext = [];
var initMatrix = function( next ){
for( var i = 0; i < numNodes; i++ ){
var newRow = new Array( numNodes );
for( var j = 0; j < numNodes; j++ ){
newRow[ j ] = undefined;
}
next.push( newRow );
}
};
initMatrix( next );
initMatrix( edgeNext );
// Process edges
for( var i = 0; i < edges.length ; i++ ){
var sourceIndex = id2position[ edges[ i ].source().id() ];
var targetIndex = id2position[ edges[ i ].target().id() ];
var weight = weightFn( edges[ i ] );
// Check if already process another edge between same 2 nodes
if( dist[ sourceIndex ][ targetIndex ] > weight ){
dist[ sourceIndex ][ targetIndex ] = weight;
next[ sourceIndex ][ targetIndex ] = targetIndex;
edgeNext[ sourceIndex ][ targetIndex ] = edges[ i ];
}
}
// If undirected graph, process 'reversed' edges
if( !directed ){
for( var i = 0; i < edges.length ; i++ ){
var sourceIndex = id2position[ edges[ i ].target().id() ];
var targetIndex = id2position[ edges[ i ].source().id() ];
var weight = weightFn( edges[ i ] );
// Check if already process another edge between same 2 nodes
if( dist[ sourceIndex ][ targetIndex ] > weight ){
dist[ sourceIndex ][ targetIndex ] = weight;
next[ sourceIndex ][ targetIndex ] = targetIndex;
edgeNext[ sourceIndex ][ targetIndex ] = edges[ i ];
}
}
}
// Main loop
for( var k = 0; k < numNodes; k++ ){
for( var i = 0; i < numNodes; i++ ){
for( var j = 0; j < numNodes; j++ ){
if( dist[ i ][ k ] + dist[ k ][ j ] < dist[ i ][ j ] ){
dist[ i ][ j ] = dist[ i ][ k ] + dist[ k ][ j ];
next[ i ][ j ] = next[ i ][ k ];
}
}
}
}
// Build result object
var position2id = [];
for( var i = 0; i < numNodes; i++ ){
position2id.push( nodes[ i ].id() );
}
var res = {
distance: function( from, to ){
if( is.string( from ) ){
// from is a selector string
var fromId = (cy.filter( from )[0]).id();
} else {
// from is a node
var fromId = from.id();
}
if( is.string( to ) ){
// to is a selector string
var toId = (cy.filter( to )[0]).id();
} else {
// to is a node
var toId = to.id();
}
return dist[ id2position[ fromId ] ][ id2position[ toId ] ];
},
path: function( from, to ){
var reconstructPathAux = function( from, to, next, position2id, edgeNext ){
if( from === to ){
return cy.getElementById( position2id[ from ] );
}
if( next[ from ][ to ] === undefined ){
return undefined;
}
var path = [ cy.getElementById( position2id[ from ] ) ];
var prev = from;
while( from !== to ){
prev = from;
from = next[ from ][ to ];
var edge = edgeNex ......
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
...fnFilter = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}n/a
forEach = function ( fn, thisArg ){
if( is.fn( fn ) ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var ret = thisArg ? fn.apply( thisArg, [ ele, i, this ] ) : fn( ele, i, this );
if( ret === false ){ break; } // exit each early on return false
}
}
return this;
}...
proto[ pName ] = pVal; // take impl from base
}
for( var pName in rProto ){
proto[ pName ] = rProto[ pName ]; // take impl from registrant
}
bProto.clientFunctions.forEach( function( name ){
proto[ name ] = proto[ name ] || function(){
util.error( 'Renderer does not implement `renderer.' + name + '()` on its prototype' );
};
} );
ext = Renderer;
...getElementById = function ( id ){
var cy = this._private.cy;
var ele = this._private.ids[ id ];
return ele ? ele : new Collection( cy ); // get ele or empty collection
}...
var elesfn = ({
parent: function( selector ){
var parents = [];
var cy = this._private.cy;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parent = cy.getElementById( ele._private.data.parent );
if( parent.size() > 0 ){
parents.push( parent );
}
}
return this.spawn( parents, { unique: true } ).filter( selector );
...grabbable = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':removed':
allColonSelectorsMatch = ele.removed();
break;
case ':inside':
allColonSelectorsMatch = !ele.removed();
break;
case ':grabbable':
allColonSelectorsMatch = ele.grabbable();
break;
case ':ungrabbable':
allColonSelectorsMatch = !ele.grabbable();
break;
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
...grabbed = function (){
var ele = this[0];
if( ele ){
return ele._private.grabbed;
}
}...
case ':hidden':
allColonSelectorsMatch = !ele.visible();
break;
case ':transparent':
allColonSelectorsMatch = ele.transparent();
break;
case ':grabbed':
allColonSelectorsMatch = ele.grabbed();
break;
case ':free':
allColonSelectorsMatch = !ele.grabbed();
break;
case ':removed':
allColonSelectorsMatch = ele.removed();
break;
...grabify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
group = function (){
var ele = this[0];
if( ele ){
return ele._private.group;
}
}...
'use strict';
var elesfn = ({
isNode: function(){
return this.group() === 'nodes';
},
isEdge: function(){
return this.group() === 'edges';
},
isLoop: function(){
...hasClass = function ( className ){
var ele = this[0];
return ( ele != null && ele._private.classes[ className ] ) ? true : false;
}...
if( !allIdsMatch ) return false;
// check classes
var allClassesMatch = true;
for( var k = 0; k < query.classes.length; k++ ){
var cls = query.classes[ k ];
allClassesMatch = allClassesMatch && ele.hasClass( cls );
if( !allClassesMatch ) break;
}
if( !allClassesMatch ) return false;
// generic checking for data/metadata
var operandsMatch = function( params ){
...hasElementWithId = function ( id ){
return !!this._private.ids[ id ];
}...
if( !allMetaMatches ){
return false;
}
// check collection
if( query.collection != null ){
var matchesAny = query.collection.hasElementWithId( ele.id() );
if( !matchesAny ){
return false;
}
}
// check filter function
...function dimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
if( ele.isParent() ){
return _p[ opts.autoName ] || 0;
}
var d = ele.pstyle( opts.name );
switch( d.strValue ){
case 'label':
return _p.rstyle[ opts.labelName ] || 0;
default:
return d.pfValue;
}
} else {
return 1;
}
}
}...
};
}
var eleTakesUpSpace = function( ele ){
return (
ele.pstyle( 'display' ).value === 'element'
&& ele.width() !== 0
&& ( ele.isNode() ? ele.height() !== 0 : true )
);
};
elesfn.takesUpSpace = defineDerivedStateFunction({
ok: eleTakesUpSpace
});
...hidden = function (){
var ele = this[0];
if( ele ){
return !ele.visible();
}
}n/a
hide = function (){
this.css( 'display', 'none' );
return this; // chaining
}n/a
id = function (){
var ele = this[0];
if( ele ){
return ele._private.data.id;
}
}...
if( !allMetaMatches ){
return false;
}
// check collection
if( query.collection != null ){
var matchesAny = query.collection.hasElementWithId( ele.id() );
if( !matchesAny ){
return false;
}
}
// check filter function
...inactive = function (){
var ele = this[0];
if( ele ){
return !ele._private.active;
}
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
var defineDagAllHops = function( params ){
return function( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
...indegree = function ( includeLoops ){
var self = this;
if( includeLoops === undefined ){
includeLoops = true;
}
if( self.length === 0 ){ return; }
if( self.isNode() && !self.removed() ){
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
} else {
return;
}
}n/a
inside = function (){
var ele = this[0];
return ele && !ele._private.removed;
}n/a
instanceString = function (){
return 'collection';
}...
var typeofstr = typeof '';
var typeofobj = typeof {};
var typeoffn = typeof function(){};
var typeofhtmlele = typeof HTMLElement;
var instanceStr = function( obj ){
return obj && obj.instanceString && is.fn( obj.instanceString ) ? obj.instanceString
() : null;
};
var is = {
defined: function( obj ){
return obj != null; // not undefined or null
},
...interactive = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return true; }
var ele = this[0];
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele ){
var _p = ele._private;
if( !ok( ele ) ){ return false; }
if( ele.isNode() ){
if( hasCompoundNodes ){
var parents = _p.data.parent ? ele.parents() : null;
if( parents ){ for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
if( !parentOk( parent ) ){ return false; }
} }
}
return true;
} else {
return edgeOkViaNode( _p.source ) && edgeOkViaNode( _p.target );
}
}
}...
edgeOkViaNode: eleTakesUpSpace
});
elesfn.noninteractive = function(){
var ele = this[0];
if( ele ){
return !ele.interactive();
}
};
var eleVisible = function( ele ){
return (
ele.pstyle( 'visibility' ).value === 'visible'
&& ele.pstyle( 'opacity' ).pfValue !== 0
...intersect = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}...
collection = this.cy().collection( collection );
// cheap extra check
if( this.length !== collection.length ){
return false;
}
return this.intersect( collection ).length === this.length;
},
anySame: function( collection ){
collection = this.cy().collection( collection );
return this.intersect( collection ).length > 0;
},
...intersection = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}...
var alpha = options.alpha;
} else {
alpha = 0;
}
if( !directed ){
var connEdges = root.connectedEdges().intersection( callingEles );
var k = connEdges.length;
var s = 0;
// Now, sum edge weights
for( var i = 0; i < connEdges.length; i++ ){
var edge = connEdges[ i ];
s += weightFn( edge );
...is = function ( selector ){
return this.filter( selector ).length > 0;
}n/a
isChild = function (){
var ele = this[0];
if( ele ){
return ele._private.data.parent !== undefined && ele.parent().length !== 0;
}
}n/a
isEdge = function (){
return this.group() === 'edges';
}...
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
break;
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) ===
ele.data( 'target' );
break;
case ':simple':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) !== ele.data( 'target' );
break;
case ':active':
allColonSelectorsMatch = ele.active();
break;
...isLoop = function (){
return this.isEdge() && this.source().id() === this.target().id();
}...
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
...isNode = function (){
return this.group() === 'nodes';
}...
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
case ':unanimated':
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
...isParent = function (){
var ele = this[0];
if( ele ){
return ele._private.children.length !== 0;
}
}...
allowGetting: true,
validKeys: [ 'x', 'y' ],
onSet: function( eles ){
var updatedEles = eles.updateCompoundBounds();
updatedEles.rtrigger( 'position' );
},
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
// position but no notification to renderer
silentPosition: define.data( {
field: 'position',
bindingEvent: 'position',
...isSimple = function (){
return this.isEdge() && this.source().id() !== this.target().id();
}n/a
json = function ( obj ){
var ele = this.element();
var cy = this.cy();
if( ele == null && obj ){ return this; } // can't set to no eles
if( ele == null ){ return undefined; } // can't get from no eles
var p = ele._private;
if( is.plainObject( obj ) ){ // set
cy.startBatch();
if( obj.data ){
ele.data( obj.data );
}
if( obj.position ){
ele.position( obj.position );
}
// ignore group -- immutable
var checkSwitch = function( k, trueFnName, falseFnName ){
var obj_k = obj[ k ];
if( obj_k != null && obj_k !== p[ k ] ){
if( obj_k ){
ele[ trueFnName ]();
} else {
ele[ falseFnName ]();
}
}
};
checkSwitch( 'removed', 'remove', 'restore' );
checkSwitch( 'selected', 'select', 'unselect' );
checkSwitch( 'selectable', 'selectify', 'unselectify' );
checkSwitch( 'locked', 'lock', 'unlock' );
checkSwitch( 'grabbable', 'grabify', 'ungrabify' );
if( obj.classes != null ){
ele.classes( obj.classes );
}
cy.endBatch();
return this;
} else if( obj === undefined ){ // get
var json = {
data: util.copy( p.data ),
position: util.copy( p.position ),
group: p.group,
removed: p.removed,
selected: p.selected,
selectable: p.selectable,
locked: p.locked,
grabbable: p.grabbable,
classes: null
};
json.classes = Object.keys( p.classes ).filter(function( cls ){
return p.classes[cls];
}).join(' ');
return json;
}
}...
return;
}
// make the element array-like, just like a collection
this.length = 1;
this[0] = this;
// NOTE: when something is added here, add also to ele.json()
this._private = {
cy: cy,
single: true, // indicates this is an element
data: params.data || {}, // data object
position: params.position || {}, // (x, y) position pair
autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value
autoHeight: undefined,
...jsons = function (){
var jsons = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var json = ele.json();
jsons.push( json );
}
return jsons;
}...
if( struct.source !== undefined || struct.target !== undefined ){
var srcId = struct.source;
var tgtId = struct.target;
var srcExists = cy.hasElementWithId( srcId );
var tgtExists = cy.hasElementWithId( tgtId );
if( srcExists || tgtExists ){
var jsons = this.jsons();
this.remove();
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
...kargerStein = function ( options ){
var eles = this;
options = options || {};
// Function which colapses 2 (meta) nodes into one
// Updates the remaining edge lists
// Receives as a paramater the edge which causes the collapse
var colapse = function( edgeIndex, nodeMap, remainingEdges ){
var edgeInfo = remainingEdges[ edgeIndex ];
var sourceIn = edgeInfo[1];
var targetIn = edgeInfo[2];
var partition1 = nodeMap[ sourceIn ];
var partition2 = nodeMap[ targetIn ];
// Delete all edges between partition1 and partition2
var newEdges = remainingEdges.filter( function( edge ){
if( nodeMap[ edge[1] ] === partition1 && nodeMap[ edge[2] ] === partition2 ){
return false;
}
if( nodeMap[ edge[1] ] === partition2 && nodeMap[ edge[2] ] === partition1 ){
return false;
}
return true;
} );
// All edges pointing to partition2 should now point to partition1
for( var i = 0; i < newEdges.length; i++ ){
var edge = newEdges[ i ];
if( edge[1] === partition2 ){ // Check source
newEdges[ i ] = edge.slice( 0 );
newEdges[ i ][1] = partition1;
} else if( edge[2] === partition2 ){ // Check target
newEdges[ i ] = edge.slice( 0 );
newEdges[ i ][2] = partition1;
}
}
// Move all nodes from partition2 to partition1
for( var i = 0; i < nodeMap.length; i++ ){
if( nodeMap[ i ] === partition2 ){
nodeMap[ i ] = partition1;
}
}
return newEdges;
};
// Contracts a graph until we reach a certain number of meta nodes
var contractUntil = function( metaNodeMap,
remainingEdges,
size,
sizeLimit ){
// Stop condition
if( size <= sizeLimit ){
return remainingEdges;
}
// Choose an edge randomly
var edgeIndex = Math.floor( (Math.random() * remainingEdges.length) );
// Colapse graph based on edge
var newEdges = colapse( edgeIndex, metaNodeMap, remainingEdges );
return contractUntil( metaNodeMap,
newEdges,
size - 1,
sizeLimit );
};
var cy = this._private.cy;
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
var numEdges = edges.length;
var numIter = Math.ceil( Math.pow( Math.log( numNodes ) / Math.LN2, 2 ) );
var stopSize = Math.floor( numNodes / Math.sqrt( 2 ) );
if( numNodes < 2 ){
util.error( 'At least 2 nodes are required for Karger-Stein algorithm' );
return undefined;
}
// Create numerical identifiers for each node
// mapping: node id -> position in nodes array
// for reverse mapping, simply use nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Now store edge destination as indexes
// Format for each edge (edge index, source node index, target node index)
var edgeIndexes = [];
for( var i = 0; i < numEdges; i++ ){
var e = edges[ i ];
edgeIndexes.push( [ i, id2position[ e.source().id() ], id2position[ e.target().id() ] ] );
}
// We will store the best cut found here
var minCutSize = Infinity;
var minCut;
// Initial meta node partition
var originalMetaNode = [];
for( var i = 0; i < numNodes; i++ ){
originalMetaNode.push( i );
}
// Main loop
for( var iter = 0; iter <= numIter; iter++ ){
// Create new meta node partition
var metaNodeMap = originalMetaNode.slice( 0 );
// Contract until stop point (stopSize nodes)
var edgesState = contractUntil( metaNodeMap, edgeIndexes, numNodes, stopSize );
// Create a copy of the colapsed nodes state
var metaNodeMap2 = metaNodeMap.slice( 0 );
// Run 2 iterations starting in the stop state
var res1 = contractUntil( metaNodeMap, edgesState, stopSize, 2 );
var res2 = contractUntil( metaNodeMap2, edgesState, stopSize, 2 );
// Is any of the 2 results the best cut so far?
if( res1.length <= res2.length && res1.length < minCutSize ){
minCutSiz ...n/a
kruskal = function ( weightFn ){
var cy = this.cy();
weightFn = is.fn( weightFn ) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)
function findSet( ele ){
for( var i = 0; i < forest.length; i++ ){
var eles = forest[ i ];
if( eles.anySame( ele ) ){
return {
eles: eles,
index: i
};
}
}
}
var A = cy.collection( cy, [] );
var forest = [];
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
forest.push( nodes[ i ].collection() );
}
var edges = this.edges();
var S = edges.toArray().sort( function( a, b ){
var weightA = weightFn( a );
var weightB = weightFn( b );
return weightA - weightB;
} );
for( var i = 0; i < S.length; i++ ){
var edge = S[ i ];
var u = edge.source()[0];
var v = edge.target()[0];
var setU = findSet( u );
var setV = findSet( v );
if( setU.index !== setV.index ){
A = A.add( edge );
// combine forests for u and v
forest[ setU.index ] = setU.eles.add( setV.eles );
forest.splice( setV.index, 1 );
}
}
return nodes.add( A );
}n/a
last = function (){
return this[ this.length - 1 ] || this.spawn();
}n/a
layout = function ( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}n/a
layoutPositions = function ( layout, options, fn ){
var nodes = this.nodes();
var cy = this.cy();
layout.trigger( { type: 'layoutstart', layout: layout } );
layout.animations = [];
if( options.animate ){
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var newPos = fn( node, i );
var pos = node.position();
if( !is.number( pos.x ) || !is.number( pos.y ) ){
node.silentPosition( { x: 0, y: 0 } );
}
var ani = node.animation( {
position: newPos,
duration: options.animationDuration,
easing: options.animationEasing
} );
layout.animations.push( ani );
ani.play();
}
var onStep;
cy.on( 'step.*', ( onStep = function(){
if( options.fit ){
cy.fit( options.eles, options.padding );
}
}) );
layout.one('layoutstop', function(){
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
return ani.promise();
}) ).then(function(){
cy.off('step.*', onStep);
if( options.zoom != null ){
cy.zoom( options.zoom );
}
if( options.pan ){
cy.pan( options.pan );
}
if( options.fit ){
cy.fit( options.eles, options.padding );
}
layout.one( 'layoutstop', options.stop );
layout.trigger( { type: 'layoutstop', layout: layout } );
});
} else {
nodes.positions( fn );
if( options.fit ){
cy.fit( options.eles, options.padding );
}
if( options.zoom != null ){
cy.zoom( options.zoom );
}
if( options.pan ){
cy.pan( options.pan );
}
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
layout.one( 'layoutstop', options.stop );
layout.trigger( { type: 'layoutstop', layout: layout } );
}
return this; // chaining
}...
for( var j = 0; j < depth.length; j++ ){
var node = depth[ j ];
pos[ node.id() ] = getPosition( node, i === depths.length - 1 );
}
}
nodes.layoutPositions( this, options, function( node ){
return pos[ node.id() ];
} );
return this; // chaining
};
module.exports = BreadthFirstLayout;
...function dagExtremityImpl( selector ){
var eles = this;
var ret = [];
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
if( !ele.isNode() ){
continue;
}
var disqualified = false;
var edges = ele.connectedEdges();
for( var j = 0; j < edges.length; j++ ){
var edge = edges[j];
var src = edge.source();
var tgt = edge.target();
if(
( params.noIncomingEdges && tgt === ele && src !== ele )
|| ( params.noOutgoingEdges && src === ele && tgt !== ele )
){
disqualified = true;
break;
}
}
if( !disqualified ){
ret.push( ele );
}
}
return this.spawn( ret, { unique: true } ).filter( selector );
}n/a
function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}n/a
lock = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
locked = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':selectable':
allColonSelectorsMatch = ele.selectable();
break;
case ':unselectable':
allColonSelectorsMatch = !ele.selectable();
break;
case ':locked':
allColonSelectorsMatch = ele.locked();
break;
case ':unlocked':
allColonSelectorsMatch = !ele.locked();
break;
case ':visible':
allColonSelectorsMatch = ele.visible();
break;
...makeLayout = function ( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}...
return this; // chaining
},
layout: function( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}
});
// aliases:
...map = function ( mapFn, thisArg ){
var arr = [];
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var ret = thisArg ? mapFn.apply( thisArg, [ ele, i, eles ] ) : mapFn( ele, i, eles );
arr.push( ret );
}
return arr;
}...
layout.one('layoutstop', function(){
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
return ani.promise();
}) ).then(function(){
cy.off('step.*', onStep);
if( options.zoom != null ){
cy.zoom( options.zoom );
}
...max = function ( valFn, thisArg ){
var max = -Infinity;
var maxEle;
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );
if( val > max ){
max = val;
maxEle = ele;
}
}
return {
value: max,
ele: maxEle
};
}...
var b = math.dist( A, C );
var c = math.dist( A, B );
return Math.acos( (a*a + b*b - c*c)/(2*a*b) );
};
math.bound = function( min, val, max ){
return Math.max( min, Math.min( max, val ) );
};
// makes a full bb (x1, y1, x2, y2, w, h) from implicit params
math.makeBoundingBox = function( bb ){
if( bb == null ){
return {
x1: Infinity,
...maxDegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}...
unhandledNodes = unhandledNodes.not( currComp );
components.push( currComp );
}
roots = cy.collection();
for( var i = 0; i < components.length; i++ ){
var comp = components[ i ];
var maxDegree = comp.maxDegree( false );
var compRoots = comp.filter( function( ele ){
return ele.degree( false ) === maxDegree;
} );
roots = roots.add( compRoots );
}
...maxIndegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
maxOutdegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
merge = function ( toAdd ){
var _p = this._private;
var cy = _p.cy;
if( !toAdd ){
return this;
}
if( toAdd && is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
for( var i = 0; i < toAdd.length; i++ ){
var toAddEle = toAdd[ i ];
var id = toAddEle._private.data.id;
var add = !_p.ids[ id ];
if( add ){
var index = this.length++;
this[ index ] = toAddEle;
_p.ids[ id ] = toAddEle;
_p.indexes[ id ] = index;
} else { // replace
var index = _p.indexes[ id ];
this[ index ] = toAddEle;
_p.ids[ id ] = toAddEle;
}
}
return this; // chaining
}...
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
...min = function ( valFn, thisArg ){
var min = Infinity;
var minEle;
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );
if( val < min ){
min = val;
minEle = ele;
}
}
return {
value: min,
ele: minEle
};
}...
var b = math.dist( A, C );
var c = math.dist( A, B );
return Math.acos( (a*a + b*b - c*c)/(2*a*b) );
};
math.bound = function( min, val, max ){
return Math.max( min, Math.min( max, val ) );
};
// makes a full bb (x1, y1, x2, y2, w, h) from implicit params
math.makeBoundingBox = function( bb ){
if( bb == null ){
return {
x1: Infinity,
...minDegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
minIndegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
minOutdegree = function ( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
}
return ret;
}n/a
function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
modelPositions = function ( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var pos = fn( ele, i );
if( pos && !ele.locked() && !ele.isParent() ){
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
return this; // chaining
}n/a
move = function ( struct ){
var cy = this._private.cy;
if( struct.source !== undefined || struct.target !== undefined ){
var srcId = struct.source;
var tgtId = struct.target;
var srcExists = cy.hasElementWithId( srcId );
var tgtExists = cy.hasElementWithId( tgtId );
if( srcExists || tgtExists ){
var jsons = this.jsons();
this.remove();
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
if( json.group === 'edges' ){
if( srcExists ){ json.data.source = srcId; }
if( tgtExists ){ json.data.target = tgtId; }
json.scratch = ele._private.scratch;
}
}
return cy.add( jsons );
}
} else if( struct.parent !== undefined ){ // move node to new parent
var parentId = struct.parent;
var parentExists = parentId === null || cy.hasElementWithId( parentId );
if( parentExists ){
var jsons = this.jsons();
var descs = this.descendants();
var descsEtcJsons = descs.union( descs.union( this ).connectedEdges() ).jsons();
this.remove(); // NB: also removes descendants and their connected edges
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
if( json.group === 'nodes' ){
json.data.parent = parentId === null ? undefined : parentId;
json.scratch = ele._private.scratch;
}
}
return cy.add( jsons.concat( descsEtcJsons ) );
}
}
return this; // if nothing done
}n/a
n = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
return this.intersect( collection ).length > 0;
},
allAreNeighbors: function( collection ){
collection = this.cy().collection( collection );
return this.neighborhood().intersect( collection ).length === collection.length;
}
});
elesfn.allAreNeighbours = elesfn.allAreNeighbors;
module.exports = elesfn;
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}n/a
nodes = function ( selector ){
return this.filter( function( ele, i ){
return ele.isNode();
} ).filter( selector );
}...
}
} )
} );
function defineDegreeBoundsFunction( degreeFn, callback ){
return function( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
...nonempty = function (){
return !this.empty();
}...
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
case ':unanimated':
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
...noninteractive = function (){
var ele = this[0];
if( ele ){
return !ele.interactive();
}
}n/a
nonorphans = function ( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().nonempty();
} ).filter( selector );
}n/a
not = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}...
children = children.concat( ele._private.children );
}
return this.spawn( children, { unique: true } ).filter( selector );
},
siblings: function( selector ){
return this.parent().children().not( this ).filter( selector );
},
isParent: function(){
var ele = this[0];
if( ele ){
return ele._private.children.length !== 0;
...off = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}...
return this;
};
}
layoutProto.on = define.on( { layout: true } );
layoutProto.one = define.on( { layout: true, unbindSelfOnTrigger: true } );
layoutProto.once = define.on( { layout: true, unbindAllBindersOnTrigger: true } );
layoutProto.off = define.off( { layout: true } );
layoutProto.trigger = define.trigger( { layout: true } );
define.eventAliasesOn( layoutProto );
ext = Layout; // replace with our wrapped layout
} else if( type === 'renderer' && name !== 'null' && name !== 'base' ){
...function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}...
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
...function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}n/a
function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}...
var onStep;
cy.on( 'step.*', ( onStep = function(){
if( options.fit ){
cy.fit( options.eles, options.padding );
}
}) );
layout.one('layoutstop', function(){
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
...openNeighborhood = function ( selector ){
return this.neighborhood( selector );
}...
for( var i = 0; i < V.length; i++ ){
var v = V[ i ];
var vid = v.id();
if( directed ){
A[ vid ] = v.outgoers().nodes(); // get outgoers of every node
} else {
A[ vid ] = v.openNeighborhood().nodes(); // get neighbors of every node
}
C.set( vid, 0 );
}
for( var s = 0; s < V.length; s++ ){
var sid = V[s].id();
...openNeighbourhood = function ( selector ){
return this.neighborhood( selector );
}n/a
or = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}n/a
orphans = function ( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().empty();
} ).filter( selector );
}n/a
outdegree = function ( includeLoops ){
var self = this;
if( includeLoops === undefined ){
includeLoops = true;
}
if( self.length === 0 ){ return; }
if( self.isNode() && !self.removed() ){
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
} else {
return;
}
}n/a
function outerDimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
var dim = ele[ opts.name ]();
var border = ele.pstyle( 'border-width' ).pfValue; // n.b. 1/2 each side
var padding = 2 * ele.pstyle( 'padding' ).pfValue;
return dim + border + padding;
} else {
return 1;
}
}
}...
if( isNode && options.includeNodes ){
var pos = _p.position;
x = pos.x;
y = pos.y;
var w = ele.outerWidth();
var halfW = w / 2;
var h = ele.outerHeight();
var halfH = h / 2;
// handle node dimensions
/////////////////////////
ex1 = x - halfW - overlayPadding;
ex2 = x + halfW + overlayPadding;
...function outerDimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
var dim = ele[ opts.name ]();
var border = ele.pstyle( 'border-width' ).pfValue; // n.b. 1/2 each side
var padding = 2 * ele.pstyle( 'padding' ).pfValue;
return dim + border + padding;
} else {
return 1;
}
}
}...
wHalf = w / 2;
}
if( isNode && options.includeNodes ){
var pos = _p.position;
x = pos.x;
y = pos.y;
var w = ele.outerWidth();
var halfW = w / 2;
var h = ele.outerHeight();
var halfH = h / 2;
// handle node dimensions
/////////////////////////
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
var defineDagAllHops = function( params ){
return function( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
...pageRank = function ( options ){
options = options || {};
var normalizeVector = function( vector ){
var length = vector.length;
// First, get sum of all elements
var total = 0;
for( var i = 0; i < length; i++ ){
total += vector[ i ];
}
// Now, divide each by the sum of all elements
for( var i = 0; i < length; i++ ){
vector[ i ] = vector[ i ] / total;
}
};
// dampingFactor - optional
if( options != null &&
options.dampingFactor != null ){
var dampingFactor = options.dampingFactor;
} else {
var dampingFactor = 0.8; // Default damping factor
}
// desired precision - optional
if( options != null &&
options.precision != null ){
var epsilon = options.precision;
} else {
var epsilon = 0.000001; // Default precision
}
// Max number of iterations - optional
if( options != null &&
options.iterations != null ){
var numIter = options.iterations;
} else {
var numIter = 200; // Default number of iterations
}
// Weight function - optional
if( options != null &&
options.weight != null &&
is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
var cy = this._private.cy;
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
var numEdges = edges.length;
// Create numerical identifiers for each node
// mapping: node id -> position in nodes array
// for reverse mapping, simply use nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Construct transposed adjacency matrix
// First lets have a zeroed matrix of the right size
// We'll also keep track of the sum of each column
var matrix = [];
var columnSum = [];
var additionalProb = (1 - dampingFactor) / numNodes;
// Create null matric
for( var i = 0; i < numNodes; i++ ){
var newRow = [];
for( var j = 0; j < numNodes; j++ ){
newRow.push( 0.0 );
}
matrix.push( newRow );
columnSum.push( 0.0 );
}
// Now, process edges
for( var i = 0; i < numEdges; i++ ){
var edge = edges[ i ];
var s = id2position[ edge.source().id() ];
var t = id2position[ edge.target().id() ];
var w = weightFn( edge );
// Update matrix
matrix[ t ][ s ] += w;
// Update column sum
columnSum[ s ] += w;
}
// Add additional probability based on damping factor
// Also, take into account columns that have sum = 0
var p = 1.0 / numNodes + additionalProb; // Shorthand
// Traverse matrix, column by column
for( var j = 0; j < numNodes; j++ ){
if( columnSum[ j ] === 0 ){
// No 'links' out from node jth, assume equal probability for each possible node
for( var i = 0; i < numNodes; i++ ){
matrix[ i ][ j ] = p;
}
} else {
// Node jth has outgoing link, compute normalized probabilities
for( var i = 0; i < numNodes; i++ ){
matrix[ i ][ j ] = matrix[ i ][ j ] / columnSum[ j ] + additionalProb;
}
}
}
// Compute dominant eigenvector using power method
var eigenvector = [];
var nullVector = [];
var previous;
// Start with a vector of all 1's
// Also, initialize a null vector which will be used as shorthand
for( var i = 0; i < numNodes; i++ ){
eigenvector.push( 1.0 );
nullVector.push( 0.0 );
}
for( var iter = 0; iter < numIter; iter++ ){
// New array with all 0's
var temp = nullVector.slice( 0 );
// Multiply matrix with previous result
for( var i = 0; i < numNodes; i++ ){
for( var j = 0; j < numNodes; j++ ){
temp[ i ] += matrix[ i ][ j ] * eigenvector[ j ];
}
}
normalizeVector( temp );
previous = eigenvector;
eigenvector = temp;
var diff = 0;
// Compute difference (squared module) of both vectors
for( var i = 0; i < numNodes; i++ ){
diff += Math.pow( previous[ i ] - eigenvector[ i ], 2 ); ...n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
this.recalculateRenderedStyle( opts.useCache );
}
for( var i = 0; i < eles.length; i++ ){
var ele = eles[i];
if( styleEnabled && ele.isEdge() && ele.pstyle('curve-style').strValue === 'bezier' ){
ele.parallelEdges().recalculateRenderedStyle( opts.useCache ); // n.b. ele.parallelEdges
() single is cached
}
updateBoundsFromBox( bounds, cachedBoundingBoxImpl( ele, opts ) );
}
bounds.x1 = noninf( bounds.x1 );
bounds.y1 = noninf( bounds.y1 );
...parent = function ( selector ){
var parents = [];
var cy = this._private.cy;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parent = cy.getElementById( ele._private.data.parent );
if( parent.size() > 0 ){
parents.push( parent );
}
}
return this.spawn( parents, { unique: true } ).filter( selector );
}...
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
break;
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) === ele.data( 'target' );
break;
...parents = function ( selector ){
var parents = [];
var eles = this.parent();
while( eles.nonempty() ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
parents.push( ele );
}
eles = eles.parent();
}
return this.spawn( parents, { unique: true } ).filter( selector );
}...
};
if( !confirmRelations( query.parent, function(){
return ele.parent();
} ) ){ return false; }
if( !confirmRelations( query.ancestor, function(){
return ele.parents();
} ) ){ return false; }
if( !confirmRelations( query.child, function(){
return ele.children();
} ) ){ return false; }
if( !confirmRelations( query.descendant, function(){
...parsedStyle = function ( property ){
var ele = this[0];
if( !ele.cy().styleEnabled() ){ return; }
if( ele ){
return ele._private.style[ property ] || ele.cy().style().getDefaultProperty( property );
}
}n/a
function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
points = function ( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var pos = fn( ele, i );
if( pos && !ele.locked() && !ele.isParent() ){
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
return this; // chaining
}n/a
pon = function ( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
self.on.apply( self, onArgs );
} );
}n/a
poolIndex = function (){
var cy = this._private.cy;
var eles = cy._private.elements;
var id = this._private.data.id;
return eles._private.indexes[ id ];
}...
return 1; // 'a' is a node, it should be drawn later
} else if( aIsEdge && bIsNode ){
return -1; // 'a' is an edge, it should be drawn first
} else { // both nodes or both edges
if( zDiff === 0 ){ // same z-index => compare indices in the core (order added to graph w/ last on top)
return a.poolIndex() - b.poolIndex();
} else {
return zDiff;
}
}
// elements on different level
} else {
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}...
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
positions: function( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
...positions = function ( pos, silent ){
if( is.plainObject( pos ) ){
this.position( pos );
} else if( is.fn( pos ) ){
var fn = pos;
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var pos = fn( ele, i );
if( pos && !ele.locked() && !ele.isParent() ){
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
return this; // chaining
}...
}
}
return this; // chaining
},
silentPositions: function( pos ){
return this.positions( pos, true );
},
// get/set the rendered (i.e. on screen) positon of the element
renderedPosition: function( dim, val ){
var ele = this[0];
var cy = this.cy();
var zoom = cy.zoom();
...predecessors = function ( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
if( !sElesIds[ nid ] ){
sElesIds[ nid ] = true;
sEles.push( n );
newNext = true;
}
}
if( !newNext ){ break; } // done if touched all outgoers already
eles = next;
}
return this.spawn( sEles, { unique: true } ).filter( selector );
}n/a
promiseOn = function ( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
self.on.apply( self, onArgs );
} );
}n/a
pstyle = function ( property ){
var ele = this[0];
if( !ele.cy().styleEnabled() ){ return; }
if( ele ){
return ele._private.style[ property ] || ele.cy().style().getDefaultProperty( property );
}
}...
var updated = [];
function update( parent ){
if( !parent.isParent() ){ return; }
var _p = parent._private;
var children = parent.children();
var includeLabels = parent.pstyle( 'compound-sizing-wrt-labels' ).value
=== 'include';
var bb = children.boundingBox( {
includeLabels: includeLabels,
includeOverlays: false,
// updating the compound bounds happens outside of the regular
// cache cycle (i.e. before fired events)
useCache: false
...recalculateRenderedStyle = function ( useCache ){
var cy = this.cy();
var renderer = cy.renderer();
var styleEnabled = cy.styleEnabled();
if( renderer && styleEnabled ){
renderer.recalculateRenderedStyle( this, useCache );
}
return this;
}...
elesfn.recalculateRenderedStyle = function( useCache ){
var cy = this.cy();
var renderer = cy.renderer();
var styleEnabled = cy.styleEnabled();
if( renderer && styleEnabled ){
renderer.recalculateRenderedStyle( this, useCache );
}
return this;
};
function filledBbOpts( options ){
return {
...relativeComplement = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}n/a
relativePoint = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var ppos = is.plainObject( dim ) ? dim : undefined;
var setting = ppos !== undefined || ( val !== undefined && is.string( dim ) );
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = val + origin[ dim ];
} else if( ppos !== undefined ){ // set whole position
ele._private.position = {
x: ppos.x + origin.x,
y: ppos.y + origin.y
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
ppos = {
x: pos.x - origin.x,
y: pos.y - origin.y
};
if( dim === undefined ){ // then return the whole rendered position
return ppos;
} else { // then return the specified dimension
return ppos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
relativePosition = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var ppos = is.plainObject( dim ) ? dim : undefined;
var setting = ppos !== undefined || ( val !== undefined && is.string( dim ) );
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = val + origin[ dim ];
} else if( ppos !== undefined ){ // set whole position
ele._private.position = {
x: ppos.x + origin.x,
y: ppos.y + origin.y
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
var parent = hasCompoundNodes ? ele.parent() : null;
var hasParent = parent && parent.length > 0;
var relativeToParent = hasParent;
if( hasParent ){
parent = parent[0];
}
var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };
ppos = {
x: pos.x - origin.x,
y: pos.y - origin.y
};
if( dim === undefined ){ // then return the whole rendered position
return ppos;
} else { // then return the specified dimension
return ppos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
remove = function ( notifyRenderer ){
var self = this;
var removed = [];
var elesToRemove = [];
var elesToRemoveIds = {};
var cy = self._private.cy;
if( notifyRenderer === undefined ){
notifyRenderer = true;
}
// add connected edges
function addConnectedEdges( node ){
var edges = node._private.edges;
for( var i = 0; i < edges.length; i++ ){
add( edges[ i ] );
}
}
// add descendant nodes
function addChildren( node ){
var children = node._private.children;
for( var i = 0; i < children.length; i++ ){
add( children[ i ] );
}
}
function add( ele ){
var alreadyAdded = elesToRemoveIds[ ele.id() ];
if( alreadyAdded ){
return;
} else {
elesToRemoveIds[ ele.id() ] = true;
}
if( ele.isNode() ){
elesToRemove.push( ele ); // nodes are removed last
addConnectedEdges( ele );
addChildren( ele );
} else {
elesToRemove.unshift( ele ); // edges are removed first
}
}
// make the list of elements to remove
// (may be removing more than specified due to connected edges etc)
for( var i = 0, l = self.length; i < l; i++ ){
var ele = self[ i ];
add( ele );
}
function removeEdgeRef( node, edge ){
var connectedEdges = node._private.edges;
util.removeFromArray( connectedEdges, edge );
// removing an edges invalidates the traversal cache for its nodes
node._private.traversalCache = null;
}
function removeParallelRefs( edge ){
// removing an edge invalidates the traversal caches for the parallel edges
var pedges = edge.parallelEdges();
for( var j = 0; j < pedges.length; j++ ){
pedges[j]._private.traversalCache = null;
}
}
var alteredParents = [];
alteredParents.ids = {};
function removeChildRef( parent, ele ){
ele = ele[0];
parent = parent[0];
var children = parent._private.children;
var pid = parent.id();
util.removeFromArray( children, ele );
if( !alteredParents.ids[ pid ] ){
alteredParents.ids[ pid ] = true;
alteredParents.push( parent );
}
}
// remove from core pool
cy.removeFromPool( elesToRemove );
for( var i = 0; i < elesToRemove.length; i++ ){
var ele = elesToRemove[ i ];
// mark as removed
ele._private.removed = true;
// add to list of removed elements
removed.push( ele );
if( ele.isEdge() ){ // remove references to this edge in its connected nodes
var src = ele.source()[0];
var tgt = ele.target()[0];
removeEdgeRef( src, ele );
removeEdgeRef( tgt, ele );
removeParallelRefs( ele );
} else { // remove reference to parent
var parent = ele.parent();
if( parent.length !== 0 ){
removeChildRef( parent, ele );
}
}
}
// check to see if we have a compound graph or not
var elesStillInside = cy._private.elements;
cy._private.hasCompoundNodes = false;
for( var i = 0; i < elesStillInside.length; i++ ){
var ele = elesStillInside[ i ];
if( ele.isParent() ){
cy._private.hasCompoundNodes = true;
break;
}
}
var removedElements = new Collection( this.cy(), removed );
if( removedElements.size() > 0 ){
// must manually notify since trigger won't do this automatically once removed
if( notifyRenderer ){
this.cy().notify( {
type: 'remove',
eles: removedElements
} );
}
removedElements.trigger( 'remove' );
}
// the parents who were modified by the removal need their style updated
for( var i = 0; i < alteredParents.length; i++ ){
var ele = alteredParents[ i ];
if( !ele.removed() ){
ele.updateStyle();
}
}
return new Collection( cy, removed );
}...
var tgtId = struct.target;
var srcExists = cy.hasElementWithId( srcId );
var tgtExists = cy.hasElementWithId( tgtId );
if( srcExists || tgtExists ){
var jsons = this.jsons();
this.remove();
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
if( json.group === 'edges' ){
if( srcExists ){ json.data.source = srcId; }
...function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}n/a
removeBypass = function ( names ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
var eles = this;
if( names === undefined ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeAllBypasses( ele, updateTransitions );
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeBypasses( ele, names, updateTransitions );
}
}
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
}n/a
removeClass = function ( classes ){
return this.toggleClass( classes, false );
}...
duration = 250;
} else if( duration === 0 ){
return self; // nothing to do really
}
self.addClass( classes );
setTimeout( function(){
self.removeClass( classes );
}, duration );
return self;
}
});
module.exports = elesfn;
...removeCss = function ( names ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
var eles = this;
if( names === undefined ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeAllBypasses( ele, updateTransitions );
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeBypasses( ele, names, updateTransitions );
}
}
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
}n/a
function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}...
return function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
...removeListener = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}n/a
function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}n/a
function removeDataImpl( names ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
// .removeData()
} else if( names === undefined ){ // then delete all keys
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
var _privateFields = all[ i_a ]._private[ p.field ];
var keys = Object.keys( _privateFields );
for( var i = 0; i < keys.length; i++ ){
var key = keys[i];
var validKeyToDelete = !p.immutableKeys[ key ];
if( validKeyToDelete ){
_privateFields[ key ] = undefined;
}
}
}
if( p.triggerEvent ){
self[ p.triggerFnName ]( p.event );
}
}
return self; // maintain chaining
}n/a
removeStyle = function ( names ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
var eles = this;
if( names === undefined ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeAllBypasses( ele, updateTransitions );
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeBypasses( ele, names, updateTransitions );
}
}
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
}n/a
removed = function (){
var ele = this[0];
return ele && ele._private.removed;
}...
case ':grabbed':
allColonSelectorsMatch = ele.grabbed();
break;
case ':free':
allColonSelectorsMatch = !ele.grabbed();
break;
case ':removed':
allColonSelectorsMatch = ele.removed();
break;
case ':inside':
allColonSelectorsMatch = !ele.removed();
break;
case ':grabbable':
allColonSelectorsMatch = ele.grabbable();
break;
...renderedBoundingBox = function ( options ){
var bb = this.boundingBox( options );
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var x1 = bb.x1 * zoom + pan.x;
var x2 = bb.x2 * zoom + pan.x;
var y1 = bb.y1 * zoom + pan.y;
var y2 = bb.y2 * zoom + pan.y;
return {
x1: x1,
x2: x2,
y1: y1,
y2: y2,
w: x2 - x1,
h: y2 - y1
};
}n/a
renderedBoundingbox = function ( options ){
var bb = this.boundingBox( options );
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var x1 = bb.x1 * zoom + pan.x;
var x2 = bb.x2 * zoom + pan.x;
var y1 = bb.y1 * zoom + pan.y;
var y2 = bb.y2 * zoom + pan.y;
return {
x1: x1,
x2: x2,
y1: y1,
y2: y2,
w: x2 - x1,
h: y2 - y1
};
}n/a
renderedCss = function ( property ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var ele = this[0];
if( ele ){
var renstyle = ele.cy().style().getRenderedStyle( ele );
if( property === undefined ){
return renstyle;
} else {
return renstyle[ property ];
}
}
}n/a
function renderedDimImpl(){
var ele = this[0];
if( ele ){
var d = ele[ opts.name ]();
return d * this.cy().zoom();
}
}n/a
function renderedOuterDimImpl(){
var ele = this[0];
if( ele ){
var od = ele[ opts.outerName ]();
return od * this.cy().zoom();
}
}n/a
function renderedOuterDimImpl(){
var ele = this[0];
if( ele ){
var od = ele[ opts.outerName ]();
return od * this.cy().zoom();
}
}n/a
renderedPoint = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var rpos = is.plainObject( dim ) ? dim : undefined;
var setting = rpos !== undefined || ( val !== undefined && is.string( dim ) );
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = ( val - pan[ dim ] ) / zoom;
} else if( rpos !== undefined ){ // set whole position
ele._private.position = {
x: ( rpos.x - pan.x ) / zoom,
y: ( rpos.y - pan.y ) / zoom
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
rpos = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
if( dim === undefined ){ // then return the whole rendered position
return rpos;
} else { // then return the specified dimension
return rpos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
renderedPosition = function ( dim, val ){
var ele = this[0];
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var rpos = is.plainObject( dim ) ? dim : undefined;
var setting = rpos !== undefined || ( val !== undefined && is.string( dim ) );
if( ele && ele.isNode() ){ // must have an element and must be a node to return position
if( setting ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
if( val !== undefined ){ // set one dimension
ele._private.position[ dim ] = ( val - pan[ dim ] ) / zoom;
} else if( rpos !== undefined ){ // set whole position
ele._private.position = {
x: ( rpos.x - pan.x ) / zoom,
y: ( rpos.y - pan.y ) / zoom
};
}
}
this.rtrigger( 'position' );
} else { // getting
var pos = ele._private.position;
rpos = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
if( dim === undefined ){ // then return the whole rendered position
return rpos;
} else { // then return the specified dimension
return rpos[ dim ];
}
}
} else if( !setting ){
return undefined; // for empty collection case
}
return this; // chaining
}n/a
renderedStyle = function ( property ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var ele = this[0];
if( ele ){
var renstyle = ele.cy().style().getRenderedStyle( ele );
if( property === undefined ){
return renstyle;
} else {
return renstyle[ property ];
}
}
}n/a
function renderedDimImpl(){
var ele = this[0];
if( ele ){
var d = ele[ opts.name ]();
return d * this.cy().zoom();
}
}n/a
restore = function ( notifyRenderer ){
var self = this;
var cy = self.cy();
var cy_p = cy._private;
if( notifyRenderer === undefined ){
notifyRenderer = true;
}
// create arrays of nodes and edges, since we need to
// restore the nodes first
var nodes = [];
var edges = [];
var elements;
for( var i = 0, l = self.length; i < l; i++ ){
var ele = self[ i ];
if( !ele.removed() ){
// don't need to handle this ele
continue;
}
// keep nodes first in the array and edges after
if( ele.isNode() ){ // put to front of array if node
nodes.push( ele );
} else { // put to end of array if edge
edges.push( ele );
}
}
elements = nodes.concat( edges );
var i;
var removeFromElements = function(){
elements.splice( i, 1 );
i--;
};
// now, restore each element
for( i = 0; i < elements.length; i++ ){
var ele = elements[ i ];
var _private = ele._private;
var data = _private.data;
// the traversal cache should start fresh when ele is added
_private.traversalCache = null;
// set id and validate
if( data.id === undefined ){
data.id = idFactory.generate( cy, ele );
} else if( is.number( data.id ) ){
data.id = '' + data.id; // now it's a string
} else if( is.emptyString( data.id ) || !is.string( data.id ) ){
util.error( 'Can not create element with invalid string ID `' + data.id + '`' );
// can't create element if it has empty string as id or non-string id
removeFromElements();
continue;
} else if( cy.hasElementWithId( data.id ) ){
util.error( 'Can not create second element with ID `' + data.id + '`' );
// can't create element if one already has that id
removeFromElements();
continue;
}
var id = data.id; // id is finalised, now let's keep a ref
if( ele.isNode() ){ // extra checks for nodes
var node = ele;
var pos = _private.position;
// make sure the nodes have a defined position
if( pos.x == null ){
pos.x = 0;
}
if( pos.y == null ){
pos.y = 0;
}
}
if( ele.isEdge() ){ // extra checks for edges
var edge = ele;
var fields = [ 'source', 'target' ];
var fieldsLength = fields.length;
var badSourceOrTarget = false;
for( var j = 0; j < fieldsLength; j++ ){
var field = fields[ j ];
var val = data[ field ];
if( is.number( val ) ){
val = data[ field ] = '' + data[ field ]; // now string
}
if( val == null || val === '' ){
// can't create if source or target is not defined properly
util.error( 'Can not create edge `' + id + '` with unspecified ' + field );
badSourceOrTarget = true;
} else if( !cy.hasElementWithId( val ) ){
// can't create edge if one of its nodes doesn't exist
util.error( 'Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`' );
badSourceOrTarget = true;
}
}
if( badSourceOrTarget ){ removeFromElements(); continue; } // can't create this
var src = cy.getElementById( data.source );
var tgt = cy.getElementById( data.target );
src._private.edges.push( edge );
tgt._private.edges.push( edge );
edge._private.source = src;
edge._private.target = tgt;
} // if is edge
// create mock ids / indexes maps for element so it can be used like collections
_private.ids = {};
_private.ids[ id ] = ele;
_private.indexes = {};
_private.indexes[ id ] = ele;
_private.removed = false;
cy.addToPool( ele );
} // for each element
// do compound node sanity checks
for( var i = 0; i < nodes.length; i++ ){ // each node
var node = nodes[ i ];
var data = node._private.data;
if( is.number( data.parent ) ){ // then automake string
data.parent = '' + data.parent;
}
var parentId = data.parent;
var specifiedParent = parentId != null;
if( specifiedParent ){
var parent = cy.getElementById ......
}
if( params.style || params.css ){
cy.style().applyBypass( this, params.style || params.css );
}
if( restore === undefined || restore ){
this.restore();
}
};
module.exports = Element;
...function dagExtremityImpl( selector ){
var eles = this;
var ret = [];
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
if( !ele.isNode() ){
continue;
}
var disqualified = false;
var edges = ele.connectedEdges();
for( var j = 0; j < edges.length; j++ ){
var edge = edges[j];
var src = edge.source();
var tgt = edge.target();
if(
( params.noIncomingEdges && tgt === ele && src !== ele )
|| ( params.noOutgoingEdges && src === ele && tgt !== ele )
){
disqualified = true;
break;
}
}
if( !disqualified ){
ret.push( ele );
}
}
return this.spawn( ret, { unique: true } ).filter( selector );
}...
roots = cy.collection( rootsArray );
} else if( is.string( options.roots ) ){
roots = cy.$( options.roots );
} else {
if( options.directed ){
roots = nodes.roots();
} else {
var components = [];
var unhandledNodes = nodes;
while( unhandledNodes.length > 0 ){
var currComp = cy.collection();
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
rtrigger = function ( event, extraParams ){ // for internal use only
if( this.length === 0 ){ return; } // empty collections don't need to notify anything
// notify renderer
this.cy().notify( {
type: event,
eles: this
} );
this.trigger( event, extraParams );
return this;
}...
settingEvent: 'position',
settingTriggersEvent: true,
triggerFnName: 'rtrigger',
allowGetting: true,
validKeys: [ 'x', 'y' ],
onSet: function( eles ){
var updatedEles = eles.updateCompoundBounds();
updatedEles.rtrigger( 'position' );
},
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
// position but no notification to renderer
...same = function ( collection ){
collection = this.cy().collection( collection );
// cheap extra check
if( this.length !== collection.length ){
return false;
}
return this.intersect( collection ).length === this.length;
}...
return;
}
};
}
util.extend( elesfn, {
degree: defineDegreeFunction( function( node, edge ){
if( edge.source().same( edge.target() ) ){
return 2;
} else {
return 1;
}
} ),
indegree: defineDegreeFunction( function( node, edge ){
...function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}n/a
select = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}...
var elesfn = {};
function defineSwitchFunction( params ){
return function(){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
...selectable = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':selected':
allColonSelectorsMatch = ele.selected();
break;
case ':unselected':
allColonSelectorsMatch = !ele.selected();
break;
case ':selectable':
allColonSelectorsMatch = ele.selectable();
break;
case ':unselectable':
allColonSelectorsMatch = !ele.selectable();
break;
case ':locked':
allColonSelectorsMatch = ele.locked();
break;
...selected = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
// check colon selectors
var allColonSelectorsMatch = true;
for( var k = 0; k < query.colonSelectors.length; k++ ){
var sel = query.colonSelectors[ k ];
switch( sel ){
case ':selected':
allColonSelectorsMatch = ele.selected();
break;
case ':unselected':
allColonSelectorsMatch = !ele.selected();
break;
case ':selectable':
allColonSelectorsMatch = ele.selectable();
break;
...selectify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
show = function (){
this.css( 'display', 'element' );
return this; // chaining
}n/a
siblings = function ( selector ){
return this.parent().children().not( this ).filter( selector );
}n/a
function dataImpl( name, value ){
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
}
return ret;
// .data('foo', 'bar')
} else if( p.allowSetting && value !== undefined ){ // set
var valid = !p.immutableKeys[ name ];
if( valid ){
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
var valid = !p.immutableKeys[ k ];
if( valid ){
for( var j = 0; j < all.length; j++ ){
var ele = all[j];
if( p.canSet( ele ) ){
ele._private[ p.field ][ k ] = v;
}
}
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
return ret;
}
return self; // maintain chainability
}...
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var newPos = fn( node, i );
var pos = node.position();
if( !is.number( pos.x ) || !is.number( pos.y ) ){
node.silentPosition( { x: 0, y: 0 } );
}
var ani = node.animation( {
position: newPos,
duration: options.animationDuration,
easing: options.animationEasing
} );
...silentPositions = function ( pos ){
return this.positions( pos, true );
}n/a
size = function (){
return this.length;
}...
if( !matchesAny ){
return false;
}
}
// check filter function
if( query.filter != null && ele.collection().filter( query.filter ).size() ===
0 ){
return false;
}
// check parent/child relations
var confirmRelations = function( query, eles ){
if( query != null ){
var matches = false;
...slice = function ( start, end ){
var array = [];
var thisSize = this.length;
if( end == null ){
end = thisSize;
}
if( start == null ){
start = 0;
}
if( start < 0 ){
start = thisSize + start;
}
if( end < 0 ){
end = thisSize + end;
}
for( var i = start; i >= 0 && i < end && i < thisSize; i++ ){
array.push( this[ i ] );
}
return this.spawn( array );
}...
*/
nlargest = function( array, n, cmp ){
var elem, result, _i, _len, _ref;
if( cmp == null ){
cmp = defaultCmp;
}
result = array.slice( 0, n );
if( !result.length ){
return result;
}
heapify( result, cmp );
_ref = array.slice( n );
for( _i = 0, _len = _ref.length; _i < _len; _i++ ){
elem = _ref[ _i ];
...some = function ( fn, thisArg ){
for( var i = 0; i < this.length; i++ ){
var ret = !thisArg ? fn( this[ i ], i, this ) : fn.apply( thisArg, [ this[ i ], i, this ] );
if( ret ){
return true;
}
}
return false;
}n/a
sort = function ( sortFn ){
if( !is.fn( sortFn ) ){
return this;
}
var sorted = this.toArray().sort( sortFn );
return this.spawn( sorted );
}...
}
heapify( result, cmp );
_ref = array.slice( n );
for( _i = 0, _len = _ref.length; _i < _len; _i++ ){
elem = _ref[ _i ];
heappushpop( result, elem, cmp );
}
return result.sort( cmp ).reverse();
};
/*
Find the n smallest elements in a dataset.
*/
...sortByZIndex = function (){
return this.sort( zIndexSort );
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
return;
}
};
}
util.extend( elesfn, {
degree: defineDegreeFunction( function( node, edge ){
if( edge.source().same( edge.target() ) ){
return 2;
} else {
return 1;
}
} ),
indegree: defineDegreeFunction( function( node, edge ){
...function sourceImpl( selector ){
var sources = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var src = ele._private[ params.attr ];
if( src ){
sources.push( src );
}
}
return this.spawn( sources, { unique: true } ).filter( selector );
}n/a
spawn = function ( cy, eles, opts ){
if( !is.core( cy ) ){ // cy is optional
opts = eles;
eles = cy;
cy = this.cy();
}
return new Collection( cy, eles, opts );
}...
changed.push( ele );
}
}
// trigger update style on those eles that had class changes
if( changed.length > 0 ){
this.spawn( changed )
.updateStyle()
.trigger( 'class' )
;
}
return self;
},
...spawnSelf = function (){
return this.spawn( this );
}...
var hasCompounds = cy.hasCompoundNodes();
var style = cy.style();
var updatedEles = this;
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( hasCompounds ){ // then add everything up and down for compound selector checks
updatedEles = this.spawnSelf().merge( this.descendants() ).merge( this.parents() );
}
style.apply( updatedEles );
if( hasCompounds ){
var updatedCompounds = updatedEles.updateCompoundBounds();
...stdFilter = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}...
ancestors = ancestors.intersect( parents ); // current list must be common with current ele parents set
}
return ancestors.filter( selector );
},
orphans: function( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().empty();
} ).filter( selector );
},
nonorphans: function( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().nonempty();
...function stopImpl( clearQueue, jumpToEnd ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
if( !cy.styleEnabled() ){ return this; }
for( var i = 0; i < all.length; i++ ){
var ele = all[ i ];
var _p = ele._private;
var anis = _p.animation.current;
for( var j = 0; j < anis.length; j++ ){
var ani = anis[ j ];
var ani_p = ani._private;
if( jumpToEnd ){
// next iteration of the animation loop, the animation
// will go straight to the end and be removed
ani_p.duration = 0;
}
}
// clear the queue of future animations
if( clearQueue ){
_p.animation.queue = [];
}
if( !jumpToEnd ){
_p.animation.current = [];
}
}
// we have to notify (the animation loop doesn't do it for us on `stop`)
cy.notify( {
eles: this,
type: 'draw'
} );
return this;
}...
var opts = this.options;
if( opts && opts.animate ){
var anis = this.animations;
if( anis ){
for( var i = 0; i < anis.length; i++ ){
anis[ i ].stop();
}
}
}
if( regStop ){
regStop.call( this );
} else {
...style = function ( name, value ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
if( is.plainObject( name ) ){ // then extend the bypass
var props = name;
style.applyBypass( this, props, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
} else if( is.string( name ) ){
if( value === undefined ){ // then get the property from the style
var ele = this[0];
if( ele ){
return style.getStylePropertyValue( ele, name );
} else { // empty collection => can't get any value
return;
}
} else { // then set the bypass with the property value
style.applyBypass( this, name, value, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
}
} else if( name === undefined ){
var ele = this[0];
if( ele ){
return style.getRawStyle( ele );
} else { // empty collection => can't get any value
return;
}
}
return this; // chaining
}...
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
var isCore = !selfIsArrayLike;
var isEles = !isCore;
if( !cy.styleEnabled() ){ return this; }
var style = cy.style();
properties = util.extend( {}, properties, params );
if( properties.duration === undefined ){
properties.duration = 400;
}
...subtract = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}n/a
successors = function ( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
if( !sElesIds[ nid ] ){
sElesIds[ nid ] = true;
sEles.push( n );
newNext = true;
}
}
if( !newNext ){ break; } // done if touched all outgoers already
eles = next;
}
return this.spawn( sEles, { unique: true } ).filter( selector );
}n/a
symdiff = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var elements = [];
var col1 = this;
var col2 = other;
var add = function( col, other ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( !inOther ){
elements.push( ele );
}
}
};
add( col1, col2 );
add( col2, col1 );
return this.spawn( elements );
}n/a
symmetricDifference = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var elements = [];
var col1 = this;
var col2 = other;
var add = function( col, other ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( !inOther ){
elements.push( ele );
}
}
};
add( col1, col2 );
add( col2, col1 );
return this.spawn( elements );
}n/a
takesUpSpace = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return true; }
var ele = this[0];
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele ){
var _p = ele._private;
if( !ok( ele ) ){ return false; }
if( ele.isNode() ){
if( hasCompoundNodes ){
var parents = _p.data.parent ? ele.parents() : null;
if( parents ){ for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
if( !parentOk( parent ) ){ return false; }
} }
}
return true;
} else {
return edgeOkViaNode( _p.source ) && edgeOkViaNode( _p.target );
}
}
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
return;
}
};
}
util.extend( elesfn, {
degree: defineDegreeFunction( function( node, edge ){
if( edge.source().same( edge.target() ) ){
return 2;
} else {
return 1;
}
} ),
indegree: defineDegreeFunction( function( node, edge ){
...function sourceImpl( selector ){
var sources = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var src = ele._private[ params.attr ];
if( src ){
sources.push( src );
}
}
return this.spawn( sources, { unique: true } ).filter( selector );
}n/a
toArray = function (){
var array = [];
for( var i = 0; i < this.length; i++ ){
array.push( this[ i ] );
}
return array;
}...
},
sort: function( sortFn ){
if( !is.fn( sortFn ) ){
return this;
}
var sorted = this.toArray().sort( sortFn );
return this.spawn( sorted );
},
sortByZIndex: function(){
return this.sort( zIndexSort );
},
...toggleClass = function ( classesStr, toggle ){
var classes = classesStr.match( /\S+/g ) || [];
var self = this;
var changed = []; // eles who had classes changed
for( var i = 0, il = self.length; i < il; i++ ){
var ele = self[ i ];
var changedEle = false;
for( var j = 0; j < classes.length; j++ ){
var cls = classes[ j ];
var eleClasses = ele._private.classes;
var hasClass = eleClasses[ cls ];
var shouldAdd = toggle || (toggle === undefined && !hasClass);
if( shouldAdd ){
eleClasses[ cls ] = true;
if( !hasClass && !changedEle ){
changed.push( ele );
changedEle = true;
}
} else { // then remove
eleClasses[ cls ] = false;
if( hasClass && !changedEle ){
changed.push( ele );
changedEle = true;
}
}
} // for j classes
} // for i eles
// trigger update style on those eles that had class changes
if( changed.length > 0 ){
this.spawn( changed )
.updateStyle()
.trigger( 'class' )
;
}
return self;
}...
;
}
return self;
},
addClass: function( classes ){
return this.toggleClass( classes, true );
},
hasClass: function( className ){
var ele = this[0];
return ( ele != null && ele._private.classes[ className ] ) ? true : false;
},
...totalDegree = function ( includeLoops ){
var total = 0;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
total += nodes[ i ].degree( includeLoops );
}
return total;
}n/a
transparent = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return false; }
var ele = this[0];
var hasCompoundNodes = ele.cy().hasCompoundNodes();
if( ele ){
if( !hasCompoundNodes ){
return ele.pstyle( 'opacity' ).value === 0;
} else {
return ele.effectiveOpacity() === 0;
}
}
}...
case ':visible':
allColonSelectorsMatch = ele.visible();
break;
case ':hidden':
allColonSelectorsMatch = !ele.visible();
break;
case ':transparent':
allColonSelectorsMatch = ele.transparent();
break;
case ':grabbed':
allColonSelectorsMatch = ele.grabbed();
break;
case ':free':
allColonSelectorsMatch = !ele.grabbed();
break;
...function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
events.push( {
type: type,
namespace: namespace
} );
}
} else if( eventsIsObject ){ // put in length 1 array
var eventArgObj = events;
events = [ eventArgObj ];
}
if( extraParams ){
if( !is.array( extraParams ) ){ // make sure extra params are in an array if specified
extraParams = [ extraParams ];
}
} else { // otherwise, we've got nothing
extraParams = [];
}
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
evt.target = evt.target || triggerer;
evt.cy = evt.cy || cy;
} else { // then we have to make one
evt = new Event( evtObj, {
target: triggerer,
cy: cy,
namespace: evtObj.namespace
} );
}
// if a layout was specified, then put it in the typed event
if( evtObj.layout ){
evt.layout = evtObj.layout;
}
// if triggered by layout, put in event
if( params.layout ){
evt.layout = triggerer;
}
// create a rendered position based on the passed position
if( evt.position ){
var pos = evt.position;
var zoom = cy.zoom();
var pan = cy.pan();
evt.renderedPosition = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
}
if( fnToTrigger ){ // then override the listeners list with just the one we specified
listeners = [ {
namespace: evt.namespace,
type: evt.type,
callback: fnToTrigger
} ];
}
for( var k = 0; k < listeners.length; k++ ){ // check each listener
var lis = listeners[ k ];
var nsMatches = !lis.namespace || lis.namespace === evt.namespace || lis.namespace === define.event.universalNamespace;
var typeMatches = lis.type === evt.type;
var targetMatches = lis.delegated ? ( triggerer !== evt.target && is.element( evt.target ) && lis.selObj.matches( evt.target
) ) : (true); // we're not going to validate the hierarchy; that's too expensive
var listenerMatches = nsMatches && typeMatches && targetMatches;
if( listenerMatches ){ // then trigger it
var args = [ evt ];
args = args.concat( extraParams ); // add extra params to args list
if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener
listeners.splice( k, 1 );
k--;
}
if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders
var binders = lis.binders;
for( var l = 0; l < binders.length; l++ ){
var binder = b ......
// bubble up event for elements
if( bubbleUp ){
var parent = hasCompounds ? triggerer._private.parent : null;
var hasParent = parent != null && parent.length !== 0;
if( hasParent ){ // then bubble up to parent
parent = parent[0];
parent.trigger( evt );
} else { // otherwise, bubble up to the core
cy.trigger( evt );
}
}
} // for each of all
} // for each event
...u = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}n/a
unactivate = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
unbind = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}n/a
ungrabify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
union = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}...
} else if( struct.parent !== undefined ){ // move node to new parent
var parentId = struct.parent;
var parentExists = parentId === null || cy.hasElementWithId( parentId );
if( parentExists ){
var jsons = this.jsons();
var descs = this.descendants();
var descsEtcJsons = descs.union( descs.union( this ).connectedEdges() ).jsons();
this.remove(); // NB: also removes descendants and their connected edges
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
...unique = function (){
return new Collection( this._private.cy, this, { unique: true } );
}n/a
unlisten = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}n/a
unlock = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
unmerge = function ( toRemove ){
var cy = this._private.cy;
if( !toRemove ){
return this;
}
if( toRemove && is.string( toRemove ) ){
var selector = toRemove;
toRemove = cy.mutableElements().filter( selector );
}
for( var i = 0; i < toRemove.length; i++ ){
this.unmergeOne( toRemove[ i ] );
}
return this; // chaining
}...
var cy = self.cy();
var visited = self.spawn();
var unvisited = self.nodes().spawnSelf();
var components = [];
var visitInComponent = function( node, component ){
visited.merge( node );
unvisited.unmerge( node );
component.merge( node );
};
if( unvisited.empty() ){ return self.spawn(); }
do {
var component = cy.collection();
...unmergeOne = function ( ele ){
ele = ele[0];
var _p = this._private;
var id = ele._private.data.id;
var i = _p.indexes[ id ];
if( i == null ){
return this; // no need to remove
}
// remove ele
this[ i ] = undefined;
_p.ids[ id ] = undefined;
_p.indexes[ id ] = undefined;
var unmergedLastEle = i === this.length - 1;
// replace empty spot with last ele in collection
if( this.length > 1 && !unmergedLastEle ){
var lastEleI = this.length - 1;
var lastEle = this[ lastEleI ];
var lastEleId = lastEle._private.data.id;
this[ lastEleI ] = undefined;
this[ i ] = lastEle;
_p.indexes[ lastEleId ] = i;
}
// the collection is now 1 ele smaller
this.length--;
return this;
}...
if( toRemove && is.string( toRemove ) ){
var selector = toRemove;
toRemove = cy.mutableElements().filter( selector );
}
for( var i = 0; i < toRemove.length; i++ ){
this.unmergeOne( toRemove[ i ] );
}
return this; // chaining
},
map: function( mapFn, thisArg ){
var arr = [];
...unselect = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
unselectify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
updateCompoundBounds = function (){
var cy = this.cy();
// save cycles for non compound graphs or when style disabled
if( !cy.styleEnabled() || !cy.hasCompoundNodes() ){ return cy.collection(); }
var updated = [];
function update( parent ){
if( !parent.isParent() ){ return; }
var _p = parent._private;
var children = parent.children();
var includeLabels = parent.pstyle( 'compound-sizing-wrt-labels' ).value === 'include';
var bb = children.boundingBox( {
includeLabels: includeLabels,
includeOverlays: false,
// updating the compound bounds happens outside of the regular
// cache cycle (i.e. before fired events)
useCache: false
} );
var pos = _p.position;
_p.autoWidth = bb.w;
pos.x = (bb.x1 + bb.x2) / 2;
_p.autoHeight = bb.h;
pos.y = (bb.y1 + bb.y2) / 2;
updated.push( parent );
}
// go up, level by level
var eles = this;
while( eles.nonempty() ){
// update each parent node in this level
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
update( ele );
}
// next level
eles = eles.parent();
}
// return changed
return this.spawn( updated );
}...
allowSetting: true,
settingEvent: 'position',
settingTriggersEvent: true,
triggerFnName: 'rtrigger',
allowGetting: true,
validKeys: [ 'x', 'y' ],
onSet: function( eles ){
var updatedEles = eles.updateCompoundBounds();
updatedEles.rtrigger( 'position' );
},
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
...updateMappers = function ( notifyRenderer ){
var cy = this._private.cy;
var style = cy.style();
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( !cy.styleEnabled() ){ return this; }
style.updateMappers( this );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
if( notifyRenderer ){
toNotify.rtrigger( 'style' ); // let renderer know we changed style
} else {
toNotify.trigger( 'style' ); // just fire the event
}
return this; // chaining
}...
updateMappers: function( notifyRenderer ){
var cy = this._private.cy;
var style = cy.style();
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( !cy.styleEnabled() ){ return this; }
style.updateMappers( this );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
if( notifyRenderer ){
toNotify.rtrigger( 'style' ); // let renderer know we changed style
} else {
...updateStyle = function ( notifyRenderer ){
var cy = this._private.cy;
if( !cy.styleEnabled() ){ return this; }
if( cy._private.batchingStyle ){
var bEles = cy._private.batchStyleEles;
bEles.merge( this );
return this; // chaining and exit early when batching
}
var hasCompounds = cy.hasCompoundNodes();
var style = cy.style();
var updatedEles = this;
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( hasCompounds ){ // then add everything up and down for compound selector checks
updatedEles = this.spawnSelf().merge( this.descendants() ).merge( this.parents() );
}
style.apply( updatedEles );
if( hasCompounds ){
var updatedCompounds = updatedEles.updateCompoundBounds();
// disable for performance for now
// (as updatedCompounds would be a subset of updatedEles ayway b/c of selectors check)
// if( updatedCompounds.length > 0 ){
// updatedEles.merge( updatedCompounds );
// }
}
if( notifyRenderer ){
updatedEles.rtrigger( 'style' ); // let renderer know we changed style
} else {
updatedEles.trigger( 'style' ); // just fire the event
}
return this; // chaining
}...
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
...visible = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return true; }
var ele = this[0];
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele ){
var _p = ele._private;
if( !ok( ele ) ){ return false; }
if( ele.isNode() ){
if( hasCompoundNodes ){
var parents = _p.data.parent ? ele.parents() : null;
if( parents ){ for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
if( !parentOk( parent ) ){ return false; }
} }
}
return true;
} else {
return edgeOkViaNode( _p.source ) && edgeOkViaNode( _p.target );
}
}
}...
case ':locked':
allColonSelectorsMatch = ele.locked();
break;
case ':unlocked':
allColonSelectorsMatch = !ele.locked();
break;
case ':visible':
allColonSelectorsMatch = ele.visible();
break;
case ':hidden':
allColonSelectorsMatch = !ele.visible();
break;
case ':transparent':
allColonSelectorsMatch = ele.transparent();
break;
...function dimImpl(){
var ele = this[0];
var _p = ele._private;
var cy = _p.cy;
var styleEnabled = cy._private.styleEnabled;
if( ele ){
if( styleEnabled ){
if( ele.isParent() ){
return _p[ opts.autoName ] || 0;
}
var d = ele.pstyle( opts.name );
switch( d.strValue ){
case 'label':
return _p.rstyle[ opts.labelName ] || 0;
default:
return d.pfValue;
}
} else {
return 1;
}
}
}...
}
};
}
var eleTakesUpSpace = function( ele ){
return (
ele.pstyle( 'display' ).value === 'element'
&& ele.width() !== 0
&& ( ele.isNode() ? ele.height() !== 0 : true )
);
};
elesfn.takesUpSpace = defineDerivedStateFunction({
ok: eleTakesUpSpace
});
...xor = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var elements = [];
var col1 = this;
var col2 = other;
var add = function( col, other ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( !inOther ){
elements.push( ele );
}
}
};
add( col1, col2 );
add( col2, col1 );
return this.spawn( elements );
}n/a
zDepth = function (){
var ele = this[0];
if( !ele ){ return undefined; }
// var cy = ele.cy();
var _p = ele._private;
var group = _p.group;
if( group === 'nodes' ){
var depth = _p.data.parent ? ele.parents().size() : 0;
if( !ele.isParent() ){
return Number.MAX_VALUE; // childless nodes always on top
}
return depth;
} else {
var src = _p.source;
var tgt = _p.target;
var srcDepth = src.zDepth();
var tgtDepth = tgt.zDepth();
return Math.max( srcDepth, tgtDepth, 0 ); // depth of deepest parent
}
}...
return Number.MAX_VALUE; // childless nodes always on top
}
return depth;
} else {
var src = _p.source;
var tgt = _p.target;
var srcDepth = src.zDepth();
var tgtDepth = tgt.zDepth();
return Math.max( srcDepth, tgtDepth, 0 ); // depth of deepest parent
}
}
});
...event = function ( src, props ){
// Allow instantiation without the 'new' keyword
if( !(this instanceof Event) ){
return new Event( src, props );
}
// Event object
if( src && src.type ){
this.originalEvent = src;
this.type = src.type;
// Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = ( src.defaultPrevented ) ? returnTrue : returnFalse;
// Event type
} else {
this.type = src;
}
// Put explicitly provided properties onto the event object
if( props ){
// util.extend( this, props );
// more efficient to manually copy fields we use
this.type = props.type !== undefined ? props.type : this.type;
this.cy = props.cy;
this.target = props.target;
this.position = props.position;
this.renderedPosition = props.renderedPosition;
this.namespace = props.namespace;
this.layout = props.layout;
this.message = props.message;
}
// Create a timestamp if incoming event doesn't have one
this.timeStamp = src && src.timeStamp || Date.now();
}...
return function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
...instanceString = function (){
return 'event';
}...
var typeofstr = typeof '';
var typeofobj = typeof {};
var typeoffn = typeof function(){};
var typeofhtmlele = typeof HTMLElement;
var instanceStr = function( obj ){
return obj && obj.instanceString && is.fn( obj.instanceString ) ? obj.instanceString
() : null;
};
var is = {
defined: function( obj ){
return obj != null; // not undefined or null
},
...function returnFalse(){
return false;
}n/a
function returnFalse(){
return false;
}n/a
function returnFalse(){
return false;
}...
}
}
// run the callback
var context = lis.delegated ? evt.target : triggerer;
var ret = lis.callback.apply( context, args );
if( ret === false || evt.isPropagationStopped() ){
// then don't bubble
bubbleUp = false;
if( ret === false ){
// returning false is a shorthand for stopping propagation and preventing the def. action
evt.stopPropagation();
evt.preventDefault();
...preventDefault = function (){
this.isDefaultPrevented = returnTrue;
var e = this.originalEvent;
if( !e ){
return;
}
// if preventDefault exists run it on the original event
if( e.preventDefault ){
e.preventDefault();
}
}...
if( ret === false || evt.isPropagationStopped() ){
// then don't bubble
bubbleUp = false;
if( ret === false ){
// returning false is a shorthand for stopping propagation and preventing the def. action
evt.stopPropagation();
evt.preventDefault();
}
}
} // if listener matches
} // for each listener
// bubble up event for elements
if( bubbleUp ){
...stopImmediatePropagation = function (){
this.isImmediatePropagationStopped = returnTrue;
this.stopPropagation();
}n/a
stopPropagation = function (){
this.isPropagationStopped = returnTrue;
var e = this.originalEvent;
if( !e ){
return;
}
// if stopPropagation exists run it on the original event
if( e.stopPropagation ){
e.stopPropagation();
}
}...
if( ret === false || evt.isPropagationStopped() ){
// then don't bubble
bubbleUp = false;
if( ret === false ){
// returning false is a shorthand for stopping propagation and preventing the def. action
evt.stopPropagation();
evt.preventDefault();
}
}
} // if listener matches
} // for each listener
// bubble up event for elements
...function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}n/a
function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}...
this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */
this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */
this.onFulfilled = []; /* initial handlers */
this.onRejected = []; /* initial handlers */
/* provide optional information-hiding proxy */
this.proxy = {
then: this.then.bind( this )
};
/* support optional executor function */
if( typeof executor === 'function' )
executor.call( this, this.fulfill.bind( this ), this.reject.bind( this ) );
};
...function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
events.push( {
type: type,
namespace: namespace
} );
}
} else if( eventsIsObject ){ // put in length 1 array
var eventArgObj = events;
events = [ eventArgObj ];
}
if( extraParams ){
if( !is.array( extraParams ) ){ // make sure extra params are in an array if specified
extraParams = [ extraParams ];
}
} else { // otherwise, we've got nothing
extraParams = [];
}
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
evt.target = evt.target || triggerer;
evt.cy = evt.cy || cy;
} else { // then we have to make one
evt = new Event( evtObj, {
target: triggerer,
cy: cy,
namespace: evtObj.namespace
} );
}
// if a layout was specified, then put it in the typed event
if( evtObj.layout ){
evt.layout = evtObj.layout;
}
// if triggered by layout, put in event
if( params.layout ){
evt.layout = triggerer;
}
// create a rendered position based on the passed position
if( evt.position ){
var pos = evt.position;
var zoom = cy.zoom();
var pan = cy.pan();
evt.renderedPosition = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
}
if( fnToTrigger ){ // then override the listeners list with just the one we specified
listeners = [ {
namespace: evt.namespace,
type: evt.type,
callback: fnToTrigger
} ];
}
for( var k = 0; k < listeners.length; k++ ){ // check each listener
var lis = listeners[ k ];
var nsMatches = !lis.namespace || lis.namespace === evt.namespace || lis.namespace === define.event.universalNamespace;
var typeMatches = lis.type === evt.type;
var targetMatches = lis.delegated ? ( triggerer !== evt.target && is.element( evt.target ) && lis.selObj.matches( evt.target
) ) : (true); // we're not going to validate the hierarchy; that's too expensive
var listenerMatches = nsMatches && typeMatches && targetMatches;
if( listenerMatches ){ // then trigger it
var args = [ evt ];
args = args.concat( extraParams ); // add extra params to args list
if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener
listeners.splice( k, 1 );
k--;
}
if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders
var binders = lis.binders;
for( var l = 0; l < binders.length; l++ ){
var binder = b ...n/a
function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}n/a
off = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}...
return this;
};
}
layoutProto.on = define.on( { layout: true } );
layoutProto.one = define.on( { layout: true, unbindSelfOnTrigger: true } );
layoutProto.once = define.on( { layout: true, unbindAllBindersOnTrigger: true } );
layoutProto.off = define.off( { layout: true } );
layoutProto.trigger = define.trigger( { layout: true } );
define.eventAliasesOn( layoutProto );
ext = Layout; // replace with our wrapped layout
} else if( type === 'renderer' && name !== 'null' && name !== 'base' ){
...function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}...
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
// .data(function(){ ... })
} else if( p.allowBinding && is.fn( name ) ){ // bind to event
var fn = name;
self.on( p.bindingEvent, fn );
// .data()
} else if( p.allowGetting && name === undefined ){ // get whole object
var ret;
if( single ){
ret = single._private[ p.field ];
}
...function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}n/a
function onImpl( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var p = params;
if( is.fn( selector ) ){ // selector is actually callback
callback = selector;
selector = undefined;
}
// if there isn't a callback, we can't really do anything
// (can't speak for mapped events arg version)
if( !(is.fn( callback ) || callback === false) && eventsIsString ){
return self; // maintain chaining
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
if( !is.fn( callback ) ){ continue; }
evts = evts.split( /\s+/ );
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
if( match ){
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
var listener = {
callback: callback, // callback to run
delegated: selector ? true : false, // whether the evt is delegated
selector: selector, // the selector to match for delegated events
selObj: new Selector( selector ), // cached selector object to save rebuilding
type: type, // the event type (e.g. 'click')
namespace: namespace, // the event namespace (e.g. ".foo")
unbindSelfOnTrigger: p.unbindSelfOnTrigger,
unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,
binders: all // who bound together
};
for( var j = 0; j < all.length; j++ ){
var _p = all[ j ]._private = all[ j ]._private || {};
_p.listeners = _p.listeners || [];
_p.listeners.push( listener );
}
}
} // for events array
} // for events map
return self; // maintain chaining
}...
var onStep;
cy.on( 'step.*', ( onStep = function(){
if( options.fit ){
cy.fit( options.eles, options.padding );
}
}) );
layout.one('layoutstop', function(){
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
...pon = function ( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
self.on.apply( self, onArgs );
} );
}n/a
promiseOn = function ( events, selector ){
var self = this;
var args = Array.prototype.slice.call( arguments, 0 );
return new Promise( function( resolve, reject ){
var callback = function( e ){
self.off.apply( self, offArgs );
resolve( e );
};
var onArgs = args.concat( [ callback ] );
var offArgs = onArgs.concat( [] );
self.on.apply( self, onArgs );
} );
}n/a
removeListener = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}n/a
rtrigger = function ( event, extraParams ){ // for internal use only
if( this.length === 0 ){ return; } // empty collections don't need to notify anything
// notify renderer
this.cy().notify( {
type: event,
eles: this
} );
this.trigger( event, extraParams );
return this;
}...
settingEvent: 'position',
settingTriggersEvent: true,
triggerFnName: 'rtrigger',
allowGetting: true,
validKeys: [ 'x', 'y' ],
onSet: function( eles ){
var updatedEles = eles.updateCompoundBounds();
updatedEles.rtrigger( 'position' );
},
canSet: function( ele ){
return !ele.locked() && !ele.isParent();
}
} ),
// position but no notification to renderer
...function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
for( var i = 0; i < evts.length; i++ ){
var evt = evts[ i ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.regex ); // type[.namespace]
var type = match[1];
var namespace = match[2] ? match[2] : undefined;
events.push( {
type: type,
namespace: namespace
} );
}
} else if( eventsIsObject ){ // put in length 1 array
var eventArgObj = events;
events = [ eventArgObj ];
}
if( extraParams ){
if( !is.array( extraParams ) ){ // make sure extra params are in an array if specified
extraParams = [ extraParams ];
}
} else { // otherwise, we've got nothing
extraParams = [];
}
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
evt.target = evt.target || triggerer;
evt.cy = evt.cy || cy;
} else { // then we have to make one
evt = new Event( evtObj, {
target: triggerer,
cy: cy,
namespace: evtObj.namespace
} );
}
// if a layout was specified, then put it in the typed event
if( evtObj.layout ){
evt.layout = evtObj.layout;
}
// if triggered by layout, put in event
if( params.layout ){
evt.layout = triggerer;
}
// create a rendered position based on the passed position
if( evt.position ){
var pos = evt.position;
var zoom = cy.zoom();
var pan = cy.pan();
evt.renderedPosition = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
}
if( fnToTrigger ){ // then override the listeners list with just the one we specified
listeners = [ {
namespace: evt.namespace,
type: evt.type,
callback: fnToTrigger
} ];
}
for( var k = 0; k < listeners.length; k++ ){ // check each listener
var lis = listeners[ k ];
var nsMatches = !lis.namespace || lis.namespace === evt.namespace || lis.namespace === define.event.universalNamespace;
var typeMatches = lis.type === evt.type;
var targetMatches = lis.delegated ? ( triggerer !== evt.target && is.element( evt.target ) && lis.selObj.matches( evt.target
) ) : (true); // we're not going to validate the hierarchy; that's too expensive
var listenerMatches = nsMatches && typeMatches && targetMatches;
if( listenerMatches ){ // then trigger it
var args = [ evt ];
args = args.concat( extraParams ); // add extra params to args list
if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener
listeners.splice( k, 1 );
k--;
}
if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders
var binders = lis.binders;
for( var l = 0; l < binders.length; l++ ){
var binder = b ......
// bubble up event for elements
if( bubbleUp ){
var parent = hasCompounds ? triggerer._private.parent : null;
var hasParent = parent != null && parent.length !== 0;
if( hasParent ){ // then bubble up to parent
parent = parent[0];
parent.trigger( evt );
} else { // otherwise, bubble up to the core
cy.trigger( evt );
}
}
} // for each of all
} // for each event
...unbind = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}n/a
unlisten = function ( events, selector, callback ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
if( arguments.length === 0 ){ // then unbind all
for( var i = 0; i < all.length; i++ ){
all[ i ]._private = all[ i ]._private || {};
_p.listeners = [];
}
return self; // maintain chaining
}
if( is.fn( selector ) || selector === false ){ // selector is actually callback
callback = selector;
selector = undefined;
}
if( eventsIsString ){ // then convert to map
var map = {};
map[ events ] = callback;
events = map;
}
var keys = Object.keys( events );
for( var k = 0; k < keys.length; k++ ){
var evts = keys[k];
callback = events[ evts ];
if( callback === false ){
callback = define.event.falseCallback;
}
evts = evts.split( /\s+/ );
for( var h = 0; h < evts.length; h++ ){
var evt = evts[ h ];
if( is.emptyString( evt ) ){ continue; }
var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]
if( match ){
var type = match[1] ? match[1] : undefined;
var namespace = match[2] ? match[2] : undefined;
for( var i = 0; i < all.length; i++ ){ //
var _p = all[ i ]._private = all[ i ]._private || {};
var listeners = _p.listeners = _p.listeners || [];
for( var j = 0; j < listeners.length; j++ ){
var listener = listeners[ j ];
var nsMatches = !namespace || namespace === listener.namespace;
var typeMatches = !type || listener.type === type;
var cbMatches = !callback || callback === listener.callback;
var listenerMatches = nsMatches && typeMatches && cbMatches;
// delete listener if it matches
if( listenerMatches ){
listeners.splice( j, 1 );
j--;
}
} // for listeners
} // for all
} // if match
} // for events array
} // for events map
return self; // maintain chaining
}n/a
jpeg = function ( options ){
var renderer = this._private.renderer;
options = options || {};
options.bg = options.bg || '#fff';
return renderer.jpg( options );
}n/a
jpg = function ( options ){
var renderer = this._private.renderer;
options = options || {};
options.bg = options.bg || '#fff';
return renderer.jpg( options );
}...
jpg: function( options ){
var renderer = this._private.renderer;
options = options || {};
options.bg = options.bg || '#fff';
return renderer.jpg( options );
}
});
corefn.jpeg = corefn.jpg;
module.exports = corefn;
...png = function ( options ){
var renderer = this._private.renderer;
options = options || {};
return renderer.png( options );
}...
var corefn = ({
png: function( options ){
var renderer = this._private.renderer;
options = options || {};
return renderer.png( options );
},
jpg: function( options ){
var renderer = this._private.renderer;
options = options || {};
options.bg = options.bg || '#fff';
...filter = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}...
meta: [],
// fake selectors
collection: null, // a collection to match against
filter: null, // filter function
// these are defined in the upward direction rather than down (e.g. child)
// because we need to go up in Selector.filter()
parent: null, // parent query obj
ancestor: null, // ancestor query obj
subject: null, // defines subject in compound query (subject query obj; points to self if subject)
// use these only when subject has been defined
child: null,
descendant: null
...abscomp = function (){
var cy = this._private.cy;
return cy.mutableElements().not( this );
}n/a
absoluteComplement = function (){
var cy = this._private.cy;
return cy.mutableElements().not( this );
}n/a
add = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}...
var elePos = ele._private.position;
elePos.x = pos.x;
elePos.y = pos.y;
}
}
var updatedEles = this.updateCompoundBounds();
var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;
if( silent ){
toTrigger.trigger( 'position' );
} else {
toTrigger.rtrigger( 'position' );
}
}
...and = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}n/a
complement = function (){
var cy = this._private.cy;
return cy.mutableElements().not( this );
}n/a
diff = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var left = [];
var right = [];
var both = [];
var col1 = this;
var col2 = other;
var add = function( col, other, retEles ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( inOther ){
both.push( ele );
} else {
retEles.push( ele );
}
}
};
add( col1, col2, left );
add( col2, col1, right );
return {
left: this.spawn( left, { unique: true } ),
right: this.spawn( right, { unique: true } ),
both: this.spawn( both, { unique: true } )
};
}n/a
difference = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}n/a
edges = function ( selector ){
return this.filter( function( ele, i ){
return ele.isEdge();
} ).filter( selector );
}...
var defaults = {
codirected: false
};
params = util.extend( {}, defaults, params );
return function parallelEdgesImpl( selector ){ // micro-optimised for renderer
var elements = [];
var edges = this.edges();
var p = params;
// look at all the edges in the collection
for( var i = 0; i < edges.length; i++ ){
var edge1 = edges[ i ];
var edge1_p = edge1._private;
var src1 = edge1_p.source;
...filterFn = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}n/a
fnFilter = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}n/a
intersect = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}...
collection = this.cy().collection( collection );
// cheap extra check
if( this.length !== collection.length ){
return false;
}
return this.intersect( collection ).length === this.length;
},
anySame: function( collection ){
collection = this.cy().collection( collection );
return this.intersect( collection ).length > 0;
},
...intersection = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}...
var alpha = options.alpha;
} else {
alpha = 0;
}
if( !directed ){
var connEdges = root.connectedEdges().intersection( callingEles );
var k = connEdges.length;
var s = 0;
// Now, sum edge weights
for( var i = 0; i < connEdges.length; i++ ){
var edge = connEdges[ i ];
s += weightFn( edge );
...map = function ( mapFn, thisArg ){
var arr = [];
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var ret = thisArg ? mapFn.apply( thisArg, [ ele, i, eles ] ) : mapFn( ele, i, eles );
arr.push( ret );
}
return arr;
}...
layout.one('layoutstop', function(){
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
return ani.promise();
}) ).then(function(){
cy.off('step.*', onStep);
if( options.zoom != null ){
cy.zoom( options.zoom );
}
...max = function ( valFn, thisArg ){
var max = -Infinity;
var maxEle;
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );
if( val > max ){
max = val;
maxEle = ele;
}
}
return {
value: max,
ele: maxEle
};
}...
var b = math.dist( A, C );
var c = math.dist( A, B );
return Math.acos( (a*a + b*b - c*c)/(2*a*b) );
};
math.bound = function( min, val, max ){
return Math.max( min, Math.min( max, val ) );
};
// makes a full bb (x1, y1, x2, y2, w, h) from implicit params
math.makeBoundingBox = function( bb ){
if( bb == null ){
return {
x1: Infinity,
...merge = function ( toAdd ){
var _p = this._private;
var cy = _p.cy;
if( !toAdd ){
return this;
}
if( toAdd && is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
for( var i = 0; i < toAdd.length; i++ ){
var toAddEle = toAdd[ i ];
var id = toAddEle._private.data.id;
var add = !_p.ids[ id ];
if( add ){
var index = this.length++;
this[ index ] = toAddEle;
_p.ids[ id ] = toAddEle;
_p.indexes[ id ] = index;
} else { // replace
var index = _p.indexes[ id ];
this[ index ] = toAddEle;
_p.ids[ id ] = toAddEle;
}
}
return this; // chaining
}...
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
...min = function ( valFn, thisArg ){
var min = Infinity;
var minEle;
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );
if( val < min ){
min = val;
minEle = ele;
}
}
return {
value: min,
ele: minEle
};
}...
var b = math.dist( A, C );
var c = math.dist( A, B );
return Math.acos( (a*a + b*b - c*c)/(2*a*b) );
};
math.bound = function( min, val, max ){
return Math.max( min, Math.min( max, val ) );
};
// makes a full bb (x1, y1, x2, y2, w, h) from implicit params
math.makeBoundingBox = function( bb ){
if( bb == null ){
return {
x1: Infinity,
...n = function ( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
}
var elements = [];
var col1 = this;
var col2 = other;
var col1Smaller = this.length < other.length;
// var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;
var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;
var col = col1Smaller ? col1 : col2;
for( var i = 0; i < col.length; i++ ){
var id = col[ i ]._private.data.id;
var ele = ids2[ id ];
if( ele ){
elements.push( ele );
}
}
return this.spawn( elements );
}n/a
nodes = function ( selector ){
return this.filter( function( ele, i ){
return ele.isNode();
} ).filter( selector );
}...
}
} )
} );
function defineDegreeBoundsFunction( degreeFn, callback ){
return function( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
...not = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}...
children = children.concat( ele._private.children );
}
return this.spawn( children, { unique: true } ).filter( selector );
},
siblings: function( selector ){
return this.parent().children().not( this ).filter( selector );
},
isParent: function(){
var ele = this[0];
if( ele ){
return ele._private.children.length !== 0;
...or = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}n/a
relativeComplement = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}n/a
stdFilter = function ( filter, thisArg ){
if( filter === undefined ){ // check this first b/c it's the most common/performant case
return this;
} else if( is.string( filter ) || is.elementOrCollection( filter ) ){
return Selector( filter ).filter( this );
} else if( is.fn( filter ) ){
var filterEles = this.spawn();
var eles = this;
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var include = thisArg ? filter.apply( thisArg, [ ele, i, eles ] ) : filter( ele, i, eles );
if( include ){
filterEles.merge( ele );
}
}
return filterEles;
}
return this.spawn(); // if not handled by above, give 'em an empty collection
}...
ancestors = ancestors.intersect( parents ); // current list must be common with current ele parents set
}
return ancestors.filter( selector );
},
orphans: function( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().empty();
} ).filter( selector );
},
nonorphans: function( selector ){
return this.stdFilter( function( ele ){
return ele.isNode() && ele.parent().nonempty();
...subtract = function ( toRemove ){
if( !toRemove ){
return this;
} else {
if( is.string( toRemove ) ){
toRemove = this.filter( toRemove );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
var element = this[ i ];
var remove = toRemove._private.ids[ element.id() ];
if( !remove ){
elements.push( element );
}
}
return this.spawn( elements );
}
}n/a
symdiff = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var elements = [];
var col1 = this;
var col2 = other;
var add = function( col, other ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( !inOther ){
elements.push( ele );
}
}
};
add( col1, col2 );
add( col2, col1 );
return this.spawn( elements );
}n/a
symmetricDifference = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var elements = [];
var col1 = this;
var col2 = other;
var add = function( col, other ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( !inOther ){
elements.push( ele );
}
}
};
add( col1, col2 );
add( col2, col1 );
return this.spawn( elements );
}n/a
u = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}n/a
union = function ( toAdd ){
var cy = this._private.cy;
if( !toAdd ){
return this;
}
if( is.string( toAdd ) ){
var selector = toAdd;
toAdd = cy.mutableElements().filter( selector );
}
var elements = [];
for( var i = 0; i < this.length; i++ ){
elements.push( this[ i ] );
}
for( var i = 0; i < toAdd.length; i++ ){
var add = !this._private.ids[ toAdd[ i ].id() ];
if( add ){
elements.push( toAdd[ i ] );
}
}
return this.spawn( elements );
}...
} else if( struct.parent !== undefined ){ // move node to new parent
var parentId = struct.parent;
var parentExists = parentId === null || cy.hasElementWithId( parentId );
if( parentExists ){
var jsons = this.jsons();
var descs = this.descendants();
var descsEtcJsons = descs.union( descs.union( this ).connectedEdges() ).jsons();
this.remove(); // NB: also removes descendants and their connected edges
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
...unmerge = function ( toRemove ){
var cy = this._private.cy;
if( !toRemove ){
return this;
}
if( toRemove && is.string( toRemove ) ){
var selector = toRemove;
toRemove = cy.mutableElements().filter( selector );
}
for( var i = 0; i < toRemove.length; i++ ){
this.unmergeOne( toRemove[ i ] );
}
return this; // chaining
}...
var cy = self.cy();
var visited = self.spawn();
var unvisited = self.nodes().spawnSelf();
var components = [];
var visitInComponent = function( node, component ){
visited.merge( node );
unvisited.unmerge( node );
component.merge( node );
};
if( unvisited.empty() ){ return self.spawn(); }
do {
var component = cy.collection();
...unmergeOne = function ( ele ){
ele = ele[0];
var _p = this._private;
var id = ele._private.data.id;
var i = _p.indexes[ id ];
if( i == null ){
return this; // no need to remove
}
// remove ele
this[ i ] = undefined;
_p.ids[ id ] = undefined;
_p.indexes[ id ] = undefined;
var unmergedLastEle = i === this.length - 1;
// replace empty spot with last ele in collection
if( this.length > 1 && !unmergedLastEle ){
var lastEleI = this.length - 1;
var lastEle = this[ lastEleI ];
var lastEleId = lastEle._private.data.id;
this[ lastEleI ] = undefined;
this[ i ] = lastEle;
_p.indexes[ lastEleId ] = i;
}
// the collection is now 1 ele smaller
this.length--;
return this;
}...
if( toRemove && is.string( toRemove ) ){
var selector = toRemove;
toRemove = cy.mutableElements().filter( selector );
}
for( var i = 0; i < toRemove.length; i++ ){
this.unmergeOne( toRemove[ i ] );
}
return this; // chaining
},
map: function( mapFn, thisArg ){
var arr = [];
...xor = function ( other ){
var cy = this._private.cy;
if( is.string( other ) ){
other = cy.$( other );
}
var elements = [];
var col1 = this;
var col2 = other;
var add = function( col, other ){
for( var i = 0; i < col.length; i++ ){
var ele = col[ i ];
var id = ele._private.data.id;
var inOther = other._private.ids[ id ];
if( !inOther ){
elements.push( ele );
}
}
};
add( col1, col2 );
add( col2, col1 );
return this.spawn( elements );
}n/a
floydWarshall = function ( options ){
options = options || {};
var cy = this.cy();
// Weight function - optional
if( options.weight != null && is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
// directed - optional
if( options.directed != null ){
var directed = options.directed;
} else {
var directed = false;
}
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
// mapping: node id -> position in nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Initialize distance matrix
var dist = [];
for( var i = 0; i < numNodes; i++ ){
var newRow = new Array( numNodes );
for( var j = 0; j < numNodes; j++ ){
if( i == j ){
newRow[ j ] = 0;
} else {
newRow[ j ] = Infinity;
}
}
dist.push( newRow );
}
// Initialize matrix used for path reconstruction
// Initialize distance matrix
var next = [];
var edgeNext = [];
var initMatrix = function( next ){
for( var i = 0; i < numNodes; i++ ){
var newRow = new Array( numNodes );
for( var j = 0; j < numNodes; j++ ){
newRow[ j ] = undefined;
}
next.push( newRow );
}
};
initMatrix( next );
initMatrix( edgeNext );
// Process edges
for( var i = 0; i < edges.length ; i++ ){
var sourceIndex = id2position[ edges[ i ].source().id() ];
var targetIndex = id2position[ edges[ i ].target().id() ];
var weight = weightFn( edges[ i ] );
// Check if already process another edge between same 2 nodes
if( dist[ sourceIndex ][ targetIndex ] > weight ){
dist[ sourceIndex ][ targetIndex ] = weight;
next[ sourceIndex ][ targetIndex ] = targetIndex;
edgeNext[ sourceIndex ][ targetIndex ] = edges[ i ];
}
}
// If undirected graph, process 'reversed' edges
if( !directed ){
for( var i = 0; i < edges.length ; i++ ){
var sourceIndex = id2position[ edges[ i ].target().id() ];
var targetIndex = id2position[ edges[ i ].source().id() ];
var weight = weightFn( edges[ i ] );
// Check if already process another edge between same 2 nodes
if( dist[ sourceIndex ][ targetIndex ] > weight ){
dist[ sourceIndex ][ targetIndex ] = weight;
next[ sourceIndex ][ targetIndex ] = targetIndex;
edgeNext[ sourceIndex ][ targetIndex ] = edges[ i ];
}
}
}
// Main loop
for( var k = 0; k < numNodes; k++ ){
for( var i = 0; i < numNodes; i++ ){
for( var j = 0; j < numNodes; j++ ){
if( dist[ i ][ k ] + dist[ k ][ j ] < dist[ i ][ j ] ){
dist[ i ][ j ] = dist[ i ][ k ] + dist[ k ][ j ];
next[ i ][ j ] = next[ i ][ k ];
}
}
}
}
// Build result object
var position2id = [];
for( var i = 0; i < numNodes; i++ ){
position2id.push( nodes[ i ].id() );
}
var res = {
distance: function( from, to ){
if( is.string( from ) ){
// from is a selector string
var fromId = (cy.filter( from )[0]).id();
} else {
// from is a node
var fromId = from.id();
}
if( is.string( to ) ){
// to is a selector string
var toId = (cy.filter( to )[0]).id();
} else {
// to is a node
var toId = to.id();
}
return dist[ id2position[ fromId ] ][ id2position[ toId ] ];
},
path: function( from, to ){
var reconstructPathAux = function( from, to, next, position2id, edgeNext ){
if( from === to ){
return cy.getElementById( position2id[ from ] );
}
if( next[ from ][ to ] === undefined ){
return undefined;
}
var path = [ cy.getElementById( position2id[ from ] ) ];
var prev = from;
while( from !== to ){
prev = from;
from = next[ from ][ to ];
var edge = edgeNex ......
if( harmonic === undefined ){
harmonic = true;
}
var closenesses = {};
var maxCloseness = 0;
var nodes = this.nodes();
var fw = this.floydWarshall( { weight: options.weight, directed: options.directed } );
// Compute closeness for every node and find the maximum closeness
for( var i = 0; i < nodes.length; i++ ){
var currCloseness = 0;
for( var j = 0; j < nodes.length; j++ ){
if( i != j ){
var d = fw.distance( nodes[ i ], nodes[ j ] );
...getAnimationStartStyle = function ( ele, aniProps ){
var rstyle = {};
for( var i = 0; i < aniProps.length; i++ ){
var aniProp = aniProps[ i ];
var name = aniProp.name;
var styleProp = ele.pstyle( name );
if( styleProp !== undefined ){ // then make a prop of it
if( is.plainObject( styleProp ) ){
styleProp = this.parse( name, styleProp.strValue );
} else {
styleProp = this.parse( name, styleProp );
}
}
if( styleProp ){
rstyle[ name ] = styleProp;
}
}
return rstyle;
}n/a
getPropsList = function ( propsObj ){
var self = this;
var rstyle = [];
var style = propsObj;
var props = self.properties;
if( style ){
var names = Object.keys( style );
for( var i = 0; i < names.length; i++ ){
var name = names[i];
var val = style[ name ];
var prop = props[ name ] || props[ util.camel2dash( name ) ];
var styleProp = this.parse( prop.name, val );
rstyle.push( styleProp );
}
}
return rstyle;
}...
var propertiesEmpty = Object.keys( properties ).length === 0;
if( propertiesEmpty ){
return new Animation( all[0], properties ); // nothing to animate
}
if( isEles ){
properties.style = style.getPropsList( properties.style || properties.css );
properties.css = undefined;
}
if( properties.renderedPosition && isEles ){
var rpos = properties.renderedPosition;
var pan = cy.pan();
...getRawStyle = function ( ele, isRenderedVal ){
var self = this;
var ele = ele[0]; // insure it's an element
if( ele ){
var rstyle = {};
for( var i = 0; i < self.properties.length; i++ ){
var prop = self.properties[ i ];
var val = self.getStylePropertyValue( ele, prop.name, isRenderedVal );
if( val ){
rstyle[ prop.name ] = val;
rstyle[ util.dash2camel( prop.name ) ] = val;
}
}
return rstyle;
}
}...
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
}
} else if( name === undefined ){
var ele = this[0];
if( ele ){
return style.getRawStyle( ele );
} else { // empty collection => can't get any value
return;
}
}
return this; // chaining
},
...getRenderedStyle = function ( ele ){
return this.getRawStyle( ele, true );
}...
renderedStyle: function( property ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var ele = this[0];
if( ele ){
var renstyle = ele.cy().style().getRenderedStyle( ele );
if( property === undefined ){
return renstyle;
} else {
return renstyle[ property ];
}
}
...getStylePropertyValue = function ( ele, propName, isRenderedVal ){
var self = this;
var ele = ele[0]; // insure it's an element
if( ele ){
var prop = self.properties[ propName ];
if( prop.alias ){
prop = prop.pointsTo;
}
var type = prop.type;
var styleProp = ele.pstyle( prop.name );
var zoom = ele.cy().zoom();
if( styleProp ){
var units = styleProp.units ? type.implicitUnits || 'px' : null;
var val = units ? [].concat( styleProp.pfValue ).map( function( pfValue ){
return ( pfValue * (isRenderedVal ? zoom : 1) ) + units;
} ).join( ' ' ) : styleProp.strValue;
return val;
}
}
}...
} else if( is.string( name ) ){
if( value === undefined ){ // then get the property from the style
var ele = this[0];
if( ele ){
return style.getStylePropertyValue( ele, name );
} else { // empty collection => can't get any value
return;
}
} else { // then set the bypass with the property value
style.applyBypass( this, name, value, updateTransitions );
...function GridLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
run = function (){
var params = this.options;
var options = params;
var cy = params.cy;
var eles = options.eles;
var nodes = eles.nodes().not( ':parent' );
if( options.sort ){
nodes = nodes.sort( options.sort );
}
var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} );
if( bb.h === 0 || bb.w === 0 ){
nodes.layoutPositions( this, options, function( ele ){
return { x: bb.x1, y: bb.y1 };
} );
} else {
// width/height * splits^2 = cells where splits is number of times to split width
var cells = nodes.size();
var splits = Math.sqrt( cells * bb.h / bb.w );
var rows = Math.round( splits );
var cols = Math.round( bb.w / bb.h * splits );
var small = function( val ){
if( val == null ){
return Math.min( rows, cols );
} else {
var min = Math.min( rows, cols );
if( min == rows ){
rows = val;
} else {
cols = val;
}
}
};
var large = function( val ){
if( val == null ){
return Math.max( rows, cols );
} else {
var max = Math.max( rows, cols );
if( max == rows ){
rows = val;
} else {
cols = val;
}
}
};
var oRows = options.rows;
var oCols = options.cols != null ? options.cols : options.columns;
// if rows or columns were set in options, use those values
if( oRows != null && oCols != null ){
rows = oRows;
cols = oCols;
} else if( oRows != null && oCols == null ){
rows = oRows;
cols = Math.ceil( cells / rows );
} else if( oRows == null && oCols != null ){
cols = oCols;
rows = Math.ceil( cells / cols );
}
// otherwise use the automatic values and adjust accordingly
// if rounding was up, see if we can reduce rows or columns
else if( cols * rows > cells ){
var sm = small();
var lg = large();
// reducing the small side takes away the most cells, so try it first
if( (sm - 1) * lg >= cells ){
small( sm - 1 );
} else if( (lg - 1) * sm >= cells ){
large( lg - 1 );
}
} else {
// if rounding was too low, add rows or columns
while( cols * rows < cells ){
var sm = small();
var lg = large();
// try to add to larger side first (adds less in multiplication)
if( (lg + 1) * sm >= cells ){
large( lg + 1 );
} else {
small( sm + 1 );
}
}
}
var cellWidth = bb.w / cols;
var cellHeight = bb.h / rows;
if( options.condense ){
cellWidth = 0;
cellHeight = 0;
}
if( options.avoidOverlap ){
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var pos = node._private.position;
if( pos.x == null || pos.y == null ){ // for bb
pos.x = 0;
pos.y = 0;
}
var nbb = node.boundingBox();
var p = options.avoidOverlapPadding;
var w = nbb.w + p;
var h = nbb.h + p;
cellWidth = Math.max( cellWidth, w );
cellHeight = Math.max( cellHeight, h );
}
}
var cellUsed = {}; // e.g. 'c-0-2' => true
var used = function( row, col ){
return cellUsed[ 'c-' + row + '-' + col ] ? true : false;
};
var use = function( row, col ){
cellUsed[ 'c-' + row + '-' + col ] = true;
};
// to keep track of current cell position
var row = 0;
var col = 0;
var moveToNextCell = function(){
col++;
if( col >= cols ){
col = 0;
row++;
}
};
// get a cache of all the manual positions
var id2manPos = {};
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var rcPos = options.position( node );
if( rcPos && (rcPos.row !== undefined || rcPos.col !== undefined) ){ // must have at least row or col def'd
var pos = {
row: rcPos.row,
col: rcPos.col
};
if( pos.col === und ......
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...group = function (){
var ele = this[0];
if( ele ){
return ele._private.group;
}
}...
'use strict';
var elesfn = ({
isNode: function(){
return this.group() === 'nodes';
},
isEdge: function(){
return this.group() === 'edges';
},
isLoop: function(){
...isEdge = function (){
return this.group() === 'edges';
}...
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
break;
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) ===
ele.data( 'target' );
break;
case ':simple':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) !== ele.data( 'target' );
break;
case ':active':
allColonSelectorsMatch = ele.active();
break;
...isLoop = function (){
return this.isEdge() && this.source().id() === this.target().id();
}...
var degree = 0;
var node = self[0];
var connectedEdges = node._private.edges;
for( var i = 0; i < connectedEdges.length; i++ ){
var edge = connectedEdges[ i ];
if( !includeLoops && edge.isLoop() ){
continue;
}
degree += callback( node, edge );
}
return degree;
...isNode = function (){
return this.group() === 'nodes';
}...
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
case ':unanimated':
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
...isSimple = function (){
return this.isEdge() && this.source().id() !== this.target().id();
}n/a
function Heap( cmp ){
this.cmp = cmp != null ? cmp : defaultCmp;
this.nodes = [];
}n/a
heapify = function ( array, cmp ){
var i, _i, _j, _len, _ref, _ref1, _results, _results1;
if( cmp == null ){
cmp = defaultCmp;
}
_ref1 = (function(){
_results1 = [];
for( var _j = 0, _ref = floor( array.length / 2 ); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j-- ){ _results1.push
( _j ); }
return _results1;
}).apply( this ).reverse();
_results = [];
for( _i = 0, _len = _ref1.length; _i < _len; _i++ ){
i = _ref1[ _i ];
_results.push( _siftup( array, i, cmp ) );
}
return _results;
}n/a
nlargest = function ( array, n, cmp ){
var elem, result, _i, _len, _ref;
if( cmp == null ){
cmp = defaultCmp;
}
result = array.slice( 0, n );
if( !result.length ){
return result;
}
heapify( result, cmp );
_ref = array.slice( n );
for( _i = 0, _len = _ref.length; _i < _len; _i++ ){
elem = _ref[ _i ];
heappushpop( result, elem, cmp );
}
return result.sort( cmp ).reverse();
}n/a
nsmallest = function ( array, n, cmp ){
var elem, i, los, result, _i, _j, _len, _ref, _ref1, _results;
if( cmp == null ){
cmp = defaultCmp;
}
if( n * 10 <= array.length ){
result = array.slice( 0, n ).sort( cmp );
if( !result.length ){
return result;
}
los = result[ result.length - 1];
_ref = array.slice( n );
for( _i = 0, _len = _ref.length; _i < _len; _i++ ){
elem = _ref[ _i ];
if( cmp( elem, los ) < 0 ){
insort( result, elem, 0, null, cmp );
result.pop();
los = result[ result.length - 1];
}
}
return result;
}
heapify( array, cmp );
_results = [];
for( i = _j = 0, _ref1 = min( n, array.length ); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j ){
_results.push( heappop( array, cmp ) );
}
return _results;
}n/a
pop = function ( array, cmp ){
var lastelt, returnitem;
if( cmp == null ){
cmp = defaultCmp;
}
lastelt = array.pop();
if( array.length ){
returnitem = array[0];
array[0] = lastelt;
_siftup( array, 0, cmp );
} else {
returnitem = lastelt;
}
return returnitem;
}...
*/
heappop = function( array, cmp ){
var lastelt, returnitem;
if( cmp == null ){
cmp = defaultCmp;
}
lastelt = array.pop();
if( array.length ){
returnitem = array[0];
array[0] = lastelt;
_siftup( array, 0, cmp );
} else {
returnitem = lastelt;
}
...push = function ( array, item, cmp ){
if( cmp == null ){
cmp = defaultCmp;
}
array.push( item );
return _siftdown( array, 0, array.length - 1, cmp );
}...
_p.hooked = false;
_p.applying = false;
_p.progress = 0;
_p.completes = [];
_p.frames = [];
if( _p.complete && is.fn( _p.complete ) ){
_p.completes.push( _p.complete );
}
// for future timeline/animations impl
this.length = 1;
this[0] = this;
};
...pushpop = function ( array, item, cmp ){
var _ref;
if( cmp == null ){
cmp = defaultCmp;
}
if( array.length && cmp( array[0], item ) < 0 ){
_ref = [ array[0], item ], item = _ref[0], array[0] = _ref[1];
_siftup( array, 0, cmp );
}
return item;
}n/a
replace = function ( array, item, cmp ){
var returnitem;
if( cmp == null ){
cmp = defaultCmp;
}
returnitem = array[0];
array[0] = item;
_siftup( array, 0, cmp );
return returnitem;
}...
tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number
tokens.className = tokens.variable; // a class name (follows variable conventions)
tokens.id = tokens.variable; // an element id (follows variable conventions)
// when a token like a variable has escaped meta characters, we need to clean the backslashes out
// so that values get compared properly in Selector.filter()
var cleanMetaChars = function( str ){
return str.replace( new RegExp( '\\\\(' + tokens.metaChar + ')',
x27;g' ), function( match, $1, offset, original ){
return $1;
} );
};
// add @ variants to comparatorOp
var ops = tokens.comparatorOp.split( '|' );
for( var i = 0; i < ops.length; i++ ){
...updateItem = function ( array, item, cmp ){
var pos;
if( cmp == null ){
cmp = defaultCmp;
}
pos = array.indexOf( item );
if( pos === -1 ){
return;
}
_siftdown( array, 0, pos, cmp );
return _siftup( array, pos, cmp );
}...
if( d[w] > d[v] + edgeWeight ){
d[w] = d[v] + edgeWeight;
if( Q.nodes.indexOf( w ) < 0 ){ //if w is not in Q
Q.push( w );
} else { // update position if w is in Q
Q.updateItem( w );
}
g[w] = 0;
P[w] = [];
}
if( d[w] == d[v] + edgeWeight ){
...clear = function (){
return this.nodes = [];
}n/a
clone = function (){
var heap;
heap = new Heap();
heap.nodes = this.nodes.slice( 0 );
return heap;
}n/a
contains = function ( x ){
return this.nodes.indexOf( x ) !== -1;
}n/a
copy = function (){
var heap;
heap = new Heap();
heap.nodes = this.nodes.slice( 0 );
return heap;
}...
changedEle = true;
break;
}
}
}
if( changedEle ){
_p.classes = util.copy( classesMap );
changed.push( ele );
}
}
// trigger update style on those eles that had class changes
if( changed.length > 0 ){
...empty = function (){
return this.nodes.length === 0;
}...
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
break;
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) === ele.data( 'target' );
break;
case ':simple':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) !== ele.data( 'target' );
break;
...front = function (){
return this.nodes[0];
}n/a
has = function ( x ){
return this.nodes.indexOf( x ) !== -1;
}n/a
heapify = function (){
return heapify( this.nodes, this.cmp );
}n/a
insert = function ( x ){
return heappush( this.nodes, x, this.cmp );
}n/a
peek = function (){
return this.nodes[0];
}n/a
pop = function (){
return heappop( this.nodes, this.cmp );
}...
*/
heappop = function( array, cmp ){
var lastelt, returnitem;
if( cmp == null ){
cmp = defaultCmp;
}
lastelt = array.pop();
if( array.length ){
returnitem = array[0];
array[0] = lastelt;
_siftup( array, 0, cmp );
} else {
returnitem = lastelt;
}
...push = function ( x ){
return heappush( this.nodes, x, this.cmp );
}...
_p.hooked = false;
_p.applying = false;
_p.progress = 0;
_p.completes = [];
_p.frames = [];
if( _p.complete && is.fn( _p.complete ) ){
_p.completes.push( _p.complete );
}
// for future timeline/animations impl
this.length = 1;
this[0] = this;
};
...pushpop = function ( x ){
return heappushpop( this.nodes, x, this.cmp );
}n/a
replace = function ( x ){
return heapreplace( this.nodes, x, this.cmp );
}...
tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number
tokens.className = tokens.variable; // a class name (follows variable conventions)
tokens.id = tokens.variable; // an element id (follows variable conventions)
// when a token like a variable has escaped meta characters, we need to clean the backslashes out
// so that values get compared properly in Selector.filter()
var cleanMetaChars = function( str ){
return str.replace( new RegExp( '\\\\(' + tokens.metaChar + ')',
x27;g' ), function( match, $1, offset, original ){
return $1;
} );
};
// add @ variants to comparatorOp
var ops = tokens.comparatorOp.split( '|' );
for( var i = 0; i < ops.length; i++ ){
...size = function (){
return this.nodes.length;
}...
if( !matchesAny ){
return false;
}
}
// check filter function
if( query.filter != null && ele.collection().filter( query.filter ).size() ===
0 ){
return false;
}
// check parent/child relations
var confirmRelations = function( query, eles ){
if( query != null ){
var matches = false;
...toArray = function (){
return this.nodes.slice( 0 );
}...
},
sort: function( sortFn ){
if( !is.fn( sortFn ) ){
return this;
}
var sorted = this.toArray().sort( sortFn );
return this.spawn( sorted );
},
sortByZIndex: function(){
return this.sort( zIndexSort );
},
...top = function (){
return this.nodes[0];
}n/a
updateItem = function ( x ){
return updateItem( this.nodes, x, this.cmp );
}...
if( d[w] > d[v] + edgeWeight ){
d[w] = d[v] + edgeWeight;
if( Q.nodes.indexOf( w ) < 0 ){ //if w is not in Q
Q.push( w );
} else { // update position if w is in Q
Q.updateItem( w );
}
g[w] = 0;
P[w] = [];
}
if( d[w] == d[v] + edgeWeight ){
...index = function ( cy, elements, options ){
if( cy === undefined || !is.core( cy ) ){
util.error( 'A collection must have a reference to the core' );
return;
}
var ids = {};
var indexes = {};
var createdElements = false;
if( !elements ){
elements = [];
} else if( elements.length > 0 && is.plainObject( elements[0] ) && !is.element( elements[0] ) ){
createdElements = true;
// make elements from json and restore all at once later
var eles = [];
var elesIds = {};
for( var i = 0, l = elements.length; i < l; i++ ){
var json = elements[ i ];
if( json.data == null ){
json.data = {};
}
var data = json.data;
// make sure newly created elements have valid ids
if( data.id == null ){
data.id = idFactory.generate( cy, json );
} else if( cy.hasElementWithId( data.id ) || elesIds[ data.id ] ){
continue; // can't create element if prior id already exists
}
var ele = new Element( cy, json, false );
eles.push( ele );
elesIds[ data.id ] = true;
}
elements = eles;
}
this.length = 0;
for( var i = 0, l = elements.length; i < l; i++ ){
var element = elements[ i ];
if( !element ){ continue; }
var id = element._private.data.id;
if( !options || (options.unique && !ids[ id ] ) ){
ids[ id ] = element;
indexes[ id ] = this.length;
this[ this.length ] = element;
this.length++;
}
}
this._private = {
cy: cy,
ids: ids,
indexes: indexes
};
// restore the elements if we created them from json
if( createdElements ){
this.restore();
}
}n/a
array = function ( obj ){
return Array.isArray ? Array.isArray( obj ) : obj != null && obj instanceof Array;
}...
} else if( eventsIsObject ){ // put in length 1 array
var eventArgObj = events;
events = [ eventArgObj ];
}
if( extraParams ){
if( !is.array( extraParams ) ){ // make sure extra params are in an array if specified
extraParams = [ extraParams ];
}
} else { // otherwise, we've got nothing
extraParams = [];
}
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
...bool = function ( obj ){
return obj != null && typeof obj === typeof true;
}...
if( options.weight != null && is.fn( options.weight ) ){
var weight = options.weight;
} else {
var weight = function(){return 1;};
}
// directed - optional
if( options.directed != null && is.bool( options.directed ) ){
var directed = options.directed;
} else {
var directed = false;
}
var harmonic = options.harmonic;
if( harmonic === undefined ){
...boundingBox = function ( obj ){
return is.plainObject( obj ) &&
is.number( obj.x1 ) && is.number( obj.x2 ) &&
is.number( obj.y1 ) && is.number( obj.y2 )
;
}...
return undefined; // for empty collection case
}
return this; // chaining
},
renderedBoundingBox: function( options ){
var bb = this.boundingBox( options );
var cy = this.cy();
var zoom = cy.zoom();
var pan = cy.pan();
var x1 = bb.x1 * zoom + pan.x;
var x2 = bb.x2 * zoom + pan.x;
var y1 = bb.y1 * zoom + pan.y;
...chromium = function (){
return window && ( typeof chrome !== 'undefined' );
}...
},
khtml: function(){
return navigator && navigator.vendor.match( /kde/i ); // probably a better way to detect this...
},
khtmlEtc: function(){
return is.khtml() || is.webkit() || is.chromium();
},
ms: function(){
return navigator && navigator.userAgent.match( /msie|trident|edge/i ); // probably a better way to detect this...
},
windows: function(){
...collection = function ( obj ){
return instanceStr( obj ) === 'collection' && !obj._private.single;
}...
return undefined;
} else {
return null != obj && obj instanceof HTMLElement;
}
},
elementOrCollection: function( obj ){
return is.element( obj ) || is.collection( obj );
},
element: function( obj ){
return instanceStr( obj ) === 'collection' && obj._private.single;
},
collection: function( obj ){
...core = function ( obj ){
return instanceStr( obj ) === 'core';
}...
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
for( var i = 0; i < evts.length; i++ ){
...defined = function ( obj ){
return obj != null; // not undefined or null
}n/a
domElement = function ( obj ){
if( typeof HTMLElement === 'undefined' ){
return false; // we're not in a browser so it doesn't matter
} else {
return obj instanceof HTMLElement;
}
}n/a
element = function ( obj ){
return instanceStr( obj ) === 'collection' && obj._private.single;
}...
for( var i = 0; i < events.length; i++ ){ // trigger each event in order
var evtObj = events[ i ];
for( var j = 0; j < all.length; j++ ){ // for each
var triggerer = all[ j ];
var _p = triggerer._private = triggerer._private || {};
var listeners = _p.listeners = _p.listeners || [];
var triggererIsElement = is.element( triggerer );
var bubbleUp = triggererIsElement || params.layout;
// create the event for this element from the event object
var evt;
if( eventsIsEvent ){ // then just get the object
evt = evtObj;
...elementOrCollection = function ( obj ){
return is.element( obj ) || is.collection( obj );
}...
q = tAni.queue;
} else {
q = tAni.current;
}
q.push( this );
// add to the animation loop pool
if( is.elementOrCollection( _p.target ) ){
_p.target.cy().addToAnimationPool( _p.target );
}
_p.hooked = true;
}
return this;
...emptyString = function ( obj ){
if( obj === undefined || obj === null ){ // null is empty
return true;
} else if( obj === '' || obj.match( /^\s+$/ ) ){
return true; // empty string is empty
}
return false; // otherwise, we don't know what we've got
}...
// .removeData('foo bar')
if( is.string( names ) ){ // then get the list of keys, and delete them
var keys = names.split( /\s+/ );
var l = keys.length;
for( var i = 0; i < l; i++ ){ // delete each non-empty key
var key = keys[ i ];
if( is.emptyString( key ) ){ continue; }
var valid = !p.immutableKeys[ key ]; // not valid if immutable
if( valid ){
for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){
all[ i_a ]._private[ p.field ][ key ] = undefined;
}
}
...event = function ( obj ){
return instanceStr( obj ) === 'event';
}...
return function triggerImpl( events, extraParams, fnToTrigger ){
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var eventsIsString = is.string( events );
var eventsIsObject = is.plainObject( events );
var eventsIsEvent = is.event( events );
var _p = this._private = this._private || {};
var cy = _p.cy || ( is.core( this ) ? this : null );
var hasCompounds = cy ? cy.hasCompoundNodes() : false;
if( eventsIsString ){ // then make a plain event object for each event name
var evts = events.split( /\s+/ );
events = [];
...fabric = function ( obj ){
return instanceStr( obj ) === 'fabric';
}n/a
fn = function ( obj ){
return obj != null && typeof obj === typeoffn;
}...
_p.playing = false;
_p.hooked = false;
_p.applying = false;
_p.progress = 0;
_p.completes = [];
_p.frames = [];
if( _p.complete && is.fn( _p.complete ) ){
_p.completes.push( _p.complete );
}
// for future timeline/animations impl
this.length = 1;
this[0] = this;
};
...gecko = function (){
return window && ( typeof InstallTrigger !== 'undefined' || ('MozAppearance' in document.documentElement.style) );
}n/a
htmlElement = function ( obj ){
if( 'undefined' === typeofhtmlele ){
return undefined;
} else {
return null != obj && obj instanceof HTMLElement;
}
}n/a
integer = function ( obj ){
return is.number( obj ) && Math.floor( obj ) === obj;
}...
if( isNaN( value ) && type.enums !== undefined ){
value = passedValue;
return checkEnums();
}
// check if value must be an integer
if( type.integer && !is.integer( value ) ){
return null;
}
// check value is within range
if( (type.min !== undefined && value < type.min)
|| (type.max !== undefined && value > type.max)
){
...khtml = function (){
return navigator && navigator.vendor.match( /kde/i ); // probably a better way to detect this...
}...
},
khtml: function(){
return navigator && navigator.vendor.match( /kde/i ); // probably a better way to detect this...
},
khtmlEtc: function(){
return is.khtml() || is.webkit() || is.chromium();
},
ms: function(){
return navigator && navigator.userAgent.match( /msie|trident|edge/i ); // probably a better way to detect this...
},
windows: function(){
...khtmlEtc = function (){
return is.khtml() || is.webkit() || is.chromium();
}n/a
linux = function (){
return navigator && navigator.appVersion.match( /Linux/i );
}n/a
mac = function (){
return navigator && navigator.appVersion.match( /Mac/i );
}n/a
ms = function (){
return navigator && navigator.userAgent.match( /msie|trident|edge/i ); // probably a better way to detect this...
}n/a
nonemptyString = function ( obj ){
if( obj && is.string( obj ) && obj !== '' && !obj.match( /^\s+$/ ) ){
return true;
}
return false;
}n/a
number = function ( obj ){
return obj != null && typeof obj === typeof 1 && !isNaN( obj );
}...
},
number: function( obj ){
return obj != null && typeof obj === typeof 1 && !isNaN( obj );
},
integer: function( obj ){
return is.number( obj ) && Math.floor( obj ) === obj;
},
bool: function( obj ){
return obj != null && typeof obj === typeof true;
},
htmlElement: function( obj ){
...object = function ( obj ){
return obj != null && typeof obj === typeofobj;
}...
return is.plainObject( obj ) &&
is.number( obj.x1 ) && is.number( obj.x2 ) &&
is.number( obj.y1 ) && is.number( obj.y2 )
;
},
promise: function( obj ){
return is.object( obj ) && is.fn( obj.then );
},
touch: function(){
return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch
);
},
gecko: function(){
...plainObject = function ( obj ){
return obj != null && typeof obj === typeofobj && !is.array( obj ) && obj.constructor === Object;
}...
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
}
}
// .data({ 'foo': 'bar' })
} else if( p.allowSetting && is.plainObject( name ) ){ // extend
var obj = name;
var k, v;
var keys = Object.keys( obj );
for( var i = 0; i < keys.length; i++ ){
k = keys[ i ];
v = obj[ k ];
...promise = function ( obj ){
return is.object( obj ) && is.fn( obj.then );
}...
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
return ani.promise();
}) ).then(function(){
cy.off('step.*', onStep);
if( options.zoom != null ){
cy.zoom( options.zoom );
}
...string = function ( obj ){
return obj != null && typeof obj == typeofstr;
}...
var p = params;
var self = this;
var selfIsArrayLike = self.length !== undefined;
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var single = selfIsArrayLike ? self[0] : self;
// .data('foo', ...)
if( is.string( name ) ){ // set or get property
// .data('foo')
if( p.allowGetting && value === undefined ){ // get
var ret;
if( single ){
ret = single._private[ p.field ][ name ];
...style = function ( obj ){
return instanceStr( obj ) === 'style';
}...
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
var isCore = !selfIsArrayLike;
var isEles = !isCore;
if( !cy.styleEnabled() ){ return this; }
var style = cy.style();
properties = util.extend( {}, properties, params );
if( properties.duration === undefined ){
properties.duration = 400;
}
...stylesheet = function ( obj ){
return instanceStr( obj ) === 'stylesheet';
}n/a
thread = function ( obj ){
return instanceStr( obj ) === 'thread';
}n/a
touch = function (){
return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch );
}n/a
unix = function (){
return navigator && navigator.appVersion.match( /X11/i );
}n/a
webkit = function (){
return window && ( typeof webkitURL !== 'undefined' || ('WebkitAppearance' in document.documentElement.style) );
}...
},
khtml: function(){
return navigator && navigator.vendor.match( /kde/i ); // probably a better way to detect this...
},
khtmlEtc: function(){
return is.khtml() || is.webkit() || is.chromium();
},
ms: function(){
return navigator && navigator.userAgent.match( /msie|trident|edge/i ); // probably a better way to detect this...
},
windows: function(){
...windows = function (){
return navigator && navigator.appVersion.match( /Win/i );
}n/a
each = function ( fn, thisArg ){
if( is.fn( fn ) ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var ret = thisArg ? fn.apply( thisArg, [ ele, i, this ] ) : fn( ele, i, this );
if( ret === false ){ break; } // exit each early on return false
}
}
return this;
}n/a
empty = function (){
return this.length === 0;
}...
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
break;
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) === ele.data( 'target' );
break;
case ':simple':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) !== ele.data( 'target' );
break;
...eq = function ( i ){
return this[ i ] || this.spawn();
}n/a
first = function (){
return this[0] || this.spawn();
}n/a
forEach = function ( fn, thisArg ){
if( is.fn( fn ) ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var ret = thisArg ? fn.apply( thisArg, [ ele, i, this ] ) : fn( ele, i, this );
if( ret === false ){ break; } // exit each early on return false
}
}
return this;
}...
proto[ pName ] = pVal; // take impl from base
}
for( var pName in rProto ){
proto[ pName ] = rProto[ pName ]; // take impl from registrant
}
bProto.clientFunctions.forEach( function( name ){
proto[ name ] = proto[ name ] || function(){
util.error( 'Renderer does not implement `renderer.' + name + '()` on its prototype' );
};
} );
ext = Renderer;
...last = function (){
return this[ this.length - 1 ] || this.spawn();
}n/a
nonempty = function (){
return !this.empty();
}...
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
case ':unanimated':
allColonSelectorsMatch = !ele.animated();
break;
case ':parent':
allColonSelectorsMatch = ele.isNode() && ele.children().nonempty();
break;
case ':child':
case ':nonorphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().nonempty();
break;
case ':orphan':
allColonSelectorsMatch = ele.isNode() && ele.parent().empty();
...size = function (){
return this.length;
}...
if( !matchesAny ){
return false;
}
}
// check filter function
if( query.filter != null && ele.collection().filter( query.filter ).size() ===
0 ){
return false;
}
// check parent/child relations
var confirmRelations = function( query, eles ){
if( query != null ){
var matches = false;
...slice = function ( start, end ){
var array = [];
var thisSize = this.length;
if( end == null ){
end = thisSize;
}
if( start == null ){
start = 0;
}
if( start < 0 ){
start = thisSize + start;
}
if( end < 0 ){
end = thisSize + end;
}
for( var i = start; i >= 0 && i < end && i < thisSize; i++ ){
array.push( this[ i ] );
}
return this.spawn( array );
}...
*/
nlargest = function( array, n, cmp ){
var elem, result, _i, _len, _ref;
if( cmp == null ){
cmp = defaultCmp;
}
result = array.slice( 0, n );
if( !result.length ){
return result;
}
heapify( result, cmp );
_ref = array.slice( n );
for( _i = 0, _len = _ref.length; _i < _len; _i++ ){
elem = _ref[ _i ];
...sort = function ( sortFn ){
if( !is.fn( sortFn ) ){
return this;
}
var sorted = this.toArray().sort( sortFn );
return this.spawn( sorted );
}...
}
heapify( result, cmp );
_ref = array.slice( n );
for( _i = 0, _len = _ref.length; _i < _len; _i++ ){
elem = _ref[ _i ];
heappushpop( result, elem, cmp );
}
return result.sort( cmp ).reverse();
};
/*
Find the n smallest elements in a dataset.
*/
...sortByZIndex = function (){
return this.sort( zIndexSort );
}n/a
toArray = function (){
var array = [];
for( var i = 0; i < this.length; i++ ){
array.push( this[ i ] );
}
return array;
}...
},
sort: function( sortFn ){
if( !is.fn( sortFn ) ){
return this;
}
var sorted = this.toArray().sort( sortFn );
return this.spawn( sorted );
},
sortByZIndex: function(){
return this.sort( zIndexSort );
},
...zDepth = function (){
var ele = this[0];
if( !ele ){ return undefined; }
// var cy = ele.cy();
var _p = ele._private;
var group = _p.group;
if( group === 'nodes' ){
var depth = _p.data.parent ? ele.parents().size() : 0;
if( !ele.isParent() ){
return Number.MAX_VALUE; // childless nodes always on top
}
return depth;
} else {
var src = _p.source;
var tgt = _p.target;
var srcDepth = src.zDepth();
var tgtDepth = tgt.zDepth();
return Math.max( srcDepth, tgtDepth, 0 ); // depth of deepest parent
}
}...
return Number.MAX_VALUE; // childless nodes always on top
}
return depth;
} else {
var src = _p.source;
var tgt = _p.target;
var srcDepth = src.zDepth();
var tgtDepth = tgt.zDepth();
return Math.max( srcDepth, tgtDepth, 0 ); // depth of deepest parent
}
}
});
...json = function (){
var json = [];
for( var i = this.defaultLength; i < this.length; i++ ){
var cxt = this[ i ];
var selector = cxt.selector;
var props = cxt.properties;
var css = {};
for( var j = 0; j < props.length; j++ ){
var prop = props[ j ];
css[ prop.name ] = prop.strValue;
}
json.push( {
selector: !selector ? 'core' : selector.toString(),
style: css
} );
}
return json;
}...
return;
}
// make the element array-like, just like a collection
this.length = 1;
this[0] = this;
// NOTE: when something is added here, add also to ele.json()
this._private = {
cy: cy,
single: true, // indicates this is an element
data: params.data || {}, // data object
position: params.position || {}, // (x, y) position pair
autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value
autoHeight: undefined,
...applyFromJson = function ( json ){
var style = this;
for( var i = 0; i < json.length; i++ ){
var context = json[ i ];
var selector = context.selector;
var props = context.style || context.css;
var names = Object.keys( props );
style.selector( selector ); // apply selector
for( var j = 0; j < names.length; j++ ){
var name = names[j];
var value = props[ name ];
style.css( name, value ); // apply property
}
}
return style;
}...
};
// accessible cy.style() function
styfn.fromJson = function( json ){
var style = this;
style.resetToDefault();
style.applyFromJson( json );
return style;
};
// get json from cy.style() api
styfn.json = function(){
var json = [];
...fromJson = function ( json ){
var style = this;
style.resetToDefault();
style.applyFromJson( json );
return style;
}n/a
kargerStein = function ( options ){
var eles = this;
options = options || {};
// Function which colapses 2 (meta) nodes into one
// Updates the remaining edge lists
// Receives as a paramater the edge which causes the collapse
var colapse = function( edgeIndex, nodeMap, remainingEdges ){
var edgeInfo = remainingEdges[ edgeIndex ];
var sourceIn = edgeInfo[1];
var targetIn = edgeInfo[2];
var partition1 = nodeMap[ sourceIn ];
var partition2 = nodeMap[ targetIn ];
// Delete all edges between partition1 and partition2
var newEdges = remainingEdges.filter( function( edge ){
if( nodeMap[ edge[1] ] === partition1 && nodeMap[ edge[2] ] === partition2 ){
return false;
}
if( nodeMap[ edge[1] ] === partition2 && nodeMap[ edge[2] ] === partition1 ){
return false;
}
return true;
} );
// All edges pointing to partition2 should now point to partition1
for( var i = 0; i < newEdges.length; i++ ){
var edge = newEdges[ i ];
if( edge[1] === partition2 ){ // Check source
newEdges[ i ] = edge.slice( 0 );
newEdges[ i ][1] = partition1;
} else if( edge[2] === partition2 ){ // Check target
newEdges[ i ] = edge.slice( 0 );
newEdges[ i ][2] = partition1;
}
}
// Move all nodes from partition2 to partition1
for( var i = 0; i < nodeMap.length; i++ ){
if( nodeMap[ i ] === partition2 ){
nodeMap[ i ] = partition1;
}
}
return newEdges;
};
// Contracts a graph until we reach a certain number of meta nodes
var contractUntil = function( metaNodeMap,
remainingEdges,
size,
sizeLimit ){
// Stop condition
if( size <= sizeLimit ){
return remainingEdges;
}
// Choose an edge randomly
var edgeIndex = Math.floor( (Math.random() * remainingEdges.length) );
// Colapse graph based on edge
var newEdges = colapse( edgeIndex, metaNodeMap, remainingEdges );
return contractUntil( metaNodeMap,
newEdges,
size - 1,
sizeLimit );
};
var cy = this._private.cy;
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
var numEdges = edges.length;
var numIter = Math.ceil( Math.pow( Math.log( numNodes ) / Math.LN2, 2 ) );
var stopSize = Math.floor( numNodes / Math.sqrt( 2 ) );
if( numNodes < 2 ){
util.error( 'At least 2 nodes are required for Karger-Stein algorithm' );
return undefined;
}
// Create numerical identifiers for each node
// mapping: node id -> position in nodes array
// for reverse mapping, simply use nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Now store edge destination as indexes
// Format for each edge (edge index, source node index, target node index)
var edgeIndexes = [];
for( var i = 0; i < numEdges; i++ ){
var e = edges[ i ];
edgeIndexes.push( [ i, id2position[ e.source().id() ], id2position[ e.target().id() ] ] );
}
// We will store the best cut found here
var minCutSize = Infinity;
var minCut;
// Initial meta node partition
var originalMetaNode = [];
for( var i = 0; i < numNodes; i++ ){
originalMetaNode.push( i );
}
// Main loop
for( var iter = 0; iter <= numIter; iter++ ){
// Create new meta node partition
var metaNodeMap = originalMetaNode.slice( 0 );
// Contract until stop point (stopSize nodes)
var edgesState = contractUntil( metaNodeMap, edgeIndexes, numNodes, stopSize );
// Create a copy of the colapsed nodes state
var metaNodeMap2 = metaNodeMap.slice( 0 );
// Run 2 iterations starting in the stop state
var res1 = contractUntil( metaNodeMap, edgesState, stopSize, 2 );
var res2 = contractUntil( metaNodeMap2, edgesState, stopSize, 2 );
// Is any of the 2 results the best cut so far?
if( res1.length <= res2.length && res1.length < minCutSize ){
minCutSiz ...n/a
kruskal = function ( weightFn ){
var cy = this.cy();
weightFn = is.fn( weightFn ) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)
function findSet( ele ){
for( var i = 0; i < forest.length; i++ ){
var eles = forest[ i ];
if( eles.anySame( ele ) ){
return {
eles: eles,
index: i
};
}
}
}
var A = cy.collection( cy, [] );
var forest = [];
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
forest.push( nodes[ i ].collection() );
}
var edges = this.edges();
var S = edges.toArray().sort( function( a, b ){
var weightA = weightFn( a );
var weightB = weightFn( b );
return weightA - weightB;
} );
for( var i = 0; i < S.length; i++ ){
var edge = S[ i ];
var u = edge.source()[0];
var v = edge.target()[0];
var setU = findSet( u );
var setV = findSet( v );
if( setU.index !== setV.index ){
A = A.add( edge );
// combine forests for u and v
forest[ setU.index ] = setU.eles.add( setV.eles );
forest.splice( setV.index, 1 );
}
}
return nodes.add( A );
}n/a
layout = function ( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}n/a
createLayout = function ( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}n/a
layoutPositions = function ( layout, options, fn ){
var nodes = this.nodes();
var cy = this.cy();
layout.trigger( { type: 'layoutstart', layout: layout } );
layout.animations = [];
if( options.animate ){
for( var i = 0; i < nodes.length; i++ ){
var node = nodes[ i ];
var newPos = fn( node, i );
var pos = node.position();
if( !is.number( pos.x ) || !is.number( pos.y ) ){
node.silentPosition( { x: 0, y: 0 } );
}
var ani = node.animation( {
position: newPos,
duration: options.animationDuration,
easing: options.animationEasing
} );
layout.animations.push( ani );
ani.play();
}
var onStep;
cy.on( 'step.*', ( onStep = function(){
if( options.fit ){
cy.fit( options.eles, options.padding );
}
}) );
layout.one('layoutstop', function(){
cy.off('step.*', onStep);
});
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
Promise.all( layout.animations.map(function( ani ){
return ani.promise();
}) ).then(function(){
cy.off('step.*', onStep);
if( options.zoom != null ){
cy.zoom( options.zoom );
}
if( options.pan ){
cy.pan( options.pan );
}
if( options.fit ){
cy.fit( options.eles, options.padding );
}
layout.one( 'layoutstop', options.stop );
layout.trigger( { type: 'layoutstop', layout: layout } );
});
} else {
nodes.positions( fn );
if( options.fit ){
cy.fit( options.eles, options.padding );
}
if( options.zoom != null ){
cy.zoom( options.zoom );
}
if( options.pan ){
cy.pan( options.pan );
}
layout.one( 'layoutready', options.ready );
layout.trigger( { type: 'layoutready', layout: layout } );
layout.one( 'layoutstop', options.stop );
layout.trigger( { type: 'layoutstop', layout: layout } );
}
return this; // chaining
}...
for( var j = 0; j < depth.length; j++ ){
var node = depth[ j ];
pos[ node.id() ] = getPosition( node, i === depths.length - 1 );
}
}
nodes.layoutPositions( this, options, function( node ){
return pos[ node.id() ];
} );
return this; // chaining
};
module.exports = BreadthFirstLayout;
...makeLayout = function ( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}...
return this; // chaining
},
layout: function( options ){
var cy = this.cy();
return cy.makeLayout( util.extend( {}, options, {
eles: this
} ) );
}
});
// aliases:
...deleteMap = function ( options ){
var obj = options.map;
var keys = options.keys;
var l = keys.length;
var keepChildren = options.keepChildren;
for( var i = 0; i < l; i++ ){
var key = keys[ i ];
if( is.plainObject( key ) ){
this.error( 'Tried to delete map with object key' );
}
var lastKey = i === options.keys.length - 1;
if( lastKey ){
if( keepChildren ){ // then only delete child fields not in keepChildren
var children = Object.keys( obj );
for( var j = 0; j < children.length; j++ ){
var child = children[j];
if( !keepChildren[ child ] ){
obj[ child ] = undefined;
}
}
} else {
obj[ key ] = undefined;
}
} else {
obj = obj[ key ];
}
}
}n/a
getMap = function ( options ){
var obj = options.map;
var keys = options.keys;
var l = keys.length;
for( var i = 0; i < l; i++ ){
var key = keys[ i ];
if( is.plainObject( key ) ){
this.error( 'Tried to get map with object key' );
}
obj = obj[ key ];
if( obj == null ){
return obj;
}
}
return obj;
}...
map: extensions,
keys: [ type, name ],
value: ext
} );
}
function getExtension( type, name ){
return util.getMap( {
map: extensions,
keys: [ type, name ]
} );
}
function setModule( type, name, moduleType, moduleName, registrant ){
return util.setMap( {
...mapEmpty = function ( map ){
var empty = true;
if( map != null ){
return Object.keys( map ).length === 0;
}
return empty;
}n/a
pushMap = function ( options ){
var array = this.getMap( options );
if( array == null ){ // if empty, put initial array
this.setMap( this.extend( {}, options, {
value: [ options.value ]
} ) );
} else {
array.push( options.value );
}
}n/a
setMap = function ( options ){
var obj = options.map;
var key;
var keys = options.keys;
var l = keys.length;
for( var i = 0; i < l; i++ ){
var key = keys[ i ];
if( is.plainObject( key ) ){
this.error( 'Tried to set map with object key' );
}
if( i < keys.length - 1 ){
// extend the map if necessary
if( obj[ key ] == null ){
obj[ key ] = {};
}
obj = obj[ key ];
} else {
// set the value
obj[ key ] = options.value;
}
}
}...
};
} );
ext = Renderer;
}
return util.setMap( {
map: extensions,
keys: [ type, name ],
value: ext
} );
}
function getExtension( type, name ){
...arePositionsSame = function ( p1, p2 ){
return p1.x === p2.x && p1.y === p2.y;
}n/a
array2point = function ( arr ){
return {
x: arr[0],
y: arr[1]
};
}n/a
bound = function ( min, val, max ){
return Math.max( min, Math.min( max, val ) );
}n/a
boundingBoxInBoundingBox = function ( bb1, bb2 ){
return (
math.inBoundingBox( bb1, bb2.x1, bb2.y1 )
&& math.inBoundingBox( bb1, bb2.x2, bb2.y2 )
);
}n/a
boundingBoxesIntersect = function ( bb1, bb2 ){
// case: one bb to right of other
if( bb1.x1 > bb2.x2 ){ return false; }
if( bb2.x1 > bb1.x2 ){ return false; }
// case: one bb to left of other
if( bb1.x2 < bb2.x1 ){ return false; }
if( bb2.x2 < bb1.x1 ){ return false; }
// case: one bb above other
if( bb1.y2 < bb2.y1 ){ return false; }
if( bb2.y2 < bb1.y1 ){ return false; }
// case: one bb below other
if( bb1.y1 > bb2.y2 ){ return false; }
if( bb2.y1 > bb1.y2 ){ return false; }
// otherwise, must have some overlap
return true;
}n/a
copyPosition = function ( p ){
return { x: p.x, y: p.y };
}n/a
deg2rad = function ( deg ){
return Math.PI * deg / 180;
}...
// normalise value in ms
if( units === 'ms' || units === 's' ){
ret.pfValue = units === 'ms' ? value : 1000 * value;
}
// normalise value in rad
if( units === 'deg' || units === 'rad' ){
ret.pfValue = units === 'rad' ? value : math.deg2rad( value );
}
return ret;
} else if( type.propList ){
var props = [];
...dist = function ( p1, p2 ){
return Math.sqrt( math.sqdist( p1, p2 ) );
}...
math.lineAt = function( p0, p1, t, d ){
var vec = {
x: p1.x - p0.x,
y: p1.y - p0.y
};
var vecDist = math.dist( p0, p1 );
var normVec = {
x: vec.x / vecDist,
y: vec.y / vecDist
};
t = t == null ? 0 : t;
...expandBoundingBox = function ( bb, padding ){
bb.x1 -= padding;
bb.x2 += padding;
bb.y1 -= padding;
bb.y2 += padding;
bb.w = bb.x2 - bb.x1;
bb.h = bb.y2 - bb.y1;
return bb;
}...
bounds.x2 = noninf( bounds.x2 );
bounds.y2 = noninf( bounds.y2 );
bounds.w = noninf( bounds.x2 - bounds.x1 );
bounds.h = noninf( bounds.y2 - bounds.y1 );
// expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides
if( bounds.w > 0 && bounds.h > 0 && displayed ){
math.expandBoundingBox( bounds, 1 );
}
return bounds;
};
var tf = function( val ){
if( val ){
...expandPolygon = function ( points, pad ){
var expandedLineSet = new Array( points.length * 2 );
var currentPointX, currentPointY, nextPointX, nextPointY;
for( var i = 0; i < points.length / 2; i++ ){
currentPointX = points[ i * 2];
currentPointY = points[ i * 2 + 1];
if( i < points.length / 2 - 1 ){
nextPointX = points[ (i + 1) * 2];
nextPointY = points[ (i + 1) * 2 + 1];
} else {
nextPointX = points[0];
nextPointY = points[1];
}
// Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY]
// Assume CCW polygon winding
var offsetX = (nextPointY - currentPointY);
var offsetY = -(nextPointX - currentPointX);
// Normalize
var offsetLength = Math.sqrt( offsetX * offsetX + offsetY * offsetY );
var normalizedOffsetX = offsetX / offsetLength;
var normalizedOffsetY = offsetY / offsetLength;
expandedLineSet[ i * 4] = currentPointX + normalizedOffsetX * pad;
expandedLineSet[ i * 4 + 1] = currentPointY + normalizedOffsetY * pad;
expandedLineSet[ i * 4 + 2] = nextPointX + normalizedOffsetX * pad;
expandedLineSet[ i * 4 + 3] = nextPointY + normalizedOffsetY * pad;
}
return expandedLineSet;
}...
transformedPoints[ i * 2] += centerX;
transformedPoints[ i * 2 + 1] += centerY;
}
var points;
if( padding > 0 ){
var expandedLineSet = this.expandPolygon(
transformedPoints,
-padding );
points = this.joinLines( expandedLineSet );
} else {
points = transformedPoints;
}
...findCircleNearPoint = function ( centerX, centerY, radius, farX, farY ){
var displacementX = farX - centerX;
var displacementY = farY - centerY;
var distance = Math.sqrt( displacementX * displacementX
+ displacementY * displacementY );
var unitDisplacementX = displacementX / distance;
var unitDisplacementY = displacementY / distance;
return [ centerX + unitDisplacementX * radius,
centerY + unitDisplacementY * radius ];
}n/a
findMaxSqDistanceToOrigin = function ( points ){
var maxSqDistance = 0.000001;
var sqDistance;
for( var i = 0; i < points.length / 2; i++ ){
sqDistance = points[ i * 2] * points[ i * 2]
+ points[ i * 2 + 1] * points[ i * 2 + 1];
if( sqDistance > maxSqDistance ){
maxSqDistance = sqDistance;
}
}
return maxSqDistance;
}n/a
finiteLinesIntersect = function ( x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines ){
var dx13 = x1 - x3;
var dx21 = x2 - x1;
var dx43 = x4 - x3;
var dy13 = y1 - y3;
var dy21 = y2 - y1;
var dy43 = y4 - y3;
var ua_t = dx43 * dy13 - dy43 * dx13;
var ub_t = dx21 * dy13 - dy21 * dx13;
var u_b = dy43 * dx21 - dx43 * dy21;
if( u_b !== 0 ){
var ua = ua_t / u_b;
var ub = ub_t / u_b;
var flptThreshold = 0.001;
var min = 0 - flptThreshold;
var max = 1 + flptThreshold;
if( min <= ua && ua <= max && min <= ub && ub <= max ){
return [ x1 + ua * dx21, y1 + ua * dy21 ];
} else {
if( !infiniteLines ){
return [];
} else {
return [ x1 + ua * dx21, y1 + ua * dy21 ];
}
}
} else {
if( ua_t === 0 || ub_t === 0 ){
// Parallel, coincident lines. Check if overlap
// Check endpoint of second line
if( this.midOfThree( x1, x2, x4 ) === x4 ){
return [ x4, y4 ];
}
// Check start point of second line
if( this.midOfThree( x1, x2, x3 ) === x3 ){
return [ x3, y3 ];
}
// Endpoint of first line
if( this.midOfThree( x3, x4, x2 ) === x2 ){
return [ x2, y2 ];
}
return [];
} else {
// Parallel, non-coincident
return [];
}
}
}...
// Top segment, left to right
{
var topStartX = nodeX - halfWidth + cornerRadius - padding;
var topStartY = nodeY - halfHeight - padding;
var topEndX = nodeX + halfWidth - cornerRadius + padding;
var topEndY = topStartY;
straightLineIntersections = this.finiteLinesIntersect(
x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false );
if( straightLineIntersections.length > 0 ){
return straightLineIntersections;
}
}
...fitPolygonToSquare = function ( points ){
var x, y;
var sides = points.length / 2;
var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
for( var i = 0; i < sides; i++ ){
x = points[2 * i ];
y = points[2 * i + 1];
minX = Math.min( minX, x );
maxX = Math.max( maxX, x );
minY = Math.min( minY, y );
maxY = Math.max( maxY, y );
}
// stretch factors
var sx = 2 / (maxX - minX);
var sy = 2 / (maxY - minY);
for( var i = 0; i < sides; i++ ){
x = points[2 * i ] = points[2 * i ] * sx;
y = points[2 * i + 1] = points[2 * i + 1] * sy;
minX = Math.min( minX, x );
maxX = Math.max( maxX, x );
minY = Math.min( minY, y );
maxY = Math.max( maxY, y );
}
if( minY < -1 ){
for( var i = 0; i < sides; i++ ){
y = points[2 * i + 1] = points[2 * i + 1] + (-1 - minY);
}
}
return points;
}...
}
return [ offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1] ];
};
math.generateUnitNgonPointsFitToSquare = function( sides, rotationRadians ){
var points = math.generateUnitNgonPoints( sides, rotationRadians );
points = math.fitPolygonToSquare( points );
return points;
};
math.fitPolygonToSquare = function( points ){
var x, y;
var sides = points.length / 2;
...generateUnitNgonPoints = function ( sides, rotationRadians ){
var increment = 1.0 / sides * 2 * Math.PI;
var startAngle = sides % 2 === 0 ?
Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0;
// console.log(nodeShapes['square']);
startAngle += rotationRadians;
var points = new Array( sides * 2 );
var currentAngle, x, y;
for( var i = 0; i < sides; i++ ){
currentAngle = i * increment + startAngle;
x = points[2 * i ] = Math.cos( currentAngle );// * (1 + i/2);
y = points[2 * i + 1] = Math.sin( -currentAngle );// * (1 + i/2);
}
return points;
}...
lenRatio = 0.00001;
}
return [ offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1] ];
};
math.generateUnitNgonPointsFitToSquare = function( sides, rotationRadians ){
var points = math.generateUnitNgonPoints( sides, rotationRadians );
points = math.fitPolygonToSquare( points );
return points;
};
math.fitPolygonToSquare = function( points ){
var x, y;
...generateUnitNgonPointsFitToSquare = function ( sides, rotationRadians ){
var points = math.generateUnitNgonPoints( sides, rotationRadians );
points = math.fitPolygonToSquare( points );
return points;
}n/a
getRoundRectangleRadius = function ( width, height ){
// Set the default radius, unless half of width or height is smaller than default
return Math.min( width / 4, height / 4, 8 );
}...
&& math.inBoundingBox( bb1, bb2.x2, bb2.y2 )
);
};
math.roundRectangleIntersectLine = function(
x, y, nodeX, nodeY, width, height, padding ){
var cornerRadius = this.getRoundRectangleRadius( width, height );
var halfWidth = width / 2;
var halfHeight = height / 2;
// Check intersections with straight line segments
var straightLineIntersections;
...inBezierVicinity = function ( x, y, x1, y1, x2, y2, x3, y3, tolerance ){
var bb = {
x1: Math.min( x1, x3, x2 ) - tolerance,
x2: Math.max( x1, x3, x2 ) + tolerance,
y1: Math.min( y1, y3, y2 ) - tolerance,
y2: Math.max( y1, y3, y2 ) + tolerance
};
// if outside the rough bounding box for the bezier, then it can't be a hit
if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){
// console.log('bezier out of rough bb')
return false;
} else {
// console.log('do more expensive check');
return true;
}
}n/a
inBoundingBox = function ( bb, x, y ){
return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2;
}...
};
math.inBoundingBox = function( bb, x, y ){
return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2;
};
math.pointInBoundingBox = function( bb, pt ){
return this.inBoundingBox( bb, pt.x, pt.y );
};
math.boundingBoxInBoundingBox = function( bb1, bb2 ){
return (
math.inBoundingBox( bb1, bb2.x1, bb2.y1 )
&& math.inBoundingBox( bb1, bb2.x2, bb2.y2 )
);
...inLineVicinity = function ( x, y, lx1, ly1, lx2, ly2, tolerance ){
var t = tolerance;
var x1 = Math.min( lx1, lx2 );
var x2 = Math.max( lx1, lx2 );
var y1 = Math.min( ly1, ly2 );
var y2 = Math.max( ly1, ly2 );
return x1 - t <= x && x <= x2 + t
&& y1 - t <= y && y <= y2 + t;
}n/a
intersectLineCircle = function ( x1, y1, x2, y2, centerX, centerY, radius ){
// Calculate d, direction vector of line
var d = [ x2 - x1, y2 - y1 ]; // Direction vector of line
var c = [ centerX, centerY ]; // Center of circle
var f = [ x1 - centerX, y1 - centerY ];
var a = d[0] * d[0] + d[1] * d[1];
var b = 2 * (f[0] * d[0] + f[1] * d[1]);
var c = (f[0] * f[0] + f[1] * f[1]) - radius * radius ;
var discriminant = b * b - 4 * a * c;
if( discriminant < 0 ){
return [];
}
var t1 = (-b + Math.sqrt( discriminant )) / (2 * a);
var t2 = (-b - Math.sqrt( discriminant )) / (2 * a);
var tMin = Math.min( t1, t2 );
var tMax = Math.max( t1, t2 );
var inRangeParams = [];
if( tMin >= 0 && tMin <= 1 ){
inRangeParams.push( tMin );
}
if( tMax >= 0 && tMax <= 1 ){
inRangeParams.push( tMax );
}
if( inRangeParams.length === 0 ){
return [];
}
var nearIntersectionX = inRangeParams[0] * d[0] + x1;
var nearIntersectionY = inRangeParams[0] * d[1] + y1;
if( inRangeParams.length > 1 ){
if( inRangeParams[0] == inRangeParams[1] ){
return [ nearIntersectionX, nearIntersectionY ];
} else {
var farIntersectionX = inRangeParams[1] * d[0] + x1;
var farIntersectionY = inRangeParams[1] * d[1] + y1;
return [ nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY ];
}
} else {
return [ nearIntersectionX, nearIntersectionY ];
}
}...
// Check intersections with arc segments
var arcIntersections;
// Top Left
{
var topLeftCenterX = nodeX - halfWidth + cornerRadius;
var topLeftCenterY = nodeY - halfHeight + cornerRadius;
arcIntersections = this.intersectLineCircle(
x, y, nodeX, nodeY,
topLeftCenterX, topLeftCenterY, cornerRadius + padding );
// Ensure the intersection is on the desired quarter of the circle
if( arcIntersections.length > 0
&& arcIntersections[0] <= topLeftCenterX
&& arcIntersections[1] <= topLeftCenterY ){
...intersectLineEllipse = function ( x, y, centerX, centerY, ellipseWradius, ellipseHradius ){
var dispX = centerX - x;
var dispY = centerY - y;
dispX /= ellipseWradius;
dispY /= ellipseHradius;
var len = Math.sqrt( dispX * dispX + dispY * dispY );
var newLength = len - 1;
if( newLength < 0 ){
return [];
}
var lenProportion = newLength / len;
return [ (centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y ];
}n/a
joinLines = function ( lineSet ){
var vertices = new Array( lineSet.length / 2 );
var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY;
var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY;
for( var i = 0; i < lineSet.length / 4; i++ ){
currentLineStartX = lineSet[ i * 4];
currentLineStartY = lineSet[ i * 4 + 1];
currentLineEndX = lineSet[ i * 4 + 2];
currentLineEndY = lineSet[ i * 4 + 3];
if( i < lineSet.length / 4 - 1 ){
nextLineStartX = lineSet[ (i + 1) * 4];
nextLineStartY = lineSet[ (i + 1) * 4 + 1];
nextLineEndX = lineSet[ (i + 1) * 4 + 2];
nextLineEndY = lineSet[ (i + 1) * 4 + 3];
} else {
nextLineStartX = lineSet[0];
nextLineStartY = lineSet[1];
nextLineEndX = lineSet[2];
nextLineEndY = lineSet[3];
}
var intersection = this.finiteLinesIntersect(
currentLineStartX, currentLineStartY,
currentLineEndX, currentLineEndY,
nextLineStartX, nextLineStartY,
nextLineEndX, nextLineEndY,
true );
vertices[ i * 2] = intersection[0];
vertices[ i * 2 + 1] = intersection[1];
}
return vertices;
}...
var points;
if( padding > 0 ){
var expandedLineSet = this.expandPolygon(
transformedPoints,
-padding );
points = this.joinLines( expandedLineSet );
} else {
points = transformedPoints;
}
return math.pointInsidePolygonPoints( x, y, points );
};
...lineAt = function ( p0, p1, t, d ){
var vec = {
x: p1.x - p0.x,
y: p1.y - p0.y
};
var vecDist = math.dist( p0, p1 );
var normVec = {
x: vec.x / vecDist,
y: vec.y / vecDist
};
t = t == null ? 0 : t;
var d = d != null ? d : t * vecDist;
return {
x: p0.x + normVec.x * d,
y: p0.y + normVec.y * d
};
}...
return {
x: p0.x + normVec.x * d,
y: p0.y + normVec.y * d
};
};
math.lineAtDist = function( p0, p1, d ){
return math.lineAt( p0, p1, undefined, d );
};
// get angle at A via cosine law
math.triangleAngle = function( A, B, C ){
var a = math.dist( B, C );
var b = math.dist( A, C );
var c = math.dist( A, B );
...lineAtDist = function ( p0, p1, d ){
return math.lineAt( p0, p1, undefined, d );
}n/a
function log2() { [native code] }n/a
makeBoundingBox = function ( bb ){
if( bb == null ){
return {
x1: Infinity,
y1: Infinity,
x2: -Infinity,
y2: -Infinity,
w: 0,
h: 0
};
} else if( bb.x1 != null && bb.y1 != null ){
if( bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1 ){
return {
x1: bb.x1,
y1: bb.y1,
x2: bb.x2,
y2: bb.y2,
w: bb.x2 - bb.x1,
h: bb.y2 - bb.y1
};
} else if( bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0 ){
return {
x1: bb.x1,
y1: bb.y1,
x2: bb.x1 + bb.w,
y2: bb.y1 + bb.h,
w: bb.w,
h: bb.h
};
}
}
}...
var options = params;
var cy = params.cy;
var eles = options.eles;
var nodes = eles.nodes().not( ':parent' );
var graph = eles;
var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} );
var roots;
if( is.elementOrCollection( options.roots ) ){
roots = options.roots;
} else if( is.array( options.roots ) ){
...midOfThree = function ( a, b, c ){
if( (b <= a && a <= c) || (c <= a && a <= b) ){
return a;
} else if( (a <= b && b <= c) || (c <= b && b <= a) ){
return b;
} else {
return c;
}
}...
}
} else {
if( ua_t === 0 || ub_t === 0 ){
// Parallel, coincident lines. Check if overlap
// Check endpoint of second line
if( this.midOfThree( x1, x2, x4 ) === x4 ){
return [ x4, y4 ];
}
// Check start point of second line
if( this.midOfThree( x1, x2, x3 ) === x3 ){
return [ x3, y3 ];
}
...pointInBoundingBox = function ( bb, pt ){
return this.inBoundingBox( bb, pt.x, pt.y );
}n/a
pointInsidePolygon = function ( x, y, basePoints, centerX, centerY, width, height, direction, padding ){
//var direction = arguments[6];
var transformedPoints = new Array( basePoints.length );
// Gives negative angle
var angle;
if( direction[0] != null ){
angle = Math.atan( direction[1] / direction[0] );
if( direction[0] < 0 ){
angle = angle + Math.PI / 2;
} else {
angle = -angle - Math.PI / 2;
}
} else {
angle = direction;
}
var cos = Math.cos( -angle );
var sin = Math.sin( -angle );
// console.log("base: " + basePoints);
for( var i = 0; i < transformedPoints.length / 2; i++ ){
transformedPoints[ i * 2] =
width / 2 * (basePoints[ i * 2] * cos
- basePoints[ i * 2 + 1] * sin);
transformedPoints[ i * 2 + 1] =
height / 2 * (basePoints[ i * 2 + 1] * cos
+ basePoints[ i * 2] * sin);
transformedPoints[ i * 2] += centerX;
transformedPoints[ i * 2 + 1] += centerY;
}
var points;
if( padding > 0 ){
var expandedLineSet = this.expandPolygon(
transformedPoints,
-padding );
points = this.joinLines( expandedLineSet );
} else {
points = transformedPoints;
}
return math.pointInsidePolygonPoints( x, y, points );
}n/a
pointInsidePolygonPoints = function ( x, y, points ){
var x1, y1, x2, y2;
var y3;
// Intersect with vertical line through (x, y)
var up = 0;
var down = 0;
for( var i = 0; i < points.length / 2; i++ ){
x1 = points[ i * 2];
y1 = points[ i * 2 + 1];
if( i + 1 < points.length / 2 ){
x2 = points[ (i + 1) * 2];
y2 = points[ (i + 1) * 2 + 1];
} else {
x2 = points[ (i + 1 - points.length / 2) * 2];
y2 = points[ (i + 1 - points.length / 2) * 2 + 1];
}
if( x1 == x && x2 == x ){
// then ignore
} else if( (x1 >= x && x >= x2)
|| (x1 <= x && x <= x2) ){
y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1;
if( y3 > y ){
up++;
}
if( y3 < y ){
down++;
}
} else {
continue;
}
}
if( up % 2 === 0 ){
return false;
} else {
return true;
}
}...
-padding );
points = this.joinLines( expandedLineSet );
} else {
points = transformedPoints;
}
return math.pointInsidePolygonPoints( x, y, points );
};
math.joinLines = function( lineSet ){
var vertices = new Array( lineSet.length / 2 );
var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY;
...polygonIntersectLine = function ( x, y, basePoints, centerX, centerY, width, height, padding ){
var intersections = [];
var intersection;
var transformedPoints = new Array( basePoints.length );
for( var i = 0; i < transformedPoints.length / 2; i++ ){
transformedPoints[ i * 2] = basePoints[ i * 2] * width + centerX;
transformedPoints[ i * 2 + 1] = basePoints[ i * 2 + 1] * height + centerY;
}
var points;
if( padding > 0 ){
var expandedLineSet = math.expandPolygon(
transformedPoints,
-padding );
points = math.joinLines( expandedLineSet );
} else {
points = transformedPoints;
}
// var points = transformedPoints;
var currentX, currentY, nextX, nextY;
for( var i = 0; i < points.length / 2; i++ ){
currentX = points[ i * 2];
currentY = points[ i * 2 + 1];
if( i < points.length / 2 - 1 ){
nextX = points[ (i + 1) * 2];
nextY = points[ (i + 1) * 2 + 1];
} else {
nextX = points[0];
nextY = points[1];
}
intersection = this.finiteLinesIntersect(
x, y, centerX, centerY,
currentX, currentY,
nextX, nextY );
if( intersection.length !== 0 ){
intersections.push( intersection[0], intersection[1] );
}
}
return intersections;
}n/a
qbezierAt = function ( p0, p1, p2, t ){
return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;
}...
// from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves
math.qbezierAt = function( p0, p1, p2, t ){
return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;
};
math.qbezierPtAt = function( p0, p1, p2, t ){
return {
x: math.qbezierAt( p0.x, p1.x, p2.x, t ),
y: math.qbezierAt( p0.y, p1.y, p2.y, t )
};
};
math.lineAt = function( p0, p1, t, d ){
var vec = {
x: p1.x - p0.x,
...qbezierPtAt = function ( p0, p1, p2, t ){
return {
x: math.qbezierAt( p0.x, p1.x, p2.x, t ),
y: math.qbezierAt( p0.y, p1.y, p2.y, t )
};
}n/a
roundRectangleIntersectLine = function ( x, y, nodeX, nodeY, width, height, padding ){
var cornerRadius = this.getRoundRectangleRadius( width, height );
var halfWidth = width / 2;
var halfHeight = height / 2;
// Check intersections with straight line segments
var straightLineIntersections;
// Top segment, left to right
{
var topStartX = nodeX - halfWidth + cornerRadius - padding;
var topStartY = nodeY - halfHeight - padding;
var topEndX = nodeX + halfWidth - cornerRadius + padding;
var topEndY = topStartY;
straightLineIntersections = this.finiteLinesIntersect(
x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false );
if( straightLineIntersections.length > 0 ){
return straightLineIntersections;
}
}
// Right segment, top to bottom
{
var rightStartX = nodeX + halfWidth + padding;
var rightStartY = nodeY - halfHeight + cornerRadius - padding;
var rightEndX = rightStartX;
var rightEndY = nodeY + halfHeight - cornerRadius + padding;
straightLineIntersections = this.finiteLinesIntersect(
x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false );
if( straightLineIntersections.length > 0 ){
return straightLineIntersections;
}
}
// Bottom segment, left to right
{
var bottomStartX = nodeX - halfWidth + cornerRadius - padding;
var bottomStartY = nodeY + halfHeight + padding;
var bottomEndX = nodeX + halfWidth - cornerRadius + padding;
var bottomEndY = bottomStartY;
straightLineIntersections = this.finiteLinesIntersect(
x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false );
if( straightLineIntersections.length > 0 ){
return straightLineIntersections;
}
}
// Left segment, top to bottom
{
var leftStartX = nodeX - halfWidth - padding;
var leftStartY = nodeY - halfHeight + cornerRadius - padding;
var leftEndX = leftStartX;
var leftEndY = nodeY + halfHeight - cornerRadius + padding;
straightLineIntersections = this.finiteLinesIntersect(
x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false );
if( straightLineIntersections.length > 0 ){
return straightLineIntersections;
}
}
// Check intersections with arc segments
var arcIntersections;
// Top Left
{
var topLeftCenterX = nodeX - halfWidth + cornerRadius;
var topLeftCenterY = nodeY - halfHeight + cornerRadius;
arcIntersections = this.intersectLineCircle(
x, y, nodeX, nodeY,
topLeftCenterX, topLeftCenterY, cornerRadius + padding );
// Ensure the intersection is on the desired quarter of the circle
if( arcIntersections.length > 0
&& arcIntersections[0] <= topLeftCenterX
&& arcIntersections[1] <= topLeftCenterY ){
return [ arcIntersections[0], arcIntersections[1] ];
}
}
// Top Right
{
var topRightCenterX = nodeX + halfWidth - cornerRadius;
var topRightCenterY = nodeY - halfHeight + cornerRadius;
arcIntersections = this.intersectLineCircle(
x, y, nodeX, nodeY,
topRightCenterX, topRightCenterY, cornerRadius + padding );
// Ensure the intersection is on the desired quarter of the circle
if( arcIntersections.length > 0
&& arcIntersections[0] >= topRightCenterX
&& arcIntersections[1] <= topRightCenterY ){
return [ arcIntersections[0], arcIntersections[1] ];
}
}
// Bottom Right
{
var bottomRightCenterX = nodeX + halfWidth - cornerRadius;
var bottomRightCenterY = nodeY + halfHeight - cornerRadius;
arcIntersections = this.intersectLineCircle(
x, y, nodeX, nodeY,
bottomRightCenterX, bottomRightCenterY, cornerRadius + padding );
// Ensure the intersection is on the desired quarter of the circle
if( arcIntersections.length > 0
&& arcIntersections[0] >= bottomRightCenterX
&& arcIntersections[1] >= bottomRightCenterY ){
return [ arcIntersections[0], arcIntersections[1] ];
}
}
// Bottom Left
{
var bottomLeftCenterX = nodeX - halfWidth + cornerRadius;
var bottom ...n/a
shortenIntersection = function ( intersection, offset, amount ){
var disp = [ intersection[0] - offset[0], intersection[1] - offset[1] ];
var length = Math.sqrt( disp[0] * disp[0] + disp[1] * disp[1] );
var lenRatio = (length - amount) / length;
if( lenRatio < 0 ){
lenRatio = 0.00001;
}
return [ offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1] ];
}n/a
signum = function ( x ){
if( x > 0 ){
return 1;
} else if( x < 0 ){
return -1;
} else {
return 0;
}
}n/a
solveCubic = function ( a, b, c, d, result ){
// Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where
// r is the real component, i is the imaginary component
// An implementation of the Cardano method from the year 1545
// http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots
b /= a;
c /= a;
d /= a;
var discriminant, q, r, dum1, s, t, term1, r13;
q = (3.0 * c - (b * b)) / 9.0;
r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b));
r /= 54.0;
discriminant = q * q * q + r * r;
result[1] = 0;
term1 = (b / 3.0);
if( discriminant > 0 ){
s = r + Math.sqrt( discriminant );
s = ((s < 0) ? -Math.pow( -s, (1.0 / 3.0) ) : Math.pow( s, (1.0 / 3.0) ));
t = r - Math.sqrt( discriminant );
t = ((t < 0) ? -Math.pow( -t, (1.0 / 3.0) ) : Math.pow( t, (1.0 / 3.0) ));
result[0] = -term1 + s + t;
term1 += (s + t) / 2.0;
result[4] = result[2] = -term1;
term1 = Math.sqrt( 3.0 ) * (-t + s) / 2;
result[3] = term1;
result[5] = -term1;
return;
}
result[5] = result[3] = 0;
if( discriminant === 0 ){
r13 = ((r < 0) ? -Math.pow( -r, (1.0 / 3.0) ) : Math.pow( r, (1.0 / 3.0) ));
result[0] = -term1 + 2.0 * r13;
result[4] = result[2] = -(r13 + term1);
return;
}
q = -q;
dum1 = q * q * q;
dum1 = Math.acos( r / Math.sqrt( dum1 ) );
r13 = 2.0 * Math.sqrt( q );
result[0] = -term1 + r13 * Math.cos( dum1 / 3.0 );
result[2] = -term1 + r13 * Math.cos( (dum1 + 2.0 * Math.PI) / 3.0 );
result[4] = -term1 + r13 * Math.cos( (dum1 + 4.0 * Math.PI) / 3.0 );
return;
}...
+ y1 * y2 - y1 * y1 + y1 * y - y2 * y;
// debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a);
var roots = [];
// Use the cubic solving algorithm
this.solveCubic( a, b, c, d, roots );
var zeroThreshold = 0.0000001;
var params = [];
for( var index = 0; index < 6; index += 2 ){
if( Math.abs( roots[ index + 1] ) < zeroThreshold
...sqdist = function ( p1, p2 ){
var dx = p2.x - p1.x;
var dy = p2.y - p1.y;
return dx * dx + dy * dy;
}...
return -1;
} else {
return 0;
}
};
math.dist = function( p1, p2 ){
return Math.sqrt( math.sqdist( p1, p2 ) );
};
math.sqdist = function( p1, p2 ){
var dx = p2.x - p1.x;
var dy = p2.y - p1.y;
return dx * dx + dy * dy;
...sqdistToFiniteLine = function ( x, y, x1, y1, x2, y2 ){
var offset = [ x - x1, y - y1 ];
var line = [ x2 - x1, y2 - y1 ];
var lineSq = line[0] * line[0] + line[1] * line[1];
var hypSq = offset[0] * offset[0] + offset[1] * offset[1];
var dotProduct = offset[0] * line[0] + offset[1] * line[1];
var adjSq = dotProduct * dotProduct / lineSq;
if( dotProduct < 0 ){
return hypSq;
}
if( adjSq > lineSq ){
return (x - x2) * (x - x2) + (y - y2) * (y - y2);
}
return hypSq - adjSq;
}n/a
sqdistToQuadraticBezier = function ( x, y, x1, y1, x2, y2, x3, y3 ){
// Find minimum distance by using the minimum of the distance
// function between the given point and the curve
// This gives the coefficients of the resulting cubic equation
// whose roots tell us where a possible minimum is
// (Coefficients are divided by 4)
var a = 1.0 * x1 * x1 - 4 * x1 * x2 + 2 * x1 * x3 + 4 * x2 * x2 - 4 * x2 * x3 + x3 * x3
+ y1 * y1 - 4 * y1 * y2 + 2 * y1 * y3 + 4 * y2 * y2 - 4 * y2 * y3 + y3 * y3;
var b = 1.0 * 9 * x1 * x2 - 3 * x1 * x1 - 3 * x1 * x3 - 6 * x2 * x2 + 3 * x2 * x3
+ 9 * y1 * y2 - 3 * y1 * y1 - 3 * y1 * y3 - 6 * y2 * y2 + 3 * y2 * y3;
var c = 1.0 * 3 * x1 * x1 - 6 * x1 * x2 + x1 * x3 - x1 * x + 2 * x2 * x2 + 2 * x2 * x - x3 * x
+ 3 * y1 * y1 - 6 * y1 * y2 + y1 * y3 - y1 * y + 2 * y2 * y2 + 2 * y2 * y - y3 * y;
var d = 1.0 * x1 * x2 - x1 * x1 + x1 * x - x2 * x
+ y1 * y2 - y1 * y1 + y1 * y - y2 * y;
// debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a);
var roots = [];
// Use the cubic solving algorithm
this.solveCubic( a, b, c, d, roots );
var zeroThreshold = 0.0000001;
var params = [];
for( var index = 0; index < 6; index += 2 ){
if( Math.abs( roots[ index + 1] ) < zeroThreshold
&& roots[ index ] >= 0
&& roots[ index ] <= 1.0 ){
params.push( roots[ index ] );
}
}
params.push( 1.0 );
params.push( 0.0 );
var minDistanceSquared = -1;
var closestParam;
var curX, curY, distSquared;
for( var i = 0; i < params.length; i++ ){
curX = Math.pow( 1.0 - params[ i ], 2.0 ) * x1
+ 2.0 * (1 - params[ i ]) * params[ i ] * x2
+ params[ i ] * params[ i ] * x3;
curY = Math.pow( 1 - params[ i ], 2.0 ) * y1
+ 2 * (1.0 - params[ i ]) * params[ i ] * y2
+ params[ i ] * params[ i ] * y3;
distSquared = Math.pow( curX - x, 2 ) + Math.pow( curY - y, 2 );
// debug('distance for param ' + params[i] + ": " + Math.sqrt(distSquared));
if( minDistanceSquared >= 0 ){
if( distSquared < minDistanceSquared ){
minDistanceSquared = distSquared;
closestParam = params[ i ];
}
} else {
minDistanceSquared = distSquared;
closestParam = params[ i ];
}
}
return minDistanceSquared;
}n/a
triangleAngle = function ( A, B, C ){
var a = math.dist( B, C );
var b = math.dist( A, C );
var c = math.dist( A, B );
return Math.acos( (a*a + b*b - c*c)/(2*a*b) );
}n/a
updateBoundingBox = function ( bb1, bb2 ){
// update bb1 with bb2 bounds
bb1.x1 = Math.min( bb1.x1, bb2.x1 );
bb1.x2 = Math.max( bb1.x2, bb2.x2 );
bb1.w = bb1.x2 - bb1.x1;
bb1.y1 = Math.min( bb1.y1, bb2.y1 );
bb1.y2 = Math.max( bb1.y2, bb2.y2 );
bb1.h = bb1.y2 - bb1.y1;
}n/a
batch = function ( callback ){
this.startBatch();
callback();
this.endBatch();
return this;
}...
return this;
},
// for backwards compatibility
batchData: function( map ){
var cy = this;
return this.batch( function(){
var ids = Object.keys( map );
for( var i = 0; i < ids.length; i++ ){
var id = ids[i];
var data = map[ id ];
var ele = cy.getElementById( id );
...batchData = function ( map ){
var cy = this;
return this.batch( function(){
var ids = Object.keys( map );
for( var i = 0; i < ids.length; i++ ){
var id = ids[i];
var data = map[ id ];
var ele = cy.getElementById( id );
ele.data( data );
}
} );
}n/a
endBatch = function (){
var _p = this._private;
_p.batchCount--;
if( _p.batchCount === 0 ){
// update style for dirty eles
_p.batchingStyle = false;
_p.batchStyleEles.updateStyle();
// notify the renderer of queued eles and event types
_p.batchingNotify = false;
this.notify( {
type: _p.batchNotifyTypes,
eles: _p.batchNotifyEles
} );
}
return this;
}...
checkSwitch( 'grabbable', 'grabify', 'ungrabify' );
if( obj.classes != null ){
ele.classes( obj.classes );
}
cy.endBatch();
return this;
} else if( obj === undefined ){ // get
var json = {
data: util.copy( p.data ),
...noNotifications = function ( callback ){
this.notifications( false );
callback();
this.notifications( true );
}n/a
notifications = function ( bool ){
var p = this._private;
if( bool === undefined ){
return p.notificationsEnabled;
} else {
p.notificationsEnabled = bool ? true : false;
}
}...
return p.notificationsEnabled;
} else {
p.notificationsEnabled = bool ? true : false;
}
},
noNotifications: function( callback ){
this.notifications( false );
callback();
this.notifications( true );
},
startBatch: function(){
var _p = this._private;
...notify = function ( params ){
var _p = this._private;
if( _p.batchingNotify ){
var bEles = _p.batchNotifyEles;
var bTypes = _p.batchNotifyTypes;
if( params.eles ){
bEles.merge( params.eles );
}
if( !bTypes.ids[ params.type ] ){
bTypes.push( params.type );
bTypes.ids[ params.type ] = true;
}
return; // notifications are disabled during batching
}
if( !_p.notificationsEnabled ){ return; } // exit on disabled
var renderer = this.renderer();
// exit if destroy() called on core or renderer in between frames #1499
// TODO first check this.isDestroyed() in >=3.1 #1440
if( !renderer ){ return; }
renderer.notify( params );
}...
if( !jumpToEnd ){
_p.animation.current = [];
}
}
// we have to notify (the animation loop doesn't do it for us on `stop`)
cy.notify( {
eles: this,
type: 'draw'
} );
return this;
};
} // stop
...startBatch = function (){
var _p = this._private;
if( _p.batchCount == null ){
_p.batchCount = 0;
}
if( _p.batchCount === 0 ){
_p.batchingStyle = _p.batchingNotify = true;
_p.batchStyleEles = this.collection();
_p.batchNotifyEles = this.collection();
_p.batchNotifyTypes = [];
_p.batchNotifyTypes.ids = {};
}
_p.batchCount++;
return this;
}...
if( ele == null ){ return undefined; } // can't get from no eles
var p = ele._private;
if( is.plainObject( obj ) ){ // set
cy.startBatch();
if( obj.data ){
ele.data( obj.data );
}
if( obj.position ){
ele.position( obj.position );
...function NullLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
run = function (){
var options = this.options;
var eles = options.eles; // elements to consider in the layout
var layout = this;
// cy is automatically populated for us in the constructor
var cy = options.cy; // jshint ignore:line
layout.trigger( 'layoutstart' );
// puts all nodes at (0, 0)
eles.nodes().positions( function(){
return {
x: 0,
y: 0
};
} );
// trigger layoutready when each node has had its position set at least once
layout.one( 'layoutready', options.ready );
layout.trigger( 'layoutready' );
// trigger layoutstop when the layout stops (e.g. finishes)
layout.one( 'layoutstop', options.stop );
layout.trigger( 'layoutstop' );
return this; // chaining
}...
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...stop = function (){
return this; // chaining
}...
var opts = this.options;
if( opts && opts.animate ){
var anis = this.animations;
if( anis ){
for( var i = 0; i < anis.length; i++ ){
anis[ i ].stop();
}
}
}
if( regStop ){
regStop.call( this );
} else {
...pageRank = function ( options ){
options = options || {};
var normalizeVector = function( vector ){
var length = vector.length;
// First, get sum of all elements
var total = 0;
for( var i = 0; i < length; i++ ){
total += vector[ i ];
}
// Now, divide each by the sum of all elements
for( var i = 0; i < length; i++ ){
vector[ i ] = vector[ i ] / total;
}
};
// dampingFactor - optional
if( options != null &&
options.dampingFactor != null ){
var dampingFactor = options.dampingFactor;
} else {
var dampingFactor = 0.8; // Default damping factor
}
// desired precision - optional
if( options != null &&
options.precision != null ){
var epsilon = options.precision;
} else {
var epsilon = 0.000001; // Default precision
}
// Max number of iterations - optional
if( options != null &&
options.iterations != null ){
var numIter = options.iterations;
} else {
var numIter = 200; // Default number of iterations
}
// Weight function - optional
if( options != null &&
options.weight != null &&
is.fn( options.weight ) ){
var weightFn = options.weight;
} else {
// If not specified, assume each edge has equal weight (1)
var weightFn = function( e ){return 1;};
}
var cy = this._private.cy;
var edges = this.edges().stdFilter( function( e ){ return !e.isLoop(); } );
var nodes = this.nodes();
var numNodes = nodes.length;
var numEdges = edges.length;
// Create numerical identifiers for each node
// mapping: node id -> position in nodes array
// for reverse mapping, simply use nodes array
var id2position = {};
for( var i = 0; i < numNodes; i++ ){
id2position[ nodes[ i ].id() ] = i;
}
// Construct transposed adjacency matrix
// First lets have a zeroed matrix of the right size
// We'll also keep track of the sum of each column
var matrix = [];
var columnSum = [];
var additionalProb = (1 - dampingFactor) / numNodes;
// Create null matric
for( var i = 0; i < numNodes; i++ ){
var newRow = [];
for( var j = 0; j < numNodes; j++ ){
newRow.push( 0.0 );
}
matrix.push( newRow );
columnSum.push( 0.0 );
}
// Now, process edges
for( var i = 0; i < numEdges; i++ ){
var edge = edges[ i ];
var s = id2position[ edge.source().id() ];
var t = id2position[ edge.target().id() ];
var w = weightFn( edge );
// Update matrix
matrix[ t ][ s ] += w;
// Update column sum
columnSum[ s ] += w;
}
// Add additional probability based on damping factor
// Also, take into account columns that have sum = 0
var p = 1.0 / numNodes + additionalProb; // Shorthand
// Traverse matrix, column by column
for( var j = 0; j < numNodes; j++ ){
if( columnSum[ j ] === 0 ){
// No 'links' out from node jth, assume equal probability for each possible node
for( var i = 0; i < numNodes; i++ ){
matrix[ i ][ j ] = p;
}
} else {
// Node jth has outgoing link, compute normalized probabilities
for( var i = 0; i < numNodes; i++ ){
matrix[ i ][ j ] = matrix[ i ][ j ] / columnSum[ j ] + additionalProb;
}
}
}
// Compute dominant eigenvector using power method
var eigenvector = [];
var nullVector = [];
var previous;
// Start with a vector of all 1's
// Also, initialize a null vector which will be used as shorthand
for( var i = 0; i < numNodes; i++ ){
eigenvector.push( 1.0 );
nullVector.push( 0.0 );
}
for( var iter = 0; iter < numIter; iter++ ){
// New array with all 0's
var temp = nullVector.slice( 0 );
// Multiply matrix with previous result
for( var i = 0; i < numNodes; i++ ){
for( var j = 0; j < numNodes; j++ ){
temp[ i ] += matrix[ i ][ j ] * eigenvector[ j ];
}
}
normalizeVector( temp );
previous = eigenvector;
eigenvector = temp;
var diff = 0;
// Compute difference (squared module) of both vectors
for( var i = 0; i < numNodes; i++ ){
diff += Math.pow( previous[ i ] - eigenvector[ i ], 2 ); ...n/a
parse = function ( name, value, propIsBypass, propIsFlat ){
var self = this;
// function values can't be cached in all cases, and there isn't much benefit of caching them anyway
if( is.fn( value ) ){
return self.parseImpl( name, value, propIsBypass, propIsFlat );
}
var argHash = [ name, value, propIsBypass, propIsFlat ].join( '$' );
var propCache = self.propCache = self.propCache || {};
var ret;
if( !(ret = propCache[ argHash ]) ){
ret = propCache[ argHash ] = self.parseImpl( name, value, propIsBypass, propIsFlat );
}
// always need a copy since props are mutated later in their lifecycles
ret = util.copy( ret );
if( ret ){
ret.value = util.copy( ret.value ); // because it could be an array, e.g. colour
}
return ret;
}...
// edges connected to compound nodes can not be haystacks
if(
parsedProp.name === 'curve-style'
&& parsedProp.value === 'haystack'
&& ele.isEdge()
&& ( ele.isLoop() || ele.source().isParent() || ele.target().isParent() )
){
prop = parsedProp = this.parse( parsedProp.name, 'bezier', propIsBypass );
}
if( prop.delete ){ // delete the property and use the default value on falsey value
style[ prop.name ] = undefined;
return true;
}
...parseImpl = function ( name, value, propIsBypass, propIsFlat ){
var self = this;
name = util.camel2dash( name ); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName')
var property = self.properties[ name ];
var passedValue = value;
var types = self.types;
if( !property ){ return null; } // return null on property of unknown name
if( value === undefined || value === null ){ return null; } // can't assign null
// the property may be an alias
if( property.alias ){
property = property.pointsTo;
name = property.name;
}
var valueIsString = is.string( value );
if( valueIsString ){ // trim the value to make parsing easier
value = value.trim();
}
var type = property.type;
if( !type ){ return null; } // no type, no luck
// check if bypass is null or empty string (i.e. indication to delete bypass property)
if( propIsBypass && (value === '' || value === null) ){
return {
name: name,
value: value,
bypass: true,
deleteBypass: true
};
}
// check if value is a function used as a mapper
if( is.fn( value ) ){
return {
name: name,
value: value,
strValue: 'fn',
mapped: types.fn,
bypass: propIsBypass
};
}
// check if value is mapped
var data, mapData;
if( !valueIsString || propIsFlat ){
// then don't bother to do the expensive regex checks
} else if( (data = new RegExp( types.data.regex ).exec( value )) ){
if( propIsBypass ){ return false; } // mappers not allowed in bypass
var mapped = types.data;
return {
name: name,
value: data,
strValue: '' + value,
mapped: mapped,
field: data[1],
bypass: propIsBypass
};
} else if( (mapData = new RegExp( types.mapData.regex ).exec( value )) ){
if( propIsBypass ){ return false; } // mappers not allowed in bypass
if( type.multiple ){ return false; } // impossible to map to num
var mapped = types.mapData;
// we can map only if the type is a colour or a number
if( !(type.color || type.number) ){ return false; }
var valueMin = this.parse( name, mapData[4] ); // parse to validate
if( !valueMin || valueMin.mapped ){ return false; } // can't be invalid or mapped
var valueMax = this.parse( name, mapData[5] ); // parse to validate
if( !valueMax || valueMax.mapped ){ return false; } // can't be invalid or mapped
// check if valueMin and valueMax are the same
if( valueMin.value === valueMax.value ){
return false; // can't make much of a mapper without a range
} else if( type.color ){
var c1 = valueMin.value;
var c2 = valueMax.value;
var same = c1[0] === c2[0] // red
&& c1[1] === c2[1] // green
&& c1[2] === c2[2] // blue
&& ( // optional alpha
c1[3] === c2[3] // same alpha outright
|| (
(c1[3] == null || c1[3] === 1) // full opacity for colour 1?
&&
(c2[3] == null || c2[3] === 1) // full opacity for colour 2?
)
)
;
if( same ){ return false; } // can't make a mapper without a range
}
return {
name: name,
value: mapData,
strValue: '' + value,
mapped: mapped,
field: mapData[1],
fieldMin: parseFloat( mapData[2] ), // min & max are numeric
fieldMax: parseFloat( mapData[3] ),
valueMin: valueMin.value,
valueMax: valueMax.value,
bypass: propIsBypass
};
}
if( type.multiple && propIsFlat !== 'multiple' ){
var vals;
if( valueIsString ){
vals = value.split( /\s+/ );
} else if( is.array( value ) ){
vals = value;
} else {
vals = [ value ];
}
if( type.evenMultiple && vals.length % 2 !== 0 ){ return null; }
var valArr = vals.map( function( v ){
var p = self.parse( name, v, propIsBypass, 'multiple' );
if( p.pfValue != null ){
return p.pfValue;
} else {
return p.value;
}
} );
return {
name: name,
value: valArr,
pfValue: valArr,
s ......
// a caching layer for property parsing
styfn.parse = function( name, value, propIsBypass, propIsFlat ){
var self = this;
// function values can't be cached in all cases, and there isn't much benefit of caching them anyway
if( is.fn( value ) ){
return self.parseImpl( name, value, propIsBypass, propIsFlat );
}
var argHash = [ name, value, propIsBypass, propIsFlat ].join( '$' );
var propCache = self.propCache = self.propCache || {};
var ret;
if( !(ret = propCache[ argHash ]) ){
...function PresetLayout( options ){
this.options = util.extend( {}, defaults, options );
}n/a
run = function (){
var options = this.options;
var eles = options.eles;
var nodes = eles.nodes();
var posIsFn = is.fn( options.positions );
function getPosition( node ){
if( options.positions == null ){
return null;
}
if( posIsFn ){
return options.positions( node );
}
var pos = options.positions[ node._private.data.id ];
if( pos == null ){
return null;
}
return pos;
}
nodes.layoutPositions( this, options, function( node, i ){
var position = getPosition( node );
if( node.locked() || position == null ){
return false;
}
return position;
} );
return this; // chaining
}...
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...addDefaultStylesheet = function (){
this
.selector( '$node > node' ) // compound (parent) node properties
.css( {
'shape': 'rectangle',
'padding': 10,
'background-color': '#eee',
'border-color': '#ccc',
'border-width': 1
} )
.selector( 'edge' ) // just edge properties
.css( {
'width': 3,
'curve-style': 'haystack'
} )
.selector( ':selected' )
.css( {
'background-color': '#0169D9',
'line-color': '#0169D9',
'source-arrow-color': '#0169D9',
'target-arrow-color': '#0169D9',
'mid-source-arrow-color': '#0169D9',
'mid-target-arrow-color': '#0169D9'
} )
.selector( 'node:parent:selected' )
.css( {
'background-color': '#CCE1F9',
'border-color': '#aec8e5'
} )
.selector( ':active' )
.css( {
'overlay-color': 'black',
'overlay-padding': 10,
'overlay-opacity': 0.25
} )
.selector( 'core' ) // just core properties
.css( {
'selection-box-color': '#ddd',
'selection-box-opacity': 0.65,
'selection-box-border-color': '#aaa',
'selection-box-border-width': 1,
'active-bg-color': 'black',
'active-bg-opacity': 0.15,
'active-bg-size': 30,
'outside-texture-bg-color': '#000',
'outside-texture-bg-opacity': 0.125
} )
;
this.defaultLength = this.length;
}n/a
getDefaultProperties = function (){
var self = this;
var args = arguments;
var ret;
var k = keyFn.apply( self, args );
var cache = memoizedFn.cache;
if( !(ret = cache[ k ]) ){
ret = cache[ k ] = fn.apply( self, args );
}
return ret;
}...
props.push( aliasProp );
props[ alias.name ] = aliasProp; // allow lookup by name
}
})();
styfn.getDefaultProperty = function( name ){
return this.getDefaultProperties()[ name ];
};
styfn.getDefaultProperties = util.memoize( function(){
var rawProps = util.extend( {
'events': 'yes',
'text-events': 'no',
'text-valign': 'top',
...getDefaultProperty = function ( name ){
return this.getDefaultProperties()[ name ];
}...
// get the internal parsed style object for the specified property
parsedStyle: function( property ){
var ele = this[0];
if( !ele.cy().styleEnabled() ){ return; }
if( ele ){
return ele._private.style[ property ] || ele.cy().style().getDefaultProperty( property
);
}
},
// get the specified css property as a rendered value (i.e. on-screen value)
// or get the whole rendered style if no property specified (NB doesn't allow setting)
renderedStyle: function( property ){
var cy = this.cy();
...function RandomLayout( options ){
this.options = util.extend( {}, defaults, options );
}...
sizeLimit ){
// Stop condition
if( size <= sizeLimit ){
return remainingEdges;
}
// Choose an edge randomly
var edgeIndex = Math.floor( (Math.random() * remainingEdges.length) );
// Colapse graph based on edge
var newEdges = colapse( edgeIndex, metaNodeMap, remainingEdges );
return contractUntil( metaNodeMap,
newEdges,
size - 1,
...run = function (){
var options = this.options;
var cy = options.cy;
var eles = options.eles;
var nodes = eles.nodes().not( ':parent' );
var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} );
var getPos = function( node, i ){
return {
x: bb.x1 + Math.round( Math.random() * bb.w ),
y: bb.y1 + Math.round( Math.random() * bb.h )
};
};
nodes.layoutPositions( this, options, getPos );
return this; // chaining
}...
for( var i = 0; i < optLayoutFns.length; i++ ){
var fnName = optLayoutFns[ i ];
layoutProto[ fnName ] = layoutProto[ fnName ] || function(){ return this; };
}
// either .start() or .run() is defined, so autogen the other
if( layoutProto.start && !layoutProto.run ){
layoutProto.run = function(){ this.start(); return this; };
} else if( !layoutProto.start && layoutProto.run ){
layoutProto.start = function(){ this.run(); return this; };
}
var regStop = registrant.prototype.stop;
...renderer = function (){
return this._private.renderer;
}...
useCache: true
};
var defBbOptsKey = getKey( defBbOpts );
elesfn.recalculateRenderedStyle = function( useCache ){
var cy = this.cy();
var renderer = cy.renderer();
var styleEnabled = cy.styleEnabled();
if( renderer && styleEnabled ){
renderer.recalculateRenderedStyle( this, useCache );
}
return this;
...destroyRenderer = function (){
var cy = this;
cy.notify( { type: 'destroy' } ); // destroy the renderer
var domEle = cy.container();
if( domEle ){
domEle._cyreg = null;
while( domEle.childNodes.length > 0 ){
domEle.removeChild( domEle.childNodes[0] );
}
}
cy._private.renderer = null; // to be extra safe, remove the ref
}n/a
forceRender = function (){
this.notify( {
type: 'draw'
} );
return this;
}n/a
initRenderer = function ( options ){
var cy = this;
var RendererProto = cy.extension( 'renderer', options.name );
if( RendererProto == null ){
util.error( 'Can not initialise: No such renderer `%s` found; did you include its JS file?', options.name );
return;
}
var rOpts = util.extend( {}, options, {
cy: cy
} );
cy._private.renderer = new RendererProto( rOpts );
}n/a
invalidateDimensions = function (){
this.invalidateSize();
this.notify( {
type: 'resize'
} );
this.trigger( 'resize' );
return this;
}n/a
offRender = function ( fn ){
return this.off('render', fn);
}n/a
onRender = function ( fn ){
return this.on('render', fn);
}n/a
renderTo = function ( context, zoom, pan, pxRatio ){
var r = this._private.renderer;
r.renderTo( context, zoom, pan, pxRatio );
return this;
}...
var util = require( '../util' );
var corefn = ({
renderTo: function( context, zoom, pan, pxRatio ){
var r = this._private.renderer;
r.renderTo( context, zoom, pan, pxRatio );
return this;
},
renderer: function(){
return this._private.renderer;
},
...resize = function (){
this.invalidateSize();
this.notify( {
type: 'resize'
} );
this.trigger( 'resize' );
return this;
}n/a
collection = function ( eles, opts ){
if( is.string( eles ) ){
return this.$( eles );
} else if( is.elementOrCollection( eles ) ){
return eles.collection();
} else if( is.array( eles ) ){
return new Collection( this, eles, opts );
}
return new Collection( this );
}...
return undefined;
} else {
return null != obj && obj instanceof HTMLElement;
}
},
elementOrCollection: function( obj ){
return is.element( obj ) || is.collection( obj );
},
element: function( obj ){
return instanceStr( obj ) === 'collection' && obj._private.single;
},
collection: function( obj ){
...edges = function ( selector ){
var edges = this.$( function( ele ){
return ele.isEdge();
} );
if( selector ){
return edges.filter( selector );
}
return edges;
}...
var defaults = {
codirected: false
};
params = util.extend( {}, defaults, params );
return function parallelEdgesImpl( selector ){ // micro-optimised for renderer
var elements = [];
var edges = this.edges();
var p = params;
// look at all the edges in the collection
for( var i = 0; i < edges.length; i++ ){
var edge1 = edges[ i ];
var edge1_p = edge1._private;
var src1 = edge1_p.source;
...elements = function ( selector ){
var eles = this._private.elements;
if( selector ){
return eles.filter( selector );
} else {
return eles.spawnSelf();
}
}n/a
filter = function ( selector ){
var eles = this._private.elements;
if( selector ){
return eles.filter( selector );
} else {
return eles.spawnSelf();
}
}...
meta: [],
// fake selectors
collection: null, // a collection to match against
filter: null, // filter function
// these are defined in the upward direction rather than down (e.g. child)
// because we need to go up in Selector.filter()
parent: null, // parent query obj
ancestor: null, // ancestor query obj
subject: null, // defines subject in compound query (subject query obj; points to self if subject)
// use these only when subject has been defined
child: null,
descendant: null
...mutableElements = function (){
return this._private.elements;
}...
}
},
absoluteComplement: function(){
var cy = this._private.cy;
return cy.mutableElements().not( this );
},
intersect: function( other ){
// if a selector is specified, then filter by it instead
if( is.string( other ) ){
var selector = other;
return this.filter( selector );
...nodes = function ( selector ){
var nodes = this.$( function( ele ){
return ele.isNode();
} );
if( selector ){
return nodes.filter( selector );
}
return nodes;
}...
}
} )
} );
function defineDegreeBoundsFunction( degreeFn, callback ){
return function( includeLoops ){
var ret;
var nodes = this.nodes();
for( var i = 0; i < nodes.length; i++ ){
var ele = nodes[ i ];
var degree = ele[ degreeFn ]( includeLoops );
if( degree !== undefined && (ret === undefined || callback( degree, ret )) ){
ret = degree;
}
...selector = function ( selector ){
if( !(this instanceof Selector) ){
return new Selector( selector );
}
var self = this;
self._private = {
selectorText: null,
invalid: true
};
// storage for parsed queries
var newQuery = function(){
return {
classes: [],
colonSelectors: [],
data: [],
group: null,
ids: [],
meta: [],
// fake selectors
collection: null, // a collection to match against
filter: null, // filter function
// these are defined in the upward direction rather than down (e.g. child)
// because we need to go up in Selector.filter()
parent: null, // parent query obj
ancestor: null, // ancestor query obj
subject: null, // defines subject in compound query (subject query obj; points to self if subject)
// use these only when subject has been defined
child: null,
descendant: null
};
};
if( !selector || ( is.string( selector ) && selector.match( /^\s*$/ ) ) ){
self.length = 0;
} else if( selector === '*' || selector === 'edge' || selector === 'node' ){
// make single, group-only selectors cheap to make and cheap to filter
self[0] = newQuery();
self[0].group = selector === '*' ? selector : selector + 's';
self[0].groupOnly = true;
self._private.invalid = false;
self._private.selectorText = selector;
self.length = 1;
} else if( is.elementOrCollection( selector ) ){
var collection = selector.collection();
self[0] = newQuery();
self[0].collection = collection;
self.length = 1;
} else if( is.fn( selector ) ){
self[0] = newQuery();
self[0].filter = selector;
self.length = 1;
} else if( is.string( selector ) ){
// the current subject in the query
var currentSubject = null;
// tokens in the query language
var tokens = {
metaChar: '[\\!\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]', // chars we need to
escape in var names, etc
comparatorOp: '=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=', // binary comparison op (used in data selectors)
boolOp: '\\?|\\!|\\^', // boolean (unary) operators (used in data selectors)
string: '"(?:\\\\"|[^"])*"' + '|' + "'(?:\\\\'|[^'])*'", // string literals (used in data selectors) -- doublequotes | singlequotes
number: util.regex.number, // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123
meta: 'degree|indegree|outdegree', // allowed metadata fields (i.e. allowed functions to use from Collection)
separator: '\\s*,\\s*', // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass
descendant: '\\s+',
child: '\\s+>\\s+',
subject: '\\$'
};
tokens.variable = '(?:[\\w-]|(?:\\\\' + tokens.metaChar + '))+'; // a variable name
tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number
tokens.className = tokens.variable; // a class name (follows variable conventions)
tokens.id = tokens.variable; // an element id (follows variable conventions)
// when a token like a variable has escaped meta characters, we need to clean the backslashes out
// so that values get compared properly in Selector.filter()
var cleanMetaChars = function( str ){
return str.replace( new RegExp( '\\\\(' + tokens.metaChar + ')', 'g' ), function( match, $1, offset, original ){
return $1;
} );
};
// add @ variants to comparatorOp
var ops = tokens.comparatorOp.split( '|' );
for( var i = 0; i < ops.length; i++ ){
var op = ops[ i ];
tokens.comparatorOp += '|@' + op;
}
// add ! variants to comparatorOp
var ops = tokens.comparatorOp.split( '|' );
for( var i = 0; i < ops.length; i++ ){
var op = ops[ i ];
if( op.indexOf( '!' ) >= 0 ){ continue; } // skip ops that explicitly contain !
if( op === '=' ){ continue; } // skip = b/c != is explicitly defined
tokens.comparatorOp += '|\\!' + op;
}
// NOTE: add new expression syntax here ......
for( var i = 0; i < json.length; i++ ){
var context = json[ i ];
var selector = context.selector;
var props = context.style || context.css;
var names = Object.keys( props );
style.selector( selector ); // apply selector
for( var j = 0; j < names.length; j++ ){
var name = names[j];
var value = props[ name ];
style.css( name, value ); // apply property
}
...eq = function ( i ){
return this[ i ];
}n/a
filter = function ( collection ){
var self = this;
var cy = collection.cy();
// don't bother trying if it's invalid
if( self._private.invalid ){
return cy.collection();
}
var selectorFunction = function( element, i ){
for( var j = 0; j < self.length; j++ ){
var query = self[ j ];
if( queryMatches( query, element ) ){
return true;
}
}
return false;
};
if( self._private.selectorText == null ){
selectorFunction = function(){ return true; };
}
var filteredCollection = collection.filter( selectorFunction );
return filteredCollection;
}...
meta: [],
// fake selectors
collection: null, // a collection to match against
filter: null, // filter function
// these are defined in the upward direction rather than down (e.g. child)
// because we need to go up in Selector.filter()
parent: null, // parent query obj
ancestor: null, // ancestor query obj
subject: null, // defines subject in compound query (subject query obj; points to self if subject)
// use these only when subject has been defined
child: null,
descendant: null
...matches = function ( ele ){
var self = this;
// don't bother trying if it's invalid
if( self._private.invalid ){
return false;
}
for( var j = 0; j < self.length; j++ ){
var query = self[ j ];
if( queryMatches( query, ele ) ){
return true;
}
}
return false;
}...
} ];
}
for( var k = 0; k < listeners.length; k++ ){ // check each listener
var lis = listeners[ k ];
var nsMatches = !lis.namespace || lis.namespace === evt.namespace || lis.namespace === define.event.universalNamespace
;
var typeMatches = lis.type === evt.type;
var targetMatches = lis.delegated ? ( triggerer !== evt.target && is.element( evt.target ) && lis
.selObj.matches( evt.target ) ) : (true); // we're not going to validate the hierarchy
; that's too expensive
var listenerMatches = nsMatches && typeMatches && targetMatches;
if( listenerMatches ){ // then trigger it
var args = [ evt ];
args = args.concat( extraParams ); // add extra params to args list
if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener
...selector = function (){
var str = '';
var clean = function( obj ){
if( obj == null ){
return '';
} else {
return obj;
}
};
var cleanVal = function( val ){
if( is.string( val ) ){
return '"' + val + '"';
} else {
return clean( val );
}
};
var space = function( val ){
return ' ' + val + ' ';
};
var queryToString = function( query ){
var str = '';
if( query.subject === query ){
str += '$';
}
var group = clean( query.group );
str += group.substring( 0, group.length - 1 );
for( var j = 0; j < query.data.length; j++ ){
var data = query.data[ j ];
if( data.value ){
str += '[' + data.field + space( clean( data.operator ) ) + cleanVal( data.value ) + ']';
} else {
str += '[' + clean( data.operator ) + data.field + ']';
}
}
for( var j = 0; j < query.meta.length; j++ ){
var meta = query.meta[ j ];
str += '[[' + meta.field + space( clean( meta.operator ) ) + cleanVal( meta.value ) + ']]';
}
for( var j = 0; j < query.colonSelectors.length; j++ ){
var sel = query.colonSelectors[ i ];
str += sel;
}
for( var j = 0; j < query.ids.length; j++ ){
var sel = '#' + query.ids[ i ];
str += sel;
}
for( var j = 0; j < query.classes.length; j++ ){
var sel = '.' + query.classes[ j ];
str += sel;
}
if( query.parent != null ){
str = queryToString( query.parent ) + ' > ' + str;
}
if( query.ancestor != null ){
str = queryToString( query.ancestor ) + ' ' + str;
}
if( query.child != null ){
str += ' > ' + queryToString( query.child );
}
if( query.descendant != null ){
str += ' ' + queryToString( query.descendant );
}
return str;
};
for( var i = 0; i < this.length; i++ ){
var query = this[ i ];
str += queryToString( query );
if( this.length > 1 && i < this.length - 1 ){
str += ', ';
}
}
return str;
}...
for( var i = 0; i < json.length; i++ ){
var context = json[ i ];
var selector = context.selector;
var props = context.style || context.css;
var names = Object.keys( props );
style.selector( selector ); // apply selector
for( var j = 0; j < names.length; j++ ){
var name = names[j];
var value = props[ name ];
style.css( name, value ); // apply property
}
...size = function (){
return this.length;
}...
if( !matchesAny ){
return false;
}
}
// check filter function
if( query.filter != null && ele.collection().filter( query.filter ).size() ===
0 ){
return false;
}
// check parent/child relations
var confirmRelations = function( query, eles ){
if( query != null ){
var matches = false;
...toString = function (){
var str = '';
var clean = function( obj ){
if( obj == null ){
return '';
} else {
return obj;
}
};
var cleanVal = function( val ){
if( is.string( val ) ){
return '"' + val + '"';
} else {
return clean( val );
}
};
var space = function( val ){
return ' ' + val + ' ';
};
var queryToString = function( query ){
var str = '';
if( query.subject === query ){
str += '$';
}
var group = clean( query.group );
str += group.substring( 0, group.length - 1 );
for( var j = 0; j < query.data.length; j++ ){
var data = query.data[ j ];
if( data.value ){
str += '[' + data.field + space( clean( data.operator ) ) + cleanVal( data.value ) + ']';
} else {
str += '[' + clean( data.operator ) + data.field + ']';
}
}
for( var j = 0; j < query.meta.length; j++ ){
var meta = query.meta[ j ];
str += '[[' + meta.field + space( clean( meta.operator ) ) + cleanVal( meta.value ) + ']]';
}
for( var j = 0; j < query.colonSelectors.length; j++ ){
var sel = query.colonSelectors[ i ];
str += sel;
}
for( var j = 0; j < query.ids.length; j++ ){
var sel = '#' + query.ids[ i ];
str += sel;
}
for( var j = 0; j < query.classes.length; j++ ){
var sel = '.' + query.classes[ j ];
str += sel;
}
if( query.parent != null ){
str = queryToString( query.parent ) + ' > ' + str;
}
if( query.ancestor != null ){
str = queryToString( query.ancestor ) + ' ' + str;
}
if( query.child != null ){
str += ' > ' + queryToString( query.child );
}
if( query.descendant != null ){
str += ' ' + queryToString( query.descendant );
}
return str;
};
for( var i = 0; i < this.length; i++ ){
var query = this[ i ];
str += queryToString( query );
if( this.length > 1 && i < this.length - 1 ){
str += ', ';
}
}
return str;
}...
tokens.comparatorOp += '|\\!' + op;
}
// NOTE: add new expression syntax here to have it recognised by the parser;
// - a query contains all adjacent (i.e. no separator in between) expressions;
// - the current query is stored in self[i] --- you can use the reference to `this` in the populate function;
// - you need to check the query objects in Selector.filter() for it actually filter properly, but that's pretty straight forward
// - when you add something here, also add to Selector.toString()
var exprs = [
{
name: 'group',
query: true,
regex: '(node|edge|\\*)',
populate: function( group ){
this.group = group === '*' ? group : group + 's';
...applyFromString = function ( string ){
var self = this;
var style = this;
var remaining = '' + string;
var selAndBlockStr;
var blockRem;
var propAndValStr;
// remove comments from the style string
remaining = remaining.replace( /[/][*](\s|.)+?[*][/]/g, '' );
function removeSelAndBlockFromRemaining(){
// remove the parsed selector and block from the remaining text to parse
if( remaining.length > selAndBlockStr.length ){
remaining = remaining.substr( selAndBlockStr.length );
} else {
remaining = '';
}
}
function removePropAndValFromRem(){
// remove the parsed property and value from the remaining block text to parse
if( blockRem.length > propAndValStr.length ){
blockRem = blockRem.substr( propAndValStr.length );
} else {
blockRem = '';
}
}
while( true ){
var nothingLeftToParse = remaining.match( /^\s*$/ );
if( nothingLeftToParse ){ break; }
var selAndBlock = remaining.match( /^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/ );
if( !selAndBlock ){
util.error( 'Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' +
remaining );
break;
}
selAndBlockStr = selAndBlock[0];
// parse the selector
var selectorStr = selAndBlock[1];
if( selectorStr !== 'core' ){
var selector = new Selector( selectorStr );
if( selector._private.invalid ){
util.error( 'Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr );
// skip this selector and block
removeSelAndBlockFromRemaining();
continue;
}
}
// parse the block of properties and values
var blockStr = selAndBlock[2];
var invalidBlock = false;
blockRem = blockStr;
var props = [];
while( true ){
var nothingLeftToParse = blockRem.match( /^\s*$/ );
if( nothingLeftToParse ){ break; }
var propAndVal = blockRem.match( /^\s*(.+?)\s*:\s*(.+?)\s*;/ );
if( !propAndVal ){
util.error( 'Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr
);
invalidBlock = true;
break;
}
propAndValStr = propAndVal[0];
var propStr = propAndVal[1];
var valStr = propAndVal[2];
var prop = self.properties[ propStr ];
if( !prop ){
util.error( 'Skipping property: Invalid property name in: ' + propAndValStr );
// skip this property in the block
removePropAndValFromRem();
continue;
}
var parsedProp = style.parse( propStr, valStr );
if( !parsedProp ){
util.error( 'Skipping property: Invalid property definition in: ' + propAndValStr );
// skip this property in the block
removePropAndValFromRem();
continue;
}
props.push( {
name: propStr,
val: valStr
} );
removePropAndValFromRem();
}
if( invalidBlock ){
removeSelAndBlockFromRemaining();
break;
}
// put the parsed block in the style
style.selector( selectorStr );
for( var i = 0; i < props.length; i++ ){
var prop = props[ i ];
style.css( prop.name, prop.val );
}
removeSelAndBlockFromRemaining();
}
return style;
}...
return style;
};
styfn.fromString = function( string ){
var style = this;
style.resetToDefault();
style.applyFromString( string );
return style;
};
module.exports = styfn;
...fromString = function ( string ){
var style = this;
style.resetToDefault();
style.applyFromString( string );
return style;
}n/a
camel2dash = function (){
var self = this;
var args = arguments;
var ret;
var k = keyFn.apply( self, args );
var cache = memoizedFn.cache;
if( !(ret = cache[ k ]) ){
ret = cache[ k ] = fn.apply( self, args );
}
return ret;
}...
} // for eles
return ret;
};
// only useful in specific cases like animation
styfn.overrideBypass = function( eles, name, value ){
name = util.camel2dash( name );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
var prop = ele._private.style[ name ];
var type = this.properties[ name ].type;
var isColor = type.color;
var isMulti = type.mutiple;
...capitalize = function ( str ){
if( is.emptyString( str ) ){
return str;
}
return str.charAt( 0 ).toUpperCase() + str.substring( 1 );
}...
bounds.w = noninf( bounds.x2 - bounds.x1 );
bounds.h = noninf( bounds.y2 - bounds.y1 );
return bounds;
};
var defineDimFns = function( opts ){
opts.uppercaseName = util.capitalize( opts.name );
opts.autoName = 'auto' + opts.uppercaseName;
opts.labelName = 'label' + opts.uppercaseName;
opts.outerName = 'outer' + opts.uppercaseName;
opts.uppercaseOuterName = util.capitalize( opts.outerName );
fn[ opts.name ] = function dimImpl(){
var ele = this[0];
...dash2camel = function (){
var self = this;
var args = arguments;
var ret;
var k = keyFn.apply( self, args );
var cache = memoizedFn.cache;
if( !(ret = cache[ k ]) ){
ret = cache[ k ] = fn.apply( self, args );
}
return ret;
}...
for( var i = 0; i < self.properties.length; i++ ){
var prop = self.properties[ i ];
var name = prop.name;
var value = specifiedProps[ name ];
if( value === undefined ){ // try camel case name too
value = specifiedProps[ util.dash2camel( name ) ];
}
if( value !== undefined ){
var parsedProp = this.parse( name, value, true );
if( parsedProp ){
props.push( parsedProp );
...prependCamel = function (){
var self = this;
var args = arguments;
var ret;
var k = keyFn.apply( self, args );
var cache = memoizedFn.cache;
if( !(ret = cache[ k ]) ){
ret = cache[ k ] = fn.apply( self, args );
}
return ret;
}n/a
style = function ( name, value ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
if( is.plainObject( name ) ){ // then extend the bypass
var props = name;
style.applyBypass( this, props, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
} else if( is.string( name ) ){
if( value === undefined ){ // then get the property from the style
var ele = this[0];
if( ele ){
return style.getStylePropertyValue( ele, name );
} else { // empty collection => can't get any value
return;
}
} else { // then set the bypass with the property value
style.applyBypass( this, name, value, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
}
} else if( name === undefined ){
var ele = this[0];
if( ele ){
return style.getRawStyle( ele );
} else { // empty collection => can't get any value
return;
}
}
return this; // chaining
}...
var all = selfIsArrayLike ? self : [ self ]; // put in array if not array-like
var cy = this._private.cy || this;
var isCore = !selfIsArrayLike;
var isEles = !isCore;
if( !cy.styleEnabled() ){ return this; }
var style = cy.style();
properties = util.extend( {}, properties, params );
if( properties.duration === undefined ){
properties.duration = 400;
}
...backgrounding = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return false; }
var ele = this[0];
return ele._private.backgrounding ? true : false;
}...
case ':active':
allColonSelectorsMatch = ele.active();
break;
case ':inactive':
allColonSelectorsMatch = !ele.active();
break;
case ':backgrounding':
allColonSelectorsMatch = ele.backgrounding();
break;
case ':nonbackgrounding':
allColonSelectorsMatch = !ele.backgrounding();
break;
}
if( !allColonSelectorsMatch ) break;
...bypass = function ( name, value ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
if( is.plainObject( name ) ){ // then extend the bypass
var props = name;
style.applyBypass( this, props, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
} else if( is.string( name ) ){
if( value === undefined ){ // then get the property from the style
var ele = this[0];
if( ele ){
return style.getStylePropertyValue( ele, name );
} else { // empty collection => can't get any value
return;
}
} else { // then set the bypass with the property value
style.applyBypass( this, name, value, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
}
} else if( name === undefined ){
var ele = this[0];
if( ele ){
return style.getRawStyle( ele );
} else { // empty collection => can't get any value
return;
}
}
return this; // chaining
}n/a
css = function ( name, value ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
if( is.plainObject( name ) ){ // then extend the bypass
var props = name;
style.applyBypass( this, props, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
} else if( is.string( name ) ){
if( value === undefined ){ // then get the property from the style
var ele = this[0];
if( ele ){
return style.getStylePropertyValue( ele, name );
} else { // empty collection => can't get any value
return;
}
} else { // then set the bypass with the property value
style.applyBypass( this, name, value, updateTransitions );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
}
} else if( name === undefined ){
var ele = this[0];
if( ele ){
return style.getRawStyle( ele );
} else { // empty collection => can't get any value
return;
}
}
return this; // chaining
}...
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
},
show: function(){
this.css( 'display', 'element' );
return this; // chaining
},
hide: function(){
this.css( 'display', 'none' );
return this; // chaining
},
...effectiveOpacity = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return 1; }
var hasCompoundNodes = cy.hasCompoundNodes();
var ele = this[0];
if( ele ){
var _p = ele._private;
var parentOpacity = ele.pstyle( 'opacity' ).value;
if( !hasCompoundNodes ){ return parentOpacity; }
var parents = !_p.data.parent ? null : ele.parents();
if( parents ){
for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
var opacity = parent.pstyle( 'opacity' ).value;
parentOpacity = opacity * parentOpacity;
}
}
return parentOpacity;
}
}...
var ele = this[0];
var hasCompoundNodes = ele.cy().hasCompoundNodes();
if( ele ){
if( !hasCompoundNodes ){
return ele.pstyle( 'opacity' ).value === 0;
} else {
return ele.effectiveOpacity() === 0;
}
}
},
backgrounding: function(){
var cy = this.cy();
if( !cy.styleEnabled() ){ return false; }
...hidden = function (){
var ele = this[0];
if( ele ){
return !ele.visible();
}
}n/a
hide = function (){
this.css( 'display', 'none' );
return this; // chaining
}n/a
interactive = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return true; }
var ele = this[0];
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele ){
var _p = ele._private;
if( !ok( ele ) ){ return false; }
if( ele.isNode() ){
if( hasCompoundNodes ){
var parents = _p.data.parent ? ele.parents() : null;
if( parents ){ for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
if( !parentOk( parent ) ){ return false; }
} }
}
return true;
} else {
return edgeOkViaNode( _p.source ) && edgeOkViaNode( _p.target );
}
}
}...
edgeOkViaNode: eleTakesUpSpace
});
elesfn.noninteractive = function(){
var ele = this[0];
if( ele ){
return !ele.interactive();
}
};
var eleVisible = function( ele ){
return (
ele.pstyle( 'visibility' ).value === 'visible'
&& ele.pstyle( 'opacity' ).pfValue !== 0
...noninteractive = function (){
var ele = this[0];
if( ele ){
return !ele.interactive();
}
}n/a
parsedStyle = function ( property ){
var ele = this[0];
if( !ele.cy().styleEnabled() ){ return; }
if( ele ){
return ele._private.style[ property ] || ele.cy().style().getDefaultProperty( property );
}
}n/a
pstyle = function ( property ){
var ele = this[0];
if( !ele.cy().styleEnabled() ){ return; }
if( ele ){
return ele._private.style[ property ] || ele.cy().style().getDefaultProperty( property );
}
}...
var updated = [];
function update( parent ){
if( !parent.isParent() ){ return; }
var _p = parent._private;
var children = parent.children();
var includeLabels = parent.pstyle( 'compound-sizing-wrt-labels' ).value
=== 'include';
var bb = children.boundingBox( {
includeLabels: includeLabels,
includeOverlays: false,
// updating the compound bounds happens outside of the regular
// cache cycle (i.e. before fired events)
useCache: false
...removeBypass = function ( names ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
var eles = this;
if( names === undefined ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeAllBypasses( ele, updateTransitions );
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeBypasses( ele, names, updateTransitions );
}
}
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
}n/a
removeCss = function ( names ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
var eles = this;
if( names === undefined ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeAllBypasses( ele, updateTransitions );
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeBypasses( ele, names, updateTransitions );
}
}
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
}n/a
removeStyle = function ( names ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var updateTransitions = false;
var style = cy.style();
var eles = this;
if( names === undefined ){
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeAllBypasses( ele, updateTransitions );
}
} else {
names = names.split( /\s+/ );
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
style.removeBypasses( ele, names, updateTransitions );
}
}
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
toNotify.rtrigger( 'style' ); // let the renderer know we've updated style
return this; // chaining
}n/a
renderedCss = function ( property ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var ele = this[0];
if( ele ){
var renstyle = ele.cy().style().getRenderedStyle( ele );
if( property === undefined ){
return renstyle;
} else {
return renstyle[ property ];
}
}
}n/a
renderedStyle = function ( property ){
var cy = this.cy();
if( !cy.styleEnabled() ){ return this; }
var ele = this[0];
if( ele ){
var renstyle = ele.cy().style().getRenderedStyle( ele );
if( property === undefined ){
return renstyle;
} else {
return renstyle[ property ];
}
}
}n/a
show = function (){
this.css( 'display', 'element' );
return this; // chaining
}n/a
takesUpSpace = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return true; }
var ele = this[0];
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele ){
var _p = ele._private;
if( !ok( ele ) ){ return false; }
if( ele.isNode() ){
if( hasCompoundNodes ){
var parents = _p.data.parent ? ele.parents() : null;
if( parents ){ for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
if( !parentOk( parent ) ){ return false; }
} }
}
return true;
} else {
return edgeOkViaNode( _p.source ) && edgeOkViaNode( _p.target );
}
}
}n/a
transparent = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return false; }
var ele = this[0];
var hasCompoundNodes = ele.cy().hasCompoundNodes();
if( ele ){
if( !hasCompoundNodes ){
return ele.pstyle( 'opacity' ).value === 0;
} else {
return ele.effectiveOpacity() === 0;
}
}
}...
case ':visible':
allColonSelectorsMatch = ele.visible();
break;
case ':hidden':
allColonSelectorsMatch = !ele.visible();
break;
case ':transparent':
allColonSelectorsMatch = ele.transparent();
break;
case ':grabbed':
allColonSelectorsMatch = ele.grabbed();
break;
case ':free':
allColonSelectorsMatch = !ele.grabbed();
break;
...updateMappers = function ( notifyRenderer ){
var cy = this._private.cy;
var style = cy.style();
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( !cy.styleEnabled() ){ return this; }
style.updateMappers( this );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
if( notifyRenderer ){
toNotify.rtrigger( 'style' ); // let renderer know we changed style
} else {
toNotify.trigger( 'style' ); // just fire the event
}
return this; // chaining
}...
updateMappers: function( notifyRenderer ){
var cy = this._private.cy;
var style = cy.style();
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( !cy.styleEnabled() ){ return this; }
style.updateMappers( this );
var updatedCompounds = this.updateCompoundBounds();
var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;
if( notifyRenderer ){
toNotify.rtrigger( 'style' ); // let renderer know we changed style
} else {
...updateStyle = function ( notifyRenderer ){
var cy = this._private.cy;
if( !cy.styleEnabled() ){ return this; }
if( cy._private.batchingStyle ){
var bEles = cy._private.batchStyleEles;
bEles.merge( this );
return this; // chaining and exit early when batching
}
var hasCompounds = cy.hasCompoundNodes();
var style = cy.style();
var updatedEles = this;
notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
if( hasCompounds ){ // then add everything up and down for compound selector checks
updatedEles = this.spawnSelf().merge( this.descendants() ).merge( this.parents() );
}
style.apply( updatedEles );
if( hasCompounds ){
var updatedCompounds = updatedEles.updateCompoundBounds();
// disable for performance for now
// (as updatedCompounds would be a subset of updatedEles ayway b/c of selectors check)
// if( updatedCompounds.length > 0 ){
// updatedEles.merge( updatedCompounds );
// }
}
if( notifyRenderer ){
updatedEles.rtrigger( 'style' ); // let renderer know we changed style
} else {
updatedEles.trigger( 'style' ); // just fire the event
}
return this; // chaining
}...
for( var i = 0, l = all.length; i < l; i++ ){
if( p.canSet( all[ i ] ) ){
all[ i ]._private[ p.field ][ name ] = value;
}
}
// update mappers if asked
if( p.updateStyle ){ self.updateStyle(); }
// call onSet callback
p.onSet( self );
if( p.settingTriggersEvent ){
self[ p.triggerFnName ]( p.settingEvent );
}
...visible = function (){
var cy = this.cy();
if( !cy.styleEnabled() ){ return true; }
var ele = this[0];
var hasCompoundNodes = cy.hasCompoundNodes();
if( ele ){
var _p = ele._private;
if( !ok( ele ) ){ return false; }
if( ele.isNode() ){
if( hasCompoundNodes ){
var parents = _p.data.parent ? ele.parents() : null;
if( parents ){ for( var i = 0; i < parents.length; i++ ){
var parent = parents[ i ];
if( !parentOk( parent ) ){ return false; }
} }
}
return true;
} else {
return edgeOkViaNode( _p.source ) && edgeOkViaNode( _p.target );
}
}
}...
case ':locked':
allColonSelectorsMatch = ele.locked();
break;
case ':unlocked':
allColonSelectorsMatch = !ele.locked();
break;
case ':visible':
allColonSelectorsMatch = ele.visible();
break;
case ':hidden':
allColonSelectorsMatch = !ele.visible();
break;
case ':transparent':
allColonSelectorsMatch = ele.transparent();
break;
...activate = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
active = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':loop':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) === ele.data( 'target' );
break;
case ':simple':
allColonSelectorsMatch = ele.isEdge() && ele.data( 'source' ) !== ele.data( 'target' );
break;
case ':active':
allColonSelectorsMatch = ele.active();
break;
case ':inactive':
allColonSelectorsMatch = !ele.active();
break;
case ':backgrounding':
allColonSelectorsMatch = ele.backgrounding();
break;
...deselect = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
grabbable = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':removed':
allColonSelectorsMatch = ele.removed();
break;
case ':inside':
allColonSelectorsMatch = !ele.removed();
break;
case ':grabbable':
allColonSelectorsMatch = ele.grabbable();
break;
case ':ungrabbable':
allColonSelectorsMatch = !ele.grabbable();
break;
case ':animated':
allColonSelectorsMatch = ele.animated();
break;
...grabbed = function (){
var ele = this[0];
if( ele ){
return ele._private.grabbed;
}
}...
case ':hidden':
allColonSelectorsMatch = !ele.visible();
break;
case ':transparent':
allColonSelectorsMatch = ele.transparent();
break;
case ':grabbed':
allColonSelectorsMatch = ele.grabbed();
break;
case ':free':
allColonSelectorsMatch = !ele.grabbed();
break;
case ':removed':
allColonSelectorsMatch = ele.removed();
break;
...grabify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
inactive = function (){
var ele = this[0];
if( ele ){
return !ele._private.active;
}
}n/a
lock = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
locked = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':selectable':
allColonSelectorsMatch = ele.selectable();
break;
case ':unselectable':
allColonSelectorsMatch = !ele.selectable();
break;
case ':locked':
allColonSelectorsMatch = ele.locked();
break;
case ':unlocked':
allColonSelectorsMatch = !ele.locked();
break;
case ':visible':
allColonSelectorsMatch = ele.visible();
break;
...select = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}...
var elesfn = {};
function defineSwitchFunction( params ){
return function(){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
...selectable = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
case ':selected':
allColonSelectorsMatch = ele.selected();
break;
case ':unselected':
allColonSelectorsMatch = !ele.selected();
break;
case ':selectable':
allColonSelectorsMatch = ele.selectable();
break;
case ':unselectable':
allColonSelectorsMatch = !ele.selectable();
break;
case ':locked':
allColonSelectorsMatch = ele.locked();
break;
...selected = function (){
var ele = this[0];
if( ele ){
if( params.overrideField ){
var val = params.overrideField( ele );
if( val !== undefined ){
return val;
}
}
return ele._private[ params.field ];
}
}...
// check colon selectors
var allColonSelectorsMatch = true;
for( var k = 0; k < query.colonSelectors.length; k++ ){
var sel = query.colonSelectors[ k ];
switch( sel ){
case ':selected':
allColonSelectorsMatch = ele.selected();
break;
case ':unselected':
allColonSelectorsMatch = !ele.selected();
break;
case ':selectable':
allColonSelectorsMatch = ele.selectable();
break;
...selectify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
unactivate = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
ungrabify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
unlock = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
unselect = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
unselectify = function (){
var args = arguments;
var changedEles = [];
// e.g. cy.nodes().select( data, handler )
if( args.length === 2 ){
var data = args[0];
var handler = args[1];
this.on( params.event, data, handler );
}
// e.g. cy.nodes().select( handler )
else if( args.length === 1 ){
var handler = args[0];
this.on( params.event, handler );
}
// e.g. cy.nodes().select()
else if( args.length === 0 ){
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var able = !params.ableField || ele._private[ params.ableField ];
var changed = ele._private[ params.field ] != params.value;
if( params.overrideAble ){
var overrideAble = params.overrideAble( ele );
if( overrideAble !== undefined ){
able = overrideAble;
if( !overrideAble ){ return this; } // to save cycles assume not able for all on override
}
}
if( able ){
ele._private[ params.field ] = params.value;
if( changed ){
changedEles.push( ele );
}
}
}
var changedColl = this.spawn( changedEles );
changedColl.updateStyle(); // change of state => possible change of style
changedColl.trigger( params.event );
}
return this;
}n/a
debounce = function ( func, wait, options ){ // ported lodash debounce function
var util = this;
var args,
maxTimeoutId,
result,
stamp,
thisArg,
timeoutId,
trailingCall,
lastCalled = 0,
maxWait = false,
trailing = true;
if( !is.fn( func ) ){
return;
}
wait = Math.max( 0, wait ) || 0;
if( options === true ){
var leading = true;
trailing = false;
} else if( is.plainObject( options ) ){
leading = options.leading;
maxWait = 'maxWait' in options && (Math.max( wait, options.maxWait ) || 0);
trailing = 'trailing' in options ? options.trailing : trailing;
}
var delayed = function(){
var remaining = wait - (util.now() - stamp);
if( remaining <= 0 ){
if( maxTimeoutId ){
clearTimeout( maxTimeoutId );
}
var isCalled = trailingCall;
maxTimeoutId = timeoutId = trailingCall = undefined;
if( isCalled ){
lastCalled = util.now();
result = func.apply( thisArg, args );
if( !timeoutId && !maxTimeoutId ){
args = thisArg = null;
}
}
} else {
timeoutId = setTimeout( delayed, remaining );
}
};
var maxDelayed = function(){
if( timeoutId ){
clearTimeout( timeoutId );
}
maxTimeoutId = timeoutId = trailingCall = undefined;
if( trailing || (maxWait !== wait) ){
lastCalled = util.now();
result = func.apply( thisArg, args );
if( !timeoutId && !maxTimeoutId ){
args = thisArg = null;
}
}
};
return function(){
args = arguments;
stamp = util.now();
thisArg = this;
trailingCall = trailing && (timeoutId || !leading);
if( maxWait === false ){
var leadingCall = leading && !timeoutId;
} else {
if( !maxTimeoutId && !leading ){
lastCalled = stamp;
}
var remaining = maxWait - (stamp - lastCalled),
isCalled = remaining <= 0;
if( isCalled ){
if( maxTimeoutId ){
maxTimeoutId = clearTimeout( maxTimeoutId );
}
lastCalled = stamp;
result = func.apply( thisArg, args );
}
else if( !maxTimeoutId ){
maxTimeoutId = setTimeout( maxDelayed, remaining );
}
}
if( isCalled && timeoutId ){
timeoutId = clearTimeout( timeoutId );
}
else if( !timeoutId && wait !== maxWait ){
timeoutId = setTimeout( delayed, wait );
}
if( leadingCall ){
isCalled = true;
result = func.apply( thisArg, args );
}
if( isCalled && !timeoutId && !maxTimeoutId ){
args = thisArg = null;
}
return result;
};
}...
trailing = 'trailing' in options ? options.trailing : trailing;
}
options = options || {};
options.leading = leading;
options.maxWait = wait;
options.trailing = trailing;
return util.debounce( func, wait, options );
};
util.now = function(){
return Date.now();
};
util.debounce = function( func, wait, options ){ // ported lodash debounce function
...now = function (){
return Date.now();
}...
this.renderedPosition = props.renderedPosition;
this.namespace = props.namespace;
this.layout = props.layout;
this.message = props.message;
}
// Create a timestamp if incoming event doesn't have one
this.timeStamp = src && src.timeStamp || Date.now();
};
function returnFalse(){
return false;
}
function returnTrue(){
...performanceNow = function (){ return Date.now(); }n/a
requestAnimationFrame = function ( fn ){
raf( fn );
}...
var util = {};
var pnow = performance && performance.now ? function(){ return performance.now(); } : function(){ return Date.now(); };
var raf = (function(){
if( window ) {
if( window.requestAnimationFrame ){
return function( fn ){ window.requestAnimationFrame( fn ); };
} else if( window.mozRequestAnimationFrame ){
return function( fn ){ window.mozRequestAnimationFrame( fn ); };
} else if( window.webkitRequestAnimationFrame ){
return function( fn ){ window.webkitRequestAnimationFrame( fn ); };
} else if( window.msRequestAnimationFrame ){
return function( fn ){ window.msRequestAnimationFrame( fn ); };
}
...throttle = function ( func, wait, options ){
var leading = true,
trailing = true;
if( options === false ){
leading = false;
} else if( is.plainObject( options ) ){
leading = 'leading' in options ? options.leading : leading;
trailing = 'trailing' in options ? options.trailing : trailing;
}
options = options || {};
options.leading = leading;
options.maxWait = wait;
options.trailing = trailing;
return util.debounce( func, wait, options );
}n/a
closedNeighborhood = function ( selector ){
return this.neighborhood().add( this ).filter( selector );
}n/a
closedNeighbourhood = function ( selector ){
return this.neighborhood().add( this ).filter( selector );
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}n/a
components = function (){
var self = this;
var cy = self.cy();
var visited = self.spawn();
var unvisited = self.nodes().spawnSelf();
var components = [];
var visitInComponent = function( node, component ){
visited.merge( node );
unvisited.unmerge( node );
component.merge( node );
};
if( unvisited.empty() ){ return self.spawn(); }
do {
var component = cy.collection();
components.push( component );
var root = unvisited[0];
visitInComponent( root, component );
self.bfs({
directed: false,
roots: root,
visit: function( v, e, u, i, depth ){
visitInComponent( v, component );
}
} );
} while( unvisited.length > 0 );
return components.map(function( component ){
var connectedEdges = component.connectedEdges().stdFilter(function( edge ){
return component.anySame( edge.source() ) && component.anySame( edge.target() );
});
return component.union( connectedEdges );
});
}...
clientWidth: cy.width(),
clientHeight: cy.width(),
boundingBox: math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
x1: 0, y1: 0, w: cy.width(), h: cy.height()
} )
};
var components = options.eles.components();
var id2cmptId = {};
for( var i = 0; i < components.length; i++ ){
var component = components[ i ];
for( var j = 0; j < component.length; j++ ){
var node = component[ j ];
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
} else if( struct.parent !== undefined ){ // move node to new parent
var parentId = struct.parent;
var parentExists = parentId === null || cy.hasElementWithId( parentId );
if( parentExists ){
var jsons = this.jsons();
var descs = this.descendants();
var descsEtcJsons = descs.union( descs.union( this ).connectedEdges() ).jsons();
this.remove(); // NB: also removes descendants and their connected edges
for( var i = 0; i < jsons.length; i++ ){
var json = jsons[i];
var ele = this[i];
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
ele.source()[0]._private.traversalCache = null;
ele.target()[0]._private.traversalCache = null;
}
var toUpdateStyle;
if( cy_p.hasCompoundNodes ){
toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() );
} else {
toUpdateStyle = restored;
}
toUpdateStyle.updateStyle( notifyRenderer );
if( notifyRenderer ){
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
if( weighted ){
for( var j = 0; j < A[v].length; j++ ){
var w = A[v][j];
var vEle = cy.getElementById( v );
var edge;
if( vEle.edgesTo( w ).length > 0 ){
edge = vEle.edgesTo( w )[0];
} else {
edge = w.edgesTo( vEle )[0];
}
var edgeWeight = weightFn( edge );
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
var node = nodes[ i ];
dist[ node.id() ] = node.same( source ) ? 0 : Infinity;
Q.push( node );
}
var distBetween = function( u, v ){
var uvs = ( directed ? u.edgesTo( v ) : u.edgesWith( v ) ).intersect( edges );
var smallestDistance = Infinity;
var smallestEdge;
for( var i = 0; i < uvs.length; i++ ){
var edge = uvs[ i ];
var weight = weightFn( edge );
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
var defineDagAllHops = function( params ){
return function( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
...function dagExtremityImpl( selector ){
var eles = this;
var ret = [];
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
if( !ele.isNode() ){
continue;
}
var disqualified = false;
var edges = ele.connectedEdges();
for( var j = 0; j < edges.length; j++ ){
var edge = edges[j];
var src = edge.source();
var tgt = edge.target();
if(
( params.noIncomingEdges && tgt === ele && src !== ele )
|| ( params.noOutgoingEdges && src === ele && tgt !== ele )
){
disqualified = true;
break;
}
}
if( !disqualified ){
ret.push( ele );
}
}
return this.spawn( ret, { unique: true } ).filter( selector );
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
return this.intersect( collection ).length > 0;
},
allAreNeighbors: function( collection ){
collection = this.cy().collection( collection );
return this.neighborhood().intersect( collection ).length === collection.length;
}
});
elesfn.allAreNeighbours = elesfn.allAreNeighbors;
module.exports = elesfn;
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}n/a
openNeighborhood = function ( selector ){
return this.neighborhood( selector );
}...
for( var i = 0; i < V.length; i++ ){
var v = V[ i ];
var vid = v.id();
if( directed ){
A[ vid ] = v.outgoers().nodes(); // get outgoers of every node
} else {
A[ vid ] = v.openNeighborhood().nodes(); // get neighbors of every node
}
C.set( vid, 0 );
}
for( var s = 0; s < V.length; s++ ){
var sid = V[s].id();
...openNeighbourhood = function ( selector ){
return this.neighborhood( selector );
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
var defineDagAllHops = function( params ){
return function( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
this.recalculateRenderedStyle( opts.useCache );
}
for( var i = 0; i < eles.length; i++ ){
var ele = eles[i];
if( styleEnabled && ele.isEdge() && ele.pstyle('curve-style').strValue === 'bezier' ){
ele.parallelEdges().recalculateRenderedStyle( opts.useCache ); // n.b. ele.parallelEdges
() single is cached
}
updateBoundsFromBox( bounds, cachedBoundingBoxImpl( ele, opts ) );
}
bounds.x1 = noninf( bounds.x1 );
bounds.y1 = noninf( bounds.y1 );
...predecessors = function ( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
if( !sElesIds[ nid ] ){
sElesIds[ nid ] = true;
sEles.push( n );
newNext = true;
}
}
if( !newNext ){ break; } // done if touched all outgoers already
eles = next;
}
return this.spawn( sEles, { unique: true } ).filter( selector );
}n/a
function dagExtremityImpl( selector ){
var eles = this;
var ret = [];
for( var i = 0; i < eles.length; i++ ){
var ele = eles[ i ];
if( !ele.isNode() ){
continue;
}
var disqualified = false;
var edges = ele.connectedEdges();
for( var j = 0; j < edges.length; j++ ){
var edge = edges[j];
var src = edge.source();
var tgt = edge.target();
if(
( params.noIncomingEdges && tgt === ele && src !== ele )
|| ( params.noOutgoingEdges && src === ele && tgt !== ele )
){
disqualified = true;
break;
}
}
if( !disqualified ){
ret.push( ele );
}
}
return this.spawn( ret, { unique: true } ).filter( selector );
}...
roots = cy.collection( rootsArray );
} else if( is.string( options.roots ) ){
roots = cy.$( options.roots );
} else {
if( options.directed ){
roots = nodes.roots();
} else {
var components = [];
var unhandledNodes = nodes;
while( unhandledNodes.length > 0 ){
var currComp = cy.collection();
...function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
return;
}
};
}
util.extend( elesfn, {
degree: defineDegreeFunction( function( node, edge ){
if( edge.source().same( edge.target() ) ){
return 2;
} else {
return 1;
}
} ),
indegree: defineDegreeFunction( function( node, edge ){
...function sourceImpl( selector ){
var sources = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var src = ele._private[ params.attr ];
if( src ){
sources.push( src );
}
}
return this.spawn( sources, { unique: true } ).filter( selector );
}n/a
successors = function ( selector ){
var eles = this;
var sEles = [];
var sElesIds = {};
for( ;; ){
var next = params.outgoing ? eles.outgoers() : eles.incomers();
if( next.length === 0 ){ break; } // done if none left
var newNext = false;
for( var i = 0; i < next.length; i++ ){
var n = next[ i ];
var nid = n.id();
if( !sElesIds[ nid ] ){
sElesIds[ nid ] = true;
sEles.push( n );
newNext = true;
}
}
if( !newNext ){ break; } // done if touched all outgoers already
eles = next;
}
return this.spawn( sEles, { unique: true } ).filter( selector );
}n/a
function traversalCache( arg1, arg2, arg3, arg4 ){
var selectorOrEles = arg1;
var eles = this;
var key;
if( selectorOrEles == null ){
key = 'null';
} else if( is.elementOrCollection( selectorOrEles ) && selectorOrEles.length === 1 ){
key = '#' + selectorOrEles.id();
}
if( eles.length === 1 && key ){
var _p = eles[0]._private;
var tch = _p.traversalCache = _p.traversalCache || {};
var ch = tch[ name ] = tch[ name ] || {};
var cacheHit = ch[ key ];
if( cacheHit ){
return cacheHit;
} else {
return ( ch[ key ] = fn.call( eles, arg1, arg2, arg3, arg4 ) );
}
} else {
return fn.call( eles, arg1, arg2, arg3, arg4 );
}
}...
return;
}
};
}
util.extend( elesfn, {
degree: defineDegreeFunction( function( node, edge ){
if( edge.source().same( edge.target() ) ){
return 2;
} else {
return 1;
}
} ),
indegree: defineDegreeFunction( function( node, edge ){
...function sourceImpl( selector ){
var sources = [];
for( var i = 0; i < this.length; i++ ){
var ele = this[ i ];
var src = ele._private[ params.attr ];
if( src ){
sources.push( src );
}
}
return this.spawn( sources, { unique: true } ).filter( selector );
}n/a
viewport = function ( opts ){
var _p = this._private;
var zoomDefd = true;
var panDefd = true;
var events = []; // to trigger
var zoomFailed = false;
var panFailed = false;
if( !opts ){ return this; }
if( !is.number( opts.zoom ) ){ zoomDefd = false; }
if( !is.plainObject( opts.pan ) ){ panDefd = false; }
if( !zoomDefd && !panDefd ){ return this; }
if( zoomDefd ){
var z = opts.zoom;
if( z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled ){
zoomFailed = true;
} else {
_p.zoom = z;
events.push( 'zoom' );
}
}
if( panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled ){
var p = opts.pan;
if( is.number( p.x ) ){
_p.pan.x = p.x;
panFailed = false;
}
if( is.number( p.y ) ){
_p.pan.y = p.y;
panFailed = false;
}
if( !panFailed ){
events.push( 'pan' );
}
}
if( events.length > 0 ){
events.push( 'viewport' );
this.trigger( events.join( ' ' ) );
this.notify( {
type: 'viewport'
} );
}
return this; // chaining
}...
},
reset: function(){
if( !this._private.panningEnabled || !this._private.zoomingEnabled ){
return this;
}
this.viewport( {
pan: { x: 0, y: 0 },
zoom: 1
} );
return this; // chaining
},
...autolock = function ( bool ){
if( bool !== undefined ){
this._private.autolock = bool ? true : false;
} else {
return this._private.autolock;
}
return this; // chaining
}...
value: false
} );
}
defineSwitchSet( {
field: 'locked',
overrideField: function( ele ){
return ele.cy().autolock() ? true : undefined;
},
on: 'lock',
off: 'unlock'
} );
defineSwitchSet( {
field: 'grabbable',
...autolockNodes = function ( bool ){
if( bool !== undefined ){
this._private.autolock = bool ? true : false;
} else {
return this._private.autolock;
}
return this; // chaining
}n/a
autoungrabify = function ( bool ){
if( bool !== undefined ){
this._private.autoungrabify = bool ? true : false;
} else {
return this._private.autoungrabify;
}
return this; // chaining
}...
on: 'lock',
off: 'unlock'
} );
defineSwitchSet( {
field: 'grabbable',
overrideField: function( ele ){
return ele.cy().autoungrabify() ? false : undefined;
},
on: 'grabify',
off: 'ungrabify'
} );
defineSwitchSet( {
field: 'selected',
...autoungrabifyNodes = function ( bool ){
if( bool !== undefined ){
this._private.autoungrabify = bool ? true : false;
} else {
return this._private.autoungrabify;
}
return this; // chaining
}n/a
autounselectify = function ( bool ){
if( bool !== undefined ){
this._private.autounselectify = bool ? true : false;
} else {
return this._private.autounselectify;
}
return this; // chaining
}...
off: 'ungrabify'
} );
defineSwitchSet( {
field: 'selected',
ableField: 'selectable',
overrideAble: function( ele ){
return ele.cy().autounselectify() ? false : undefined;
},
on: 'select',
off: 'unselect'
} );
defineSwitchSet( {
field: 'selectable',
...boxSelectionEnabled = function ( bool ){
if( bool !== undefined ){
this._private.boxSelectionEnabled = bool ? true : false;
} else {
return this._private.boxSelectionEnabled;
}
return this; // chaining
}n/a
center = function ( elements ){
var pan = this.getCenterPan( elements );
if( pan ){
this._private.pan = pan;
this.trigger( 'pan viewport' );
this.notify( { // notify the renderer that the viewport changed
type: 'viewport'
} );
}
return this; // chaining
}n/a
centre = function ( elements ){
var pan = this.getCenterPan( elements );
if( pan ){
this._private.pan = pan;
this.trigger( 'pan viewport' );
this.notify( { // notify the renderer that the viewport changed
type: 'viewport'
} );
}
return this; // chaining
}n/a
extent = function (){
var pan = this._private.pan;
var zoom = this._private.zoom;
var rb = this.renderedExtent();
var b = {
x1: ( rb.x1 - pan.x ) / zoom,
x2: ( rb.x2 - pan.x ) / zoom,
y1: ( rb.y1 - pan.y ) / zoom,
y2: ( rb.y2 - pan.y ) / zoom
};
b.w = b.x2 - b.x1;
b.h = b.y2 - b.y1;
return b;
}n/a
fit = function ( elements, padding ){
var viewportState = this.getFitViewport( elements, padding );
if( viewportState ){
var _p = this._private;
_p.zoom = viewportState.zoom;
_p.pan = viewportState.pan;
this.trigger( 'pan zoom viewport' );
this.notify( { // notify the renderer that the viewport changed
type: 'viewport'
} );
}
return this; // chaining
}...
ani.play();
}
var onStep;
cy.on( 'step.*', ( onStep = function(){
if( options.fit ){
cy.fit( options.eles, options.padding );
}
}) );
layout.one('layoutstop', function(){
cy.off('step.*', onStep);
});
...getCenterPan = function ( elements, zoom ){
if( !this._private.panningEnabled ){
return;
}
if( is.string( elements ) ){
var selector = elements;
elements = this.mutableElements().filter( selector );
} else if( !is.elementOrCollection( elements ) ){
elements = this.mutableElements();
}
var bb = elements.boundingBox();
var w = this.width();
var h = this.height();
zoom = zoom === undefined ? this._private.zoom : zoom;
var pan = { // middle
x: (w - zoom * ( bb.x1 + bb.x2 )) / 2,
y: (h - zoom * ( bb.y1 + bb.y2 )) / 2
};
return pan;
}...
y: cyPan.y + panBy.y
};
}
// override pan w/ center if set
var center = properties.center || properties.centre;
if( center && isCore ){
var centerPan = cy.getCenterPan( center.eles, properties.zoom );
if( centerPan ){
properties.pan = centerPan;
}
}
// override pan & zoom w/ fit if set
...getFitViewport = function ( elements, padding ){
if( is.number( elements ) && padding === undefined ){ // elements is optional
padding = elements;
elements = undefined;
}
if( !this._private.panningEnabled || !this._private.zoomingEnabled ){
return;
}
var bb;
if( is.string( elements ) ){
var sel = elements;
elements = this.$( sel );
} else if( is.boundingBox( elements ) ){ // assume bb
var bbe = elements;
bb = {
x1: bbe.x1,
y1: bbe.y1,
x2: bbe.x2,
y2: bbe.y2
};
bb.w = bb.x2 - bb.x1;
bb.h = bb.y2 - bb.y1;
} else if( !is.elementOrCollection( elements ) ){
elements = this.mutableElements();
}
bb = bb || elements.boundingBox();
var w = this.width();
var h = this.height();
var zoom;
padding = is.number( padding ) ? padding : 0;
if( !isNaN( w ) && !isNaN( h ) && w > 0 && h > 0 && !isNaN( bb.w ) && !isNaN( bb.h ) && bb.w > 0 && bb.h > 0 ){
zoom = Math.min( (w - 2 * padding) / bb.w, (h - 2 * padding) / bb.h );
// crop zoom
zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;
zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;
var pan = { // now pan to middle
x: (w - zoom * ( bb.x1 + bb.x2 )) / 2,
y: (h - zoom * ( bb.y1 + bb.y2 )) / 2
};
return {
zoom: zoom,
pan: pan
};
}
return;
}...
properties.pan = centerPan;
}
}
// override pan & zoom w/ fit if set
if( properties.fit && isCore ){
var fit = properties.fit;
var fitVp = cy.getFitViewport( fit.eles || fit.boundingBox, fit.padding );
if( fitVp ){
properties.pan = fitVp.pan;
properties.zoom = fitVp.zoom;
}
}
...height = function (){
return this.size().height;
}...
};
}
var eleTakesUpSpace = function( ele ){
return (
ele.pstyle( 'display' ).value === 'element'
&& ele.width() !== 0
&& ( ele.isNode() ? ele.height() !== 0 : true )
);
};
elesfn.takesUpSpace = defineDerivedStateFunction({
ok: eleTakesUpSpace
});
...invalidateSize = function (){
this._private.sizeCache = null;
}...
type: 'draw'
} );
return this;
},
resize: function(){
this.invalidateSize();
this.notify( {
type: 'resize'
} );
this.trigger( 'resize' );
...maxZoom = function ( zoom ){
if( zoom === undefined ){
return this._private.maxZoom;
} else if( is.number( zoom ) ){
this._private.maxZoom = zoom;
}
return this;
}n/a
minZoom = function ( zoom ){
if( zoom === undefined ){
return this._private.minZoom;
} else if( is.number( zoom ) ){
this._private.minZoom = zoom;
}
return this;
}n/a
pan = function (){
var args = arguments;
var pan = this._private.pan;
var dim, val, dims, x, y;
switch( args.length ){
case 0: // .pan()
return pan;
case 1:
if( is.string( args[0] ) ){ // .pan('x')
dim = args[0];
return pan[ dim ];
} else if( is.plainObject( args[0] ) ){ // .pan({ x: 0, y: 100 })
if( !this._private.panningEnabled ){
return this;
}
dims = args[0];
x = dims.x;
y = dims.y;
if( is.number( x ) ){
pan.x = x;
}
if( is.number( y ) ){
pan.y = y;
}
this.trigger( 'pan viewport' );
}
break;
case 2: // .pan('x', 100)
if( !this._private.panningEnabled ){
return this;
}
dim = args[0];
val = args[1];
if( (dim === 'x' || dim === 'y') && is.number( val ) ){
pan[ dim ] = val;
}
this.trigger( 'pan viewport' );
break;
default:
break; // invalid
}
this.notify( { // notify the renderer that the viewport changed
type: 'viewport'
} );
return this; // chaining
}...
evt.layout = triggerer;
}
// create a rendered position based on the passed position
if( evt.position ){
var pos = evt.position;
var zoom = cy.zoom();
var pan = cy.pan();
evt.renderedPosition = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
}
...panBy = function ( params ){
var args = arguments;
var pan = this._private.pan;
var dim, val, dims, x, y;
if( !this._private.panningEnabled ){
return this;
}
switch( args.length ){
case 1:
if( is.plainObject( args[0] ) ){ // .panBy({ x: 0, y: 100 })
dims = args[0];
x = dims.x;
y = dims.y;
if( is.number( x ) ){
pan.x += x;
}
if( is.number( y ) ){
pan.y += y;
}
this.trigger( 'pan viewport' );
}
break;
case 2: // .panBy('x', 100)
dim = args[0];
val = args[1];
if( (dim === 'x' || dim === 'y') && is.number( val ) ){
pan[ dim ] += val;
}
this.trigger( 'pan viewport' );
break;
default:
break; // invalid
}
this.notify( { // notify the renderer that the viewport changed
type: 'viewport'
} );
return this; // chaining
}...
if( !this._private.panningEnabled ){
return this;
}
switch( args.length ){
case 1:
if( is.plainObject( args[0] ) ){ // .panBy({ x: 0, y: 100 })
dims = args[0];
x = dims.x;
y = dims.y;
if( is.number( x ) ){
pan.x += x;
}
...panningEnabled = function ( bool ){
if( bool !== undefined ){
this._private.panningEnabled = bool ? true : false;
} else {
return this._private.panningEnabled;
}
return this; // chaining
}n/a
renderedExtent = function (){
var width = this.width();
var height = this.height();
return {
x1: 0,
y1: 0,
x2: width,
y2: height,
w: width,
h: height
};
}...
height: function(){
return this.size().height;
},
extent: function(){
var pan = this._private.pan;
var zoom = this._private.zoom;
var rb = this.renderedExtent();
var b = {
x1: ( rb.x1 - pan.x ) / zoom,
x2: ( rb.x2 - pan.x ) / zoom,
y1: ( rb.y1 - pan.y ) / zoom,
y2: ( rb.y2 - pan.y ) / zoom
};
...reset = function (){
if( !this._private.panningEnabled || !this._private.zoomingEnabled ){
return this;
}
this.viewport( {
pan: { x: 0, y: 0 },
zoom: 1
} );
return this; // chaining
}n/a
size = function (){
var _p = this._private;
var container = _p.container;
return ( _p.sizeCache = _p.sizeCache || ( container ? (function(){
var rect = container.getBoundingClientRect();
var style = window.getComputedStyle( container );
var val = function( name ){ return parseFloat( style.getPropertyValue( name ) ); };
return {
width: rect.width - val('padding-left') - val('padding-right') - val('border-left-width') - val('border-right-width'),
height: rect.height - val('padding-top') - val('padding-bottom') - val('border-top-width') - val('border-bottom-width')
};
})() : { // fallback if no container (not 0 b/c can be used for dividing etc)
width: 1,
height: 1
} ) );
}...
if( !matchesAny ){
return false;
}
}
// check filter function
if( query.filter != null && ele.collection().filter( query.filter ).size() ===
0 ){
return false;
}
// check parent/child relations
var confirmRelations = function( query, eles ){
if( query != null ){
var matches = false;
...userPanningEnabled = function ( bool ){
if( bool !== undefined ){
this._private.userPanningEnabled = bool ? true : false;
} else {
return this._private.userPanningEnabled;
}
return this; // chaining
}n/a
userZoomingEnabled = function ( bool ){
if( bool !== undefined ){
this._private.userZoomingEnabled = bool ? true : false;
} else {
return this._private.userZoomingEnabled;
}
return this; // chaining
}n/a
width = function (){
return this.size().width;
}...
}
};
}
var eleTakesUpSpace = function( ele ){
return (
ele.pstyle( 'display' ).value === 'element'
&& ele.width() !== 0
&& ( ele.isNode() ? ele.height() !== 0 : true )
);
};
elesfn.takesUpSpace = defineDerivedStateFunction({
ok: eleTakesUpSpace
});
...zoom = function ( params ){
var pos; // in rendered px
var zoom;
if( params === undefined ){ // then get the zoom
return this._private.zoom;
} else if( is.number( params ) ){ // then set the zoom
zoom = params;
} else if( is.plainObject( params ) ){ // then zoom about a point
zoom = params.level;
if( params.position ){
var p = params.position;
var pan = this._private.pan;
var z = this._private.zoom;
pos = { // convert to rendered px
x: p.x * z + pan.x,
y: p.y * z + pan.y
};
} else if( params.renderedPosition ){
pos = params.renderedPosition;
}
if( pos && !this._private.panningEnabled ){
return this; // panning disabled
}
}
if( !this._private.zoomingEnabled ){
return this; // zooming disabled
}
if( !is.number( zoom ) || ( pos && (!is.number( pos.x ) || !is.number( pos.y )) ) ){
return this; // can't zoom with invalid params
}
// crop zoom
zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;
zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;
if( pos ){ // set zoom about position
var pan1 = this._private.pan;
var zoom1 = this._private.zoom;
var zoom2 = zoom;
var pan2 = {
x: -zoom2 / zoom1 * (pos.x - pan1.x) + pos.x,
y: -zoom2 / zoom1 * (pos.y - pan1.y) + pos.y
};
this._private.zoom = zoom;
this._private.pan = pan2;
var posChanged = pan1.x !== pan2.x || pan1.y !== pan2.y;
this.trigger( ' zoom ' + (posChanged ? ' pan ' : '') + ' viewport ' );
} else { // just set the zoom
this._private.zoom = zoom;
this.trigger( 'zoom viewport' );
}
this.notify( { // notify the renderer that the viewport changed
type: 'viewport'
} );
return this; // chaining
}...
if( params.layout ){
evt.layout = triggerer;
}
// create a rendered position based on the passed position
if( evt.position ){
var pos = evt.position;
var zoom = cy.zoom();
var pan = cy.pan();
evt.renderedPosition = {
x: pos.x * zoom + pan.x,
y: pos.y * zoom + pan.y
};
}
...zoomingEnabled = function ( bool ){
if( bool !== undefined ){
this._private.zoomingEnabled = bool ? true : false;
} else {
return this._private.zoomingEnabled;
}
return this; // chaining
}n/a