cytoscape-edgehandles
Advanced tools
Comparing version 3.2.4 to 3.3.0
(function webpackUniversalModuleDefinition(root, factory) { | ||
if(typeof exports === 'object' && typeof module === 'object') | ||
module.exports = factory(); | ||
module.exports = factory(require("lodash.memoize"), require("lodash.throttle")); | ||
else if(typeof define === 'function' && define.amd) | ||
define([], factory); | ||
define(["lodash.memoize", "lodash.throttle"], factory); | ||
else if(typeof exports === 'object') | ||
exports["cytoscapeEdgehandles"] = factory(); | ||
exports["cytoscapeEdgehandles"] = factory(require("lodash.memoize"), require("lodash.throttle")); | ||
else | ||
root["cytoscapeEdgehandles"] = factory(); | ||
})(this, function() { | ||
root["cytoscapeEdgehandles"] = factory(root["_"]["memoize"], root["_"]["throttle"]); | ||
})(this, function(__WEBPACK_EXTERNAL_MODULE_13__, __WEBPACK_EXTERNAL_MODULE_14__) { | ||
return /******/ (function(modules) { // webpackBootstrap | ||
@@ -76,3 +76,3 @@ /******/ // The module cache | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(__webpack_require__.s = 11); | ||
/******/ return __webpack_require__(__webpack_require__.s = 12); | ||
/******/ }) | ||
@@ -110,3 +110,3 @@ /************************************************************************/ | ||
var Edgehandles = __webpack_require__(9); | ||
var Edgehandles = __webpack_require__(10); | ||
var assign = __webpack_require__(0); | ||
@@ -164,3 +164,4 @@ | ||
var cy = this.cy; | ||
var cy = this.cy, | ||
options = this.options; | ||
@@ -224,3 +225,7 @@ // grabbing nodes | ||
this.addListener(cy, 'tapdragout', 'node', function (e) { | ||
_this.unpreview(e.target); | ||
if (options.snap && e.target.same(_this.targetNode)) { | ||
// then keep the preview | ||
} else { | ||
_this.unpreview(e.target); | ||
} | ||
}); | ||
@@ -257,2 +262,6 @@ | ||
handleNodes: 'node', // selector/filter function for whether edges can be made from a given node | ||
snap: false, // when enabled, the edge can be drawn by just moving close to a target node (can be confusing on compound graphs) | ||
snapThreshold: 50, // the target node must be less than or equal to this many pixels away from the cursor/finger | ||
snapFrequency: 15, // the number of times per second (Hz) that snap checks done (lower is less expensive) | ||
noEdgeEventsInDraw: false, // set events:no to edges during draws, prevents mouseouts on compounds | ||
handlePosition: function handlePosition(node) { | ||
@@ -429,3 +438,3 @@ return 'middle top'; // sets the position of the handle in the format of "X-AXIS Y-AXIS" such as "left top", "middle top" | ||
if (!preview && options.preview) { | ||
previewEles.removeClass('eh-preview'); | ||
previewEles.removeClass('eh-preview').style('events', ''); | ||
@@ -456,3 +465,4 @@ this.emit('complete', this.mp(), source, target, previewEles); | ||
group: 'nodes', | ||
position: p | ||
position: p, | ||
style: { 'events': 'no' } | ||
}, options.nodeParams(source, target)), classes)); | ||
@@ -465,3 +475,4 @@ | ||
target: interNode.id() | ||
} | ||
}, | ||
style: { 'events': 'no' } | ||
}, options.edgeParams(source, target, 0)), classes)); | ||
@@ -474,3 +485,4 @@ | ||
target: target.id() | ||
} | ||
}, | ||
style: { 'events': 'no' } | ||
}, options.edgeParams(source, target, 1)), classes)); | ||
@@ -486,3 +498,4 @@ | ||
target: target.id() | ||
} | ||
}, | ||
style: { 'events': 'no' } | ||
}, options.edgeParams(source, target, 0)), classes)); | ||
@@ -665,2 +678,27 @@ | ||
function disableEdgeEvents() { | ||
if (this.options.noEdgeEventsInDraw) { | ||
this.cy.edges().style('events', 'no'); | ||
} | ||
return this; | ||
} | ||
function enableEdgeEvents() { | ||
if (this.options.noEdgeEventsInDraw) { | ||
this.cy.edges().style('events', ''); | ||
} | ||
return this; | ||
} | ||
module.exports = { disableEdgeEvents: disableEdgeEvents, enableEdgeEvents: enableEdgeEvents }; | ||
/***/ }), | ||
/* 8 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
function enable() { | ||
@@ -685,3 +723,3 @@ this.enabled = true; | ||
/***/ }), | ||
/* 8 */ | ||
/* 9 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
@@ -692,2 +730,4 @@ | ||
var memoize = __webpack_require__(13); | ||
function canStartOn(node) { | ||
@@ -768,2 +808,3 @@ var options = this.options, | ||
this.disableGestures(); | ||
this.disableEdgeEvents(); | ||
@@ -784,2 +825,3 @@ this.emit('start', this.hp(), node); | ||
this.updateEdge(); | ||
this.throttledSnap(); | ||
@@ -789,8 +831,60 @@ return this; | ||
function snap() { | ||
if (!this.active || !this.options.snap) { | ||
return false; | ||
} | ||
var cy = this.cy; | ||
var tgt = this.targetNode; | ||
var threshold = this.options.snapThreshold; | ||
var sqThreshold = function sqThreshold(n) { | ||
var r = getRadius(n);var t = r + threshold;return t * t; | ||
}; | ||
var mousePos = this.mp(); | ||
var sqDist = function sqDist(p1, p2) { | ||
return (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y); | ||
}; | ||
var getRadius = function getRadius(n) { | ||
return (n.outerWidth() + n.outerHeight()) / 4; | ||
}; | ||
var nodeSqDist = memoize(function (n) { | ||
return sqDist(n.position(), mousePos); | ||
}, function (n) { | ||
return n.id(); | ||
}); | ||
var isWithinTheshold = function isWithinTheshold(n) { | ||
return nodeSqDist(n) <= sqThreshold(n); | ||
}; | ||
var cmpSqDist = function cmpSqDist(n1, n2) { | ||
return nodeSqDist(n1) - nodeSqDist(n2); | ||
}; | ||
var allowHoverDelay = false; | ||
var nodesByDist = cy.nodes(isWithinTheshold).sort(cmpSqDist); | ||
var snapped = false; | ||
if (tgt.nonempty() && !isWithinTheshold(tgt)) { | ||
this.unpreview(tgt); | ||
} | ||
for (var i = 0; i < nodesByDist.length; i++) { | ||
var n = nodesByDist[i]; | ||
if (n.same(tgt) || this.preview(n, allowHoverDelay)) { | ||
snapped = true; | ||
break; | ||
} | ||
} | ||
return snapped; | ||
} | ||
function preview(target) { | ||
var _this = this; | ||
var allowHoverDelay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
var options = this.options, | ||
sourceNode = this.sourceNode, | ||
ghostNode = this.ghostNode, | ||
ghostEles = this.ghostEles, | ||
presumptiveTargets = this.presumptiveTargets, | ||
@@ -806,31 +900,44 @@ previewEles = this.previewEles, | ||
var isHandle = target.same(this.handleNode); | ||
var isExistingTgt = target.same(this.targetNode); | ||
if (!active || isHandle || isGhost || noEdge) { | ||
return; | ||
if (!active || isHandle || isGhost || noEdge || isExistingTgt || isLoop && !loopAllowed) { | ||
return false; | ||
} | ||
if (this.targetNode.nonempty()) { | ||
this.unpreview(this.targetNode); | ||
} | ||
clearTimeout(this.previewTimeout); | ||
this.previewTimeout = setTimeout(function () { | ||
var applyPreview = function applyPreview() { | ||
_this.targetNode = target; | ||
presumptiveTargets.merge(target); | ||
target.addClass('eh-presumptive-target'); | ||
target.addClass('eh-target'); | ||
if (!isLoop || isLoop && loopAllowed) { | ||
target.addClass('eh-target'); | ||
_this.emit('hoverover', _this.mp(), source, target); | ||
_this.emit('hoverover', _this.mp(), source, target); | ||
if (options.preview) { | ||
target.addClass('eh-preview'); | ||
if (options.preview) { | ||
target.addClass('eh-preview'); | ||
ghostEles.addClass('eh-preview-active'); | ||
sourceNode.addClass('eh-preview-active'); | ||
target.addClass('eh-preview-active'); | ||
_this.makePreview(); | ||
_this.makePreview(); | ||
_this.emit('previewon', _this.mp(), source, target, previewEles); | ||
} | ||
_this.emit('previewon', _this.mp(), source, target, previewEles); | ||
} | ||
}, options.hoverDelay); | ||
}; | ||
return this; | ||
if (allowHoverDelay && options.hoverDelay > 0) { | ||
this.previewTimeout = setTimeout(applyPreview, options.hoverDelay); | ||
} else { | ||
applyPreview(); | ||
} | ||
return true; | ||
} | ||
@@ -846,2 +953,3 @@ | ||
previewEles = this.previewEles, | ||
ghostEles = this.ghostEles, | ||
cy = this.cy; | ||
@@ -854,3 +962,5 @@ | ||
target.removeClass('eh-preview eh-target eh-presumptive-target'); | ||
target.removeClass('eh-preview eh-target eh-presumptive-target eh-preview-active'); | ||
ghostEles.removeClass('eh-preview-active'); | ||
sourceNode.removeClass('eh-preview-active'); | ||
@@ -893,2 +1003,3 @@ this.targetNode = cy.collection(); | ||
this.resetGestures(); | ||
this.enableEdgeEvents(); | ||
@@ -903,3 +1014,3 @@ this.active = false; | ||
module.exports = { | ||
show: show, hide: hide, start: start, update: update, preview: preview, unpreview: unpreview, stop: stop, | ||
show: show, hide: hide, start: start, update: update, preview: preview, unpreview: unpreview, stop: stop, snap: snap, | ||
canStartOn: canStartOn, canStartDrawModeOn: canStartDrawModeOn, canStartNonDrawModeOn: canStartNonDrawModeOn | ||
@@ -909,3 +1020,3 @@ }; | ||
/***/ }), | ||
/* 9 */ | ||
/* 10 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
@@ -918,2 +1029,3 @@ | ||
var assign = __webpack_require__(0); | ||
var throttle = __webpack_require__(14); | ||
@@ -924,5 +1036,6 @@ var cyGesturesToggle = __webpack_require__(2); | ||
var drawing = __webpack_require__(6); | ||
var enabling = __webpack_require__(7); | ||
var gestureLifecycle = __webpack_require__(8); | ||
var listeners = __webpack_require__(10); | ||
var enabling = __webpack_require__(8); | ||
var gestureLifecycle = __webpack_require__(9); | ||
var listeners = __webpack_require__(11); | ||
var edgeEvents = __webpack_require__(7); | ||
@@ -958,2 +1071,4 @@ function Edgehandles(options) { | ||
this.addListeners(); | ||
this.throttledSnap = throttle(this.snap.bind(this), 1000 / options.snapFrequency); | ||
} | ||
@@ -994,3 +1109,3 @@ | ||
[cyGesturesToggle, cyListeners, drawMode, drawing, enabling, gestureLifecycle, listeners].forEach(extend); | ||
[cyGesturesToggle, cyListeners, drawMode, drawing, enabling, gestureLifecycle, listeners, edgeEvents].forEach(extend); | ||
@@ -1000,3 +1115,3 @@ module.exports = Edgehandles; | ||
/***/ }), | ||
/* 10 */ | ||
/* 11 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
@@ -1115,3 +1230,3 @@ | ||
/***/ }), | ||
/* 11 */ | ||
/* 12 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
@@ -1140,4 +1255,16 @@ | ||
/***/ }), | ||
/* 13 */ | ||
/***/ (function(module, exports) { | ||
module.exports = __WEBPACK_EXTERNAL_MODULE_13__; | ||
/***/ }), | ||
/* 14 */ | ||
/***/ (function(module, exports) { | ||
module.exports = __WEBPACK_EXTERNAL_MODULE_14__; | ||
/***/ }) | ||
/******/ ]); | ||
}); |
{ | ||
"name": "cytoscape-edgehandles", | ||
"version": "3.2.4", | ||
"version": "3.3.0", | ||
"description": "Edge creation UI extension for Cytoscape", | ||
@@ -13,3 +13,3 @@ "main": "cytoscape-edgehandles.js", | ||
"gh-pages:demo": "cpy demo.html . --rename=index.html", | ||
"gh-pages:deploy": "gh-pages -d .", | ||
"gh-pages:deploy": "gh-pages -d . -v node_modules/**", | ||
"gh-pages:cleanup": "rimraf index.html", | ||
@@ -58,3 +58,7 @@ "copyright": "update license", | ||
"cytoscape": "^3.2.0" | ||
}, | ||
"dependencies": { | ||
"lodash.memoize": "^4.1.2", | ||
"lodash.throttle": "^4.1.1" | ||
} | ||
} |
@@ -11,3 +11,3 @@ cytoscape-edgehandles | ||
This extension creates handles on nodes that can be dragged to create edges between nodes ([demo](https://cytoscape.github.io/cytoscape.js-edgehandles/)) | ||
This extension creates handles on nodes that can be dragged to create edges between nodes ([demo](https://cytoscape.github.io/cytoscape.js-edgehandles/), [snapping demo](https://cytoscape.github.io/cytoscape.js-edgehandles/demo-snap.html), [compound demo](https://cytoscape.github.io/cytoscape.js-edgehandles/demo-compound.html)) | ||
@@ -75,2 +75,6 @@ | ||
handleNodes: 'node', // selector/filter function for whether edges can be made from a given node | ||
snap: false, // when enabled, the edge can be drawn by just moving close to a target node (can be confusing on compound graphs) | ||
snapThreshold: 50, // the target node must be less than or equal to this many pixels away from the cursor/finger | ||
snapFrequency: 15, // the number of times per second (Hz) that snap checks done (lower is less expensive) | ||
noEdgeEventsInDraw: false, // set events:no to edges during draws, prevents mouseouts on compounds | ||
handlePosition: function( node ){ | ||
@@ -169,2 +173,3 @@ return 'middle top'; // sets the position of the handle in the format of "X-AXIS Y-AXIS" such as "left top", "middle top" | ||
* `eh-presumptive-target` : A node that, during an edge drag, may become a target when released | ||
* `eh-preview-active` : Applied to the source, target, and ghost edge when the preview is active | ||
@@ -171,0 +176,0 @@ |
function addCytoscapeListeners(){ | ||
let { cy } = this; | ||
let { cy, options } = this; | ||
@@ -56,3 +56,7 @@ // grabbing nodes | ||
this.addListener( cy, 'tapdragout', 'node', e => { | ||
this.unpreview( e.target ); | ||
if( options.snap && e.target.same(this.targetNode) ){ | ||
// then keep the preview | ||
} else { | ||
this.unpreview( e.target ); | ||
} | ||
} ); | ||
@@ -59,0 +63,0 @@ |
@@ -6,2 +6,6 @@ /* eslint-disable no-unused-vars */ | ||
handleNodes: 'node', // selector/filter function for whether edges can be made from a given node | ||
snap: false, // when enabled, the edge can be drawn by just moving close to a target node (can be confusing on compound graphs) | ||
snapThreshold: 50, // the target node must be less than or equal to this many pixels away from the cursor/finger | ||
snapFrequency: 15, // the number of times per second (Hz) that snap checks done (lower is less expensive) | ||
noEdgeEventsInDraw: false, // set events:no to edges during draws, prevents mouseouts on compounds | ||
handlePosition: function( node ){ | ||
@@ -8,0 +12,0 @@ return 'middle top'; // sets the position of the handle in the format of "X-AXIS Y-AXIS" such as "left top", "middle top" |
@@ -42,3 +42,3 @@ const assign = require('../assign'); | ||
if( !preview && options.preview ) { | ||
previewEles.removeClass('eh-preview'); | ||
previewEles.removeClass('eh-preview').style('events', ''); | ||
@@ -71,3 +71,4 @@ this.emit( 'complete', this.mp(), source, target, previewEles ); | ||
group: 'nodes', | ||
position: p | ||
position: p, | ||
style: { 'events': 'no' } | ||
}, | ||
@@ -85,3 +86,4 @@ options.nodeParams( source, target ) | ||
target: interNode.id() | ||
} | ||
}, | ||
style: { 'events': 'no' } | ||
}, | ||
@@ -99,3 +101,4 @@ options.edgeParams( source, target, 0 ) | ||
target: target.id() | ||
} | ||
}, | ||
style: { 'events': 'no' } | ||
}, | ||
@@ -115,3 +118,4 @@ options.edgeParams( source, target, 1 ) | ||
target: target.id() | ||
} | ||
}, | ||
style: { 'events': 'no' } | ||
}, | ||
@@ -118,0 +122,0 @@ options.edgeParams( source, target, 0 ) |
@@ -0,1 +1,3 @@ | ||
const memoize = require('lodash.memoize'); | ||
function canStartOn( node ){ | ||
@@ -56,2 +58,3 @@ const { options, previewEles, ghostEles, handleNode } = this; | ||
this.disableGestures(); | ||
this.disableEdgeEvents(); | ||
@@ -70,2 +73,3 @@ this.emit( 'start', this.hp(), node ); | ||
this.updateEdge(); | ||
this.throttledSnap(); | ||
@@ -75,4 +79,38 @@ return this; | ||
function preview( target ){ | ||
let { options, sourceNode, ghostNode, presumptiveTargets, previewEles, active } = this; | ||
function snap(){ | ||
if( !this.active || !this.options.snap ){ return false; } | ||
let cy = this.cy; | ||
let tgt = this.targetNode; | ||
let threshold = this.options.snapThreshold; | ||
let sqThreshold = n => { let r = getRadius(n); let t = r + threshold; return t * t; }; | ||
let mousePos = this.mp(); | ||
let sqDist = (p1, p2) => (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y); | ||
let getRadius = n => ( n.outerWidth() + n.outerHeight() ) / 4; | ||
let nodeSqDist = memoize(n => sqDist(n.position(), mousePos), n => n.id()); | ||
let isWithinTheshold = n => nodeSqDist(n) <= sqThreshold(n); | ||
let cmpSqDist = (n1, n2) => nodeSqDist(n1) - nodeSqDist(n2); | ||
let allowHoverDelay = false; | ||
let nodesByDist = cy.nodes(isWithinTheshold).sort(cmpSqDist); | ||
let snapped = false; | ||
if( tgt.nonempty() && !isWithinTheshold(tgt) ){ | ||
this.unpreview(tgt); | ||
} | ||
for(let i = 0; i < nodesByDist.length; i++){ | ||
let n = nodesByDist[i]; | ||
if( n.same(tgt) || this.preview(n, allowHoverDelay) ){ | ||
snapped = true; | ||
break; | ||
} | ||
} | ||
return snapped; | ||
} | ||
function preview( target, allowHoverDelay = true ){ | ||
let { options, sourceNode, ghostNode, ghostEles, presumptiveTargets, previewEles, active } = this; | ||
let source = sourceNode; | ||
@@ -84,29 +122,42 @@ let isLoop = target.same( source ); | ||
let isHandle = target.same( this.handleNode ); | ||
let isExistingTgt = target.same( this.targetNode ); | ||
if( !active || isHandle || isGhost || noEdge ) { return; } | ||
if( !active || isHandle || isGhost || noEdge || isExistingTgt || (isLoop && !loopAllowed) ) { return false; } | ||
if( this.targetNode.nonempty() ){ | ||
this.unpreview( this.targetNode ); | ||
} | ||
clearTimeout( this.previewTimeout ); | ||
this.previewTimeout = setTimeout( () => { | ||
let applyPreview = () => { | ||
this.targetNode = target; | ||
presumptiveTargets.merge( target ); | ||
target.addClass('eh-presumptive-target'); | ||
target.addClass('eh-target'); | ||
if( !isLoop || ( isLoop && loopAllowed ) ) { | ||
target.addClass('eh-target'); | ||
this.emit( 'hoverover', this.mp(), source, target ); | ||
this.emit( 'hoverover', this.mp(), source, target ); | ||
if( options.preview ){ | ||
target.addClass('eh-preview'); | ||
if( options.preview ){ | ||
target.addClass('eh-preview'); | ||
ghostEles.addClass('eh-preview-active'); | ||
sourceNode.addClass('eh-preview-active'); | ||
target.addClass('eh-preview-active'); | ||
this.makePreview(); | ||
this.makePreview(); | ||
this.emit( 'previewon', this.mp(), source, target, previewEles ); | ||
} | ||
this.emit( 'previewon', this.mp(), source, target, previewEles ); | ||
} | ||
}, options.hoverDelay ); | ||
}; | ||
return this; | ||
if( allowHoverDelay && options.hoverDelay > 0 ){ | ||
this.previewTimeout = setTimeout( applyPreview, options.hoverDelay ); | ||
} else { | ||
applyPreview(); | ||
} | ||
return true; | ||
} | ||
@@ -117,3 +168,3 @@ | ||
let { previewTimeout, sourceNode, previewEles, cy } = this; | ||
let { previewTimeout, sourceNode, previewEles, ghostEles, cy } = this; | ||
clearTimeout( previewTimeout ); | ||
@@ -124,3 +175,5 @@ this.previewTimeout = null; | ||
target.removeClass('eh-preview eh-target eh-presumptive-target'); | ||
target.removeClass('eh-preview eh-target eh-presumptive-target eh-preview-active'); | ||
ghostEles.removeClass('eh-preview-active'); | ||
sourceNode.removeClass('eh-preview-active'); | ||
@@ -157,2 +210,3 @@ this.targetNode = cy.collection(); | ||
this.resetGestures(); | ||
this.enableEdgeEvents(); | ||
@@ -167,4 +221,4 @@ this.active = false; | ||
module.exports = { | ||
show, hide, start, update, preview, unpreview, stop, | ||
show, hide, start, update, preview, unpreview, stop, snap, | ||
canStartOn, canStartDrawModeOn, canStartNonDrawModeOn | ||
}; |
const defaults = require('./defaults'); | ||
const assign = require('../assign'); | ||
const throttle = require('lodash.throttle'); | ||
@@ -11,2 +12,3 @@ const cyGesturesToggle = require('./cy-gestures-toggle'); | ||
const listeners = require('./listeners'); | ||
const edgeEvents = require('./edge-events-toggle'); | ||
@@ -42,2 +44,4 @@ function Edgehandles( options ){ | ||
this.addListeners(); | ||
this.throttledSnap = throttle( this.snap.bind(this), 1000/options.snapFrequency ); | ||
} | ||
@@ -82,5 +86,6 @@ | ||
gestureLifecycle, | ||
listeners | ||
listeners, | ||
edgeEvents | ||
].forEach( extend ); | ||
module.exports = Edgehandles; |
@@ -25,3 +25,16 @@ const path = require('path'); | ||
}, | ||
externals: PROD ? Object.keys( pkg.dependencies || {} ) : [], | ||
externals: { | ||
'lodash.memoize': { | ||
commonjs: 'lodash.memoize', | ||
commonjs2: 'lodash.memoize', | ||
amd: 'lodash.memoize', | ||
root: ['_', 'memoize'] | ||
}, | ||
'lodash.throttle': { | ||
commonjs: 'lodash.throttle', | ||
commonjs2: 'lodash.throttle', | ||
amd: 'lodash.throttle', | ||
root: ['_', 'throttle'] | ||
} | ||
}, | ||
plugins: MIN ? [ | ||
@@ -28,0 +41,0 @@ new webpack.optimize.UglifyJsPlugin({ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
168332
26
1766
245
3
+ Addedlodash.memoize@^4.1.2
+ Addedlodash.throttle@^4.1.1
+ Addedlodash.memoize@4.1.2(transitive)
+ Addedlodash.throttle@4.1.1(transitive)