File size: 4,867 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import * as util from '../util';
import * as is from '../is';
import Set from '../set';
// represents a node or an edge
let Element = function( cy, params, restore = true ){
if( cy === undefined || params === undefined || !is.core( cy ) ){
util.error( 'An element must have a core reference and parameters set' );
return;
}
let 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()
let _p = this._private = {
cy: cy,
single: true, // indicates this is an element
data: params.data || {}, // data object
position: params.position || { x: 0, y: 0 }, // (x, y) position pair
autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value
autoHeight: undefined,
autoPadding: undefined,
compoundBoundsClean: false, // whether the compound dimensions need to be recalculated the next time dimensions are read
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
styleKeys: {}, // per-group keys of style property values
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
pannable: params.pannable === undefined ? (group === 'edges' ? true : false) : ( params.pannable ? true : false ), // whether the element has passthrough panning enabled
active: false, // whether the element is active from user interaction
classes: new Set(), // 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
parent: params.parent && params.parent.isNode() ? params.parent : null, // parent ref
traversalCache: {}, // cache of output of traversal functions
backgrounding: false, // whether background images are loading
bbCache: null, // cache of the current bounding box
bbCacheShift: { x: 0, y: 0 }, // shift applied to cached bb to be applied on next get
bodyBounds: null, // bounds cache of element body, w/o overlay
overlayBounds: null, // bounds cache of element body, including overlay
labelBounds: { // bounds cache of labels
all: null,
source: null,
target: null,
main: null
},
arrowBounds: { // bounds cache of edge arrows
source: null,
target: null,
'mid-source': null,
'mid-target': null
}
};
if( _p.position.x == null ){ _p.position.x = 0; }
if( _p.position.y == null ){ _p.position.y = 0; }
// renderedPosition overrides if specified
if( params.renderedPosition ){
let rpos = params.renderedPosition;
let pan = cy.pan();
let zoom = cy.zoom();
_p.position = {
x: (rpos.x - pan.x) / zoom,
y: (rpos.y - pan.y) / zoom
};
}
let classes = [];
if( is.array( params.classes ) ){
classes = params.classes;
} else if( is.string( params.classes ) ){
classes = params.classes.split( /\s+/ );
}
for( let i = 0, l = classes.length; i < l; i++ ){
let cls = classes[ i ];
if( !cls || cls === '' ){ continue; }
_p.classes.add(cls);
}
this.createEmitter();
let bypass = params.style || params.css;
if( bypass ){
util.warn('Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead.');
this.style(bypass);
}
if( restore === undefined || restore ){
this.restore();
}
};
export default Element;
|