close #32 (beta) new feature "system magnetization"
This commit is contained in:
@@ -28,6 +28,7 @@ requirejs.config({
|
||||
velocityUI: 'lib/velocity.ui.min', // v5.0.4 plugin for velocity - http://julian.com/research/velocity/#uiPack
|
||||
slidebars: 'lib/slidebars', // v0.10 Slidebars - side menu plugin http://plugins.adchsm.me/slidebars/
|
||||
jsPlumb: 'lib/dom.jsPlumb-1.7.6-min', // v1.7.6 jsPlumb (Vanilla)- main map draw plugin https://jsplumbtoolkit.com/
|
||||
farahey: 'lib/farahey-0.5', // v0.5 jsPlumb "magnetizing" extension - https://github.com/jsplumb/farahey
|
||||
customScrollbar: 'lib/jquery.mCustomScrollbar.concat.min', // v3.0.9 Custom scroll bars - http://manos.malihu.gr/
|
||||
datatables: 'lib/datatables/jquery.dataTables.min', // v1.10.7 DataTables - https://datatables.net/
|
||||
//datatablesBootstrap: 'lib/datatables/dataTables.bootstrap', // DataTables - not used (bootstrap style)
|
||||
@@ -70,6 +71,9 @@ requirejs.config({
|
||||
bootstrap: {
|
||||
deps: ['jquery']
|
||||
},
|
||||
farahey: {
|
||||
deps: ['jsPlumb']
|
||||
},
|
||||
velocity: {
|
||||
deps: ['jquery']
|
||||
},
|
||||
|
||||
156
js/app/map/magnetizing.js
Normal file
156
js/app/map/magnetizing.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Map "magnetizing" feature
|
||||
* jsPlumb extension used: http://morrisonpitt.com/farahey/
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'farahey'
|
||||
], function($) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = {
|
||||
systemClass: 'pf-system' // class for all systems
|
||||
};
|
||||
|
||||
/**
|
||||
* Cached current "Magnetizer" object
|
||||
* @type {Magnetizer}
|
||||
*/
|
||||
var m8 = null;
|
||||
|
||||
/**
|
||||
* init a jsPlumb (map) Element for "magnetised" function.
|
||||
* this is optional and prevents systems from being overlapped
|
||||
*/
|
||||
$.fn.initMagnetizer = function(){
|
||||
var mapContainer = this;
|
||||
|
||||
var systemsOnMap = mapContainer.find('.' + config.systemClass);
|
||||
|
||||
/**
|
||||
* helper function
|
||||
* get current system offset
|
||||
* @param system
|
||||
* @returns {{left, top}}
|
||||
* @private
|
||||
*/
|
||||
var _offset = function(system) {
|
||||
|
||||
var _ = function(p) {
|
||||
var v = system.style[p];
|
||||
return parseInt(v.substring(0, v.length - 2));
|
||||
};
|
||||
|
||||
return {
|
||||
left:_('left'),
|
||||
top:_('top')
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* helper function
|
||||
* set new syste offset
|
||||
* @param system
|
||||
* @param o
|
||||
* @private
|
||||
*/
|
||||
var _setOffset = function(system, o) {
|
||||
|
||||
var markAsUpdated = false;
|
||||
|
||||
// new position must be within parent container
|
||||
// no negative offset!
|
||||
if(
|
||||
o.left >= 0 &&
|
||||
o.left <= 2300
|
||||
){
|
||||
markAsUpdated = true;
|
||||
system.style.left = o.left + 'px';
|
||||
}
|
||||
|
||||
if(
|
||||
o.top >= 0 &&
|
||||
o.top <= 498
|
||||
){
|
||||
markAsUpdated = true;
|
||||
system.style.top = o.top + 'px';
|
||||
}
|
||||
|
||||
if(markAsUpdated === true){
|
||||
$(system).markAsChanged();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* helper function
|
||||
* exclude current dragged element(s) from position update
|
||||
* @param id
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
var _dragFilter = function(id) {
|
||||
|
||||
return !$('#' + id).hasClass('jsPlumb_dragged');
|
||||
};
|
||||
|
||||
// main init for "magnetize" feature ------------------------------------------------------
|
||||
m8 = new Magnetizer({
|
||||
container: mapContainer,
|
||||
getContainerPosition:function(c) {
|
||||
return c.offset();
|
||||
},
|
||||
getPosition:_offset,
|
||||
getSize: function(system) {
|
||||
return [ $(system).outerWidth(), $(system).outerHeight() ];
|
||||
},
|
||||
getId : function(system) {
|
||||
return $(system).attr('id');
|
||||
},
|
||||
setPosition:_setOffset,
|
||||
elements: systemsOnMap,
|
||||
filter:_dragFilter,
|
||||
padding:[8, 8]
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$.fn.destroyMagnetizer = function(){
|
||||
var mapContainer = this;
|
||||
|
||||
// remove cached "magnetizer" instance
|
||||
m8 = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* update system positions for "all" systems that are effected by drag&drop
|
||||
* @param map
|
||||
* @param e
|
||||
*/
|
||||
var executeAtEvent = function(map, e){
|
||||
|
||||
// check if magnetizer is active
|
||||
if(m8 !== null && e ){
|
||||
m8.executeAtEvent(e);
|
||||
map.repaintEverything();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* rearrange all systems of a map
|
||||
* needs "magnetization" to be active
|
||||
* @param map
|
||||
*/
|
||||
var executeAtCenter = function(map){
|
||||
if(m8 !== null){
|
||||
m8.executeAtCenter();
|
||||
map.repaintEverything();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
executeAtCenter: executeAtCenter,
|
||||
executeAtEvent: executeAtEvent
|
||||
};
|
||||
});
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Main map functionality
|
||||
*/
|
||||
|
||||
define([
|
||||
'jquery',
|
||||
'app/init',
|
||||
@@ -5,12 +9,12 @@ define([
|
||||
'app/render',
|
||||
'bootbox',
|
||||
'app/ccp',
|
||||
'jsPlumb',
|
||||
'app/map/magnetizing',
|
||||
'dragToSelect',
|
||||
'select2',
|
||||
'app/map/contextmenu',
|
||||
'app/map/overlay'
|
||||
], function($, Init, Util, Render, bootbox, CCP) {
|
||||
], function($, Init, Util, Render, bootbox, CCP, MagnetizerWrapper) {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -22,7 +26,8 @@ define([
|
||||
},
|
||||
|
||||
mapSnapToGridDimension: 20, // px for grid snapping (grid YxY)
|
||||
mapSnapToGrid: false, // Snap systems to grid while dragging
|
||||
mapSnapToGrid: false, // "Snap to Grid" feature for drag&drop systems on map (optional)
|
||||
mapMagnetizer: false, // "Magnetizer" feature for drag&drop systems on map (optional)
|
||||
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
|
||||
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
|
||||
headMapTrackingId: 'pf-head-map-tracking', // id for "map tracking" toggle (checkbox)
|
||||
@@ -616,6 +621,8 @@ define([
|
||||
|
||||
var mapContainer = mapConfig.map.getContainer();
|
||||
|
||||
var newSystems = 0;
|
||||
|
||||
if(mapContainer === undefined){
|
||||
// add new map
|
||||
|
||||
@@ -688,6 +695,7 @@ define([
|
||||
|
||||
if( addNewSystem === true){
|
||||
drawSystem(mapConfig.map, systemData);
|
||||
newSystems++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,6 +788,16 @@ define([
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// init/update map "magnetization" feature if new systems where added
|
||||
if(
|
||||
config.mapMagnetizer === true &&
|
||||
newSystems > 0
|
||||
){
|
||||
mapContainer.initMagnetizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return mapContainer;
|
||||
@@ -876,7 +894,10 @@ define([
|
||||
|
||||
connectorElements.velocity('transition.fadeIn', {
|
||||
stagger: 30,
|
||||
duration: 120
|
||||
duration: 120,
|
||||
complete: function(){
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
// show overlay elements (if some exist)
|
||||
@@ -884,10 +905,7 @@ define([
|
||||
overlayElements.delay(500).velocity('transition.fadeIn', {
|
||||
stagger: 50,
|
||||
duration: 180,
|
||||
display: 'auto',
|
||||
complete: function(){
|
||||
callback();
|
||||
}
|
||||
display: 'auto'
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1677,7 +1695,7 @@ define([
|
||||
constrain: true,
|
||||
//scroll: true, // not working because of customized scrollbar
|
||||
filter: '.' + config.systemHeadNameClass, // disable drag on "system name"
|
||||
snapThreshold: config.mapSnapToGridDimension, // distance for grid snapping "magnet" effect
|
||||
snapThreshold: config.mapSnapToGridDimension, // distance for grid snapping "magnet" effect (optional)
|
||||
start: function(params, a, b){
|
||||
var dragSystem = $(params.el);
|
||||
|
||||
@@ -1707,9 +1725,13 @@ define([
|
||||
// move them to the "top"
|
||||
$(selectedSystems).updateSystemZIndex();
|
||||
},
|
||||
drag: function(){
|
||||
drag: function(p){
|
||||
// start map update timer
|
||||
mapOverlayTimer.startMapUpdateCounter();
|
||||
|
||||
// update system positions for "all" systems that are effected by drag&drop
|
||||
// this requires "magnet" feature to be active! (optional)
|
||||
MagnetizerWrapper.executeAtEvent(map, p.e);
|
||||
},
|
||||
stop: function(params){
|
||||
var dragSystem = $(params.el);
|
||||
@@ -1736,7 +1758,6 @@ define([
|
||||
// set all selected systems as "changes" for update
|
||||
tempSystem.markAsChanged();
|
||||
|
||||
|
||||
// set new position for popover edit field (system name)
|
||||
var tempPosition = tempSystem.position();
|
||||
|
||||
@@ -2035,7 +2056,6 @@ define([
|
||||
// connection element
|
||||
this.setParameter('updated', 0);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2419,32 +2439,44 @@ define([
|
||||
|
||||
// catch events =========================================================
|
||||
|
||||
// toggle "snap to grid" option
|
||||
$(mapContainer).on('pf:menuGrid', function(e, data){
|
||||
// toggle global map option (e.g. "grid snap", "magnetization"
|
||||
$(mapContainer).on('pf:menuMapOption', function(e, data){
|
||||
|
||||
var currentMapElement = $(this);
|
||||
|
||||
config.mapSnapToGrid = !config.mapSnapToGrid;
|
||||
// toggle map option
|
||||
config[data.option] = !config[data.option];
|
||||
|
||||
// toggle grid class
|
||||
currentMapElement.toggleClass(config.mapGridClass);
|
||||
// toggle map class (e.g. for grid)
|
||||
if(data.class){
|
||||
currentMapElement.toggleClass( config[data.class] );
|
||||
}
|
||||
|
||||
// toggle button class
|
||||
$(data.button).toggleClass('active');
|
||||
|
||||
var notificationText = 'disabled';
|
||||
if(config.mapSnapToGrid){
|
||||
if( config[data.option] ){
|
||||
|
||||
// call optional jQuery extension on mapElement
|
||||
if(data.onEnable){
|
||||
$.fn[ data.onEnable ].apply( currentMapElement );
|
||||
}
|
||||
|
||||
// show map overlay info icon
|
||||
notificationText = 'enabled';
|
||||
|
||||
// show map overlay grid info
|
||||
currentMapElement.getMapOverlay('info').updateOverlayIcon('grid', 'show');
|
||||
currentMapElement.getMapOverlay('info').updateOverlayIcon(data.option, 'show');
|
||||
}else{
|
||||
// call optional jQuery extension on mapElement
|
||||
if(data.onDisable){
|
||||
$.fn[ data.onDisable ].apply( currentMapElement );
|
||||
}
|
||||
|
||||
// hide map overlay grid info
|
||||
currentMapElement.getMapOverlay('info').updateOverlayIcon('grid', 'hide');
|
||||
// hide map overlay info icon
|
||||
currentMapElement.getMapOverlay('info').updateOverlayIcon(data.option, 'hide');
|
||||
}
|
||||
|
||||
Util.showNotify({title: 'Grid snapping', text: notificationText, type: 'info'});
|
||||
Util.showNotify({title: data.description, text: notificationText, type: 'info'});
|
||||
});
|
||||
|
||||
// delete system event
|
||||
@@ -2902,6 +2934,15 @@ define([
|
||||
|
||||
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
|
||||
|
||||
// re-init "magnetizer" with new added system
|
||||
if(config.mapMagnetizer === true){
|
||||
var mapContainer = this.map.getContainer();
|
||||
$(mapContainer).initMagnetizer();
|
||||
|
||||
// re/arrange systems (prevent overlapping)
|
||||
MagnetizerWrapper.executeAtCenter(this.map);
|
||||
}
|
||||
|
||||
if(callback){
|
||||
callback();
|
||||
}
|
||||
@@ -3319,19 +3360,19 @@ define([
|
||||
jsPlumb.Defaults.LogEnabled = true;
|
||||
|
||||
var newJsPlumbInstance = jsPlumb.getInstance({
|
||||
Anchor: 'Continuous', // anchors on each site
|
||||
Container: null, // will be set as soon as container is connected to DOM
|
||||
Anchor: 'Continuous', // anchors on each site
|
||||
Container: null, // will be set as soon as container is connected to DOM
|
||||
PaintStyle:{
|
||||
lineWidth: 4, // width of a Connector's line. An integer.
|
||||
strokeStyle: 'red', // color for a Connector
|
||||
outlineColor: 'red', // color of the outline for an Endpoint or Connector. see fillStyle examples.
|
||||
outlineWidth: 2 // width of the outline for an Endpoint or Connector. An integer.
|
||||
lineWidth: 4, // width of a Connector's line. An integer.
|
||||
strokeStyle: 'red', // color for a Connector
|
||||
outlineColor: 'red', // color of the outline for an Endpoint or Connector. see fillStyle examples.
|
||||
outlineWidth: 2 // width of the outline for an Endpoint or Connector. An integer.
|
||||
},
|
||||
Connector:[ 'Bezier', { curviness: 40 } ], // default connector style (this is not used!) all connections have their own style (by scope)
|
||||
Connector:[ 'Bezier', { curviness: 40 } ], // default connector style (this is not used!) all connections have their own style (by scope)
|
||||
Endpoints: [ [ 'Dot', { radius: 5 } ], [ 'Dot', { radius: 5 } ] ],
|
||||
// Endpoint: 'Blank', // does not work... :(
|
||||
ReattachConnections: false, // re-attach connection if dragged with mouse to "nowhere"
|
||||
Scope: Init.defaultMapScope, // default map scope for connections
|
||||
ReattachConnections: false, // re-attach connection if dragged with mouse to "nowhere"
|
||||
Scope: Init.defaultMapScope, // default map scope for connections
|
||||
LogEnabled: true
|
||||
});
|
||||
|
||||
@@ -3447,18 +3488,23 @@ define([
|
||||
}
|
||||
|
||||
// callback function after tab switch
|
||||
function switchTabCallback( mapName ){
|
||||
function switchTabCallback( mapName, mapContainer ){
|
||||
Util.showNotify({title: 'Map initialized', text: mapName + ' - loaded', type: 'success'});
|
||||
|
||||
if( config.mapMagnetizer === true ){
|
||||
mapContainer.initMagnetizer();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(options.showAnimation){
|
||||
// show nice visualization effect
|
||||
mapContainer.visualizeMap('show', function(){
|
||||
switchTabCallback( mapConfig.config.name );
|
||||
switchTabCallback( mapConfig.config.name, mapContainer );
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -19,12 +19,27 @@ define([
|
||||
// map overlays
|
||||
mapOverlayClass: 'pf-map-overlay', // class for all map overlays
|
||||
mapOverlayTimerClass: 'pf-map-overlay-timer', // class for map overlay timer e.g. map timer
|
||||
mapOverlayInfoClass: 'pf-map-overlay-info', // class for map overlay info e.g. map info
|
||||
mapOverlayInfoClass: 'pf-map-overlay-info' // class for map overlay info e.g. map info
|
||||
|
||||
// map overlay icons
|
||||
mapOverlayFilterClass: 'pf-map-overlay-filter', // class for "filter" icon within a overlay
|
||||
mapOverlayGridClass: 'pf-map-overlay-grid' // class for "grid" icon within a overlay
|
||||
};
|
||||
|
||||
// overlay options (all available map options shown in overlay)
|
||||
var options = {
|
||||
filter: {
|
||||
title: 'active filter',
|
||||
class: 'pf-map-overlay-filter',
|
||||
iconClass: ['fa', 'fa-fw', 'fa-filter']
|
||||
},
|
||||
mapSnapToGrid: {
|
||||
title: 'active grid',
|
||||
class: 'pf-map-overlay-grid',
|
||||
iconClass: ['glyphicon', 'glyphicon-th']
|
||||
},
|
||||
mapMagnetizer: {
|
||||
title: 'active magnetizer',
|
||||
class: 'pf-map-overlay-magnetizer',
|
||||
iconClass: ['fa', 'fa-fw', 'fa-magnet']
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -172,24 +187,18 @@ define([
|
||||
/**
|
||||
* update (show/hide) a overlay icon in the "info"-overlay
|
||||
* show/hide the overlay itself is no icons are visible
|
||||
* @param iconName
|
||||
* @param option
|
||||
* @param viewType
|
||||
*/
|
||||
$.fn.updateOverlayIcon = function(iconName, viewType){
|
||||
$.fn.updateOverlayIcon = function(option, viewType){
|
||||
var mapOverlayInfo = $(this);
|
||||
|
||||
var showOverlay = false;
|
||||
|
||||
var mapOverlayIconClass = options[option].class;
|
||||
|
||||
// look for the overlay icon that should be updated
|
||||
var iconElement = null;
|
||||
switch(iconName){
|
||||
case 'filter':
|
||||
iconElement = mapOverlayInfo.find('.' + config.mapOverlayFilterClass);
|
||||
break;
|
||||
case 'grid':
|
||||
iconElement = mapOverlayInfo.find('.' + config.mapOverlayGridClass);
|
||||
break;
|
||||
}
|
||||
var iconElement = mapOverlayInfo.find('.' + mapOverlayIconClass);
|
||||
|
||||
if(iconElement){
|
||||
if(viewType === 'show'){
|
||||
@@ -198,7 +207,7 @@ define([
|
||||
}else if(viewType === 'hide'){
|
||||
iconElement.hide();
|
||||
|
||||
// check if ther is any visible icon remaining
|
||||
// check if there is any visible icon remaining
|
||||
var visibleIcons = mapOverlayInfo.find('i:visible');
|
||||
if(visibleIcons.length > 0){
|
||||
showOverlay = true;
|
||||
@@ -228,33 +237,33 @@ define([
|
||||
*/
|
||||
$.fn.initMapOverlays = function(){
|
||||
return this.each(function(){
|
||||
var parentElemtn = $(this);
|
||||
var parentElement = $(this);
|
||||
|
||||
var mapOverlayTimer = $('<div>', {
|
||||
class: [config.mapOverlayClass, config.mapOverlayTimerClass].join(' ')
|
||||
});
|
||||
parentElemtn.append(mapOverlayTimer);
|
||||
parentElement.append(mapOverlayTimer);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// add map overlay info. after scrollbar is initialized
|
||||
var mapOverlayInfo = $('<div>', {
|
||||
class: [config.mapOverlayClass, config.mapOverlayInfoClass].join(' ')
|
||||
}).append(
|
||||
$('<i>', {
|
||||
class: ['fa', 'fa-fw', 'fa-filter', 'pull-right', config.mapOverlayFilterClass].join(' ')
|
||||
}).attr('title', 'active filter').tooltip({
|
||||
placement: 'left',
|
||||
container: 'body'
|
||||
})
|
||||
).append(
|
||||
$('<i>', {
|
||||
class: ['glyphicon', 'glyphicon-th', 'pull-right', config.mapOverlayGridClass].join(' ')
|
||||
}).attr('title', 'active grid').tooltip({
|
||||
placement: 'left',
|
||||
container: 'body'
|
||||
})
|
||||
);
|
||||
parentElemtn.append(mapOverlayInfo);
|
||||
});
|
||||
|
||||
// add all overlay elements
|
||||
for (var prop in options) {
|
||||
if(options.hasOwnProperty(prop)){
|
||||
mapOverlayInfo.append(
|
||||
$('<i>', {
|
||||
class: options[prop].iconClass.concat( ['pull-right', options[prop].class] ).join(' ')
|
||||
}).attr('title', options[prop].title).tooltip({
|
||||
placement: 'left',
|
||||
container: 'body'
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
parentElement.append(mapOverlayInfo);
|
||||
|
||||
// reset map update timer
|
||||
mapOverlayTimer.setMapUpdateCounter(100, config.logTimerCount);
|
||||
|
||||
@@ -280,12 +280,39 @@ define([
|
||||
class: 'list-group-item',
|
||||
href: '#'
|
||||
}).html(' Grid snapping').prepend(
|
||||
$('<i>',{
|
||||
class: 'glyphicon glyphicon-th'
|
||||
})
|
||||
).on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('Grid', {button: this});
|
||||
$('<i>',{
|
||||
class: 'glyphicon glyphicon-th'
|
||||
})
|
||||
).on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
|
||||
option: 'mapSnapToGrid',
|
||||
button: this,
|
||||
description: 'Grid snapping',
|
||||
class: 'mapGridClass'
|
||||
});
|
||||
})
|
||||
).append(
|
||||
$('<a>', {
|
||||
class: 'list-group-item',
|
||||
href: '#'
|
||||
}).html(' Magnetizing').prepend(
|
||||
$('<i>',{
|
||||
class: 'fa fa-magnet fa-fw'
|
||||
})
|
||||
).on('click', function(){
|
||||
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
|
||||
option: 'mapMagnetizer',
|
||||
button: this,
|
||||
description: 'Magnetizer',
|
||||
onEnable: 'initMagnetizer', // jQuery extension function
|
||||
onDisable: 'destroyMagnetizer' // jQuery extension function
|
||||
});
|
||||
}).append(
|
||||
$('<span>',{
|
||||
class: ['badge', 'bg-color', 'bg-color-orange', 'pull-right'].join(' '),
|
||||
html: 'β'
|
||||
})
|
||||
)
|
||||
).append(
|
||||
$('<a>', {
|
||||
class: 'list-group-item',
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"bootstrap2-toggle.min.js","sources":["bootstrap2-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":"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"}
|
||||
350
js/lib/farahey-0.5.js
Normal file
350
js/lib/farahey-0.5.js
Normal file
@@ -0,0 +1,350 @@
|
||||
;(function() {
|
||||
|
||||
var root = this;
|
||||
var Farahey;
|
||||
if (typeof exports !== 'undefined') {
|
||||
Farahey = exports;
|
||||
} else {
|
||||
Farahey = root.Farahey = {};
|
||||
}
|
||||
|
||||
var findInsertionPoint = function(sortedArr, val, comparator) {
|
||||
var low = 0, high = sortedArr.length;
|
||||
var mid = -1, c = 0;
|
||||
while(low < high) {
|
||||
mid = parseInt((low + high)/2);
|
||||
c = comparator(sortedArr[mid], val);
|
||||
if(c < 0) {
|
||||
low = mid + 1;
|
||||
}else if(c > 0) {
|
||||
high = mid;
|
||||
}else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
return low;
|
||||
},
|
||||
geomSupport = typeof jsPlumbGeom !== "undefined" ? jsPlumbGeom : Biltong,
|
||||
insertSorted = function(array, value, comparator) {
|
||||
var ip = findInsertionPoint(array, value, comparator);
|
||||
array.splice(ip, 0, value);
|
||||
},
|
||||
distanceFromOriginComparator = function(r1, r2, origin) {
|
||||
var d1 = geomSupport.lineLength(origin, [ r1.x + (r1.w / 2), r1.y + (r1.h / 2)]),
|
||||
d2 = geomSupport.lineLength(origin, [ r2.x + (r2.w / 2), r2.y + (r2.h / 2)]);
|
||||
|
||||
return d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
|
||||
},
|
||||
EntryComparator = function(origin, getSize) {
|
||||
var _origin = origin,
|
||||
_cache = {},
|
||||
_get = function(entry) {
|
||||
if (!_cache[entry[1]]) {
|
||||
var s = getSize(entry[2]);
|
||||
_cache[entry[1]] = {
|
||||
l:entry[0][0],
|
||||
t:entry[0][1],
|
||||
w:s[0],
|
||||
h:s[1],
|
||||
center:[entry[0][0] + (s[0] / 2), entry[0][1] + (s[1] / 2) ]
|
||||
};
|
||||
}
|
||||
return _cache[entry[1]];
|
||||
}
|
||||
this.setOrigin = function(o) {
|
||||
_origin = o;
|
||||
_cache = {};
|
||||
};
|
||||
this.compare = function(e1, e2) {
|
||||
var d1 = geomSupport.lineLength(_origin, _get(e1).center),
|
||||
d2 = geomSupport.lineLength(_origin, _get(e2).center);
|
||||
|
||||
return d1 < d2 ? -1 : d1 == d2 ? 0 : 1;
|
||||
};
|
||||
};
|
||||
|
||||
var _isOnEdge = function(r, axis, dim, v) { return (r[axis] <= v && v <= r[axis] + r[dim]); },
|
||||
_xAdj = [ function(r1, r2) { return r1.x + r1.w - r2.x; }, function(r1, r2) { return r1.x - (r2.x + r2.w); } ],
|
||||
_yAdj = [ function(r1, r2) { return r1.y + r1.h - r2.y; }, function(r1, r2) { return r1.y - (r2.y + r2.h); } ],
|
||||
_adj = [ null, [ _xAdj[0], _yAdj[1] ], [ _xAdj[0], _yAdj[0] ], [ _xAdj[1], _yAdj[0] ], [ _xAdj[1], _yAdj[1] ] ],
|
||||
_genAdj = function(r1, r2, m, b, s) {
|
||||
if (isNaN(m)) m = 0;
|
||||
var y = r2.y + r2.h,
|
||||
x = (m == Infinity || m == -Infinity) ? r2.x + (r2.w / 2) : (y - b) / m,
|
||||
theta = Math.atan(m);
|
||||
|
||||
if (_isOnEdge(r2, "x", "w", x)) {
|
||||
var rise = _adj[s][1](r1, r2),
|
||||
hyp = rise / Math.sin(theta),
|
||||
run = hyp * Math.cos(theta);
|
||||
return { left:run, top:rise };
|
||||
}
|
||||
else {
|
||||
var run = _adj[s][0](r1, r2),
|
||||
hyp = run / Math.cos(theta),
|
||||
rise = hyp * Math.sin(theta);
|
||||
return { left:run, top:rise };
|
||||
}
|
||||
},
|
||||
/*
|
||||
* Calculates how far to move r2 from r1 so that it no longer overlaps.
|
||||
* if origin is supplied, then it means we want r2 to move along a vector joining r2's center to that point.
|
||||
* otherwise we want it to move along a vector joining the two rectangle centers.
|
||||
*/
|
||||
_calculateSpacingAdjustment = Farahey.calculateSpacingAdjustment = function(r1, r2) {
|
||||
var c1 = r1.center || [ r1.x + (r1.w / 2), r1.y + (r1.h / 2) ],
|
||||
c2 = r2.center || [ r2.x + (r2.w / 2), r2.y + (r2.h / 2) ],
|
||||
m = geomSupport.gradient(c1, c2),
|
||||
s = geomSupport.quadrant(c1, c2),
|
||||
b = (m == Infinity || m == -Infinity || isNaN(m)) ? 0 : c1[1] - (m * c1[0]);
|
||||
|
||||
return _genAdj(r1, r2, m, b, s);
|
||||
},
|
||||
// calculate a padded rectangle for the given element with offset & size, and desired padding.
|
||||
_paddedRectangle = Farahey.paddedRectangle = function(o, s, p) {
|
||||
return { x:o[0] - p[0], y: o[1] - p[1], w:s[0] + (2 * p[0]), h:s[1] + (2 * p[1]) };
|
||||
},
|
||||
_magnetize = function(positionArray, positions, sizes, padding,
|
||||
constrain, origin, filter,
|
||||
updateOnStep, stepInterval, stepCallback)
|
||||
{
|
||||
origin = origin || [0,0];
|
||||
stepCallback = stepCallback || function() { };
|
||||
|
||||
var focus = _paddedRectangle(origin, [1,1], padding),
|
||||
iterations = 100, iteration = 1, uncleanRun = true, adjustBy, constrainedAdjustment,
|
||||
_movedElements = {},
|
||||
_move = function(id, o, x, y) {
|
||||
_movedElements[id] = true;
|
||||
o[0] += x;
|
||||
o[1] += y;
|
||||
},
|
||||
step = function() {
|
||||
for (var i = 0; i < positionArray.length; i++) {
|
||||
var o1 = positions[positionArray[i][1]],
|
||||
oid = positionArray[i][1],
|
||||
a1 = positionArray[i][2], // angle to node from magnet origin
|
||||
s1 = sizes[positionArray[i][1]],
|
||||
// create a rectangle for first element: this encompasses the element and padding on each
|
||||
//side
|
||||
r1 = _paddedRectangle(o1, s1, padding);
|
||||
|
||||
if (filter(positionArray[i][1]) && geomSupport.intersects(focus, r1)) {
|
||||
adjustBy = _calculateSpacingAdjustment(focus, r1);
|
||||
constrainedAdjustment = constrain(positionArray[i][1], o1, adjustBy);
|
||||
_move(oid, o1, constrainedAdjustment.left, constrainedAdjustment.top);
|
||||
}
|
||||
|
||||
// now move others to account for this one, if necessary.
|
||||
// reset rectangle for node
|
||||
r1 = _paddedRectangle(o1, s1, padding);
|
||||
for (var j = 0; j < positionArray.length; j++) {
|
||||
if (i != j) {
|
||||
var o2 = positions[positionArray[j][1]],
|
||||
a2 = positionArray[j][2], // angle to node from magnet origin
|
||||
s2 = sizes[positionArray[j][1]],
|
||||
// create a rectangle for the second element, again by putting padding of the desired
|
||||
// amount around the bounds of the element.
|
||||
r2 = _paddedRectangle(o2, s2, padding);
|
||||
|
||||
// if the two rectangles intersect then figure out how much to move the second one by.
|
||||
if (geomSupport.intersects(r1, r2)) {
|
||||
// TODO in 0.3, instead of moving neither, the other node should move.
|
||||
if (filter(positionArray[j][1])) {
|
||||
uncleanRun = true;
|
||||
adjustBy = _calculateSpacingAdjustment(r1, r2),
|
||||
constrainedAdjustment = constrain(positionArray[j][1], o2, adjustBy);
|
||||
|
||||
_move(positionArray[j][1], o2, constrainedAdjustment.left, constrainedAdjustment.top);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateOnStep)
|
||||
stepCallback();
|
||||
|
||||
if (uncleanRun && iteration < iterations) {
|
||||
uncleanRun = false;
|
||||
iteration++;
|
||||
if (updateOnStep) {
|
||||
window.setTimeout(step, stepInterval);
|
||||
}
|
||||
else
|
||||
step();
|
||||
}
|
||||
};
|
||||
|
||||
step();
|
||||
return _movedElements;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @name Magnetizer
|
||||
* @classdesc Applies repulsive magnetism to a set of elements relative to a given point, with a specified
|
||||
* amount of padding around the point.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Magnetizer#constructor
|
||||
* @function
|
||||
* @param {Selector|Element} [container] Element that contains the elements to magnetize. Only required if you intend to use the `executeAtEvent` method.
|
||||
* @param {Function} [getContainerPosition] Function that returns the position of the container (as an object of the form `{left:.., top:..}`) when requested. Only required if you intend to use the `executeAtEvent` method.
|
||||
* @param {Function} getPosition A function that takes an element id and returns its position. It does not matter to which element this position is computed as long as you remain consistent with this method, `setPosition` and the `origin` property.
|
||||
* @param {Function} setPosition A function that takes an element id and position, and sets it. See note about offset parent above.
|
||||
* @param {Function} getSize A function that takes an element id and returns its size, in pixels.
|
||||
* @param {Integer[]} [padding] Optional padding for x and y directions. Defaults to 20 pixels in each direction.
|
||||
* @param {Function} [constrain] Optional function that takes an id and a proposed amount of movement in each axis, and returns the allowed amount of movement in each axis. You can use this to constrain your elements to a grid, for instance, or a path, etc.
|
||||
* @param {Integer[]} [origin] The origin of magnetization, in pixels. Defaults to 0,0. You can also supply this to the `execute` call.
|
||||
* @param {Selector|String[]|Element[]} elements List of elements on which to operate.
|
||||
* @param {Boolean} [executeNow=false] Whether or not to execute the routine immediately.
|
||||
* @param {Function} [filter] Optional function that takes an element id and returns whether or not that element can be moved.
|
||||
* @param {Boolean} [orderByDistanceFromOrigin=false] Whether or not to sort elements first by distance from origin. Can have better results but takes more time.
|
||||
*/
|
||||
root.Magnetizer = function(params) {
|
||||
var getPosition = params.getPosition,
|
||||
getSize = params.getSize,
|
||||
getId = params.getId,
|
||||
setPosition = params.setPosition,
|
||||
padding = params.padding || [20, 20],
|
||||
// expects a { left:.., top:... } object. returns how far it can actually go.
|
||||
constrain = params.constrain || function(id, current, delta) { return delta; },
|
||||
positionArray = [],
|
||||
positions = {},
|
||||
sizes = {},
|
||||
elements = params.elements || [],
|
||||
origin = params.origin || [0,0],
|
||||
executeNow = params.executeNow,
|
||||
minx, miny, maxx, maxy,
|
||||
getOrigin = this.getOrigin = function() { return origin; },
|
||||
filter = params.filter || function(_) { return true; },
|
||||
orderByDistanceFromOrigin = params.orderByDistanceFromOrigin,
|
||||
comparator = new EntryComparator(origin, getSize),
|
||||
updateOnStep = params.updateOnStep,
|
||||
stepInterval = params.stepInterval || 350,
|
||||
originDebugMarker,
|
||||
debug = params.debug,
|
||||
createOriginDebugger = function() {
|
||||
var d = document.createElement("div");
|
||||
d.style.position = "absolute";
|
||||
d.style.width = "10px";
|
||||
d.style.height = "10px";
|
||||
d.style.backgroundColor = "red";
|
||||
document.body.appendChild(d);
|
||||
originDebugMarker = d;
|
||||
},
|
||||
_addToPositionArray = function(p) {
|
||||
if (!orderByDistanceFromOrigin || positionArray.length == 0)
|
||||
positionArray.push(p);
|
||||
else {
|
||||
insertSorted(positionArray, p, comparator.compare);
|
||||
}
|
||||
},
|
||||
_updatePositions = function() {
|
||||
comparator.setOrigin(origin);
|
||||
positionArray = []; positions = {}; sizes = {};
|
||||
minx = miny = Infinity;
|
||||
maxx = maxy = -Infinity;
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var p = getPosition(elements[i]),
|
||||
s = getSize(elements[i]),
|
||||
id = getId(elements[i]);
|
||||
|
||||
positions[id] = [p.left, p.top];
|
||||
_addToPositionArray([ [p.left, p.top], id, elements[i]]);
|
||||
sizes[id] = s;
|
||||
minx = Math.min(minx, p.left);
|
||||
miny = Math.min(miny, p.top);
|
||||
maxx = Math.max(maxx, p.left + s[0]);
|
||||
maxy = Math.max(maxy, p.top + s[1]);
|
||||
}
|
||||
},
|
||||
_run = function() {
|
||||
if (elements.length > 1) {
|
||||
var _movedElements = _magnetize(positionArray, positions, sizes, padding, constrain, origin, filter, updateOnStep, stepInterval, _positionElements);
|
||||
_positionElements(_movedElements);
|
||||
}
|
||||
},
|
||||
_positionElements = function(_movedElements) {
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var id = getId(elements[i]);
|
||||
if (_movedElements[id])
|
||||
setPosition(elements[i], { left:positions[id][0], top:positions[id][1] });
|
||||
}
|
||||
},
|
||||
setOrigin = function(o) {
|
||||
if (o != null) {
|
||||
origin = o;
|
||||
comparator.setOrigin(o);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Magnetizer#execute
|
||||
* @function
|
||||
* @desc Runs the magnetize routine.
|
||||
* @param {Integer[]} [o] Optional origin to use. You may have set this in the constructor and do not wish to supply it, or you may be happy with the default of [0,0].
|
||||
*/
|
||||
this.execute = function(o) {
|
||||
setOrigin(o);
|
||||
_updatePositions();
|
||||
_run();
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Magnetizer#executeAtCenter
|
||||
* @function
|
||||
* @desc Computes the center of all the nodes and then uses that as the magnetization origin when it runs the routine.
|
||||
*/
|
||||
this.executeAtCenter = function() {
|
||||
_updatePositions();
|
||||
setOrigin([
|
||||
(minx + maxx) / 2,
|
||||
(miny + maxy) / 2
|
||||
]);
|
||||
_run();
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Magnetizer#executeAtEvent
|
||||
* @function
|
||||
* @desc Runs the magnetize routine using the location of the given event as the origin. To use this
|
||||
* method you need to have provided a `container`, and a `getContainerPosition` function to the
|
||||
* constructor.
|
||||
* @param {Event} e Event to get origin location from.
|
||||
*/
|
||||
this.executeAtEvent = function(e) {
|
||||
var c = params.container,
|
||||
o = params.getContainerPosition(c),
|
||||
x = e.pageX - o.left + c[0].scrollLeft,
|
||||
y = e.pageY - o.top + c[0].scrollTop;
|
||||
|
||||
if (debug) {
|
||||
originDebugMarker.style.left = e.pageX + "px";
|
||||
originDebugMarker.style.top = e.pageY + "px";
|
||||
}
|
||||
|
||||
this.execute([x,y]);
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Magnetize#setElements
|
||||
* @function
|
||||
* @desc Sets the current list of elements.
|
||||
* @param {Object[]} _els List of elements, in whatever format the magnetizer is setup to use.
|
||||
*/
|
||||
this.setElements = function(_els) {
|
||||
elements = _els;
|
||||
};
|
||||
|
||||
|
||||
if (debug)
|
||||
createOriginDebugger();
|
||||
|
||||
if (executeNow) this.execute();
|
||||
|
||||
};
|
||||
}).call(this);
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user