diff --git a/dist/vis.js b/dist/vis.js
index 7c960390..0b7be4d4 100644
--- a/dist/vis.js
+++ b/dist/vis.js
@@ -123,12 +123,12 @@ return /******/ (function(modules) { // webpackBootstrap
// Network
exports.Network = __webpack_require__(37);
exports.network = {
- Edge: __webpack_require__(43),
+ Edge: __webpack_require__(38),
Groups: __webpack_require__(40),
Images: __webpack_require__(41),
- Node: __webpack_require__(42),
- Popup: __webpack_require__(44),
- dotparser: __webpack_require__(39)
+ Node: __webpack_require__(39),
+ Popup: __webpack_require__(42),
+ dotparser: __webpack_require__(43)
};
// Deprecated since v3.0.0
@@ -5490,154 +5490,154 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ function(module, exports, __webpack_require__) {
var map = {
- "./ar": 56,
- "./ar-ma": 54,
- "./ar-ma.js": 54,
- "./ar-sa": 55,
- "./ar-sa.js": 55,
- "./ar.js": 56,
- "./az": 57,
- "./az.js": 57,
- "./bg": 58,
- "./bg.js": 58,
- "./bn": 59,
- "./bn.js": 59,
- "./br": 60,
- "./br.js": 60,
- "./bs": 61,
- "./bs.js": 61,
- "./ca": 62,
- "./ca.js": 62,
- "./cs": 63,
- "./cs.js": 63,
- "./cv": 64,
- "./cv.js": 64,
- "./cy": 65,
- "./cy.js": 65,
- "./da": 66,
- "./da.js": 66,
- "./de": 68,
- "./de-at": 67,
- "./de-at.js": 67,
- "./de.js": 68,
- "./el": 69,
- "./el.js": 69,
- "./en-au": 70,
- "./en-au.js": 70,
- "./en-ca": 71,
- "./en-ca.js": 71,
- "./en-gb": 72,
- "./en-gb.js": 72,
- "./eo": 73,
- "./eo.js": 73,
- "./es": 74,
- "./es.js": 74,
- "./et": 75,
- "./et.js": 75,
- "./eu": 76,
- "./eu.js": 76,
- "./fa": 77,
- "./fa.js": 77,
- "./fi": 78,
- "./fi.js": 78,
- "./fo": 79,
- "./fo.js": 79,
- "./fr": 81,
- "./fr-ca": 80,
- "./fr-ca.js": 80,
- "./fr.js": 81,
- "./gl": 82,
- "./gl.js": 82,
- "./he": 83,
- "./he.js": 83,
- "./hi": 84,
- "./hi.js": 84,
- "./hr": 85,
- "./hr.js": 85,
- "./hu": 86,
- "./hu.js": 86,
- "./hy-am": 87,
- "./hy-am.js": 87,
- "./id": 88,
- "./id.js": 88,
- "./is": 89,
- "./is.js": 89,
- "./it": 90,
- "./it.js": 90,
- "./ja": 91,
- "./ja.js": 91,
- "./ka": 92,
- "./ka.js": 92,
- "./km": 93,
- "./km.js": 93,
- "./ko": 94,
- "./ko.js": 94,
- "./lb": 95,
- "./lb.js": 95,
- "./lt": 96,
- "./lt.js": 96,
- "./lv": 97,
- "./lv.js": 97,
- "./mk": 98,
- "./mk.js": 98,
- "./ml": 99,
- "./ml.js": 99,
- "./mr": 100,
- "./mr.js": 100,
- "./ms-my": 101,
- "./ms-my.js": 101,
- "./nb": 102,
- "./nb.js": 102,
- "./ne": 103,
- "./ne.js": 103,
- "./nl": 104,
- "./nl.js": 104,
- "./nn": 105,
- "./nn.js": 105,
- "./pl": 106,
- "./pl.js": 106,
- "./pt": 108,
- "./pt-br": 107,
- "./pt-br.js": 107,
- "./pt.js": 108,
- "./ro": 109,
- "./ro.js": 109,
- "./ru": 110,
- "./ru.js": 110,
- "./sk": 111,
- "./sk.js": 111,
- "./sl": 112,
- "./sl.js": 112,
- "./sq": 113,
- "./sq.js": 113,
- "./sr": 115,
- "./sr-cyrl": 114,
- "./sr-cyrl.js": 114,
- "./sr.js": 115,
- "./sv": 116,
- "./sv.js": 116,
- "./ta": 117,
- "./ta.js": 117,
- "./th": 118,
- "./th.js": 118,
- "./tl-ph": 119,
- "./tl-ph.js": 119,
- "./tr": 120,
- "./tr.js": 120,
- "./tzm": 122,
- "./tzm-latn": 121,
- "./tzm-latn.js": 121,
- "./tzm.js": 122,
- "./uk": 123,
- "./uk.js": 123,
- "./uz": 124,
- "./uz.js": 124,
- "./vi": 125,
- "./vi.js": 125,
- "./zh-cn": 126,
- "./zh-cn.js": 126,
- "./zh-tw": 127,
- "./zh-tw.js": 127
+ "./ar": 46,
+ "./ar-ma": 44,
+ "./ar-ma.js": 44,
+ "./ar-sa": 45,
+ "./ar-sa.js": 45,
+ "./ar.js": 46,
+ "./az": 47,
+ "./az.js": 47,
+ "./bg": 48,
+ "./bg.js": 48,
+ "./bn": 49,
+ "./bn.js": 49,
+ "./br": 50,
+ "./br.js": 50,
+ "./bs": 51,
+ "./bs.js": 51,
+ "./ca": 52,
+ "./ca.js": 52,
+ "./cs": 53,
+ "./cs.js": 53,
+ "./cv": 54,
+ "./cv.js": 54,
+ "./cy": 55,
+ "./cy.js": 55,
+ "./da": 56,
+ "./da.js": 56,
+ "./de": 58,
+ "./de-at": 57,
+ "./de-at.js": 57,
+ "./de.js": 58,
+ "./el": 59,
+ "./el.js": 59,
+ "./en-au": 60,
+ "./en-au.js": 60,
+ "./en-ca": 61,
+ "./en-ca.js": 61,
+ "./en-gb": 62,
+ "./en-gb.js": 62,
+ "./eo": 63,
+ "./eo.js": 63,
+ "./es": 64,
+ "./es.js": 64,
+ "./et": 65,
+ "./et.js": 65,
+ "./eu": 66,
+ "./eu.js": 66,
+ "./fa": 67,
+ "./fa.js": 67,
+ "./fi": 68,
+ "./fi.js": 68,
+ "./fo": 69,
+ "./fo.js": 69,
+ "./fr": 71,
+ "./fr-ca": 70,
+ "./fr-ca.js": 70,
+ "./fr.js": 71,
+ "./gl": 72,
+ "./gl.js": 72,
+ "./he": 73,
+ "./he.js": 73,
+ "./hi": 74,
+ "./hi.js": 74,
+ "./hr": 75,
+ "./hr.js": 75,
+ "./hu": 76,
+ "./hu.js": 76,
+ "./hy-am": 77,
+ "./hy-am.js": 77,
+ "./id": 78,
+ "./id.js": 78,
+ "./is": 79,
+ "./is.js": 79,
+ "./it": 80,
+ "./it.js": 80,
+ "./ja": 81,
+ "./ja.js": 81,
+ "./ka": 82,
+ "./ka.js": 82,
+ "./km": 83,
+ "./km.js": 83,
+ "./ko": 84,
+ "./ko.js": 84,
+ "./lb": 85,
+ "./lb.js": 85,
+ "./lt": 86,
+ "./lt.js": 86,
+ "./lv": 87,
+ "./lv.js": 87,
+ "./mk": 88,
+ "./mk.js": 88,
+ "./ml": 89,
+ "./ml.js": 89,
+ "./mr": 90,
+ "./mr.js": 90,
+ "./ms-my": 91,
+ "./ms-my.js": 91,
+ "./nb": 92,
+ "./nb.js": 92,
+ "./ne": 93,
+ "./ne.js": 93,
+ "./nl": 94,
+ "./nl.js": 94,
+ "./nn": 95,
+ "./nn.js": 95,
+ "./pl": 96,
+ "./pl.js": 96,
+ "./pt": 98,
+ "./pt-br": 97,
+ "./pt-br.js": 97,
+ "./pt.js": 98,
+ "./ro": 99,
+ "./ro.js": 99,
+ "./ru": 100,
+ "./ru.js": 100,
+ "./sk": 101,
+ "./sk.js": 101,
+ "./sl": 102,
+ "./sl.js": 102,
+ "./sq": 103,
+ "./sq.js": 103,
+ "./sr": 105,
+ "./sr-cyrl": 104,
+ "./sr-cyrl.js": 104,
+ "./sr.js": 105,
+ "./sv": 106,
+ "./sv.js": 106,
+ "./ta": 107,
+ "./ta.js": 107,
+ "./th": 108,
+ "./th.js": 108,
+ "./tl-ph": 109,
+ "./tl-ph.js": 109,
+ "./tr": 110,
+ "./tr.js": 110,
+ "./tzm": 112,
+ "./tzm-latn": 111,
+ "./tzm-latn.js": 111,
+ "./tzm.js": 112,
+ "./uk": 113,
+ "./uk.js": 113,
+ "./uz": 114,
+ "./uz.js": 114,
+ "./vi": 115,
+ "./vi.js": 115,
+ "./zh-cn": 116,
+ "./zh-cn.js": 116,
+ "./zh-tw": 117,
+ "./zh-tw.js": 117
};
function webpackContext(req) {
return __webpack_require__(webpackContextResolve(req));
@@ -19077,20 +19077,20 @@ return /******/ (function(modules) { // webpackBootstrap
var Emitter = __webpack_require__(12);
var Hammer = __webpack_require__(3);
- var mousetrap = __webpack_require__(38);
+ var mousetrap = __webpack_require__(118);
var util = __webpack_require__(1);
var DataSet = __webpack_require__(9);
var DataView = __webpack_require__(10);
- var dotparser = __webpack_require__(39);
+ var dotparser = __webpack_require__(43);
var Groups = __webpack_require__(40);
var Images = __webpack_require__(41);
- var Node = __webpack_require__(42);
- var Edge = __webpack_require__(43);
- var Popup = __webpack_require__(44);
- var MixinLoader = __webpack_require__(45);
+ var Node = __webpack_require__(39);
+ var Edge = __webpack_require__(38);
+ var Popup = __webpack_require__(42);
+ var MixinLoader = __webpack_require__(119);
// Load custom shapes into CanvasRenderingContext2D
- __webpack_require__(53);
+ __webpack_require__(130);
/**
* @constructor Network
@@ -19263,7 +19263,7 @@ return /******/ (function(modules) { // webpackBootstrap
roundness: 0.5
},
dynamicSmoothCurves: true,
- maxVelocity: 10,
+ maxVelocity: 30,
minVelocity: 0.1, // px/s
stabilizationIterations: 1000, // maximum number of iteration to stabilize
labels:{
@@ -21425,16125 +21425,16125 @@ return /******/ (function(modules) { // webpackBootstrap
/* 38 */
/***/ function(module, exports, __webpack_require__) {
+ var util = __webpack_require__(1);
+ var Node = __webpack_require__(39);
+
/**
- * Copyright 2012 Craig Campbell
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Mousetrap is a simple keyboard shortcut library for Javascript with
- * no external dependencies
+ * @class Edge
*
- * @version 1.1.2
- * @url craig.is/killing/mice
+ * A edge connects two nodes
+ * @param {Object} properties Object with properties. Must contain
+ * At least properties from and to.
+ * Available properties: from (number),
+ * to (number), label (string, color (string),
+ * width (number), style (string),
+ * length (number), title (string)
+ * @param {Network} network A Network object, used to find and edge to
+ * nodes.
+ * @param {Object} constants An object with default values for
+ * example for the color
*/
+ function Edge (properties, network, constants) {
+ if (!network) {
+ throw "No network provided";
+ }
+ this.network = network;
- /**
- * mapping of special keycodes to their corresponding keys
- *
- * everything in this dictionary cannot use keypress events
- * so it has to be here to map to the correct keycodes for
- * keyup/keydown events
- *
- * @type {Object}
- */
- var _MAP = {
- 8: 'backspace',
- 9: 'tab',
- 13: 'enter',
- 16: 'shift',
- 17: 'ctrl',
- 18: 'alt',
- 20: 'capslock',
- 27: 'esc',
- 32: 'space',
- 33: 'pageup',
- 34: 'pagedown',
- 35: 'end',
- 36: 'home',
- 37: 'left',
- 38: 'up',
- 39: 'right',
- 40: 'down',
- 45: 'ins',
- 46: 'del',
- 91: 'meta',
- 93: 'meta',
- 224: 'meta'
- },
-
- /**
- * mapping for special characters so they can support
- *
- * this dictionary is only used incase you want to bind a
- * keyup or keydown event to one of these keys
- *
- * @type {Object}
- */
- _KEYCODE_MAP = {
- 106: '*',
- 107: '+',
- 109: '-',
- 110: '.',
- 111 : '/',
- 186: ';',
- 187: '=',
- 188: ',',
- 189: '-',
- 190: '.',
- 191: '/',
- 192: '`',
- 219: '[',
- 220: '\\',
- 221: ']',
- 222: '\''
- },
-
- /**
- * this is a mapping of keys that require shift on a US keypad
- * back to the non shift equivelents
- *
- * this is so you can use keyup events with these keys
- *
- * note that this will only work reliably on US keyboards
- *
- * @type {Object}
- */
- _SHIFT_MAP = {
- '~': '`',
- '!': '1',
- '@': '2',
- '#': '3',
- '$': '4',
- '%': '5',
- '^': '6',
- '&': '7',
- '*': '8',
- '(': '9',
- ')': '0',
- '_': '-',
- '+': '=',
- ':': ';',
- '\"': '\'',
- '<': ',',
- '>': '.',
- '?': '/',
- '|': '\\'
- },
+ // initialize constants
+ this.widthMin = constants.edges.widthMin;
+ this.widthMax = constants.edges.widthMax;
- /**
- * this is a list of special strings you can use to map
- * to modifier keys when you specify your keyboard shortcuts
- *
- * @type {Object}
- */
- _SPECIAL_ALIASES = {
- 'option': 'alt',
- 'command': 'meta',
- 'return': 'enter',
- 'escape': 'esc'
- },
+ // initialize variables
+ this.id = undefined;
+ this.fromId = undefined;
+ this.toId = undefined;
+ this.style = constants.edges.style;
+ this.title = undefined;
+ this.width = constants.edges.width;
+ this.widthSelectionMultiplier = constants.edges.widthSelectionMultiplier;
+ this.widthSelected = this.width * this.widthSelectionMultiplier;
+ this.hoverWidth = constants.edges.hoverWidth;
+ this.value = undefined;
+ this.length = constants.physics.springLength;
+ this.customLength = false;
+ this.selected = false;
+ this.hover = false;
+ this.smoothCurves = constants.smoothCurves;
+ this.dynamicSmoothCurves = constants.dynamicSmoothCurves;
+ this.arrowScaleFactor = constants.edges.arrowScaleFactor;
+ this.inheritColor = constants.edges.inheritColor;
- /**
- * variable to store the flipped version of _MAP from above
- * needed to check if we should use keypress or not when no action
- * is specified
- *
- * @type {Object|undefined}
- */
- _REVERSE_MAP,
+ this.from = null; // a node
+ this.to = null; // a node
+ this.via = null; // a temp node
- /**
- * a list of all the callbacks setup via Mousetrap.bind()
- *
- * @type {Object}
- */
- _callbacks = {},
+ // we use this to be able to reconnect the edge to a cluster if its node is put into a cluster
+ // by storing the original information we can revert to the original connection when the cluser is opened.
+ this.originalFromId = [];
+ this.originalToId = [];
- /**
- * direct map of string combinations to callbacks used for trigger()
- *
- * @type {Object}
- */
- _direct_map = {},
+ this.connected = false;
- /**
- * keeps track of what level each sequence is at since multiple
- * sequences can start out with the same sequence
- *
- * @type {Object}
- */
- _sequence_levels = {},
+ // Added to support dashed lines
+ // David Jordan
+ // 2012-08-08
+ this.dash = util.extend({}, constants.edges.dash); // contains properties length, gap, altLength
- /**
- * variable to store the setTimeout call
- *
- * @type {null|number}
- */
- _reset_timer,
+ this.color = {color:constants.edges.color.color,
+ highlight:constants.edges.color.highlight,
+ hover:constants.edges.color.hover};
+ this.widthFixed = false;
+ this.lengthFixed = false;
- /**
- * temporary state where we will ignore the next keyup
- *
- * @type {boolean|string}
- */
- _ignore_next_keyup = false,
+ this.setProperties(properties, constants);
- /**
- * are we currently inside of a sequence?
- * type of action ("keyup" or "keydown" or "keypress") or false
- *
- * @type {boolean|string}
- */
- _inside_sequence = false;
+ this.controlNodesEnabled = false;
+ this.controlNodes = {from:null, to:null, positions:{}};
+ this.connectedNode = null;
+ }
- /**
- * loop through the f keys, f1 to f19 and add them to the map
- * programatically
- */
- for (var i = 1; i < 20; ++i) {
- _MAP[111 + i] = 'f' + i;
+ /**
+ * Set or overwrite properties for the edge
+ * @param {Object} properties an object with properties
+ * @param {Object} constants and object with default, global properties
+ */
+ Edge.prototype.setProperties = function(properties, constants) {
+ if (!properties) {
+ return;
}
- /**
- * loop through to map numbers on the numeric keypad
- */
- for (i = 0; i <= 9; ++i) {
- _MAP[i + 96] = i;
- }
+ if (properties.from !== undefined) {this.fromId = properties.from;}
+ if (properties.to !== undefined) {this.toId = properties.to;}
- /**
- * cross browser add event method
- *
- * @param {Element|HTMLDocument} object
- * @param {string} type
- * @param {Function} callback
- * @returns void
- */
- function _addEvent(object, type, callback) {
- if (object.addEventListener) {
- return object.addEventListener(type, callback, false);
- }
+ if (properties.id !== undefined) {this.id = properties.id;}
+ if (properties.style !== undefined) {this.style = properties.style;}
+ if (properties.label !== undefined) {this.label = properties.label;}
- object.attachEvent('on' + type, callback);
+ if (this.label) {
+ this.fontSize = constants.edges.fontSize;
+ this.fontFace = constants.edges.fontFace;
+ this.fontColor = constants.edges.fontColor;
+ this.fontFill = constants.edges.fontFill;
+
+ if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;}
+ if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
+ if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
+ if (properties.fontFill !== undefined) {this.fontFill = properties.fontFill;}
}
- /**
- * takes the event and returns the key character
- *
- * @param {Event} e
- * @return {string}
- */
- function _characterFromEvent(e) {
+ if (properties.title !== undefined) {this.title = properties.title;}
+ if (properties.width !== undefined) {this.width = properties.width;}
+ if (properties.widthSelectionMultiplier !== undefined)
+ {this.widthSelectionMultiplier = properties.widthSelectionMultiplier;}
+ if (properties.hoverWidth !== undefined) {this.hoverWidth = properties.hoverWidth;}
+ if (properties.value !== undefined) {this.value = properties.value;}
+ if (properties.length !== undefined) {this.length = properties.length;
+ this.customLength = true;}
- // for keypress events we should return the character as is
- if (e.type == 'keypress') {
- return String.fromCharCode(e.which);
- }
+ // scale the arrow
+ if (properties.arrowScaleFactor !== undefined) {this.arrowScaleFactor = properties.arrowScaleFactor;}
- // for non keypress events the special maps are needed
- if (_MAP[e.which]) {
- return _MAP[e.which];
- }
+ if (properties.inheritColor !== undefined) {this.inheritColor = properties.inheritColor;}
- if (_KEYCODE_MAP[e.which]) {
- return _KEYCODE_MAP[e.which];
- }
+ // Added to support dashed lines
+ // David Jordan
+ // 2012-08-08
+ if (properties.dash) {
+ if (properties.dash.length !== undefined) {this.dash.length = properties.dash.length;}
+ if (properties.dash.gap !== undefined) {this.dash.gap = properties.dash.gap;}
+ if (properties.dash.altLength !== undefined) {this.dash.altLength = properties.dash.altLength;}
+ }
- // if it is not in the special map
- return String.fromCharCode(e.which).toLowerCase();
+ if (properties.color !== undefined) {
+ if (util.isString(properties.color)) {
+ this.color.color = properties.color;
+ this.color.highlight = properties.color;
+ }
+ else {
+ if (properties.color.color !== undefined) {this.color.color = properties.color.color;}
+ if (properties.color.highlight !== undefined) {this.color.highlight = properties.color.highlight;}
+ if (properties.color.hover !== undefined) {this.color.hover = properties.color.hover;}
+ }
}
- /**
- * should we stop this event before firing off callbacks
- *
- * @param {Event} e
- * @return {boolean}
- */
- function _stop(e) {
- var element = e.target || e.srcElement,
- tag_name = element.tagName;
+ // A node is connected when it has a from and to node.
+ this.connect();
- // if the element has the class "mousetrap" then no need to stop
- if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
- return false;
- }
+ this.widthFixed = this.widthFixed || (properties.width !== undefined);
+ this.lengthFixed = this.lengthFixed || (properties.length !== undefined);
- // stop for input, select, and textarea
- return tag_name == 'INPUT' || tag_name == 'SELECT' || tag_name == 'TEXTAREA' || (element.contentEditable && element.contentEditable == 'true');
- }
+ this.widthSelected = this.width * this.widthSelectionMultiplier;
- /**
- * checks if two arrays are equal
- *
- * @param {Array} modifiers1
- * @param {Array} modifiers2
- * @returns {boolean}
- */
- function _modifiersMatch(modifiers1, modifiers2) {
- return modifiers1.sort().join(',') === modifiers2.sort().join(',');
+ // set draw method based on style
+ switch (this.style) {
+ case 'line': this.draw = this._drawLine; break;
+ case 'arrow': this.draw = this._drawArrow; break;
+ case 'arrow-center': this.draw = this._drawArrowCenter; break;
+ case 'dash-line': this.draw = this._drawDashLine; break;
+ default: this.draw = this._drawLine; break;
}
+ };
- /**
- * resets all sequence counters except for the ones passed in
- *
- * @param {Object} do_not_reset
- * @returns void
- */
- function _resetSequences(do_not_reset) {
- do_not_reset = do_not_reset || {};
+ /**
+ * Connect an edge to its nodes
+ */
+ Edge.prototype.connect = function () {
+ this.disconnect();
- var active_sequences = false,
- key;
+ this.from = this.network.nodes[this.fromId] || null;
+ this.to = this.network.nodes[this.toId] || null;
+ this.connected = (this.from && this.to);
- for (key in _sequence_levels) {
- if (do_not_reset[key]) {
- active_sequences = true;
- continue;
- }
- _sequence_levels[key] = 0;
- }
+ if (this.connected) {
+ this.from.attachEdge(this);
+ this.to.attachEdge(this);
+ }
+ else {
+ if (this.from) {
+ this.from.detachEdge(this);
+ }
+ if (this.to) {
+ this.to.detachEdge(this);
+ }
+ }
+ };
- if (!active_sequences) {
- _inside_sequence = false;
- }
+ /**
+ * Disconnect an edge from its nodes
+ */
+ Edge.prototype.disconnect = function () {
+ if (this.from) {
+ this.from.detachEdge(this);
+ this.from = null;
+ }
+ if (this.to) {
+ this.to.detachEdge(this);
+ this.to = null;
}
- /**
- * finds all callbacks that match based on the keycode, modifiers,
- * and action
- *
- * @param {string} character
- * @param {Array} modifiers
- * @param {string} action
- * @param {boolean=} remove - should we remove any matches
- * @param {string=} combination
- * @returns {Array}
- */
- function _getMatches(character, modifiers, action, remove, combination) {
- var i,
- callback,
- matches = [];
+ this.connected = false;
+ };
- // if there are no events related to this keycode
- if (!_callbacks[character]) {
- return [];
- }
+ /**
+ * get the title of this edge.
+ * @return {string} title The title of the edge, or undefined when no title
+ * has been set.
+ */
+ Edge.prototype.getTitle = function() {
+ return typeof this.title === "function" ? this.title() : this.title;
+ };
- // if a modifier key is coming up on its own we should allow it
- if (action == 'keyup' && _isModifier(character)) {
- modifiers = [character];
- }
- // loop through all callbacks for the key that was pressed
- // and see if any of them match
- for (i = 0; i < _callbacks[character].length; ++i) {
- callback = _callbacks[character][i];
+ /**
+ * Retrieve the value of the edge. Can be undefined
+ * @return {Number} value
+ */
+ Edge.prototype.getValue = function() {
+ return this.value;
+ };
- // if this is a sequence but it is not at the right level
- // then move onto the next match
- if (callback.seq && _sequence_levels[callback.seq] != callback.level) {
- continue;
- }
+ /**
+ * Adjust the value range of the edge. The edge will adjust it's width
+ * based on its value.
+ * @param {Number} min
+ * @param {Number} max
+ */
+ Edge.prototype.setValueRange = function(min, max) {
+ if (!this.widthFixed && this.value !== undefined) {
+ var scale = (this.widthMax - this.widthMin) / (max - min);
+ this.width = (this.value - min) * scale + this.widthMin;
+ }
+ };
- // if the action we are looking for doesn't match the action we got
- // then we should keep going
- if (action != callback.action) {
- continue;
- }
+ /**
+ * Redraw a edge
+ * Draw this edge in the given canvas
+ * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
+ * @param {CanvasRenderingContext2D} ctx
+ */
+ Edge.prototype.draw = function(ctx) {
+ throw "Method draw not initialized in edge";
+ };
- // if this is a keypress event that means that we need to only
- // look at the character, otherwise check the modifiers as
- // well
- if (action == 'keypress' || _modifiersMatch(modifiers, callback.modifiers)) {
+ /**
+ * Check if this object is overlapping with the provided object
+ * @param {Object} obj an object with parameters left, top
+ * @return {boolean} True if location is located on the edge
+ */
+ Edge.prototype.isOverlappingWith = function(obj) {
+ if (this.connected) {
+ var distMax = 10;
+ var xFrom = this.from.x;
+ var yFrom = this.from.y;
+ var xTo = this.to.x;
+ var yTo = this.to.y;
+ var xObj = obj.left;
+ var yObj = obj.top;
- // remove is used so if you change your mind and call bind a
- // second time with a new function the first one is overwritten
- if (remove && callback.combo == combination) {
- _callbacks[character].splice(i, 1);
- }
+ var dist = this._getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
- matches.push(callback);
- }
- }
+ return (dist < distMax);
+ }
+ else {
+ return false
+ }
+ };
- return matches;
+ Edge.prototype._getColor = function() {
+ var colorObj = this.color;
+ if (this.inheritColor == "to") {
+ colorObj = {
+ highlight: this.to.color.highlight.border,
+ hover: this.to.color.hover.border,
+ color: this.to.color.border
+ };
+ }
+ else if (this.inheritColor == "from" || this.inheritColor == true) {
+ colorObj = {
+ highlight: this.from.color.highlight.border,
+ hover: this.from.color.hover.border,
+ color: this.from.color.border
+ };
}
- /**
- * takes a key event and figures out what the modifiers are
- *
- * @param {Event} e
- * @returns {Array}
- */
- function _eventModifiers(e) {
- var modifiers = [];
+ if (this.selected == true) {return colorObj.highlight;}
+ else if (this.hover == true) {return colorObj.hover;}
+ else {return colorObj.color;}
+ }
- if (e.shiftKey) {
- modifiers.push('shift');
- }
- if (e.altKey) {
- modifiers.push('alt');
- }
+ /**
+ * Redraw a edge as a line
+ * Draw this edge in the given canvas
+ * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
+ * @param {CanvasRenderingContext2D} ctx
+ * @private
+ */
+ Edge.prototype._drawLine = function(ctx) {
+ // set style
+ ctx.strokeStyle = this._getColor();
+ ctx.lineWidth = this._getLineWidth();
- if (e.ctrlKey) {
- modifiers.push('ctrl');
- }
+ if (this.from != this.to) {
+ // draw line
+ var via = this._line(ctx);
- if (e.metaKey) {
- modifiers.push('meta');
+ // draw label
+ var point;
+ if (this.label) {
+ if (this.smoothCurves.enabled == true && via != null) {
+ var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
+ var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
+ point = {x:midpointX, y:midpointY};
}
-
- return modifiers;
+ else {
+ point = this._pointOnLine(0.5);
+ }
+ this._label(ctx, this.label, point.x, point.y);
+ }
+ }
+ else {
+ var x, y;
+ var radius = this.length / 4;
+ var node = this.from;
+ if (!node.width) {
+ node.resize(ctx);
+ }
+ if (node.width > node.height) {
+ x = node.x + node.width / 2;
+ y = node.y - radius;
+ }
+ else {
+ x = node.x + radius;
+ y = node.y - node.height / 2;
+ }
+ this._circle(ctx, x, y, radius);
+ point = this._pointOnCircle(x, y, radius, 0.5);
+ this._label(ctx, this.label, point.x, point.y);
}
+ };
- /**
- * actually calls the callback function
- *
- * if your callback function returns false this will use the jquery
- * convention - prevent default and stop propogation on the event
- *
- * @param {Function} callback
- * @param {Event} e
- * @returns void
- */
- function _fireCallback(callback, e) {
- if (callback(e) === false) {
- if (e.preventDefault) {
- e.preventDefault();
- }
+ /**
+ * Get the line width of the edge. Depends on width and whether one of the
+ * connected nodes is selected.
+ * @return {Number} width
+ * @private
+ */
+ Edge.prototype._getLineWidth = function() {
+ if (this.selected == true) {
+ return Math.min(this.widthSelected, this.widthMax)*this.networkScaleInv;
+ }
+ else {
+ if (this.hover == true) {
+ return Math.min(this.hoverWidth, this.widthMax)*this.networkScaleInv;
+ }
+ else {
+ return this.width*this.networkScaleInv;
+ }
+ }
+ };
- if (e.stopPropagation) {
- e.stopPropagation();
- }
+ Edge.prototype._getViaCoordinates = function () {
+ var xVia = null;
+ var yVia = null;
+ var factor = this.smoothCurves.roundness;
+ var type = this.smoothCurves.type;
+ if (factor == 0) {
+ return {x:null,y:null};
+ }
- e.returnValue = false;
- e.cancelBubble = true;
+ var dx = Math.abs(this.from.x - this.to.x);
+ var dy = Math.abs(this.from.y - this.to.y);
+ if (type == 'discrete' || type == 'diagonalCross') {
+ if (Math.abs(this.from.x - this.to.x) < Math.abs(this.from.y - this.to.y)) {
+ if (this.from.y > this.to.y) {
+ if (this.from.x < this.to.x) {
+ xVia = this.from.x + factor * dy;
+ yVia = this.from.y - factor * dy;
+ }
+ else if (this.from.x > this.to.x) {
+ xVia = this.from.x - factor * dy;
+ yVia = this.from.y - factor * dy;
+ }
+ }
+ else if (this.from.y < this.to.y) {
+ if (this.from.x < this.to.x) {
+ xVia = this.from.x + factor * dy;
+ yVia = this.from.y + factor * dy;
+ }
+ else if (this.from.x > this.to.x) {
+ xVia = this.from.x - factor * dy;
+ yVia = this.from.y + factor * dy;
+ }
+ }
+ if (type == "discrete") {
+ xVia = dx < factor * dy ? this.from.x : xVia;
+ }
+ }
+ else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) {
+ if (this.from.y > this.to.y) {
+ if (this.from.x < this.to.x) {
+ xVia = this.from.x + factor * dx;
+ yVia = this.from.y - factor * dx;
+ }
+ else if (this.from.x > this.to.x) {
+ xVia = this.from.x - factor * dx;
+ yVia = this.from.y - factor * dx;
+ }
+ }
+ else if (this.from.y < this.to.y) {
+ if (this.from.x < this.to.x) {
+ xVia = this.from.x + factor * dx;
+ yVia = this.from.y + factor * dx;
+ }
+ else if (this.from.x > this.to.x) {
+ xVia = this.from.x - factor * dx;
+ yVia = this.from.y + factor * dx;
+ }
}
+ if (type == "discrete") {
+ yVia = dy < factor * dx ? this.from.y : yVia;
+ }
+ }
}
-
- /**
- * handles a character key event
- *
- * @param {string} character
- * @param {Event} e
- * @returns void
- */
- function _handleCharacter(character, e) {
-
- // if this event should not happen stop here
- if (_stop(e)) {
- return;
+ else if (type == "straightCross") {
+ if (Math.abs(this.from.x - this.to.x) < Math.abs(this.from.y - this.to.y)) {
+ xVia = this.from.x;
+ yVia = this.to.y
+ }
+ else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) {
+ xVia = this.to.x;
+ yVia = this.from.y;
+ }
+ }
+ else if (type == 'horizontal') {
+ xVia = this.to.x;
+ yVia = this.from.y;
+ }
+ else if (type == 'vertical') {
+ xVia = this.from.x;
+ yVia = this.to.y;
+ }
+ else { // continuous
+ if (Math.abs(this.from.x - this.to.x) < Math.abs(this.from.y - this.to.y)) {
+ if (this.from.y > this.to.y) {
+ if (this.from.x < this.to.x) {
+ // console.log(1)
+ xVia = this.from.x + factor * dy;
+ yVia = this.from.y - factor * dy;
+ xVia = this.to.x < xVia ? this.to.x : xVia;
+ }
+ else if (this.from.x > this.to.x) {
+ // console.log(2)
+ xVia = this.from.x - factor * dy;
+ yVia = this.from.y - factor * dy;
+ xVia = this.to.x > xVia ? this.to.x :xVia;
+ }
}
-
- var callbacks = _getMatches(character, _eventModifiers(e), e.type),
- i,
- do_not_reset = {},
- processed_sequence_callback = false;
-
- // loop through matching callbacks for this key event
- for (i = 0; i < callbacks.length; ++i) {
-
- // fire for all sequence callbacks
- // this is because if for example you have multiple sequences
- // bound such as "g i" and "g t" they both need to fire the
- // callback for matching g cause otherwise you can only ever
- // match the first one
- if (callbacks[i].seq) {
- processed_sequence_callback = true;
-
- // keep a list of which sequences were matches for later
- do_not_reset[callbacks[i].seq] = 1;
- _fireCallback(callbacks[i].callback, e);
- continue;
- }
-
- // if there were no sequence matches but we are still here
- // that means this is a regular match so we should fire that
- if (!processed_sequence_callback && !_inside_sequence) {
- _fireCallback(callbacks[i].callback, e);
- }
+ else if (this.from.y < this.to.y) {
+ if (this.from.x < this.to.x) {
+ // console.log(3)
+ xVia = this.from.x + factor * dy;
+ yVia = this.from.y + factor * dy;
+ xVia = this.to.x < xVia ? this.to.x : xVia;
+ }
+ else if (this.from.x > this.to.x) {
+ // console.log(4, this.from.x, this.to.x)
+ xVia = this.from.x - factor * dy;
+ yVia = this.from.y + factor * dy;
+ xVia = this.to.x > xVia ? this.to.x : xVia;
+ }
}
-
- // if you are inside of a sequence and the key you are pressing
- // is not a modifier key then we should reset all sequences
- // that were not matched by this key event
- if (e.type == _inside_sequence && !_isModifier(character)) {
- _resetSequences(do_not_reset);
+ }
+ else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) {
+ if (this.from.y > this.to.y) {
+ if (this.from.x < this.to.x) {
+ // console.log(5)
+ xVia = this.from.x + factor * dx;
+ yVia = this.from.y - factor * dx;
+ yVia = this.to.y > yVia ? this.to.y : yVia;
+ }
+ else if (this.from.x > this.to.x) {
+ // console.log(6)
+ xVia = this.from.x - factor * dx;
+ yVia = this.from.y - factor * dx;
+ yVia = this.to.y > yVia ? this.to.y : yVia;
+ }
+ }
+ else if (this.from.y < this.to.y) {
+ if (this.from.x < this.to.x) {
+ // console.log(7)
+ xVia = this.from.x + factor * dx;
+ yVia = this.from.y + factor * dx;
+ yVia = this.to.y < yVia ? this.to.y : yVia;
+ }
+ else if (this.from.x > this.to.x) {
+ // console.log(8)
+ xVia = this.from.x - factor * dx;
+ yVia = this.from.y + factor * dx;
+ yVia = this.to.y < yVia ? this.to.y : yVia;
+ }
}
+ }
}
- /**
- * handles a keydown event
- *
- * @param {Event} e
- * @returns void
- */
- function _handleKey(e) {
-
- // normalize e.which for key events
- // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion
- e.which = typeof e.which == "number" ? e.which : e.keyCode;
- var character = _characterFromEvent(e);
+ return {x:xVia, y:yVia};
+ }
- // no character found then stop
- if (!character) {
- return;
+ /**
+ * Draw a line between two nodes
+ * @param {CanvasRenderingContext2D} ctx
+ * @private
+ */
+ Edge.prototype._line = function (ctx) {
+ // draw a straight line
+ ctx.beginPath();
+ ctx.moveTo(this.from.x, this.from.y);
+ if (this.smoothCurves.enabled == true) {
+ if (this.smoothCurves.dynamic == false) {
+ var via = this._getViaCoordinates();
+ if (via.x == null) {
+ ctx.lineTo(this.to.x, this.to.y);
+ ctx.stroke();
+ return null;
}
-
- if (e.type == 'keyup' && _ignore_next_keyup == character) {
- _ignore_next_keyup = false;
- return;
+ else {
+ // this.via.x = via.x;
+ // this.via.y = via.y;
+ ctx.quadraticCurveTo(via.x,via.y,this.to.x, this.to.y);
+ ctx.stroke();
+ return via;
}
-
- _handleCharacter(character, e);
+ }
+ else {
+ ctx.quadraticCurveTo(this.via.x,this.via.y,this.to.x, this.to.y);
+ ctx.stroke();
+ return this.via;
+ }
}
-
- /**
- * determines if the keycode specified is a modifier key or not
- *
- * @param {string} key
- * @returns {boolean}
- */
- function _isModifier(key) {
- return key == 'shift' || key == 'ctrl' || key == 'alt' || key == 'meta';
+ else {
+ ctx.lineTo(this.to.x, this.to.y);
+ ctx.stroke();
+ return null;
}
+ };
- /**
- * called to set a 1 second timeout on the specified sequence
- *
- * this is so after each key press in the sequence you have 1 second
- * to press the next key before you have to start over
- *
- * @returns void
- */
- function _resetSequenceTimer() {
- clearTimeout(_reset_timer);
- _reset_timer = setTimeout(_resetSequences, 1000);
- }
+ /**
+ * Draw a line from a node to itself, a circle
+ * @param {CanvasRenderingContext2D} ctx
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} radius
+ * @private
+ */
+ Edge.prototype._circle = function (ctx, x, y, radius) {
+ // draw a circle
+ ctx.beginPath();
+ ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
+ ctx.stroke();
+ };
- /**
- * reverses the map lookup so that we can look for specific keys
- * to see what can and can't use keypress
- *
- * @return {Object}
- */
- function _getReverseMap() {
- if (!_REVERSE_MAP) {
- _REVERSE_MAP = {};
- for (var key in _MAP) {
+ /**
+ * Draw label with white background and with the middle at (x, y)
+ * @param {CanvasRenderingContext2D} ctx
+ * @param {String} text
+ * @param {Number} x
+ * @param {Number} y
+ * @private
+ */
+ Edge.prototype._label = function (ctx, text, x, y) {
+ if (text) {
+ // TODO: cache the calculated size
+ ctx.font = ((this.from.selected || this.to.selected) ? "bold " : "") +
+ this.fontSize + "px " + this.fontFace;
+ ctx.fillStyle = this.fontFill;
+ var width = ctx.measureText(text).width;
+ var height = this.fontSize;
+ var left = x - width / 2;
+ var top = y - height / 2;
- // pull out the numeric keypad from here cause keypress should
- // be able to detect the keys from the character
- if (key > 95 && key < 112) {
- continue;
- }
+ ctx.fillRect(left, top, width, height);
- if (_MAP.hasOwnProperty(key)) {
- _REVERSE_MAP[_MAP[key]] = key;
- }
- }
- }
- return _REVERSE_MAP;
+ // draw text
+ ctx.fillStyle = this.fontColor || "black";
+ ctx.textAlign = "left";
+ ctx.textBaseline = "top";
+ ctx.fillText(text, left, top);
}
+ };
- /**
- * picks the best action based on the key combination
- *
- * @param {string} key - character for key
- * @param {Array} modifiers
- * @param {string=} action passed in
- */
- function _pickBestAction(key, modifiers, action) {
+ /**
+ * Redraw a edge as a dashed line
+ * Draw this edge in the given canvas
+ * @author David Jordan
+ * @date 2012-08-08
+ * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
+ * @param {CanvasRenderingContext2D} ctx
+ * @private
+ */
+ Edge.prototype._drawDashLine = function(ctx) {
+ // set style
+ if (this.selected == true) {ctx.strokeStyle = this.color.highlight;}
+ else if (this.hover == true) {ctx.strokeStyle = this.color.hover;}
+ else {ctx.strokeStyle = this.color.color;}
- // if no action was picked in we should try to pick the one
- // that we think would work best for this key
- if (!action) {
- action = _getReverseMap()[key] ? 'keydown' : 'keypress';
- }
+ ctx.lineWidth = this._getLineWidth();
- // modifier keys don't work as expected with keypress,
- // switch to keydown
- if (action == 'keypress' && modifiers.length) {
- action = 'keydown';
- }
+ var via = null;
+ // only firefox and chrome support this method, else we use the legacy one.
+ if (ctx.mozDash !== undefined || ctx.setLineDash !== undefined) {
+ // configure the dash pattern
+ var pattern = [0];
+ if (this.dash.length !== undefined && this.dash.gap !== undefined) {
+ pattern = [this.dash.length,this.dash.gap];
+ }
+ else {
+ pattern = [5,5];
+ }
- return action;
- }
+ // set dash settings for chrome or firefox
+ if (typeof ctx.setLineDash !== 'undefined') { //Chrome
+ ctx.setLineDash(pattern);
+ ctx.lineDashOffset = 0;
- /**
- * binds a key sequence to an event
- *
- * @param {string} combo - combo specified in bind call
- * @param {Array} keys
- * @param {Function} callback
- * @param {string=} action
- * @returns void
- */
- function _bindSequence(combo, keys, callback, action) {
-
- // start off by adding a sequence level record for this combination
- // and setting the level to 0
- _sequence_levels[combo] = 0;
-
- // if there is no action pick the best one for the first key
- // in the sequence
- if (!action) {
- action = _pickBestAction(keys[0], []);
- }
+ } else { //Firefox
+ ctx.mozDash = pattern;
+ ctx.mozDashOffset = 0;
+ }
- /**
- * callback to increase the sequence level for this sequence and reset
- * all other sequences that were active
- *
- * @param {Event} e
- * @returns void
- */
- var _increaseSequence = function(e) {
- _inside_sequence = action;
- ++_sequence_levels[combo];
- _resetSequenceTimer();
- },
+ // draw the line
+ via = this._line(ctx);
- /**
- * wraps the specified callback inside of another function in order
- * to reset all sequence counters as soon as this sequence is done
- *
- * @param {Event} e
- * @returns void
- */
- _callbackAndReset = function(e) {
- _fireCallback(callback, e);
+ // restore the dash settings.
+ if (typeof ctx.setLineDash !== 'undefined') { //Chrome
+ ctx.setLineDash([0]);
+ ctx.lineDashOffset = 0;
- // we should ignore the next key up if the action is key down
- // or keypress. this is so if you finish a sequence and
- // release the key the final key will not trigger a keyup
- if (action !== 'keyup') {
- _ignore_next_keyup = _characterFromEvent(e);
- }
+ } else { //Firefox
+ ctx.mozDash = [0];
+ ctx.mozDashOffset = 0;
+ }
+ }
+ else { // unsupporting smooth lines
+ // draw dashed line
+ ctx.beginPath();
+ ctx.lineCap = 'round';
+ if (this.dash.altLength !== undefined) //If an alt dash value has been set add to the array this value
+ {
+ ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
+ [this.dash.length,this.dash.gap,this.dash.altLength,this.dash.gap]);
+ }
+ else if (this.dash.length !== undefined && this.dash.gap !== undefined) //If a dash and gap value has been set add to the array this value
+ {
+ ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
+ [this.dash.length,this.dash.gap]);
+ }
+ else //If all else fails draw a line
+ {
+ ctx.moveTo(this.from.x, this.from.y);
+ ctx.lineTo(this.to.x, this.to.y);
+ }
+ ctx.stroke();
+ }
- // weird race condition if a sequence ends with the key
- // another sequence begins with
- setTimeout(_resetSequences, 10);
- },
- i;
+ // draw label
+ if (this.label) {
+ var point;
+ if (this.smoothCurves.enabled == true && via != null) {
+ var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
+ var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
+ point = {x:midpointX, y:midpointY};
+ }
+ else {
+ point = this._pointOnLine(0.5);
+ }
+ this._label(ctx, this.label, point.x, point.y);
+ }
+ };
- // loop through keys one at a time and bind the appropriate callback
- // function. for any key leading up to the final one it should
- // increase the sequence. after the final, it should reset all sequences
- for (i = 0; i < keys.length; ++i) {
- _bindSingle(keys[i], i < keys.length - 1 ? _increaseSequence : _callbackAndReset, action, combo, i);
- }
+ /**
+ * Get a point on a line
+ * @param {Number} percentage. Value between 0 (line start) and 1 (line end)
+ * @return {Object} point
+ * @private
+ */
+ Edge.prototype._pointOnLine = function (percentage) {
+ return {
+ x: (1 - percentage) * this.from.x + percentage * this.to.x,
+ y: (1 - percentage) * this.from.y + percentage * this.to.y
}
+ };
- /**
- * binds a single keyboard combination
- *
- * @param {string} combination
- * @param {Function} callback
- * @param {string=} action
- * @param {string=} sequence_name - name of sequence if part of sequence
- * @param {number=} level - what part of the sequence the command is
- * @returns void
- */
- function _bindSingle(combination, callback, action, sequence_name, level) {
+ /**
+ * Get a point on a circle
+ * @param {Number} x
+ * @param {Number} y
+ * @param {Number} radius
+ * @param {Number} percentage. Value between 0 (line start) and 1 (line end)
+ * @return {Object} point
+ * @private
+ */
+ Edge.prototype._pointOnCircle = function (x, y, radius, percentage) {
+ var angle = (percentage - 3/8) * 2 * Math.PI;
+ return {
+ x: x + radius * Math.cos(angle),
+ y: y - radius * Math.sin(angle)
+ }
+ };
- // make sure multiple spaces in a row become a single space
- combination = combination.replace(/\s+/g, ' ');
+ /**
+ * Redraw a edge as a line with an arrow halfway the line
+ * Draw this edge in the given canvas
+ * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
+ * @param {CanvasRenderingContext2D} ctx
+ * @private
+ */
+ Edge.prototype._drawArrowCenter = function(ctx) {
+ var point;
+ // set style
+ if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
+ else if (this.hover == true) {ctx.strokeStyle = this.color.hover; ctx.fillStyle = this.color.hover;}
+ else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
+ ctx.lineWidth = this._getLineWidth();
- var sequence = combination.split(' '),
- i,
- key,
- keys,
- modifiers = [];
+ if (this.from != this.to) {
+ // draw line
+ var via = this._line(ctx);
- // if this pattern is a sequence of keys then run through this method
- // to reprocess each pattern one key at a time
- if (sequence.length > 1) {
- return _bindSequence(combination, sequence, callback, action);
- }
+ var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
+ var length = (10 + 5 * this.width) * this.arrowScaleFactor;
+ // draw an arrow halfway the line
+ if (this.smoothCurves.enabled == true && via != null) {
+ var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
+ var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
+ point = {x:midpointX, y:midpointY};
+ }
+ else {
+ point = this._pointOnLine(0.5);
+ }
- // take the keys from this pattern and figure out what the actual
- // pattern is all about
- keys = combination === '+' ? ['+'] : combination.split('+');
+ ctx.arrow(point.x, point.y, angle, length);
+ ctx.fill();
+ ctx.stroke();
- for (i = 0; i < keys.length; ++i) {
- key = keys[i];
+ // draw label
+ if (this.label) {
+ this._label(ctx, this.label, point.x, point.y);
+ }
+ }
+ else {
+ // draw circle
+ var x, y;
+ var radius = 0.25 * Math.max(100,this.length);
+ var node = this.from;
+ if (!node.width) {
+ node.resize(ctx);
+ }
+ if (node.width > node.height) {
+ x = node.x + node.width * 0.5;
+ y = node.y - radius;
+ }
+ else {
+ x = node.x + radius;
+ y = node.y - node.height * 0.5;
+ }
+ this._circle(ctx, x, y, radius);
- // normalize key names
- if (_SPECIAL_ALIASES[key]) {
- key = _SPECIAL_ALIASES[key];
- }
+ // draw all arrows
+ var angle = 0.2 * Math.PI;
+ var length = (10 + 5 * this.width) * this.arrowScaleFactor;
+ point = this._pointOnCircle(x, y, radius, 0.5);
+ ctx.arrow(point.x, point.y, angle, length);
+ ctx.fill();
+ ctx.stroke();
- // if this is not a keypress event then we should
- // be smart about using shift keys
- // this will only work for US keyboards however
- if (action && action != 'keypress' && _SHIFT_MAP[key]) {
- key = _SHIFT_MAP[key];
- modifiers.push('shift');
- }
+ // draw label
+ if (this.label) {
+ point = this._pointOnCircle(x, y, radius, 0.5);
+ this._label(ctx, this.label, point.x, point.y);
+ }
+ }
+ };
- // if this key is a modifier then add it to the list of modifiers
- if (_isModifier(key)) {
- modifiers.push(key);
- }
- }
- // depending on what the key combination is
- // we will try to pick the best event for it
- action = _pickBestAction(key, modifiers, action);
- // make sure to initialize array if this is the first time
- // a callback is added for this key
- if (!_callbacks[key]) {
- _callbacks[key] = [];
- }
+ /**
+ * Redraw a edge as a line with an arrow
+ * Draw this edge in the given canvas
+ * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
+ * @param {CanvasRenderingContext2D} ctx
+ * @private
+ */
+ Edge.prototype._drawArrow = function(ctx) {
+ // set style
+ if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
+ else if (this.hover == true) {ctx.strokeStyle = this.color.hover; ctx.fillStyle = this.color.hover;}
+ else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
- // remove an existing match if there is one
- _getMatches(key, modifiers, action, !sequence_name, combination);
+ ctx.lineWidth = this._getLineWidth();
- // add this call back to the array
- // if it is a sequence put it at the beginning
- // if not put it at the end
- //
- // this is important because the way these are processed expects
- // the sequence ones to come first
- _callbacks[key][sequence_name ? 'unshift' : 'push']({
- callback: callback,
- modifiers: modifiers,
- action: action,
- seq: sequence_name,
- level: level,
- combo: combination
- });
- }
+ var angle, length;
+ //draw a line
+ if (this.from != this.to) {
+ angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
+ var dx = (this.to.x - this.from.x);
+ var dy = (this.to.y - this.from.y);
+ var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
- /**
- * binds multiple combinations to the same callback
- *
- * @param {Array} combinations
- * @param {Function} callback
- * @param {string|undefined} action
- * @returns void
- */
- function _bindMultiple(combinations, callback, action) {
- for (var i = 0; i < combinations.length; ++i) {
- _bindSingle(combinations[i], callback, action);
- }
- }
+ var fromBorderDist = this.from.distanceToBorder(ctx, angle + Math.PI);
+ var fromBorderPoint = (edgeSegmentLength - fromBorderDist) / edgeSegmentLength;
+ var xFrom = (fromBorderPoint) * this.from.x + (1 - fromBorderPoint) * this.to.x;
+ var yFrom = (fromBorderPoint) * this.from.y + (1 - fromBorderPoint) * this.to.y;
- // start!
- _addEvent(document, 'keypress', _handleKey);
- _addEvent(document, 'keydown', _handleKey);
- _addEvent(document, 'keyup', _handleKey);
+ var via;
+ if (this.smoothCurves.dynamic == true && this.smoothCurves.enabled == true ) {
+ via = this.via;
+ }
+ else if (this.smoothCurves.enabled == true) {
+ via = this._getViaCoordinates();
+ }
- var mousetrap = {
+ if (this.smoothCurves.enabled == true && via.x != null) {
+ angle = Math.atan2((this.to.y - via.y), (this.to.x - via.x));
+ dx = (this.to.x - via.x);
+ dy = (this.to.y - via.y);
+ edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
+ }
+ var toBorderDist = this.to.distanceToBorder(ctx, angle);
+ var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
- /**
- * binds an event to mousetrap
- *
- * can be a single key, a combination of keys separated with +,
- * a comma separated list of keys, an array of keys, or
- * a sequence of keys separated by spaces
- *
- * be sure to list the modifier keys first to make sure that the
- * correct key ends up getting bound (the last key in the pattern)
- *
- * @param {string|Array} keys
- * @param {Function} callback
- * @param {string=} action - 'keypress', 'keydown', or 'keyup'
- * @returns void
- */
- bind: function(keys, callback, action) {
- _bindMultiple(keys instanceof Array ? keys : [keys], callback, action);
- _direct_map[keys + ':' + action] = callback;
- return this;
- },
+ var xTo,yTo;
+ if (this.smoothCurves.enabled == true && via.x != null) {
+ xTo = (1 - toBorderPoint) * via.x + toBorderPoint * this.to.x;
+ yTo = (1 - toBorderPoint) * via.y + toBorderPoint * this.to.y;
+ }
+ else {
+ xTo = (1 - toBorderPoint) * this.from.x + toBorderPoint * this.to.x;
+ yTo = (1 - toBorderPoint) * this.from.y + toBorderPoint * this.to.y;
+ }
- /**
- * unbinds an event to mousetrap
- *
- * the unbinding sets the callback function of the specified key combo
- * to an empty function and deletes the corresponding key in the
- * _direct_map dict.
- *
- * the keycombo+action has to be exactly the same as
- * it was defined in the bind method
- *
- * TODO: actually remove this from the _callbacks dictionary instead
- * of binding an empty function
- *
- * @param {string|Array} keys
- * @param {string} action
- * @returns void
- */
- unbind: function(keys, action) {
- if (_direct_map[keys + ':' + action]) {
- delete _direct_map[keys + ':' + action];
- this.bind(keys, function() {}, action);
- }
- return this;
- },
+ ctx.beginPath();
+ ctx.moveTo(xFrom,yFrom);
+ if (this.smoothCurves.enabled == true && via.x != null) {
+ ctx.quadraticCurveTo(via.x,via.y,xTo, yTo);
+ }
+ else {
+ ctx.lineTo(xTo, yTo);
+ }
+ ctx.stroke();
- /**
- * triggers an event that has already been bound
- *
- * @param {string} keys
- * @param {string=} action
- * @returns void
- */
- trigger: function(keys, action) {
- _direct_map[keys + ':' + action]();
- return this;
- },
+ // draw arrow at the end of the line
+ length = (10 + 5 * this.width) * this.arrowScaleFactor;
+ ctx.arrow(xTo, yTo, angle, length);
+ ctx.fill();
+ ctx.stroke();
- /**
- * resets the library back to its initial state. this is useful
- * if you want to clear out the current keyboard shortcuts and bind
- * new ones - for example if you switch to another page
- *
- * @returns void
- */
- reset: function() {
- _callbacks = {};
- _direct_map = {};
- return this;
+ // draw label
+ if (this.label) {
+ var point;
+ if (this.smoothCurves.enabled == true && via != null) {
+ var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
+ var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
+ point = {x:midpointX, y:midpointY};
}
- };
+ else {
+ point = this._pointOnLine(0.5);
+ }
+ this._label(ctx, this.label, point.x, point.y);
+ }
+ }
+ else {
+ // draw circle
+ var node = this.from;
+ var x, y, arrow;
+ var radius = 0.25 * Math.max(100,this.length);
+ if (!node.width) {
+ node.resize(ctx);
+ }
+ if (node.width > node.height) {
+ x = node.x + node.width * 0.5;
+ y = node.y - radius;
+ arrow = {
+ x: x,
+ y: node.y,
+ angle: 0.9 * Math.PI
+ };
+ }
+ else {
+ x = node.x + radius;
+ y = node.y - node.height * 0.5;
+ arrow = {
+ x: node.x,
+ y: y,
+ angle: 0.6 * Math.PI
+ };
+ }
+ ctx.beginPath();
+ // TODO: similarly, for a line without arrows, draw to the border of the nodes instead of the center
+ ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
+ ctx.stroke();
- module.exports = mousetrap;
+ // draw all arrows
+ var length = (10 + 5 * this.width) * this.arrowScaleFactor;
+ ctx.arrow(arrow.x, arrow.y, arrow.angle, length);
+ ctx.fill();
+ ctx.stroke();
+ // draw label
+ if (this.label) {
+ point = this._pointOnCircle(x, y, radius, 0.5);
+ this._label(ctx, this.label, point.x, point.y);
+ }
+ }
+ };
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
/**
- * Parse a text source containing data in DOT language into a JSON object.
- * The object contains two lists: one with nodes and one with edges.
- *
- * DOT language reference: http://www.graphviz.org/doc/info/lang.html
- *
- * @param {String} data Text containing a graph in DOT-notation
- * @return {Object} graph An object containing two parameters:
- * {Object[]} nodes
- * {Object[]} edges
+ * Calculate the distance between a point (x3,y3) and a line segment from
+ * (x1,y1) to (x2,y2).
+ * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
+ * @param {number} x1
+ * @param {number} y1
+ * @param {number} x2
+ * @param {number} y2
+ * @param {number} x3
+ * @param {number} y3
+ * @private
*/
- function parseDOT (data) {
- dot = data;
- return parseGraph();
- }
-
- // token types enumeration
- var TOKENTYPE = {
- NULL : 0,
- DELIMITER : 1,
- IDENTIFIER: 2,
- UNKNOWN : 3
- };
-
- // map with all delimiters
- var DELIMITERS = {
- '{': true,
- '}': true,
- '[': true,
- ']': true,
- ';': true,
- '=': true,
- ',': true,
+ Edge.prototype._getDistanceToEdge = function (x1,y1, x2,y2, x3,y3) { // x3,y3 is the point
+ if (this.from != this.to) {
+ if (this.smoothCurves.enabled == true) {
+ var xVia, yVia;
+ if (this.smoothCurves.enabled == true && this.smoothCurves.dynamic == true) {
+ xVia = this.via.x;
+ yVia = this.via.y;
+ }
+ else {
+ var via = this._getViaCoordinates();
+ xVia = via.x;
+ yVia = via.y;
+ }
+ var minDistance = 1e9;
+ var i,t,x,y,dx,dy;
+ for (i = 0; i < 10; i++) {
+ t = 0.1*i;
+ x = Math.pow(1-t,2)*x1 + (2*t*(1 - t))*xVia + Math.pow(t,2)*x2;
+ y = Math.pow(1-t,2)*y1 + (2*t*(1 - t))*yVia + Math.pow(t,2)*y2;
+ dx = Math.abs(x3-x);
+ dy = Math.abs(y3-y);
+ minDistance = Math.min(minDistance,Math.sqrt(dx*dx + dy*dy));
+ }
+ return minDistance
+ }
+ else {
+ var px = x2-x1,
+ py = y2-y1,
+ something = px*px + py*py,
+ u = ((x3 - x1) * px + (y3 - y1) * py) / something;
- '->': true,
- '--': true
+ if (u > 1) {
+ u = 1;
+ }
+ else if (u < 0) {
+ u = 0;
+ }
+
+ var x = x1 + u * px,
+ y = y1 + u * py,
+ dx = x - x3,
+ dy = y - y3;
+
+ //# Note: If the actual distance does not matter,
+ //# if you only want to compare what this function
+ //# returns to other results of this function, you
+ //# can just return the squared distance instead
+ //# (i.e. remove the sqrt) to gain a little performance
+
+ return Math.sqrt(dx*dx + dy*dy);
+ }
+ }
+ else {
+ var x, y, dx, dy;
+ var radius = this.length / 4;
+ var node = this.from;
+ if (!node.width) {
+ node.resize(ctx);
+ }
+ if (node.width > node.height) {
+ x = node.x + node.width / 2;
+ y = node.y - radius;
+ }
+ else {
+ x = node.x + radius;
+ y = node.y - node.height / 2;
+ }
+ dx = x - x3;
+ dy = y - y3;
+ return Math.abs(Math.sqrt(dx*dx + dy*dy) - radius);
+ }
};
- var dot = ''; // current dot file
- var index = 0; // current index in dot file
- var c = ''; // current token character in expr
- var token = ''; // current token
- var tokenType = TOKENTYPE.NULL; // type of the token
+
/**
- * Get the first character from the dot file.
- * The character is stored into the char c. If the end of the dot file is
- * reached, the function puts an empty string in c.
+ * This allows the zoom level of the network to influence the rendering
+ *
+ * @param scale
*/
- function first() {
- index = 0;
- c = dot.charAt(0);
- }
+ Edge.prototype.setScale = function(scale) {
+ this.networkScaleInv = 1.0/scale;
+ };
+
+
+ Edge.prototype.select = function() {
+ this.selected = true;
+ };
+
+ Edge.prototype.unselect = function() {
+ this.selected = false;
+ };
+
+ Edge.prototype.positionBezierNode = function() {
+ if (this.via !== null) {
+ this.via.x = 0.5 * (this.from.x + this.to.x);
+ this.via.y = 0.5 * (this.from.y + this.to.y);
+ }
+ };
/**
- * Get the next character from the dot file.
- * The character is stored into the char c. If the end of the dot file is
- * reached, the function puts an empty string in c.
+ * This function draws the control nodes for the manipulator. In order to enable this, only set the this.controlNodesEnabled to true.
+ * @param ctx
*/
- function next() {
- index++;
- c = dot.charAt(index);
- }
+ Edge.prototype._drawControlNodes = function(ctx) {
+ if (this.controlNodesEnabled == true) {
+ if (this.controlNodes.from === null && this.controlNodes.to === null) {
+ var nodeIdFrom = "edgeIdFrom:".concat(this.id);
+ var nodeIdTo = "edgeIdTo:".concat(this.id);
+ var constants = {
+ nodes:{group:'', radius:8},
+ physics:{damping:0},
+ clustering: {maxNodeSizeIncrements: 0 ,nodeScaling: {width:0, height: 0, radius:0}}
+ };
+ this.controlNodes.from = new Node(
+ {id:nodeIdFrom,
+ shape:'dot',
+ color:{background:'#ff4e00', border:'#3c3c3c', highlight: {background:'#07f968'}}
+ },{},{},constants);
+ this.controlNodes.to = new Node(
+ {id:nodeIdTo,
+ shape:'dot',
+ color:{background:'#ff4e00', border:'#3c3c3c', highlight: {background:'#07f968'}}
+ },{},{},constants);
+ }
+
+ if (this.controlNodes.from.selected == false && this.controlNodes.to.selected == false) {
+ this.controlNodes.positions = this.getControlNodePositions(ctx);
+ this.controlNodes.from.x = this.controlNodes.positions.from.x;
+ this.controlNodes.from.y = this.controlNodes.positions.from.y;
+ this.controlNodes.to.x = this.controlNodes.positions.to.x;
+ this.controlNodes.to.y = this.controlNodes.positions.to.y;
+ }
+
+ this.controlNodes.from.draw(ctx);
+ this.controlNodes.to.draw(ctx);
+ }
+ else {
+ this.controlNodes = {from:null, to:null, positions:{}};
+ }
+ };
/**
- * Preview the next character from the dot file.
- * @return {String} cNext
+ * Enable control nodes.
+ * @private
*/
- function nextPreview() {
- return dot.charAt(index + 1);
- }
+ Edge.prototype._enableControlNodes = function() {
+ this.controlNodesEnabled = true;
+ };
/**
- * Test whether given character is alphabetic or numeric
- * @param {String} c
- * @return {Boolean} isAlphaNumeric
+ * disable control nodes
+ * @private
*/
- var regexAlphaNumeric = /[a-zA-Z_0-9.:#]/;
- function isAlphaNumeric(c) {
- return regexAlphaNumeric.test(c);
- }
+ Edge.prototype._disableControlNodes = function() {
+ this.controlNodesEnabled = false;
+ };
/**
- * Merge all properties of object b into object b
- * @param {Object} a
- * @param {Object} b
- * @return {Object} a
+ * This checks if one of the control nodes is selected and if so, returns the control node object. Else it returns null.
+ * @param x
+ * @param y
+ * @returns {null}
+ * @private
*/
- function merge (a, b) {
- if (!a) {
- a = {};
- }
+ Edge.prototype._getSelectedControlNode = function(x,y) {
+ var positions = this.controlNodes.positions;
+ var fromDistance = Math.sqrt(Math.pow(x - positions.from.x,2) + Math.pow(y - positions.from.y,2));
+ var toDistance = Math.sqrt(Math.pow(x - positions.to.x ,2) + Math.pow(y - positions.to.y ,2));
- if (b) {
- for (var name in b) {
- if (b.hasOwnProperty(name)) {
- a[name] = b[name];
- }
- }
+ if (fromDistance < 15) {
+ this.connectedNode = this.from;
+ this.from = this.controlNodes.from;
+ return this.controlNodes.from;
}
- return a;
- }
+ else if (toDistance < 15) {
+ this.connectedNode = this.to;
+ this.to = this.controlNodes.to;
+ return this.controlNodes.to;
+ }
+ else {
+ return null;
+ }
+ };
+
/**
- * Set a value in an object, where the provided parameter name can be a
- * path with nested parameters. For example:
- *
- * var obj = {a: 2};
- * setValue(obj, 'b.c', 3); // obj = {a: 2, b: {c: 3}}
- *
- * @param {Object} obj
- * @param {String} path A parameter name or dot-separated parameter path,
- * like "color.highlight.border".
- * @param {*} value
+ * this resets the control nodes to their original position.
+ * @private
*/
- function setValue(obj, path, value) {
- var keys = path.split('.');
- var o = obj;
- while (keys.length) {
- var key = keys.shift();
- if (keys.length) {
- // this isn't the end point
- if (!o[key]) {
- o[key] = {};
- }
- o = o[key];
- }
- else {
- // this is the end point
- o[key] = value;
- }
+ Edge.prototype._restoreControlNodes = function() {
+ if (this.controlNodes.from.selected == true) {
+ this.from = this.connectedNode;
+ this.connectedNode = null;
+ this.controlNodes.from.unselect();
}
- }
+ if (this.controlNodes.to.selected == true) {
+ this.to = this.connectedNode;
+ this.connectedNode = null;
+ this.controlNodes.to.unselect();
+ }
+ };
/**
- * Add a node to a graph object. If there is already a node with
- * the same id, their attributes will be merged.
- * @param {Object} graph
- * @param {Object} node
+ * this calculates the position of the control nodes on the edges of the parent nodes.
+ *
+ * @param ctx
+ * @returns {{from: {x: number, y: number}, to: {x: *, y: *}}}
*/
- function addNode(graph, node) {
- var i, len;
- var current = null;
+ Edge.prototype.getControlNodePositions = function(ctx) {
+ var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
+ var dx = (this.to.x - this.from.x);
+ var dy = (this.to.y - this.from.y);
+ var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
+ var fromBorderDist = this.from.distanceToBorder(ctx, angle + Math.PI);
+ var fromBorderPoint = (edgeSegmentLength - fromBorderDist) / edgeSegmentLength;
+ var xFrom = (fromBorderPoint) * this.from.x + (1 - fromBorderPoint) * this.to.x;
+ var yFrom = (fromBorderPoint) * this.from.y + (1 - fromBorderPoint) * this.to.y;
- // find root graph (in case of subgraph)
- var graphs = [graph]; // list with all graphs from current graph to root graph
- var root = graph;
- while (root.parent) {
- graphs.push(root.parent);
- root = root.parent;
+ var via;
+ if (this.smoothCurves.dynamic == true && this.smoothCurves.enabled == true) {
+ via = this.via;
+ }
+ else if (this.smoothCurves.enabled == true) {
+ via = this._getViaCoordinates();
}
- // find existing node (at root level) by its id
- if (root.nodes) {
- for (i = 0, len = root.nodes.length; i < len; i++) {
- if (node.id === root.nodes[i].id) {
- current = root.nodes[i];
- break;
- }
- }
+ if (this.smoothCurves.enabled == true && via.x != null) {
+ angle = Math.atan2((this.to.y - via.y), (this.to.x - via.x));
+ dx = (this.to.x - via.x);
+ dy = (this.to.y - via.y);
+ edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
}
+ var toBorderDist = this.to.distanceToBorder(ctx, angle);
+ var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
- if (!current) {
- // this is a new node
- current = {
- id: node.id
- };
- if (graph.node) {
- // clone default attributes
- current.attr = merge(current.attr, graph.node);
- }
+ var xTo,yTo;
+ if (this.smoothCurves.enabled == true && via.x != null) {
+ xTo = (1 - toBorderPoint) * via.x + toBorderPoint * this.to.x;
+ yTo = (1 - toBorderPoint) * via.y + toBorderPoint * this.to.y;
+ }
+ else {
+ xTo = (1 - toBorderPoint) * this.from.x + toBorderPoint * this.to.x;
+ yTo = (1 - toBorderPoint) * this.from.y + toBorderPoint * this.to.y;
}
- // add node to this (sub)graph and all its parent graphs
- for (i = graphs.length - 1; i >= 0; i--) {
- var g = graphs[i];
+ return {from:{x:xFrom,y:yFrom},to:{x:xTo,y:yTo}};
+ };
- if (!g.nodes) {
- g.nodes = [];
- }
- if (g.nodes.indexOf(current) == -1) {
- g.nodes.push(current);
- }
- }
+ module.exports = Edge;
- // merge attributes
- if (node.attr) {
- current.attr = merge(current.attr, node.attr);
- }
- }
+/***/ },
+/* 39 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var util = __webpack_require__(1);
/**
- * Add an edge to a graph object
- * @param {Object} graph
- * @param {Object} edge
+ * @class Node
+ * A node. A node can be connected to other nodes via one or multiple edges.
+ * @param {object} properties An object containing properties for the node. All
+ * properties are optional, except for the id.
+ * {number} id Id of the node. Required
+ * {string} label Text label for the node
+ * {number} x Horizontal position of the node
+ * {number} y Vertical position of the node
+ * {string} shape Node shape, available:
+ * "database", "circle", "ellipse",
+ * "box", "image", "text", "dot",
+ * "star", "triangle", "triangleDown",
+ * "square"
+ * {string} image An image url
+ * {string} title An title text, can be HTML
+ * {anytype} group A group name or number
+ * @param {Network.Images} imagelist A list with images. Only needed
+ * when the node has an image
+ * @param {Network.Groups} grouplist A list with groups. Needed for
+ * retrieving group properties
+ * @param {Object} constants An object with default values for
+ * example for the color
+ *
*/
- function addEdge(graph, edge) {
- if (!graph.edges) {
- graph.edges = [];
- }
- graph.edges.push(edge);
- if (graph.edge) {
- var attr = merge({}, graph.edge); // clone default attributes
- edge.attr = merge(attr, edge.attr); // merge attributes
- }
+ function Node(properties, imagelist, grouplist, constants) {
+ this.selected = false;
+ this.hover = false;
+
+ this.edges = []; // all edges connected to this node
+ this.dynamicEdges = [];
+ this.reroutedEdges = {};
+
+ this.group = constants.nodes.group;
+ this.fontSize = Number(constants.nodes.fontSize);
+ this.fontFace = constants.nodes.fontFace;
+ this.fontColor = constants.nodes.fontColor;
+ this.fontDrawThreshold = 3;
+
+ this.color = constants.nodes.color;
+
+ // set defaults for the properties
+ this.id = undefined;
+ this.shape = constants.nodes.shape;
+ this.image = constants.nodes.image;
+ this.x = null;
+ this.y = null;
+ this.xFixed = false;
+ this.yFixed = false;
+ this.horizontalAlignLeft = true; // these are for the navigation controls
+ this.verticalAlignTop = true; // these are for the navigation controls
+ this.radius = constants.nodes.radius;
+ this.baseRadiusValue = constants.nodes.radius;
+ this.radiusFixed = false;
+ this.radiusMin = constants.nodes.radiusMin;
+ this.radiusMax = constants.nodes.radiusMax;
+ this.level = -1;
+ this.preassignedLevel = false;
+
+
+ this.imagelist = imagelist;
+ this.grouplist = grouplist;
+
+ // physics properties
+ this.fx = 0.0; // external force x
+ this.fy = 0.0; // external force y
+ this.vx = 0.0; // velocity x
+ this.vy = 0.0; // velocity y
+ this.minForce = constants.minForce;
+ this.damping = constants.physics.damping;
+ this.mass = 1; // kg
+ this.fixedData = {x:null,y:null};
+
+ this.setProperties(properties, constants);
+
+ // creating the variables for clustering
+ this.resetCluster();
+ this.dynamicEdgesLength = 0;
+ this.clusterSession = 0;
+ this.clusterSizeWidthFactor = constants.clustering.nodeScaling.width;
+ this.clusterSizeHeightFactor = constants.clustering.nodeScaling.height;
+ this.clusterSizeRadiusFactor = constants.clustering.nodeScaling.radius;
+ this.maxNodeSizeIncrements = constants.clustering.maxNodeSizeIncrements;
+ this.growthIndicator = 0;
+
+ // variables to tell the node about the network.
+ this.networkScaleInv = 1;
+ this.networkScale = 1;
+ this.canvasTopLeft = {"x": -300, "y": -300};
+ this.canvasBottomRight = {"x": 300, "y": 300};
+ this.parentEdgeId = null;
}
/**
- * Create an edge to a graph object
- * @param {Object} graph
- * @param {String | Number | Object} from
- * @param {String | Number | Object} to
- * @param {String} type
- * @param {Object | null} attr
- * @return {Object} edge
+ * (re)setting the clustering variables and objects
*/
- function createEdge(graph, from, to, type, attr) {
- var edge = {
- from: from,
- to: to,
- type: type
- };
+ Node.prototype.resetCluster = function() {
+ // clustering variables
+ this.formationScale = undefined; // this is used to determine when to open the cluster
+ this.clusterSize = 1; // this signifies the total amount of nodes in this cluster
+ this.containedNodes = {};
+ this.containedEdges = {};
+ this.clusterSessions = [];
+ };
- if (graph.edge) {
- edge.attr = merge({}, graph.edge); // clone default attributes
+ /**
+ * Attach a edge to the node
+ * @param {Edge} edge
+ */
+ Node.prototype.attachEdge = function(edge) {
+ if (this.edges.indexOf(edge) == -1) {
+ this.edges.push(edge);
}
- edge.attr = merge(edge.attr || {}, attr); // merge attributes
-
- return edge;
- }
+ if (this.dynamicEdges.indexOf(edge) == -1) {
+ this.dynamicEdges.push(edge);
+ }
+ this.dynamicEdgesLength = this.dynamicEdges.length;
+ };
/**
- * Get next token in the current dot file.
- * The token and token type are available as token and tokenType
+ * Detach a edge from the node
+ * @param {Edge} edge
*/
- function getToken() {
- tokenType = TOKENTYPE.NULL;
- token = '';
-
- // skip over whitespaces
- while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter
- next();
+ Node.prototype.detachEdge = function(edge) {
+ var index = this.edges.indexOf(edge);
+ if (index != -1) {
+ this.edges.splice(index, 1);
+ this.dynamicEdges.splice(index, 1);
}
+ this.dynamicEdgesLength = this.dynamicEdges.length;
+ };
- do {
- var isComment = false;
- // skip comment
- if (c == '#') {
- // find the previous non-space character
- var i = index - 1;
- while (dot.charAt(i) == ' ' || dot.charAt(i) == '\t') {
- i--;
- }
- if (dot.charAt(i) == '\n' || dot.charAt(i) == '') {
- // the # is at the start of a line, this is indeed a line comment
- while (c != '' && c != '\n') {
- next();
- }
- isComment = true;
- }
- }
- if (c == '/' && nextPreview() == '/') {
- // skip line comment
- while (c != '' && c != '\n') {
- next();
- }
- isComment = true;
- }
- if (c == '/' && nextPreview() == '*') {
- // skip block comment
- while (c != '') {
- if (c == '*' && nextPreview() == '/') {
- // end of block comment found. skip these last two characters
- next();
- next();
- break;
- }
- else {
- next();
- }
- }
- isComment = true;
- }
-
- // skip over whitespaces
- while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter
- next();
- }
- }
- while (isComment);
-
- // check for end of dot file
- if (c == '') {
- // token is still empty
- tokenType = TOKENTYPE.DELIMITER;
+ /**
+ * Set or overwrite properties for the node
+ * @param {Object} properties an object with properties
+ * @param {Object} constants and object with default, global properties
+ */
+ Node.prototype.setProperties = function(properties, constants) {
+ if (!properties) {
return;
}
+ this.originalLabel = undefined;
+ // basic properties
+ if (properties.id !== undefined) {this.id = properties.id;}
+ if (properties.label !== undefined) {this.label = properties.label; this.originalLabel = properties.label;}
+ if (properties.title !== undefined) {this.title = properties.title;}
+ if (properties.group !== undefined) {this.group = properties.group;}
+ if (properties.x !== undefined) {this.x = properties.x;}
+ if (properties.y !== undefined) {this.y = properties.y;}
+ if (properties.value !== undefined) {this.value = properties.value;}
+ if (properties.level !== undefined) {this.level = properties.level; this.preassignedLevel = true;}
- // check for delimiters consisting of 2 characters
- var c2 = c + nextPreview();
- if (DELIMITERS[c2]) {
- tokenType = TOKENTYPE.DELIMITER;
- token = c2;
- next();
- next();
- return;
+
+ // physics
+ if (properties.mass !== undefined) {this.mass = properties.mass;}
+
+ // navigation controls properties
+ if (properties.horizontalAlignLeft !== undefined) {this.horizontalAlignLeft = properties.horizontalAlignLeft;}
+ if (properties.verticalAlignTop !== undefined) {this.verticalAlignTop = properties.verticalAlignTop;}
+ if (properties.triggerFunction !== undefined) {this.triggerFunction = properties.triggerFunction;}
+
+ if (this.id === undefined) {
+ throw "Node must have an id";
}
- // check for delimiters consisting of 1 character
- if (DELIMITERS[c]) {
- tokenType = TOKENTYPE.DELIMITER;
- token = c;
- next();
- return;
+ // copy group properties
+ if (this.group) {
+ var groupObj = this.grouplist.get(this.group);
+ for (var prop in groupObj) {
+ if (groupObj.hasOwnProperty(prop)) {
+ this[prop] = groupObj[prop];
+ }
+ }
}
- // check for an identifier (number or string)
- // TODO: more precise parsing of numbers/strings (and the port separator ':')
- if (isAlphaNumeric(c) || c == '-') {
- token += c;
- next();
+ // individual shape properties
+ if (properties.shape !== undefined) {this.shape = properties.shape;}
+ if (properties.image !== undefined) {this.image = properties.image;}
+ if (properties.radius !== undefined) {this.radius = properties.radius;}
+ if (properties.color !== undefined) {this.color = util.parseColor(properties.color);}
- while (isAlphaNumeric(c)) {
- token += c;
- next();
- }
- if (token == 'false') {
- token = false; // convert to boolean
- }
- else if (token == 'true') {
- token = true; // convert to boolean
+ if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;}
+ if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
+ if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
+
+ if (this.image !== undefined && this.image != "") {
+ if (this.imagelist) {
+ this.imageObj = this.imagelist.load(this.image);
}
- else if (!isNaN(Number(token))) {
- token = Number(token); // convert to number
+ else {
+ throw "No imagelist provided";
}
- tokenType = TOKENTYPE.IDENTIFIER;
- return;
}
- // check for a string enclosed by double quotes
- if (c == '"') {
- next();
- while (c != '' && (c != '"' || (c == '"' && nextPreview() == '"'))) {
- token += c;
- if (c == '"') { // skip the escape character
- next();
- }
- next();
- }
- if (c != '"') {
- throw newSyntaxError('End of string " expected');
- }
- next();
- tokenType = TOKENTYPE.IDENTIFIER;
- return;
+ this.xFixed = this.xFixed || (properties.x !== undefined && !properties.allowedToMoveX);
+ this.yFixed = this.yFixed || (properties.y !== undefined && !properties.allowedToMoveY);
+ this.radiusFixed = this.radiusFixed || (properties.radius !== undefined);
+
+ if (this.shape == 'image') {
+ this.radiusMin = constants.nodes.widthMin;
+ this.radiusMax = constants.nodes.widthMax;
}
- // something unknown is found, wrong characters, a syntax error
- tokenType = TOKENTYPE.UNKNOWN;
- while (c != '') {
- token += c;
- next();
+ // choose draw method depending on the shape
+ switch (this.shape) {
+ case 'database': this.draw = this._drawDatabase; this.resize = this._resizeDatabase; break;
+ case 'box': this.draw = this._drawBox; this.resize = this._resizeBox; break;
+ case 'circle': this.draw = this._drawCircle; this.resize = this._resizeCircle; break;
+ case 'ellipse': this.draw = this._drawEllipse; this.resize = this._resizeEllipse; break;
+ // TODO: add diamond shape
+ case 'image': this.draw = this._drawImage; this.resize = this._resizeImage; break;
+ case 'text': this.draw = this._drawText; this.resize = this._resizeText; break;
+ case 'dot': this.draw = this._drawDot; this.resize = this._resizeShape; break;
+ case 'square': this.draw = this._drawSquare; this.resize = this._resizeShape; break;
+ case 'triangle': this.draw = this._drawTriangle; this.resize = this._resizeShape; break;
+ case 'triangleDown': this.draw = this._drawTriangleDown; this.resize = this._resizeShape; break;
+ case 'star': this.draw = this._drawStar; this.resize = this._resizeShape; break;
+ default: this.draw = this._drawEllipse; this.resize = this._resizeEllipse; break;
}
- throw new SyntaxError('Syntax error in part "' + chop(token, 30) + '"');
- }
+ // reset the size of the node, this can be changed
+ this._reset();
+ };
/**
- * Parse a graph.
- * @returns {Object} graph
+ * select this node
*/
- function parseGraph() {
- var graph = {};
+ Node.prototype.select = function() {
+ this.selected = true;
+ this._reset();
+ };
- first();
- getToken();
+ /**
+ * unselect this node
+ */
+ Node.prototype.unselect = function() {
+ this.selected = false;
+ this._reset();
+ };
- // optional strict keyword
- if (token == 'strict') {
- graph.strict = true;
- getToken();
- }
- // graph or digraph keyword
- if (token == 'graph' || token == 'digraph') {
- graph.type = token;
- getToken();
- }
+ /**
+ * Reset the calculated size of the node, forces it to recalculate its size
+ */
+ Node.prototype.clearSizeCache = function() {
+ this._reset();
+ };
- // optional graph id
- if (tokenType == TOKENTYPE.IDENTIFIER) {
- graph.id = token;
- getToken();
- }
+ /**
+ * Reset the calculated size of the node, forces it to recalculate its size
+ * @private
+ */
+ Node.prototype._reset = function() {
+ this.width = undefined;
+ this.height = undefined;
+ };
- // open angle bracket
- if (token != '{') {
- throw newSyntaxError('Angle bracket { expected');
- }
- getToken();
+ /**
+ * get the title of this node.
+ * @return {string} title The title of the node, or undefined when no title
+ * has been set.
+ */
+ Node.prototype.getTitle = function() {
+ return typeof this.title === "function" ? this.title() : this.title;
+ };
- // statements
- parseStatements(graph);
+ /**
+ * Calculate the distance to the border of the Node
+ * @param {CanvasRenderingContext2D} ctx
+ * @param {Number} angle Angle in radians
+ * @returns {number} distance Distance to the border in pixels
+ */
+ Node.prototype.distanceToBorder = function (ctx, angle) {
+ var borderWidth = 1;
- // close angle bracket
- if (token != '}') {
- throw newSyntaxError('Angle bracket } expected');
+ if (!this.width) {
+ this.resize(ctx);
}
- getToken();
- // end of file
- if (token !== '') {
- throw newSyntaxError('End of file expected');
- }
- getToken();
+ switch (this.shape) {
+ case 'circle':
+ case 'dot':
+ return this.radius + borderWidth;
- // remove temporary default properties
- delete graph.node;
- delete graph.edge;
- delete graph.graph;
+ case 'ellipse':
+ var a = this.width / 2;
+ var b = this.height / 2;
+ var w = (Math.sin(angle) * a);
+ var h = (Math.cos(angle) * b);
+ return a * b / Math.sqrt(w * w + h * h);
- return graph;
- }
+ // TODO: implement distanceToBorder for database
+ // TODO: implement distanceToBorder for triangle
+ // TODO: implement distanceToBorder for triangleDown
+
+ case 'box':
+ case 'image':
+ case 'text':
+ default:
+ if (this.width) {
+ return Math.min(
+ Math.abs(this.width / 2 / Math.cos(angle)),
+ Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth;
+ // TODO: reckon with border radius too in case of box
+ }
+ else {
+ return 0;
+ }
+
+ }
+ // TODO: implement calculation of distance to border for all shapes
+ };
/**
- * Parse a list with statements.
- * @param {Object} graph
+ * Set forces acting on the node
+ * @param {number} fx Force in horizontal direction
+ * @param {number} fy Force in vertical direction
*/
- function parseStatements (graph) {
- while (token !== '' && token != '}') {
- parseStatement(graph);
- if (token == ';') {
- getToken();
- }
- }
- }
+ Node.prototype._setForce = function(fx, fy) {
+ this.fx = fx;
+ this.fy = fy;
+ };
/**
- * Parse a single statement. Can be a an attribute statement, node
- * statement, a series of node statements and edge statements, or a
- * parameter.
- * @param {Object} graph
+ * Add forces acting on the node
+ * @param {number} fx Force in horizontal direction
+ * @param {number} fy Force in vertical direction
+ * @private
*/
- function parseStatement(graph) {
- // parse subgraph
- var subgraph = parseSubgraph(graph);
- if (subgraph) {
- // edge statements
- parseEdge(graph, subgraph);
+ Node.prototype._addForce = function(fx, fy) {
+ this.fx += fx;
+ this.fy += fy;
+ };
- return;
+ /**
+ * Perform one discrete step for the node
+ * @param {number} interval Time interval in seconds
+ */
+ Node.prototype.discreteStep = function(interval) {
+ if (!this.xFixed) {
+ var dx = this.damping * this.vx; // damping force
+ var ax = (this.fx - dx) / this.mass; // acceleration
+ this.vx += ax * interval; // velocity
+ this.x += this.vx * interval; // position
}
- // parse an attribute statement
- var attr = parseAttributeStatement(graph);
- if (attr) {
- return;
+ if (!this.yFixed) {
+ var dy = this.damping * this.vy; // damping force
+ var ay = (this.fy - dy) / this.mass; // acceleration
+ this.vy += ay * interval; // velocity
+ this.y += this.vy * interval; // position
}
+ };
- // parse node
- if (tokenType != TOKENTYPE.IDENTIFIER) {
- throw newSyntaxError('Identifier expected');
+
+
+ /**
+ * Perform one discrete step for the node
+ * @param {number} interval Time interval in seconds
+ * @param {number} maxVelocity The speed limit imposed on the velocity
+ */
+ Node.prototype.discreteStepLimited = function(interval, maxVelocity) {
+ if (!this.xFixed) {
+ var dx = this.damping * this.vx; // damping force
+ var ax = (this.fx - dx) / this.mass; // acceleration
+ this.vx += ax * interval; // velocity
+ this.vx = (Math.abs(this.vx) > maxVelocity) ? ((this.vx > 0) ? maxVelocity : -maxVelocity) : this.vx;
+ this.x += this.vx * interval; // position
+ }
+ else {
+ this.fx = 0;
}
- var id = token; // id can be a string or a number
- getToken();
- if (token == '=') {
- // id statement
- getToken();
- if (tokenType != TOKENTYPE.IDENTIFIER) {
- throw newSyntaxError('Identifier expected');
- }
- graph[id] = token;
- getToken();
- // TODO: implement comma separated list with "a_list: ID=ID [','] [a_list] "
+ if (!this.yFixed) {
+ var dy = this.damping * this.vy; // damping force
+ var ay = (this.fy - dy) / this.mass; // acceleration
+ this.vy += ay * interval; // velocity
+ this.vy = (Math.abs(this.vy) > maxVelocity) ? ((this.vy > 0) ? maxVelocity : -maxVelocity) : this.vy;
+ this.y += this.vy * interval; // position
}
else {
- parseNodeStatement(graph, id);
+ this.fy = 0;
}
- }
+ };
/**
- * Parse a subgraph
- * @param {Object} graph parent graph object
- * @return {Object | null} subgraph
+ * Check if this node has a fixed x and y position
+ * @return {boolean} true if fixed, false if not
*/
- function parseSubgraph (graph) {
- var subgraph = null;
+ Node.prototype.isFixed = function() {
+ return (this.xFixed && this.yFixed);
+ };
- // optional subgraph keyword
- if (token == 'subgraph') {
- subgraph = {};
- subgraph.type = 'subgraph';
- getToken();
+ /**
+ * Check if this node is moving
+ * @param {number} vmin the minimum velocity considered as "moving"
+ * @return {boolean} true if moving, false if it has no velocity
+ */
+ // TODO: replace this method with calculating the kinetic energy
+ Node.prototype.isMoving = function(vmin) {
+ return (Math.abs(this.vx) > vmin || Math.abs(this.vy) > vmin);
+ };
- // optional graph id
- if (tokenType == TOKENTYPE.IDENTIFIER) {
- subgraph.id = token;
- getToken();
- }
- }
+ /**
+ * check if this node is selecte
+ * @return {boolean} selected True if node is selected, else false
+ */
+ Node.prototype.isSelected = function() {
+ return this.selected;
+ };
- // open angle bracket
- if (token == '{') {
- getToken();
+ /**
+ * Retrieve the value of the node. Can be undefined
+ * @return {Number} value
+ */
+ Node.prototype.getValue = function() {
+ return this.value;
+ };
- if (!subgraph) {
- subgraph = {};
- }
- subgraph.parent = graph;
- subgraph.node = graph.node;
- subgraph.edge = graph.edge;
- subgraph.graph = graph.graph;
+ /**
+ * Calculate the distance from the nodes location to the given location (x,y)
+ * @param {Number} x
+ * @param {Number} y
+ * @return {Number} value
+ */
+ Node.prototype.getDistance = function(x, y) {
+ var dx = this.x - x,
+ dy = this.y - y;
+ return Math.sqrt(dx * dx + dy * dy);
+ };
- // statements
- parseStatements(subgraph);
- // close angle bracket
- if (token != '}') {
- throw newSyntaxError('Angle bracket } expected');
+ /**
+ * Adjust the value range of the node. The node will adjust it's radius
+ * based on its value.
+ * @param {Number} min
+ * @param {Number} max
+ */
+ Node.prototype.setValueRange = function(min, max) {
+ if (!this.radiusFixed && this.value !== undefined) {
+ if (max == min) {
+ this.radius = (this.radiusMin + this.radiusMax) / 2;
}
- getToken();
-
- // remove temporary default properties
- delete subgraph.node;
- delete subgraph.edge;
- delete subgraph.graph;
- delete subgraph.parent;
-
- // register at the parent graph
- if (!graph.subgraphs) {
- graph.subgraphs = [];
+ else {
+ var scale = (this.radiusMax - this.radiusMin) / (max - min);
+ this.radius = (this.value - min) * scale + this.radiusMin;
}
- graph.subgraphs.push(subgraph);
}
+ this.baseRadiusValue = this.radius;
+ };
- return subgraph;
- }
+ /**
+ * Draw this node in the given canvas
+ * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
+ * @param {CanvasRenderingContext2D} ctx
+ */
+ Node.prototype.draw = function(ctx) {
+ throw "Draw method not initialized for node";
+ };
/**
- * parse an attribute statement like "node [shape=circle fontSize=16]".
- * Available keywords are 'node', 'edge', 'graph'.
- * The previous list with default attributes will be replaced
- * @param {Object} graph
- * @returns {String | null} keyword Returns the name of the parsed attribute
- * (node, edge, graph), or null if nothing
- * is parsed.
+ * Recalculate the size of this node in the given canvas
+ * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
+ * @param {CanvasRenderingContext2D} ctx
*/
- function parseAttributeStatement (graph) {
- // attribute statements
- if (token == 'node') {
- getToken();
-
- // node attributes
- graph.node = parseAttributeList();
- return 'node';
- }
- else if (token == 'edge') {
- getToken();
-
- // edge attributes
- graph.edge = parseAttributeList();
- return 'edge';
- }
- else if (token == 'graph') {
- getToken();
-
- // graph attributes
- graph.graph = parseAttributeList();
- return 'graph';
- }
-
- return null;
- }
+ Node.prototype.resize = function(ctx) {
+ throw "Resize method not initialized for node";
+ };
/**
- * parse a node statement
- * @param {Object} graph
- * @param {String | Number} id
+ * Check if this object is overlapping with the provided object
+ * @param {Object} obj an object with parameters left, top, right, bottom
+ * @return {boolean} True if location is located on node
*/
- function parseNodeStatement(graph, id) {
- // node statement
- var node = {
- id: id
- };
- var attr = parseAttributeList();
- if (attr) {
- node.attr = attr;
- }
- addNode(graph, node);
-
- // edge statements
- parseEdge(graph, id);
- }
+ Node.prototype.isOverlappingWith = function(obj) {
+ return (this.left < obj.right &&
+ this.left + this.width > obj.left &&
+ this.top < obj.bottom &&
+ this.top + this.height > obj.top);
+ };
- /**
- * Parse an edge or a series of edges
- * @param {Object} graph
- * @param {String | Number} from Id of the from node
- */
- function parseEdge(graph, from) {
- while (token == '->' || token == '--') {
- var to;
- var type = token;
- getToken();
+ Node.prototype._resizeImage = function (ctx) {
+ // TODO: pre calculate the image size
- var subgraph = parseSubgraph(graph);
- if (subgraph) {
- to = subgraph;
+ if (!this.width || !this.height) { // undefined or 0
+ var width, height;
+ if (this.value) {
+ this.radius = this.baseRadiusValue;
+ var scale = this.imageObj.height / this.imageObj.width;
+ if (scale !== undefined) {
+ width = this.radius || this.imageObj.width;
+ height = this.radius * scale || this.imageObj.height;
+ }
+ else {
+ width = 0;
+ height = 0;
+ }
}
else {
- if (tokenType != TOKENTYPE.IDENTIFIER) {
- throw newSyntaxError('Identifier or subgraph expected');
- }
- to = token;
- addNode(graph, {
- id: to
- });
- getToken();
+ width = this.imageObj.width;
+ height = this.imageObj.height;
}
+ this.width = width;
+ this.height = height;
- // parse edge attributes
- var attr = parseAttributeList();
-
- // create edge
- var edge = createEdge(graph, from, to, type, attr);
- addEdge(graph, edge);
-
- from = to;
+ this.growthIndicator = 0;
+ if (this.width > 0 && this.height > 0) {
+ this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
+ this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
+ this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
+ this.growthIndicator = this.width - width;
+ }
}
- }
- /**
- * Parse a set with attributes,
- * for example [label="1.000", shape=solid]
- * @return {Object | null} attr
- */
- function parseAttributeList() {
- var attr = null;
+ };
- while (token == '[') {
- getToken();
- attr = {};
- while (token !== '' && token != ']') {
- if (tokenType != TOKENTYPE.IDENTIFIER) {
- throw newSyntaxError('Attribute name expected');
- }
- var name = token;
+ Node.prototype._drawImage = function (ctx) {
+ this._resizeImage(ctx);
- getToken();
- if (token != '=') {
- throw newSyntaxError('Equal sign = expected');
- }
- getToken();
+ this.left = this.x - this.width / 2;
+ this.top = this.y - this.height / 2;
- if (tokenType != TOKENTYPE.IDENTIFIER) {
- throw newSyntaxError('Attribute value expected');
- }
- var value = token;
- setValue(attr, name, value); // name can be a path
+ var yLabel;
+ if (this.imageObj.width != 0 ) {
+ // draw the shade
+ if (this.clusterSize > 1) {
+ var lineWidth = ((this.clusterSize > 1) ? 10 : 0.0);
+ lineWidth *= this.networkScaleInv;
+ lineWidth = Math.min(0.2 * this.width,lineWidth);
- getToken();
- if (token ==',') {
- getToken();
- }
+ ctx.globalAlpha = 0.5;
+ ctx.drawImage(this.imageObj, this.left - lineWidth, this.top - lineWidth, this.width + 2*lineWidth, this.height + 2*lineWidth);
}
- if (token != ']') {
- throw newSyntaxError('Bracket ] expected');
- }
- getToken();
+ // draw the image
+ ctx.globalAlpha = 1.0;
+ ctx.drawImage(this.imageObj, this.left, this.top, this.width, this.height);
+ yLabel = this.y + this.height / 2;
+ }
+ else {
+ // image still loading... just draw the label for now
+ yLabel = this.y;
}
- return attr;
- }
+ this._label(ctx, this.label, this.x, yLabel, undefined, "top");
+ };
- /**
- * Create a syntax error with extra information on current token and index.
- * @param {String} message
- * @returns {SyntaxError} err
- */
- function newSyntaxError(message) {
- return new SyntaxError(message + ', got "' + chop(token, 30) + '" (char ' + index + ')');
- }
- /**
- * Chop off text after a maximum length
- * @param {String} text
- * @param {Number} maxLength
- * @returns {String}
- */
- function chop (text, maxLength) {
- return (text.length <= maxLength) ? text : (text.substr(0, 27) + '...');
- }
+ Node.prototype._resizeBox = function (ctx) {
+ if (!this.width) {
+ var margin = 5;
+ var textSize = this.getTextSize(ctx);
+ this.width = textSize.width + 2 * margin;
+ this.height = textSize.height + 2 * margin;
+
+ this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeWidthFactor;
+ this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeHeightFactor;
+ this.growthIndicator = this.width - (textSize.width + 2 * margin);
+ // this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor;
- /**
- * Execute a function fn for each pair of elements in two arrays
- * @param {Array | *} array1
- * @param {Array | *} array2
- * @param {function} fn
- */
- function forEach2(array1, array2, fn) {
- if (array1 instanceof Array) {
- array1.forEach(function (elem1) {
- if (array2 instanceof Array) {
- array2.forEach(function (elem2) {
- fn(elem1, elem2);
- });
- }
- else {
- fn(elem1, array2);
- }
- });
- }
- else {
- if (array2 instanceof Array) {
- array2.forEach(function (elem2) {
- fn(array1, elem2);
- });
- }
- else {
- fn(array1, array2);
- }
}
- }
+ };
- /**
- * Convert a string containing a graph in DOT language into a map containing
- * with nodes and edges in the format of graph.
- * @param {String} data Text containing a graph in DOT-notation
- * @return {Object} graphData
- */
- function DOTToGraph (data) {
- // parse the DOT file
- var dotData = parseDOT(data);
- var graphData = {
- nodes: [],
- edges: [],
- options: {}
- };
+ Node.prototype._drawBox = function (ctx) {
+ this._resizeBox(ctx);
- // copy the nodes
- if (dotData.nodes) {
- dotData.nodes.forEach(function (dotNode) {
- var graphNode = {
- id: dotNode.id,
- label: String(dotNode.label || dotNode.id)
- };
- merge(graphNode, dotNode.attr);
- if (graphNode.image) {
- graphNode.shape = 'image';
- }
- graphData.nodes.push(graphNode);
- });
+ this.left = this.x - this.width / 2;
+ this.top = this.y - this.height / 2;
+
+ var clusterLineWidth = 2.5;
+ var selectionLineWidth = 2;
+
+ ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
+
+ // draw the outer border
+ if (this.clusterSize > 1) {
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+
+ ctx.roundRect(this.left-2*ctx.lineWidth, this.top-2*ctx.lineWidth, this.width+4*ctx.lineWidth, this.height+4*ctx.lineWidth, this.radius);
+ ctx.stroke();
}
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- // copy the edges
- if (dotData.edges) {
- /**
- * Convert an edge in DOT format to an edge with VisGraph format
- * @param {Object} dotEdge
- * @returns {Object} graphEdge
- */
- function convertEdge(dotEdge) {
- var graphEdge = {
- from: dotEdge.from,
- to: dotEdge.to
- };
- merge(graphEdge, dotEdge.attr);
- graphEdge.style = (dotEdge.type == '->') ? 'arrow' : 'line';
- return graphEdge;
- }
+ ctx.fillStyle = this.selected ? this.color.highlight.background : this.color.background;
- dotData.edges.forEach(function (dotEdge) {
- var from, to;
- if (dotEdge.from instanceof Object) {
- from = dotEdge.from.nodes;
- }
- else {
- from = {
- id: dotEdge.from
- }
- }
+ ctx.roundRect(this.left, this.top, this.width, this.height, this.radius);
+ ctx.fill();
+ ctx.stroke();
- if (dotEdge.to instanceof Object) {
- to = dotEdge.to.nodes;
- }
- else {
- to = {
- id: dotEdge.to
- }
- }
+ this._label(ctx, this.label, this.x, this.y);
+ };
- if (dotEdge.from instanceof Object && dotEdge.from.edges) {
- dotEdge.from.edges.forEach(function (subEdge) {
- var graphEdge = convertEdge(subEdge);
- graphData.edges.push(graphEdge);
- });
- }
- forEach2(from, to, function (from, to) {
- var subEdge = createEdge(graphData, from.id, to.id, dotEdge.type, dotEdge.attr);
- var graphEdge = convertEdge(subEdge);
- graphData.edges.push(graphEdge);
- });
+ Node.prototype._resizeDatabase = function (ctx) {
+ if (!this.width) {
+ var margin = 5;
+ var textSize = this.getTextSize(ctx);
+ var size = textSize.width + 2 * margin;
+ this.width = size;
+ this.height = size;
- if (dotEdge.to instanceof Object && dotEdge.to.edges) {
- dotEdge.to.edges.forEach(function (subEdge) {
- var graphEdge = convertEdge(subEdge);
- graphData.edges.push(graphEdge);
- });
- }
- });
+ // scaling used for clustering
+ this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
+ this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
+ this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
+ this.growthIndicator = this.width - size;
}
+ };
- // copy the options
- if (dotData.attr) {
- graphData.options = dotData.attr;
- }
+ Node.prototype._drawDatabase = function (ctx) {
+ this._resizeDatabase(ctx);
+ this.left = this.x - this.width / 2;
+ this.top = this.y - this.height / 2;
- return graphData;
- }
+ var clusterLineWidth = 2.5;
+ var selectionLineWidth = 2;
- // exports
- exports.parseDOT = parseDOT;
- exports.DOTToGraph = DOTToGraph;
+ ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
+ // draw the outer border
+ if (this.clusterSize > 1) {
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
-/***/ },
-/* 40 */
-/***/ function(module, exports, __webpack_require__) {
+ ctx.database(this.x - this.width/2 - 2*ctx.lineWidth, this.y - this.height*0.5 - 2*ctx.lineWidth, this.width + 4*ctx.lineWidth, this.height + 4*ctx.lineWidth);
+ ctx.stroke();
+ }
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- var util = __webpack_require__(1);
+ ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
+ ctx.database(this.x - this.width/2, this.y - this.height*0.5, this.width, this.height);
+ ctx.fill();
+ ctx.stroke();
- /**
- * @class Groups
- * This class can store groups and properties specific for groups.
- */
- function Groups() {
- this.clear();
- this.defaultIndex = 0;
- }
+ this._label(ctx, this.label, this.x, this.y);
+ };
- /**
- * default constants for group colors
- */
- Groups.DEFAULT = [
- {border: "#2B7CE9", background: "#97C2FC", highlight: {border: "#2B7CE9", background: "#D2E5FF"}, hover: {border: "#2B7CE9", background: "#D2E5FF"}}, // blue
- {border: "#FFA500", background: "#FFFF00", highlight: {border: "#FFA500", background: "#FFFFA3"}, hover: {border: "#FFA500", background: "#FFFFA3"}}, // yellow
- {border: "#FA0A10", background: "#FB7E81", highlight: {border: "#FA0A10", background: "#FFAFB1"}, hover: {border: "#FA0A10", background: "#FFAFB1"}}, // red
- {border: "#41A906", background: "#7BE141", highlight: {border: "#41A906", background: "#A1EC76"}, hover: {border: "#41A906", background: "#A1EC76"}}, // green
- {border: "#E129F0", background: "#EB7DF4", highlight: {border: "#E129F0", background: "#F0B3F5"}, hover: {border: "#E129F0", background: "#F0B3F5"}}, // magenta
- {border: "#7C29F0", background: "#AD85E4", highlight: {border: "#7C29F0", background: "#D3BDF0"}, hover: {border: "#7C29F0", background: "#D3BDF0"}}, // purple
- {border: "#C37F00", background: "#FFA807", highlight: {border: "#C37F00", background: "#FFCA66"}, hover: {border: "#C37F00", background: "#FFCA66"}}, // orange
- {border: "#4220FB", background: "#6E6EFD", highlight: {border: "#4220FB", background: "#9B9BFD"}, hover: {border: "#4220FB", background: "#9B9BFD"}}, // darkblue
- {border: "#FD5A77", background: "#FFC0CB", highlight: {border: "#FD5A77", background: "#FFD1D9"}, hover: {border: "#FD5A77", background: "#FFD1D9"}}, // pink
- {border: "#4AD63A", background: "#C2FABC", highlight: {border: "#4AD63A", background: "#E6FFE3"}, hover: {border: "#4AD63A", background: "#E6FFE3"}} // mint
- ];
+ Node.prototype._resizeCircle = function (ctx) {
+ if (!this.width) {
+ var margin = 5;
+ var textSize = this.getTextSize(ctx);
+ var diameter = Math.max(textSize.width, textSize.height) + 2 * margin;
+ this.radius = diameter / 2;
+ this.width = diameter;
+ this.height = diameter;
- /**
- * Clear all groups
- */
- Groups.prototype.clear = function () {
- this.groups = {};
- this.groups.length = function()
- {
- var i = 0;
- for ( var p in this ) {
- if (this.hasOwnProperty(p)) {
- i++;
- }
- }
- return i;
+ // scaling used for clustering
+ // this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeWidthFactor;
+ // this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeHeightFactor;
+ this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor;
+ this.growthIndicator = this.radius - 0.5*diameter;
}
};
+ Node.prototype._drawCircle = function (ctx) {
+ this._resizeCircle(ctx);
+ this.left = this.x - this.width / 2;
+ this.top = this.y - this.height / 2;
- /**
- * get group properties of a groupname. If groupname is not found, a new group
- * is added.
- * @param {*} groupname Can be a number, string, Date, etc.
- * @return {Object} group The created group, containing all group properties
- */
- Groups.prototype.get = function (groupname) {
- var group = this.groups[groupname];
+ var clusterLineWidth = 2.5;
+ var selectionLineWidth = 2;
- if (group == undefined) {
- // create new group
- var index = this.defaultIndex % Groups.DEFAULT.length;
- this.defaultIndex++;
- group = {};
- group.color = Groups.DEFAULT[index];
- this.groups[groupname] = group;
+ ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
+
+ // draw the outer border
+ if (this.clusterSize > 1) {
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+
+ ctx.circle(this.x, this.y, this.radius+2*ctx.lineWidth);
+ ctx.stroke();
}
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- return group;
+ ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
+ ctx.circle(this.x, this.y, this.radius);
+ ctx.fill();
+ ctx.stroke();
+
+ this._label(ctx, this.label, this.x, this.y);
};
- /**
- * Add a custom group style
- * @param {String} groupname
- * @param {Object} style An object containing borderColor,
- * backgroundColor, etc.
- * @return {Object} group The created group object
- */
- Groups.prototype.add = function (groupname, style) {
- this.groups[groupname] = style;
- if (style.color) {
- style.color = util.parseColor(style.color);
+ Node.prototype._resizeEllipse = function (ctx) {
+ if (!this.width) {
+ var textSize = this.getTextSize(ctx);
+
+ this.width = textSize.width * 1.5;
+ this.height = textSize.height * 2;
+ if (this.width < this.height) {
+ this.width = this.height;
+ }
+ var defaultSize = this.width;
+
+ // scaling used for clustering
+ this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
+ this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
+ this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
+ this.growthIndicator = this.width - defaultSize;
}
- return style;
};
- module.exports = Groups;
+ Node.prototype._drawEllipse = function (ctx) {
+ this._resizeEllipse(ctx);
+ this.left = this.x - this.width / 2;
+ this.top = this.y - this.height / 2;
+ var clusterLineWidth = 2.5;
+ var selectionLineWidth = 2;
-/***/ },
-/* 41 */
-/***/ function(module, exports, __webpack_require__) {
+ ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
- /**
- * @class Images
- * This class loads images and keeps them stored.
- */
- function Images() {
- this.images = {};
-
- this.callback = undefined;
- }
-
- /**
- * Set an onload callback function. This will be called each time an image
- * is loaded
- * @param {function} callback
- */
- Images.prototype.setOnloadCallback = function(callback) {
- this.callback = callback;
- };
+ // draw the outer border
+ if (this.clusterSize > 1) {
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- /**
- *
- * @param {string} url Url of the image
- * @return {Image} img The image object
- */
- Images.prototype.load = function(url) {
- var img = this.images[url];
- if (img == undefined) {
- // create the image
- var images = this;
- img = new Image();
- this.images[url] = img;
- img.onload = function() {
- if (images.callback) {
- images.callback(this);
- }
- };
- img.src = url;
+ ctx.ellipse(this.left-2*ctx.lineWidth, this.top-2*ctx.lineWidth, this.width+4*ctx.lineWidth, this.height+4*ctx.lineWidth);
+ ctx.stroke();
}
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- return img;
- };
+ ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
- module.exports = Images;
+ ctx.ellipse(this.left, this.top, this.width, this.height);
+ ctx.fill();
+ ctx.stroke();
+ this._label(ctx, this.label, this.x, this.y);
+ };
+ Node.prototype._drawDot = function (ctx) {
+ this._drawShape(ctx, 'circle');
+ };
-/***/ },
-/* 42 */
-/***/ function(module, exports, __webpack_require__) {
+ Node.prototype._drawTriangle = function (ctx) {
+ this._drawShape(ctx, 'triangle');
+ };
- var util = __webpack_require__(1);
+ Node.prototype._drawTriangleDown = function (ctx) {
+ this._drawShape(ctx, 'triangleDown');
+ };
- /**
- * @class Node
- * A node. A node can be connected to other nodes via one or multiple edges.
- * @param {object} properties An object containing properties for the node. All
- * properties are optional, except for the id.
- * {number} id Id of the node. Required
- * {string} label Text label for the node
- * {number} x Horizontal position of the node
- * {number} y Vertical position of the node
- * {string} shape Node shape, available:
- * "database", "circle", "ellipse",
- * "box", "image", "text", "dot",
- * "star", "triangle", "triangleDown",
- * "square"
- * {string} image An image url
- * {string} title An title text, can be HTML
- * {anytype} group A group name or number
- * @param {Network.Images} imagelist A list with images. Only needed
- * when the node has an image
- * @param {Network.Groups} grouplist A list with groups. Needed for
- * retrieving group properties
- * @param {Object} constants An object with default values for
- * example for the color
- *
- */
- function Node(properties, imagelist, grouplist, constants) {
- this.selected = false;
- this.hover = false;
+ Node.prototype._drawSquare = function (ctx) {
+ this._drawShape(ctx, 'square');
+ };
- this.edges = []; // all edges connected to this node
- this.dynamicEdges = [];
- this.reroutedEdges = {};
+ Node.prototype._drawStar = function (ctx) {
+ this._drawShape(ctx, 'star');
+ };
- this.group = constants.nodes.group;
- this.fontSize = Number(constants.nodes.fontSize);
- this.fontFace = constants.nodes.fontFace;
- this.fontColor = constants.nodes.fontColor;
- this.fontDrawThreshold = 3;
+ Node.prototype._resizeShape = function (ctx) {
+ if (!this.width) {
+ this.radius = this.baseRadiusValue;
+ var size = 2 * this.radius;
+ this.width = size;
+ this.height = size;
- this.color = constants.nodes.color;
+ // scaling used for clustering
+ this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
+ this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
+ this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor;
+ this.growthIndicator = this.width - size;
+ }
+ };
- // set defaults for the properties
- this.id = undefined;
- this.shape = constants.nodes.shape;
- this.image = constants.nodes.image;
- this.x = null;
- this.y = null;
- this.xFixed = false;
- this.yFixed = false;
- this.horizontalAlignLeft = true; // these are for the navigation controls
- this.verticalAlignTop = true; // these are for the navigation controls
- this.radius = constants.nodes.radius;
- this.baseRadiusValue = constants.nodes.radius;
- this.radiusFixed = false;
- this.radiusMin = constants.nodes.radiusMin;
- this.radiusMax = constants.nodes.radiusMax;
- this.level = -1;
- this.preassignedLevel = false;
+ Node.prototype._drawShape = function (ctx, shape) {
+ this._resizeShape(ctx);
+ this.left = this.x - this.width / 2;
+ this.top = this.y - this.height / 2;
- this.imagelist = imagelist;
- this.grouplist = grouplist;
+ var clusterLineWidth = 2.5;
+ var selectionLineWidth = 2;
+ var radiusMultiplier = 2;
- // physics properties
- this.fx = 0.0; // external force x
- this.fy = 0.0; // external force y
- this.vx = 0.0; // velocity x
- this.vy = 0.0; // velocity y
- this.minForce = constants.minForce;
- this.damping = constants.physics.damping;
- this.mass = 1; // kg
- this.fixedData = {x:null,y:null};
+ // choose draw method depending on the shape
+ switch (shape) {
+ case 'dot': radiusMultiplier = 2; break;
+ case 'square': radiusMultiplier = 2; break;
+ case 'triangle': radiusMultiplier = 3; break;
+ case 'triangleDown': radiusMultiplier = 3; break;
+ case 'star': radiusMultiplier = 4; break;
+ }
- this.setProperties(properties, constants);
+ ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
- // creating the variables for clustering
- this.resetCluster();
- this.dynamicEdgesLength = 0;
- this.clusterSession = 0;
- this.clusterSizeWidthFactor = constants.clustering.nodeScaling.width;
- this.clusterSizeHeightFactor = constants.clustering.nodeScaling.height;
- this.clusterSizeRadiusFactor = constants.clustering.nodeScaling.radius;
- this.maxNodeSizeIncrements = constants.clustering.maxNodeSizeIncrements;
- this.growthIndicator = 0;
+ // draw the outer border
+ if (this.clusterSize > 1) {
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- // variables to tell the node about the network.
- this.networkScaleInv = 1;
- this.networkScale = 1;
- this.canvasTopLeft = {"x": -300, "y": -300};
- this.canvasBottomRight = {"x": 300, "y": 300};
- this.parentEdgeId = null;
- }
+ ctx[shape](this.x, this.y, this.radius + radiusMultiplier * ctx.lineWidth);
+ ctx.stroke();
+ }
+ ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
+ ctx.lineWidth *= this.networkScaleInv;
+ ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- /**
- * (re)setting the clustering variables and objects
- */
- Node.prototype.resetCluster = function() {
- // clustering variables
- this.formationScale = undefined; // this is used to determine when to open the cluster
- this.clusterSize = 1; // this signifies the total amount of nodes in this cluster
- this.containedNodes = {};
- this.containedEdges = {};
- this.clusterSessions = [];
- };
+ ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
+ ctx[shape](this.x, this.y, this.radius);
+ ctx.fill();
+ ctx.stroke();
- /**
- * Attach a edge to the node
- * @param {Edge} edge
- */
- Node.prototype.attachEdge = function(edge) {
- if (this.edges.indexOf(edge) == -1) {
- this.edges.push(edge);
- }
- if (this.dynamicEdges.indexOf(edge) == -1) {
- this.dynamicEdges.push(edge);
+ if (this.label) {
+ this._label(ctx, this.label, this.x, this.y + this.height / 2, undefined, 'top',true);
}
- this.dynamicEdgesLength = this.dynamicEdges.length;
};
- /**
- * Detach a edge from the node
- * @param {Edge} edge
- */
- Node.prototype.detachEdge = function(edge) {
- var index = this.edges.indexOf(edge);
- if (index != -1) {
- this.edges.splice(index, 1);
- this.dynamicEdges.splice(index, 1);
+ Node.prototype._resizeText = function (ctx) {
+ if (!this.width) {
+ var margin = 5;
+ var textSize = this.getTextSize(ctx);
+ this.width = textSize.width + 2 * margin;
+ this.height = textSize.height + 2 * margin;
+
+ // scaling used for clustering
+ this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
+ this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
+ this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
+ this.growthIndicator = this.width - (textSize.width + 2 * margin);
}
- this.dynamicEdgesLength = this.dynamicEdges.length;
};
+ Node.prototype._drawText = function (ctx) {
+ this._resizeText(ctx);
+ this.left = this.x - this.width / 2;
+ this.top = this.y - this.height / 2;
- /**
- * Set or overwrite properties for the node
- * @param {Object} properties an object with properties
- * @param {Object} constants and object with default, global properties
- */
- Node.prototype.setProperties = function(properties, constants) {
- if (!properties) {
- return;
- }
- this.originalLabel = undefined;
- // basic properties
- if (properties.id !== undefined) {this.id = properties.id;}
- if (properties.label !== undefined) {this.label = properties.label; this.originalLabel = properties.label;}
- if (properties.title !== undefined) {this.title = properties.title;}
- if (properties.group !== undefined) {this.group = properties.group;}
- if (properties.x !== undefined) {this.x = properties.x;}
- if (properties.y !== undefined) {this.y = properties.y;}
- if (properties.value !== undefined) {this.value = properties.value;}
- if (properties.level !== undefined) {this.level = properties.level; this.preassignedLevel = true;}
-
+ this._label(ctx, this.label, this.x, this.y);
+ };
- // physics
- if (properties.mass !== undefined) {this.mass = properties.mass;}
- // navigation controls properties
- if (properties.horizontalAlignLeft !== undefined) {this.horizontalAlignLeft = properties.horizontalAlignLeft;}
- if (properties.verticalAlignTop !== undefined) {this.verticalAlignTop = properties.verticalAlignTop;}
- if (properties.triggerFunction !== undefined) {this.triggerFunction = properties.triggerFunction;}
+ Node.prototype._label = function (ctx, text, x, y, align, baseline, labelUnderNode) {
+ if (text && this.fontSize * this.networkScale > this.fontDrawThreshold) {
+ ctx.font = (this.selected ? "bold " : "") + this.fontSize + "px " + this.fontFace;
+ ctx.fillStyle = this.fontColor || "black";
+ ctx.textAlign = align || "center";
+ ctx.textBaseline = baseline || "middle";
- if (this.id === undefined) {
- throw "Node must have an id";
- }
+ var lines = text.split('\n');
+ var lineCount = lines.length;
+ var fontSize = (this.fontSize + 4);
+ var yLine = y + (1 - lineCount) / 2 * fontSize;
+ if (labelUnderNode == true) {
+ yLine = y + (1 - lineCount) / (2 * fontSize);
+ }
- // copy group properties
- if (this.group) {
- var groupObj = this.grouplist.get(this.group);
- for (var prop in groupObj) {
- if (groupObj.hasOwnProperty(prop)) {
- this[prop] = groupObj[prop];
- }
+ for (var i = 0; i < lineCount; i++) {
+ ctx.fillText(lines[i], x, yLine);
+ yLine += fontSize;
}
}
+ };
- // individual shape properties
- if (properties.shape !== undefined) {this.shape = properties.shape;}
- if (properties.image !== undefined) {this.image = properties.image;}
- if (properties.radius !== undefined) {this.radius = properties.radius;}
- if (properties.color !== undefined) {this.color = util.parseColor(properties.color);}
- if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;}
- if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
- if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
+ Node.prototype.getTextSize = function(ctx) {
+ if (this.label !== undefined) {
+ ctx.font = (this.selected ? "bold " : "") + this.fontSize + "px " + this.fontFace;
- if (this.image !== undefined && this.image != "") {
- if (this.imagelist) {
- this.imageObj = this.imagelist.load(this.image);
- }
- else {
- throw "No imagelist provided";
- }
- }
+ var lines = this.label.split('\n'),
+ height = (this.fontSize + 4) * lines.length,
+ width = 0;
- this.xFixed = this.xFixed || (properties.x !== undefined && !properties.allowedToMoveX);
- this.yFixed = this.yFixed || (properties.y !== undefined && !properties.allowedToMoveY);
- this.radiusFixed = this.radiusFixed || (properties.radius !== undefined);
+ for (var i = 0, iMax = lines.length; i < iMax; i++) {
+ width = Math.max(width, ctx.measureText(lines[i]).width);
+ }
- if (this.shape == 'image') {
- this.radiusMin = constants.nodes.widthMin;
- this.radiusMax = constants.nodes.widthMax;
+ return {"width": width, "height": height};
}
-
- // choose draw method depending on the shape
- switch (this.shape) {
- case 'database': this.draw = this._drawDatabase; this.resize = this._resizeDatabase; break;
- case 'box': this.draw = this._drawBox; this.resize = this._resizeBox; break;
- case 'circle': this.draw = this._drawCircle; this.resize = this._resizeCircle; break;
- case 'ellipse': this.draw = this._drawEllipse; this.resize = this._resizeEllipse; break;
- // TODO: add diamond shape
- case 'image': this.draw = this._drawImage; this.resize = this._resizeImage; break;
- case 'text': this.draw = this._drawText; this.resize = this._resizeText; break;
- case 'dot': this.draw = this._drawDot; this.resize = this._resizeShape; break;
- case 'square': this.draw = this._drawSquare; this.resize = this._resizeShape; break;
- case 'triangle': this.draw = this._drawTriangle; this.resize = this._resizeShape; break;
- case 'triangleDown': this.draw = this._drawTriangleDown; this.resize = this._resizeShape; break;
- case 'star': this.draw = this._drawStar; this.resize = this._resizeShape; break;
- default: this.draw = this._drawEllipse; this.resize = this._resizeEllipse; break;
+ else {
+ return {"width": 0, "height": 0};
}
- // reset the size of the node, this can be changed
- this._reset();
};
/**
- * select this node
+ * this is used to determine if a node is visible at all. this is used to determine when it needs to be drawn.
+ * there is a safety margin of 0.3 * width;
+ *
+ * @returns {boolean}
*/
- Node.prototype.select = function() {
- this.selected = true;
- this._reset();
+ Node.prototype.inArea = function() {
+ if (this.width !== undefined) {
+ return (this.x + this.width *this.networkScaleInv >= this.canvasTopLeft.x &&
+ this.x - this.width *this.networkScaleInv < this.canvasBottomRight.x &&
+ this.y + this.height*this.networkScaleInv >= this.canvasTopLeft.y &&
+ this.y - this.height*this.networkScaleInv < this.canvasBottomRight.y);
+ }
+ else {
+ return true;
+ }
};
/**
- * unselect this node
+ * checks if the core of the node is in the display area, this is used for opening clusters around zoom
+ * @returns {boolean}
*/
- Node.prototype.unselect = function() {
- this.selected = false;
- this._reset();
+ Node.prototype.inView = function() {
+ return (this.x >= this.canvasTopLeft.x &&
+ this.x < this.canvasBottomRight.x &&
+ this.y >= this.canvasTopLeft.y &&
+ this.y < this.canvasBottomRight.y);
};
-
/**
- * Reset the calculated size of the node, forces it to recalculate its size
+ * This allows the zoom level of the network to influence the rendering
+ * We store the inverted scale and the coordinates of the top left, and bottom right points of the canvas
+ *
+ * @param scale
+ * @param canvasTopLeft
+ * @param canvasBottomRight
*/
- Node.prototype.clearSizeCache = function() {
- this._reset();
+ Node.prototype.setScaleAndPos = function(scale,canvasTopLeft,canvasBottomRight) {
+ this.networkScaleInv = 1.0/scale;
+ this.networkScale = scale;
+ this.canvasTopLeft = canvasTopLeft;
+ this.canvasBottomRight = canvasBottomRight;
};
+
/**
- * Reset the calculated size of the node, forces it to recalculate its size
- * @private
+ * This allows the zoom level of the network to influence the rendering
+ *
+ * @param scale
*/
- Node.prototype._reset = function() {
- this.width = undefined;
- this.height = undefined;
+ Node.prototype.setScale = function(scale) {
+ this.networkScaleInv = 1.0/scale;
+ this.networkScale = scale;
};
+
+
/**
- * get the title of this node.
- * @return {string} title The title of the node, or undefined when no title
- * has been set.
+ * set the velocity at 0. Is called when this node is contained in another during clustering
*/
- Node.prototype.getTitle = function() {
- return typeof this.title === "function" ? this.title() : this.title;
+ Node.prototype.clearVelocity = function() {
+ this.vx = 0;
+ this.vy = 0;
};
+
/**
- * Calculate the distance to the border of the Node
- * @param {CanvasRenderingContext2D} ctx
- * @param {Number} angle Angle in radians
- * @returns {number} distance Distance to the border in pixels
+ * Basic preservation of (kinectic) energy
+ *
+ * @param massBeforeClustering
*/
- Node.prototype.distanceToBorder = function (ctx, angle) {
- var borderWidth = 1;
-
- if (!this.width) {
- this.resize(ctx);
- }
-
- switch (this.shape) {
- case 'circle':
- case 'dot':
- return this.radius + borderWidth;
+ Node.prototype.updateVelocity = function(massBeforeClustering) {
+ var energyBefore = this.vx * this.vx * massBeforeClustering;
+ //this.vx = (this.vx < 0) ? -Math.sqrt(energyBefore/this.mass) : Math.sqrt(energyBefore/this.mass);
+ this.vx = Math.sqrt(energyBefore/this.mass);
+ energyBefore = this.vy * this.vy * massBeforeClustering;
+ //this.vy = (this.vy < 0) ? -Math.sqrt(energyBefore/this.mass) : Math.sqrt(energyBefore/this.mass);
+ this.vy = Math.sqrt(energyBefore/this.mass);
+ };
- case 'ellipse':
- var a = this.width / 2;
- var b = this.height / 2;
- var w = (Math.sin(angle) * a);
- var h = (Math.cos(angle) * b);
- return a * b / Math.sqrt(w * w + h * h);
+ module.exports = Node;
- // TODO: implement distanceToBorder for database
- // TODO: implement distanceToBorder for triangle
- // TODO: implement distanceToBorder for triangleDown
- case 'box':
- case 'image':
- case 'text':
- default:
- if (this.width) {
- return Math.min(
- Math.abs(this.width / 2 / Math.cos(angle)),
- Math.abs(this.height / 2 / Math.sin(angle))) + borderWidth;
- // TODO: reckon with border radius too in case of box
- }
- else {
- return 0;
- }
+/***/ },
+/* 40 */
+/***/ function(module, exports, __webpack_require__) {
- }
- // TODO: implement calculation of distance to border for all shapes
- };
+ var util = __webpack_require__(1);
/**
- * Set forces acting on the node
- * @param {number} fx Force in horizontal direction
- * @param {number} fy Force in vertical direction
+ * @class Groups
+ * This class can store groups and properties specific for groups.
*/
- Node.prototype._setForce = function(fx, fy) {
- this.fx = fx;
- this.fy = fy;
- };
+ function Groups() {
+ this.clear();
+ this.defaultIndex = 0;
+ }
+
/**
- * Add forces acting on the node
- * @param {number} fx Force in horizontal direction
- * @param {number} fy Force in vertical direction
- * @private
+ * default constants for group colors
*/
- Node.prototype._addForce = function(fx, fy) {
- this.fx += fx;
- this.fy += fy;
- };
+ Groups.DEFAULT = [
+ {border: "#2B7CE9", background: "#97C2FC", highlight: {border: "#2B7CE9", background: "#D2E5FF"}, hover: {border: "#2B7CE9", background: "#D2E5FF"}}, // blue
+ {border: "#FFA500", background: "#FFFF00", highlight: {border: "#FFA500", background: "#FFFFA3"}, hover: {border: "#FFA500", background: "#FFFFA3"}}, // yellow
+ {border: "#FA0A10", background: "#FB7E81", highlight: {border: "#FA0A10", background: "#FFAFB1"}, hover: {border: "#FA0A10", background: "#FFAFB1"}}, // red
+ {border: "#41A906", background: "#7BE141", highlight: {border: "#41A906", background: "#A1EC76"}, hover: {border: "#41A906", background: "#A1EC76"}}, // green
+ {border: "#E129F0", background: "#EB7DF4", highlight: {border: "#E129F0", background: "#F0B3F5"}, hover: {border: "#E129F0", background: "#F0B3F5"}}, // magenta
+ {border: "#7C29F0", background: "#AD85E4", highlight: {border: "#7C29F0", background: "#D3BDF0"}, hover: {border: "#7C29F0", background: "#D3BDF0"}}, // purple
+ {border: "#C37F00", background: "#FFA807", highlight: {border: "#C37F00", background: "#FFCA66"}, hover: {border: "#C37F00", background: "#FFCA66"}}, // orange
+ {border: "#4220FB", background: "#6E6EFD", highlight: {border: "#4220FB", background: "#9B9BFD"}, hover: {border: "#4220FB", background: "#9B9BFD"}}, // darkblue
+ {border: "#FD5A77", background: "#FFC0CB", highlight: {border: "#FD5A77", background: "#FFD1D9"}, hover: {border: "#FD5A77", background: "#FFD1D9"}}, // pink
+ {border: "#4AD63A", background: "#C2FABC", highlight: {border: "#4AD63A", background: "#E6FFE3"}, hover: {border: "#4AD63A", background: "#E6FFE3"}} // mint
+ ];
+
/**
- * Perform one discrete step for the node
- * @param {number} interval Time interval in seconds
+ * Clear all groups
*/
- Node.prototype.discreteStep = function(interval) {
- if (!this.xFixed) {
- var dx = this.damping * this.vx; // damping force
- var ax = (this.fx - dx) / this.mass; // acceleration
- this.vx += ax * interval; // velocity
- this.x += this.vx * interval; // position
- }
-
- if (!this.yFixed) {
- var dy = this.damping * this.vy; // damping force
- var ay = (this.fy - dy) / this.mass; // acceleration
- this.vy += ay * interval; // velocity
- this.y += this.vy * interval; // position
+ Groups.prototype.clear = function () {
+ this.groups = {};
+ this.groups.length = function()
+ {
+ var i = 0;
+ for ( var p in this ) {
+ if (this.hasOwnProperty(p)) {
+ i++;
+ }
+ }
+ return i;
}
};
-
/**
- * Perform one discrete step for the node
- * @param {number} interval Time interval in seconds
- * @param {number} maxVelocity The speed limit imposed on the velocity
+ * get group properties of a groupname. If groupname is not found, a new group
+ * is added.
+ * @param {*} groupname Can be a number, string, Date, etc.
+ * @return {Object} group The created group, containing all group properties
*/
- Node.prototype.discreteStepLimited = function(interval, maxVelocity) {
- if (!this.xFixed) {
- var dx = this.damping * this.vx; // damping force
- var ax = (this.fx - dx) / this.mass; // acceleration
- this.vx += ax * interval; // velocity
- this.vx = (Math.abs(this.vx) > maxVelocity) ? ((this.vx > 0) ? maxVelocity : -maxVelocity) : this.vx;
- this.x += this.vx * interval; // position
- }
- else {
- this.fx = 0;
- }
+ Groups.prototype.get = function (groupname) {
+ var group = this.groups[groupname];
- if (!this.yFixed) {
- var dy = this.damping * this.vy; // damping force
- var ay = (this.fy - dy) / this.mass; // acceleration
- this.vy += ay * interval; // velocity
- this.vy = (Math.abs(this.vy) > maxVelocity) ? ((this.vy > 0) ? maxVelocity : -maxVelocity) : this.vy;
- this.y += this.vy * interval; // position
- }
- else {
- this.fy = 0;
+ if (group == undefined) {
+ // create new group
+ var index = this.defaultIndex % Groups.DEFAULT.length;
+ this.defaultIndex++;
+ group = {};
+ group.color = Groups.DEFAULT[index];
+ this.groups[groupname] = group;
}
- };
- /**
- * Check if this node has a fixed x and y position
- * @return {boolean} true if fixed, false if not
- */
- Node.prototype.isFixed = function() {
- return (this.xFixed && this.yFixed);
+ return group;
};
/**
- * Check if this node is moving
- * @param {number} vmin the minimum velocity considered as "moving"
- * @return {boolean} true if moving, false if it has no velocity
+ * Add a custom group style
+ * @param {String} groupname
+ * @param {Object} style An object containing borderColor,
+ * backgroundColor, etc.
+ * @return {Object} group The created group object
*/
- // TODO: replace this method with calculating the kinetic energy
- Node.prototype.isMoving = function(vmin) {
- return (Math.abs(this.vx) > vmin || Math.abs(this.vy) > vmin);
+ Groups.prototype.add = function (groupname, style) {
+ this.groups[groupname] = style;
+ if (style.color) {
+ style.color = util.parseColor(style.color);
+ }
+ return style;
};
+ module.exports = Groups;
+
+
+/***/ },
+/* 41 */
+/***/ function(module, exports, __webpack_require__) {
+
/**
- * check if this node is selecte
- * @return {boolean} selected True if node is selected, else false
+ * @class Images
+ * This class loads images and keeps them stored.
*/
- Node.prototype.isSelected = function() {
- return this.selected;
- };
+ function Images() {
+ this.images = {};
+
+ this.callback = undefined;
+ }
/**
- * Retrieve the value of the node. Can be undefined
- * @return {Number} value
+ * Set an onload callback function. This will be called each time an image
+ * is loaded
+ * @param {function} callback
*/
- Node.prototype.getValue = function() {
- return this.value;
+ Images.prototype.setOnloadCallback = function(callback) {
+ this.callback = callback;
};
/**
- * Calculate the distance from the nodes location to the given location (x,y)
- * @param {Number} x
- * @param {Number} y
- * @return {Number} value
+ *
+ * @param {string} url Url of the image
+ * @return {Image} img The image object
*/
- Node.prototype.getDistance = function(x, y) {
- var dx = this.x - x,
- dy = this.y - y;
- return Math.sqrt(dx * dx + dy * dy);
+ Images.prototype.load = function(url) {
+ var img = this.images[url];
+ if (img == undefined) {
+ // create the image
+ var images = this;
+ img = new Image();
+ this.images[url] = img;
+ img.onload = function() {
+ if (images.callback) {
+ images.callback(this);
+ }
+ };
+ img.src = url;
+ }
+
+ return img;
};
+ module.exports = Images;
+
+
+/***/ },
+/* 42 */
+/***/ function(module, exports, __webpack_require__) {
/**
- * Adjust the value range of the node. The node will adjust it's radius
- * based on its value.
- * @param {Number} min
- * @param {Number} max
+ * Popup is a class to create a popup window with some text
+ * @param {Element} container The container object.
+ * @param {Number} [x]
+ * @param {Number} [y]
+ * @param {String} [text]
+ * @param {Object} [style] An object containing borderColor,
+ * backgroundColor, etc.
*/
- Node.prototype.setValueRange = function(min, max) {
- if (!this.radiusFixed && this.value !== undefined) {
- if (max == min) {
- this.radius = (this.radiusMin + this.radiusMax) / 2;
- }
- else {
- var scale = (this.radiusMax - this.radiusMin) / (max - min);
- this.radius = (this.value - min) * scale + this.radiusMin;
+ function Popup(container, x, y, text, style) {
+ if (container) {
+ this.container = container;
+ }
+ else {
+ this.container = document.body;
+ }
+
+ // x, y and text are optional, see if a style object was passed in their place
+ if (style === undefined) {
+ if (typeof x === "object") {
+ style = x;
+ x = undefined;
+ } else if (typeof text === "object") {
+ style = text;
+ text = undefined;
+ } else {
+ // for backwards compatibility, in case clients other than Network are creating Popup directly
+ style = {
+ fontColor: 'black',
+ fontSize: 14, // px
+ fontFace: 'verdana',
+ color: {
+ border: '#666',
+ background: '#FFFFC6'
+ }
+ }
}
}
- this.baseRadiusValue = this.radius;
- };
+
+ this.x = 0;
+ this.y = 0;
+ this.padding = 5;
+
+ if (x !== undefined && y !== undefined ) {
+ this.setPosition(x, y);
+ }
+ if (text !== undefined) {
+ this.setText(text);
+ }
+
+ // create the frame
+ this.frame = document.createElement("div");
+ var styleAttr = this.frame.style;
+ styleAttr.position = "absolute";
+ styleAttr.visibility = "hidden";
+ styleAttr.border = "1px solid " + style.color.border;
+ styleAttr.color = style.fontColor;
+ styleAttr.fontSize = style.fontSize + "px";
+ styleAttr.fontFamily = style.fontFace;
+ styleAttr.padding = this.padding + "px";
+ styleAttr.backgroundColor = style.color.background;
+ styleAttr.borderRadius = "3px";
+ styleAttr.MozBorderRadius = "3px";
+ styleAttr.WebkitBorderRadius = "3px";
+ styleAttr.boxShadow = "3px 3px 10px rgba(128, 128, 128, 0.5)";
+ styleAttr.whiteSpace = "nowrap";
+ this.container.appendChild(this.frame);
+ }
/**
- * Draw this node in the given canvas
- * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
- * @param {CanvasRenderingContext2D} ctx
+ * @param {number} x Horizontal position of the popup window
+ * @param {number} y Vertical position of the popup window
*/
- Node.prototype.draw = function(ctx) {
- throw "Draw method not initialized for node";
+ Popup.prototype.setPosition = function(x, y) {
+ this.x = parseInt(x);
+ this.y = parseInt(y);
};
/**
- * Recalculate the size of this node in the given canvas
- * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
- * @param {CanvasRenderingContext2D} ctx
+ * Set the text for the popup window. This can be HTML code
+ * @param {string} text
*/
- Node.prototype.resize = function(ctx) {
- throw "Resize method not initialized for node";
+ Popup.prototype.setText = function(text) {
+ this.frame.innerHTML = text;
};
/**
- * Check if this object is overlapping with the provided object
- * @param {Object} obj an object with parameters left, top, right, bottom
- * @return {boolean} True if location is located on node
+ * Show the popup window
+ * @param {boolean} show Optional. Show or hide the window
*/
- Node.prototype.isOverlappingWith = function(obj) {
- return (this.left < obj.right &&
- this.left + this.width > obj.left &&
- this.top < obj.bottom &&
- this.top + this.height > obj.top);
- };
+ Popup.prototype.show = function (show) {
+ if (show === undefined) {
+ show = true;
+ }
- Node.prototype._resizeImage = function (ctx) {
- // TODO: pre calculate the image size
+ if (show) {
+ var height = this.frame.clientHeight;
+ var width = this.frame.clientWidth;
+ var maxHeight = this.frame.parentNode.clientHeight;
+ var maxWidth = this.frame.parentNode.clientWidth;
- if (!this.width || !this.height) { // undefined or 0
- var width, height;
- if (this.value) {
- this.radius = this.baseRadiusValue;
- var scale = this.imageObj.height / this.imageObj.width;
- if (scale !== undefined) {
- width = this.radius || this.imageObj.width;
- height = this.radius * scale || this.imageObj.height;
- }
- else {
- width = 0;
- height = 0;
- }
+ var top = (this.y - height);
+ if (top + height + this.padding > maxHeight) {
+ top = maxHeight - height - this.padding;
}
- else {
- width = this.imageObj.width;
- height = this.imageObj.height;
+ if (top < this.padding) {
+ top = this.padding;
}
- this.width = width;
- this.height = height;
- this.growthIndicator = 0;
- if (this.width > 0 && this.height > 0) {
- this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
- this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
- this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
- this.growthIndicator = this.width - width;
+ var left = this.x;
+ if (left + width + this.padding > maxWidth) {
+ left = maxWidth - width - this.padding;
}
- }
-
- };
-
- Node.prototype._drawImage = function (ctx) {
- this._resizeImage(ctx);
-
- this.left = this.x - this.width / 2;
- this.top = this.y - this.height / 2;
-
- var yLabel;
- if (this.imageObj.width != 0 ) {
- // draw the shade
- if (this.clusterSize > 1) {
- var lineWidth = ((this.clusterSize > 1) ? 10 : 0.0);
- lineWidth *= this.networkScaleInv;
- lineWidth = Math.min(0.2 * this.width,lineWidth);
-
- ctx.globalAlpha = 0.5;
- ctx.drawImage(this.imageObj, this.left - lineWidth, this.top - lineWidth, this.width + 2*lineWidth, this.height + 2*lineWidth);
+ if (left < this.padding) {
+ left = this.padding;
}
- // draw the image
- ctx.globalAlpha = 1.0;
- ctx.drawImage(this.imageObj, this.left, this.top, this.width, this.height);
- yLabel = this.y + this.height / 2;
+ this.frame.style.left = left + "px";
+ this.frame.style.top = top + "px";
+ this.frame.style.visibility = "visible";
}
else {
- // image still loading... just draw the label for now
- yLabel = this.y;
+ this.hide();
}
-
- this._label(ctx, this.label, this.x, yLabel, undefined, "top");
};
-
- Node.prototype._resizeBox = function (ctx) {
- if (!this.width) {
- var margin = 5;
- var textSize = this.getTextSize(ctx);
- this.width = textSize.width + 2 * margin;
- this.height = textSize.height + 2 * margin;
-
- this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeWidthFactor;
- this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeHeightFactor;
- this.growthIndicator = this.width - (textSize.width + 2 * margin);
- // this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor;
-
- }
+ /**
+ * Hide the popup window
+ */
+ Popup.prototype.hide = function () {
+ this.frame.style.visibility = "hidden";
};
- Node.prototype._drawBox = function (ctx) {
- this._resizeBox(ctx);
-
- this.left = this.x - this.width / 2;
- this.top = this.y - this.height / 2;
-
- var clusterLineWidth = 2.5;
- var selectionLineWidth = 2;
-
- ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
-
- // draw the outer border
- if (this.clusterSize > 1) {
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+ module.exports = Popup;
- ctx.roundRect(this.left-2*ctx.lineWidth, this.top-2*ctx.lineWidth, this.width+4*ctx.lineWidth, this.height+4*ctx.lineWidth, this.radius);
- ctx.stroke();
- }
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- ctx.fillStyle = this.selected ? this.color.highlight.background : this.color.background;
+/***/ },
+/* 43 */
+/***/ function(module, exports, __webpack_require__) {
- ctx.roundRect(this.left, this.top, this.width, this.height, this.radius);
- ctx.fill();
- ctx.stroke();
+ /**
+ * Parse a text source containing data in DOT language into a JSON object.
+ * The object contains two lists: one with nodes and one with edges.
+ *
+ * DOT language reference: http://www.graphviz.org/doc/info/lang.html
+ *
+ * @param {String} data Text containing a graph in DOT-notation
+ * @return {Object} graph An object containing two parameters:
+ * {Object[]} nodes
+ * {Object[]} edges
+ */
+ function parseDOT (data) {
+ dot = data;
+ return parseGraph();
+ }
- this._label(ctx, this.label, this.x, this.y);
+ // token types enumeration
+ var TOKENTYPE = {
+ NULL : 0,
+ DELIMITER : 1,
+ IDENTIFIER: 2,
+ UNKNOWN : 3
};
+ // map with all delimiters
+ var DELIMITERS = {
+ '{': true,
+ '}': true,
+ '[': true,
+ ']': true,
+ ';': true,
+ '=': true,
+ ',': true,
- Node.prototype._resizeDatabase = function (ctx) {
- if (!this.width) {
- var margin = 5;
- var textSize = this.getTextSize(ctx);
- var size = textSize.width + 2 * margin;
- this.width = size;
- this.height = size;
-
- // scaling used for clustering
- this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
- this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
- this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
- this.growthIndicator = this.width - size;
- }
+ '->': true,
+ '--': true
};
- Node.prototype._drawDatabase = function (ctx) {
- this._resizeDatabase(ctx);
- this.left = this.x - this.width / 2;
- this.top = this.y - this.height / 2;
+ var dot = ''; // current dot file
+ var index = 0; // current index in dot file
+ var c = ''; // current token character in expr
+ var token = ''; // current token
+ var tokenType = TOKENTYPE.NULL; // type of the token
- var clusterLineWidth = 2.5;
- var selectionLineWidth = 2;
+ /**
+ * Get the first character from the dot file.
+ * The character is stored into the char c. If the end of the dot file is
+ * reached, the function puts an empty string in c.
+ */
+ function first() {
+ index = 0;
+ c = dot.charAt(0);
+ }
- ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
+ /**
+ * Get the next character from the dot file.
+ * The character is stored into the char c. If the end of the dot file is
+ * reached, the function puts an empty string in c.
+ */
+ function next() {
+ index++;
+ c = dot.charAt(index);
+ }
- // draw the outer border
- if (this.clusterSize > 1) {
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+ /**
+ * Preview the next character from the dot file.
+ * @return {String} cNext
+ */
+ function nextPreview() {
+ return dot.charAt(index + 1);
+ }
- ctx.database(this.x - this.width/2 - 2*ctx.lineWidth, this.y - this.height*0.5 - 2*ctx.lineWidth, this.width + 4*ctx.lineWidth, this.height + 4*ctx.lineWidth);
- ctx.stroke();
+ /**
+ * Test whether given character is alphabetic or numeric
+ * @param {String} c
+ * @return {Boolean} isAlphaNumeric
+ */
+ var regexAlphaNumeric = /[a-zA-Z_0-9.:#]/;
+ function isAlphaNumeric(c) {
+ return regexAlphaNumeric.test(c);
+ }
+
+ /**
+ * Merge all properties of object b into object b
+ * @param {Object} a
+ * @param {Object} b
+ * @return {Object} a
+ */
+ function merge (a, b) {
+ if (!a) {
+ a = {};
}
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
- ctx.database(this.x - this.width/2, this.y - this.height*0.5, this.width, this.height);
- ctx.fill();
- ctx.stroke();
+ if (b) {
+ for (var name in b) {
+ if (b.hasOwnProperty(name)) {
+ a[name] = b[name];
+ }
+ }
+ }
+ return a;
+ }
- this._label(ctx, this.label, this.x, this.y);
- };
-
-
- Node.prototype._resizeCircle = function (ctx) {
- if (!this.width) {
- var margin = 5;
- var textSize = this.getTextSize(ctx);
- var diameter = Math.max(textSize.width, textSize.height) + 2 * margin;
- this.radius = diameter / 2;
-
- this.width = diameter;
- this.height = diameter;
-
- // scaling used for clustering
- // this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeWidthFactor;
- // this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeHeightFactor;
- this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor;
- this.growthIndicator = this.radius - 0.5*diameter;
+ /**
+ * Set a value in an object, where the provided parameter name can be a
+ * path with nested parameters. For example:
+ *
+ * var obj = {a: 2};
+ * setValue(obj, 'b.c', 3); // obj = {a: 2, b: {c: 3}}
+ *
+ * @param {Object} obj
+ * @param {String} path A parameter name or dot-separated parameter path,
+ * like "color.highlight.border".
+ * @param {*} value
+ */
+ function setValue(obj, path, value) {
+ var keys = path.split('.');
+ var o = obj;
+ while (keys.length) {
+ var key = keys.shift();
+ if (keys.length) {
+ // this isn't the end point
+ if (!o[key]) {
+ o[key] = {};
+ }
+ o = o[key];
+ }
+ else {
+ // this is the end point
+ o[key] = value;
+ }
}
- };
-
- Node.prototype._drawCircle = function (ctx) {
- this._resizeCircle(ctx);
- this.left = this.x - this.width / 2;
- this.top = this.y - this.height / 2;
-
- var clusterLineWidth = 2.5;
- var selectionLineWidth = 2;
-
- ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
+ }
- // draw the outer border
- if (this.clusterSize > 1) {
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+ /**
+ * Add a node to a graph object. If there is already a node with
+ * the same id, their attributes will be merged.
+ * @param {Object} graph
+ * @param {Object} node
+ */
+ function addNode(graph, node) {
+ var i, len;
+ var current = null;
- ctx.circle(this.x, this.y, this.radius+2*ctx.lineWidth);
- ctx.stroke();
+ // find root graph (in case of subgraph)
+ var graphs = [graph]; // list with all graphs from current graph to root graph
+ var root = graph;
+ while (root.parent) {
+ graphs.push(root.parent);
+ root = root.parent;
}
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
- ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
- ctx.circle(this.x, this.y, this.radius);
- ctx.fill();
- ctx.stroke();
+ // find existing node (at root level) by its id
+ if (root.nodes) {
+ for (i = 0, len = root.nodes.length; i < len; i++) {
+ if (node.id === root.nodes[i].id) {
+ current = root.nodes[i];
+ break;
+ }
+ }
+ }
- this._label(ctx, this.label, this.x, this.y);
- };
+ if (!current) {
+ // this is a new node
+ current = {
+ id: node.id
+ };
+ if (graph.node) {
+ // clone default attributes
+ current.attr = merge(current.attr, graph.node);
+ }
+ }
- Node.prototype._resizeEllipse = function (ctx) {
- if (!this.width) {
- var textSize = this.getTextSize(ctx);
+ // add node to this (sub)graph and all its parent graphs
+ for (i = graphs.length - 1; i >= 0; i--) {
+ var g = graphs[i];
- this.width = textSize.width * 1.5;
- this.height = textSize.height * 2;
- if (this.width < this.height) {
- this.width = this.height;
+ if (!g.nodes) {
+ g.nodes = [];
+ }
+ if (g.nodes.indexOf(current) == -1) {
+ g.nodes.push(current);
}
- var defaultSize = this.width;
-
- // scaling used for clustering
- this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
- this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
- this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
- this.growthIndicator = this.width - defaultSize;
}
- };
-
- Node.prototype._drawEllipse = function (ctx) {
- this._resizeEllipse(ctx);
- this.left = this.x - this.width / 2;
- this.top = this.y - this.height / 2;
- var clusterLineWidth = 2.5;
- var selectionLineWidth = 2;
+ // merge attributes
+ if (node.attr) {
+ current.attr = merge(current.attr, node.attr);
+ }
+ }
- ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
+ /**
+ * Add an edge to a graph object
+ * @param {Object} graph
+ * @param {Object} edge
+ */
+ function addEdge(graph, edge) {
+ if (!graph.edges) {
+ graph.edges = [];
+ }
+ graph.edges.push(edge);
+ if (graph.edge) {
+ var attr = merge({}, graph.edge); // clone default attributes
+ edge.attr = merge(attr, edge.attr); // merge attributes
+ }
+ }
- // draw the outer border
- if (this.clusterSize > 1) {
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+ /**
+ * Create an edge to a graph object
+ * @param {Object} graph
+ * @param {String | Number | Object} from
+ * @param {String | Number | Object} to
+ * @param {String} type
+ * @param {Object | null} attr
+ * @return {Object} edge
+ */
+ function createEdge(graph, from, to, type, attr) {
+ var edge = {
+ from: from,
+ to: to,
+ type: type
+ };
- ctx.ellipse(this.left-2*ctx.lineWidth, this.top-2*ctx.lineWidth, this.width+4*ctx.lineWidth, this.height+4*ctx.lineWidth);
- ctx.stroke();
+ if (graph.edge) {
+ edge.attr = merge({}, graph.edge); // clone default attributes
}
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+ edge.attr = merge(edge.attr || {}, attr); // merge attributes
- ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
+ return edge;
+ }
- ctx.ellipse(this.left, this.top, this.width, this.height);
- ctx.fill();
- ctx.stroke();
- this._label(ctx, this.label, this.x, this.y);
- };
+ /**
+ * Get next token in the current dot file.
+ * The token and token type are available as token and tokenType
+ */
+ function getToken() {
+ tokenType = TOKENTYPE.NULL;
+ token = '';
- Node.prototype._drawDot = function (ctx) {
- this._drawShape(ctx, 'circle');
- };
+ // skip over whitespaces
+ while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter
+ next();
+ }
- Node.prototype._drawTriangle = function (ctx) {
- this._drawShape(ctx, 'triangle');
- };
+ do {
+ var isComment = false;
- Node.prototype._drawTriangleDown = function (ctx) {
- this._drawShape(ctx, 'triangleDown');
- };
+ // skip comment
+ if (c == '#') {
+ // find the previous non-space character
+ var i = index - 1;
+ while (dot.charAt(i) == ' ' || dot.charAt(i) == '\t') {
+ i--;
+ }
+ if (dot.charAt(i) == '\n' || dot.charAt(i) == '') {
+ // the # is at the start of a line, this is indeed a line comment
+ while (c != '' && c != '\n') {
+ next();
+ }
+ isComment = true;
+ }
+ }
+ if (c == '/' && nextPreview() == '/') {
+ // skip line comment
+ while (c != '' && c != '\n') {
+ next();
+ }
+ isComment = true;
+ }
+ if (c == '/' && nextPreview() == '*') {
+ // skip block comment
+ while (c != '') {
+ if (c == '*' && nextPreview() == '/') {
+ // end of block comment found. skip these last two characters
+ next();
+ next();
+ break;
+ }
+ else {
+ next();
+ }
+ }
+ isComment = true;
+ }
- Node.prototype._drawSquare = function (ctx) {
- this._drawShape(ctx, 'square');
- };
+ // skip over whitespaces
+ while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter
+ next();
+ }
+ }
+ while (isComment);
- Node.prototype._drawStar = function (ctx) {
- this._drawShape(ctx, 'star');
- };
+ // check for end of dot file
+ if (c == '') {
+ // token is still empty
+ tokenType = TOKENTYPE.DELIMITER;
+ return;
+ }
- Node.prototype._resizeShape = function (ctx) {
- if (!this.width) {
- this.radius = this.baseRadiusValue;
- var size = 2 * this.radius;
- this.width = size;
- this.height = size;
+ // check for delimiters consisting of 2 characters
+ var c2 = c + nextPreview();
+ if (DELIMITERS[c2]) {
+ tokenType = TOKENTYPE.DELIMITER;
+ token = c2;
+ next();
+ next();
+ return;
+ }
- // scaling used for clustering
- this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
- this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
- this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor;
- this.growthIndicator = this.width - size;
+ // check for delimiters consisting of 1 character
+ if (DELIMITERS[c]) {
+ tokenType = TOKENTYPE.DELIMITER;
+ token = c;
+ next();
+ return;
}
- };
- Node.prototype._drawShape = function (ctx, shape) {
- this._resizeShape(ctx);
+ // check for an identifier (number or string)
+ // TODO: more precise parsing of numbers/strings (and the port separator ':')
+ if (isAlphaNumeric(c) || c == '-') {
+ token += c;
+ next();
- this.left = this.x - this.width / 2;
- this.top = this.y - this.height / 2;
+ while (isAlphaNumeric(c)) {
+ token += c;
+ next();
+ }
+ if (token == 'false') {
+ token = false; // convert to boolean
+ }
+ else if (token == 'true') {
+ token = true; // convert to boolean
+ }
+ else if (!isNaN(Number(token))) {
+ token = Number(token); // convert to number
+ }
+ tokenType = TOKENTYPE.IDENTIFIER;
+ return;
+ }
- var clusterLineWidth = 2.5;
- var selectionLineWidth = 2;
- var radiusMultiplier = 2;
+ // check for a string enclosed by double quotes
+ if (c == '"') {
+ next();
+ while (c != '' && (c != '"' || (c == '"' && nextPreview() == '"'))) {
+ token += c;
+ if (c == '"') { // skip the escape character
+ next();
+ }
+ next();
+ }
+ if (c != '"') {
+ throw newSyntaxError('End of string " expected');
+ }
+ next();
+ tokenType = TOKENTYPE.IDENTIFIER;
+ return;
+ }
- // choose draw method depending on the shape
- switch (shape) {
- case 'dot': radiusMultiplier = 2; break;
- case 'square': radiusMultiplier = 2; break;
- case 'triangle': radiusMultiplier = 3; break;
- case 'triangleDown': radiusMultiplier = 3; break;
- case 'star': radiusMultiplier = 4; break;
+ // something unknown is found, wrong characters, a syntax error
+ tokenType = TOKENTYPE.UNKNOWN;
+ while (c != '') {
+ token += c;
+ next();
}
+ throw new SyntaxError('Syntax error in part "' + chop(token, 30) + '"');
+ }
- ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
+ /**
+ * Parse a graph.
+ * @returns {Object} graph
+ */
+ function parseGraph() {
+ var graph = {};
- // draw the outer border
- if (this.clusterSize > 1) {
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
+ first();
+ getToken();
- ctx[shape](this.x, this.y, this.radius + radiusMultiplier * ctx.lineWidth);
- ctx.stroke();
+ // optional strict keyword
+ if (token == 'strict') {
+ graph.strict = true;
+ getToken();
}
- ctx.lineWidth = (this.selected ? selectionLineWidth : 1.0) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0);
- ctx.lineWidth *= this.networkScaleInv;
- ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
-
- ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
- ctx[shape](this.x, this.y, this.radius);
- ctx.fill();
- ctx.stroke();
- if (this.label) {
- this._label(ctx, this.label, this.x, this.y + this.height / 2, undefined, 'top',true);
+ // graph or digraph keyword
+ if (token == 'graph' || token == 'digraph') {
+ graph.type = token;
+ getToken();
}
- };
- Node.prototype._resizeText = function (ctx) {
- if (!this.width) {
- var margin = 5;
- var textSize = this.getTextSize(ctx);
- this.width = textSize.width + 2 * margin;
- this.height = textSize.height + 2 * margin;
+ // optional graph id
+ if (tokenType == TOKENTYPE.IDENTIFIER) {
+ graph.id = token;
+ getToken();
+ }
- // scaling used for clustering
- this.width += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeWidthFactor;
- this.height += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeHeightFactor;
- this.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor;
- this.growthIndicator = this.width - (textSize.width + 2 * margin);
+ // open angle bracket
+ if (token != '{') {
+ throw newSyntaxError('Angle bracket { expected');
}
- };
+ getToken();
- Node.prototype._drawText = function (ctx) {
- this._resizeText(ctx);
- this.left = this.x - this.width / 2;
- this.top = this.y - this.height / 2;
+ // statements
+ parseStatements(graph);
- this._label(ctx, this.label, this.x, this.y);
- };
+ // close angle bracket
+ if (token != '}') {
+ throw newSyntaxError('Angle bracket } expected');
+ }
+ getToken();
+ // end of file
+ if (token !== '') {
+ throw newSyntaxError('End of file expected');
+ }
+ getToken();
- Node.prototype._label = function (ctx, text, x, y, align, baseline, labelUnderNode) {
- if (text && this.fontSize * this.networkScale > this.fontDrawThreshold) {
- ctx.font = (this.selected ? "bold " : "") + this.fontSize + "px " + this.fontFace;
- ctx.fillStyle = this.fontColor || "black";
- ctx.textAlign = align || "center";
- ctx.textBaseline = baseline || "middle";
+ // remove temporary default properties
+ delete graph.node;
+ delete graph.edge;
+ delete graph.graph;
- var lines = text.split('\n');
- var lineCount = lines.length;
- var fontSize = (this.fontSize + 4);
- var yLine = y + (1 - lineCount) / 2 * fontSize;
- if (labelUnderNode == true) {
- yLine = y + (1 - lineCount) / (2 * fontSize);
- }
+ return graph;
+ }
- for (var i = 0; i < lineCount; i++) {
- ctx.fillText(lines[i], x, yLine);
- yLine += fontSize;
+ /**
+ * Parse a list with statements.
+ * @param {Object} graph
+ */
+ function parseStatements (graph) {
+ while (token !== '' && token != '}') {
+ parseStatement(graph);
+ if (token == ';') {
+ getToken();
}
}
- };
+ }
+ /**
+ * Parse a single statement. Can be a an attribute statement, node
+ * statement, a series of node statements and edge statements, or a
+ * parameter.
+ * @param {Object} graph
+ */
+ function parseStatement(graph) {
+ // parse subgraph
+ var subgraph = parseSubgraph(graph);
+ if (subgraph) {
+ // edge statements
+ parseEdge(graph, subgraph);
- Node.prototype.getTextSize = function(ctx) {
- if (this.label !== undefined) {
- ctx.font = (this.selected ? "bold " : "") + this.fontSize + "px " + this.fontFace;
+ return;
+ }
- var lines = this.label.split('\n'),
- height = (this.fontSize + 4) * lines.length,
- width = 0;
+ // parse an attribute statement
+ var attr = parseAttributeStatement(graph);
+ if (attr) {
+ return;
+ }
- for (var i = 0, iMax = lines.length; i < iMax; i++) {
- width = Math.max(width, ctx.measureText(lines[i]).width);
- }
+ // parse node
+ if (tokenType != TOKENTYPE.IDENTIFIER) {
+ throw newSyntaxError('Identifier expected');
+ }
+ var id = token; // id can be a string or a number
+ getToken();
- return {"width": width, "height": height};
+ if (token == '=') {
+ // id statement
+ getToken();
+ if (tokenType != TOKENTYPE.IDENTIFIER) {
+ throw newSyntaxError('Identifier expected');
+ }
+ graph[id] = token;
+ getToken();
+ // TODO: implement comma separated list with "a_list: ID=ID [','] [a_list] "
}
else {
- return {"width": 0, "height": 0};
+ parseNodeStatement(graph, id);
}
- };
+ }
/**
- * this is used to determine if a node is visible at all. this is used to determine when it needs to be drawn.
- * there is a safety margin of 0.3 * width;
- *
- * @returns {boolean}
+ * Parse a subgraph
+ * @param {Object} graph parent graph object
+ * @return {Object | null} subgraph
*/
- Node.prototype.inArea = function() {
- if (this.width !== undefined) {
- return (this.x + this.width *this.networkScaleInv >= this.canvasTopLeft.x &&
- this.x - this.width *this.networkScaleInv < this.canvasBottomRight.x &&
- this.y + this.height*this.networkScaleInv >= this.canvasTopLeft.y &&
- this.y - this.height*this.networkScaleInv < this.canvasBottomRight.y);
- }
- else {
- return true;
- }
- };
+ function parseSubgraph (graph) {
+ var subgraph = null;
- /**
- * checks if the core of the node is in the display area, this is used for opening clusters around zoom
- * @returns {boolean}
- */
- Node.prototype.inView = function() {
- return (this.x >= this.canvasTopLeft.x &&
- this.x < this.canvasBottomRight.x &&
- this.y >= this.canvasTopLeft.y &&
- this.y < this.canvasBottomRight.y);
- };
+ // optional subgraph keyword
+ if (token == 'subgraph') {
+ subgraph = {};
+ subgraph.type = 'subgraph';
+ getToken();
- /**
- * This allows the zoom level of the network to influence the rendering
- * We store the inverted scale and the coordinates of the top left, and bottom right points of the canvas
- *
- * @param scale
- * @param canvasTopLeft
- * @param canvasBottomRight
- */
- Node.prototype.setScaleAndPos = function(scale,canvasTopLeft,canvasBottomRight) {
- this.networkScaleInv = 1.0/scale;
- this.networkScale = scale;
- this.canvasTopLeft = canvasTopLeft;
- this.canvasBottomRight = canvasBottomRight;
- };
+ // optional graph id
+ if (tokenType == TOKENTYPE.IDENTIFIER) {
+ subgraph.id = token;
+ getToken();
+ }
+ }
+ // open angle bracket
+ if (token == '{') {
+ getToken();
- /**
- * This allows the zoom level of the network to influence the rendering
- *
- * @param scale
- */
- Node.prototype.setScale = function(scale) {
- this.networkScaleInv = 1.0/scale;
- this.networkScale = scale;
- };
+ if (!subgraph) {
+ subgraph = {};
+ }
+ subgraph.parent = graph;
+ subgraph.node = graph.node;
+ subgraph.edge = graph.edge;
+ subgraph.graph = graph.graph;
+
+ // statements
+ parseStatements(subgraph);
+ // close angle bracket
+ if (token != '}') {
+ throw newSyntaxError('Angle bracket } expected');
+ }
+ getToken();
+ // remove temporary default properties
+ delete subgraph.node;
+ delete subgraph.edge;
+ delete subgraph.graph;
+ delete subgraph.parent;
- /**
- * set the velocity at 0. Is called when this node is contained in another during clustering
- */
- Node.prototype.clearVelocity = function() {
- this.vx = 0;
- this.vy = 0;
- };
+ // register at the parent graph
+ if (!graph.subgraphs) {
+ graph.subgraphs = [];
+ }
+ graph.subgraphs.push(subgraph);
+ }
+ return subgraph;
+ }
/**
- * Basic preservation of (kinectic) energy
- *
- * @param massBeforeClustering
+ * parse an attribute statement like "node [shape=circle fontSize=16]".
+ * Available keywords are 'node', 'edge', 'graph'.
+ * The previous list with default attributes will be replaced
+ * @param {Object} graph
+ * @returns {String | null} keyword Returns the name of the parsed attribute
+ * (node, edge, graph), or null if nothing
+ * is parsed.
*/
- Node.prototype.updateVelocity = function(massBeforeClustering) {
- var energyBefore = this.vx * this.vx * massBeforeClustering;
- //this.vx = (this.vx < 0) ? -Math.sqrt(energyBefore/this.mass) : Math.sqrt(energyBefore/this.mass);
- this.vx = Math.sqrt(energyBefore/this.mass);
- energyBefore = this.vy * this.vy * massBeforeClustering;
- //this.vy = (this.vy < 0) ? -Math.sqrt(energyBefore/this.mass) : Math.sqrt(energyBefore/this.mass);
- this.vy = Math.sqrt(energyBefore/this.mass);
- };
+ function parseAttributeStatement (graph) {
+ // attribute statements
+ if (token == 'node') {
+ getToken();
- module.exports = Node;
+ // node attributes
+ graph.node = parseAttributeList();
+ return 'node';
+ }
+ else if (token == 'edge') {
+ getToken();
+ // edge attributes
+ graph.edge = parseAttributeList();
+ return 'edge';
+ }
+ else if (token == 'graph') {
+ getToken();
-/***/ },
-/* 43 */
-/***/ function(module, exports, __webpack_require__) {
+ // graph attributes
+ graph.graph = parseAttributeList();
+ return 'graph';
+ }
- var util = __webpack_require__(1);
- var Node = __webpack_require__(42);
+ return null;
+ }
/**
- * @class Edge
- *
- * A edge connects two nodes
- * @param {Object} properties Object with properties. Must contain
- * At least properties from and to.
- * Available properties: from (number),
- * to (number), label (string, color (string),
- * width (number), style (string),
- * length (number), title (string)
- * @param {Network} network A Network object, used to find and edge to
- * nodes.
- * @param {Object} constants An object with default values for
- * example for the color
+ * parse a node statement
+ * @param {Object} graph
+ * @param {String | Number} id
*/
- function Edge (properties, network, constants) {
- if (!network) {
- throw "No network provided";
+ function parseNodeStatement(graph, id) {
+ // node statement
+ var node = {
+ id: id
+ };
+ var attr = parseAttributeList();
+ if (attr) {
+ node.attr = attr;
}
- this.network = network;
-
- // initialize constants
- this.widthMin = constants.edges.widthMin;
- this.widthMax = constants.edges.widthMax;
-
- // initialize variables
- this.id = undefined;
- this.fromId = undefined;
- this.toId = undefined;
- this.style = constants.edges.style;
- this.title = undefined;
- this.width = constants.edges.width;
- this.widthSelectionMultiplier = constants.edges.widthSelectionMultiplier;
- this.widthSelected = this.width * this.widthSelectionMultiplier;
- this.hoverWidth = constants.edges.hoverWidth;
- this.value = undefined;
- this.length = constants.physics.springLength;
- this.customLength = false;
- this.selected = false;
- this.hover = false;
- this.smoothCurves = constants.smoothCurves;
- this.dynamicSmoothCurves = constants.dynamicSmoothCurves;
- this.arrowScaleFactor = constants.edges.arrowScaleFactor;
- this.inheritColor = constants.edges.inheritColor;
-
- this.from = null; // a node
- this.to = null; // a node
- this.via = null; // a temp node
-
- // we use this to be able to reconnect the edge to a cluster if its node is put into a cluster
- // by storing the original information we can revert to the original connection when the cluser is opened.
- this.originalFromId = [];
- this.originalToId = [];
-
- this.connected = false;
-
- // Added to support dashed lines
- // David Jordan
- // 2012-08-08
- this.dash = util.extend({}, constants.edges.dash); // contains properties length, gap, altLength
-
- this.color = {color:constants.edges.color.color,
- highlight:constants.edges.color.highlight,
- hover:constants.edges.color.hover};
- this.widthFixed = false;
- this.lengthFixed = false;
-
- this.setProperties(properties, constants);
+ addNode(graph, node);
- this.controlNodesEnabled = false;
- this.controlNodes = {from:null, to:null, positions:{}};
- this.connectedNode = null;
+ // edge statements
+ parseEdge(graph, id);
}
/**
- * Set or overwrite properties for the edge
- * @param {Object} properties an object with properties
- * @param {Object} constants and object with default, global properties
+ * Parse an edge or a series of edges
+ * @param {Object} graph
+ * @param {String | Number} from Id of the from node
*/
- Edge.prototype.setProperties = function(properties, constants) {
- if (!properties) {
- return;
- }
-
- if (properties.from !== undefined) {this.fromId = properties.from;}
- if (properties.to !== undefined) {this.toId = properties.to;}
-
- if (properties.id !== undefined) {this.id = properties.id;}
- if (properties.style !== undefined) {this.style = properties.style;}
- if (properties.label !== undefined) {this.label = properties.label;}
-
- if (this.label) {
- this.fontSize = constants.edges.fontSize;
- this.fontFace = constants.edges.fontFace;
- this.fontColor = constants.edges.fontColor;
- this.fontFill = constants.edges.fontFill;
-
- if (properties.fontColor !== undefined) {this.fontColor = properties.fontColor;}
- if (properties.fontSize !== undefined) {this.fontSize = properties.fontSize;}
- if (properties.fontFace !== undefined) {this.fontFace = properties.fontFace;}
- if (properties.fontFill !== undefined) {this.fontFill = properties.fontFill;}
- }
-
- if (properties.title !== undefined) {this.title = properties.title;}
- if (properties.width !== undefined) {this.width = properties.width;}
- if (properties.widthSelectionMultiplier !== undefined)
- {this.widthSelectionMultiplier = properties.widthSelectionMultiplier;}
- if (properties.hoverWidth !== undefined) {this.hoverWidth = properties.hoverWidth;}
- if (properties.value !== undefined) {this.value = properties.value;}
- if (properties.length !== undefined) {this.length = properties.length;
- this.customLength = true;}
-
- // scale the arrow
- if (properties.arrowScaleFactor !== undefined) {this.arrowScaleFactor = properties.arrowScaleFactor;}
-
- if (properties.inheritColor !== undefined) {this.inheritColor = properties.inheritColor;}
-
- // Added to support dashed lines
- // David Jordan
- // 2012-08-08
- if (properties.dash) {
- if (properties.dash.length !== undefined) {this.dash.length = properties.dash.length;}
- if (properties.dash.gap !== undefined) {this.dash.gap = properties.dash.gap;}
- if (properties.dash.altLength !== undefined) {this.dash.altLength = properties.dash.altLength;}
- }
+ function parseEdge(graph, from) {
+ while (token == '->' || token == '--') {
+ var to;
+ var type = token;
+ getToken();
- if (properties.color !== undefined) {
- if (util.isString(properties.color)) {
- this.color.color = properties.color;
- this.color.highlight = properties.color;
+ var subgraph = parseSubgraph(graph);
+ if (subgraph) {
+ to = subgraph;
}
else {
- if (properties.color.color !== undefined) {this.color.color = properties.color.color;}
- if (properties.color.highlight !== undefined) {this.color.highlight = properties.color.highlight;}
- if (properties.color.hover !== undefined) {this.color.hover = properties.color.hover;}
+ if (tokenType != TOKENTYPE.IDENTIFIER) {
+ throw newSyntaxError('Identifier or subgraph expected');
+ }
+ to = token;
+ addNode(graph, {
+ id: to
+ });
+ getToken();
}
- }
-
- // A node is connected when it has a from and to node.
- this.connect();
- this.widthFixed = this.widthFixed || (properties.width !== undefined);
- this.lengthFixed = this.lengthFixed || (properties.length !== undefined);
+ // parse edge attributes
+ var attr = parseAttributeList();
- this.widthSelected = this.width * this.widthSelectionMultiplier;
+ // create edge
+ var edge = createEdge(graph, from, to, type, attr);
+ addEdge(graph, edge);
- // set draw method based on style
- switch (this.style) {
- case 'line': this.draw = this._drawLine; break;
- case 'arrow': this.draw = this._drawArrow; break;
- case 'arrow-center': this.draw = this._drawArrowCenter; break;
- case 'dash-line': this.draw = this._drawDashLine; break;
- default: this.draw = this._drawLine; break;
+ from = to;
}
- };
+ }
/**
- * Connect an edge to its nodes
+ * Parse a set with attributes,
+ * for example [label="1.000", shape=solid]
+ * @return {Object | null} attr
*/
- Edge.prototype.connect = function () {
- this.disconnect();
+ function parseAttributeList() {
+ var attr = null;
- this.from = this.network.nodes[this.fromId] || null;
- this.to = this.network.nodes[this.toId] || null;
- this.connected = (this.from && this.to);
+ while (token == '[') {
+ getToken();
+ attr = {};
+ while (token !== '' && token != ']') {
+ if (tokenType != TOKENTYPE.IDENTIFIER) {
+ throw newSyntaxError('Attribute name expected');
+ }
+ var name = token;
- if (this.connected) {
- this.from.attachEdge(this);
- this.to.attachEdge(this);
- }
- else {
- if (this.from) {
- this.from.detachEdge(this);
- }
- if (this.to) {
- this.to.detachEdge(this);
+ getToken();
+ if (token != '=') {
+ throw newSyntaxError('Equal sign = expected');
+ }
+ getToken();
+
+ if (tokenType != TOKENTYPE.IDENTIFIER) {
+ throw newSyntaxError('Attribute value expected');
+ }
+ var value = token;
+ setValue(attr, name, value); // name can be a path
+
+ getToken();
+ if (token ==',') {
+ getToken();
+ }
}
- }
- };
- /**
- * Disconnect an edge from its nodes
- */
- Edge.prototype.disconnect = function () {
- if (this.from) {
- this.from.detachEdge(this);
- this.from = null;
- }
- if (this.to) {
- this.to.detachEdge(this);
- this.to = null;
+ if (token != ']') {
+ throw newSyntaxError('Bracket ] expected');
+ }
+ getToken();
}
- this.connected = false;
- };
+ return attr;
+ }
/**
- * get the title of this edge.
- * @return {string} title The title of the edge, or undefined when no title
- * has been set.
+ * Create a syntax error with extra information on current token and index.
+ * @param {String} message
+ * @returns {SyntaxError} err
*/
- Edge.prototype.getTitle = function() {
- return typeof this.title === "function" ? this.title() : this.title;
- };
-
+ function newSyntaxError(message) {
+ return new SyntaxError(message + ', got "' + chop(token, 30) + '" (char ' + index + ')');
+ }
/**
- * Retrieve the value of the edge. Can be undefined
- * @return {Number} value
+ * Chop off text after a maximum length
+ * @param {String} text
+ * @param {Number} maxLength
+ * @returns {String}
*/
- Edge.prototype.getValue = function() {
- return this.value;
- };
+ function chop (text, maxLength) {
+ return (text.length <= maxLength) ? text : (text.substr(0, 27) + '...');
+ }
/**
- * Adjust the value range of the edge. The edge will adjust it's width
- * based on its value.
- * @param {Number} min
- * @param {Number} max
+ * Execute a function fn for each pair of elements in two arrays
+ * @param {Array | *} array1
+ * @param {Array | *} array2
+ * @param {function} fn
*/
- Edge.prototype.setValueRange = function(min, max) {
- if (!this.widthFixed && this.value !== undefined) {
- var scale = (this.widthMax - this.widthMin) / (max - min);
- this.width = (this.value - min) * scale + this.widthMin;
+ function forEach2(array1, array2, fn) {
+ if (array1 instanceof Array) {
+ array1.forEach(function (elem1) {
+ if (array2 instanceof Array) {
+ array2.forEach(function (elem2) {
+ fn(elem1, elem2);
+ });
+ }
+ else {
+ fn(elem1, array2);
+ }
+ });
}
- };
-
- /**
- * Redraw a edge
- * Draw this edge in the given canvas
- * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
- * @param {CanvasRenderingContext2D} ctx
- */
- Edge.prototype.draw = function(ctx) {
- throw "Method draw not initialized in edge";
- };
+ else {
+ if (array2 instanceof Array) {
+ array2.forEach(function (elem2) {
+ fn(array1, elem2);
+ });
+ }
+ else {
+ fn(array1, array2);
+ }
+ }
+ }
/**
- * Check if this object is overlapping with the provided object
- * @param {Object} obj an object with parameters left, top
- * @return {boolean} True if location is located on the edge
+ * Convert a string containing a graph in DOT language into a map containing
+ * with nodes and edges in the format of graph.
+ * @param {String} data Text containing a graph in DOT-notation
+ * @return {Object} graphData
*/
- Edge.prototype.isOverlappingWith = function(obj) {
- if (this.connected) {
- var distMax = 10;
- var xFrom = this.from.x;
- var yFrom = this.from.y;
- var xTo = this.to.x;
- var yTo = this.to.y;
- var xObj = obj.left;
- var yObj = obj.top;
-
- var dist = this._getDistanceToEdge(xFrom, yFrom, xTo, yTo, xObj, yObj);
+ function DOTToGraph (data) {
+ // parse the DOT file
+ var dotData = parseDOT(data);
+ var graphData = {
+ nodes: [],
+ edges: [],
+ options: {}
+ };
- return (dist < distMax);
- }
- else {
- return false
+ // copy the nodes
+ if (dotData.nodes) {
+ dotData.nodes.forEach(function (dotNode) {
+ var graphNode = {
+ id: dotNode.id,
+ label: String(dotNode.label || dotNode.id)
+ };
+ merge(graphNode, dotNode.attr);
+ if (graphNode.image) {
+ graphNode.shape = 'image';
+ }
+ graphData.nodes.push(graphNode);
+ });
}
- };
- Edge.prototype._getColor = function() {
- var colorObj = this.color;
- if (this.inheritColor == "to") {
- colorObj = {
- highlight: this.to.color.highlight.border,
- hover: this.to.color.hover.border,
- color: this.to.color.border
- };
- }
- else if (this.inheritColor == "from" || this.inheritColor == true) {
- colorObj = {
- highlight: this.from.color.highlight.border,
- hover: this.from.color.hover.border,
- color: this.from.color.border
- };
- }
-
- if (this.selected == true) {return colorObj.highlight;}
- else if (this.hover == true) {return colorObj.hover;}
- else {return colorObj.color;}
- }
-
-
- /**
- * Redraw a edge as a line
- * Draw this edge in the given canvas
- * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
- * @param {CanvasRenderingContext2D} ctx
- * @private
- */
- Edge.prototype._drawLine = function(ctx) {
- // set style
- ctx.strokeStyle = this._getColor();
- ctx.lineWidth = this._getLineWidth();
-
- if (this.from != this.to) {
- // draw line
- var via = this._line(ctx);
-
- // draw label
- var point;
- if (this.label) {
- if (this.smoothCurves.enabled == true && via != null) {
- var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
- var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
- point = {x:midpointX, y:midpointY};
- }
- else {
- point = this._pointOnLine(0.5);
- }
- this._label(ctx, this.label, point.x, point.y);
- }
- }
- else {
- var x, y;
- var radius = this.length / 4;
- var node = this.from;
- if (!node.width) {
- node.resize(ctx);
- }
- if (node.width > node.height) {
- x = node.x + node.width / 2;
- y = node.y - radius;
- }
- else {
- x = node.x + radius;
- y = node.y - node.height / 2;
- }
- this._circle(ctx, x, y, radius);
- point = this._pointOnCircle(x, y, radius, 0.5);
- this._label(ctx, this.label, point.x, point.y);
- }
- };
-
- /**
- * Get the line width of the edge. Depends on width and whether one of the
- * connected nodes is selected.
- * @return {Number} width
- * @private
- */
- Edge.prototype._getLineWidth = function() {
- if (this.selected == true) {
- return Math.min(this.widthSelected, this.widthMax)*this.networkScaleInv;
- }
- else {
- if (this.hover == true) {
- return Math.min(this.hoverWidth, this.widthMax)*this.networkScaleInv;
- }
- else {
- return this.width*this.networkScaleInv;
+ // copy the edges
+ if (dotData.edges) {
+ /**
+ * Convert an edge in DOT format to an edge with VisGraph format
+ * @param {Object} dotEdge
+ * @returns {Object} graphEdge
+ */
+ function convertEdge(dotEdge) {
+ var graphEdge = {
+ from: dotEdge.from,
+ to: dotEdge.to
+ };
+ merge(graphEdge, dotEdge.attr);
+ graphEdge.style = (dotEdge.type == '->') ? 'arrow' : 'line';
+ return graphEdge;
}
- }
- };
-
- Edge.prototype._getViaCoordinates = function () {
- var xVia = null;
- var yVia = null;
- var factor = this.smoothCurves.roundness;
- var type = this.smoothCurves.type;
- if (factor == 0) {
- return {x:null,y:null};
- }
- var dx = Math.abs(this.from.x - this.to.x);
- var dy = Math.abs(this.from.y - this.to.y);
- if (type == 'discrete' || type == 'diagonalCross') {
- if (Math.abs(this.from.x - this.to.x) < Math.abs(this.from.y - this.to.y)) {
- if (this.from.y > this.to.y) {
- if (this.from.x < this.to.x) {
- xVia = this.from.x + factor * dy;
- yVia = this.from.y - factor * dy;
- }
- else if (this.from.x > this.to.x) {
- xVia = this.from.x - factor * dy;
- yVia = this.from.y - factor * dy;
- }
- }
- else if (this.from.y < this.to.y) {
- if (this.from.x < this.to.x) {
- xVia = this.from.x + factor * dy;
- yVia = this.from.y + factor * dy;
- }
- else if (this.from.x > this.to.x) {
- xVia = this.from.x - factor * dy;
- yVia = this.from.y + factor * dy;
- }
- }
- if (type == "discrete") {
- xVia = dx < factor * dy ? this.from.x : xVia;
- }
- }
- else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) {
- if (this.from.y > this.to.y) {
- if (this.from.x < this.to.x) {
- xVia = this.from.x + factor * dx;
- yVia = this.from.y - factor * dx;
- }
- else if (this.from.x > this.to.x) {
- xVia = this.from.x - factor * dx;
- yVia = this.from.y - factor * dx;
- }
- }
- else if (this.from.y < this.to.y) {
- if (this.from.x < this.to.x) {
- xVia = this.from.x + factor * dx;
- yVia = this.from.y + factor * dx;
- }
- else if (this.from.x > this.to.x) {
- xVia = this.from.x - factor * dx;
- yVia = this.from.y + factor * dx;
- }
- }
- if (type == "discrete") {
- yVia = dy < factor * dx ? this.from.y : yVia;
- }
- }
- }
- else if (type == "straightCross") {
- if (Math.abs(this.from.x - this.to.x) < Math.abs(this.from.y - this.to.y)) {
- xVia = this.from.x;
- yVia = this.to.y
- }
- else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) {
- xVia = this.to.x;
- yVia = this.from.y;
- }
- }
- else if (type == 'horizontal') {
- xVia = this.to.x;
- yVia = this.from.y;
- }
- else if (type == 'vertical') {
- xVia = this.from.x;
- yVia = this.to.y;
- }
- else { // continuous
- if (Math.abs(this.from.x - this.to.x) < Math.abs(this.from.y - this.to.y)) {
- if (this.from.y > this.to.y) {
- if (this.from.x < this.to.x) {
- // console.log(1)
- xVia = this.from.x + factor * dy;
- yVia = this.from.y - factor * dy;
- xVia = this.to.x < xVia ? this.to.x : xVia;
- }
- else if (this.from.x > this.to.x) {
- // console.log(2)
- xVia = this.from.x - factor * dy;
- yVia = this.from.y - factor * dy;
- xVia = this.to.x > xVia ? this.to.x :xVia;
- }
+ dotData.edges.forEach(function (dotEdge) {
+ var from, to;
+ if (dotEdge.from instanceof Object) {
+ from = dotEdge.from.nodes;
}
- else if (this.from.y < this.to.y) {
- if (this.from.x < this.to.x) {
- // console.log(3)
- xVia = this.from.x + factor * dy;
- yVia = this.from.y + factor * dy;
- xVia = this.to.x < xVia ? this.to.x : xVia;
- }
- else if (this.from.x > this.to.x) {
- // console.log(4, this.from.x, this.to.x)
- xVia = this.from.x - factor * dy;
- yVia = this.from.y + factor * dy;
- xVia = this.to.x > xVia ? this.to.x : xVia;
+ else {
+ from = {
+ id: dotEdge.from
}
}
- }
- else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) {
- if (this.from.y > this.to.y) {
- if (this.from.x < this.to.x) {
- // console.log(5)
- xVia = this.from.x + factor * dx;
- yVia = this.from.y - factor * dx;
- yVia = this.to.y > yVia ? this.to.y : yVia;
- }
- else if (this.from.x > this.to.x) {
- // console.log(6)
- xVia = this.from.x - factor * dx;
- yVia = this.from.y - factor * dx;
- yVia = this.to.y > yVia ? this.to.y : yVia;
- }
+
+ if (dotEdge.to instanceof Object) {
+ to = dotEdge.to.nodes;
}
- else if (this.from.y < this.to.y) {
- if (this.from.x < this.to.x) {
- // console.log(7)
- xVia = this.from.x + factor * dx;
- yVia = this.from.y + factor * dx;
- yVia = this.to.y < yVia ? this.to.y : yVia;
- }
- else if (this.from.x > this.to.x) {
- // console.log(8)
- xVia = this.from.x - factor * dx;
- yVia = this.from.y + factor * dx;
- yVia = this.to.y < yVia ? this.to.y : yVia;
+ else {
+ to = {
+ id: dotEdge.to
}
}
- }
- }
+ if (dotEdge.from instanceof Object && dotEdge.from.edges) {
+ dotEdge.from.edges.forEach(function (subEdge) {
+ var graphEdge = convertEdge(subEdge);
+ graphData.edges.push(graphEdge);
+ });
+ }
- return {x:xVia, y:yVia};
- }
+ forEach2(from, to, function (from, to) {
+ var subEdge = createEdge(graphData, from.id, to.id, dotEdge.type, dotEdge.attr);
+ var graphEdge = convertEdge(subEdge);
+ graphData.edges.push(graphEdge);
+ });
- /**
- * Draw a line between two nodes
- * @param {CanvasRenderingContext2D} ctx
- * @private
- */
- Edge.prototype._line = function (ctx) {
- // draw a straight line
- ctx.beginPath();
- ctx.moveTo(this.from.x, this.from.y);
- if (this.smoothCurves.enabled == true) {
- if (this.smoothCurves.dynamic == false) {
- var via = this._getViaCoordinates();
- if (via.x == null) {
- ctx.lineTo(this.to.x, this.to.y);
- ctx.stroke();
- return null;
- }
- else {
- // this.via.x = via.x;
- // this.via.y = via.y;
- ctx.quadraticCurveTo(via.x,via.y,this.to.x, this.to.y);
- ctx.stroke();
- return via;
+ if (dotEdge.to instanceof Object && dotEdge.to.edges) {
+ dotEdge.to.edges.forEach(function (subEdge) {
+ var graphEdge = convertEdge(subEdge);
+ graphData.edges.push(graphEdge);
+ });
}
- }
- else {
- ctx.quadraticCurveTo(this.via.x,this.via.y,this.to.x, this.to.y);
- ctx.stroke();
- return this.via;
- }
- }
- else {
- ctx.lineTo(this.to.x, this.to.y);
- ctx.stroke();
- return null;
+ });
}
- };
-
- /**
- * Draw a line from a node to itself, a circle
- * @param {CanvasRenderingContext2D} ctx
- * @param {Number} x
- * @param {Number} y
- * @param {Number} radius
- * @private
- */
- Edge.prototype._circle = function (ctx, x, y, radius) {
- // draw a circle
- ctx.beginPath();
- ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
- ctx.stroke();
- };
-
- /**
- * Draw label with white background and with the middle at (x, y)
- * @param {CanvasRenderingContext2D} ctx
- * @param {String} text
- * @param {Number} x
- * @param {Number} y
- * @private
- */
- Edge.prototype._label = function (ctx, text, x, y) {
- if (text) {
- // TODO: cache the calculated size
- ctx.font = ((this.from.selected || this.to.selected) ? "bold " : "") +
- this.fontSize + "px " + this.fontFace;
- ctx.fillStyle = this.fontFill;
- var width = ctx.measureText(text).width;
- var height = this.fontSize;
- var left = x - width / 2;
- var top = y - height / 2;
- ctx.fillRect(left, top, width, height);
-
- // draw text
- ctx.fillStyle = this.fontColor || "black";
- ctx.textAlign = "left";
- ctx.textBaseline = "top";
- ctx.fillText(text, left, top);
+ // copy the options
+ if (dotData.attr) {
+ graphData.options = dotData.attr;
}
- };
- /**
- * Redraw a edge as a dashed line
- * Draw this edge in the given canvas
- * @author David Jordan
- * @date 2012-08-08
- * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
- * @param {CanvasRenderingContext2D} ctx
- * @private
- */
- Edge.prototype._drawDashLine = function(ctx) {
- // set style
- if (this.selected == true) {ctx.strokeStyle = this.color.highlight;}
- else if (this.hover == true) {ctx.strokeStyle = this.color.hover;}
- else {ctx.strokeStyle = this.color.color;}
+ return graphData;
+ }
- ctx.lineWidth = this._getLineWidth();
+ // exports
+ exports.parseDOT = parseDOT;
+ exports.DOTToGraph = DOTToGraph;
- var via = null;
- // only firefox and chrome support this method, else we use the legacy one.
- if (ctx.mozDash !== undefined || ctx.setLineDash !== undefined) {
- // configure the dash pattern
- var pattern = [0];
- if (this.dash.length !== undefined && this.dash.gap !== undefined) {
- pattern = [this.dash.length,this.dash.gap];
- }
- else {
- pattern = [5,5];
- }
- // set dash settings for chrome or firefox
- if (typeof ctx.setLineDash !== 'undefined') { //Chrome
- ctx.setLineDash(pattern);
- ctx.lineDashOffset = 0;
+/***/ },
+/* 44 */
+/***/ function(module, exports, __webpack_require__) {
- } else { //Firefox
- ctx.mozDash = pattern;
- ctx.mozDashOffset = 0;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Moroccan Arabic (ar-ma)
+ // author : ElFadili Yassine : https://github.com/ElFadiliY
+ // author : Abdel Said : https://github.com/abdelsaid
+
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ return moment.lang('ar-ma', {
+ months : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),
+ monthsShort : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),
+ weekdays : "الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
+ weekdaysShort : "احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),
+ weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[اليوم على الساعة] LT",
+ nextDay: '[غدا على الساعة] LT',
+ nextWeek: 'dddd [على الساعة] LT',
+ lastDay: '[أمس على الساعة] LT',
+ lastWeek: 'dddd [على الساعة] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "في %s",
+ past : "منذ %s",
+ s : "ثوان",
+ m : "دقيقة",
+ mm : "%d دقائق",
+ h : "ساعة",
+ hh : "%d ساعات",
+ d : "يوم",
+ dd : "%d أيام",
+ M : "شهر",
+ MM : "%d أشهر",
+ y : "سنة",
+ yy : "%d سنوات"
+ },
+ week : {
+ dow : 6, // Saturday is the first day of the week.
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- // draw the line
- via = this._line(ctx);
- // restore the dash settings.
- if (typeof ctx.setLineDash !== 'undefined') { //Chrome
- ctx.setLineDash([0]);
- ctx.lineDashOffset = 0;
+/***/ },
+/* 45 */
+/***/ function(module, exports, __webpack_require__) {
- } else { //Firefox
- ctx.mozDash = [0];
- ctx.mozDashOffset = 0;
- }
- }
- else { // unsupporting smooth lines
- // draw dashed line
- ctx.beginPath();
- ctx.lineCap = 'round';
- if (this.dash.altLength !== undefined) //If an alt dash value has been set add to the array this value
- {
- ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
- [this.dash.length,this.dash.gap,this.dash.altLength,this.dash.gap]);
- }
- else if (this.dash.length !== undefined && this.dash.gap !== undefined) //If a dash and gap value has been set add to the array this value
- {
- ctx.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,
- [this.dash.length,this.dash.gap]);
- }
- else //If all else fails draw a line
- {
- ctx.moveTo(this.from.x, this.from.y);
- ctx.lineTo(this.to.x, this.to.y);
- }
- ctx.stroke();
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Arabic Saudi Arabia (ar-sa)
+ // author : Suhail Alkowaileet : https://github.com/xsoh
- // draw label
- if (this.label) {
- var point;
- if (this.smoothCurves.enabled == true && via != null) {
- var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
- var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
- point = {x:midpointX, y:midpointY};
- }
- else {
- point = this._pointOnLine(0.5);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- this._label(ctx, this.label, point.x, point.y);
- }
- };
-
- /**
- * Get a point on a line
- * @param {Number} percentage. Value between 0 (line start) and 1 (line end)
- * @return {Object} point
- * @private
- */
- Edge.prototype._pointOnLine = function (percentage) {
- return {
- x: (1 - percentage) * this.from.x + percentage * this.to.x,
- y: (1 - percentage) * this.from.y + percentage * this.to.y
- }
- };
-
- /**
- * Get a point on a circle
- * @param {Number} x
- * @param {Number} y
- * @param {Number} radius
- * @param {Number} percentage. Value between 0 (line start) and 1 (line end)
- * @return {Object} point
- * @private
- */
- Edge.prototype._pointOnCircle = function (x, y, radius, percentage) {
- var angle = (percentage - 3/8) * 2 * Math.PI;
- return {
- x: x + radius * Math.cos(angle),
- y: y - radius * Math.sin(angle)
- }
- };
+ }(function (moment) {
+ var symbolMap = {
+ '1': '١',
+ '2': '٢',
+ '3': '٣',
+ '4': '٤',
+ '5': '٥',
+ '6': '٦',
+ '7': '٧',
+ '8': '٨',
+ '9': '٩',
+ '0': '٠'
+ }, numberMap = {
+ '١': '1',
+ '٢': '2',
+ '٣': '3',
+ '٤': '4',
+ '٥': '5',
+ '٦': '6',
+ '٧': '7',
+ '٨': '8',
+ '٩': '9',
+ '٠': '0'
+ };
- /**
- * Redraw a edge as a line with an arrow halfway the line
- * Draw this edge in the given canvas
- * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
- * @param {CanvasRenderingContext2D} ctx
- * @private
- */
- Edge.prototype._drawArrowCenter = function(ctx) {
- var point;
- // set style
- if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
- else if (this.hover == true) {ctx.strokeStyle = this.color.hover; ctx.fillStyle = this.color.hover;}
- else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
- ctx.lineWidth = this._getLineWidth();
+ return moment.lang('ar-sa', {
+ months : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),
+ monthsShort : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),
+ weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
+ weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),
+ weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 12) {
+ return "ص";
+ } else {
+ return "م";
+ }
+ },
+ calendar : {
+ sameDay: "[اليوم على الساعة] LT",
+ nextDay: '[غدا على الساعة] LT',
+ nextWeek: 'dddd [على الساعة] LT',
+ lastDay: '[أمس على الساعة] LT',
+ lastWeek: 'dddd [على الساعة] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "في %s",
+ past : "منذ %s",
+ s : "ثوان",
+ m : "دقيقة",
+ mm : "%d دقائق",
+ h : "ساعة",
+ hh : "%d ساعات",
+ d : "يوم",
+ dd : "%d أيام",
+ M : "شهر",
+ MM : "%d أشهر",
+ y : "سنة",
+ yy : "%d سنوات"
+ },
+ preparse: function (string) {
+ return string.replace(/[۰-۹]/g, function (match) {
+ return numberMap[match];
+ }).replace(/،/g, ',');
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ }).replace(/,/g, '،');
+ },
+ week : {
+ dow : 6, // Saturday is the first day of the week.
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- if (this.from != this.to) {
- // draw line
- var via = this._line(ctx);
- var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
- var length = (10 + 5 * this.width) * this.arrowScaleFactor;
- // draw an arrow halfway the line
- if (this.smoothCurves.enabled == true && via != null) {
- var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
- var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
- point = {x:midpointX, y:midpointY};
- }
- else {
- point = this._pointOnLine(0.5);
- }
+/***/ },
+/* 46 */
+/***/ function(module, exports, __webpack_require__) {
- ctx.arrow(point.x, point.y, angle, length);
- ctx.fill();
- ctx.stroke();
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Arabic (ar)
+ // author : Abdel Said : https://github.com/abdelsaid
+ // changes in months, weekdays : Ahmed Elkhatib
- // draw label
- if (this.label) {
- this._label(ctx, this.label, point.x, point.y);
- }
- }
- else {
- // draw circle
- var x, y;
- var radius = 0.25 * Math.max(100,this.length);
- var node = this.from;
- if (!node.width) {
- node.resize(ctx);
- }
- if (node.width > node.height) {
- x = node.x + node.width * 0.5;
- y = node.y - radius;
- }
- else {
- x = node.x + radius;
- y = node.y - node.height * 0.5;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- this._circle(ctx, x, y, radius);
+ }(function (moment) {
+ var symbolMap = {
+ '1': '١',
+ '2': '٢',
+ '3': '٣',
+ '4': '٤',
+ '5': '٥',
+ '6': '٦',
+ '7': '٧',
+ '8': '٨',
+ '9': '٩',
+ '0': '٠'
+ }, numberMap = {
+ '١': '1',
+ '٢': '2',
+ '٣': '3',
+ '٤': '4',
+ '٥': '5',
+ '٦': '6',
+ '٧': '7',
+ '٨': '8',
+ '٩': '9',
+ '٠': '0'
+ };
- // draw all arrows
- var angle = 0.2 * Math.PI;
- var length = (10 + 5 * this.width) * this.arrowScaleFactor;
- point = this._pointOnCircle(x, y, radius, 0.5);
- ctx.arrow(point.x, point.y, angle, length);
- ctx.fill();
- ctx.stroke();
+ return moment.lang('ar', {
+ months : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"),
+ monthsShort : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"),
+ weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
+ weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),
+ weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 12) {
+ return "ص";
+ } else {
+ return "م";
+ }
+ },
+ calendar : {
+ sameDay: "[اليوم على الساعة] LT",
+ nextDay: '[غدا على الساعة] LT',
+ nextWeek: 'dddd [على الساعة] LT',
+ lastDay: '[أمس على الساعة] LT',
+ lastWeek: 'dddd [على الساعة] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "في %s",
+ past : "منذ %s",
+ s : "ثوان",
+ m : "دقيقة",
+ mm : "%d دقائق",
+ h : "ساعة",
+ hh : "%d ساعات",
+ d : "يوم",
+ dd : "%d أيام",
+ M : "شهر",
+ MM : "%d أشهر",
+ y : "سنة",
+ yy : "%d سنوات"
+ },
+ preparse: function (string) {
+ return string.replace(/[۰-۹]/g, function (match) {
+ return numberMap[match];
+ }).replace(/،/g, ',');
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ }).replace(/,/g, '،');
+ },
+ week : {
+ dow : 6, // Saturday is the first day of the week.
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- // draw label
- if (this.label) {
- point = this._pointOnCircle(x, y, radius, 0.5);
- this._label(ctx, this.label, point.x, point.y);
- }
- }
- };
+/***/ },
+/* 47 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : azerbaijani (az)
+ // author : topchiyev : https://github.com/topchiyev
- /**
- * Redraw a edge as a line with an arrow
- * Draw this edge in the given canvas
- * The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
- * @param {CanvasRenderingContext2D} ctx
- * @private
- */
- Edge.prototype._drawArrow = function(ctx) {
- // set style
- if (this.selected == true) {ctx.strokeStyle = this.color.highlight; ctx.fillStyle = this.color.highlight;}
- else if (this.hover == true) {ctx.strokeStyle = this.color.hover; ctx.fillStyle = this.color.hover;}
- else {ctx.strokeStyle = this.color.color; ctx.fillStyle = this.color.color;}
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
- ctx.lineWidth = this._getLineWidth();
+ var suffixes = {
+ 1: "-inci",
+ 5: "-inci",
+ 8: "-inci",
+ 70: "-inci",
+ 80: "-inci",
- var angle, length;
- //draw a line
- if (this.from != this.to) {
- angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
- var dx = (this.to.x - this.from.x);
- var dy = (this.to.y - this.from.y);
- var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
+ 2: "-nci",
+ 7: "-nci",
+ 20: "-nci",
+ 50: "-nci",
- var fromBorderDist = this.from.distanceToBorder(ctx, angle + Math.PI);
- var fromBorderPoint = (edgeSegmentLength - fromBorderDist) / edgeSegmentLength;
- var xFrom = (fromBorderPoint) * this.from.x + (1 - fromBorderPoint) * this.to.x;
- var yFrom = (fromBorderPoint) * this.from.y + (1 - fromBorderPoint) * this.to.y;
+ 3: "-üncü",
+ 4: "-üncü",
+ 100: "-üncü",
- var via;
- if (this.smoothCurves.dynamic == true && this.smoothCurves.enabled == true ) {
- via = this.via;
- }
- else if (this.smoothCurves.enabled == true) {
- via = this._getViaCoordinates();
- }
+ 6: "-ncı",
- if (this.smoothCurves.enabled == true && via.x != null) {
- angle = Math.atan2((this.to.y - via.y), (this.to.x - via.x));
- dx = (this.to.x - via.x);
- dy = (this.to.y - via.y);
- edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
- }
- var toBorderDist = this.to.distanceToBorder(ctx, angle);
- var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
+ 9: "-uncu",
+ 10: "-uncu",
+ 30: "-uncu",
- var xTo,yTo;
- if (this.smoothCurves.enabled == true && via.x != null) {
- xTo = (1 - toBorderPoint) * via.x + toBorderPoint * this.to.x;
- yTo = (1 - toBorderPoint) * via.y + toBorderPoint * this.to.y;
- }
- else {
- xTo = (1 - toBorderPoint) * this.from.x + toBorderPoint * this.to.x;
- yTo = (1 - toBorderPoint) * this.from.y + toBorderPoint * this.to.y;
- }
+ 60: "-ıncı",
+ 90: "-ıncı"
+ };
+ return moment.lang('az', {
+ months : "yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),
+ monthsShort : "yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),
+ weekdays : "Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),
+ weekdaysShort : "Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"),
+ weekdaysMin : "Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[bugün saat] LT',
+ nextDay : '[sabah saat] LT',
+ nextWeek : '[gələn həftə] dddd [saat] LT',
+ lastDay : '[dünən] LT',
+ lastWeek : '[keçən həftə] dddd [saat] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s sonra",
+ past : "%s əvvəl",
+ s : "birneçə saniyyə",
+ m : "bir dəqiqə",
+ mm : "%d dəqiqə",
+ h : "bir saat",
+ hh : "%d saat",
+ d : "bir gün",
+ dd : "%d gün",
+ M : "bir ay",
+ MM : "%d ay",
+ y : "bir il",
+ yy : "%d il"
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 4) {
+ return "gecə";
+ } else if (hour < 12) {
+ return "səhər";
+ } else if (hour < 17) {
+ return "gündüz";
+ } else {
+ return "axşam";
+ }
+ },
+ ordinal : function (number) {
+ if (number === 0) { // special case for zero
+ return number + "-ıncı";
+ }
+ var a = number % 10,
+ b = number % 100 - a,
+ c = number >= 100 ? 100 : null;
- ctx.beginPath();
- ctx.moveTo(xFrom,yFrom);
- if (this.smoothCurves.enabled == true && via.x != null) {
- ctx.quadraticCurveTo(via.x,via.y,xTo, yTo);
- }
- else {
- ctx.lineTo(xTo, yTo);
- }
- ctx.stroke();
+ return number + (suffixes[a] || suffixes[b] || suffixes[c]);
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- // draw arrow at the end of the line
- length = (10 + 5 * this.width) * this.arrowScaleFactor;
- ctx.arrow(xTo, yTo, angle, length);
- ctx.fill();
- ctx.stroke();
- // draw label
- if (this.label) {
- var point;
- if (this.smoothCurves.enabled == true && via != null) {
- var midpointX = 0.5*(0.5*(this.from.x + via.x) + 0.5*(this.to.x + via.x));
- var midpointY = 0.5*(0.5*(this.from.y + via.y) + 0.5*(this.to.y + via.y));
- point = {x:midpointX, y:midpointY};
- }
- else {
- point = this._pointOnLine(0.5);
- }
- this._label(ctx, this.label, point.x, point.y);
- }
- }
- else {
- // draw circle
- var node = this.from;
- var x, y, arrow;
- var radius = 0.25 * Math.max(100,this.length);
- if (!node.width) {
- node.resize(ctx);
- }
- if (node.width > node.height) {
- x = node.x + node.width * 0.5;
- y = node.y - radius;
- arrow = {
- x: x,
- y: node.y,
- angle: 0.9 * Math.PI
- };
- }
- else {
- x = node.x + radius;
- y = node.y - node.height * 0.5;
- arrow = {
- x: node.x,
- y: y,
- angle: 0.6 * Math.PI
- };
- }
- ctx.beginPath();
- // TODO: similarly, for a line without arrows, draw to the border of the nodes instead of the center
- ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
- ctx.stroke();
+/***/ },
+/* 48 */
+/***/ function(module, exports, __webpack_require__) {
- // draw all arrows
- var length = (10 + 5 * this.width) * this.arrowScaleFactor;
- ctx.arrow(arrow.x, arrow.y, arrow.angle, length);
- ctx.fill();
- ctx.stroke();
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : bulgarian (bg)
+ // author : Krasen Borisov : https://github.com/kraz
- // draw label
- if (this.label) {
- point = this._pointOnCircle(x, y, radius, 0.5);
- this._label(ctx, this.label, point.x, point.y);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- };
-
-
-
- /**
- * Calculate the distance between a point (x3,y3) and a line segment from
- * (x1,y1) to (x2,y2).
- * http://stackoverflow.com/questions/849211/shortest-distancae-between-a-point-and-a-line-segment
- * @param {number} x1
- * @param {number} y1
- * @param {number} x2
- * @param {number} y2
- * @param {number} x3
- * @param {number} y3
- * @private
- */
- Edge.prototype._getDistanceToEdge = function (x1,y1, x2,y2, x3,y3) { // x3,y3 is the point
- if (this.from != this.to) {
- if (this.smoothCurves.enabled == true) {
- var xVia, yVia;
- if (this.smoothCurves.enabled == true && this.smoothCurves.dynamic == true) {
- xVia = this.via.x;
- yVia = this.via.y;
- }
- else {
- var via = this._getViaCoordinates();
- xVia = via.x;
- yVia = via.y;
- }
- var minDistance = 1e9;
- var i,t,x,y,dx,dy;
- for (i = 0; i < 10; i++) {
- t = 0.1*i;
- x = Math.pow(1-t,2)*x1 + (2*t*(1 - t))*xVia + Math.pow(t,2)*x2;
- y = Math.pow(1-t,2)*y1 + (2*t*(1 - t))*yVia + Math.pow(t,2)*y2;
- dx = Math.abs(x3-x);
- dy = Math.abs(y3-y);
- minDistance = Math.min(minDistance,Math.sqrt(dx*dx + dy*dy));
- }
- return minDistance
- }
- else {
- var px = x2-x1,
- py = y2-y1,
- something = px*px + py*py,
- u = ((x3 - x1) * px + (y3 - y1) * py) / something;
+ }(function (moment) {
+ return moment.lang('bg', {
+ months : "януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),
+ monthsShort : "янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),
+ weekdays : "неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),
+ weekdaysShort : "нед_пон_вто_сря_чет_пет_съб".split("_"),
+ weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "D.MM.YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Днес в] LT',
+ nextDay : '[Утре в] LT',
+ nextWeek : 'dddd [в] LT',
+ lastDay : '[Вчера в] LT',
+ lastWeek : function () {
+ switch (this.day()) {
+ case 0:
+ case 3:
+ case 6:
+ return '[В изминалата] dddd [в] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[В изминалия] dddd [в] LT';
+ }
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "след %s",
+ past : "преди %s",
+ s : "няколко секунди",
+ m : "минута",
+ mm : "%d минути",
+ h : "час",
+ hh : "%d часа",
+ d : "ден",
+ dd : "%d дни",
+ M : "месец",
+ MM : "%d месеца",
+ y : "година",
+ yy : "%d години"
+ },
+ ordinal : function (number) {
+ var lastDigit = number % 10,
+ last2Digits = number % 100;
+ if (number === 0) {
+ return number + '-ев';
+ } else if (last2Digits === 0) {
+ return number + '-ен';
+ } else if (last2Digits > 10 && last2Digits < 20) {
+ return number + '-ти';
+ } else if (lastDigit === 1) {
+ return number + '-ви';
+ } else if (lastDigit === 2) {
+ return number + '-ри';
+ } else if (lastDigit === 7 || lastDigit === 8) {
+ return number + '-ми';
+ } else {
+ return number + '-ти';
+ }
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- if (u > 1) {
- u = 1;
- }
- else if (u < 0) {
- u = 0;
- }
- var x = x1 + u * px,
- y = y1 + u * py,
- dx = x - x3,
- dy = y - y3;
+/***/ },
+/* 49 */
+/***/ function(module, exports, __webpack_require__) {
- //# Note: If the actual distance does not matter,
- //# if you only want to compare what this function
- //# returns to other results of this function, you
- //# can just return the squared distance instead
- //# (i.e. remove the sqrt) to gain a little performance
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Bengali (bn)
+ // author : Kaushik Gandhi : https://github.com/kaushikgandhi
- return Math.sqrt(dx*dx + dy*dy);
- }
- }
- else {
- var x, y, dx, dy;
- var radius = this.length / 4;
- var node = this.from;
- if (!node.width) {
- node.resize(ctx);
- }
- if (node.width > node.height) {
- x = node.x + node.width / 2;
- y = node.y - radius;
- }
- else {
- x = node.x + radius;
- y = node.y - node.height / 2;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- dx = x - x3;
- dy = y - y3;
- return Math.abs(Math.sqrt(dx*dx + dy*dy) - radius);
- }
- };
+ }(function (moment) {
+ var symbolMap = {
+ '1': '১',
+ '2': '২',
+ '3': '৩',
+ '4': '৪',
+ '5': '৫',
+ '6': '৬',
+ '7': '৭',
+ '8': '৮',
+ '9': '৯',
+ '0': '০'
+ },
+ numberMap = {
+ '১': '1',
+ '২': '2',
+ '৩': '3',
+ '৪': '4',
+ '৫': '5',
+ '৬': '6',
+ '৭': '7',
+ '৮': '8',
+ '৯': '9',
+ '০': '0'
+ };
+ return moment.lang('bn', {
+ months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split("_"),
+ monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split("_"),
+ weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split("_"),
+ weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split("_"),
+ weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split("_"),
+ longDateFormat : {
+ LT : "A h:mm সময়",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY, LT",
+ LLLL : "dddd, D MMMM YYYY, LT"
+ },
+ calendar : {
+ sameDay : '[আজ] LT',
+ nextDay : '[আগামীকাল] LT',
+ nextWeek : 'dddd, LT',
+ lastDay : '[গতকাল] LT',
+ lastWeek : '[গত] dddd, LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s পরে",
+ past : "%s আগে",
+ s : "কএক সেকেন্ড",
+ m : "এক মিনিট",
+ mm : "%d মিনিট",
+ h : "এক ঘন্টা",
+ hh : "%d ঘন্টা",
+ d : "এক দিন",
+ dd : "%d দিন",
+ M : "এক মাস",
+ MM : "%d মাস",
+ y : "এক বছর",
+ yy : "%d বছর"
+ },
+ preparse: function (string) {
+ return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
+ return numberMap[match];
+ });
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ });
+ },
+ //Bengali is a vast language its spoken
+ //in different forms in various parts of the world.
+ //I have just generalized with most common one used
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 4) {
+ return "রাত";
+ } else if (hour < 10) {
+ return "শকাল";
+ } else if (hour < 17) {
+ return "দুপুর";
+ } else if (hour < 20) {
+ return "বিকেল";
+ } else {
+ return "রাত";
+ }
+ },
+ week : {
+ dow : 0, // Sunday is the first day of the week.
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * This allows the zoom level of the network to influence the rendering
- *
- * @param scale
- */
- Edge.prototype.setScale = function(scale) {
- this.networkScaleInv = 1.0/scale;
- };
+/***/ },
+/* 50 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : breton (br)
+ // author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
- Edge.prototype.select = function() {
- this.selected = true;
- };
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function relativeTimeWithMutation(number, withoutSuffix, key) {
+ var format = {
+ 'mm': "munutenn",
+ 'MM': "miz",
+ 'dd': "devezh"
+ };
+ return number + ' ' + mutation(format[key], number);
+ }
- Edge.prototype.unselect = function() {
- this.selected = false;
- };
+ function specialMutationForYears(number) {
+ switch (lastNumber(number)) {
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ case 9:
+ return number + ' bloaz';
+ default:
+ return number + ' vloaz';
+ }
+ }
- Edge.prototype.positionBezierNode = function() {
- if (this.via !== null) {
- this.via.x = 0.5 * (this.from.x + this.to.x);
- this.via.y = 0.5 * (this.from.y + this.to.y);
- }
- };
+ function lastNumber(number) {
+ if (number > 9) {
+ return lastNumber(number % 10);
+ }
+ return number;
+ }
- /**
- * This function draws the control nodes for the manipulator. In order to enable this, only set the this.controlNodesEnabled to true.
- * @param ctx
- */
- Edge.prototype._drawControlNodes = function(ctx) {
- if (this.controlNodesEnabled == true) {
- if (this.controlNodes.from === null && this.controlNodes.to === null) {
- var nodeIdFrom = "edgeIdFrom:".concat(this.id);
- var nodeIdTo = "edgeIdTo:".concat(this.id);
- var constants = {
- nodes:{group:'', radius:8},
- physics:{damping:0},
- clustering: {maxNodeSizeIncrements: 0 ,nodeScaling: {width:0, height: 0, radius:0}}
- };
- this.controlNodes.from = new Node(
- {id:nodeIdFrom,
- shape:'dot',
- color:{background:'#ff4e00', border:'#3c3c3c', highlight: {background:'#07f968'}}
- },{},{},constants);
- this.controlNodes.to = new Node(
- {id:nodeIdTo,
- shape:'dot',
- color:{background:'#ff4e00', border:'#3c3c3c', highlight: {background:'#07f968'}}
- },{},{},constants);
+ function mutation(text, number) {
+ if (number === 2) {
+ return softMutation(text);
+ }
+ return text;
}
- if (this.controlNodes.from.selected == false && this.controlNodes.to.selected == false) {
- this.controlNodes.positions = this.getControlNodePositions(ctx);
- this.controlNodes.from.x = this.controlNodes.positions.from.x;
- this.controlNodes.from.y = this.controlNodes.positions.from.y;
- this.controlNodes.to.x = this.controlNodes.positions.to.x;
- this.controlNodes.to.y = this.controlNodes.positions.to.y;
+ function softMutation(text) {
+ var mutationTable = {
+ 'm': 'v',
+ 'b': 'v',
+ 'd': 'z'
+ };
+ if (mutationTable[text.charAt(0)] === undefined) {
+ return text;
+ }
+ return mutationTable[text.charAt(0)] + text.substring(1);
}
- this.controlNodes.from.draw(ctx);
- this.controlNodes.to.draw(ctx);
- }
- else {
- this.controlNodes = {from:null, to:null, positions:{}};
- }
- };
+ return moment.lang('br', {
+ months : "Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),
+ monthsShort : "Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),
+ weekdays : "Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),
+ weekdaysShort : "Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),
+ weekdaysMin : "Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),
+ longDateFormat : {
+ LT : "h[e]mm A",
+ L : "DD/MM/YYYY",
+ LL : "D [a viz] MMMM YYYY",
+ LLL : "D [a viz] MMMM YYYY LT",
+ LLLL : "dddd, D [a viz] MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Hiziv da] LT',
+ nextDay : '[Warc\'hoazh da] LT',
+ nextWeek : 'dddd [da] LT',
+ lastDay : '[Dec\'h da] LT',
+ lastWeek : 'dddd [paset da] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "a-benn %s",
+ past : "%s 'zo",
+ s : "un nebeud segondennoù",
+ m : "ur vunutenn",
+ mm : relativeTimeWithMutation,
+ h : "un eur",
+ hh : "%d eur",
+ d : "un devezh",
+ dd : relativeTimeWithMutation,
+ M : "ur miz",
+ MM : relativeTimeWithMutation,
+ y : "ur bloaz",
+ yy : specialMutationForYears
+ },
+ ordinal : function (number) {
+ var output = (number === 1) ? 'añ' : 'vet';
+ return number + output;
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * Enable control nodes.
- * @private
- */
- Edge.prototype._enableControlNodes = function() {
- this.controlNodesEnabled = true;
- };
- /**
- * disable control nodes
- * @private
- */
- Edge.prototype._disableControlNodes = function() {
- this.controlNodesEnabled = false;
- };
+/***/ },
+/* 51 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This checks if one of the control nodes is selected and if so, returns the control node object. Else it returns null.
- * @param x
- * @param y
- * @returns {null}
- * @private
- */
- Edge.prototype._getSelectedControlNode = function(x,y) {
- var positions = this.controlNodes.positions;
- var fromDistance = Math.sqrt(Math.pow(x - positions.from.x,2) + Math.pow(y - positions.from.y,2));
- var toDistance = Math.sqrt(Math.pow(x - positions.to.x ,2) + Math.pow(y - positions.to.y ,2));
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : bosnian (bs)
+ // author : Nedim Cholich : https://github.com/frontyard
+ // based on (hr) translation by Bojan Marković
- if (fromDistance < 15) {
- this.connectedNode = this.from;
- this.from = this.controlNodes.from;
- return this.controlNodes.from;
- }
- else if (toDistance < 15) {
- this.connectedNode = this.to;
- this.to = this.controlNodes.to;
- return this.controlNodes.to;
- }
- else {
- return null;
- }
- };
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function translate(number, withoutSuffix, key) {
+ var result = number + " ";
+ switch (key) {
+ case 'm':
+ return withoutSuffix ? 'jedna minuta' : 'jedne minute';
+ case 'mm':
+ if (number === 1) {
+ result += 'minuta';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'minute';
+ } else {
+ result += 'minuta';
+ }
+ return result;
+ case 'h':
+ return withoutSuffix ? 'jedan sat' : 'jednog sata';
+ case 'hh':
+ if (number === 1) {
+ result += 'sat';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'sata';
+ } else {
+ result += 'sati';
+ }
+ return result;
+ case 'dd':
+ if (number === 1) {
+ result += 'dan';
+ } else {
+ result += 'dana';
+ }
+ return result;
+ case 'MM':
+ if (number === 1) {
+ result += 'mjesec';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'mjeseca';
+ } else {
+ result += 'mjeseci';
+ }
+ return result;
+ case 'yy':
+ if (number === 1) {
+ result += 'godina';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'godine';
+ } else {
+ result += 'godina';
+ }
+ return result;
+ }
+ }
- /**
- * this resets the control nodes to their original position.
- * @private
- */
- Edge.prototype._restoreControlNodes = function() {
- if (this.controlNodes.from.selected == true) {
- this.from = this.connectedNode;
- this.connectedNode = null;
- this.controlNodes.from.unselect();
- }
- if (this.controlNodes.to.selected == true) {
- this.to = this.connectedNode;
- this.connectedNode = null;
- this.controlNodes.to.unselect();
- }
- };
-
- /**
- * this calculates the position of the control nodes on the edges of the parent nodes.
- *
- * @param ctx
- * @returns {{from: {x: number, y: number}, to: {x: *, y: *}}}
- */
- Edge.prototype.getControlNodePositions = function(ctx) {
- var angle = Math.atan2((this.to.y - this.from.y), (this.to.x - this.from.x));
- var dx = (this.to.x - this.from.x);
- var dy = (this.to.y - this.from.y);
- var edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
- var fromBorderDist = this.from.distanceToBorder(ctx, angle + Math.PI);
- var fromBorderPoint = (edgeSegmentLength - fromBorderDist) / edgeSegmentLength;
- var xFrom = (fromBorderPoint) * this.from.x + (1 - fromBorderPoint) * this.to.x;
- var yFrom = (fromBorderPoint) * this.from.y + (1 - fromBorderPoint) * this.to.y;
-
- var via;
- if (this.smoothCurves.dynamic == true && this.smoothCurves.enabled == true) {
- via = this.via;
- }
- else if (this.smoothCurves.enabled == true) {
- via = this._getViaCoordinates();
- }
-
- if (this.smoothCurves.enabled == true && via.x != null) {
- angle = Math.atan2((this.to.y - via.y), (this.to.x - via.x));
- dx = (this.to.x - via.x);
- dy = (this.to.y - via.y);
- edgeSegmentLength = Math.sqrt(dx * dx + dy * dy);
- }
- var toBorderDist = this.to.distanceToBorder(ctx, angle);
- var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength;
-
- var xTo,yTo;
- if (this.smoothCurves.enabled == true && via.x != null) {
- xTo = (1 - toBorderPoint) * via.x + toBorderPoint * this.to.x;
- yTo = (1 - toBorderPoint) * via.y + toBorderPoint * this.to.y;
- }
- else {
- xTo = (1 - toBorderPoint) * this.from.x + toBorderPoint * this.to.x;
- yTo = (1 - toBorderPoint) * this.from.y + toBorderPoint * this.to.y;
- }
+ return moment.lang('bs', {
+ months : "januar_februar_mart_april_maj_juni_juli_avgust_septembar_oktobar_novembar_decembar".split("_"),
+ monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
+ weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),
+ weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"),
+ weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD. MM. YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd, D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[danas u] LT',
+ nextDay : '[sutra u] LT',
- return {from:{x:xFrom,y:yFrom},to:{x:xTo,y:yTo}};
- };
+ nextWeek : function () {
+ switch (this.day()) {
+ case 0:
+ return '[u] [nedjelju] [u] LT';
+ case 3:
+ return '[u] [srijedu] [u] LT';
+ case 6:
+ return '[u] [subotu] [u] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[u] dddd [u] LT';
+ }
+ },
+ lastDay : '[jučer u] LT',
+ lastWeek : function () {
+ switch (this.day()) {
+ case 0:
+ case 3:
+ return '[prošlu] dddd [u] LT';
+ case 6:
+ return '[prošle] [subote] [u] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[prošli] dddd [u] LT';
+ }
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "za %s",
+ past : "prije %s",
+ s : "par sekundi",
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : "dan",
+ dd : translate,
+ M : "mjesec",
+ MM : translate,
+ y : "godinu",
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- module.exports = Edge;
/***/ },
-/* 44 */
+/* 52 */
/***/ function(module, exports, __webpack_require__) {
- /**
- * Popup is a class to create a popup window with some text
- * @param {Element} container The container object.
- * @param {Number} [x]
- * @param {Number} [y]
- * @param {String} [text]
- * @param {Object} [style] An object containing borderColor,
- * backgroundColor, etc.
- */
- function Popup(container, x, y, text, style) {
- if (container) {
- this.container = container;
- }
- else {
- this.container = document.body;
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : catalan (ca)
+ // author : Juan G. Hurtado : https://github.com/juanghurtado
- // x, y and text are optional, see if a style object was passed in their place
- if (style === undefined) {
- if (typeof x === "object") {
- style = x;
- x = undefined;
- } else if (typeof text === "object") {
- style = text;
- text = undefined;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
} else {
- // for backwards compatibility, in case clients other than Network are creating Popup directly
- style = {
- fontColor: 'black',
- fontSize: 14, // px
- fontFace: 'verdana',
- color: {
- border: '#666',
- background: '#FFFFC6'
- }
- }
+ factory(window.moment); // Browser global
}
- }
-
- this.x = 0;
- this.y = 0;
- this.padding = 5;
-
- if (x !== undefined && y !== undefined ) {
- this.setPosition(x, y);
- }
- if (text !== undefined) {
- this.setText(text);
- }
-
- // create the frame
- this.frame = document.createElement("div");
- var styleAttr = this.frame.style;
- styleAttr.position = "absolute";
- styleAttr.visibility = "hidden";
- styleAttr.border = "1px solid " + style.color.border;
- styleAttr.color = style.fontColor;
- styleAttr.fontSize = style.fontSize + "px";
- styleAttr.fontFamily = style.fontFace;
- styleAttr.padding = this.padding + "px";
- styleAttr.backgroundColor = style.color.background;
- styleAttr.borderRadius = "3px";
- styleAttr.MozBorderRadius = "3px";
- styleAttr.WebkitBorderRadius = "3px";
- styleAttr.boxShadow = "3px 3px 10px rgba(128, 128, 128, 0.5)";
- styleAttr.whiteSpace = "nowrap";
- this.container.appendChild(this.frame);
- }
-
- /**
- * @param {number} x Horizontal position of the popup window
- * @param {number} y Vertical position of the popup window
- */
- Popup.prototype.setPosition = function(x, y) {
- this.x = parseInt(x);
- this.y = parseInt(y);
- };
+ }(function (moment) {
+ return moment.lang('ca', {
+ months : "gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),
+ monthsShort : "gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),
+ weekdays : "diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),
+ weekdaysShort : "dg._dl._dt._dc._dj._dv._ds.".split("_"),
+ weekdaysMin : "Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : function () {
+ return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+ },
+ nextDay : function () {
+ return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+ },
+ nextWeek : function () {
+ return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+ },
+ lastDay : function () {
+ return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+ },
+ lastWeek : function () {
+ return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "en %s",
+ past : "fa %s",
+ s : "uns segons",
+ m : "un minut",
+ mm : "%d minuts",
+ h : "una hora",
+ hh : "%d hores",
+ d : "un dia",
+ dd : "%d dies",
+ M : "un mes",
+ MM : "%d mesos",
+ y : "un any",
+ yy : "%d anys"
+ },
+ ordinal : '%dº',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * Set the text for the popup window. This can be HTML code
- * @param {string} text
- */
- Popup.prototype.setText = function(text) {
- this.frame.innerHTML = text;
- };
- /**
- * Show the popup window
- * @param {boolean} show Optional. Show or hide the window
- */
- Popup.prototype.show = function (show) {
- if (show === undefined) {
- show = true;
- }
+/***/ },
+/* 53 */
+/***/ function(module, exports, __webpack_require__) {
- if (show) {
- var height = this.frame.clientHeight;
- var width = this.frame.clientWidth;
- var maxHeight = this.frame.parentNode.clientHeight;
- var maxWidth = this.frame.parentNode.clientWidth;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : czech (cs)
+ // author : petrbela : https://github.com/petrbela
- var top = (this.y - height);
- if (top + height + this.padding > maxHeight) {
- top = maxHeight - height - this.padding;
- }
- if (top < this.padding) {
- top = this.padding;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ var months = "leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),
+ monthsShort = "led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_");
- var left = this.x;
- if (left + width + this.padding > maxWidth) {
- left = maxWidth - width - this.padding;
- }
- if (left < this.padding) {
- left = this.padding;
+ function plural(n) {
+ return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
}
- this.frame.style.left = left + "px";
- this.frame.style.top = top + "px";
- this.frame.style.visibility = "visible";
- }
- else {
- this.hide();
- }
- };
-
- /**
- * Hide the popup window
- */
- Popup.prototype.hide = function () {
- this.frame.style.visibility = "hidden";
- };
+ function translate(number, withoutSuffix, key, isFuture) {
+ var result = number + " ";
+ switch (key) {
+ case 's': // a few seconds / in a few seconds / a few seconds ago
+ return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
+ case 'm': // a minute / in a minute / a minute ago
+ return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
+ case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'minuty' : 'minut');
+ } else {
+ return result + 'minutami';
+ }
+ break;
+ case 'h': // an hour / in an hour / an hour ago
+ return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
+ case 'hh': // 9 hours / in 9 hours / 9 hours ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'hodiny' : 'hodin');
+ } else {
+ return result + 'hodinami';
+ }
+ break;
+ case 'd': // a day / in a day / a day ago
+ return (withoutSuffix || isFuture) ? 'den' : 'dnem';
+ case 'dd': // 9 days / in 9 days / 9 days ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'dny' : 'dní');
+ } else {
+ return result + 'dny';
+ }
+ break;
+ case 'M': // a month / in a month / a month ago
+ return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
+ case 'MM': // 9 months / in 9 months / 9 months ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'měsíce' : 'měsíců');
+ } else {
+ return result + 'měsíci';
+ }
+ break;
+ case 'y': // a year / in a year / a year ago
+ return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
+ case 'yy': // 9 years / in 9 years / 9 years ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'roky' : 'let');
+ } else {
+ return result + 'lety';
+ }
+ break;
+ }
+ }
- module.exports = Popup;
+ return moment.lang('cs', {
+ months : months,
+ monthsShort : monthsShort,
+ monthsParse : (function (months, monthsShort) {
+ var i, _monthsParse = [];
+ for (i = 0; i < 12; i++) {
+ // use custom parser to solve problem with July (červenec)
+ _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
+ }
+ return _monthsParse;
+ }(months, monthsShort)),
+ weekdays : "neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),
+ weekdaysShort : "ne_po_út_st_čt_pá_so".split("_"),
+ weekdaysMin : "ne_po_út_st_čt_pá_so".split("_"),
+ longDateFormat : {
+ LT: "H.mm",
+ L : "DD. MM. YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[dnes v] LT",
+ nextDay: '[zítra v] LT',
+ nextWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[v neděli v] LT';
+ case 1:
+ case 2:
+ return '[v] dddd [v] LT';
+ case 3:
+ return '[ve středu v] LT';
+ case 4:
+ return '[ve čtvrtek v] LT';
+ case 5:
+ return '[v pátek v] LT';
+ case 6:
+ return '[v sobotu v] LT';
+ }
+ },
+ lastDay: '[včera v] LT',
+ lastWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[minulou neděli v] LT';
+ case 1:
+ case 2:
+ return '[minulé] dddd [v] LT';
+ case 3:
+ return '[minulou středu v] LT';
+ case 4:
+ case 5:
+ return '[minulý] dddd [v] LT';
+ case 6:
+ return '[minulou sobotu v] LT';
+ }
+ },
+ sameElse: "L"
+ },
+ relativeTime : {
+ future : "za %s",
+ past : "před %s",
+ s : translate,
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : translate,
+ dd : translate,
+ M : translate,
+ MM : translate,
+ y : translate,
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
/***/ },
-/* 45 */
+/* 54 */
/***/ function(module, exports, __webpack_require__) {
- var PhysicsMixin = __webpack_require__(46);
- var ClusterMixin = __webpack_require__(47);
- var SectorsMixin = __webpack_require__(48);
- var SelectionMixin = __webpack_require__(49);
- var ManipulationMixin = __webpack_require__(50);
- var NavigationMixin = __webpack_require__(51);
- var HierarchicalLayoutMixin = __webpack_require__(52);
-
- /**
- * Load a mixin into the network object
- *
- * @param {Object} sourceVariable | this object has to contain functions.
- * @private
- */
- exports._loadMixin = function (sourceVariable) {
- for (var mixinFunction in sourceVariable) {
- if (sourceVariable.hasOwnProperty(mixinFunction)) {
- this[mixinFunction] = sourceVariable[mixinFunction];
- }
- }
- };
-
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : chuvash (cv)
+ // author : Anatoly Mironov : https://github.com/mirontoli
- /**
- * removes a mixin from the network object.
- *
- * @param {Object} sourceVariable | this object has to contain functions.
- * @private
- */
- exports._clearMixin = function (sourceVariable) {
- for (var mixinFunction in sourceVariable) {
- if (sourceVariable.hasOwnProperty(mixinFunction)) {
- this[mixinFunction] = undefined;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- };
-
-
- /**
- * Mixin the physics system and initialize the parameters required.
- *
- * @private
- */
- exports._loadPhysicsSystem = function () {
- this._loadMixin(PhysicsMixin);
- this._loadSelectedForceSolver();
- if (this.constants.configurePhysics == true) {
- this._loadPhysicsConfiguration();
- }
- };
-
-
- /**
- * Mixin the cluster system and initialize the parameters required.
- *
- * @private
- */
- exports._loadClusterSystem = function () {
- this.clusterSession = 0;
- this.hubThreshold = 5;
- this._loadMixin(ClusterMixin);
- };
-
+ }(function (moment) {
+ return moment.lang('cv', {
+ months : "кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"),
+ monthsShort : "кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"),
+ weekdays : "вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун".split("_"),
+ weekdaysShort : "выр_тун_ытл_юн_кĕç_эрн_шăм".split("_"),
+ weekdaysMin : "вр_тн_ыт_юн_кç_эр_шм".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD-MM-YYYY",
+ LL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]",
+ LLL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT",
+ LLLL : "dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT"
+ },
+ calendar : {
+ sameDay: '[Паян] LT [сехетре]',
+ nextDay: '[Ыран] LT [сехетре]',
+ lastDay: '[Ĕнер] LT [сехетре]',
+ nextWeek: '[Çитес] dddd LT [сехетре]',
+ lastWeek: '[Иртнĕ] dddd LT [сехетре]',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : function (output) {
+ var affix = /сехет$/i.exec(output) ? "рен" : /çул$/i.exec(output) ? "тан" : "ран";
+ return output + affix;
+ },
+ past : "%s каялла",
+ s : "пĕр-ик çеккунт",
+ m : "пĕр минут",
+ mm : "%d минут",
+ h : "пĕр сехет",
+ hh : "%d сехет",
+ d : "пĕр кун",
+ dd : "%d кун",
+ M : "пĕр уйăх",
+ MM : "%d уйăх",
+ y : "пĕр çул",
+ yy : "%d çул"
+ },
+ ordinal : '%d-мĕш',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * Mixin the sector system and initialize the parameters required
- *
- * @private
- */
- exports._loadSectorSystem = function () {
- this.sectors = {};
- this.activeSector = ["default"];
- this.sectors["active"] = {};
- this.sectors["active"]["default"] = {"nodes": {},
- "edges": {},
- "nodeIndices": [],
- "formationScale": 1.0,
- "drawingNode": undefined };
- this.sectors["frozen"] = {};
- this.sectors["support"] = {"nodes": {},
- "edges": {},
- "nodeIndices": [],
- "formationScale": 1.0,
- "drawingNode": undefined };
- this.nodeIndices = this.sectors["active"]["default"]["nodeIndices"]; // the node indices list is used to speed up the computation of the repulsion fields
+/***/ },
+/* 55 */
+/***/ function(module, exports, __webpack_require__) {
- this._loadMixin(SectorsMixin);
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Welsh (cy)
+ // author : Robert Allen
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang("cy", {
+ months: "Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),
+ monthsShort: "Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),
+ weekdays: "Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),
+ weekdaysShort: "Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),
+ weekdaysMin: "Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),
+ // time formats are the same as en-gb
+ longDateFormat: {
+ LT: "HH:mm",
+ L: "DD/MM/YYYY",
+ LL: "D MMMM YYYY",
+ LLL: "D MMMM YYYY LT",
+ LLLL: "dddd, D MMMM YYYY LT"
+ },
+ calendar: {
+ sameDay: '[Heddiw am] LT',
+ nextDay: '[Yfory am] LT',
+ nextWeek: 'dddd [am] LT',
+ lastDay: '[Ddoe am] LT',
+ lastWeek: 'dddd [diwethaf am] LT',
+ sameElse: 'L'
+ },
+ relativeTime: {
+ future: "mewn %s",
+ past: "%s yn ôl",
+ s: "ychydig eiliadau",
+ m: "munud",
+ mm: "%d munud",
+ h: "awr",
+ hh: "%d awr",
+ d: "diwrnod",
+ dd: "%d diwrnod",
+ M: "mis",
+ MM: "%d mis",
+ y: "blwyddyn",
+ yy: "%d flynedd"
+ },
+ // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
+ ordinal: function (number) {
+ var b = number,
+ output = '',
+ lookup = [
+ '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
+ 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
+ ];
- /**
- * Mixin the selection system and initialize the parameters required
- *
- * @private
- */
- exports._loadSelectionSystem = function () {
- this.selectionObj = {nodes: {}, edges: {}};
+ if (b > 20) {
+ if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
+ output = 'fed'; // not 30ain, 70ain or 90ain
+ } else {
+ output = 'ain';
+ }
+ } else if (b > 0) {
+ output = lookup[b];
+ }
- this._loadMixin(SelectionMixin);
- };
+ return number + output;
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * Mixin the navigationUI (User Interface) system and initialize the parameters required
- *
- * @private
- */
- exports._loadManipulationSystem = function () {
- // reset global variables -- these are used by the selection of nodes and edges.
- this.blockConnectingEdgeSelection = false;
- this.forceAppendSelection = false;
+/***/ },
+/* 56 */
+/***/ function(module, exports, __webpack_require__) {
- if (this.constants.dataManipulation.enabled == true) {
- // load the manipulator HTML elements. All styling done in css.
- if (this.manipulationDiv === undefined) {
- this.manipulationDiv = document.createElement('div');
- this.manipulationDiv.className = 'network-manipulationDiv';
- this.manipulationDiv.id = 'network-manipulationDiv';
- if (this.editMode == true) {
- this.manipulationDiv.style.display = "block";
- }
- else {
- this.manipulationDiv.style.display = "none";
- }
- this.containerElement.insertBefore(this.manipulationDiv, this.frame);
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : danish (da)
+ // author : Ulrik Nielsen : https://github.com/mrbase
- if (this.editModeDiv === undefined) {
- this.editModeDiv = document.createElement('div');
- this.editModeDiv.className = 'network-manipulation-editMode';
- this.editModeDiv.id = 'network-manipulation-editMode';
- if (this.editMode == true) {
- this.editModeDiv.style.display = "none";
- }
- else {
- this.editModeDiv.style.display = "block";
- }
- this.containerElement.insertBefore(this.editModeDiv, this.frame);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ return moment.lang('da', {
+ months : "januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),
+ monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),
+ weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),
+ weekdaysShort : "søn_man_tir_ons_tor_fre_lør".split("_"),
+ weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd [d.] D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[I dag kl.] LT',
+ nextDay : '[I morgen kl.] LT',
+ nextWeek : 'dddd [kl.] LT',
+ lastDay : '[I går kl.] LT',
+ lastWeek : '[sidste] dddd [kl] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "om %s",
+ past : "%s siden",
+ s : "få sekunder",
+ m : "et minut",
+ mm : "%d minutter",
+ h : "en time",
+ hh : "%d timer",
+ d : "en dag",
+ dd : "%d dage",
+ M : "en måned",
+ MM : "%d måneder",
+ y : "et år",
+ yy : "%d år"
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- if (this.closeDiv === undefined) {
- this.closeDiv = document.createElement('div');
- this.closeDiv.className = 'network-manipulation-closeDiv';
- this.closeDiv.id = 'network-manipulation-closeDiv';
- this.closeDiv.style.display = this.manipulationDiv.style.display;
- this.containerElement.insertBefore(this.closeDiv, this.frame);
- }
- // load the manipulation functions
- this._loadMixin(ManipulationMixin);
+/***/ },
+/* 57 */
+/***/ function(module, exports, __webpack_require__) {
- // create the manipulator toolbar
- this._createManipulatorBar();
- }
- else {
- if (this.manipulationDiv !== undefined) {
- // removes all the bindings and overloads
- this._createManipulatorBar();
- // remove the manipulation divs
- this.containerElement.removeChild(this.manipulationDiv);
- this.containerElement.removeChild(this.editModeDiv);
- this.containerElement.removeChild(this.closeDiv);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : austrian german (de-at)
+ // author : lluchs : https://github.com/lluchs
+ // author: Menelion Elensúle: https://github.com/Oire
+ // author : Martin Groller : https://github.com/MadMG
- this.manipulationDiv = undefined;
- this.editModeDiv = undefined;
- this.closeDiv = undefined;
- // remove the mixin functions
- this._clearMixin(ManipulationMixin);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 'm': ['eine Minute', 'einer Minute'],
+ 'h': ['eine Stunde', 'einer Stunde'],
+ 'd': ['ein Tag', 'einem Tag'],
+ 'dd': [number + ' Tage', number + ' Tagen'],
+ 'M': ['ein Monat', 'einem Monat'],
+ 'MM': [number + ' Monate', number + ' Monaten'],
+ 'y': ['ein Jahr', 'einem Jahr'],
+ 'yy': [number + ' Jahre', number + ' Jahren']
+ };
+ return withoutSuffix ? format[key][0] : format[key][1];
}
- }
- };
-
-
- /**
- * Mixin the navigation (User Interface) system and initialize the parameters required
- *
- * @private
- */
- exports._loadNavigationControls = function () {
- this._loadMixin(NavigationMixin);
-
- // the clean function removes the button divs, this is done to remove the bindings.
- this._cleanNavigation();
- if (this.constants.navigation.enabled == true) {
- this._loadNavigationElements();
- }
- };
-
- /**
- * Mixin the hierarchical layout system.
- *
- * @private
- */
- exports._loadHierarchySystem = function () {
- this._loadMixin(HierarchicalLayoutMixin);
- };
+ return moment.lang('de-at', {
+ months : "Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
+ monthsShort : "Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
+ weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),
+ weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),
+ weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"),
+ longDateFormat : {
+ LT: "HH:mm [Uhr]",
+ L : "DD.MM.YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd, D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[Heute um] LT",
+ sameElse: "L",
+ nextDay: '[Morgen um] LT',
+ nextWeek: 'dddd [um] LT',
+ lastDay: '[Gestern um] LT',
+ lastWeek: '[letzten] dddd [um] LT'
+ },
+ relativeTime : {
+ future : "in %s",
+ past : "vor %s",
+ s : "ein paar Sekunden",
+ m : processRelativeTime,
+ mm : "%d Minuten",
+ h : processRelativeTime,
+ hh : "%d Stunden",
+ d : processRelativeTime,
+ dd : processRelativeTime,
+ M : processRelativeTime,
+ MM : processRelativeTime,
+ y : processRelativeTime,
+ yy : processRelativeTime
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
/***/ },
-/* 46 */
+/* 58 */
/***/ function(module, exports, __webpack_require__) {
- var util = __webpack_require__(1);
- var RepulsionMixin = __webpack_require__(128);
- var HierarchialRepulsionMixin = __webpack_require__(129);
- var BarnesHutMixin = __webpack_require__(130);
-
- /**
- * Toggling barnes Hut calculation on and off.
- *
- * @private
- */
- exports._toggleBarnesHut = function () {
- this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled;
- this._loadSelectedForceSolver();
- this.moving = true;
- this.start();
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : german (de)
+ // author : lluchs : https://github.com/lluchs
+ // author: Menelion Elensúle: https://github.com/Oire
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 'm': ['eine Minute', 'einer Minute'],
+ 'h': ['eine Stunde', 'einer Stunde'],
+ 'd': ['ein Tag', 'einem Tag'],
+ 'dd': [number + ' Tage', number + ' Tagen'],
+ 'M': ['ein Monat', 'einem Monat'],
+ 'MM': [number + ' Monate', number + ' Monaten'],
+ 'y': ['ein Jahr', 'einem Jahr'],
+ 'yy': [number + ' Jahre', number + ' Jahren']
+ };
+ return withoutSuffix ? format[key][0] : format[key][1];
+ }
- /**
- * This loads the node force solver based on the barnes hut or repulsion algorithm
- *
- * @private
- */
- exports._loadSelectedForceSolver = function () {
- // this overloads the this._calculateNodeForces
- if (this.constants.physics.barnesHut.enabled == true) {
- this._clearMixin(RepulsionMixin);
- this._clearMixin(HierarchialRepulsionMixin);
+ return moment.lang('de', {
+ months : "Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
+ monthsShort : "Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
+ weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),
+ weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),
+ weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"),
+ longDateFormat : {
+ LT: "HH:mm [Uhr]",
+ L : "DD.MM.YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd, D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[Heute um] LT",
+ sameElse: "L",
+ nextDay: '[Morgen um] LT',
+ nextWeek: 'dddd [um] LT',
+ lastDay: '[Gestern um] LT',
+ lastWeek: '[letzten] dddd [um] LT'
+ },
+ relativeTime : {
+ future : "in %s",
+ past : "vor %s",
+ s : "ein paar Sekunden",
+ m : processRelativeTime,
+ mm : "%d Minuten",
+ h : processRelativeTime,
+ hh : "%d Stunden",
+ d : processRelativeTime,
+ dd : processRelativeTime,
+ M : processRelativeTime,
+ MM : processRelativeTime,
+ y : processRelativeTime,
+ yy : processRelativeTime
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- this.constants.physics.centralGravity = this.constants.physics.barnesHut.centralGravity;
- this.constants.physics.springLength = this.constants.physics.barnesHut.springLength;
- this.constants.physics.springConstant = this.constants.physics.barnesHut.springConstant;
- this.constants.physics.damping = this.constants.physics.barnesHut.damping;
- this._loadMixin(BarnesHutMixin);
- }
- else if (this.constants.physics.hierarchicalRepulsion.enabled == true) {
- this._clearMixin(BarnesHutMixin);
- this._clearMixin(RepulsionMixin);
+/***/ },
+/* 59 */
+/***/ function(module, exports, __webpack_require__) {
- this.constants.physics.centralGravity = this.constants.physics.hierarchicalRepulsion.centralGravity;
- this.constants.physics.springLength = this.constants.physics.hierarchicalRepulsion.springLength;
- this.constants.physics.springConstant = this.constants.physics.hierarchicalRepulsion.springConstant;
- this.constants.physics.damping = this.constants.physics.hierarchicalRepulsion.damping;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : modern greek (el)
+ // author : Aggelos Karalias : https://github.com/mehiel
- this._loadMixin(HierarchialRepulsionMixin);
- }
- else {
- this._clearMixin(BarnesHutMixin);
- this._clearMixin(HierarchialRepulsionMixin);
- this.barnesHutTree = undefined;
-
- this.constants.physics.centralGravity = this.constants.physics.repulsion.centralGravity;
- this.constants.physics.springLength = this.constants.physics.repulsion.springLength;
- this.constants.physics.springConstant = this.constants.physics.repulsion.springConstant;
- this.constants.physics.damping = this.constants.physics.repulsion.damping;
-
- this._loadMixin(RepulsionMixin);
- }
- };
-
- /**
- * Before calculating the forces, we check if we need to cluster to keep up performance and we check
- * if there is more than one node. If it is just one node, we dont calculate anything.
- *
- * @private
- */
- exports._initializeForceCalculation = function () {
- // stop calculation if there is only one node
- if (this.nodeIndices.length == 1) {
- this.nodes[this.nodeIndices[0]]._setForce(0, 0);
- }
- else {
- // if there are too many nodes on screen, we cluster without repositioning
- if (this.nodeIndices.length > this.constants.clustering.clusterThreshold && this.constants.clustering.enabled == true) {
- this.clusterToFit(this.constants.clustering.reduceToNodes, false);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ return moment.lang('el', {
+ monthsNominativeEl : "Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),
+ monthsGenitiveEl : "Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),
+ months : function (momentToFormat, format) {
+ if (/D/.test(format.substring(0, format.indexOf("MMMM")))) { // if there is a day number before 'MMMM'
+ return this._monthsGenitiveEl[momentToFormat.month()];
+ } else {
+ return this._monthsNominativeEl[momentToFormat.month()];
+ }
+ },
+ monthsShort : "Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),
+ weekdays : "Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),
+ weekdaysShort : "Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),
+ weekdaysMin : "Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),
+ meridiem : function (hours, minutes, isLower) {
+ if (hours > 11) {
+ return isLower ? 'μμ' : 'ΜΜ';
+ } else {
+ return isLower ? 'πμ' : 'ΠΜ';
+ }
+ },
+ longDateFormat : {
+ LT : "h:mm A",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendarEl : {
+ sameDay : '[Σήμερα {}] LT',
+ nextDay : '[Αύριο {}] LT',
+ nextWeek : 'dddd [{}] LT',
+ lastDay : '[Χθες {}] LT',
+ lastWeek : function() {
+ switch (this.day()) {
+ case 6:
+ return '[το προηγούμενο] dddd [{}] LT';
+ default:
+ return '[την προηγούμενη] dddd [{}] LT';
+ }
+ },
+ sameElse : 'L'
+ },
+ calendar : function (key, mom) {
+ var output = this._calendarEl[key],
+ hours = mom && mom.hours();
- // we now start the force calculation
- this._calculateForces();
- }
- };
-
-
- /**
- * Calculate the external forces acting on the nodes
- * Forces are caused by: edges, repulsing forces between nodes, gravity
- * @private
- */
- exports._calculateForces = function () {
- // Gravity is required to keep separated groups from floating off
- // the forces are reset to zero in this loop by using _setForce instead
- // of _addForce
+ if (typeof output === 'function') {
+ output = output.apply(mom);
+ }
- this._calculateGravitationalForces();
- this._calculateNodeForces();
+ return output.replace("{}", (hours % 12 === 1 ? "στη" : "στις"));
+ },
+ relativeTime : {
+ future : "σε %s",
+ past : "%s πριν",
+ s : "δευτερόλεπτα",
+ m : "ένα λεπτό",
+ mm : "%d λεπτά",
+ h : "μία ώρα",
+ hh : "%d ώρες",
+ d : "μία μέρα",
+ dd : "%d μέρες",
+ M : "ένας μήνας",
+ MM : "%d μήνες",
+ y : "ένας χρόνος",
+ yy : "%d χρόνια"
+ },
+ ordinal : function (number) {
+ return number + 'η';
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4st is the first week of the year.
+ }
+ });
+ }));
- if (this.constants.physics.springConstant > 0) {
- if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) {
- this._calculateSpringForcesWithSupport();
- }
- else {
- if (this.constants.physics.hierarchicalRepulsion.enabled == true) {
- this._calculateHierarchicalSpringForces();
- }
- else {
- this._calculateSpringForces();
- }
- }
- }
- };
+/***/ },
+/* 60 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * Smooth curves are created by adding invisible nodes in the center of the edges. These nodes are also
- * handled in the calculateForces function. We then use a quadratic curve with the center node as control.
- * This function joins the datanodes and invisible (called support) nodes into one object.
- * We do this so we do not contaminate this.nodes with the support nodes.
- *
- * @private
- */
- exports._updateCalculationNodes = function () {
- if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) {
- this.calculationNodes = {};
- this.calculationNodeIndices = [];
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : australian english (en-au)
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- this.calculationNodes[nodeId] = this.nodes[nodeId];
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- var supportNodes = this.sectors['support']['nodes'];
- for (var supportNodeId in supportNodes) {
- if (supportNodes.hasOwnProperty(supportNodeId)) {
- if (this.edges.hasOwnProperty(supportNodes[supportNodeId].parentEdgeId)) {
- this.calculationNodes[supportNodeId] = supportNodes[supportNodeId];
- }
- else {
- supportNodes[supportNodeId]._setForce(0, 0);
+ }(function (moment) {
+ return moment.lang('en-au', {
+ months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
+ monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
+ weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
+ weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+ weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+ longDateFormat : {
+ LT : "h:mm A",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Today at] LT',
+ nextDay : '[Tomorrow at] LT',
+ nextWeek : 'dddd [at] LT',
+ lastDay : '[Yesterday at] LT',
+ lastWeek : '[Last] dddd [at] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "in %s",
+ past : "%s ago",
+ s : "a few seconds",
+ m : "a minute",
+ mm : "%d minutes",
+ h : "an hour",
+ hh : "%d hours",
+ d : "a day",
+ dd : "%d days",
+ M : "a month",
+ MM : "%d months",
+ y : "a year",
+ yy : "%d years"
+ },
+ ordinal : function (number) {
+ var b = number % 10,
+ output = (~~ (number % 100 / 10) === 1) ? 'th' :
+ (b === 1) ? 'st' :
+ (b === 2) ? 'nd' :
+ (b === 3) ? 'rd' : 'th';
+ return number + output;
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
}
- }
- }
-
- for (var idx in this.calculationNodes) {
- if (this.calculationNodes.hasOwnProperty(idx)) {
- this.calculationNodeIndices.push(idx);
- }
- }
- }
- else {
- this.calculationNodes = this.nodes;
- this.calculationNodeIndices = this.nodeIndices;
- }
- };
+ });
+ }));
- /**
- * this function applies the central gravity effect to keep groups from floating off
- *
- * @private
- */
- exports._calculateGravitationalForces = function () {
- var dx, dy, distance, node, i;
- var nodes = this.calculationNodes;
- var gravity = this.constants.physics.centralGravity;
- var gravityForce = 0;
+/***/ },
+/* 61 */
+/***/ function(module, exports, __webpack_require__) {
- for (i = 0; i < this.calculationNodeIndices.length; i++) {
- node = nodes[this.calculationNodeIndices[i]];
- node.damping = this.constants.physics.damping; // possibly add function to alter damping properties of clusters.
- // gravity does not apply when we are in a pocket sector
- if (this._sector() == "default" && gravity != 0) {
- dx = -node.x;
- dy = -node.y;
- distance = Math.sqrt(dx * dx + dy * dy);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : canadian english (en-ca)
+ // author : Jonathan Abourbih : https://github.com/jonbca
- gravityForce = (distance == 0) ? 0 : (gravity / distance);
- node.fx = dx * gravityForce;
- node.fy = dy * gravityForce;
- }
- else {
- node.fx = 0;
- node.fy = 0;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- };
-
-
+ }(function (moment) {
+ return moment.lang('en-ca', {
+ months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
+ monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
+ weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
+ weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+ weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+ longDateFormat : {
+ LT : "h:mm A",
+ L : "YYYY-MM-DD",
+ LL : "D MMMM, YYYY",
+ LLL : "D MMMM, YYYY LT",
+ LLLL : "dddd, D MMMM, YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Today at] LT',
+ nextDay : '[Tomorrow at] LT',
+ nextWeek : 'dddd [at] LT',
+ lastDay : '[Yesterday at] LT',
+ lastWeek : '[Last] dddd [at] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "in %s",
+ past : "%s ago",
+ s : "a few seconds",
+ m : "a minute",
+ mm : "%d minutes",
+ h : "an hour",
+ hh : "%d hours",
+ d : "a day",
+ dd : "%d days",
+ M : "a month",
+ MM : "%d months",
+ y : "a year",
+ yy : "%d years"
+ },
+ ordinal : function (number) {
+ var b = number % 10,
+ output = (~~ (number % 100 / 10) === 1) ? 'th' :
+ (b === 1) ? 'st' :
+ (b === 2) ? 'nd' :
+ (b === 3) ? 'rd' : 'th';
+ return number + output;
+ }
+ });
+ }));
- /**
- * this function calculates the effects of the springs in the case of unsmooth curves.
- *
- * @private
- */
- exports._calculateSpringForces = function () {
- var edgeLength, edge, edgeId;
- var dx, dy, fx, fy, springForce, distance;
- var edges = this.edges;
+/***/ },
+/* 62 */
+/***/ function(module, exports, __webpack_require__) {
- // forces caused by the edges, modelled as springs
- for (edgeId in edges) {
- if (edges.hasOwnProperty(edgeId)) {
- edge = edges[edgeId];
- if (edge.connected) {
- // only calculate forces if nodes are in the same sector
- if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
- edgeLength = edge.customLength ? edge.length : this.constants.physics.springLength;
- // this implies that the edges between big clusters are longer
- edgeLength += (edge.to.clusterSize + edge.from.clusterSize - 2) * this.constants.clustering.edgeGrowth;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : great britain english (en-gb)
+ // author : Chris Gedrim : https://github.com/chrisgedrim
- dx = (edge.from.x - edge.to.x);
- dy = (edge.from.y - edge.to.y);
- distance = Math.sqrt(dx * dx + dy * dy);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('en-gb', {
+ months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
+ monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
+ weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
+ weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+ weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Today at] LT',
+ nextDay : '[Tomorrow at] LT',
+ nextWeek : 'dddd [at] LT',
+ lastDay : '[Yesterday at] LT',
+ lastWeek : '[Last] dddd [at] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "in %s",
+ past : "%s ago",
+ s : "a few seconds",
+ m : "a minute",
+ mm : "%d minutes",
+ h : "an hour",
+ hh : "%d hours",
+ d : "a day",
+ dd : "%d days",
+ M : "a month",
+ MM : "%d months",
+ y : "a year",
+ yy : "%d years"
+ },
+ ordinal : function (number) {
+ var b = number % 10,
+ output = (~~ (number % 100 / 10) === 1) ? 'th' :
+ (b === 1) ? 'st' :
+ (b === 2) ? 'nd' :
+ (b === 3) ? 'rd' : 'th';
+ return number + output;
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- if (distance == 0) {
- distance = 0.01;
- }
- // the 1/distance is so the fx and fy can be calculated without sine or cosine.
- springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
+/***/ },
+/* 63 */
+/***/ function(module, exports, __webpack_require__) {
- fx = dx * springForce;
- fy = dy * springForce;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : esperanto (eo)
+ // author : Colin Dean : https://github.com/colindean
+ // komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko.
+ // Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!
- edge.from.fx += fx;
- edge.from.fy += fy;
- edge.to.fx -= fx;
- edge.to.fy -= fy;
- }
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- };
+ }(function (moment) {
+ return moment.lang('eo', {
+ months : "januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"),
+ monthsShort : "jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec".split("_"),
+ weekdays : "Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato".split("_"),
+ weekdaysShort : "Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab".split("_"),
+ weekdaysMin : "Di_Lu_Ma_Me_Ĵa_Ve_Sa".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "YYYY-MM-DD",
+ LL : "D[-an de] MMMM, YYYY",
+ LLL : "D[-an de] MMMM, YYYY LT",
+ LLLL : "dddd, [la] D[-an de] MMMM, YYYY LT"
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours > 11) {
+ return isLower ? 'p.t.m.' : 'P.T.M.';
+ } else {
+ return isLower ? 'a.t.m.' : 'A.T.M.';
+ }
+ },
+ calendar : {
+ sameDay : '[Hodiaŭ je] LT',
+ nextDay : '[Morgaŭ je] LT',
+ nextWeek : 'dddd [je] LT',
+ lastDay : '[Hieraŭ je] LT',
+ lastWeek : '[pasinta] dddd [je] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "je %s",
+ past : "antaŭ %s",
+ s : "sekundoj",
+ m : "minuto",
+ mm : "%d minutoj",
+ h : "horo",
+ hh : "%d horoj",
+ d : "tago",//ne 'diurno', ĉar estas uzita por proksimumo
+ dd : "%d tagoj",
+ M : "monato",
+ MM : "%d monatoj",
+ y : "jaro",
+ yy : "%d jaroj"
+ },
+ ordinal : "%da",
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
+/***/ },
+/* 64 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : spanish (es)
+ // author : Julio Napurí : https://github.com/julionc
- /**
- * This function calculates the springforces on the nodes, accounting for the support nodes.
- *
- * @private
- */
- exports._calculateSpringForcesWithSupport = function () {
- var edgeLength, edge, edgeId, combinedClusterSize;
- var edges = this.edges;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ var monthsShortDot = "ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),
+ monthsShort = "ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");
- // forces caused by the edges, modelled as springs
- for (edgeId in edges) {
- if (edges.hasOwnProperty(edgeId)) {
- edge = edges[edgeId];
- if (edge.connected) {
- // only calculate forces if nodes are in the same sector
- if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
- if (edge.via != null) {
- var node1 = edge.to;
- var node2 = edge.via;
- var node3 = edge.from;
+ return moment.lang('es', {
+ months : "enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),
+ monthsShort : function (m, format) {
+ if (/-MMM-/.test(format)) {
+ return monthsShort[m.month()];
+ } else {
+ return monthsShortDot[m.month()];
+ }
+ },
+ weekdays : "domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),
+ weekdaysShort : "dom._lun._mar._mié._jue._vie._sáb.".split("_"),
+ weekdaysMin : "Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD/MM/YYYY",
+ LL : "D [de] MMMM [del] YYYY",
+ LLL : "D [de] MMMM [del] YYYY LT",
+ LLLL : "dddd, D [de] MMMM [del] YYYY LT"
+ },
+ calendar : {
+ sameDay : function () {
+ return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+ },
+ nextDay : function () {
+ return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+ },
+ nextWeek : function () {
+ return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+ },
+ lastDay : function () {
+ return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+ },
+ lastWeek : function () {
+ return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "en %s",
+ past : "hace %s",
+ s : "unos segundos",
+ m : "un minuto",
+ mm : "%d minutos",
+ h : "una hora",
+ hh : "%d horas",
+ d : "un día",
+ dd : "%d días",
+ M : "un mes",
+ MM : "%d meses",
+ y : "un año",
+ yy : "%d años"
+ },
+ ordinal : '%dº',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- edgeLength = edge.customLength ? edge.length : this.constants.physics.springLength;
- combinedClusterSize = node1.clusterSize + node3.clusterSize - 2;
+/***/ },
+/* 65 */
+/***/ function(module, exports, __webpack_require__) {
- // this implies that the edges between big clusters are longer
- edgeLength += combinedClusterSize * this.constants.clustering.edgeGrowth;
- this._calculateSpringForce(node1, node2, 0.5 * edgeLength);
- this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : estonian (et)
+ // author : Henry Kehlmann : https://github.com/madhenry
+ // improvements : Illimar Tambek : https://github.com/ragulka
+
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
+ 'm' : ['ühe minuti', 'üks minut'],
+ 'mm': [number + ' minuti', number + ' minutit'],
+ 'h' : ['ühe tunni', 'tund aega', 'üks tund'],
+ 'hh': [number + ' tunni', number + ' tundi'],
+ 'd' : ['ühe päeva', 'üks päev'],
+ 'M' : ['kuu aja', 'kuu aega', 'üks kuu'],
+ 'MM': [number + ' kuu', number + ' kuud'],
+ 'y' : ['ühe aasta', 'aasta', 'üks aasta'],
+ 'yy': [number + ' aasta', number + ' aastat']
+ };
+ if (withoutSuffix) {
+ return format[key][2] ? format[key][2] : format[key][1];
}
- }
+ return isFuture ? format[key][0] : format[key][1];
}
- }
- };
+ return moment.lang('et', {
+ months : "jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),
+ monthsShort : "jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),
+ weekdays : "pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"),
+ weekdaysShort : "P_E_T_K_N_R_L".split("_"),
+ weekdaysMin : "P_E_T_K_N_R_L".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD.MM.YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd, D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Täna,] LT',
+ nextDay : '[Homme,] LT',
+ nextWeek : '[Järgmine] dddd LT',
+ lastDay : '[Eile,] LT',
+ lastWeek : '[Eelmine] dddd LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s pärast",
+ past : "%s tagasi",
+ s : processRelativeTime,
+ m : processRelativeTime,
+ mm : processRelativeTime,
+ h : processRelativeTime,
+ hh : processRelativeTime,
+ d : processRelativeTime,
+ dd : '%d päeva',
+ M : processRelativeTime,
+ MM : processRelativeTime,
+ y : processRelativeTime,
+ yy : processRelativeTime
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * This is the code actually performing the calculation for the function above. It is split out to avoid repetition.
- *
- * @param node1
- * @param node2
- * @param edgeLength
- * @private
- */
- exports._calculateSpringForce = function (node1, node2, edgeLength) {
- var dx, dy, fx, fy, springForce, distance;
- dx = (node1.x - node2.x);
- dy = (node1.y - node2.y);
- distance = Math.sqrt(dx * dx + dy * dy);
+/***/ },
+/* 66 */
+/***/ function(module, exports, __webpack_require__) {
- if (distance == 0) {
- distance = 0.01;
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : euskara (eu)
+ // author : Eneko Illarramendi : https://github.com/eillarra
- // the 1/distance is so the fx and fy can be calculated without sine or cosine.
- springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('eu', {
+ months : "urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),
+ monthsShort : "urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),
+ weekdays : "igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),
+ weekdaysShort : "ig._al._ar._az._og._ol._lr.".split("_"),
+ weekdaysMin : "ig_al_ar_az_og_ol_lr".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "YYYY-MM-DD",
+ LL : "YYYY[ko] MMMM[ren] D[a]",
+ LLL : "YYYY[ko] MMMM[ren] D[a] LT",
+ LLLL : "dddd, YYYY[ko] MMMM[ren] D[a] LT",
+ l : "YYYY-M-D",
+ ll : "YYYY[ko] MMM D[a]",
+ lll : "YYYY[ko] MMM D[a] LT",
+ llll : "ddd, YYYY[ko] MMM D[a] LT"
+ },
+ calendar : {
+ sameDay : '[gaur] LT[etan]',
+ nextDay : '[bihar] LT[etan]',
+ nextWeek : 'dddd LT[etan]',
+ lastDay : '[atzo] LT[etan]',
+ lastWeek : '[aurreko] dddd LT[etan]',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s barru",
+ past : "duela %s",
+ s : "segundo batzuk",
+ m : "minutu bat",
+ mm : "%d minutu",
+ h : "ordu bat",
+ hh : "%d ordu",
+ d : "egun bat",
+ dd : "%d egun",
+ M : "hilabete bat",
+ MM : "%d hilabete",
+ y : "urte bat",
+ yy : "%d urte"
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- fx = dx * springForce;
- fy = dy * springForce;
- node1.fx += fx;
- node1.fy += fy;
- node2.fx -= fx;
- node2.fy -= fy;
- };
+/***/ },
+/* 67 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Persian Language
+ // author : Ebrahim Byagowi : https://github.com/ebraminio
- /**
- * Load the HTML for the physics config and bind it
- * @private
- */
- exports._loadPhysicsConfiguration = function () {
- if (this.physicsConfiguration === undefined) {
- this.backupConstants = {};
- util.deepExtend(this.backupConstants,this.constants);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ var symbolMap = {
+ '1': '۱',
+ '2': '۲',
+ '3': '۳',
+ '4': '۴',
+ '5': '۵',
+ '6': '۶',
+ '7': '۷',
+ '8': '۸',
+ '9': '۹',
+ '0': '۰'
+ }, numberMap = {
+ '۱': '1',
+ '۲': '2',
+ '۳': '3',
+ '۴': '4',
+ '۵': '5',
+ '۶': '6',
+ '۷': '7',
+ '۸': '8',
+ '۹': '9',
+ '۰': '0'
+ };
- var hierarchicalLayoutDirections = ["LR", "RL", "UD", "DU"];
- this.physicsConfiguration = document.createElement('div');
- this.physicsConfiguration.className = "PhysicsConfiguration";
- this.physicsConfiguration.innerHTML = '' +
- '
' +
- '' +
- '' +
- '' +
- ''
- this.containerElement.parentElement.insertBefore(this.physicsConfiguration, this.containerElement);
- this.optionsDiv = document.createElement("div");
- this.optionsDiv.style.fontSize = "14px";
- this.optionsDiv.style.fontFamily = "verdana";
- this.containerElement.parentElement.insertBefore(this.optionsDiv, this.containerElement);
+ return moment.lang('fa', {
+ months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
+ monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
+ weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
+ weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
+ weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
+ longDateFormat : {
+ LT : 'HH:mm',
+ L : 'DD/MM/YYYY',
+ LL : 'D MMMM YYYY',
+ LLL : 'D MMMM YYYY LT',
+ LLLL : 'dddd, D MMMM YYYY LT'
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 12) {
+ return "قبل از ظهر";
+ } else {
+ return "بعد از ظهر";
+ }
+ },
+ calendar : {
+ sameDay : '[امروز ساعت] LT',
+ nextDay : '[فردا ساعت] LT',
+ nextWeek : 'dddd [ساعت] LT',
+ lastDay : '[دیروز ساعت] LT',
+ lastWeek : 'dddd [پیش] [ساعت] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'در %s',
+ past : '%s پیش',
+ s : 'چندین ثانیه',
+ m : 'یک دقیقه',
+ mm : '%d دقیقه',
+ h : 'یک ساعت',
+ hh : '%d ساعت',
+ d : 'یک روز',
+ dd : '%d روز',
+ M : 'یک ماه',
+ MM : '%d ماه',
+ y : 'یک سال',
+ yy : '%d سال'
+ },
+ preparse: function (string) {
+ return string.replace(/[۰-۹]/g, function (match) {
+ return numberMap[match];
+ }).replace(/،/g, ',');
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ }).replace(/,/g, '،');
+ },
+ ordinal : '%dم',
+ week : {
+ dow : 6, // Saturday is the first day of the week.
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- var rangeElement;
- rangeElement = document.getElementById('graph_BH_gc');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_gc', -1, "physics_barnesHut_gravitationalConstant");
- rangeElement = document.getElementById('graph_BH_cg');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_cg', 1, "physics_centralGravity");
- rangeElement = document.getElementById('graph_BH_sc');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_sc', 1, "physics_springConstant");
- rangeElement = document.getElementById('graph_BH_sl');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_sl', 1, "physics_springLength");
- rangeElement = document.getElementById('graph_BH_damp');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_damp', 1, "physics_damping");
- rangeElement = document.getElementById('graph_R_nd');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_nd', 1, "physics_repulsion_nodeDistance");
- rangeElement = document.getElementById('graph_R_cg');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_cg', 1, "physics_centralGravity");
- rangeElement = document.getElementById('graph_R_sc');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_sc', 1, "physics_springConstant");
- rangeElement = document.getElementById('graph_R_sl');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_sl', 1, "physics_springLength");
- rangeElement = document.getElementById('graph_R_damp');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_damp', 1, "physics_damping");
+/***/ },
+/* 68 */
+/***/ function(module, exports, __webpack_require__) {
- rangeElement = document.getElementById('graph_H_nd');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_nd', 1, "physics_hierarchicalRepulsion_nodeDistance");
- rangeElement = document.getElementById('graph_H_cg');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_cg', 1, "physics_centralGravity");
- rangeElement = document.getElementById('graph_H_sc');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_sc', 1, "physics_springConstant");
- rangeElement = document.getElementById('graph_H_sl');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_sl', 1, "physics_springLength");
- rangeElement = document.getElementById('graph_H_damp');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_damp', 1, "physics_damping");
- rangeElement = document.getElementById('graph_H_direction');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_direction', hierarchicalLayoutDirections, "hierarchicalLayout_direction");
- rangeElement = document.getElementById('graph_H_levsep');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_levsep', 1, "hierarchicalLayout_levelSeparation");
- rangeElement = document.getElementById('graph_H_nspac');
- rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_nspac', 1, "hierarchicalLayout_nodeSpacing");
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : finnish (fi)
+ // author : Tarmo Aidantausta : https://github.com/bleadof
- var radioButton1 = document.getElementById("graph_physicsMethod1");
- var radioButton2 = document.getElementById("graph_physicsMethod2");
- var radioButton3 = document.getElementById("graph_physicsMethod3");
- radioButton2.checked = true;
- if (this.constants.physics.barnesHut.enabled) {
- radioButton1.checked = true;
- }
- if (this.constants.hierarchicalLayout.enabled) {
- radioButton3.checked = true;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),
+ numbersFuture = ['nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
+ numbersPast[7], numbersPast[8], numbersPast[9]];
- var graph_toggleSmooth = document.getElementById("graph_toggleSmooth");
- var graph_repositionNodes = document.getElementById("graph_repositionNodes");
- var graph_generateOptions = document.getElementById("graph_generateOptions");
-
- graph_toggleSmooth.onclick = graphToggleSmoothCurves.bind(this);
- graph_repositionNodes.onclick = graphRepositionNodes.bind(this);
- graph_generateOptions.onclick = graphGenerateOptions.bind(this);
- if (this.constants.smoothCurves == true && this.constants.dynamicSmoothCurves == false) {
- graph_toggleSmooth.style.background = "#A4FF56";
- }
- else {
- graph_toggleSmooth.style.background = "#FF8532";
+ function translate(number, withoutSuffix, key, isFuture) {
+ var result = "";
+ switch (key) {
+ case 's':
+ return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
+ case 'm':
+ return isFuture ? 'minuutin' : 'minuutti';
+ case 'mm':
+ result = isFuture ? 'minuutin' : 'minuuttia';
+ break;
+ case 'h':
+ return isFuture ? 'tunnin' : 'tunti';
+ case 'hh':
+ result = isFuture ? 'tunnin' : 'tuntia';
+ break;
+ case 'd':
+ return isFuture ? 'päivän' : 'päivä';
+ case 'dd':
+ result = isFuture ? 'päivän' : 'päivää';
+ break;
+ case 'M':
+ return isFuture ? 'kuukauden' : 'kuukausi';
+ case 'MM':
+ result = isFuture ? 'kuukauden' : 'kuukautta';
+ break;
+ case 'y':
+ return isFuture ? 'vuoden' : 'vuosi';
+ case 'yy':
+ result = isFuture ? 'vuoden' : 'vuotta';
+ break;
+ }
+ result = verbalNumber(number, isFuture) + " " + result;
+ return result;
}
+ function verbalNumber(number, isFuture) {
+ return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;
+ }
- switchConfigurations.apply(this);
-
- radioButton1.onchange = switchConfigurations.bind(this);
- radioButton2.onchange = switchConfigurations.bind(this);
- radioButton3.onchange = switchConfigurations.bind(this);
- }
- };
-
- /**
- * This overwrites the this.constants.
- *
- * @param constantsVariableName
- * @param value
- * @private
- */
- exports._overWriteGraphConstants = function (constantsVariableName, value) {
- var nameArray = constantsVariableName.split("_");
- if (nameArray.length == 1) {
- this.constants[nameArray[0]] = value;
- }
- else if (nameArray.length == 2) {
- this.constants[nameArray[0]][nameArray[1]] = value;
- }
- else if (nameArray.length == 3) {
- this.constants[nameArray[0]][nameArray[1]][nameArray[2]] = value;
- }
- };
-
+ return moment.lang('fi', {
+ months : "tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),
+ monthsShort : "tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),
+ weekdays : "sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),
+ weekdaysShort : "su_ma_ti_ke_to_pe_la".split("_"),
+ weekdaysMin : "su_ma_ti_ke_to_pe_la".split("_"),
+ longDateFormat : {
+ LT : "HH.mm",
+ L : "DD.MM.YYYY",
+ LL : "Do MMMM[ta] YYYY",
+ LLL : "Do MMMM[ta] YYYY, [klo] LT",
+ LLLL : "dddd, Do MMMM[ta] YYYY, [klo] LT",
+ l : "D.M.YYYY",
+ ll : "Do MMM YYYY",
+ lll : "Do MMM YYYY, [klo] LT",
+ llll : "ddd, Do MMM YYYY, [klo] LT"
+ },
+ calendar : {
+ sameDay : '[tänään] [klo] LT',
+ nextDay : '[huomenna] [klo] LT',
+ nextWeek : 'dddd [klo] LT',
+ lastDay : '[eilen] [klo] LT',
+ lastWeek : '[viime] dddd[na] [klo] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s päästä",
+ past : "%s sitten",
+ s : translate,
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : translate,
+ dd : translate,
+ M : translate,
+ MM : translate,
+ y : translate,
+ yy : translate
+ },
+ ordinal : "%d.",
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * this function is bound to the toggle smooth curves button. That is also why it is not in the prototype.
- */
- function graphToggleSmoothCurves () {
- this.constants.smoothCurves.enabled = !this.constants.smoothCurves.enabled;
- var graph_toggleSmooth = document.getElementById("graph_toggleSmooth");
- if (this.constants.smoothCurves.enabled == true) {graph_toggleSmooth.style.background = "#A4FF56";}
- else {graph_toggleSmooth.style.background = "#FF8532";}
- this._configureSmoothCurves(false);
- }
+/***/ },
+/* 69 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * this function is used to scramble the nodes
- *
- */
- function graphRepositionNodes () {
- for (var nodeId in this.calculationNodes) {
- if (this.calculationNodes.hasOwnProperty(nodeId)) {
- this.calculationNodes[nodeId].vx = 0; this.calculationNodes[nodeId].vy = 0;
- this.calculationNodes[nodeId].fx = 0; this.calculationNodes[nodeId].fy = 0;
- }
- }
- if (this.constants.hierarchicalLayout.enabled == true) {
- this._setupHierarchicalLayout();
- }
- else {
- this.repositionNodes();
- }
- this.moving = true;
- this.start();
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : faroese (fo)
+ // author : Ragnar Johannesen : https://github.com/ragnar123
- /**
- * this is used to generate an options file from the playing with physics system.
- */
- function graphGenerateOptions () {
- var options = "No options are required, default values used.";
- var optionsSpecific = [];
- var radioButton1 = document.getElementById("graph_physicsMethod1");
- var radioButton2 = document.getElementById("graph_physicsMethod2");
- if (radioButton1.checked == true) {
- if (this.constants.physics.barnesHut.gravitationalConstant != this.backupConstants.physics.barnesHut.gravitationalConstant) {optionsSpecific.push("gravitationalConstant: " + this.constants.physics.barnesHut.gravitationalConstant);}
- if (this.constants.physics.centralGravity != this.backupConstants.physics.barnesHut.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
- if (this.constants.physics.springLength != this.backupConstants.physics.barnesHut.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);}
- if (this.constants.physics.springConstant != this.backupConstants.physics.barnesHut.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
- if (this.constants.physics.damping != this.backupConstants.physics.barnesHut.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
- if (optionsSpecific.length != 0) {
- options = "var options = {";
- options += "physics: {barnesHut: {";
- for (var i = 0; i < optionsSpecific.length; i++) {
- options += optionsSpecific[i];
- if (i < optionsSpecific.length - 1) {
- options += ", "
- }
- }
- options += '}}'
- }
- if (this.constants.smoothCurves.enabled != this.backupConstants.smoothCurves.enabled) {
- if (optionsSpecific.length == 0) {options = "var options = {";}
- else {options += ", "}
- options += "smoothCurves: " + this.constants.smoothCurves.enabled;
- }
- if (options != "No options are required, default values used.") {
- options += '};'
- }
- }
- else if (radioButton2.checked == true) {
- options = "var options = {";
- options += "physics: {barnesHut: {enabled: false}";
- if (this.constants.physics.repulsion.nodeDistance != this.backupConstants.physics.repulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.repulsion.nodeDistance);}
- if (this.constants.physics.centralGravity != this.backupConstants.physics.repulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
- if (this.constants.physics.springLength != this.backupConstants.physics.repulsion.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);}
- if (this.constants.physics.springConstant != this.backupConstants.physics.repulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
- if (this.constants.physics.damping != this.backupConstants.physics.repulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
- if (optionsSpecific.length != 0) {
- options += ", repulsion: {";
- for (var i = 0; i < optionsSpecific.length; i++) {
- options += optionsSpecific[i];
- if (i < optionsSpecific.length - 1) {
- options += ", "
- }
- }
- options += '}}'
- }
- if (optionsSpecific.length == 0) {options += "}"}
- if (this.constants.smoothCurves != this.backupConstants.smoothCurves) {
- options += ", smoothCurves: " + this.constants.smoothCurves;
- }
- options += '};'
- }
- else {
- options = "var options = {";
- if (this.constants.physics.hierarchicalRepulsion.nodeDistance != this.backupConstants.physics.hierarchicalRepulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.hierarchicalRepulsion.nodeDistance);}
- if (this.constants.physics.centralGravity != this.backupConstants.physics.hierarchicalRepulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
- if (this.constants.physics.springLength != this.backupConstants.physics.hierarchicalRepulsion.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);}
- if (this.constants.physics.springConstant != this.backupConstants.physics.hierarchicalRepulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
- if (this.constants.physics.damping != this.backupConstants.physics.hierarchicalRepulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
- if (optionsSpecific.length != 0) {
- options += "physics: {hierarchicalRepulsion: {";
- for (var i = 0; i < optionsSpecific.length; i++) {
- options += optionsSpecific[i];
- if (i < optionsSpecific.length - 1) {
- options += ", ";
- }
- }
- options += '}},';
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- options += 'hierarchicalLayout: {';
- optionsSpecific = [];
- if (this.constants.hierarchicalLayout.direction != this.backupConstants.hierarchicalLayout.direction) {optionsSpecific.push("direction: " + this.constants.hierarchicalLayout.direction);}
- if (Math.abs(this.constants.hierarchicalLayout.levelSeparation) != this.backupConstants.hierarchicalLayout.levelSeparation) {optionsSpecific.push("levelSeparation: " + this.constants.hierarchicalLayout.levelSeparation);}
- if (this.constants.hierarchicalLayout.nodeSpacing != this.backupConstants.hierarchicalLayout.nodeSpacing) {optionsSpecific.push("nodeSpacing: " + this.constants.hierarchicalLayout.nodeSpacing);}
- if (optionsSpecific.length != 0) {
- for (var i = 0; i < optionsSpecific.length; i++) {
- options += optionsSpecific[i];
- if (i < optionsSpecific.length - 1) {
- options += ", "
+ }(function (moment) {
+ return moment.lang('fo', {
+ months : "januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"),
+ monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),
+ weekdays : "sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"),
+ weekdaysShort : "sun_mán_týs_mik_hós_frí_ley".split("_"),
+ weekdaysMin : "su_má_tý_mi_hó_fr_le".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D. MMMM, YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Í dag kl.] LT',
+ nextDay : '[Í morgin kl.] LT',
+ nextWeek : 'dddd [kl.] LT',
+ lastDay : '[Í gjár kl.] LT',
+ lastWeek : '[síðstu] dddd [kl] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "um %s",
+ past : "%s síðani",
+ s : "fá sekund",
+ m : "ein minutt",
+ mm : "%d minuttir",
+ h : "ein tími",
+ hh : "%d tímar",
+ d : "ein dagur",
+ dd : "%d dagar",
+ M : "ein mánaði",
+ MM : "%d mánaðir",
+ y : "eitt ár",
+ yy : "%d ár"
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
}
- }
- options += '}'
- }
- else {
- options += "enabled:true}";
- }
- options += '};'
- }
+ });
+ }));
- this.optionsDiv.innerHTML = options;
- }
+/***/ },
+/* 70 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * this is used to switch between barnesHut, repulsion and hierarchical.
- *
- */
- function switchConfigurations () {
- var ids = ["graph_BH_table", "graph_R_table", "graph_H_table"];
- var radioButton = document.querySelector('input[name="graph_physicsMethod"]:checked').value;
- var tableId = "graph_" + radioButton + "_table";
- var table = document.getElementById(tableId);
- table.style.display = "block";
- for (var i = 0; i < ids.length; i++) {
- if (ids[i] != tableId) {
- table = document.getElementById(ids[i]);
- table.style.display = "none";
- }
- }
- this._restoreNodes();
- if (radioButton == "R") {
- this.constants.hierarchicalLayout.enabled = false;
- this.constants.physics.hierarchicalRepulsion.enabled = false;
- this.constants.physics.barnesHut.enabled = false;
- }
- else if (radioButton == "H") {
- if (this.constants.hierarchicalLayout.enabled == false) {
- this.constants.hierarchicalLayout.enabled = true;
- this.constants.physics.hierarchicalRepulsion.enabled = true;
- this.constants.physics.barnesHut.enabled = false;
- this.constants.smoothCurves.enabled = false;
- this._setupHierarchicalLayout();
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : canadian french (fr-ca)
+ // author : Jonathan Abourbih : https://github.com/jonbca
+
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- else {
- this.constants.hierarchicalLayout.enabled = false;
- this.constants.physics.hierarchicalRepulsion.enabled = false;
- this.constants.physics.barnesHut.enabled = true;
- }
- this._loadSelectedForceSolver();
- var graph_toggleSmooth = document.getElementById("graph_toggleSmooth");
- if (this.constants.smoothCurves.enabled == true) {graph_toggleSmooth.style.background = "#A4FF56";}
- else {graph_toggleSmooth.style.background = "#FF8532";}
- this.moving = true;
- this.start();
- }
+ }(function (moment) {
+ return moment.lang('fr-ca', {
+ months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
+ monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
+ weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
+ weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"),
+ weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "YYYY-MM-DD",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[Aujourd'hui à] LT",
+ nextDay: '[Demain à] LT',
+ nextWeek: 'dddd [à] LT',
+ lastDay: '[Hier à] LT',
+ lastWeek: 'dddd [dernier à] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "dans %s",
+ past : "il y a %s",
+ s : "quelques secondes",
+ m : "une minute",
+ mm : "%d minutes",
+ h : "une heure",
+ hh : "%d heures",
+ d : "un jour",
+ dd : "%d jours",
+ M : "un mois",
+ MM : "%d mois",
+ y : "un an",
+ yy : "%d ans"
+ },
+ ordinal : function (number) {
+ return number + (number === 1 ? 'er' : '');
+ }
+ });
+ }));
- /**
- * this generates the ranges depending on the iniital values.
- *
- * @param id
- * @param map
- * @param constantsVariableName
- */
- function showValueOfRange (id,map,constantsVariableName) {
- var valueId = id + "_value";
- var rangeValue = document.getElementById(id).value;
+/***/ },
+/* 71 */
+/***/ function(module, exports, __webpack_require__) {
- if (map instanceof Array) {
- document.getElementById(valueId).value = map[parseInt(rangeValue)];
- this._overWriteGraphConstants(constantsVariableName,map[parseInt(rangeValue)]);
- }
- else {
- document.getElementById(valueId).value = parseInt(map) * parseFloat(rangeValue);
- this._overWriteGraphConstants(constantsVariableName, parseInt(map) * parseFloat(rangeValue));
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : french (fr)
+ // author : John Fischer : https://github.com/jfroffice
- if (constantsVariableName == "hierarchicalLayout_direction" ||
- constantsVariableName == "hierarchicalLayout_levelSeparation" ||
- constantsVariableName == "hierarchicalLayout_nodeSpacing") {
- this._setupHierarchicalLayout();
- }
- this.moving = true;
- this.start();
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('fr', {
+ months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
+ monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
+ weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
+ weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"),
+ weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[Aujourd'hui à] LT",
+ nextDay: '[Demain à] LT',
+ nextWeek: 'dddd [à] LT',
+ lastDay: '[Hier à] LT',
+ lastWeek: 'dddd [dernier à] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "dans %s",
+ past : "il y a %s",
+ s : "quelques secondes",
+ m : "une minute",
+ mm : "%d minutes",
+ h : "une heure",
+ hh : "%d heures",
+ d : "un jour",
+ dd : "%d jours",
+ M : "un mois",
+ MM : "%d mois",
+ y : "un an",
+ yy : "%d ans"
+ },
+ ordinal : function (number) {
+ return number + (number === 1 ? 'er' : '');
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
/***/ },
-/* 47 */
+/* 72 */
/***/ function(module, exports, __webpack_require__) {
- /**
- * Creation of the ClusterMixin var.
- *
- * This contains all the functions the Network object can use to employ clustering
- */
-
- /**
- * This is only called in the constructor of the network object
- *
- */
- exports.startWithClustering = function() {
- // cluster if the data set is big
- this.clusterToFit(this.constants.clustering.initialMaxNodes, true);
-
- // updates the lables after clustering
- this.updateLabels();
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : galician (gl)
+ // author : Juan G. Hurtado : https://github.com/juanghurtado
- // this is called here because if clusterin is disabled, the start and stabilize are called in
- // the setData function.
- if (this.stabilize) {
- this._stabilize();
- }
- this.start();
- };
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('gl', {
+ months : "Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro".split("_"),
+ monthsShort : "Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"),
+ weekdays : "Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"),
+ weekdaysShort : "Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"),
+ weekdaysMin : "Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : function () {
+ return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
+ },
+ nextDay : function () {
+ return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
+ },
+ nextWeek : function () {
+ return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
+ },
+ lastDay : function () {
+ return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';
+ },
+ lastWeek : function () {
+ return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : function (str) {
+ if (str === "uns segundos") {
+ return "nuns segundos";
+ }
+ return "en " + str;
+ },
+ past : "hai %s",
+ s : "uns segundos",
+ m : "un minuto",
+ mm : "%d minutos",
+ h : "unha hora",
+ hh : "%d horas",
+ d : "un día",
+ dd : "%d días",
+ M : "un mes",
+ MM : "%d meses",
+ y : "un ano",
+ yy : "%d anos"
+ },
+ ordinal : '%dº',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * This function clusters until the initialMaxNodes has been reached
- *
- * @param {Number} maxNumberOfNodes
- * @param {Boolean} reposition
- */
- exports.clusterToFit = function(maxNumberOfNodes, reposition) {
- var numberOfNodes = this.nodeIndices.length;
- var maxLevels = 50;
- var level = 0;
+/***/ },
+/* 73 */
+/***/ function(module, exports, __webpack_require__) {
- // we first cluster the hubs, then we pull in the outliers, repeat
- while (numberOfNodes > maxNumberOfNodes && level < maxLevels) {
- if (level % 3 == 0) {
- this.forceAggregateHubs(true);
- this.normalizeClusterLevels();
- }
- else {
- this.increaseClusterLevel(); // this also includes a cluster normalization
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Hebrew (he)
+ // author : Tomer Cohen : https://github.com/tomer
+ // author : Moshe Simantov : https://github.com/DevelopmentIL
+ // author : Tal Ater : https://github.com/TalAter
+
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ return moment.lang('he', {
+ months : "ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),
+ monthsShort : "ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),
+ weekdays : "ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),
+ weekdaysShort : "א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),
+ weekdaysMin : "א_ב_ג_ד_ה_ו_ש".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D [ב]MMMM YYYY",
+ LLL : "D [ב]MMMM YYYY LT",
+ LLLL : "dddd, D [ב]MMMM YYYY LT",
+ l : "D/M/YYYY",
+ ll : "D MMM YYYY",
+ lll : "D MMM YYYY LT",
+ llll : "ddd, D MMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[היום ב־]LT',
+ nextDay : '[מחר ב־]LT',
+ nextWeek : 'dddd [בשעה] LT',
+ lastDay : '[אתמול ב־]LT',
+ lastWeek : '[ביום] dddd [האחרון בשעה] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "בעוד %s",
+ past : "לפני %s",
+ s : "מספר שניות",
+ m : "דקה",
+ mm : "%d דקות",
+ h : "שעה",
+ hh : function (number) {
+ if (number === 2) {
+ return "שעתיים";
+ }
+ return number + " שעות";
+ },
+ d : "יום",
+ dd : function (number) {
+ if (number === 2) {
+ return "יומיים";
+ }
+ return number + " ימים";
+ },
+ M : "חודש",
+ MM : function (number) {
+ if (number === 2) {
+ return "חודשיים";
+ }
+ return number + " חודשים";
+ },
+ y : "שנה",
+ yy : function (number) {
+ if (number === 2) {
+ return "שנתיים";
+ }
+ return number + " שנים";
+ }
+ }
+ });
+ }));
- numberOfNodes = this.nodeIndices.length;
- level += 1;
- }
- // after the clustering we reposition the nodes to reduce the initial chaos
- if (level > 0 && reposition == true) {
- this.repositionNodes();
- }
- this._updateCalculationNodes();
- };
+/***/ },
+/* 74 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This function can be called to open up a specific cluster. It is only called by
- * It will unpack the cluster back one level.
- *
- * @param node | Node object: cluster to open.
- */
- exports.openCluster = function(node) {
- var isMovingBeforeClustering = this.moving;
- if (node.clusterSize > this.constants.clustering.sectorThreshold && this._nodeInActiveArea(node) &&
- !(this._sector() == "default" && this.nodeIndices.length == 1)) {
- // this loads a new sector, loads the nodes and edges and nodeIndices of it.
- this._addSector(node);
- var level = 0;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : hindi (hi)
+ // author : Mayank Singhal : https://github.com/mayanksinghal
- // we decluster until we reach a decent number of nodes
- while ((this.nodeIndices.length < this.constants.clustering.initialMaxNodes) && (level < 10)) {
- this.decreaseClusterLevel();
- level += 1;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ var symbolMap = {
+ '1': '१',
+ '2': '२',
+ '3': '३',
+ '4': '४',
+ '5': '५',
+ '6': '६',
+ '7': '७',
+ '8': '८',
+ '9': '९',
+ '0': '०'
+ },
+ numberMap = {
+ '१': '1',
+ '२': '2',
+ '३': '3',
+ '४': '4',
+ '५': '5',
+ '६': '6',
+ '७': '7',
+ '८': '8',
+ '९': '9',
+ '०': '0'
+ };
- }
- else {
- this._expandClusterNode(node,false,true);
+ return moment.lang('hi', {
+ months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split("_"),
+ monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split("_"),
+ weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"),
+ weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split("_"),
+ weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"),
+ longDateFormat : {
+ LT : "A h:mm बजे",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY, LT",
+ LLLL : "dddd, D MMMM YYYY, LT"
+ },
+ calendar : {
+ sameDay : '[आज] LT',
+ nextDay : '[कल] LT',
+ nextWeek : 'dddd, LT',
+ lastDay : '[कल] LT',
+ lastWeek : '[पिछले] dddd, LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s में",
+ past : "%s पहले",
+ s : "कुछ ही क्षण",
+ m : "एक मिनट",
+ mm : "%d मिनट",
+ h : "एक घंटा",
+ hh : "%d घंटे",
+ d : "एक दिन",
+ dd : "%d दिन",
+ M : "एक महीने",
+ MM : "%d महीने",
+ y : "एक वर्ष",
+ yy : "%d वर्ष"
+ },
+ preparse: function (string) {
+ return string.replace(/[१२३४५६७८९०]/g, function (match) {
+ return numberMap[match];
+ });
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ });
+ },
+ // Hindi notation for meridiems are quite fuzzy in practice. While there exists
+ // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 4) {
+ return "रात";
+ } else if (hour < 10) {
+ return "सुबह";
+ } else if (hour < 17) {
+ return "दोपहर";
+ } else if (hour < 20) {
+ return "शाम";
+ } else {
+ return "रात";
+ }
+ },
+ week : {
+ dow : 0, // Sunday is the first day of the week.
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- // update the index list, dynamic edges and labels
- this._updateNodeIndexList();
- this._updateDynamicEdges();
- this._updateCalculationNodes();
- this.updateLabels();
- }
- // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
- if (this.moving != isMovingBeforeClustering) {
- this.start();
- }
- };
+/***/ },
+/* 75 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : hrvatski (hr)
+ // author : Bojan Marković : https://github.com/bmarkovic
- /**
- * This calls the updateClustes with default arguments
- */
- exports.updateClustersDefault = function() {
- if (this.constants.clustering.enabled == true) {
- this.updateClusters(0,false,false);
- }
- };
+ // based on (sl) translation by Robert Sedovšek
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
- /**
- * This function can be called to increase the cluster level. This means that the nodes with only one edge connection will
- * be clustered with their connected node. This can be repeated as many times as needed.
- * This can be called externally (by a keybind for instance) to reduce the complexity of big datasets.
- */
- exports.increaseClusterLevel = function() {
- this.updateClusters(-1,false,true);
- };
+ function translate(number, withoutSuffix, key) {
+ var result = number + " ";
+ switch (key) {
+ case 'm':
+ return withoutSuffix ? 'jedna minuta' : 'jedne minute';
+ case 'mm':
+ if (number === 1) {
+ result += 'minuta';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'minute';
+ } else {
+ result += 'minuta';
+ }
+ return result;
+ case 'h':
+ return withoutSuffix ? 'jedan sat' : 'jednog sata';
+ case 'hh':
+ if (number === 1) {
+ result += 'sat';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'sata';
+ } else {
+ result += 'sati';
+ }
+ return result;
+ case 'dd':
+ if (number === 1) {
+ result += 'dan';
+ } else {
+ result += 'dana';
+ }
+ return result;
+ case 'MM':
+ if (number === 1) {
+ result += 'mjesec';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'mjeseca';
+ } else {
+ result += 'mjeseci';
+ }
+ return result;
+ case 'yy':
+ if (number === 1) {
+ result += 'godina';
+ } else if (number === 2 || number === 3 || number === 4) {
+ result += 'godine';
+ } else {
+ result += 'godina';
+ }
+ return result;
+ }
+ }
+ return moment.lang('hr', {
+ months : "sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_"),
+ monthsShort : "sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),
+ weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),
+ weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"),
+ weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD. MM. YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd, D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[danas u] LT',
+ nextDay : '[sutra u] LT',
- /**
- * This function can be called to decrease the cluster level. This means that the nodes with only one edge connection will
- * be unpacked if they are a cluster. This can be repeated as many times as needed.
- * This can be called externally (by a key-bind for instance) to look into clusters without zooming.
- */
- exports.decreaseClusterLevel = function() {
- this.updateClusters(1,false,true);
- };
+ nextWeek : function () {
+ switch (this.day()) {
+ case 0:
+ return '[u] [nedjelju] [u] LT';
+ case 3:
+ return '[u] [srijedu] [u] LT';
+ case 6:
+ return '[u] [subotu] [u] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[u] dddd [u] LT';
+ }
+ },
+ lastDay : '[jučer u] LT',
+ lastWeek : function () {
+ switch (this.day()) {
+ case 0:
+ case 3:
+ return '[prošlu] dddd [u] LT';
+ case 6:
+ return '[prošle] [subote] [u] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[prošli] dddd [u] LT';
+ }
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "za %s",
+ past : "prije %s",
+ s : "par sekundi",
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : "dan",
+ dd : translate,
+ M : "mjesec",
+ MM : translate,
+ y : "godinu",
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * This is the main clustering function. It clusters and declusters on zoom or forced
- * This function clusters on zoom, it can be called with a predefined zoom direction
- * If out, check if we can form clusters, if in, check if we can open clusters.
- * This function is only called from _zoom()
- *
- * @param {Number} zoomDirection | -1 / 0 / +1 for zoomOut / determineByZoom / zoomIn
- * @param {Boolean} recursive | enabled or disable recursive calling of the opening of clusters
- * @param {Boolean} force | enabled or disable forcing
- * @param {Boolean} doNotStart | if true do not call start
- *
- */
- exports.updateClusters = function(zoomDirection,recursive,force,doNotStart) {
- var isMovingBeforeClustering = this.moving;
- var amountOfNodes = this.nodeIndices.length;
+/***/ },
+/* 76 */
+/***/ function(module, exports, __webpack_require__) {
- // on zoom out collapse the sector if the scale is at the level the sector was made
- if (this.previousScale > this.scale && zoomDirection == 0) {
- this._collapseSector();
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : hungarian (hu)
+ // author : Adam Brunner : https://github.com/adambrunner
- // check if we zoom in or out
- if (this.previousScale > this.scale || zoomDirection == -1) { // zoom out
- // forming clusters when forced pulls outliers in. When not forced, the edge length of the
- // outer nodes determines if it is being clustered
- this._formClusters(force);
- }
- else if (this.previousScale < this.scale || zoomDirection == 1) { // zoom in
- if (force == true) {
- // _openClusters checks for each node if the formationScale of the cluster is smaller than
- // the current scale and if so, declusters. When forced, all clusters are reduced by one step
- this._openClusters(recursive,force);
- }
- else {
- // if a cluster takes up a set percentage of the active window
- this._openClustersBySize();
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- this._updateNodeIndexList();
-
- // if a cluster was NOT formed and the user zoomed out, we try clustering by hubs
- if (this.nodeIndices.length == amountOfNodes && (this.previousScale > this.scale || zoomDirection == -1)) {
- this._aggregateHubs(force);
- this._updateNodeIndexList();
- }
-
- // we now reduce chains.
- if (this.previousScale > this.scale || zoomDirection == -1) { // zoom out
- this.handleChains();
- this._updateNodeIndexList();
- }
-
- this.previousScale = this.scale;
+ }(function (moment) {
+ var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
- // rest of the update the index list, dynamic edges and labels
- this._updateDynamicEdges();
- this.updateLabels();
+ function translate(number, withoutSuffix, key, isFuture) {
+ var num = number,
+ suffix;
- // if a cluster was formed, we increase the clusterSession
- if (this.nodeIndices.length < amountOfNodes) { // this means a clustering operation has taken place
- this.clusterSession += 1;
- // if clusters have been made, we normalize the cluster level
- this.normalizeClusterLevels();
- }
+ switch (key) {
+ case 's':
+ return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
+ case 'm':
+ return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
+ case 'mm':
+ return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
+ case 'h':
+ return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
+ case 'hh':
+ return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
+ case 'd':
+ return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
+ case 'dd':
+ return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
+ case 'M':
+ return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
+ case 'MM':
+ return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
+ case 'y':
+ return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
+ case 'yy':
+ return num + (isFuture || withoutSuffix ? ' év' : ' éve');
+ }
- if (doNotStart == false || doNotStart === undefined) {
- // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
- if (this.moving != isMovingBeforeClustering) {
- this.start();
+ return '';
}
- }
-
- this._updateCalculationNodes();
- };
- /**
- * This function handles the chains. It is called on every updateClusters().
- */
- exports.handleChains = function() {
- // after clustering we check how many chains there are
- var chainPercentage = this._getChainFraction();
- if (chainPercentage > this.constants.clustering.chainThreshold) {
- this._reduceAmountOfChains(1 - this.constants.clustering.chainThreshold / chainPercentage)
+ function week(isFuture) {
+ return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
+ }
- }
- };
+ return moment.lang('hu', {
+ months : "január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),
+ monthsShort : "jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),
+ weekdays : "vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),
+ weekdaysShort : "vas_hét_kedd_sze_csüt_pén_szo".split("_"),
+ weekdaysMin : "v_h_k_sze_cs_p_szo".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "YYYY.MM.DD.",
+ LL : "YYYY. MMMM D.",
+ LLL : "YYYY. MMMM D., LT",
+ LLLL : "YYYY. MMMM D., dddd LT"
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours < 12) {
+ return isLower === true ? 'de' : 'DE';
+ } else {
+ return isLower === true ? 'du' : 'DU';
+ }
+ },
+ calendar : {
+ sameDay : '[ma] LT[-kor]',
+ nextDay : '[holnap] LT[-kor]',
+ nextWeek : function () {
+ return week.call(this, true);
+ },
+ lastDay : '[tegnap] LT[-kor]',
+ lastWeek : function () {
+ return week.call(this, false);
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s múlva",
+ past : "%s",
+ s : translate,
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : translate,
+ dd : translate,
+ M : translate,
+ MM : translate,
+ y : translate,
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * this functions starts clustering by hubs
- * The minimum hub threshold is set globally
- *
- * @private
- */
- exports._aggregateHubs = function(force) {
- this._getHubSize();
- this._formClustersByHub(force,false);
- };
+/***/ },
+/* 77 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This function is fired by keypress. It forces hubs to form.
- *
- */
- exports.forceAggregateHubs = function(doNotStart) {
- var isMovingBeforeClustering = this.moving;
- var amountOfNodes = this.nodeIndices.length;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Armenian (hy-am)
+ // author : Armendarabyan : https://github.com/armendarabyan
- this._aggregateHubs(true);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
- // update the index list, dynamic edges and labels
- this._updateNodeIndexList();
- this._updateDynamicEdges();
- this.updateLabels();
+ function monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),
+ 'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')
+ },
- // if a cluster was formed, we increase the clusterSession
- if (this.nodeIndices.length != amountOfNodes) {
- this.clusterSession += 1;
- }
+ nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
- if (doNotStart == false || doNotStart === undefined) {
- // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
- if (this.moving != isMovingBeforeClustering) {
- this.start();
+ return months[nounCase][m.month()];
}
- }
- };
- /**
- * If a cluster takes up more than a set percentage of the screen, open the cluster
- *
- * @private
- */
- exports._openClustersBySize = function() {
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- var node = this.nodes[nodeId];
- if (node.inView() == true) {
- if ((node.width*this.scale > this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientWidth) ||
- (node.height*this.scale > this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientHeight)) {
- this.openCluster(node);
- }
- }
- }
- }
- };
+ function monthsShortCaseReplace(m, format) {
+ var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');
+ return monthsShort[m.month()];
+ }
- /**
- * This function loops over all nodes in the nodeIndices list. For each node it checks if it is a cluster and if it
- * has to be opened based on the current zoom level.
- *
- * @private
- */
- exports._openClusters = function(recursive,force) {
- for (var i = 0; i < this.nodeIndices.length; i++) {
- var node = this.nodes[this.nodeIndices[i]];
- this._expandClusterNode(node,recursive,force);
- this._updateCalculationNodes();
- }
- };
+ function weekdaysCaseReplace(m, format) {
+ var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');
- /**
- * This function checks if a node has to be opened. This is done by checking the zoom level.
- * If the node contains child nodes, this function is recursively called on the child nodes as well.
- * This recursive behaviour is optional and can be set by the recursive argument.
- *
- * @param {Node} parentNode | to check for cluster and expand
- * @param {Boolean} recursive | enabled or disable recursive calling
- * @param {Boolean} force | enabled or disable forcing
- * @param {Boolean} [openAll] | This will recursively force all nodes in the parent to be released
- * @private
- */
- exports._expandClusterNode = function(parentNode, recursive, force, openAll) {
- // first check if node is a cluster
- if (parentNode.clusterSize > 1) {
- // this means that on a double tap event or a zoom event, the cluster fully unpacks if it is smaller than 20
- if (parentNode.clusterSize < this.constants.clustering.sectorThreshold) {
- openAll = true;
+ return weekdays[m.day()];
}
- recursive = openAll ? true : recursive;
- // if the last child has been added on a smaller scale than current scale decluster
- if (parentNode.formationScale < this.scale || force == true) {
- // we will check if any of the contained child nodes should be removed from the cluster
- for (var containedNodeId in parentNode.containedNodes) {
- if (parentNode.containedNodes.hasOwnProperty(containedNodeId)) {
- var childNode = parentNode.containedNodes[containedNodeId];
+ return moment.lang('hy-am', {
+ months : monthsCaseReplace,
+ monthsShort : monthsShortCaseReplace,
+ weekdays : weekdaysCaseReplace,
+ weekdaysShort : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),
+ weekdaysMin : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY թ.",
+ LLL : "D MMMM YYYY թ., LT",
+ LLLL : "dddd, D MMMM YYYY թ., LT"
+ },
+ calendar : {
+ sameDay: '[այսօր] LT',
+ nextDay: '[վաղը] LT',
+ lastDay: '[երեկ] LT',
+ nextWeek: function () {
+ return 'dddd [օրը ժամը] LT';
+ },
+ lastWeek: function () {
+ return '[անցած] dddd [օրը ժամը] LT';
+ },
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "%s հետո",
+ past : "%s առաջ",
+ s : "մի քանի վայրկյան",
+ m : "րոպե",
+ mm : "%d րոպե",
+ h : "ժամ",
+ hh : "%d ժամ",
+ d : "օր",
+ dd : "%d օր",
+ M : "ամիս",
+ MM : "%d ամիս",
+ y : "տարի",
+ yy : "%d տարի"
+ },
- // force expand will expand the largest cluster size clusters. Since we cluster from outside in, we assume that
- // the largest cluster is the one that comes from outside
- if (force == true) {
- if (childNode.clusterSession == parentNode.clusterSessions[parentNode.clusterSessions.length-1]
- || openAll) {
- this._expelChildFromParent(parentNode,containedNodeId,recursive,force,openAll);
- }
- }
- else {
- if (this._nodeInActiveArea(parentNode)) {
- this._expelChildFromParent(parentNode,containedNodeId,recursive,force,openAll);
+ meridiem : function (hour) {
+ if (hour < 4) {
+ return "գիշերվա";
+ } else if (hour < 12) {
+ return "առավոտվա";
+ } else if (hour < 17) {
+ return "ցերեկվա";
+ } else {
+ return "երեկոյան";
}
- }
- }
- }
- }
- }
- };
+ },
- /**
- * ONLY CALLED FROM _expandClusterNode
- *
- * This function will expel a child_node from a parent_node. This is to de-cluster the node. This function will remove
- * the child node from the parent contained_node object and put it back into the global nodes object.
- * The same holds for the edge that was connected to the child node. It is moved back into the global edges object.
- *
- * @param {Node} parentNode | the parent node
- * @param {String} containedNodeId | child_node id as it is contained in the containedNodes object of the parent node
- * @param {Boolean} recursive | This will also check if the child needs to be expanded.
- * With force and recursive both true, the entire cluster is unpacked
- * @param {Boolean} force | This will disregard the zoom level and will expel this child from the parent
- * @param {Boolean} openAll | This will recursively force all nodes in the parent to be released
- * @private
- */
- exports._expelChildFromParent = function(parentNode, containedNodeId, recursive, force, openAll) {
- var childNode = parentNode.containedNodes[containedNodeId];
+ ordinal: function (number, period) {
+ switch (period) {
+ case 'DDD':
+ case 'w':
+ case 'W':
+ case 'DDDo':
+ if (number === 1) {
+ return number + '-ին';
+ }
+ return number + '-րդ';
+ default:
+ return number;
+ }
+ },
- // if child node has been added on smaller scale than current, kick out
- if (childNode.formationScale < this.scale || force == true) {
- // unselect all selected items
- this._unselectAll();
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- // put the child node back in the global nodes object
- this.nodes[containedNodeId] = childNode;
- // release the contained edges from this childNode back into the global edges
- this._releaseContainedEdges(parentNode,childNode);
+/***/ },
+/* 78 */
+/***/ function(module, exports, __webpack_require__) {
- // reconnect rerouted edges to the childNode
- this._connectEdgeBackToChild(parentNode,childNode);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Bahasa Indonesia (id)
+ // author : Mohammad Satrio Utomo : https://github.com/tyok
+ // reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
- // validate all edges in dynamicEdges
- this._validateEdges(parentNode);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('id', {
+ months : "Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),
+ monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),
+ weekdays : "Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),
+ weekdaysShort : "Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),
+ weekdaysMin : "Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),
+ longDateFormat : {
+ LT : "HH.mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY [pukul] LT",
+ LLLL : "dddd, D MMMM YYYY [pukul] LT"
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours < 11) {
+ return 'pagi';
+ } else if (hours < 15) {
+ return 'siang';
+ } else if (hours < 19) {
+ return 'sore';
+ } else {
+ return 'malam';
+ }
+ },
+ calendar : {
+ sameDay : '[Hari ini pukul] LT',
+ nextDay : '[Besok pukul] LT',
+ nextWeek : 'dddd [pukul] LT',
+ lastDay : '[Kemarin pukul] LT',
+ lastWeek : 'dddd [lalu pukul] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "dalam %s",
+ past : "%s yang lalu",
+ s : "beberapa detik",
+ m : "semenit",
+ mm : "%d menit",
+ h : "sejam",
+ hh : "%d jam",
+ d : "sehari",
+ dd : "%d hari",
+ M : "sebulan",
+ MM : "%d bulan",
+ y : "setahun",
+ yy : "%d tahun"
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- // undo the changes from the clustering operation on the parent node
- parentNode.mass -= childNode.mass;
- parentNode.clusterSize -= childNode.clusterSize;
- parentNode.fontSize = Math.min(this.constants.clustering.maxFontSize, this.constants.nodes.fontSize + this.constants.clustering.fontSizeMultiplier*parentNode.clusterSize);
- parentNode.dynamicEdgesLength = parentNode.dynamicEdges.length;
- // place the child node near the parent, not at the exact same location to avoid chaos in the system
- childNode.x = parentNode.x + parentNode.growthIndicator * (0.5 - Math.random());
- childNode.y = parentNode.y + parentNode.growthIndicator * (0.5 - Math.random());
+/***/ },
+/* 79 */
+/***/ function(module, exports, __webpack_require__) {
- // remove node from the list
- delete parentNode.containedNodes[containedNodeId];
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : icelandic (is)
+ // author : Hinrik Örn Sigurðsson : https://github.com/hinrik
- // check if there are other childs with this clusterSession in the parent.
- var othersPresent = false;
- for (var childNodeId in parentNode.containedNodes) {
- if (parentNode.containedNodes.hasOwnProperty(childNodeId)) {
- if (parentNode.containedNodes[childNodeId].clusterSession == childNode.clusterSession) {
- othersPresent = true;
- break;
- }
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- // if there are no others, remove the cluster session from the list
- if (othersPresent == false) {
- parentNode.clusterSessions.pop();
+ }(function (moment) {
+ function plural(n) {
+ if (n % 100 === 11) {
+ return true;
+ } else if (n % 10 === 1) {
+ return false;
+ }
+ return true;
}
- this._repositionBezierNodes(childNode);
- // this._repositionBezierNodes(parentNode);
-
- // remove the clusterSession from the child node
- childNode.clusterSession = 0;
-
- // recalculate the size of the node on the next time the node is rendered
- parentNode.clearSizeCache();
-
- // restart the simulation to reorganise all nodes
- this.moving = true;
- }
-
- // check if a further expansion step is possible if recursivity is enabled
- if (recursive == true) {
- this._expandClusterNode(childNode,recursive,force,openAll);
- }
- };
-
-
- /**
- * position the bezier nodes at the center of the edges
- *
- * @param node
- * @private
- */
- exports._repositionBezierNodes = function(node) {
- for (var i = 0; i < node.dynamicEdges.length; i++) {
- node.dynamicEdges[i].positionBezierNode();
- }
- };
-
-
- /**
- * This function checks if any nodes at the end of their trees have edges below a threshold length
- * This function is called only from updateClusters()
- * forceLevelCollapse ignores the length of the edge and collapses one level
- * This means that a node with only one edge will be clustered with its connected node
- *
- * @private
- * @param {Boolean} force
- */
- exports._formClusters = function(force) {
- if (force == false) {
- this._formClustersByZoom();
- }
- else {
- this._forceClustersByZoom();
- }
- };
-
-
- /**
- * This function handles the clustering by zooming out, this is based on a minimum edge distance
- *
- * @private
- */
- exports._formClustersByZoom = function() {
- var dx,dy,length,
- minLength = this.constants.clustering.clusterEdgeThreshold/this.scale;
-
- // check if any edges are shorter than minLength and start the clustering
- // the clustering favours the node with the larger mass
- for (var edgeId in this.edges) {
- if (this.edges.hasOwnProperty(edgeId)) {
- var edge = this.edges[edgeId];
- if (edge.connected) {
- if (edge.toId != edge.fromId) {
- dx = (edge.to.x - edge.from.x);
- dy = (edge.to.y - edge.from.y);
- length = Math.sqrt(dx * dx + dy * dy);
-
-
- if (length < minLength) {
- // first check which node is larger
- var parentNode = edge.from;
- var childNode = edge.to;
- if (edge.to.mass > edge.from.mass) {
- parentNode = edge.to;
- childNode = edge.from;
+ function translate(number, withoutSuffix, key, isFuture) {
+ var result = number + " ";
+ switch (key) {
+ case 's':
+ return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';
+ case 'm':
+ return withoutSuffix ? 'mínúta' : 'mínútu';
+ case 'mm':
+ if (plural(number)) {
+ return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');
+ } else if (withoutSuffix) {
+ return result + 'mínúta';
}
-
- if (childNode.dynamicEdgesLength == 1) {
- this._addToCluster(parentNode,childNode,false);
+ return result + 'mínútu';
+ case 'hh':
+ if (plural(number)) {
+ return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');
}
- else if (parentNode.dynamicEdgesLength == 1) {
- this._addToCluster(childNode,parentNode,false);
+ return result + 'klukkustund';
+ case 'd':
+ if (withoutSuffix) {
+ return 'dagur';
}
- }
+ return isFuture ? 'dag' : 'degi';
+ case 'dd':
+ if (plural(number)) {
+ if (withoutSuffix) {
+ return result + 'dagar';
+ }
+ return result + (isFuture ? 'daga' : 'dögum');
+ } else if (withoutSuffix) {
+ return result + 'dagur';
+ }
+ return result + (isFuture ? 'dag' : 'degi');
+ case 'M':
+ if (withoutSuffix) {
+ return 'mánuður';
+ }
+ return isFuture ? 'mánuð' : 'mánuði';
+ case 'MM':
+ if (plural(number)) {
+ if (withoutSuffix) {
+ return result + 'mánuðir';
+ }
+ return result + (isFuture ? 'mánuði' : 'mánuðum');
+ } else if (withoutSuffix) {
+ return result + 'mánuður';
+ }
+ return result + (isFuture ? 'mánuð' : 'mánuði');
+ case 'y':
+ return withoutSuffix || isFuture ? 'ár' : 'ári';
+ case 'yy':
+ if (plural(number)) {
+ return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
+ }
+ return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
}
- }
}
- }
- };
-
- /**
- * This function forces the network to cluster all nodes with only one connecting edge to their
- * connected node.
- *
- * @private
- */
- exports._forceClustersByZoom = function() {
- for (var nodeId in this.nodes) {
- // another node could have absorbed this child.
- if (this.nodes.hasOwnProperty(nodeId)) {
- var childNode = this.nodes[nodeId];
-
- // the edges can be swallowed by another decrease
- if (childNode.dynamicEdgesLength == 1 && childNode.dynamicEdges.length != 0) {
- var edge = childNode.dynamicEdges[0];
- var parentNode = (edge.toId == childNode.id) ? this.nodes[edge.fromId] : this.nodes[edge.toId];
- // group to the largest node
- if (childNode.id != parentNode.id) {
- if (parentNode.mass > childNode.mass) {
- this._addToCluster(parentNode,childNode,true);
- }
- else {
- this._addToCluster(childNode,parentNode,true);
- }
+ return moment.lang('is', {
+ months : "janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),
+ monthsShort : "jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),
+ weekdays : "sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),
+ weekdaysShort : "sun_mán_þri_mið_fim_fös_lau".split("_"),
+ weekdaysMin : "Su_Má_Þr_Mi_Fi_Fö_La".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD/MM/YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY [kl.] LT",
+ LLLL : "dddd, D. MMMM YYYY [kl.] LT"
+ },
+ calendar : {
+ sameDay : '[í dag kl.] LT',
+ nextDay : '[á morgun kl.] LT',
+ nextWeek : 'dddd [kl.] LT',
+ lastDay : '[í gær kl.] LT',
+ lastWeek : '[síðasta] dddd [kl.] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "eftir %s",
+ past : "fyrir %s síðan",
+ s : translate,
+ m : translate,
+ mm : translate,
+ h : "klukkustund",
+ hh : translate,
+ d : translate,
+ dd : translate,
+ M : translate,
+ MM : translate,
+ y : translate,
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
}
- }
- }
- }
- };
+ });
+ }));
- /**
- * To keep the nodes of roughly equal size we normalize the cluster levels.
- * This function clusters a node to its smallest connected neighbour.
- *
- * @param node
- * @private
- */
- exports._clusterToSmallestNeighbour = function(node) {
- var smallestNeighbour = -1;
- var smallestNeighbourNode = null;
- for (var i = 0; i < node.dynamicEdges.length; i++) {
- if (node.dynamicEdges[i] !== undefined) {
- var neighbour = null;
- if (node.dynamicEdges[i].fromId != node.id) {
- neighbour = node.dynamicEdges[i].from;
- }
- else if (node.dynamicEdges[i].toId != node.id) {
- neighbour = node.dynamicEdges[i].to;
- }
+/***/ },
+/* 80 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : italian (it)
+ // author : Lorenzo : https://github.com/aliem
+ // author: Mattia Larentis: https://github.com/nostalgiaz
- if (neighbour != null && smallestNeighbour > neighbour.clusterSessions.length) {
- smallestNeighbour = neighbour.clusterSessions.length;
- smallestNeighbourNode = neighbour;
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
-
- if (neighbour != null && this.nodes[neighbour.id] !== undefined) {
- this._addToCluster(neighbour, node, true);
- }
- };
+ }(function (moment) {
+ return moment.lang('it', {
+ months : "gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),
+ monthsShort : "gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),
+ weekdays : "Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),
+ weekdaysShort : "Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),
+ weekdaysMin : "D_L_Ma_Me_G_V_S".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: '[Oggi alle] LT',
+ nextDay: '[Domani alle] LT',
+ nextWeek: 'dddd [alle] LT',
+ lastDay: '[Ieri alle] LT',
+ lastWeek: '[lo scorso] dddd [alle] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : function (s) {
+ return ((/^[0-9].+$/).test(s) ? "tra" : "in") + " " + s;
+ },
+ past : "%s fa",
+ s : "alcuni secondi",
+ m : "un minuto",
+ mm : "%d minuti",
+ h : "un'ora",
+ hh : "%d ore",
+ d : "un giorno",
+ dd : "%d giorni",
+ M : "un mese",
+ MM : "%d mesi",
+ y : "un anno",
+ yy : "%d anni"
+ },
+ ordinal: '%dº',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * This function forms clusters from hubs, it loops over all nodes
- *
- * @param {Boolean} force | Disregard zoom level
- * @param {Boolean} onlyEqual | This only clusters a hub with a specific number of edges
- * @private
- */
- exports._formClustersByHub = function(force, onlyEqual) {
- // we loop over all nodes in the list
- for (var nodeId in this.nodes) {
- // we check if it is still available since it can be used by the clustering in this loop
- if (this.nodes.hasOwnProperty(nodeId)) {
- this._formClusterFromHub(this.nodes[nodeId],force,onlyEqual);
- }
- }
- };
+/***/ },
+/* 81 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This function forms a cluster from a specific preselected hub node
- *
- * @param {Node} hubNode | the node we will cluster as a hub
- * @param {Boolean} force | Disregard zoom level
- * @param {Boolean} onlyEqual | This only clusters a hub with a specific number of edges
- * @param {Number} [absorptionSizeOffset] |
- * @private
- */
- exports._formClusterFromHub = function(hubNode, force, onlyEqual, absorptionSizeOffset) {
- if (absorptionSizeOffset === undefined) {
- absorptionSizeOffset = 0;
- }
- // we decide if the node is a hub
- if ((hubNode.dynamicEdgesLength >= this.hubThreshold && onlyEqual == false) ||
- (hubNode.dynamicEdgesLength == this.hubThreshold && onlyEqual == true)) {
- // initialize variables
- var dx,dy,length;
- var minLength = this.constants.clustering.clusterEdgeThreshold/this.scale;
- var allowCluster = false;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : japanese (ja)
+ // author : LI Long : https://github.com/baryon
- // we create a list of edges because the dynamicEdges change over the course of this loop
- var edgesIdarray = [];
- var amountOfInitialEdges = hubNode.dynamicEdges.length;
- for (var j = 0; j < amountOfInitialEdges; j++) {
- edgesIdarray.push(hubNode.dynamicEdges[j].id);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
-
- // if the hub clustering is not forces, we check if one of the edges connected
- // to a cluster is small enough based on the constants.clustering.clusterEdgeThreshold
- if (force == false) {
- allowCluster = false;
- for (j = 0; j < amountOfInitialEdges; j++) {
- var edge = this.edges[edgesIdarray[j]];
- if (edge !== undefined) {
- if (edge.connected) {
- if (edge.toId != edge.fromId) {
- dx = (edge.to.x - edge.from.x);
- dy = (edge.to.y - edge.from.y);
- length = Math.sqrt(dx * dx + dy * dy);
-
- if (length < minLength) {
- allowCluster = true;
- break;
- }
+ }(function (moment) {
+ return moment.lang('ja', {
+ months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
+ monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
+ weekdays : "日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),
+ weekdaysShort : "日_月_火_水_木_金_土".split("_"),
+ weekdaysMin : "日_月_火_水_木_金_土".split("_"),
+ longDateFormat : {
+ LT : "Ah時m分",
+ L : "YYYY/MM/DD",
+ LL : "YYYY年M月D日",
+ LLL : "YYYY年M月D日LT",
+ LLLL : "YYYY年M月D日LT dddd"
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 12) {
+ return "午前";
+ } else {
+ return "午後";
}
- }
- }
- }
- }
-
- // start the clustering if allowed
- if ((!force && allowCluster) || force) {
- // we loop over all edges INITIALLY connected to this hub
- for (j = 0; j < amountOfInitialEdges; j++) {
- edge = this.edges[edgesIdarray[j]];
- // the edge can be clustered by this function in a previous loop
- if (edge !== undefined) {
- var childNode = this.nodes[(edge.fromId == hubNode.id) ? edge.toId : edge.fromId];
- // we do not want hubs to merge with other hubs nor do we want to cluster itself.
- if ((childNode.dynamicEdges.length <= (this.hubThreshold + absorptionSizeOffset)) &&
- (childNode.id != hubNode.id)) {
- this._addToCluster(hubNode,childNode,force);
- }
+ },
+ calendar : {
+ sameDay : '[今日] LT',
+ nextDay : '[明日] LT',
+ nextWeek : '[来週]dddd LT',
+ lastDay : '[昨日] LT',
+ lastWeek : '[前週]dddd LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s後",
+ past : "%s前",
+ s : "数秒",
+ m : "1分",
+ mm : "%d分",
+ h : "1時間",
+ hh : "%d時間",
+ d : "1日",
+ dd : "%d日",
+ M : "1ヶ月",
+ MM : "%dヶ月",
+ y : "1年",
+ yy : "%d年"
}
- }
- }
- }
- };
+ });
+ }));
+/***/ },
+/* 82 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This function adds the child node to the parent node, creating a cluster if it is not already.
- *
- * @param {Node} parentNode | this is the node that will house the child node
- * @param {Node} childNode | this node will be deleted from the global this.nodes and stored in the parent node
- * @param {Boolean} force | true will only update the remainingEdges at the very end of the clustering, ensuring single level collapse
- * @private
- */
- exports._addToCluster = function(parentNode, childNode, force) {
- // join child node in the parent node
- parentNode.containedNodes[childNode.id] = childNode;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Georgian (ka)
+ // author : Irakli Janiashvili : https://github.com/irakli-janiashvili
- // manage all the edges connected to the child and parent nodes
- for (var i = 0; i < childNode.dynamicEdges.length; i++) {
- var edge = childNode.dynamicEdges[i];
- if (edge.toId == parentNode.id || edge.fromId == parentNode.id) { // edge connected to parentNode
- this._addToContainedEdges(parentNode,childNode,edge);
- }
- else {
- this._connectEdgeToCluster(parentNode,childNode,edge);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- // a contained node has no dynamic edges.
- childNode.dynamicEdges = [];
-
- // remove circular edges from clusters
- this._containCircularEdgesFromNode(parentNode,childNode);
-
-
- // remove the childNode from the global nodes object
- delete this.nodes[childNode.id];
-
- // update the properties of the child and parent
- var massBefore = parentNode.mass;
- childNode.clusterSession = this.clusterSession;
- parentNode.mass += childNode.mass;
- parentNode.clusterSize += childNode.clusterSize;
- parentNode.fontSize = Math.min(this.constants.clustering.maxFontSize, this.constants.nodes.fontSize + this.constants.clustering.fontSizeMultiplier*parentNode.clusterSize);
-
- // keep track of the clustersessions so we can open the cluster up as it has been formed.
- if (parentNode.clusterSessions[parentNode.clusterSessions.length - 1] != this.clusterSession) {
- parentNode.clusterSessions.push(this.clusterSession);
- }
-
- // forced clusters only open from screen size and double tap
- if (force == true) {
- // parentNode.formationScale = Math.pow(1 - (1.0/11.0),this.clusterSession+3);
- parentNode.formationScale = 0;
- }
- else {
- parentNode.formationScale = this.scale; // The latest child has been added on this scale
- }
+ }(function (moment) {
- // recalculate the size of the node on the next time the node is rendered
- parentNode.clearSizeCache();
+ function monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
+ 'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')
+ },
- // set the pop-out scale for the childnode
- parentNode.containedNodes[childNode.id].formationScale = parentNode.formationScale;
+ nounCase = (/D[oD] *MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
- // nullify the movement velocity of the child, this is to avoid hectic behaviour
- childNode.clearVelocity();
+ return months[nounCase][m.month()];
+ }
- // the mass has altered, preservation of energy dictates the velocity to be updated
- parentNode.updateVelocity(massBefore);
+ function weekdaysCaseReplace(m, format) {
+ var weekdays = {
+ 'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),
+ 'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')
+ },
- // restart the simulation to reorganise all nodes
- this.moving = true;
- };
+ nounCase = (/(წინა|შემდეგ)/).test(format) ?
+ 'accusative' :
+ 'nominative';
+ return weekdays[nounCase][m.day()];
+ }
- /**
- * This function will apply the changes made to the remainingEdges during the formation of the clusters.
- * This is a seperate function to allow for level-wise collapsing of the node barnesHutTree.
- * It has to be called if a level is collapsed. It is called by _formClusters().
- * @private
- */
- exports._updateDynamicEdges = function() {
- for (var i = 0; i < this.nodeIndices.length; i++) {
- var node = this.nodes[this.nodeIndices[i]];
- node.dynamicEdgesLength = node.dynamicEdges.length;
+ return moment.lang('ka', {
+ months : monthsCaseReplace,
+ monthsShort : "იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),
+ weekdays : weekdaysCaseReplace,
+ weekdaysShort : "კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"),
+ weekdaysMin : "კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"),
+ longDateFormat : {
+ LT : "h:mm A",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[დღეს] LT[-ზე]',
+ nextDay : '[ხვალ] LT[-ზე]',
+ lastDay : '[გუშინ] LT[-ზე]',
+ nextWeek : '[შემდეგ] dddd LT[-ზე]',
+ lastWeek : '[წინა] dddd LT-ზე',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : function (s) {
+ return (/(წამი|წუთი|საათი|წელი)/).test(s) ?
+ s.replace(/ი$/, "ში") :
+ s + "ში";
+ },
+ past : function (s) {
+ if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {
+ return s.replace(/(ი|ე)$/, "ის წინ");
+ }
+ if ((/წელი/).test(s)) {
+ return s.replace(/წელი$/, "წლის წინ");
+ }
+ },
+ s : "რამდენიმე წამი",
+ m : "წუთი",
+ mm : "%d წუთი",
+ h : "საათი",
+ hh : "%d საათი",
+ d : "დღე",
+ dd : "%d დღე",
+ M : "თვე",
+ MM : "%d თვე",
+ y : "წელი",
+ yy : "%d წელი"
+ },
+ ordinal : function (number) {
+ if (number === 0) {
+ return number;
+ }
- // this corrects for multiple edges pointing at the same other node
- var correction = 0;
- if (node.dynamicEdgesLength > 1) {
- for (var j = 0; j < node.dynamicEdgesLength - 1; j++) {
- var edgeToId = node.dynamicEdges[j].toId;
- var edgeFromId = node.dynamicEdges[j].fromId;
- for (var k = j+1; k < node.dynamicEdgesLength; k++) {
- if ((node.dynamicEdges[k].toId == edgeToId && node.dynamicEdges[k].fromId == edgeFromId) ||
- (node.dynamicEdges[k].fromId == edgeToId && node.dynamicEdges[k].toId == edgeFromId)) {
- correction += 1;
- }
- }
- }
- }
- node.dynamicEdgesLength -= correction;
- }
- };
+ if (number === 1) {
+ return number + "-ლი";
+ }
+ if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {
+ return "მე-" + number;
+ }
- /**
- * This adds an edge from the childNode to the contained edges of the parent node
- *
- * @param parentNode | Node object
- * @param childNode | Node object
- * @param edge | Edge object
- * @private
- */
- exports._addToContainedEdges = function(parentNode, childNode, edge) {
- // create an array object if it does not yet exist for this childNode
- if (!(parentNode.containedEdges.hasOwnProperty(childNode.id))) {
- parentNode.containedEdges[childNode.id] = []
- }
- // add this edge to the list
- parentNode.containedEdges[childNode.id].push(edge);
+ return number + "-ე";
+ },
+ week : {
+ dow : 1,
+ doy : 7
+ }
+ });
+ }));
- // remove the edge from the global edges object
- delete this.edges[edge.id];
- // remove the edge from the parent object
- for (var i = 0; i < parentNode.dynamicEdges.length; i++) {
- if (parentNode.dynamicEdges[i].id == edge.id) {
- parentNode.dynamicEdges.splice(i,1);
- break;
- }
- }
- };
+/***/ },
+/* 83 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This function connects an edge that was connected to a child node to the parent node.
- * It keeps track of which nodes it has been connected to with the originalId array.
- *
- * @param {Node} parentNode | Node object
- * @param {Node} childNode | Node object
- * @param {Edge} edge | Edge object
- * @private
- */
- exports._connectEdgeToCluster = function(parentNode, childNode, edge) {
- // handle circular edges
- if (edge.toId == edge.fromId) {
- this._addToContainedEdges(parentNode, childNode, edge);
- }
- else {
- if (edge.toId == childNode.id) { // edge connected to other node on the "to" side
- edge.originalToId.push(childNode.id);
- edge.to = parentNode;
- edge.toId = parentNode.id;
- }
- else { // edge connected to other node with the "from" side
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : khmer (km)
+ // author : Kruy Vanna : https://github.com/kruyvanna
- edge.originalFromId.push(childNode.id);
- edge.from = parentNode;
- edge.fromId = parentNode.id;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
+ }(function (moment) {
+ return moment.lang('km', {
+ months: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),
+ monthsShort: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),
+ weekdays: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),
+ weekdaysShort: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),
+ weekdaysMin: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),
+ longDateFormat: {
+ LT: "HH:mm",
+ L: "DD/MM/YYYY",
+ LL: "D MMMM YYYY",
+ LLL: "D MMMM YYYY LT",
+ LLLL: "dddd, D MMMM YYYY LT"
+ },
+ calendar: {
+ sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',
+ nextDay: '[ស្អែក ម៉ោង] LT',
+ nextWeek: 'dddd [ម៉ោង] LT',
+ lastDay: '[ម្សិលមិញ ម៉ោង] LT',
+ lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',
+ sameElse: 'L'
+ },
+ relativeTime: {
+ future: "%sទៀត",
+ past: "%sមុន",
+ s: "ប៉ុន្មានវិនាទី",
+ m: "មួយនាទី",
+ mm: "%d នាទី",
+ h: "មួយម៉ោង",
+ hh: "%d ម៉ោង",
+ d: "មួយថ្ងៃ",
+ dd: "%d ថ្ងៃ",
+ M: "មួយខែ",
+ MM: "%d ខែ",
+ y: "មួយឆ្នាំ",
+ yy: "%d ឆ្នាំ"
+ },
+ week: {
+ dow: 1, // Monday is the first day of the week.
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- this._addToReroutedEdges(parentNode,childNode,edge);
- }
- };
+/***/ },
+/* 84 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * If a node is connected to itself, a circular edge is drawn. When clustering we want to contain
- * these edges inside of the cluster.
- *
- * @param parentNode
- * @param childNode
- * @private
- */
- exports._containCircularEdgesFromNode = function(parentNode, childNode) {
- // manage all the edges connected to the child and parent nodes
- for (var i = 0; i < parentNode.dynamicEdges.length; i++) {
- var edge = parentNode.dynamicEdges[i];
- // handle circular edges
- if (edge.toId == edge.fromId) {
- this._addToContainedEdges(parentNode, childNode, edge);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : korean (ko)
+ //
+ // authors
+ //
+ // - Kyungwook, Park : https://github.com/kyungw00k
+ // - Jeeeyul Lee
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- };
-
-
- /**
- * This adds an edge from the childNode to the rerouted edges of the parent node
- *
- * @param parentNode | Node object
- * @param childNode | Node object
- * @param edge | Edge object
- * @private
- */
- exports._addToReroutedEdges = function(parentNode, childNode, edge) {
- // create an array object if it does not yet exist for this childNode
- // we store the edge in the rerouted edges so we can restore it when the cluster pops open
- if (!(parentNode.reroutedEdges.hasOwnProperty(childNode.id))) {
- parentNode.reroutedEdges[childNode.id] = [];
- }
- parentNode.reroutedEdges[childNode.id].push(edge);
+ }(function (moment) {
+ return moment.lang('ko', {
+ months : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),
+ monthsShort : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),
+ weekdays : "일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),
+ weekdaysShort : "일_월_화_수_목_금_토".split("_"),
+ weekdaysMin : "일_월_화_수_목_금_토".split("_"),
+ longDateFormat : {
+ LT : "A h시 mm분",
+ L : "YYYY.MM.DD",
+ LL : "YYYY년 MMMM D일",
+ LLL : "YYYY년 MMMM D일 LT",
+ LLLL : "YYYY년 MMMM D일 dddd LT"
+ },
+ meridiem : function (hour, minute, isUpper) {
+ return hour < 12 ? '오전' : '오후';
+ },
+ calendar : {
+ sameDay : '오늘 LT',
+ nextDay : '내일 LT',
+ nextWeek : 'dddd LT',
+ lastDay : '어제 LT',
+ lastWeek : '지난주 dddd LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s 후",
+ past : "%s 전",
+ s : "몇초",
+ ss : "%d초",
+ m : "일분",
+ mm : "%d분",
+ h : "한시간",
+ hh : "%d시간",
+ d : "하루",
+ dd : "%d일",
+ M : "한달",
+ MM : "%d달",
+ y : "일년",
+ yy : "%d년"
+ },
+ ordinal : '%d일',
+ meridiemParse : /(오전|오후)/,
+ isPM : function (token) {
+ return token === "오후";
+ }
+ });
+ }));
- // this edge becomes part of the dynamicEdges of the cluster node
- parentNode.dynamicEdges.push(edge);
- };
+/***/ },
+/* 85 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Luxembourgish (lb)
+ // author : mweimerskirch : https://github.com/mweimerskirch
- /**
- * This function connects an edge that was connected to a cluster node back to the child node.
- *
- * @param parentNode | Node object
- * @param childNode | Node object
- * @private
- */
- exports._connectEdgeBackToChild = function(parentNode, childNode) {
- if (parentNode.reroutedEdges.hasOwnProperty(childNode.id)) {
- for (var i = 0; i < parentNode.reroutedEdges[childNode.id].length; i++) {
- var edge = parentNode.reroutedEdges[childNode.id][i];
- if (edge.originalFromId[edge.originalFromId.length-1] == childNode.id) {
- edge.originalFromId.pop();
- edge.fromId = childNode.id;
- edge.from = childNode;
- }
- else {
- edge.originalToId.pop();
- edge.toId = childNode.id;
- edge.to = childNode;
- }
+ // Note: Luxembourgish has a very particular phonological rule ("Eifeler Regel") that causes the
+ // deletion of the final "n" in certain contexts. That's what the "eifelerRegelAppliesToWeekday"
+ // and "eifelerRegelAppliesToNumber" methods are meant for
- // append this edge to the list of edges connecting to the childnode
- childNode.dynamicEdges.push(edge);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 'm': ['eng Minutt', 'enger Minutt'],
+ 'h': ['eng Stonn', 'enger Stonn'],
+ 'd': ['een Dag', 'engem Dag'],
+ 'dd': [number + ' Deeg', number + ' Deeg'],
+ 'M': ['ee Mount', 'engem Mount'],
+ 'MM': [number + ' Méint', number + ' Méint'],
+ 'y': ['ee Joer', 'engem Joer'],
+ 'yy': [number + ' Joer', number + ' Joer']
+ };
+ return withoutSuffix ? format[key][0] : format[key][1];
+ }
- // remove the edge from the parent object
- for (var j = 0; j < parentNode.dynamicEdges.length; j++) {
- if (parentNode.dynamicEdges[j].id == edge.id) {
- parentNode.dynamicEdges.splice(j,1);
- break;
+ function processFutureTime(string) {
+ var number = string.substr(0, string.indexOf(' '));
+ if (eifelerRegelAppliesToNumber(number)) {
+ return "a " + string;
}
- }
+ return "an " + string;
}
- // remove the entry from the rerouted edges
- delete parentNode.reroutedEdges[childNode.id];
- }
- };
-
- /**
- * When loops are clustered, an edge can be both in the rerouted array and the contained array.
- * This function is called last to verify that all edges in dynamicEdges are in fact connected to the
- * parentNode
- *
- * @param parentNode | Node object
- * @private
- */
- exports._validateEdges = function(parentNode) {
- for (var i = 0; i < parentNode.dynamicEdges.length; i++) {
- var edge = parentNode.dynamicEdges[i];
- if (parentNode.id != edge.toId && parentNode.id != edge.fromId) {
- parentNode.dynamicEdges.splice(i,1);
+ function processPastTime(string) {
+ var number = string.substr(0, string.indexOf(' '));
+ if (eifelerRegelAppliesToNumber(number)) {
+ return "viru " + string;
+ }
+ return "virun " + string;
}
- }
- };
-
-
- /**
- * This function released the contained edges back into the global domain and puts them back into the
- * dynamic edges of both parent and child.
- *
- * @param {Node} parentNode |
- * @param {Node} childNode |
- * @private
- */
- exports._releaseContainedEdges = function(parentNode, childNode) {
- for (var i = 0; i < parentNode.containedEdges[childNode.id].length; i++) {
- var edge = parentNode.containedEdges[childNode.id][i];
-
- // put the edge back in the global edges object
- this.edges[edge.id] = edge;
-
- // put the edge back in the dynamic edges of the child and parent
- childNode.dynamicEdges.push(edge);
- parentNode.dynamicEdges.push(edge);
- }
- // remove the entry from the contained edges
- delete parentNode.containedEdges[childNode.id];
-
- };
-
-
-
-
- // ------------------- UTILITY FUNCTIONS ---------------------------- //
+ function processLastWeek(string1) {
+ var weekday = this.format('d');
+ if (eifelerRegelAppliesToWeekday(weekday)) {
+ return '[Leschte] dddd [um] LT';
+ }
+ return '[Leschten] dddd [um] LT';
+ }
- /**
- * This updates the node labels for all nodes (for debugging purposes)
- */
- exports.updateLabels = function() {
- var nodeId;
- // update node labels
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- var node = this.nodes[nodeId];
- if (node.clusterSize > 1) {
- node.label = "[".concat(String(node.clusterSize),"]");
- }
+ /**
+ * Returns true if the word before the given week day loses the "-n" ending.
+ * e.g. "Leschten Dënschdeg" but "Leschte Méindeg"
+ *
+ * @param weekday {integer}
+ * @returns {boolean}
+ */
+ function eifelerRegelAppliesToWeekday(weekday) {
+ weekday = parseInt(weekday, 10);
+ switch (weekday) {
+ case 0: // Sonndeg
+ case 1: // Méindeg
+ case 3: // Mëttwoch
+ case 5: // Freideg
+ case 6: // Samschdeg
+ return true;
+ default: // 2 Dënschdeg, 4 Donneschdeg
+ return false;
+ }
}
- }
- // update node labels
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- node = this.nodes[nodeId];
- if (node.clusterSize == 1) {
- if (node.originalLabel !== undefined) {
- node.label = node.originalLabel;
+ /**
+ * Returns true if the word before the given number loses the "-n" ending.
+ * e.g. "an 10 Deeg" but "a 5 Deeg"
+ *
+ * @param number {integer}
+ * @returns {boolean}
+ */
+ function eifelerRegelAppliesToNumber(number) {
+ number = parseInt(number, 10);
+ if (isNaN(number)) {
+ return false;
}
- else {
- node.label = String(node.id);
+ if (number < 0) {
+ // Negative Number --> always true
+ return true;
+ } else if (number < 10) {
+ // Only 1 digit
+ if (4 <= number && number <= 7) {
+ return true;
+ }
+ return false;
+ } else if (number < 100) {
+ // 2 digits
+ var lastDigit = number % 10, firstDigit = number / 10;
+ if (lastDigit === 0) {
+ return eifelerRegelAppliesToNumber(firstDigit);
+ }
+ return eifelerRegelAppliesToNumber(lastDigit);
+ } else if (number < 10000) {
+ // 3 or 4 digits --> recursively check first digit
+ while (number >= 10) {
+ number = number / 10;
+ }
+ return eifelerRegelAppliesToNumber(number);
+ } else {
+ // Anything larger than 4 digits: recursively check first n-3 digits
+ number = number / 1000;
+ return eifelerRegelAppliesToNumber(number);
}
- }
}
- }
-
- // /* Debug Override */
- // for (nodeId in this.nodes) {
- // if (this.nodes.hasOwnProperty(nodeId)) {
- // node = this.nodes[nodeId];
- // node.label = String(node.level);
- // }
- // }
- };
+ return moment.lang('lb', {
+ months: "Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
+ monthsShort: "Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
+ weekdays: "Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),
+ weekdaysShort: "So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),
+ weekdaysMin: "So_Mé_Dë_Më_Do_Fr_Sa".split("_"),
+ longDateFormat: {
+ LT: "H:mm [Auer]",
+ L: "DD.MM.YYYY",
+ LL: "D. MMMM YYYY",
+ LLL: "D. MMMM YYYY LT",
+ LLLL: "dddd, D. MMMM YYYY LT"
+ },
+ calendar: {
+ sameDay: "[Haut um] LT",
+ sameElse: "L",
+ nextDay: '[Muer um] LT',
+ nextWeek: 'dddd [um] LT',
+ lastDay: '[Gëschter um] LT',
+ lastWeek: processLastWeek
+ },
+ relativeTime: {
+ future: processFutureTime,
+ past: processPastTime,
+ s: "e puer Sekonnen",
+ m: processRelativeTime,
+ mm: "%d Minutten",
+ h: processRelativeTime,
+ hh: "%d Stonnen",
+ d: processRelativeTime,
+ dd: processRelativeTime,
+ M: processRelativeTime,
+ MM: processRelativeTime,
+ y: processRelativeTime,
+ yy: processRelativeTime
+ },
+ ordinal: '%d.',
+ week: {
+ dow: 1, // Monday is the first day of the week.
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * We want to keep the cluster level distribution rather small. This means we do not want unclustered nodes
- * if the rest of the nodes are already a few cluster levels in.
- * To fix this we use this function. It determines the min and max cluster level and sends nodes that have not
- * clustered enough to the clusterToSmallestNeighbours function.
- */
- exports.normalizeClusterLevels = function() {
- var maxLevel = 0;
- var minLevel = 1e9;
- var clusterLevel = 0;
- var nodeId;
+/***/ },
+/* 86 */
+/***/ function(module, exports, __webpack_require__) {
- // we loop over all nodes in the list
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- clusterLevel = this.nodes[nodeId].clusterSessions.length;
- if (maxLevel < clusterLevel) {maxLevel = clusterLevel;}
- if (minLevel > clusterLevel) {minLevel = clusterLevel;}
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Lithuanian (lt)
+ // author : Mindaugas Mozūras : https://github.com/mmozuras
+
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
+ }(function (moment) {
+ var units = {
+ "m" : "minutė_minutės_minutę",
+ "mm": "minutės_minučių_minutes",
+ "h" : "valanda_valandos_valandą",
+ "hh": "valandos_valandų_valandas",
+ "d" : "diena_dienos_dieną",
+ "dd": "dienos_dienų_dienas",
+ "M" : "mėnuo_mėnesio_mėnesį",
+ "MM": "mėnesiai_mėnesių_mėnesius",
+ "y" : "metai_metų_metus",
+ "yy": "metai_metų_metus"
+ },
+ weekDays = "sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_");
- if (maxLevel - minLevel > this.constants.clustering.clusterLevelDifference) {
- var amountOfNodes = this.nodeIndices.length;
- var targetLevel = maxLevel - this.constants.clustering.clusterLevelDifference;
- // we loop over all nodes in the list
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- if (this.nodes[nodeId].clusterSessions.length < targetLevel) {
- this._clusterToSmallestNeighbour(this.nodes[nodeId]);
+ function translateSeconds(number, withoutSuffix, key, isFuture) {
+ if (withoutSuffix) {
+ return "kelios sekundės";
+ } else {
+ return isFuture ? "kelių sekundžių" : "kelias sekundes";
}
- }
}
- this._updateNodeIndexList();
- this._updateDynamicEdges();
- // if a cluster was formed, we increase the clusterSession
- if (this.nodeIndices.length != amountOfNodes) {
- this.clusterSession += 1;
- }
- }
- };
-
-
-
- /**
- * This function determines if the cluster we want to decluster is in the active area
- * this means around the zoom center
- *
- * @param {Node} node
- * @returns {boolean}
- * @private
- */
- exports._nodeInActiveArea = function(node) {
- return (
- Math.abs(node.x - this.areaCenter.x) <= this.constants.clustering.activeAreaBoxSize/this.scale
- &&
- Math.abs(node.y - this.areaCenter.y) <= this.constants.clustering.activeAreaBoxSize/this.scale
- )
- };
+ function translateSingular(number, withoutSuffix, key, isFuture) {
+ return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
+ }
- /**
- * This is an adaptation of the original repositioning function. This is called if the system is clustered initially
- * It puts large clusters away from the center and randomizes the order.
- *
- */
- exports.repositionNodes = function() {
- for (var i = 0; i < this.nodeIndices.length; i++) {
- var node = this.nodes[this.nodeIndices[i]];
- if ((node.xFixed == false || node.yFixed == false)) {
- var radius = 10 * 0.1*this.nodeIndices.length * Math.min(100,node.mass);
- var angle = 2 * Math.PI * Math.random();
- if (node.xFixed == false) {node.x = radius * Math.cos(angle);}
- if (node.yFixed == false) {node.y = radius * Math.sin(angle);}
- this._repositionBezierNodes(node);
+ function special(number) {
+ return number % 10 === 0 || (number > 10 && number < 20);
}
- }
- };
+ function forms(key) {
+ return units[key].split("_");
+ }
- /**
- * We determine how many connections denote an important hub.
- * We take the mean + 2*std as the important hub size. (Assuming a normal distribution of data, ~2.2%)
- *
- * @private
- */
- exports._getHubSize = function() {
- var average = 0;
- var averageSquared = 0;
- var hubCounter = 0;
- var largestHub = 0;
+ function translate(number, withoutSuffix, key, isFuture) {
+ var result = number + " ";
+ if (number === 1) {
+ return result + translateSingular(number, withoutSuffix, key[0], isFuture);
+ } else if (withoutSuffix) {
+ return result + (special(number) ? forms(key)[1] : forms(key)[0]);
+ } else {
+ if (isFuture) {
+ return result + forms(key)[1];
+ } else {
+ return result + (special(number) ? forms(key)[1] : forms(key)[2]);
+ }
+ }
+ }
- for (var i = 0; i < this.nodeIndices.length; i++) {
+ function relativeWeekDay(moment, format) {
+ var nominative = format.indexOf('dddd HH:mm') === -1,
+ weekDay = weekDays[moment.day()];
- var node = this.nodes[this.nodeIndices[i]];
- if (node.dynamicEdgesLength > largestHub) {
- largestHub = node.dynamicEdgesLength;
+ return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + "į";
}
- average += node.dynamicEdgesLength;
- averageSquared += Math.pow(node.dynamicEdgesLength,2);
- hubCounter += 1;
- }
- average = average / hubCounter;
- averageSquared = averageSquared / hubCounter;
-
- var variance = averageSquared - Math.pow(average,2);
- var standardDeviation = Math.sqrt(variance);
+ return moment.lang("lt", {
+ months : "sausio_vasario_kovo_balandžio_gegužės_biržėlio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),
+ monthsShort : "sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),
+ weekdays : relativeWeekDay,
+ weekdaysShort : "Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),
+ weekdaysMin : "S_P_A_T_K_Pn_Š".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "YYYY-MM-DD",
+ LL : "YYYY [m.] MMMM D [d.]",
+ LLL : "YYYY [m.] MMMM D [d.], LT [val.]",
+ LLLL : "YYYY [m.] MMMM D [d.], dddd, LT [val.]",
+ l : "YYYY-MM-DD",
+ ll : "YYYY [m.] MMMM D [d.]",
+ lll : "YYYY [m.] MMMM D [d.], LT [val.]",
+ llll : "YYYY [m.] MMMM D [d.], ddd, LT [val.]"
+ },
+ calendar : {
+ sameDay : "[Šiandien] LT",
+ nextDay : "[Rytoj] LT",
+ nextWeek : "dddd LT",
+ lastDay : "[Vakar] LT",
+ lastWeek : "[Praėjusį] dddd LT",
+ sameElse : "L"
+ },
+ relativeTime : {
+ future : "po %s",
+ past : "prieš %s",
+ s : translateSeconds,
+ m : translateSingular,
+ mm : translate,
+ h : translateSingular,
+ hh : translate,
+ d : translateSingular,
+ dd : translate,
+ M : translateSingular,
+ MM : translate,
+ y : translateSingular,
+ yy : translate
+ },
+ ordinal : function (number) {
+ return number + '-oji';
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- this.hubThreshold = Math.floor(average + 2*standardDeviation);
- // always have at least one to cluster
- if (this.hubThreshold > largestHub) {
- this.hubThreshold = largestHub;
- }
+/***/ },
+/* 87 */
+/***/ function(module, exports, __webpack_require__) {
- // console.log("average",average,"averageSQ",averageSquared,"var",variance,"std",standardDeviation);
- // console.log("hubThreshold:",this.hubThreshold);
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : latvian (lv)
+ // author : Kristaps Karlsons : https://github.com/skakri
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ var units = {
+ 'mm': 'minūti_minūtes_minūte_minūtes',
+ 'hh': 'stundu_stundas_stunda_stundas',
+ 'dd': 'dienu_dienas_diena_dienas',
+ 'MM': 'mēnesi_mēnešus_mēnesis_mēneši',
+ 'yy': 'gadu_gadus_gads_gadi'
+ };
- /**
- * We reduce the amount of "extension nodes" or chains. These are not quickly clustered with the outliers and hubs methods
- * with this amount we can cluster specifically on these chains.
- *
- * @param {Number} fraction | between 0 and 1, the percentage of chains to reduce
- * @private
- */
- exports._reduceAmountOfChains = function(fraction) {
- this.hubThreshold = 2;
- var reduceAmount = Math.floor(this.nodeIndices.length * fraction);
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- if (this.nodes[nodeId].dynamicEdgesLength == 2 && this.nodes[nodeId].dynamicEdges.length >= 2) {
- if (reduceAmount > 0) {
- this._formClusterFromHub(this.nodes[nodeId],true,true,1);
- reduceAmount -= 1;
+ function format(word, number, withoutSuffix) {
+ var forms = word.split('_');
+ if (withoutSuffix) {
+ return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];
+ } else {
+ return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];
}
- }
}
- }
- };
- /**
- * We get the amount of "extension nodes" or chains. These are not quickly clustered with the outliers and hubs methods
- * with this amount we can cluster specifically on these chains.
- *
- * @private
- */
- exports._getChainFraction = function() {
- var chains = 0;
- var total = 0;
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- if (this.nodes[nodeId].dynamicEdgesLength == 2 && this.nodes[nodeId].dynamicEdges.length >= 2) {
- chains += 1;
- }
- total += 1;
+ function relativeTimeWithPlural(number, withoutSuffix, key) {
+ return number + ' ' + format(units[key], number, withoutSuffix);
}
- }
- return chains/total;
- };
+
+ return moment.lang('lv', {
+ months : "janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),
+ monthsShort : "jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),
+ weekdays : "svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),
+ weekdaysShort : "Sv_P_O_T_C_Pk_S".split("_"),
+ weekdaysMin : "Sv_P_O_T_C_Pk_S".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "YYYY. [gada] D. MMMM",
+ LLL : "YYYY. [gada] D. MMMM, LT",
+ LLLL : "YYYY. [gada] D. MMMM, dddd, LT"
+ },
+ calendar : {
+ sameDay : '[Šodien pulksten] LT',
+ nextDay : '[Rīt pulksten] LT',
+ nextWeek : 'dddd [pulksten] LT',
+ lastDay : '[Vakar pulksten] LT',
+ lastWeek : '[Pagājušā] dddd [pulksten] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s vēlāk",
+ past : "%s agrāk",
+ s : "dažas sekundes",
+ m : "minūti",
+ mm : relativeTimeWithPlural,
+ h : "stundu",
+ hh : relativeTimeWithPlural,
+ d : "dienu",
+ dd : relativeTimeWithPlural,
+ M : "mēnesi",
+ MM : relativeTimeWithPlural,
+ y : "gadu",
+ yy : relativeTimeWithPlural
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
/***/ },
-/* 48 */
+/* 88 */
/***/ function(module, exports, __webpack_require__) {
- var util = __webpack_require__(1);
-
- /**
- * Creation of the SectorMixin var.
- *
- * This contains all the functions the Network object can use to employ the sector system.
- * The sector system is always used by Network, though the benefits only apply to the use of clustering.
- * If clustering is not used, there is no overhead except for a duplicate object with references to nodes and edges.
- */
-
- /**
- * This function is only called by the setData function of the Network object.
- * This loads the global references into the active sector. This initializes the sector.
- *
- * @private
- */
- exports._putDataInSector = function() {
- this.sectors["active"][this._sector()].nodes = this.nodes;
- this.sectors["active"][this._sector()].edges = this.edges;
- this.sectors["active"][this._sector()].nodeIndices = this.nodeIndices;
- };
-
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : macedonian (mk)
+ // author : Borislav Mickov : https://github.com/B0k0
- /**
- * /**
- * This function sets the global references to nodes, edges and nodeIndices back to
- * those of the supplied (active) sector. If a type is defined, do the specific type
- *
- * @param {String} sectorId
- * @param {String} [sectorType] | "active" or "frozen"
- * @private
- */
- exports._switchToSector = function(sectorId, sectorType) {
- if (sectorType === undefined || sectorType == "active") {
- this._switchToActiveSector(sectorId);
- }
- else {
- this._switchToFrozenSector(sectorId);
- }
- };
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('mk', {
+ months : "јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),
+ monthsShort : "јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),
+ weekdays : "недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),
+ weekdaysShort : "нед_пон_вто_сре_чет_пет_саб".split("_"),
+ weekdaysMin : "нe_пo_вт_ср_че_пе_сa".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "D.MM.YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Денес во] LT',
+ nextDay : '[Утре во] LT',
+ nextWeek : 'dddd [во] LT',
+ lastDay : '[Вчера во] LT',
+ lastWeek : function () {
+ switch (this.day()) {
+ case 0:
+ case 3:
+ case 6:
+ return '[Во изминатата] dddd [во] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[Во изминатиот] dddd [во] LT';
+ }
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "после %s",
+ past : "пред %s",
+ s : "неколку секунди",
+ m : "минута",
+ mm : "%d минути",
+ h : "час",
+ hh : "%d часа",
+ d : "ден",
+ dd : "%d дена",
+ M : "месец",
+ MM : "%d месеци",
+ y : "година",
+ yy : "%d години"
+ },
+ ordinal : function (number) {
+ var lastDigit = number % 10,
+ last2Digits = number % 100;
+ if (number === 0) {
+ return number + '-ев';
+ } else if (last2Digits === 0) {
+ return number + '-ен';
+ } else if (last2Digits > 10 && last2Digits < 20) {
+ return number + '-ти';
+ } else if (lastDigit === 1) {
+ return number + '-ви';
+ } else if (lastDigit === 2) {
+ return number + '-ри';
+ } else if (lastDigit === 7 || lastDigit === 8) {
+ return number + '-ми';
+ } else {
+ return number + '-ти';
+ }
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * This function sets the global references to nodes, edges and nodeIndices back to
- * those of the supplied active sector.
- *
- * @param sectorId
- * @private
- */
- exports._switchToActiveSector = function(sectorId) {
- this.nodeIndices = this.sectors["active"][sectorId]["nodeIndices"];
- this.nodes = this.sectors["active"][sectorId]["nodes"];
- this.edges = this.sectors["active"][sectorId]["edges"];
- };
+/***/ },
+/* 89 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : malayalam (ml)
+ // author : Floyd Pink : https://github.com/floydpink
- /**
- * This function sets the global references to nodes, edges and nodeIndices back to
- * those of the supplied active sector.
- *
- * @private
- */
- exports._switchToSupportSector = function() {
- this.nodeIndices = this.sectors["support"]["nodeIndices"];
- this.nodes = this.sectors["support"]["nodes"];
- this.edges = this.sectors["support"]["edges"];
- };
-
-
- /**
- * This function sets the global references to nodes, edges and nodeIndices back to
- * those of the supplied frozen sector.
- *
- * @param sectorId
- * @private
- */
- exports._switchToFrozenSector = function(sectorId) {
- this.nodeIndices = this.sectors["frozen"][sectorId]["nodeIndices"];
- this.nodes = this.sectors["frozen"][sectorId]["nodes"];
- this.edges = this.sectors["frozen"][sectorId]["edges"];
- };
-
-
- /**
- * This function sets the global references to nodes, edges and nodeIndices back to
- * those of the currently active sector.
- *
- * @private
- */
- exports._loadLatestSector = function() {
- this._switchToSector(this._sector());
- };
-
-
- /**
- * This function returns the currently active sector Id
- *
- * @returns {String}
- * @private
- */
- exports._sector = function() {
- return this.activeSector[this.activeSector.length-1];
- };
-
-
- /**
- * This function returns the previously active sector Id
- *
- * @returns {String}
- * @private
- */
- exports._previousSector = function() {
- if (this.activeSector.length > 1) {
- return this.activeSector[this.activeSector.length-2];
- }
- else {
- throw new TypeError('there are not enough sectors in the this.activeSector array.');
- }
- };
-
-
- /**
- * We add the active sector at the end of the this.activeSector array
- * This ensures it is the currently active sector returned by _sector() and it reaches the top
- * of the activeSector stack. When we reverse our steps we move from the end to the beginning of this stack.
- *
- * @param newId
- * @private
- */
- exports._setActiveSector = function(newId) {
- this.activeSector.push(newId);
- };
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('ml', {
+ months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split("_"),
+ monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split("_"),
+ weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split("_"),
+ weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split("_"),
+ weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split("_"),
+ longDateFormat : {
+ LT : "A h:mm -നു",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY, LT",
+ LLLL : "dddd, D MMMM YYYY, LT"
+ },
+ calendar : {
+ sameDay : '[ഇന്ന്] LT',
+ nextDay : '[നാളെ] LT',
+ nextWeek : 'dddd, LT',
+ lastDay : '[ഇന്നലെ] LT',
+ lastWeek : '[കഴിഞ്ഞ] dddd, LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s കഴിഞ്ഞ്",
+ past : "%s മുൻപ്",
+ s : "അൽപ നിമിഷങ്ങൾ",
+ m : "ഒരു മിനിറ്റ്",
+ mm : "%d മിനിറ്റ്",
+ h : "ഒരു മണിക്കൂർ",
+ hh : "%d മണിക്കൂർ",
+ d : "ഒരു ദിവസം",
+ dd : "%d ദിവസം",
+ M : "ഒരു മാസം",
+ MM : "%d മാസം",
+ y : "ഒരു വർഷം",
+ yy : "%d വർഷം"
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 4) {
+ return "രാത്രി";
+ } else if (hour < 12) {
+ return "രാവിലെ";
+ } else if (hour < 17) {
+ return "ഉച്ച കഴിഞ്ഞ്";
+ } else if (hour < 20) {
+ return "വൈകുന്നേരം";
+ } else {
+ return "രാത്രി";
+ }
+ }
+ });
+ }));
- /**
- * We remove the currently active sector id from the active sector stack. This happens when
- * we reactivate the previously active sector
- *
- * @private
- */
- exports._forgetLastSector = function() {
- this.activeSector.pop();
- };
+/***/ },
+/* 90 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Marathi (mr)
+ // author : Harshad Kale : https://github.com/kalehv
- /**
- * This function creates a new active sector with the supplied newId. This newId
- * is the expanding node id.
- *
- * @param {String} newId | Id of the new active sector
- * @private
- */
- exports._createNewSector = function(newId) {
- // create the new sector
- this.sectors["active"][newId] = {"nodes":{},
- "edges":{},
- "nodeIndices":[],
- "formationScale": this.scale,
- "drawingNode": undefined};
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ var symbolMap = {
+ '1': '१',
+ '2': '२',
+ '3': '३',
+ '4': '४',
+ '5': '५',
+ '6': '६',
+ '7': '७',
+ '8': '८',
+ '9': '९',
+ '0': '०'
+ },
+ numberMap = {
+ '१': '1',
+ '२': '2',
+ '३': '3',
+ '४': '4',
+ '५': '5',
+ '६': '6',
+ '७': '7',
+ '८': '8',
+ '९': '9',
+ '०': '0'
+ };
- // create the new sector render node. This gives visual feedback that you are in a new sector.
- this.sectors["active"][newId]['drawingNode'] = new Node(
- {id:newId,
- color: {
- background: "#eaefef",
- border: "495c5e"
+ return moment.lang('mr', {
+ months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split("_"),
+ monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split("_"),
+ weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"),
+ weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split("_"),
+ weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"),
+ longDateFormat : {
+ LT : "A h:mm वाजता",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY, LT",
+ LLLL : "dddd, D MMMM YYYY, LT"
+ },
+ calendar : {
+ sameDay : '[आज] LT',
+ nextDay : '[उद्या] LT',
+ nextWeek : 'dddd, LT',
+ lastDay : '[काल] LT',
+ lastWeek: '[मागील] dddd, LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s नंतर",
+ past : "%s पूर्वी",
+ s : "सेकंद",
+ m: "एक मिनिट",
+ mm: "%d मिनिटे",
+ h : "एक तास",
+ hh : "%d तास",
+ d : "एक दिवस",
+ dd : "%d दिवस",
+ M : "एक महिना",
+ MM : "%d महिने",
+ y : "एक वर्ष",
+ yy : "%d वर्षे"
+ },
+ preparse: function (string) {
+ return string.replace(/[१२३४५६७८९०]/g, function (match) {
+ return numberMap[match];
+ });
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ });
+ },
+ meridiem: function (hour, minute, isLower)
+ {
+ if (hour < 4) {
+ return "रात्री";
+ } else if (hour < 10) {
+ return "सकाळी";
+ } else if (hour < 17) {
+ return "दुपारी";
+ } else if (hour < 20) {
+ return "सायंकाळी";
+ } else {
+ return "रात्री";
+ }
+ },
+ week : {
+ dow : 0, // Sunday is the first day of the week.
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
}
- },{},{},this.constants);
- this.sectors["active"][newId]['drawingNode'].clusterSize = 2;
- };
-
+ });
+ }));
- /**
- * This function removes the currently active sector. This is called when we create a new
- * active sector.
- *
- * @param {String} sectorId | Id of the active sector that will be removed
- * @private
- */
- exports._deleteActiveSector = function(sectorId) {
- delete this.sectors["active"][sectorId];
- };
+/***/ },
+/* 91 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This function removes the currently active sector. This is called when we reactivate
- * the previously active sector.
- *
- * @param {String} sectorId | Id of the active sector that will be removed
- * @private
- */
- exports._deleteFrozenSector = function(sectorId) {
- delete this.sectors["frozen"][sectorId];
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Bahasa Malaysia (ms-MY)
+ // author : Weldan Jamili : https://github.com/weldan
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('ms-my', {
+ months : "Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),
+ monthsShort : "Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),
+ weekdays : "Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),
+ weekdaysShort : "Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),
+ weekdaysMin : "Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),
+ longDateFormat : {
+ LT : "HH.mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY [pukul] LT",
+ LLLL : "dddd, D MMMM YYYY [pukul] LT"
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours < 11) {
+ return 'pagi';
+ } else if (hours < 15) {
+ return 'tengahari';
+ } else if (hours < 19) {
+ return 'petang';
+ } else {
+ return 'malam';
+ }
+ },
+ calendar : {
+ sameDay : '[Hari ini pukul] LT',
+ nextDay : '[Esok pukul] LT',
+ nextWeek : 'dddd [pukul] LT',
+ lastDay : '[Kelmarin pukul] LT',
+ lastWeek : 'dddd [lepas pukul] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "dalam %s",
+ past : "%s yang lepas",
+ s : "beberapa saat",
+ m : "seminit",
+ mm : "%d minit",
+ h : "sejam",
+ hh : "%d jam",
+ d : "sehari",
+ dd : "%d hari",
+ M : "sebulan",
+ MM : "%d bulan",
+ y : "setahun",
+ yy : "%d tahun"
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * Freezing an active sector means moving it from the "active" object to the "frozen" object.
- * We copy the references, then delete the active entree.
- *
- * @param sectorId
- * @private
- */
- exports._freezeSector = function(sectorId) {
- // we move the set references from the active to the frozen stack.
- this.sectors["frozen"][sectorId] = this.sectors["active"][sectorId];
- // we have moved the sector data into the frozen set, we now remove it from the active set
- this._deleteActiveSector(sectorId);
- };
+/***/ },
+/* 92 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : norwegian bokmål (nb)
+ // authors : Espen Hovlandsdal : https://github.com/rexxars
+ // Sigurd Gartmann : https://github.com/sigurdga
- /**
- * This is the reverse operation of _freezeSector. Activating means moving the sector from the "frozen"
- * object to the "active" object.
- *
- * @param sectorId
- * @private
- */
- exports._activateSector = function(sectorId) {
- // we move the set references from the frozen to the active stack.
- this.sectors["active"][sectorId] = this.sectors["frozen"][sectorId];
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('nb', {
+ months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),
+ monthsShort : "jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),
+ weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),
+ weekdaysShort : "sø._ma._ti._on._to._fr._lø.".split("_"),
+ weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"),
+ longDateFormat : {
+ LT : "H.mm",
+ L : "DD.MM.YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY [kl.] LT",
+ LLLL : "dddd D. MMMM YYYY [kl.] LT"
+ },
+ calendar : {
+ sameDay: '[i dag kl.] LT',
+ nextDay: '[i morgen kl.] LT',
+ nextWeek: 'dddd [kl.] LT',
+ lastDay: '[i går kl.] LT',
+ lastWeek: '[forrige] dddd [kl.] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "om %s",
+ past : "for %s siden",
+ s : "noen sekunder",
+ m : "ett minutt",
+ mm : "%d minutter",
+ h : "en time",
+ hh : "%d timer",
+ d : "en dag",
+ dd : "%d dager",
+ M : "en måned",
+ MM : "%d måneder",
+ y : "ett år",
+ yy : "%d år"
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- // we have moved the sector data into the active set, we now remove it from the frozen stack
- this._deleteFrozenSector(sectorId);
- };
+/***/ },
+/* 93 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This function merges the data from the currently active sector with a frozen sector. This is used
- * in the process of reverting back to the previously active sector.
- * The data that is placed in the frozen (the previously active) sector is the node that has been removed from it
- * upon the creation of a new active sector.
- *
- * @param sectorId
- * @private
- */
- exports._mergeThisWithFrozen = function(sectorId) {
- // copy all nodes
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- this.sectors["frozen"][sectorId]["nodes"][nodeId] = this.nodes[nodeId];
- }
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : nepali/nepalese
+ // author : suvash : https://github.com/suvash
- // copy all edges (if not fully clustered, else there are no edges)
- for (var edgeId in this.edges) {
- if (this.edges.hasOwnProperty(edgeId)) {
- this.sectors["frozen"][sectorId]["edges"][edgeId] = this.edges[edgeId];
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
-
- // merge the nodeIndices
- for (var i = 0; i < this.nodeIndices.length; i++) {
- this.sectors["frozen"][sectorId]["nodeIndices"].push(this.nodeIndices[i]);
- }
- };
+ }(function (moment) {
+ var symbolMap = {
+ '1': '१',
+ '2': '२',
+ '3': '३',
+ '4': '४',
+ '5': '५',
+ '6': '६',
+ '7': '७',
+ '8': '८',
+ '9': '९',
+ '0': '०'
+ },
+ numberMap = {
+ '१': '1',
+ '२': '2',
+ '३': '3',
+ '४': '4',
+ '५': '5',
+ '६': '6',
+ '७': '7',
+ '८': '8',
+ '९': '9',
+ '०': '0'
+ };
+ return moment.lang('ne', {
+ months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split("_"),
+ monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split("_"),
+ weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split("_"),
+ weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split("_"),
+ weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split("_"),
+ longDateFormat : {
+ LT : "Aको h:mm बजे",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY, LT",
+ LLLL : "dddd, D MMMM YYYY, LT"
+ },
+ preparse: function (string) {
+ return string.replace(/[१२३४५६७८९०]/g, function (match) {
+ return numberMap[match];
+ });
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ });
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 3) {
+ return "राती";
+ } else if (hour < 10) {
+ return "बिहान";
+ } else if (hour < 15) {
+ return "दिउँसो";
+ } else if (hour < 18) {
+ return "बेलुका";
+ } else if (hour < 20) {
+ return "साँझ";
+ } else {
+ return "राती";
+ }
+ },
+ calendar : {
+ sameDay : '[आज] LT',
+ nextDay : '[भोली] LT',
+ nextWeek : '[आउँदो] dddd[,] LT',
+ lastDay : '[हिजो] LT',
+ lastWeek : '[गएको] dddd[,] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%sमा",
+ past : "%s अगाडी",
+ s : "केही समय",
+ m : "एक मिनेट",
+ mm : "%d मिनेट",
+ h : "एक घण्टा",
+ hh : "%d घण्टा",
+ d : "एक दिन",
+ dd : "%d दिन",
+ M : "एक महिना",
+ MM : "%d महिना",
+ y : "एक बर्ष",
+ yy : "%d बर्ष"
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * This clusters the sector to one cluster. It was a single cluster before this process started so
- * we revert to that state. The clusterToFit function with a maximum size of 1 node does this.
- *
- * @private
- */
- exports._collapseThisToSingleCluster = function() {
- this.clusterToFit(1,false);
- };
+/***/ },
+/* 94 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * We create a new active sector from the node that we want to open.
- *
- * @param node
- * @private
- */
- exports._addSector = function(node) {
- // this is the currently active sector
- var sector = this._sector();
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : dutch (nl)
+ // author : Joris Röling : https://github.com/jjupiter
- // // this should allow me to select nodes from a frozen set.
- // if (this.sectors['active'][sector]["nodes"].hasOwnProperty(node.id)) {
- // console.log("the node is part of the active sector");
- // }
- // else {
- // console.log("I dont know what the fuck happened!!");
- // }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ var monthsShortWithDots = "jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),
+ monthsShortWithoutDots = "jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_");
- // when we switch to a new sector, we remove the node that will be expanded from the current nodes list.
- delete this.nodes[node.id];
+ return moment.lang('nl', {
+ months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),
+ monthsShort : function (m, format) {
+ if (/-MMM-/.test(format)) {
+ return monthsShortWithoutDots[m.month()];
+ } else {
+ return monthsShortWithDots[m.month()];
+ }
+ },
+ weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),
+ weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"),
+ weekdaysMin : "Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD-MM-YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: '[vandaag om] LT',
+ nextDay: '[morgen om] LT',
+ nextWeek: 'dddd [om] LT',
+ lastDay: '[gisteren om] LT',
+ lastWeek: '[afgelopen] dddd [om] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "over %s",
+ past : "%s geleden",
+ s : "een paar seconden",
+ m : "één minuut",
+ mm : "%d minuten",
+ h : "één uur",
+ hh : "%d uur",
+ d : "één dag",
+ dd : "%d dagen",
+ M : "één maand",
+ MM : "%d maanden",
+ y : "één jaar",
+ yy : "%d jaar"
+ },
+ ordinal : function (number) {
+ return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- var unqiueIdentifier = util.randomUUID();
- // we fully freeze the currently active sector
- this._freezeSector(sector);
+/***/ },
+/* 95 */
+/***/ function(module, exports, __webpack_require__) {
- // we create a new active sector. This sector has the Id of the node to ensure uniqueness
- this._createNewSector(unqiueIdentifier);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : norwegian nynorsk (nn)
+ // author : https://github.com/mechuwind
- // we add the active sector to the sectors array to be able to revert these steps later on
- this._setActiveSector(unqiueIdentifier);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('nn', {
+ months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),
+ monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),
+ weekdays : "sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),
+ weekdaysShort : "sun_mån_tys_ons_tor_fre_lau".split("_"),
+ weekdaysMin : "su_må_ty_on_to_fr_lø".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: '[I dag klokka] LT',
+ nextDay: '[I morgon klokka] LT',
+ nextWeek: 'dddd [klokka] LT',
+ lastDay: '[I går klokka] LT',
+ lastWeek: '[Føregåande] dddd [klokka] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "om %s",
+ past : "for %s sidan",
+ s : "nokre sekund",
+ m : "eit minutt",
+ mm : "%d minutt",
+ h : "ein time",
+ hh : "%d timar",
+ d : "ein dag",
+ dd : "%d dagar",
+ M : "ein månad",
+ MM : "%d månader",
+ y : "eit år",
+ yy : "%d år"
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- // we redirect the global references to the new sector's references. this._sector() now returns unqiueIdentifier
- this._switchToSector(this._sector());
- // finally we add the node we removed from our previous active sector to the new active sector
- this.nodes[node.id] = node;
- };
+/***/ },
+/* 96 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : polish (pl)
+ // author : Rafal Hirsz : https://github.com/evoL
- /**
- * We close the sector that is currently open and revert back to the one before.
- * If the active sector is the "default" sector, nothing happens.
- *
- * @private
- */
- exports._collapseSector = function() {
- // the currently active sector
- var sector = this._sector();
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ var monthsNominative = "styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),
+ monthsSubjective = "stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_");
- // we cannot collapse the default sector
- if (sector != "default") {
- if ((this.nodeIndices.length == 1) ||
- (this.sectors["active"][sector]["drawingNode"].width*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientWidth) ||
- (this.sectors["active"][sector]["drawingNode"].height*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientHeight)) {
- var previousSector = this._previousSector();
+ function plural(n) {
+ return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);
+ }
- // we collapse the sector back to a single cluster
- this._collapseThisToSingleCluster();
+ function translate(number, withoutSuffix, key) {
+ var result = number + " ";
+ switch (key) {
+ case 'm':
+ return withoutSuffix ? 'minuta' : 'minutę';
+ case 'mm':
+ return result + (plural(number) ? 'minuty' : 'minut');
+ case 'h':
+ return withoutSuffix ? 'godzina' : 'godzinę';
+ case 'hh':
+ return result + (plural(number) ? 'godziny' : 'godzin');
+ case 'MM':
+ return result + (plural(number) ? 'miesiące' : 'miesięcy');
+ case 'yy':
+ return result + (plural(number) ? 'lata' : 'lat');
+ }
+ }
- // we move the remaining nodes, edges and nodeIndices to the previous sector.
- // This previous sector is the one we will reactivate
- this._mergeThisWithFrozen(previousSector);
+ return moment.lang('pl', {
+ months : function (momentToFormat, format) {
+ if (/D MMMM/.test(format)) {
+ return monthsSubjective[momentToFormat.month()];
+ } else {
+ return monthsNominative[momentToFormat.month()];
+ }
+ },
+ monthsShort : "sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),
+ weekdays : "niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),
+ weekdaysShort : "nie_pon_wt_śr_czw_pt_sb".split("_"),
+ weekdaysMin : "N_Pn_Wt_Śr_Cz_Pt_So".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: '[Dziś o] LT',
+ nextDay: '[Jutro o] LT',
+ nextWeek: '[W] dddd [o] LT',
+ lastDay: '[Wczoraj o] LT',
+ lastWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[W zeszłą niedzielę o] LT';
+ case 3:
+ return '[W zeszłą środę o] LT';
+ case 6:
+ return '[W zeszłą sobotę o] LT';
+ default:
+ return '[W zeszły] dddd [o] LT';
+ }
+ },
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "za %s",
+ past : "%s temu",
+ s : "kilka sekund",
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : "1 dzień",
+ dd : '%d dni',
+ M : "miesiąc",
+ MM : translate,
+ y : "rok",
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- // the previously active (frozen) sector now has all the data from the currently active sector.
- // we can now delete the active sector.
- this._deleteActiveSector(sector);
- // we activate the previously active (and currently frozen) sector.
- this._activateSector(previousSector);
+/***/ },
+/* 97 */
+/***/ function(module, exports, __webpack_require__) {
- // we load the references from the newly active sector into the global references
- this._switchToSector(previousSector);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : brazilian portuguese (pt-br)
+ // author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
- // we forget the previously active sector because we reverted to the one before
- this._forgetLastSector();
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('pt-br', {
+ months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),
+ monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),
+ weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),
+ weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"),
+ weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D [de] MMMM [de] YYYY",
+ LLL : "D [de] MMMM [de] YYYY [às] LT",
+ LLLL : "dddd, D [de] MMMM [de] YYYY [às] LT"
+ },
+ calendar : {
+ sameDay: '[Hoje às] LT',
+ nextDay: '[Amanhã às] LT',
+ nextWeek: 'dddd [às] LT',
+ lastDay: '[Ontem às] LT',
+ lastWeek: function () {
+ return (this.day() === 0 || this.day() === 6) ?
+ '[Último] dddd [às] LT' : // Saturday + Sunday
+ '[Última] dddd [às] LT'; // Monday - Friday
+ },
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "em %s",
+ past : "%s atrás",
+ s : "segundos",
+ m : "um minuto",
+ mm : "%d minutos",
+ h : "uma hora",
+ hh : "%d horas",
+ d : "um dia",
+ dd : "%d dias",
+ M : "um mês",
+ MM : "%d meses",
+ y : "um ano",
+ yy : "%d anos"
+ },
+ ordinal : '%dº'
+ });
+ }));
- // finally, we update the node index list.
- this._updateNodeIndexList();
- // we refresh the list with calulation nodes and calculation node indices.
- this._updateCalculationNodes();
- }
- }
- };
+/***/ },
+/* 98 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : portuguese (pt)
+ // author : Jefferson : https://github.com/jalex79
- /**
- * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation().
- *
- * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
- * | we dont pass the function itself because then the "this" is the window object
- * | instead of the Network object
- * @param {*} [argument] | Optional: arguments to pass to the runFunction
- * @private
- */
- exports._doInAllActiveSectors = function(runFunction,argument) {
- if (argument === undefined) {
- for (var sector in this.sectors["active"]) {
- if (this.sectors["active"].hasOwnProperty(sector)) {
- // switch the global references to those of this sector
- this._switchToActiveSector(sector);
- this[runFunction]();
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- else {
- for (var sector in this.sectors["active"]) {
- if (this.sectors["active"].hasOwnProperty(sector)) {
- // switch the global references to those of this sector
- this._switchToActiveSector(sector);
- var args = Array.prototype.splice.call(arguments, 1);
- if (args.length > 1) {
- this[runFunction](args[0],args[1]);
- }
- else {
- this[runFunction](argument);
+ }(function (moment) {
+ return moment.lang('pt', {
+ months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),
+ monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),
+ weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),
+ weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"),
+ weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D [de] MMMM [de] YYYY",
+ LLL : "D [de] MMMM [de] YYYY LT",
+ LLLL : "dddd, D [de] MMMM [de] YYYY LT"
+ },
+ calendar : {
+ sameDay: '[Hoje às] LT',
+ nextDay: '[Amanhã às] LT',
+ nextWeek: 'dddd [às] LT',
+ lastDay: '[Ontem às] LT',
+ lastWeek: function () {
+ return (this.day() === 0 || this.day() === 6) ?
+ '[Último] dddd [às] LT' : // Saturday + Sunday
+ '[Última] dddd [às] LT'; // Monday - Friday
+ },
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "em %s",
+ past : "há %s",
+ s : "segundos",
+ m : "um minuto",
+ mm : "%d minutos",
+ h : "uma hora",
+ hh : "%d horas",
+ d : "um dia",
+ dd : "%d dias",
+ M : "um mês",
+ MM : "%d meses",
+ y : "um ano",
+ yy : "%d anos"
+ },
+ ordinal : '%dº',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
}
- }
- }
- }
- // we revert the global references back to our active sector
- this._loadLatestSector();
- };
+ });
+ }));
- /**
- * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation().
- *
- * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
- * | we dont pass the function itself because then the "this" is the window object
- * | instead of the Network object
- * @param {*} [argument] | Optional: arguments to pass to the runFunction
- * @private
- */
- exports._doInSupportSector = function(runFunction,argument) {
- if (argument === undefined) {
- this._switchToSupportSector();
- this[runFunction]();
- }
- else {
- this._switchToSupportSector();
- var args = Array.prototype.splice.call(arguments, 1);
- if (args.length > 1) {
- this[runFunction](args[0],args[1]);
- }
- else {
- this[runFunction](argument);
- }
- }
- // we revert the global references back to our active sector
- this._loadLatestSector();
- };
+/***/ },
+/* 99 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : romanian (ro)
+ // author : Vlad Gurdiga : https://github.com/gurdiga
+ // author : Valentin Agachi : https://github.com/avaly
- /**
- * This runs a function in all frozen sectors. This is used in the _redraw().
- *
- * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
- * | we don't pass the function itself because then the "this" is the window object
- * | instead of the Network object
- * @param {*} [argument] | Optional: arguments to pass to the runFunction
- * @private
- */
- exports._doInAllFrozenSectors = function(runFunction,argument) {
- if (argument === undefined) {
- for (var sector in this.sectors["frozen"]) {
- if (this.sectors["frozen"].hasOwnProperty(sector)) {
- // switch the global references to those of this sector
- this._switchToFrozenSector(sector);
- this[runFunction]();
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- else {
- for (var sector in this.sectors["frozen"]) {
- if (this.sectors["frozen"].hasOwnProperty(sector)) {
- // switch the global references to those of this sector
- this._switchToFrozenSector(sector);
- var args = Array.prototype.splice.call(arguments, 1);
- if (args.length > 1) {
- this[runFunction](args[0],args[1]);
- }
- else {
- this[runFunction](argument);
+ }(function (moment) {
+ function relativeTimeWithPlural(number, withoutSuffix, key) {
+ var format = {
+ 'mm': 'minute',
+ 'hh': 'ore',
+ 'dd': 'zile',
+ 'MM': 'luni',
+ 'yy': 'ani'
+ },
+ separator = ' ';
+ if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
+ separator = ' de ';
}
- }
- }
- }
- this._loadLatestSector();
- };
-
- /**
- * This runs a function in all sectors. This is used in the _redraw().
- *
- * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
- * | we don't pass the function itself because then the "this" is the window object
- * | instead of the Network object
- * @param {*} [argument] | Optional: arguments to pass to the runFunction
- * @private
- */
- exports._doInAllSectors = function(runFunction,argument) {
- var args = Array.prototype.splice.call(arguments, 1);
- if (argument === undefined) {
- this._doInAllActiveSectors(runFunction);
- this._doInAllFrozenSectors(runFunction);
- }
- else {
- if (args.length > 1) {
- this._doInAllActiveSectors(runFunction,args[0],args[1]);
- this._doInAllFrozenSectors(runFunction,args[0],args[1]);
- }
- else {
- this._doInAllActiveSectors(runFunction,argument);
- this._doInAllFrozenSectors(runFunction,argument);
+ return number + separator + format[key];
}
- }
- };
-
-
- /**
- * This clears the nodeIndices list. We cannot use this.nodeIndices = [] because we would break the link with the
- * active sector. Thus we clear the nodeIndices in the active sector, then reconnect the this.nodeIndices to it.
- *
- * @private
- */
- exports._clearNodeIndexList = function() {
- var sector = this._sector();
- this.sectors["active"][sector]["nodeIndices"] = [];
- this.nodeIndices = this.sectors["active"][sector]["nodeIndices"];
- };
-
-
- /**
- * Draw the encompassing sector node
- *
- * @param ctx
- * @param sectorType
- * @private
- */
- exports._drawSectorNodes = function(ctx,sectorType) {
- var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node;
- for (var sector in this.sectors[sectorType]) {
- if (this.sectors[sectorType].hasOwnProperty(sector)) {
- if (this.sectors[sectorType][sector]["drawingNode"] !== undefined) {
- this._switchToSector(sector,sectorType);
-
- minY = 1e9; maxY = -1e9; minX = 1e9; maxX = -1e9;
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- node = this.nodes[nodeId];
- node.resize(ctx);
- if (minX > node.x - 0.5 * node.width) {minX = node.x - 0.5 * node.width;}
- if (maxX < node.x + 0.5 * node.width) {maxX = node.x + 0.5 * node.width;}
- if (minY > node.y - 0.5 * node.height) {minY = node.y - 0.5 * node.height;}
- if (maxY < node.y + 0.5 * node.height) {maxY = node.y + 0.5 * node.height;}
- }
+ return moment.lang('ro', {
+ months : "ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),
+ monthsShort : "ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),
+ weekdays : "duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),
+ weekdaysShort : "Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),
+ weekdaysMin : "Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY H:mm",
+ LLLL : "dddd, D MMMM YYYY H:mm"
+ },
+ calendar : {
+ sameDay: "[azi la] LT",
+ nextDay: '[mâine la] LT',
+ nextWeek: 'dddd [la] LT',
+ lastDay: '[ieri la] LT',
+ lastWeek: '[fosta] dddd [la] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "peste %s",
+ past : "%s în urmă",
+ s : "câteva secunde",
+ m : "un minut",
+ mm : relativeTimeWithPlural,
+ h : "o oră",
+ hh : relativeTimeWithPlural,
+ d : "o zi",
+ dd : relativeTimeWithPlural,
+ M : "o lună",
+ MM : relativeTimeWithPlural,
+ y : "un an",
+ yy : relativeTimeWithPlural
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
}
- node = this.sectors[sectorType][sector]["drawingNode"];
- node.x = 0.5 * (maxX + minX);
- node.y = 0.5 * (maxY + minY);
- node.width = 2 * (node.x - minX);
- node.height = 2 * (node.y - minY);
- node.radius = Math.sqrt(Math.pow(0.5*node.width,2) + Math.pow(0.5*node.height,2));
- node.setScale(this.scale);
- node._drawCircle(ctx);
- }
- }
- }
- };
-
- exports._drawAllSectorNodes = function(ctx) {
- this._drawSectorNodes(ctx,"frozen");
- this._drawSectorNodes(ctx,"active");
- this._loadLatestSector();
- };
+ });
+ }));
/***/ },
-/* 49 */
+/* 100 */
/***/ function(module, exports, __webpack_require__) {
- var Node = __webpack_require__(42);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : russian (ru)
+ // author : Viktorminator : https://github.com/Viktorminator
+ // Author : Menelion Elensúle : https://github.com/Oire
- /**
- * This function can be called from the _doInAllSectors function
- *
- * @param object
- * @param overlappingNodes
- * @private
- */
- exports._getNodesOverlappingWith = function(object, overlappingNodes) {
- var nodes = this.nodes;
- for (var nodeId in nodes) {
- if (nodes.hasOwnProperty(nodeId)) {
- if (nodes[nodeId].isOverlappingWith(object)) {
- overlappingNodes.push(nodeId);
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function plural(word, num) {
+ var forms = word.split('_');
+ return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
}
- }
- };
- /**
- * retrieve all nodes overlapping with given object
- * @param {Object} object An object with parameters left, top, right, bottom
- * @return {Number[]} An array with id's of the overlapping nodes
- * @private
- */
- exports._getAllNodesOverlappingWith = function (object) {
- var overlappingNodes = [];
- this._doInAllActiveSectors("_getNodesOverlappingWith",object,overlappingNodes);
- return overlappingNodes;
- };
+ function relativeTimeWithPlural(number, withoutSuffix, key) {
+ var format = {
+ 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
+ 'hh': 'час_часа_часов',
+ 'dd': 'день_дня_дней',
+ 'MM': 'месяц_месяца_месяцев',
+ 'yy': 'год_года_лет'
+ };
+ if (key === 'm') {
+ return withoutSuffix ? 'минута' : 'минуту';
+ }
+ else {
+ return number + ' ' + plural(format[key], +number);
+ }
+ }
+ function monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
+ 'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')
+ },
- /**
- * Return a position object in canvasspace from a single point in screenspace
- *
- * @param pointer
- * @returns {{left: number, top: number, right: number, bottom: number}}
- * @private
- */
- exports._pointerToPositionObject = function(pointer) {
- var x = this._XconvertDOMtoCanvas(pointer.x);
- var y = this._YconvertDOMtoCanvas(pointer.y);
+ nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
- return {
- left: x,
- top: y,
- right: x,
- bottom: y
- };
- };
+ return months[nounCase][m.month()];
+ }
+ function monthsShortCaseReplace(m, format) {
+ var monthsShort = {
+ 'nominative': 'янв_фев_мар_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),
+ 'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')
+ },
- /**
- * Get the top node at the a specific point (like a click)
- *
- * @param {{x: Number, y: Number}} pointer
- * @return {Node | null} node
- * @private
- */
- exports._getNodeAt = function (pointer) {
- // we first check if this is an navigation controls element
- var positionObject = this._pointerToPositionObject(pointer);
- var overlappingNodes = this._getAllNodesOverlappingWith(positionObject);
+ nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
- // if there are overlapping nodes, select the last one, this is the
- // one which is drawn on top of the others
- if (overlappingNodes.length > 0) {
- return this.nodes[overlappingNodes[overlappingNodes.length - 1]];
- }
- else {
- return null;
- }
- };
+ return monthsShort[nounCase][m.month()];
+ }
+ function weekdaysCaseReplace(m, format) {
+ var weekdays = {
+ 'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
+ 'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')
+ },
- /**
- * retrieve all edges overlapping with given object, selector is around center
- * @param {Object} object An object with parameters left, top, right, bottom
- * @return {Number[]} An array with id's of the overlapping nodes
- * @private
- */
- exports._getEdgesOverlappingWith = function (object, overlappingEdges) {
- var edges = this.edges;
- for (var edgeId in edges) {
- if (edges.hasOwnProperty(edgeId)) {
- if (edges[edgeId].isOverlappingWith(object)) {
- overlappingEdges.push(edgeId);
- }
+ nounCase = (/\[ ?[Вв] ?(?:прошлую|следующую)? ?\] ?dddd/).test(format) ?
+ 'accusative' :
+ 'nominative';
+
+ return weekdays[nounCase][m.day()];
}
- }
- };
+ return moment.lang('ru', {
+ months : monthsCaseReplace,
+ monthsShort : monthsShortCaseReplace,
+ weekdays : weekdaysCaseReplace,
+ weekdaysShort : "вс_пн_вт_ср_чт_пт_сб".split("_"),
+ weekdaysMin : "вс_пн_вт_ср_чт_пт_сб".split("_"),
+ monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY г.",
+ LLL : "D MMMM YYYY г., LT",
+ LLLL : "dddd, D MMMM YYYY г., LT"
+ },
+ calendar : {
+ sameDay: '[Сегодня в] LT',
+ nextDay: '[Завтра в] LT',
+ lastDay: '[Вчера в] LT',
+ nextWeek: function () {
+ return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';
+ },
+ lastWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[В прошлое] dddd [в] LT';
+ case 1:
+ case 2:
+ case 4:
+ return '[В прошлый] dddd [в] LT';
+ case 3:
+ case 5:
+ case 6:
+ return '[В прошлую] dddd [в] LT';
+ }
+ },
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "через %s",
+ past : "%s назад",
+ s : "несколько секунд",
+ m : relativeTimeWithPlural,
+ mm : relativeTimeWithPlural,
+ h : "час",
+ hh : relativeTimeWithPlural,
+ d : "день",
+ dd : relativeTimeWithPlural,
+ M : "месяц",
+ MM : relativeTimeWithPlural,
+ y : "год",
+ yy : relativeTimeWithPlural
+ },
- /**
- * retrieve all nodes overlapping with given object
- * @param {Object} object An object with parameters left, top, right, bottom
- * @return {Number[]} An array with id's of the overlapping nodes
- * @private
- */
- exports._getAllEdgesOverlappingWith = function (object) {
- var overlappingEdges = [];
- this._doInAllActiveSectors("_getEdgesOverlappingWith",object,overlappingEdges);
- return overlappingEdges;
- };
+ meridiemParse: /ночи|утра|дня|вечера/i,
+ isPM : function (input) {
+ return /^(дня|вечера)$/.test(input);
+ },
- /**
- * Place holder. To implement change the _getNodeAt to a _getObjectAt. Have the _getObjectAt call
- * _getNodeAt and _getEdgesAt, then priortize the selection to user preferences.
- *
- * @param pointer
- * @returns {null}
- * @private
- */
- exports._getEdgeAt = function(pointer) {
- var positionObject = this._pointerToPositionObject(pointer);
- var overlappingEdges = this._getAllEdgesOverlappingWith(positionObject);
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 4) {
+ return "ночи";
+ } else if (hour < 12) {
+ return "утра";
+ } else if (hour < 17) {
+ return "дня";
+ } else {
+ return "вечера";
+ }
+ },
- if (overlappingEdges.length > 0) {
- return this.edges[overlappingEdges[overlappingEdges.length - 1]];
- }
- else {
- return null;
- }
- };
+ ordinal: function (number, period) {
+ switch (period) {
+ case 'M':
+ case 'd':
+ case 'DDD':
+ return number + '-й';
+ case 'D':
+ return number + '-го';
+ case 'w':
+ case 'W':
+ return number + '-я';
+ default:
+ return number;
+ }
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * Add object to the selection array.
- *
- * @param obj
- * @private
- */
- exports._addToSelection = function(obj) {
- if (obj instanceof Node) {
- this.selectionObj.nodes[obj.id] = obj;
- }
- else {
- this.selectionObj.edges[obj.id] = obj;
- }
- };
- /**
- * Add object to the selection array.
- *
- * @param obj
- * @private
- */
- exports._addToHover = function(obj) {
- if (obj instanceof Node) {
- this.hoverObj.nodes[obj.id] = obj;
- }
- else {
- this.hoverObj.edges[obj.id] = obj;
- }
- };
+/***/ },
+/* 101 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : slovak (sk)
+ // author : Martin Minka : https://github.com/k2s
+ // based on work of petrbela : https://github.com/petrbela
- /**
- * Remove a single option from selection.
- *
- * @param {Object} obj
- * @private
- */
- exports._removeFromSelection = function(obj) {
- if (obj instanceof Node) {
- delete this.selectionObj.nodes[obj.id];
- }
- else {
- delete this.selectionObj.edges[obj.id];
- }
- };
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ var months = "január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),
+ monthsShort = "jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_");
- /**
- * Unselect all. The selectionObj is useful for this.
- *
- * @param {Boolean} [doNotTrigger] | ignore trigger
- * @private
- */
- exports._unselectAll = function(doNotTrigger) {
- if (doNotTrigger === undefined) {
- doNotTrigger = false;
- }
- for(var nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- this.selectionObj.nodes[nodeId].unselect();
+ function plural(n) {
+ return (n > 1) && (n < 5);
}
- }
- for(var edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- this.selectionObj.edges[edgeId].unselect();
+
+ function translate(number, withoutSuffix, key, isFuture) {
+ var result = number + " ";
+ switch (key) {
+ case 's': // a few seconds / in a few seconds / a few seconds ago
+ return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';
+ case 'm': // a minute / in a minute / a minute ago
+ return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');
+ case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'minúty' : 'minút');
+ } else {
+ return result + 'minútami';
+ }
+ break;
+ case 'h': // an hour / in an hour / an hour ago
+ return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
+ case 'hh': // 9 hours / in 9 hours / 9 hours ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'hodiny' : 'hodín');
+ } else {
+ return result + 'hodinami';
+ }
+ break;
+ case 'd': // a day / in a day / a day ago
+ return (withoutSuffix || isFuture) ? 'deň' : 'dňom';
+ case 'dd': // 9 days / in 9 days / 9 days ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'dni' : 'dní');
+ } else {
+ return result + 'dňami';
+ }
+ break;
+ case 'M': // a month / in a month / a month ago
+ return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';
+ case 'MM': // 9 months / in 9 months / 9 months ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'mesiace' : 'mesiacov');
+ } else {
+ return result + 'mesiacmi';
+ }
+ break;
+ case 'y': // a year / in a year / a year ago
+ return (withoutSuffix || isFuture) ? 'rok' : 'rokom';
+ case 'yy': // 9 years / in 9 years / 9 years ago
+ if (withoutSuffix || isFuture) {
+ return result + (plural(number) ? 'roky' : 'rokov');
+ } else {
+ return result + 'rokmi';
+ }
+ break;
+ }
+ }
+
+ return moment.lang('sk', {
+ months : months,
+ monthsShort : monthsShort,
+ monthsParse : (function (months, monthsShort) {
+ var i, _monthsParse = [];
+ for (i = 0; i < 12; i++) {
+ // use custom parser to solve problem with July (červenec)
+ _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
+ }
+ return _monthsParse;
+ }(months, monthsShort)),
+ weekdays : "nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),
+ weekdaysShort : "ne_po_ut_st_št_pi_so".split("_"),
+ weekdaysMin : "ne_po_ut_st_št_pi_so".split("_"),
+ longDateFormat : {
+ LT: "H:mm",
+ L : "DD.MM.YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[dnes o] LT",
+ nextDay: '[zajtra o] LT',
+ nextWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[v nedeľu o] LT';
+ case 1:
+ case 2:
+ return '[v] dddd [o] LT';
+ case 3:
+ return '[v stredu o] LT';
+ case 4:
+ return '[vo štvrtok o] LT';
+ case 5:
+ return '[v piatok o] LT';
+ case 6:
+ return '[v sobotu o] LT';
+ }
+ },
+ lastDay: '[včera o] LT',
+ lastWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[minulú nedeľu o] LT';
+ case 1:
+ case 2:
+ return '[minulý] dddd [o] LT';
+ case 3:
+ return '[minulú stredu o] LT';
+ case 4:
+ case 5:
+ return '[minulý] dddd [o] LT';
+ case 6:
+ return '[minulú sobotu o] LT';
+ }
+ },
+ sameElse: "L"
+ },
+ relativeTime : {
+ future : "za %s",
+ past : "pred %s",
+ s : translate,
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : translate,
+ dd : translate,
+ M : translate,
+ MM : translate,
+ y : translate,
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
+
+
+/***/ },
+/* 102 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : slovenian (sl)
+ // author : Robert Sedovšek : https://github.com/sedovsek
+
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ function translate(number, withoutSuffix, key) {
+ var result = number + " ";
+ switch (key) {
+ case 'm':
+ return withoutSuffix ? 'ena minuta' : 'eno minuto';
+ case 'mm':
+ if (number === 1) {
+ result += 'minuta';
+ } else if (number === 2) {
+ result += 'minuti';
+ } else if (number === 3 || number === 4) {
+ result += 'minute';
+ } else {
+ result += 'minut';
+ }
+ return result;
+ case 'h':
+ return withoutSuffix ? 'ena ura' : 'eno uro';
+ case 'hh':
+ if (number === 1) {
+ result += 'ura';
+ } else if (number === 2) {
+ result += 'uri';
+ } else if (number === 3 || number === 4) {
+ result += 'ure';
+ } else {
+ result += 'ur';
+ }
+ return result;
+ case 'dd':
+ if (number === 1) {
+ result += 'dan';
+ } else {
+ result += 'dni';
+ }
+ return result;
+ case 'MM':
+ if (number === 1) {
+ result += 'mesec';
+ } else if (number === 2) {
+ result += 'meseca';
+ } else if (number === 3 || number === 4) {
+ result += 'mesece';
+ } else {
+ result += 'mesecev';
+ }
+ return result;
+ case 'yy':
+ if (number === 1) {
+ result += 'leto';
+ } else if (number === 2) {
+ result += 'leti';
+ } else if (number === 3 || number === 4) {
+ result += 'leta';
+ } else {
+ result += 'let';
+ }
+ return result;
+ }
}
- }
-
- this.selectionObj = {nodes:{},edges:{}};
- if (doNotTrigger == false) {
- this.emit('select', this.getSelection());
- }
- };
+ return moment.lang('sl', {
+ months : "januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),
+ monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
+ weekdays : "nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),
+ weekdaysShort : "ned._pon._tor._sre._čet._pet._sob.".split("_"),
+ weekdaysMin : "ne_po_to_sr_če_pe_so".split("_"),
+ longDateFormat : {
+ LT : "H:mm",
+ L : "DD. MM. YYYY",
+ LL : "D. MMMM YYYY",
+ LLL : "D. MMMM YYYY LT",
+ LLLL : "dddd, D. MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[danes ob] LT',
+ nextDay : '[jutri ob] LT',
- /**
- * Unselect all clusters. The selectionObj is useful for this.
- *
- * @param {Boolean} [doNotTrigger] | ignore trigger
- * @private
- */
- exports._unselectClusters = function(doNotTrigger) {
- if (doNotTrigger === undefined) {
- doNotTrigger = false;
- }
+ nextWeek : function () {
+ switch (this.day()) {
+ case 0:
+ return '[v] [nedeljo] [ob] LT';
+ case 3:
+ return '[v] [sredo] [ob] LT';
+ case 6:
+ return '[v] [soboto] [ob] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[v] dddd [ob] LT';
+ }
+ },
+ lastDay : '[včeraj ob] LT',
+ lastWeek : function () {
+ switch (this.day()) {
+ case 0:
+ case 3:
+ case 6:
+ return '[prejšnja] dddd [ob] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[prejšnji] dddd [ob] LT';
+ }
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "čez %s",
+ past : "%s nazaj",
+ s : "nekaj sekund",
+ m : translate,
+ mm : translate,
+ h : translate,
+ hh : translate,
+ d : "en dan",
+ dd : translate,
+ M : "en mesec",
+ MM : translate,
+ y : "eno leto",
+ yy : translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- for (var nodeId in this.selectionObj.nodes) {
- if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
- this.selectionObj.nodes[nodeId].unselect();
- this._removeFromSelection(this.selectionObj.nodes[nodeId]);
- }
- }
- }
- if (doNotTrigger == false) {
- this.emit('select', this.getSelection());
- }
- };
+/***/ },
+/* 103 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Albanian (sq)
+ // author : Flakërim Ismani : https://github.com/flakerimi
+ // author: Menelion Elensúle: https://github.com/Oire (tests)
+ // author : Oerd Cukalla : https://github.com/oerd (fixes)
- /**
- * return the number of selected nodes
- *
- * @returns {number}
- * @private
- */
- exports._getSelectedNodeCount = function() {
- var count = 0;
- for (var nodeId in this.selectionObj.nodes) {
- if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- count += 1;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- return count;
- };
+ }(function (moment) {
+ return moment.lang('sq', {
+ months : "Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"),
+ monthsShort : "Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"),
+ weekdays : "E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"),
+ weekdaysShort : "Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"),
+ weekdaysMin : "D_H_Ma_Më_E_P_Sh".split("_"),
+ meridiem : function (hours, minutes, isLower) {
+ return hours < 12 ? 'PD' : 'MD';
+ },
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[Sot në] LT',
+ nextDay : '[Nesër në] LT',
+ nextWeek : 'dddd [në] LT',
+ lastDay : '[Dje në] LT',
+ lastWeek : 'dddd [e kaluar në] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "në %s",
+ past : "%s më parë",
+ s : "disa sekonda",
+ m : "një minutë",
+ mm : "%d minuta",
+ h : "një orë",
+ hh : "%d orë",
+ d : "një ditë",
+ dd : "%d ditë",
+ M : "një muaj",
+ MM : "%d muaj",
+ y : "një vit",
+ yy : "%d vite"
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * return the selected node
- *
- * @returns {number}
- * @private
- */
- exports._getSelectedNode = function() {
- for (var nodeId in this.selectionObj.nodes) {
- if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- return this.selectionObj.nodes[nodeId];
- }
- }
- return null;
- };
- /**
- * return the selected edge
- *
- * @returns {number}
- * @private
- */
- exports._getSelectedEdge = function() {
- for (var edgeId in this.selectionObj.edges) {
- if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
- return this.selectionObj.edges[edgeId];
- }
- }
- return null;
- };
+/***/ },
+/* 104 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Serbian-cyrillic (sr-cyrl)
+ // author : Milan Janačković : https://github.com/milan-j
- /**
- * return the number of selected edges
- *
- * @returns {number}
- * @private
- */
- exports._getSelectedEdgeCount = function() {
- var count = 0;
- for (var edgeId in this.selectionObj.edges) {
- if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
- count += 1;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- return count;
- };
-
+ }(function (moment) {
- /**
- * return the number of selected objects.
- *
- * @returns {number}
- * @private
- */
- exports._getSelectedObjectCount = function() {
- var count = 0;
- for(var nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- count += 1;
- }
- }
- for(var edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- count += 1;
- }
- }
- return count;
- };
+ var translator = {
+ words: { //Different grammatical cases
+ m: ['један минут', 'једне минуте'],
+ mm: ['минут', 'минуте', 'минута'],
+ h: ['један сат', 'једног сата'],
+ hh: ['сат', 'сата', 'сати'],
+ dd: ['дан', 'дана', 'дана'],
+ MM: ['месец', 'месеца', 'месеци'],
+ yy: ['година', 'године', 'година']
+ },
+ correctGrammaticalCase: function (number, wordKey) {
+ return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
+ },
+ translate: function (number, withoutSuffix, key) {
+ var wordKey = translator.words[key];
+ if (key.length === 1) {
+ return withoutSuffix ? wordKey[0] : wordKey[1];
+ } else {
+ return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
+ }
+ }
+ };
- /**
- * Check if anything is selected
- *
- * @returns {boolean}
- * @private
- */
- exports._selectionIsEmpty = function() {
- for(var nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- return false;
- }
- }
- for(var edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- return false;
- }
- }
- return true;
- };
+ return moment.lang('sr-cyrl', {
+ months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],
+ monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],
+ weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],
+ weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],
+ weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],
+ longDateFormat: {
+ LT: "H:mm",
+ L: "DD. MM. YYYY",
+ LL: "D. MMMM YYYY",
+ LLL: "D. MMMM YYYY LT",
+ LLLL: "dddd, D. MMMM YYYY LT"
+ },
+ calendar: {
+ sameDay: '[данас у] LT',
+ nextDay: '[сутра у] LT',
+ nextWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[у] [недељу] [у] LT';
+ case 3:
+ return '[у] [среду] [у] LT';
+ case 6:
+ return '[у] [суботу] [у] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[у] dddd [у] LT';
+ }
+ },
+ lastDay : '[јуче у] LT',
+ lastWeek : function () {
+ var lastWeekDays = [
+ '[прошле] [недеље] [у] LT',
+ '[прошлог] [понедељка] [у] LT',
+ '[прошлог] [уторка] [у] LT',
+ '[прошле] [среде] [у] LT',
+ '[прошлог] [четвртка] [у] LT',
+ '[прошлог] [петка] [у] LT',
+ '[прошле] [суботе] [у] LT'
+ ];
+ return lastWeekDays[this.day()];
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "за %s",
+ past : "пре %s",
+ s : "неколико секунди",
+ m : translator.translate,
+ mm : translator.translate,
+ h : translator.translate,
+ hh : translator.translate,
+ d : "дан",
+ dd : translator.translate,
+ M : "месец",
+ MM : translator.translate,
+ y : "годину",
+ yy : translator.translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * check if one of the selected nodes is a cluster.
- *
- * @returns {boolean}
- * @private
- */
- exports._clusterInSelection = function() {
- for(var nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * select the edges connected to the node that is being selected
- *
- * @param {Node} node
- * @private
- */
- exports._selectConnectedEdges = function(node) {
- for (var i = 0; i < node.dynamicEdges.length; i++) {
- var edge = node.dynamicEdges[i];
- edge.select();
- this._addToSelection(edge);
- }
- };
+/***/ },
+/* 105 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * select the edges connected to the node that is being selected
- *
- * @param {Node} node
- * @private
- */
- exports._hoverConnectedEdges = function(node) {
- for (var i = 0; i < node.dynamicEdges.length; i++) {
- var edge = node.dynamicEdges[i];
- edge.hover = true;
- this._addToHover(edge);
- }
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Serbian-latin (sr)
+ // author : Milan Janačković : https://github.com/milan-j
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
- /**
- * unselect the edges connected to the node that is being selected
- *
- * @param {Node} node
- * @private
- */
- exports._unselectConnectedEdges = function(node) {
- for (var i = 0; i < node.dynamicEdges.length; i++) {
- var edge = node.dynamicEdges[i];
- edge.unselect();
- this._removeFromSelection(edge);
- }
- };
+ var translator = {
+ words: { //Different grammatical cases
+ m: ['jedan minut', 'jedne minute'],
+ mm: ['minut', 'minute', 'minuta'],
+ h: ['jedan sat', 'jednog sata'],
+ hh: ['sat', 'sata', 'sati'],
+ dd: ['dan', 'dana', 'dana'],
+ MM: ['mesec', 'meseca', 'meseci'],
+ yy: ['godina', 'godine', 'godina']
+ },
+ correctGrammaticalCase: function (number, wordKey) {
+ return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
+ },
+ translate: function (number, withoutSuffix, key) {
+ var wordKey = translator.words[key];
+ if (key.length === 1) {
+ return withoutSuffix ? wordKey[0] : wordKey[1];
+ } else {
+ return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
+ }
+ }
+ };
+ return moment.lang('sr', {
+ months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
+ monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],
+ weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],
+ weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],
+ weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
+ longDateFormat: {
+ LT: "H:mm",
+ L: "DD. MM. YYYY",
+ LL: "D. MMMM YYYY",
+ LLL: "D. MMMM YYYY LT",
+ LLLL: "dddd, D. MMMM YYYY LT"
+ },
+ calendar: {
+ sameDay: '[danas u] LT',
+ nextDay: '[sutra u] LT',
+ nextWeek: function () {
+ switch (this.day()) {
+ case 0:
+ return '[u] [nedelju] [u] LT';
+ case 3:
+ return '[u] [sredu] [u] LT';
+ case 6:
+ return '[u] [subotu] [u] LT';
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ return '[u] dddd [u] LT';
+ }
+ },
+ lastDay : '[juče u] LT',
+ lastWeek : function () {
+ var lastWeekDays = [
+ '[prošle] [nedelje] [u] LT',
+ '[prošlog] [ponedeljka] [u] LT',
+ '[prošlog] [utorka] [u] LT',
+ '[prošle] [srede] [u] LT',
+ '[prošlog] [četvrtka] [u] LT',
+ '[prošlog] [petka] [u] LT',
+ '[prošle] [subote] [u] LT'
+ ];
+ return lastWeekDays[this.day()];
+ },
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "za %s",
+ past : "pre %s",
+ s : "nekoliko sekundi",
+ m : translator.translate,
+ mm : translator.translate,
+ h : translator.translate,
+ hh : translator.translate,
+ d : "dan",
+ dd : translator.translate,
+ M : "mesec",
+ MM : translator.translate,
+ y : "godinu",
+ yy : translator.translate
+ },
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * This is called when someone clicks on a node. either select or deselect it.
- * If there is an existing selection and we don't want to append to it, clear the existing selection
- *
- * @param {Node || Edge} object
- * @param {Boolean} append
- * @param {Boolean} [doNotTrigger] | ignore trigger
- * @private
- */
- exports._selectObject = function(object, append, doNotTrigger, highlightEdges) {
- if (doNotTrigger === undefined) {
- doNotTrigger = false;
- }
- if (highlightEdges === undefined) {
- highlightEdges = true;
- }
+/***/ },
+/* 106 */
+/***/ function(module, exports, __webpack_require__) {
- if (this._selectionIsEmpty() == false && append == false && this.forceAppendSelection == false) {
- this._unselectAll(true);
- }
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : swedish (sv)
+ // author : Jens Alm : https://github.com/ulmus
- if (object.selected == false) {
- object.select();
- this._addToSelection(object);
- if (object instanceof Node && this.blockConnectingEdgeSelection == false && highlightEdges == true) {
- this._selectConnectedEdges(object);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- else {
- object.unselect();
- this._removeFromSelection(object);
- }
+ }(function (moment) {
+ return moment.lang('sv', {
+ months : "januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),
+ monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),
+ weekdays : "söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),
+ weekdaysShort : "sön_mån_tis_ons_tor_fre_lör".split("_"),
+ weekdaysMin : "sö_må_ti_on_to_fr_lö".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "YYYY-MM-DD",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: '[Idag] LT',
+ nextDay: '[Imorgon] LT',
+ lastDay: '[Igår] LT',
+ nextWeek: 'dddd LT',
+ lastWeek: '[Förra] dddd[en] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "om %s",
+ past : "för %s sedan",
+ s : "några sekunder",
+ m : "en minut",
+ mm : "%d minuter",
+ h : "en timme",
+ hh : "%d timmar",
+ d : "en dag",
+ dd : "%d dagar",
+ M : "en månad",
+ MM : "%d månader",
+ y : "ett år",
+ yy : "%d år"
+ },
+ ordinal : function (number) {
+ var b = number % 10,
+ output = (~~ (number % 100 / 10) === 1) ? 'e' :
+ (b === 1) ? 'a' :
+ (b === 2) ? 'a' :
+ (b === 3) ? 'e' : 'e';
+ return number + output;
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- if (doNotTrigger == false) {
- this.emit('select', this.getSelection());
- }
- };
+/***/ },
+/* 107 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * This is called when someone clicks on a node. either select or deselect it.
- * If there is an existing selection and we don't want to append to it, clear the existing selection
- *
- * @param {Node || Edge} object
- * @private
- */
- exports._blurObject = function(object) {
- if (object.hover == true) {
- object.hover = false;
- this.emit("blurNode",{node:object.id});
- }
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : tamil (ta)
+ // author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
- /**
- * This is called when someone clicks on a node. either select or deselect it.
- * If there is an existing selection and we don't want to append to it, clear the existing selection
- *
- * @param {Node || Edge} object
- * @private
- */
- exports._hoverObject = function(object) {
- if (object.hover == false) {
- object.hover = true;
- this._addToHover(object);
- if (object instanceof Node) {
- this.emit("hoverNode",{node:object.id});
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- if (object instanceof Node) {
- this._hoverConnectedEdges(object);
- }
- };
+ }(function (moment) {
+ /*var symbolMap = {
+ '1': '௧',
+ '2': '௨',
+ '3': '௩',
+ '4': '௪',
+ '5': '௫',
+ '6': '௬',
+ '7': '௭',
+ '8': '௮',
+ '9': '௯',
+ '0': '௦'
+ },
+ numberMap = {
+ '௧': '1',
+ '௨': '2',
+ '௩': '3',
+ '௪': '4',
+ '௫': '5',
+ '௬': '6',
+ '௭': '7',
+ '௮': '8',
+ '௯': '9',
+ '௦': '0'
+ }; */
+ return moment.lang('ta', {
+ months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"),
+ monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"),
+ weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split("_"),
+ weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split("_"),
+ weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY, LT",
+ LLLL : "dddd, D MMMM YYYY, LT"
+ },
+ calendar : {
+ sameDay : '[இன்று] LT',
+ nextDay : '[நாளை] LT',
+ nextWeek : 'dddd, LT',
+ lastDay : '[நேற்று] LT',
+ lastWeek : '[கடந்த வாரம்] dddd, LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s இல்",
+ past : "%s முன்",
+ s : "ஒரு சில விநாடிகள்",
+ m : "ஒரு நிமிடம்",
+ mm : "%d நிமிடங்கள்",
+ h : "ஒரு மணி நேரம்",
+ hh : "%d மணி நேரம்",
+ d : "ஒரு நாள்",
+ dd : "%d நாட்கள்",
+ M : "ஒரு மாதம்",
+ MM : "%d மாதங்கள்",
+ y : "ஒரு வருடம்",
+ yy : "%d ஆண்டுகள்"
+ },
+ /* preparse: function (string) {
+ return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {
+ return numberMap[match];
+ });
+ },
+ postformat: function (string) {
+ return string.replace(/\d/g, function (match) {
+ return symbolMap[match];
+ });
+ },*/
+ ordinal : function (number) {
+ return number + 'வது';
+ },
- /**
- * handles the selection part of the touch, only for navigation controls elements;
- * Touch is triggered before tap, also before hold. Hold triggers after a while.
- * This is the most responsive solution
- *
- * @param {Object} pointer
- * @private
- */
- exports._handleTouch = function(pointer) {
- };
+ // refer http://ta.wikipedia.org/s/1er1
- /**
- * handles the selection part of the tap;
- *
- * @param {Object} pointer
- * @private
- */
- exports._handleTap = function(pointer) {
- var node = this._getNodeAt(pointer);
- if (node != null) {
- this._selectObject(node,false);
- }
- else {
- var edge = this._getEdgeAt(pointer);
- if (edge != null) {
- this._selectObject(edge,false);
- }
- else {
- this._unselectAll();
- }
- }
- this.emit("click", this.getSelection());
- this._redraw();
- };
+ meridiem : function (hour, minute, isLower) {
+ if (hour >= 6 && hour <= 10) {
+ return " காலை";
+ } else if (hour >= 10 && hour <= 14) {
+ return " நண்பகல்";
+ } else if (hour >= 14 && hour <= 18) {
+ return " எற்பாடு";
+ } else if (hour >= 18 && hour <= 20) {
+ return " மாலை";
+ } else if (hour >= 20 && hour <= 24) {
+ return " இரவு";
+ } else if (hour >= 0 && hour <= 6) {
+ return " வைகறை";
+ }
+ },
+ week : {
+ dow : 0, // Sunday is the first day of the week.
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * handles the selection part of the double tap and opens a cluster if needed
- *
- * @param {Object} pointer
- * @private
- */
- exports._handleDoubleTap = function(pointer) {
- var node = this._getNodeAt(pointer);
- if (node != null && node !== undefined) {
- // we reset the areaCenter here so the opening of the node will occur
- this.areaCenter = {"x" : this._XconvertDOMtoCanvas(pointer.x),
- "y" : this._YconvertDOMtoCanvas(pointer.y)};
- this.openCluster(node);
- }
- this.emit("doubleClick", this.getSelection());
- };
+/***/ },
+/* 108 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : thai (th)
+ // author : Kridsada Thanabulpong : https://github.com/sirn
- /**
- * Handle the onHold selection part
- *
- * @param pointer
- * @private
- */
- exports._handleOnHold = function(pointer) {
- var node = this._getNodeAt(pointer);
- if (node != null) {
- this._selectObject(node,true);
- }
- else {
- var edge = this._getEdgeAt(pointer);
- if (edge != null) {
- this._selectObject(edge,true);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- this._redraw();
- };
+ }(function (moment) {
+ return moment.lang('th', {
+ months : "มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),
+ monthsShort : "มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),
+ weekdays : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),
+ weekdaysShort : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"), // yes, three characters difference
+ weekdaysMin : "อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),
+ longDateFormat : {
+ LT : "H นาฬิกา m นาที",
+ L : "YYYY/MM/DD",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY เวลา LT",
+ LLLL : "วันddddที่ D MMMM YYYY เวลา LT"
+ },
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 12) {
+ return "ก่อนเที่ยง";
+ } else {
+ return "หลังเที่ยง";
+ }
+ },
+ calendar : {
+ sameDay : '[วันนี้ เวลา] LT',
+ nextDay : '[พรุ่งนี้ เวลา] LT',
+ nextWeek : 'dddd[หน้า เวลา] LT',
+ lastDay : '[เมื่อวานนี้ เวลา] LT',
+ lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "อีก %s",
+ past : "%sที่แล้ว",
+ s : "ไม่กี่วินาที",
+ m : "1 นาที",
+ mm : "%d นาที",
+ h : "1 ชั่วโมง",
+ hh : "%d ชั่วโมง",
+ d : "1 วัน",
+ dd : "%d วัน",
+ M : "1 เดือน",
+ MM : "%d เดือน",
+ y : "1 ปี",
+ yy : "%d ปี"
+ }
+ });
+ }));
- /**
- * handle the onRelease event. These functions are here for the navigation controls module.
- *
- * @private
- */
- exports._handleOnRelease = function(pointer) {
+/***/ },
+/* 109 */
+/***/ function(module, exports, __webpack_require__) {
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Tagalog/Filipino (tl-ph)
+ // author : Dan Hagman
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('tl-ph', {
+ months : "Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),
+ monthsShort : "Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),
+ weekdays : "Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),
+ weekdaysShort : "Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),
+ weekdaysMin : "Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "MM/D/YYYY",
+ LL : "MMMM D, YYYY",
+ LLL : "MMMM D, YYYY LT",
+ LLLL : "dddd, MMMM DD, YYYY LT"
+ },
+ calendar : {
+ sameDay: "[Ngayon sa] LT",
+ nextDay: '[Bukas sa] LT',
+ nextWeek: 'dddd [sa] LT',
+ lastDay: '[Kahapon sa] LT',
+ lastWeek: 'dddd [huling linggo] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "sa loob ng %s",
+ past : "%s ang nakalipas",
+ s : "ilang segundo",
+ m : "isang minuto",
+ mm : "%d minuto",
+ h : "isang oras",
+ hh : "%d oras",
+ d : "isang araw",
+ dd : "%d araw",
+ M : "isang buwan",
+ MM : "%d buwan",
+ y : "isang taon",
+ yy : "%d taon"
+ },
+ ordinal : function (number) {
+ return number;
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- *
- * retrieve the currently selected objects
- * @return {{nodes: Array., edges: Array.}} selection
- */
- exports.getSelection = function() {
- var nodeIds = this.getSelectedNodes();
- var edgeIds = this.getSelectedEdges();
- return {nodes:nodeIds, edges:edgeIds};
- };
+/***/ },
+/* 110 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- *
- * retrieve the currently selected nodes
- * @return {String[]} selection An array with the ids of the
- * selected nodes.
- */
- exports.getSelectedNodes = function() {
- var idArray = [];
- for(var nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- idArray.push(nodeId);
- }
- }
- return idArray
- };
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : turkish (tr)
+ // authors : Erhan Gundogan : https://github.com/erhangundogan,
+ // Burak Yiğit Kaya: https://github.com/BYK
- /**
- *
- * retrieve the currently selected edges
- * @return {Array} selection An array with the ids of the
- * selected nodes.
- */
- exports.getSelectedEdges = function() {
- var idArray = [];
- for(var edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- idArray.push(edgeId);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- }
- return idArray;
- };
+ }(function (moment) {
+ var suffixes = {
+ 1: "'inci",
+ 5: "'inci",
+ 8: "'inci",
+ 70: "'inci",
+ 80: "'inci",
- /**
- * select zero or more nodes
- * @param {Number[] | String[]} selection An array with the ids of the
- * selected nodes.
- */
- exports.setSelection = function(selection) {
- var i, iMax, id;
+ 2: "'nci",
+ 7: "'nci",
+ 20: "'nci",
+ 50: "'nci",
- if (!selection || (selection.length == undefined))
- throw 'Selection must be an array with ids';
+ 3: "'üncü",
+ 4: "'üncü",
+ 100: "'üncü",
- // first unselect any selected node
- this._unselectAll(true);
+ 6: "'ncı",
- for (i = 0, iMax = selection.length; i < iMax; i++) {
- id = selection[i];
+ 9: "'uncu",
+ 10: "'uncu",
+ 30: "'uncu",
- var node = this.nodes[id];
- if (!node) {
- throw new RangeError('Node with id "' + id + '" not found');
- }
- this._selectObject(node,true,true);
- }
+ 60: "'ıncı",
+ 90: "'ıncı"
+ };
- console.log("setSelection is deprecated. Please use selectNodes instead.")
+ return moment.lang('tr', {
+ months : "Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),
+ monthsShort : "Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),
+ weekdays : "Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),
+ weekdaysShort : "Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),
+ weekdaysMin : "Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd, D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay : '[bugün saat] LT',
+ nextDay : '[yarın saat] LT',
+ nextWeek : '[haftaya] dddd [saat] LT',
+ lastDay : '[dün] LT',
+ lastWeek : '[geçen hafta] dddd [saat] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "%s sonra",
+ past : "%s önce",
+ s : "birkaç saniye",
+ m : "bir dakika",
+ mm : "%d dakika",
+ h : "bir saat",
+ hh : "%d saat",
+ d : "bir gün",
+ dd : "%d gün",
+ M : "bir ay",
+ MM : "%d ay",
+ y : "bir yıl",
+ yy : "%d yıl"
+ },
+ ordinal : function (number) {
+ if (number === 0) { // special case for zero
+ return number + "'ıncı";
+ }
+ var a = number % 10,
+ b = number % 100 - a,
+ c = number >= 100 ? 100 : null;
- this.redraw();
- };
+ return number + (suffixes[a] || suffixes[b] || suffixes[c]);
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- /**
- * select zero or more nodes with the option to highlight edges
- * @param {Number[] | String[]} selection An array with the ids of the
- * selected nodes.
- * @param {boolean} [highlightEdges]
- */
- exports.selectNodes = function(selection, highlightEdges) {
- var i, iMax, id;
+/***/ },
+/* 111 */
+/***/ function(module, exports, __webpack_require__) {
- if (!selection || (selection.length == undefined))
- throw 'Selection must be an array with ids';
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
+ // author : Abdel Said : https://github.com/abdelsaid
- // first unselect any selected node
- this._unselectAll(true);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('tzm-latn', {
+ months : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),
+ monthsShort : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),
+ weekdays : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
+ weekdaysShort : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
+ weekdaysMin : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[asdkh g] LT",
+ nextDay: '[aska g] LT',
+ nextWeek: 'dddd [g] LT',
+ lastDay: '[assant g] LT',
+ lastWeek: 'dddd [g] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "dadkh s yan %s",
+ past : "yan %s",
+ s : "imik",
+ m : "minuḍ",
+ mm : "%d minuḍ",
+ h : "saɛa",
+ hh : "%d tassaɛin",
+ d : "ass",
+ dd : "%d ossan",
+ M : "ayowr",
+ MM : "%d iyyirn",
+ y : "asgas",
+ yy : "%d isgasn"
+ },
+ week : {
+ dow : 6, // Saturday is the first day of the week.
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- for (i = 0, iMax = selection.length; i < iMax; i++) {
- id = selection[i];
- var node = this.nodes[id];
- if (!node) {
- throw new RangeError('Node with id "' + id + '" not found');
- }
- this._selectObject(node,true,true,highlightEdges);
- }
- this.redraw();
- };
+/***/ },
+/* 112 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : Morocco Central Atlas Tamaziɣt (tzm)
+ // author : Abdel Said : https://github.com/abdelsaid
- /**
- * select zero or more edges
- * @param {Number[] | String[]} selection An array with the ids of the
- * selected nodes.
- */
- exports.selectEdges = function(selection) {
- var i, iMax, id;
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('tzm', {
+ months : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),
+ monthsShort : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),
+ weekdays : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),
+ weekdaysShort : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),
+ weekdaysMin : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "dddd D MMMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[ⴰⵙⴷⵅ ⴴ] LT",
+ nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',
+ nextWeek: 'dddd [ⴴ] LT',
+ lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',
+ lastWeek: 'dddd [ⴴ] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s",
+ past : "ⵢⴰⵏ %s",
+ s : "ⵉⵎⵉⴽ",
+ m : "ⵎⵉⵏⵓⴺ",
+ mm : "%d ⵎⵉⵏⵓⴺ",
+ h : "ⵙⴰⵄⴰ",
+ hh : "%d ⵜⴰⵙⵙⴰⵄⵉⵏ",
+ d : "ⴰⵙⵙ",
+ dd : "%d oⵙⵙⴰⵏ",
+ M : "ⴰⵢoⵓⵔ",
+ MM : "%d ⵉⵢⵢⵉⵔⵏ",
+ y : "ⴰⵙⴳⴰⵙ",
+ yy : "%d ⵉⵙⴳⴰⵙⵏ"
+ },
+ week : {
+ dow : 6, // Saturday is the first day of the week.
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- if (!selection || (selection.length == undefined))
- throw 'Selection must be an array with ids';
- // first unselect any selected node
- this._unselectAll(true);
+/***/ },
+/* 113 */
+/***/ function(module, exports, __webpack_require__) {
- for (i = 0, iMax = selection.length; i < iMax; i++) {
- id = selection[i];
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : ukrainian (uk)
+ // author : zemlanin : https://github.com/zemlanin
+ // Author : Menelion Elensúle : https://github.com/Oire
- var edge = this.edges[id];
- if (!edge) {
- throw new RangeError('Edge with id "' + id + '" not found');
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- this._selectObject(edge,true,true,highlightEdges);
- }
- this.redraw();
- };
-
- /**
- * Validate the selection: remove ids of nodes which no longer exist
- * @private
- */
- exports._updateSelection = function () {
- for(var nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- if (!this.nodes.hasOwnProperty(nodeId)) {
- delete this.selectionObj.nodes[nodeId];
- }
+ }(function (moment) {
+ function plural(word, num) {
+ var forms = word.split('_');
+ return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
}
- }
- for(var edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- if (!this.edges.hasOwnProperty(edgeId)) {
- delete this.selectionObj.edges[edgeId];
- }
+
+ function relativeTimeWithPlural(number, withoutSuffix, key) {
+ var format = {
+ 'mm': 'хвилина_хвилини_хвилин',
+ 'hh': 'година_години_годин',
+ 'dd': 'день_дні_днів',
+ 'MM': 'місяць_місяці_місяців',
+ 'yy': 'рік_роки_років'
+ };
+ if (key === 'm') {
+ return withoutSuffix ? 'хвилина' : 'хвилину';
+ }
+ else if (key === 'h') {
+ return withoutSuffix ? 'година' : 'годину';
+ }
+ else {
+ return number + ' ' + plural(format[key], +number);
+ }
}
- }
- };
+ function monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),
+ 'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')
+ },
-/***/ },
-/* 50 */
-/***/ function(module, exports, __webpack_require__) {
+ nounCase = (/D[oD]? *MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
- var util = __webpack_require__(1);
- var Node = __webpack_require__(42);
- var Edge = __webpack_require__(43);
+ return months[nounCase][m.month()];
+ }
- /**
- * clears the toolbar div element of children
- *
- * @private
- */
- exports._clearManipulatorBar = function() {
- while (this.manipulationDiv.hasChildNodes()) {
- this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);
- }
- };
+ function weekdaysCaseReplace(m, format) {
+ var weekdays = {
+ 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
+ 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
+ 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
+ },
- /**
- * Manipulation UI temporarily overloads certain functions to extend or replace them. To be able to restore
- * these functions to their original functionality, we saved them in this.cachedFunctions.
- * This function restores these functions to their original function.
- *
- * @private
- */
- exports._restoreOverloadedFunctions = function() {
- for (var functionName in this.cachedFunctions) {
- if (this.cachedFunctions.hasOwnProperty(functionName)) {
- this[functionName] = this.cachedFunctions[functionName];
+ nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
+ 'accusative' :
+ ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
+ 'genitive' :
+ 'nominative');
+
+ return weekdays[nounCase][m.day()];
}
- }
- };
- /**
- * Enable or disable edit-mode.
- *
- * @private
- */
- exports._toggleEditMode = function() {
- this.editMode = !this.editMode;
- var toolbar = document.getElementById("network-manipulationDiv");
- var closeDiv = document.getElementById("network-manipulation-closeDiv");
- var editModeDiv = document.getElementById("network-manipulation-editMode");
- if (this.editMode == true) {
- toolbar.style.display="block";
- closeDiv.style.display="block";
- editModeDiv.style.display="none";
- closeDiv.onclick = this._toggleEditMode.bind(this);
- }
- else {
- toolbar.style.display="none";
- closeDiv.style.display="none";
- editModeDiv.style.display="block";
- closeDiv.onclick = null;
- }
- this._createManipulatorBar()
- };
+ function processHoursFunction(str) {
+ return function () {
+ return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
+ };
+ }
- /**
- * main function, creates the main toolbar. Removes functions bound to the select event. Binds all the buttons of the toolbar.
- *
- * @private
- */
- exports._createManipulatorBar = function() {
- // remove bound functions
- if (this.boundFunction) {
- this.off('select', this.boundFunction);
- }
+ return moment.lang('uk', {
+ months : monthsCaseReplace,
+ monthsShort : "січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),
+ weekdays : weekdaysCaseReplace,
+ weekdaysShort : "нд_пн_вт_ср_чт_пт_сб".split("_"),
+ weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD.MM.YYYY",
+ LL : "D MMMM YYYY р.",
+ LLL : "D MMMM YYYY р., LT",
+ LLLL : "dddd, D MMMM YYYY р., LT"
+ },
+ calendar : {
+ sameDay: processHoursFunction('[Сьогодні '),
+ nextDay: processHoursFunction('[Завтра '),
+ lastDay: processHoursFunction('[Вчора '),
+ nextWeek: processHoursFunction('[У] dddd ['),
+ lastWeek: function () {
+ switch (this.day()) {
+ case 0:
+ case 3:
+ case 5:
+ case 6:
+ return processHoursFunction('[Минулої] dddd [').call(this);
+ case 1:
+ case 2:
+ case 4:
+ return processHoursFunction('[Минулого] dddd [').call(this);
+ }
+ },
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "за %s",
+ past : "%s тому",
+ s : "декілька секунд",
+ m : relativeTimeWithPlural,
+ mm : relativeTimeWithPlural,
+ h : "годину",
+ hh : relativeTimeWithPlural,
+ d : "день",
+ dd : relativeTimeWithPlural,
+ M : "місяць",
+ MM : relativeTimeWithPlural,
+ y : "рік",
+ yy : relativeTimeWithPlural
+ },
- if (this.edgeBeingEdited !== undefined) {
- this.edgeBeingEdited._disableControlNodes();
- this.edgeBeingEdited = undefined;
- this.selectedControlNode = null;
- this.controlNodesActive = false;
- }
+ // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
- // restore overloaded functions
- this._restoreOverloadedFunctions();
+ meridiem : function (hour, minute, isLower) {
+ if (hour < 4) {
+ return "ночі";
+ } else if (hour < 12) {
+ return "ранку";
+ } else if (hour < 17) {
+ return "дня";
+ } else {
+ return "вечора";
+ }
+ },
+
+ ordinal: function (number, period) {
+ switch (period) {
+ case 'M':
+ case 'd':
+ case 'DDD':
+ case 'w':
+ case 'W':
+ return number + '-й';
+ case 'D':
+ return number + '-го';
+ default:
+ return number;
+ }
+ },
- // resume calculation
- this.freezeSimulation = false;
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+ }));
- // reset global variables
- this.blockConnectingEdgeSelection = false;
- this.forceAppendSelection = false;
- if (this.editMode == true) {
- while (this.manipulationDiv.hasChildNodes()) {
- this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);
- }
- // add the icons to the manipulator div
- this.manipulationDiv.innerHTML = "" +
- "" +
- ""+this.constants.labels['add'] +"" +
- "" +
- "" +
- ""+this.constants.labels['link'] +"";
- if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) {
- this.manipulationDiv.innerHTML += "" +
- "" +
- "" +
- ""+this.constants.labels['editNode'] +"";
- }
- else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) {
- this.manipulationDiv.innerHTML += "" +
- "" +
- "" +
- ""+this.constants.labels['editEdge'] +"";
- }
- if (this._selectionIsEmpty() == false) {
- this.manipulationDiv.innerHTML += "" +
- "" +
- "" +
- ""+this.constants.labels['del'] +"";
- }
+/***/ },
+/* 114 */
+/***/ function(module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : uzbek
+ // author : Sardor Muminov : https://github.com/muminoff
- // bind the icons
- var addNodeButton = document.getElementById("network-manipulate-addNode");
- addNodeButton.onclick = this._createAddNodeToolbar.bind(this);
- var addEdgeButton = document.getElementById("network-manipulate-connectNode");
- addEdgeButton.onclick = this._createAddEdgeToolbar.bind(this);
- if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) {
- var editButton = document.getElementById("network-manipulate-editNode");
- editButton.onclick = this._editNode.bind(this);
- }
- else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) {
- var editButton = document.getElementById("network-manipulate-editEdge");
- editButton.onclick = this._createEditEdgeToolbar.bind(this);
- }
- if (this._selectionIsEmpty() == false) {
- var deleteButton = document.getElementById("network-manipulate-delete");
- deleteButton.onclick = this._deleteSelected.bind(this);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
}
- var closeDiv = document.getElementById("network-manipulation-closeDiv");
- closeDiv.onclick = this._toggleEditMode.bind(this);
-
- this.boundFunction = this._createManipulatorBar.bind(this);
- this.on('select', this.boundFunction);
- }
- else {
- this.editModeDiv.innerHTML = "" +
- "" +
- "" + this.constants.labels['edit'] + "";
- var editModeButton = document.getElementById("network-manipulate-editModeButton");
- editModeButton.onclick = this._toggleEditMode.bind(this);
- }
- };
-
+ }(function (moment) {
+ return moment.lang('uz', {
+ months : "январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),
+ monthsShort : "янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),
+ weekdays : "Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"),
+ weekdaysShort : "Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"),
+ weekdaysMin : "Як_Ду_Се_Чо_Па_Жу_Ша".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM YYYY",
+ LLL : "D MMMM YYYY LT",
+ LLLL : "D MMMM YYYY, dddd LT"
+ },
+ calendar : {
+ sameDay : '[Бугун соат] LT [да]',
+ nextDay : '[Эртага] LT [да]',
+ nextWeek : 'dddd [куни соат] LT [да]',
+ lastDay : '[Кеча соат] LT [да]',
+ lastWeek : '[Утган] dddd [куни соат] LT [да]',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : "Якин %s ичида",
+ past : "Бир неча %s олдин",
+ s : "фурсат",
+ m : "бир дакика",
+ mm : "%d дакика",
+ h : "бир соат",
+ hh : "%d соат",
+ d : "бир кун",
+ dd : "%d кун",
+ M : "бир ой",
+ MM : "%d ой",
+ y : "бир йил",
+ yy : "%d йил"
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- /**
- * Create the toolbar for adding Nodes
- *
- * @private
- */
- exports._createAddNodeToolbar = function() {
- // clear the toolbar
- this._clearManipulatorBar();
- if (this.boundFunction) {
- this.off('select', this.boundFunction);
- }
+/***/ },
+/* 115 */
+/***/ function(module, exports, __webpack_require__) {
- // create the toolbar contents
- this.manipulationDiv.innerHTML = "" +
- "" +
- "" + this.constants.labels['back'] + " " +
- "" +
- "" +
- "" + this.constants.labels['addDescription'] + "";
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : vietnamese (vi)
+ // author : Bang Nguyen : https://github.com/bangnk
- // bind the icon
- var backButton = document.getElementById("network-manipulate-back");
- backButton.onclick = this._createManipulatorBar.bind(this);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('vi', {
+ months : "tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),
+ monthsShort : "Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),
+ weekdays : "chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),
+ weekdaysShort : "CN_T2_T3_T4_T5_T6_T7".split("_"),
+ weekdaysMin : "CN_T2_T3_T4_T5_T6_T7".split("_"),
+ longDateFormat : {
+ LT : "HH:mm",
+ L : "DD/MM/YYYY",
+ LL : "D MMMM [năm] YYYY",
+ LLL : "D MMMM [năm] YYYY LT",
+ LLLL : "dddd, D MMMM [năm] YYYY LT",
+ l : "DD/M/YYYY",
+ ll : "D MMM YYYY",
+ lll : "D MMM YYYY LT",
+ llll : "ddd, D MMM YYYY LT"
+ },
+ calendar : {
+ sameDay: "[Hôm nay lúc] LT",
+ nextDay: '[Ngày mai lúc] LT',
+ nextWeek: 'dddd [tuần tới lúc] LT',
+ lastDay: '[Hôm qua lúc] LT',
+ lastWeek: 'dddd [tuần rồi lúc] LT',
+ sameElse: 'L'
+ },
+ relativeTime : {
+ future : "%s tới",
+ past : "%s trước",
+ s : "vài giây",
+ m : "một phút",
+ mm : "%d phút",
+ h : "một giờ",
+ hh : "%d giờ",
+ d : "một ngày",
+ dd : "%d ngày",
+ M : "một tháng",
+ MM : "%d tháng",
+ y : "một năm",
+ yy : "%d năm"
+ },
+ ordinal : function (number) {
+ return number;
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- // we use the boundFunction so we can reference it when we unbind it from the "select" event.
- this.boundFunction = this._addNode.bind(this);
- this.on('select', this.boundFunction);
- };
+/***/ },
+/* 116 */
+/***/ function(module, exports, __webpack_require__) {
- /**
- * create the toolbar to connect nodes
- *
- * @private
- */
- exports._createAddEdgeToolbar = function() {
- // clear the toolbar
- this._clearManipulatorBar();
- this._unselectAll(true);
- this.freezeSimulation = true;
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : chinese
+ // author : suupic : https://github.com/suupic
+ // author : Zeno Zeng : https://github.com/zenozeng
- if (this.boundFunction) {
- this.off('select', this.boundFunction);
- }
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('zh-cn', {
+ months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
+ monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
+ weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
+ weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"),
+ weekdaysMin : "日_一_二_三_四_五_六".split("_"),
+ longDateFormat : {
+ LT : "Ah点mm",
+ L : "YYYY-MM-DD",
+ LL : "YYYY年MMMD日",
+ LLL : "YYYY年MMMD日LT",
+ LLLL : "YYYY年MMMD日ddddLT",
+ l : "YYYY-MM-DD",
+ ll : "YYYY年MMMD日",
+ lll : "YYYY年MMMD日LT",
+ llll : "YYYY年MMMD日ddddLT"
+ },
+ meridiem : function (hour, minute, isLower) {
+ var hm = hour * 100 + minute;
+ if (hm < 600) {
+ return "凌晨";
+ } else if (hm < 900) {
+ return "早上";
+ } else if (hm < 1130) {
+ return "上午";
+ } else if (hm < 1230) {
+ return "中午";
+ } else if (hm < 1800) {
+ return "下午";
+ } else {
+ return "晚上";
+ }
+ },
+ calendar : {
+ sameDay : function () {
+ return this.minutes() === 0 ? "[今天]Ah[点整]" : "[今天]LT";
+ },
+ nextDay : function () {
+ return this.minutes() === 0 ? "[明天]Ah[点整]" : "[明天]LT";
+ },
+ lastDay : function () {
+ return this.minutes() === 0 ? "[昨天]Ah[点整]" : "[昨天]LT";
+ },
+ nextWeek : function () {
+ var startOfWeek, prefix;
+ startOfWeek = moment().startOf('week');
+ prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';
+ return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm";
+ },
+ lastWeek : function () {
+ var startOfWeek, prefix;
+ startOfWeek = moment().startOf('week');
+ prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]';
+ return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm";
+ },
+ sameElse : 'LL'
+ },
+ ordinal : function (number, period) {
+ switch (period) {
+ case "d":
+ case "D":
+ case "DDD":
+ return number + "日";
+ case "M":
+ return number + "月";
+ case "w":
+ case "W":
+ return number + "周";
+ default:
+ return number;
+ }
+ },
+ relativeTime : {
+ future : "%s内",
+ past : "%s前",
+ s : "几秒",
+ m : "1分钟",
+ mm : "%d分钟",
+ h : "1小时",
+ hh : "%d小时",
+ d : "1天",
+ dd : "%d天",
+ M : "1个月",
+ MM : "%d个月",
+ y : "1年",
+ yy : "%d年"
+ },
+ week : {
+ // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+ }));
- this._unselectAll();
- this.forceAppendSelection = false;
- this.blockConnectingEdgeSelection = true;
- this.manipulationDiv.innerHTML = "" +
- "" +
- "" + this.constants.labels['back'] + " " +
- "" +
- "" +
- "" + this.constants.labels['linkDescription'] + "";
+/***/ },
+/* 117 */
+/***/ function(module, exports, __webpack_require__) {
- // bind the icon
- var backButton = document.getElementById("network-manipulate-back");
- backButton.onclick = this._createManipulatorBar.bind(this);
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
+ // language : traditional chinese (zh-tw)
+ // author : Ben : https://github.com/ben-lin
- // we use the boundFunction so we can reference it when we unbind it from the "select" event.
- this.boundFunction = this._handleConnect.bind(this);
- this.on('select', this.boundFunction);
+ (function (factory) {
+ if (true) {
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('../moment')); // Node
+ } else {
+ factory(window.moment); // Browser global
+ }
+ }(function (moment) {
+ return moment.lang('zh-tw', {
+ months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
+ monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
+ weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
+ weekdaysShort : "週日_週一_週二_週三_週四_週五_週六".split("_"),
+ weekdaysMin : "日_一_二_三_四_五_六".split("_"),
+ longDateFormat : {
+ LT : "Ah點mm",
+ L : "YYYY年MMMD日",
+ LL : "YYYY年MMMD日",
+ LLL : "YYYY年MMMD日LT",
+ LLLL : "YYYY年MMMD日ddddLT",
+ l : "YYYY年MMMD日",
+ ll : "YYYY年MMMD日",
+ lll : "YYYY年MMMD日LT",
+ llll : "YYYY年MMMD日ddddLT"
+ },
+ meridiem : function (hour, minute, isLower) {
+ var hm = hour * 100 + minute;
+ if (hm < 900) {
+ return "早上";
+ } else if (hm < 1130) {
+ return "上午";
+ } else if (hm < 1230) {
+ return "中午";
+ } else if (hm < 1800) {
+ return "下午";
+ } else {
+ return "晚上";
+ }
+ },
+ calendar : {
+ sameDay : '[今天]LT',
+ nextDay : '[明天]LT',
+ nextWeek : '[下]ddddLT',
+ lastDay : '[昨天]LT',
+ lastWeek : '[上]ddddLT',
+ sameElse : 'L'
+ },
+ ordinal : function (number, period) {
+ switch (period) {
+ case "d" :
+ case "D" :
+ case "DDD" :
+ return number + "日";
+ case "M" :
+ return number + "月";
+ case "w" :
+ case "W" :
+ return number + "週";
+ default :
+ return number;
+ }
+ },
+ relativeTime : {
+ future : "%s內",
+ past : "%s前",
+ s : "幾秒",
+ m : "一分鐘",
+ mm : "%d分鐘",
+ h : "一小時",
+ hh : "%d小時",
+ d : "一天",
+ dd : "%d天",
+ M : "一個月",
+ MM : "%d個月",
+ y : "一年",
+ yy : "%d年"
+ }
+ });
+ }));
- // temporarily overload functions
- this.cachedFunctions["_handleTouch"] = this._handleTouch;
- this.cachedFunctions["_handleOnRelease"] = this._handleOnRelease;
- this._handleTouch = this._handleConnect;
- this._handleOnRelease = this._finishConnect;
- // redraw to show the unselect
- this._redraw();
- };
+/***/ },
+/* 118 */
+/***/ function(module, exports, __webpack_require__) {
/**
- * create the toolbar to edit edges
+ * Copyright 2012 Craig Campbell
*
- * @private
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Mousetrap is a simple keyboard shortcut library for Javascript with
+ * no external dependencies
+ *
+ * @version 1.1.2
+ * @url craig.is/killing/mice
*/
- exports._createEditEdgeToolbar = function() {
- // clear the toolbar
- this._clearManipulatorBar();
- this.controlNodesActive = true;
- if (this.boundFunction) {
- this.off('select', this.boundFunction);
- }
+ /**
+ * mapping of special keycodes to their corresponding keys
+ *
+ * everything in this dictionary cannot use keypress events
+ * so it has to be here to map to the correct keycodes for
+ * keyup/keydown events
+ *
+ * @type {Object}
+ */
+ var _MAP = {
+ 8: 'backspace',
+ 9: 'tab',
+ 13: 'enter',
+ 16: 'shift',
+ 17: 'ctrl',
+ 18: 'alt',
+ 20: 'capslock',
+ 27: 'esc',
+ 32: 'space',
+ 33: 'pageup',
+ 34: 'pagedown',
+ 35: 'end',
+ 36: 'home',
+ 37: 'left',
+ 38: 'up',
+ 39: 'right',
+ 40: 'down',
+ 45: 'ins',
+ 46: 'del',
+ 91: 'meta',
+ 93: 'meta',
+ 224: 'meta'
+ },
- this.edgeBeingEdited = this._getSelectedEdge();
- this.edgeBeingEdited._enableControlNodes();
+ /**
+ * mapping for special characters so they can support
+ *
+ * this dictionary is only used incase you want to bind a
+ * keyup or keydown event to one of these keys
+ *
+ * @type {Object}
+ */
+ _KEYCODE_MAP = {
+ 106: '*',
+ 107: '+',
+ 109: '-',
+ 110: '.',
+ 111 : '/',
+ 186: ';',
+ 187: '=',
+ 188: ',',
+ 189: '-',
+ 190: '.',
+ 191: '/',
+ 192: '`',
+ 219: '[',
+ 220: '\\',
+ 221: ']',
+ 222: '\''
+ },
- this.manipulationDiv.innerHTML = "" +
- "" +
- "" + this.constants.labels['back'] + " " +
- "" +
- "" +
- "" + this.constants.labels['editEdgeDescription'] + "";
+ /**
+ * this is a mapping of keys that require shift on a US keypad
+ * back to the non shift equivelents
+ *
+ * this is so you can use keyup events with these keys
+ *
+ * note that this will only work reliably on US keyboards
+ *
+ * @type {Object}
+ */
+ _SHIFT_MAP = {
+ '~': '`',
+ '!': '1',
+ '@': '2',
+ '#': '3',
+ '$': '4',
+ '%': '5',
+ '^': '6',
+ '&': '7',
+ '*': '8',
+ '(': '9',
+ ')': '0',
+ '_': '-',
+ '+': '=',
+ ':': ';',
+ '\"': '\'',
+ '<': ',',
+ '>': '.',
+ '?': '/',
+ '|': '\\'
+ },
- // bind the icon
- var backButton = document.getElementById("network-manipulate-back");
- backButton.onclick = this._createManipulatorBar.bind(this);
+ /**
+ * this is a list of special strings you can use to map
+ * to modifier keys when you specify your keyboard shortcuts
+ *
+ * @type {Object}
+ */
+ _SPECIAL_ALIASES = {
+ 'option': 'alt',
+ 'command': 'meta',
+ 'return': 'enter',
+ 'escape': 'esc'
+ },
- // temporarily overload functions
- this.cachedFunctions["_handleTouch"] = this._handleTouch;
- this.cachedFunctions["_handleOnRelease"] = this._handleOnRelease;
- this.cachedFunctions["_handleTap"] = this._handleTap;
- this.cachedFunctions["_handleDragStart"] = this._handleDragStart;
- this.cachedFunctions["_handleOnDrag"] = this._handleOnDrag;
- this._handleTouch = this._selectControlNode;
- this._handleTap = function () {};
- this._handleOnDrag = this._controlNodeDrag;
- this._handleDragStart = function () {}
- this._handleOnRelease = this._releaseControlNode;
+ /**
+ * variable to store the flipped version of _MAP from above
+ * needed to check if we should use keypress or not when no action
+ * is specified
+ *
+ * @type {Object|undefined}
+ */
+ _REVERSE_MAP,
- // redraw to show the unselect
- this._redraw();
- };
+ /**
+ * a list of all the callbacks setup via Mousetrap.bind()
+ *
+ * @type {Object}
+ */
+ _callbacks = {},
+ /**
+ * direct map of string combinations to callbacks used for trigger()
+ *
+ * @type {Object}
+ */
+ _direct_map = {},
+ /**
+ * keeps track of what level each sequence is at since multiple
+ * sequences can start out with the same sequence
+ *
+ * @type {Object}
+ */
+ _sequence_levels = {},
+ /**
+ * variable to store the setTimeout call
+ *
+ * @type {null|number}
+ */
+ _reset_timer,
+ /**
+ * temporary state where we will ignore the next keyup
+ *
+ * @type {boolean|string}
+ */
+ _ignore_next_keyup = false,
- /**
- * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
- * to walk the user through the process.
- *
- * @private
- */
- exports._selectControlNode = function(pointer) {
- this.edgeBeingEdited.controlNodes.from.unselect();
- this.edgeBeingEdited.controlNodes.to.unselect();
- this.selectedControlNode = this.edgeBeingEdited._getSelectedControlNode(this._XconvertDOMtoCanvas(pointer.x),this._YconvertDOMtoCanvas(pointer.y));
- if (this.selectedControlNode !== null) {
- this.selectedControlNode.select();
- this.freezeSimulation = true;
- }
- this._redraw();
- };
+ /**
+ * are we currently inside of a sequence?
+ * type of action ("keyup" or "keydown" or "keypress") or false
+ *
+ * @type {boolean|string}
+ */
+ _inside_sequence = false;
- /**
- * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
- * to walk the user through the process.
- *
- * @private
- */
- exports._controlNodeDrag = function(event) {
- var pointer = this._getPointer(event.gesture.center);
- if (this.selectedControlNode !== null && this.selectedControlNode !== undefined) {
- this.selectedControlNode.x = this._XconvertDOMtoCanvas(pointer.x);
- this.selectedControlNode.y = this._YconvertDOMtoCanvas(pointer.y);
+ /**
+ * loop through the f keys, f1 to f19 and add them to the map
+ * programatically
+ */
+ for (var i = 1; i < 20; ++i) {
+ _MAP[111 + i] = 'f' + i;
}
- this._redraw();
- };
- exports._releaseControlNode = function(pointer) {
- var newNode = this._getNodeAt(pointer);
- if (newNode != null) {
- if (this.edgeBeingEdited.controlNodes.from.selected == true) {
- this._editEdge(newNode.id, this.edgeBeingEdited.to.id);
- this.edgeBeingEdited.controlNodes.from.unselect();
- }
- if (this.edgeBeingEdited.controlNodes.to.selected == true) {
- this._editEdge(this.edgeBeingEdited.from.id, newNode.id);
- this.edgeBeingEdited.controlNodes.to.unselect();
- }
- }
- else {
- this.edgeBeingEdited._restoreControlNodes();
+ /**
+ * loop through to map numbers on the numeric keypad
+ */
+ for (i = 0; i <= 9; ++i) {
+ _MAP[i + 96] = i;
}
- this.freezeSimulation = false;
- this._redraw();
- };
- /**
- * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
- * to walk the user through the process.
- *
- * @private
- */
- exports._handleConnect = function(pointer) {
- if (this._getSelectedNodeCount() == 0) {
- var node = this._getNodeAt(pointer);
- if (node != null) {
- if (node.clusterSize > 1) {
- alert("Cannot create edges to a cluster.")
+ /**
+ * cross browser add event method
+ *
+ * @param {Element|HTMLDocument} object
+ * @param {string} type
+ * @param {Function} callback
+ * @returns void
+ */
+ function _addEvent(object, type, callback) {
+ if (object.addEventListener) {
+ return object.addEventListener(type, callback, false);
}
- else {
- this._selectObject(node,false);
- // create a node the temporary line can look at
- this.sectors['support']['nodes']['targetNode'] = new Node({id:'targetNode'},{},{},this.constants);
- this.sectors['support']['nodes']['targetNode'].x = node.x;
- this.sectors['support']['nodes']['targetNode'].y = node.y;
- this.sectors['support']['nodes']['targetViaNode'] = new Node({id:'targetViaNode'},{},{},this.constants);
- this.sectors['support']['nodes']['targetViaNode'].x = node.x;
- this.sectors['support']['nodes']['targetViaNode'].y = node.y;
- this.sectors['support']['nodes']['targetViaNode'].parentEdgeId = "connectionEdge";
-
- // create a temporary edge
- this.edges['connectionEdge'] = new Edge({id:"connectionEdge",from:node.id,to:this.sectors['support']['nodes']['targetNode'].id}, this, this.constants);
- this.edges['connectionEdge'].from = node;
- this.edges['connectionEdge'].connected = true;
- this.edges['connectionEdge'].smooth = true;
- this.edges['connectionEdge'].selected = true;
- this.edges['connectionEdge'].to = this.sectors['support']['nodes']['targetNode'];
- this.edges['connectionEdge'].via = this.sectors['support']['nodes']['targetViaNode'];
-
- this.cachedFunctions["_handleOnDrag"] = this._handleOnDrag;
- this._handleOnDrag = function(event) {
- var pointer = this._getPointer(event.gesture.center);
- this.sectors['support']['nodes']['targetNode'].x = this._XconvertDOMtoCanvas(pointer.x);
- this.sectors['support']['nodes']['targetNode'].y = this._YconvertDOMtoCanvas(pointer.y);
- this.sectors['support']['nodes']['targetViaNode'].x = 0.5 * (this._XconvertDOMtoCanvas(pointer.x) + this.edges['connectionEdge'].from.x);
- this.sectors['support']['nodes']['targetViaNode'].y = this._YconvertDOMtoCanvas(pointer.y);
- };
- this.moving = true;
- this.start();
- }
- }
+ object.attachEvent('on' + type, callback);
}
- };
-
- exports._finishConnect = function(pointer) {
- if (this._getSelectedNodeCount() == 1) {
-
- // restore the drag function
- this._handleOnDrag = this.cachedFunctions["_handleOnDrag"];
- delete this.cachedFunctions["_handleOnDrag"];
-
- // remember the edge id
- var connectFromId = this.edges['connectionEdge'].fromId;
- // remove the temporary nodes and edge
- delete this.edges['connectionEdge'];
- delete this.sectors['support']['nodes']['targetNode'];
- delete this.sectors['support']['nodes']['targetViaNode'];
+ /**
+ * takes the event and returns the key character
+ *
+ * @param {Event} e
+ * @return {string}
+ */
+ function _characterFromEvent(e) {
- var node = this._getNodeAt(pointer);
- if (node != null) {
- if (node.clusterSize > 1) {
- alert("Cannot create edges to a cluster.")
- }
- else {
- this._createEdge(connectFromId,node.id);
- this._createManipulatorBar();
+ // for keypress events we should return the character as is
+ if (e.type == 'keypress') {
+ return String.fromCharCode(e.which);
}
- }
- this._unselectAll();
- }
- };
-
- /**
- * Adds a node on the specified location
- */
- exports._addNode = function() {
- if (this._selectionIsEmpty() && this.editMode == true) {
- var positionObject = this._pointerToPositionObject(this.pointerPosition);
- var defaultData = {id:util.randomUUID(),x:positionObject.left,y:positionObject.top,label:"new",allowedToMoveX:true,allowedToMoveY:true};
- if (this.triggerFunctions.add) {
- if (this.triggerFunctions.add.length == 2) {
- var me = this;
- this.triggerFunctions.add(defaultData, function(finalizedData) {
- me.nodesData.add(finalizedData);
- me._createManipulatorBar();
- me.moving = true;
- me.start();
- });
+ // for non keypress events the special maps are needed
+ if (_MAP[e.which]) {
+ return _MAP[e.which];
}
- else {
- alert(this.constants.labels['addError']);
- this._createManipulatorBar();
- this.moving = true;
- this.start();
+
+ if (_KEYCODE_MAP[e.which]) {
+ return _KEYCODE_MAP[e.which];
}
- }
- else {
- this.nodesData.add(defaultData);
- this._createManipulatorBar();
- this.moving = true;
- this.start();
- }
+
+ // if it is not in the special map
+ return String.fromCharCode(e.which).toLowerCase();
}
- };
+ /**
+ * should we stop this event before firing off callbacks
+ *
+ * @param {Event} e
+ * @return {boolean}
+ */
+ function _stop(e) {
+ var element = e.target || e.srcElement,
+ tag_name = element.tagName;
- /**
- * connect two nodes with a new edge.
- *
- * @private
- */
- exports._createEdge = function(sourceNodeId,targetNodeId) {
- if (this.editMode == true) {
- var defaultData = {from:sourceNodeId, to:targetNodeId};
- if (this.triggerFunctions.connect) {
- if (this.triggerFunctions.connect.length == 2) {
- var me = this;
- this.triggerFunctions.connect(defaultData, function(finalizedData) {
- me.edgesData.add(finalizedData);
- me.moving = true;
- me.start();
- });
- }
- else {
- alert(this.constants.labels["linkError"]);
- this.moving = true;
- this.start();
+ // if the element has the class "mousetrap" then no need to stop
+ if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
+ return false;
}
- }
- else {
- this.edgesData.add(defaultData);
- this.moving = true;
- this.start();
- }
- }
- };
- /**
- * connect two nodes with a new edge.
- *
- * @private
- */
- exports._editEdge = function(sourceNodeId,targetNodeId) {
- if (this.editMode == true) {
- var defaultData = {id: this.edgeBeingEdited.id, from:sourceNodeId, to:targetNodeId};
- if (this.triggerFunctions.editEdge) {
- if (this.triggerFunctions.editEdge.length == 2) {
- var me = this;
- this.triggerFunctions.editEdge(defaultData, function(finalizedData) {
- me.edgesData.update(finalizedData);
- me.moving = true;
- me.start();
- });
- }
- else {
- alert(this.constants.labels["linkError"]);
- this.moving = true;
- this.start();
- }
- }
- else {
- this.edgesData.update(defaultData);
- this.moving = true;
- this.start();
- }
+ // stop for input, select, and textarea
+ return tag_name == 'INPUT' || tag_name == 'SELECT' || tag_name == 'TEXTAREA' || (element.contentEditable && element.contentEditable == 'true');
}
- };
- /**
- * Create the toolbar to edit the selected node. The label and the color can be changed. Other colors are derived from the chosen color.
- *
- * @private
- */
- exports._editNode = function() {
- if (this.triggerFunctions.edit && this.editMode == true) {
- var node = this._getSelectedNode();
- var data = {id:node.id,
- label: node.label,
- group: node.group,
- shape: node.shape,
- color: {
- background:node.color.background,
- border:node.color.border,
- highlight: {
- background:node.color.highlight.background,
- border:node.color.highlight.border
- }
- }};
- if (this.triggerFunctions.edit.length == 2) {
- var me = this;
- this.triggerFunctions.edit(data, function (finalizedData) {
- me.nodesData.update(finalizedData);
- me._createManipulatorBar();
- me.moving = true;
- me.start();
- });
- }
- else {
- alert(this.constants.labels["editError"]);
- }
- }
- else {
- alert(this.constants.labels["editBoundError"]);
+ /**
+ * checks if two arrays are equal
+ *
+ * @param {Array} modifiers1
+ * @param {Array} modifiers2
+ * @returns {boolean}
+ */
+ function _modifiersMatch(modifiers1, modifiers2) {
+ return modifiers1.sort().join(',') === modifiers2.sort().join(',');
}
- };
+ /**
+ * resets all sequence counters except for the ones passed in
+ *
+ * @param {Object} do_not_reset
+ * @returns void
+ */
+ function _resetSequences(do_not_reset) {
+ do_not_reset = do_not_reset || {};
+ var active_sequences = false,
+ key;
+ for (key in _sequence_levels) {
+ if (do_not_reset[key]) {
+ active_sequences = true;
+ continue;
+ }
+ _sequence_levels[key] = 0;
+ }
- /**
- * delete everything in the selection
- *
- * @private
- */
- exports._deleteSelected = function() {
- if (!this._selectionIsEmpty() && this.editMode == true) {
- if (!this._clusterInSelection()) {
- var selectedNodes = this.getSelectedNodes();
- var selectedEdges = this.getSelectedEdges();
- if (this.triggerFunctions.del) {
- var me = this;
- var data = {nodes: selectedNodes, edges: selectedEdges};
- if (this.triggerFunctions.del.length = 2) {
- this.triggerFunctions.del(data, function (finalizedData) {
- me.edgesData.remove(finalizedData.edges);
- me.nodesData.remove(finalizedData.nodes);
- me._unselectAll();
- me.moving = true;
- me.start();
- });
- }
- else {
- alert(this.constants.labels["deleteError"])
- }
+ if (!active_sequences) {
+ _inside_sequence = false;
+ }
+ }
+
+ /**
+ * finds all callbacks that match based on the keycode, modifiers,
+ * and action
+ *
+ * @param {string} character
+ * @param {Array} modifiers
+ * @param {string} action
+ * @param {boolean=} remove - should we remove any matches
+ * @param {string=} combination
+ * @returns {Array}
+ */
+ function _getMatches(character, modifiers, action, remove, combination) {
+ var i,
+ callback,
+ matches = [];
+
+ // if there are no events related to this keycode
+ if (!_callbacks[character]) {
+ return [];
}
- else {
- this.edgesData.remove(selectedEdges);
- this.nodesData.remove(selectedNodes);
- this._unselectAll();
- this.moving = true;
- this.start();
+
+ // if a modifier key is coming up on its own we should allow it
+ if (action == 'keyup' && _isModifier(character)) {
+ modifiers = [character];
}
- }
- else {
- alert(this.constants.labels["deleteClusterError"]);
- }
- }
- };
+ // loop through all callbacks for the key that was pressed
+ // and see if any of them match
+ for (i = 0; i < _callbacks[character].length; ++i) {
+ callback = _callbacks[character][i];
-/***/ },
-/* 51 */
-/***/ function(module, exports, __webpack_require__) {
+ // if this is a sequence but it is not at the right level
+ // then move onto the next match
+ if (callback.seq && _sequence_levels[callback.seq] != callback.level) {
+ continue;
+ }
- exports._cleanNavigation = function() {
- // clean up previous navigation items
- var wrapper = document.getElementById('network-navigation_wrapper');
- if (wrapper != null) {
- this.containerElement.removeChild(wrapper);
- }
- document.onmouseup = null;
- };
+ // if the action we are looking for doesn't match the action we got
+ // then we should keep going
+ if (action != callback.action) {
+ continue;
+ }
- /**
- * Creation of the navigation controls nodes. They are drawn over the rest of the nodes and are not affected by scale and translation
- * they have a triggerFunction which is called on click. If the position of the navigation controls is dependent
- * on this.frame.canvas.clientWidth or this.frame.canvas.clientHeight, we flag horizontalAlignLeft and verticalAlignTop false.
- * This means that the location will be corrected by the _relocateNavigation function on a size change of the canvas.
- *
- * @private
- */
- exports._loadNavigationElements = function() {
- this._cleanNavigation();
+ // if this is a keypress event that means that we need to only
+ // look at the character, otherwise check the modifiers as
+ // well
+ if (action == 'keypress' || _modifiersMatch(modifiers, callback.modifiers)) {
- this.navigationDivs = {};
- var navigationDivs = ['up','down','left','right','zoomIn','zoomOut','zoomExtends'];
- var navigationDivActions = ['_moveUp','_moveDown','_moveLeft','_moveRight','_zoomIn','_zoomOut','zoomExtent'];
+ // remove is used so if you change your mind and call bind a
+ // second time with a new function the first one is overwritten
+ if (remove && callback.combo == combination) {
+ _callbacks[character].splice(i, 1);
+ }
- this.navigationDivs['wrapper'] = document.createElement('div');
- this.navigationDivs['wrapper'].id = "network-navigation_wrapper";
- this.navigationDivs['wrapper'].style.position = "absolute";
- this.navigationDivs['wrapper'].style.width = this.frame.canvas.clientWidth + "px";
- this.navigationDivs['wrapper'].style.height = this.frame.canvas.clientHeight + "px";
- this.containerElement.insertBefore(this.navigationDivs['wrapper'],this.frame);
+ matches.push(callback);
+ }
+ }
- for (var i = 0; i < navigationDivs.length; i++) {
- this.navigationDivs[navigationDivs[i]] = document.createElement('div');
- this.navigationDivs[navigationDivs[i]].id = "network-navigation_" + navigationDivs[i];
- this.navigationDivs[navigationDivs[i]].className = "network-navigation " + navigationDivs[i];
- this.navigationDivs['wrapper'].appendChild(this.navigationDivs[navigationDivs[i]]);
- this.navigationDivs[navigationDivs[i]].onmousedown = this[navigationDivActions[i]].bind(this);
+ return matches;
}
- document.onmouseup = this._stopMovement.bind(this);
- };
+ /**
+ * takes a key event and figures out what the modifiers are
+ *
+ * @param {Event} e
+ * @returns {Array}
+ */
+ function _eventModifiers(e) {
+ var modifiers = [];
- /**
- * this stops all movement induced by the navigation buttons
- *
- * @private
- */
- exports._stopMovement = function() {
- this._xStopMoving();
- this._yStopMoving();
- this._stopZoom();
- };
+ if (e.shiftKey) {
+ modifiers.push('shift');
+ }
+ if (e.altKey) {
+ modifiers.push('alt');
+ }
- /**
- * stops the actions performed by page up and down etc.
- *
- * @param event
- * @private
- */
- exports._preventDefault = function(event) {
- if (event !== undefined) {
- if (event.preventDefault) {
- event.preventDefault();
- } else {
- event.returnValue = false;
- }
- }
- };
+ if (e.ctrlKey) {
+ modifiers.push('ctrl');
+ }
+ if (e.metaKey) {
+ modifiers.push('meta');
+ }
- /**
- * move the screen up
- * By using the increments, instead of adding a fixed number to the translation, we keep fluent and
- * instant movement. The onKeypress event triggers immediately, then pauses, then triggers frequently
- * To avoid this behaviour, we do the translation in the start loop.
- *
- * @private
- */
- exports._moveUp = function(event) {
- this.yIncrement = this.constants.keyboard.speed.y;
- this.start(); // if there is no node movement, the calculation wont be done
- this._preventDefault(event);
- if (this.navigationDivs) {
- this.navigationDivs['up'].className += " active";
+ return modifiers;
}
- };
+ /**
+ * actually calls the callback function
+ *
+ * if your callback function returns false this will use the jquery
+ * convention - prevent default and stop propogation on the event
+ *
+ * @param {Function} callback
+ * @param {Event} e
+ * @returns void
+ */
+ function _fireCallback(callback, e) {
+ if (callback(e) === false) {
+ if (e.preventDefault) {
+ e.preventDefault();
+ }
+
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ }
- /**
- * move the screen down
- * @private
- */
- exports._moveDown = function(event) {
- this.yIncrement = -this.constants.keyboard.speed.y;
- this.start(); // if there is no node movement, the calculation wont be done
- this._preventDefault(event);
- if (this.navigationDivs) {
- this.navigationDivs['down'].className += " active";
+ e.returnValue = false;
+ e.cancelBubble = true;
+ }
}
- };
+ /**
+ * handles a character key event
+ *
+ * @param {string} character
+ * @param {Event} e
+ * @returns void
+ */
+ function _handleCharacter(character, e) {
- /**
- * move the screen left
- * @private
- */
- exports._moveLeft = function(event) {
- this.xIncrement = this.constants.keyboard.speed.x;
- this.start(); // if there is no node movement, the calculation wont be done
- this._preventDefault(event);
- if (this.navigationDivs) {
- this.navigationDivs['left'].className += " active";
- }
- };
+ // if this event should not happen stop here
+ if (_stop(e)) {
+ return;
+ }
+ var callbacks = _getMatches(character, _eventModifiers(e), e.type),
+ i,
+ do_not_reset = {},
+ processed_sequence_callback = false;
- /**
- * move the screen right
- * @private
- */
- exports._moveRight = function(event) {
- this.xIncrement = -this.constants.keyboard.speed.y;
- this.start(); // if there is no node movement, the calculation wont be done
- this._preventDefault(event);
- if (this.navigationDivs) {
- this.navigationDivs['right'].className += " active";
- }
- };
+ // loop through matching callbacks for this key event
+ for (i = 0; i < callbacks.length; ++i) {
+ // fire for all sequence callbacks
+ // this is because if for example you have multiple sequences
+ // bound such as "g i" and "g t" they both need to fire the
+ // callback for matching g cause otherwise you can only ever
+ // match the first one
+ if (callbacks[i].seq) {
+ processed_sequence_callback = true;
- /**
- * Zoom in, using the same method as the movement.
- * @private
- */
- exports._zoomIn = function(event) {
- this.zoomIncrement = this.constants.keyboard.speed.zoom;
- this.start(); // if there is no node movement, the calculation wont be done
- this._preventDefault(event);
- if (this.navigationDivs) {
- this.navigationDivs['zoomIn'].className += " active";
- }
- };
+ // keep a list of which sequences were matches for later
+ do_not_reset[callbacks[i].seq] = 1;
+ _fireCallback(callbacks[i].callback, e);
+ continue;
+ }
+ // if there were no sequence matches but we are still here
+ // that means this is a regular match so we should fire that
+ if (!processed_sequence_callback && !_inside_sequence) {
+ _fireCallback(callbacks[i].callback, e);
+ }
+ }
- /**
- * Zoom out
- * @private
- */
- exports._zoomOut = function() {
- this.zoomIncrement = -this.constants.keyboard.speed.zoom;
- this.start(); // if there is no node movement, the calculation wont be done
- this._preventDefault(event);
- if (this.navigationDivs) {
- this.navigationDivs['zoomOut'].className += " active";
+ // if you are inside of a sequence and the key you are pressing
+ // is not a modifier key then we should reset all sequences
+ // that were not matched by this key event
+ if (e.type == _inside_sequence && !_isModifier(character)) {
+ _resetSequences(do_not_reset);
+ }
}
- };
+ /**
+ * handles a keydown event
+ *
+ * @param {Event} e
+ * @returns void
+ */
+ function _handleKey(e) {
- /**
- * Stop zooming and unhighlight the zoom controls
- * @private
- */
- exports._stopZoom = function() {
- this.zoomIncrement = 0;
- if (this.navigationDivs) {
- this.navigationDivs['zoomIn'].className = this.navigationDivs['zoomIn'].className.replace(" active","");
- this.navigationDivs['zoomOut'].className = this.navigationDivs['zoomOut'].className.replace(" active","");
- }
- };
+ // normalize e.which for key events
+ // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion
+ e.which = typeof e.which == "number" ? e.which : e.keyCode;
+ var character = _characterFromEvent(e);
- /**
- * Stop moving in the Y direction and unHighlight the up and down
- * @private
- */
- exports._yStopMoving = function() {
- this.yIncrement = 0;
- if (this.navigationDivs) {
- this.navigationDivs['up'].className = this.navigationDivs['up'].className.replace(" active","");
- this.navigationDivs['down'].className = this.navigationDivs['down'].className.replace(" active","");
+ // no character found then stop
+ if (!character) {
+ return;
+ }
+
+ if (e.type == 'keyup' && _ignore_next_keyup == character) {
+ _ignore_next_keyup = false;
+ return;
+ }
+
+ _handleCharacter(character, e);
}
- };
+ /**
+ * determines if the keycode specified is a modifier key or not
+ *
+ * @param {string} key
+ * @returns {boolean}
+ */
+ function _isModifier(key) {
+ return key == 'shift' || key == 'ctrl' || key == 'alt' || key == 'meta';
+ }
- /**
- * Stop moving in the X direction and unHighlight left and right.
- * @private
- */
- exports._xStopMoving = function() {
- this.xIncrement = 0;
- if (this.navigationDivs) {
- this.navigationDivs['left'].className = this.navigationDivs['left'].className.replace(" active","");
- this.navigationDivs['right'].className = this.navigationDivs['right'].className.replace(" active","");
+ /**
+ * called to set a 1 second timeout on the specified sequence
+ *
+ * this is so after each key press in the sequence you have 1 second
+ * to press the next key before you have to start over
+ *
+ * @returns void
+ */
+ function _resetSequenceTimer() {
+ clearTimeout(_reset_timer);
+ _reset_timer = setTimeout(_resetSequences, 1000);
}
- };
+ /**
+ * reverses the map lookup so that we can look for specific keys
+ * to see what can and can't use keypress
+ *
+ * @return {Object}
+ */
+ function _getReverseMap() {
+ if (!_REVERSE_MAP) {
+ _REVERSE_MAP = {};
+ for (var key in _MAP) {
-/***/ },
-/* 52 */
-/***/ function(module, exports, __webpack_require__) {
+ // pull out the numeric keypad from here cause keypress should
+ // be able to detect the keys from the character
+ if (key > 95 && key < 112) {
+ continue;
+ }
- exports._resetLevels = function() {
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- var node = this.nodes[nodeId];
- if (node.preassignedLevel == false) {
- node.level = -1;
+ if (_MAP.hasOwnProperty(key)) {
+ _REVERSE_MAP[_MAP[key]] = key;
+ }
+ }
}
- }
+ return _REVERSE_MAP;
}
- };
- /**
- * This is the main function to layout the nodes in a hierarchical way.
- * It checks if the node details are supplied correctly
- *
- * @private
- */
- exports._setupHierarchicalLayout = function() {
- if (this.constants.hierarchicalLayout.enabled == true && this.nodeIndices.length > 0) {
- if (this.constants.hierarchicalLayout.direction == "RL" || this.constants.hierarchicalLayout.direction == "DU") {
- this.constants.hierarchicalLayout.levelSeparation *= -1;
- }
- else {
- this.constants.hierarchicalLayout.levelSeparation = Math.abs(this.constants.hierarchicalLayout.levelSeparation);
- }
+ /**
+ * picks the best action based on the key combination
+ *
+ * @param {string} key - character for key
+ * @param {Array} modifiers
+ * @param {string=} action passed in
+ */
+ function _pickBestAction(key, modifiers, action) {
- if (this.constants.hierarchicalLayout.direction == "RL" || this.constants.hierarchicalLayout.direction == "LR") {
- if (this.constants.smoothCurves.enabled == true) {
- this.constants.smoothCurves.type = "vertical";
- }
- }
- else {
- if (this.constants.smoothCurves.enabled == true) {
- this.constants.smoothCurves.type = "horizontal";
+ // if no action was picked in we should try to pick the one
+ // that we think would work best for this key
+ if (!action) {
+ action = _getReverseMap()[key] ? 'keydown' : 'keypress';
}
- }
- // get the size of the largest hubs and check if the user has defined a level for a node.
- var hubsize = 0;
- var node, nodeId;
- var definedLevel = false;
- var undefinedLevel = false;
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- node = this.nodes[nodeId];
- if (node.level != -1) {
- definedLevel = true;
- }
- else {
- undefinedLevel = true;
- }
- if (hubsize < node.edges.length) {
- hubsize = node.edges.length;
- }
+ // modifier keys don't work as expected with keypress,
+ // switch to keydown
+ if (action == 'keypress' && modifiers.length) {
+ action = 'keydown';
}
- }
- // if the user defined some levels but not all, alert and run without hierarchical layout
- if (undefinedLevel == true && definedLevel == true) {
- alert("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");
- this.zoomExtent(true,this.constants.clustering.enabled);
- if (!this.constants.clustering.enabled) {
- this.start();
- }
- }
- else {
- // setup the system to use hierarchical method.
- this._changeConstants();
+ return action;
+ }
- // define levels if undefined by the users. Based on hubsize
- if (undefinedLevel == true) {
- this._determineLevels(hubsize);
+ /**
+ * binds a key sequence to an event
+ *
+ * @param {string} combo - combo specified in bind call
+ * @param {Array} keys
+ * @param {Function} callback
+ * @param {string=} action
+ * @returns void
+ */
+ function _bindSequence(combo, keys, callback, action) {
+
+ // start off by adding a sequence level record for this combination
+ // and setting the level to 0
+ _sequence_levels[combo] = 0;
+
+ // if there is no action pick the best one for the first key
+ // in the sequence
+ if (!action) {
+ action = _pickBestAction(keys[0], []);
}
- // check the distribution of the nodes per level.
- var distribution = this._getDistribution();
- // place the nodes on the canvas. This also stablilizes the system.
- this._placeNodesByHierarchy(distribution);
+ /**
+ * callback to increase the sequence level for this sequence and reset
+ * all other sequences that were active
+ *
+ * @param {Event} e
+ * @returns void
+ */
+ var _increaseSequence = function(e) {
+ _inside_sequence = action;
+ ++_sequence_levels[combo];
+ _resetSequenceTimer();
+ },
- // start the simulation.
- this.start();
- }
+ /**
+ * wraps the specified callback inside of another function in order
+ * to reset all sequence counters as soon as this sequence is done
+ *
+ * @param {Event} e
+ * @returns void
+ */
+ _callbackAndReset = function(e) {
+ _fireCallback(callback, e);
+
+ // we should ignore the next key up if the action is key down
+ // or keypress. this is so if you finish a sequence and
+ // release the key the final key will not trigger a keyup
+ if (action !== 'keyup') {
+ _ignore_next_keyup = _characterFromEvent(e);
+ }
+
+ // weird race condition if a sequence ends with the key
+ // another sequence begins with
+ setTimeout(_resetSequences, 10);
+ },
+ i;
+
+ // loop through keys one at a time and bind the appropriate callback
+ // function. for any key leading up to the final one it should
+ // increase the sequence. after the final, it should reset all sequences
+ for (i = 0; i < keys.length; ++i) {
+ _bindSingle(keys[i], i < keys.length - 1 ? _increaseSequence : _callbackAndReset, action, combo, i);
+ }
}
- };
+ /**
+ * binds a single keyboard combination
+ *
+ * @param {string} combination
+ * @param {Function} callback
+ * @param {string=} action
+ * @param {string=} sequence_name - name of sequence if part of sequence
+ * @param {number=} level - what part of the sequence the command is
+ * @returns void
+ */
+ function _bindSingle(combination, callback, action, sequence_name, level) {
- /**
- * This function places the nodes on the canvas based on the hierarchial distribution.
- *
- * @param {Object} distribution | obtained by the function this._getDistribution()
- * @private
- */
- exports._placeNodesByHierarchy = function(distribution) {
- var nodeId, node;
+ // make sure multiple spaces in a row become a single space
+ combination = combination.replace(/\s+/g, ' ');
- // start placing all the level 0 nodes first. Then recursively position their branches.
- for (nodeId in distribution[0].nodes) {
- if (distribution[0].nodes.hasOwnProperty(nodeId)) {
- node = distribution[0].nodes[nodeId];
- if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
- if (node.xFixed) {
- node.x = distribution[0].minPos;
- node.xFixed = false;
+ var sequence = combination.split(' '),
+ i,
+ key,
+ keys,
+ modifiers = [];
- distribution[0].minPos += distribution[0].nodeSpacing;
- }
+ // if this pattern is a sequence of keys then run through this method
+ // to reprocess each pattern one key at a time
+ if (sequence.length > 1) {
+ return _bindSequence(combination, sequence, callback, action);
}
- else {
- if (node.yFixed) {
- node.y = distribution[0].minPos;
- node.yFixed = false;
- distribution[0].minPos += distribution[0].nodeSpacing;
- }
- }
- this._placeBranchNodes(node.edges,node.id,distribution,node.level);
- }
- }
+ // take the keys from this pattern and figure out what the actual
+ // pattern is all about
+ keys = combination === '+' ? ['+'] : combination.split('+');
- // stabilize the system after positioning. This function calls zoomExtent.
- this._stabilize();
- };
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
+ // normalize key names
+ if (_SPECIAL_ALIASES[key]) {
+ key = _SPECIAL_ALIASES[key];
+ }
- /**
- * This function get the distribution of levels based on hubsize
- *
- * @returns {Object}
- * @private
- */
- exports._getDistribution = function() {
- var distribution = {};
- var nodeId, node, level;
+ // if this is not a keypress event then we should
+ // be smart about using shift keys
+ // this will only work for US keyboards however
+ if (action && action != 'keypress' && _SHIFT_MAP[key]) {
+ key = _SHIFT_MAP[key];
+ modifiers.push('shift');
+ }
- // we fix Y because the hierarchy is vertical, we fix X so we do not give a node an x position for a second time.
- // the fix of X is removed after the x value has been set.
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- node = this.nodes[nodeId];
- node.xFixed = true;
- node.yFixed = true;
- if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
- node.y = this.constants.hierarchicalLayout.levelSeparation*node.level;
- }
- else {
- node.x = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ // if this key is a modifier then add it to the list of modifiers
+ if (_isModifier(key)) {
+ modifiers.push(key);
+ }
}
- if (!distribution.hasOwnProperty(node.level)) {
- distribution[node.level] = {amount: 0, nodes: {}, minPos:0, nodeSpacing:0};
+
+ // depending on what the key combination is
+ // we will try to pick the best event for it
+ action = _pickBestAction(key, modifiers, action);
+
+ // make sure to initialize array if this is the first time
+ // a callback is added for this key
+ if (!_callbacks[key]) {
+ _callbacks[key] = [];
}
- distribution[node.level].amount += 1;
- distribution[node.level].nodes[node.id] = node;
- }
+
+ // remove an existing match if there is one
+ _getMatches(key, modifiers, action, !sequence_name, combination);
+
+ // add this call back to the array
+ // if it is a sequence put it at the beginning
+ // if not put it at the end
+ //
+ // this is important because the way these are processed expects
+ // the sequence ones to come first
+ _callbacks[key][sequence_name ? 'unshift' : 'push']({
+ callback: callback,
+ modifiers: modifiers,
+ action: action,
+ seq: sequence_name,
+ level: level,
+ combo: combination
+ });
}
- // determine the largest amount of nodes of all levels
- var maxCount = 0;
- for (level in distribution) {
- if (distribution.hasOwnProperty(level)) {
- if (maxCount < distribution[level].amount) {
- maxCount = distribution[level].amount;
+ /**
+ * binds multiple combinations to the same callback
+ *
+ * @param {Array} combinations
+ * @param {Function} callback
+ * @param {string|undefined} action
+ * @returns void
+ */
+ function _bindMultiple(combinations, callback, action) {
+ for (var i = 0; i < combinations.length; ++i) {
+ _bindSingle(combinations[i], callback, action);
}
- }
}
- // set the initial position and spacing of each nodes accordingly
- for (level in distribution) {
- if (distribution.hasOwnProperty(level)) {
- distribution[level].nodeSpacing = (maxCount + 1) * this.constants.hierarchicalLayout.nodeSpacing;
- distribution[level].nodeSpacing /= (distribution[level].amount + 1);
- distribution[level].minPos = distribution[level].nodeSpacing - (0.5 * (distribution[level].amount + 1) * distribution[level].nodeSpacing);
- }
- }
+ // start!
+ _addEvent(document, 'keypress', _handleKey);
+ _addEvent(document, 'keydown', _handleKey);
+ _addEvent(document, 'keyup', _handleKey);
- return distribution;
- };
+ var mousetrap = {
+ /**
+ * binds an event to mousetrap
+ *
+ * can be a single key, a combination of keys separated with +,
+ * a comma separated list of keys, an array of keys, or
+ * a sequence of keys separated by spaces
+ *
+ * be sure to list the modifier keys first to make sure that the
+ * correct key ends up getting bound (the last key in the pattern)
+ *
+ * @param {string|Array} keys
+ * @param {Function} callback
+ * @param {string=} action - 'keypress', 'keydown', or 'keyup'
+ * @returns void
+ */
+ bind: function(keys, callback, action) {
+ _bindMultiple(keys instanceof Array ? keys : [keys], callback, action);
+ _direct_map[keys + ':' + action] = callback;
+ return this;
+ },
- /**
- * this function allocates nodes in levels based on the recursive branching from the largest hubs.
- *
- * @param hubsize
- * @private
- */
- exports._determineLevels = function(hubsize) {
- var nodeId, node;
+ /**
+ * unbinds an event to mousetrap
+ *
+ * the unbinding sets the callback function of the specified key combo
+ * to an empty function and deletes the corresponding key in the
+ * _direct_map dict.
+ *
+ * the keycombo+action has to be exactly the same as
+ * it was defined in the bind method
+ *
+ * TODO: actually remove this from the _callbacks dictionary instead
+ * of binding an empty function
+ *
+ * @param {string|Array} keys
+ * @param {string} action
+ * @returns void
+ */
+ unbind: function(keys, action) {
+ if (_direct_map[keys + ':' + action]) {
+ delete _direct_map[keys + ':' + action];
+ this.bind(keys, function() {}, action);
+ }
+ return this;
+ },
- // determine hubs
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- node = this.nodes[nodeId];
- if (node.edges.length == hubsize) {
- node.level = 0;
- }
- }
- }
+ /**
+ * triggers an event that has already been bound
+ *
+ * @param {string} keys
+ * @param {string=} action
+ * @returns void
+ */
+ trigger: function(keys, action) {
+ _direct_map[keys + ':' + action]();
+ return this;
+ },
- // branch from hubs
- for (nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- node = this.nodes[nodeId];
- if (node.level == 0) {
- this._setLevel(1,node.edges,node.id);
+ /**
+ * resets the library back to its initial state. this is useful
+ * if you want to clear out the current keyboard shortcuts and bind
+ * new ones - for example if you switch to another page
+ *
+ * @returns void
+ */
+ reset: function() {
+ _callbacks = {};
+ _direct_map = {};
+ return this;
}
- }
- }
- };
+ };
+
+ module.exports = mousetrap;
+
+
+
+/***/ },
+/* 119 */
+/***/ function(module, exports, __webpack_require__) {
+ var PhysicsMixin = __webpack_require__(120);
+ var ClusterMixin = __webpack_require__(124);
+ var SectorsMixin = __webpack_require__(125);
+ var SelectionMixin = __webpack_require__(126);
+ var ManipulationMixin = __webpack_require__(127);
+ var NavigationMixin = __webpack_require__(128);
+ var HierarchicalLayoutMixin = __webpack_require__(129);
/**
- * Since hierarchical layout does not support:
- * - smooth curves (based on the physics),
- * - clustering (based on dynamic node counts)
- *
- * We disable both features so there will be no problems.
+ * Load a mixin into the network object
*
+ * @param {Object} sourceVariable | this object has to contain functions.
* @private
*/
- exports._changeConstants = function() {
- this.constants.clustering.enabled = false;
- this.constants.physics.barnesHut.enabled = false;
- this.constants.physics.hierarchicalRepulsion.enabled = true;
- this._loadSelectedForceSolver();
- if (this.constants.smoothCurves.enabled == true) {
- this.constants.smoothCurves.dynamic = false;
+ exports._loadMixin = function (sourceVariable) {
+ for (var mixinFunction in sourceVariable) {
+ if (sourceVariable.hasOwnProperty(mixinFunction)) {
+ this[mixinFunction] = sourceVariable[mixinFunction];
+ }
}
- this._configureSmoothCurves();
};
/**
- * This is a recursively called function to enumerate the branches from the largest hubs and place the nodes
- * on a X position that ensures there will be no overlap.
+ * removes a mixin from the network object.
*
- * @param edges
- * @param parentId
- * @param distribution
- * @param parentLevel
+ * @param {Object} sourceVariable | this object has to contain functions.
* @private
*/
- exports._placeBranchNodes = function(edges, parentId, distribution, parentLevel) {
- for (var i = 0; i < edges.length; i++) {
- var childNode = null;
- if (edges[i].toId == parentId) {
- childNode = edges[i].from;
- }
- else {
- childNode = edges[i].to;
- }
-
- // if a node is conneceted to another node on the same level (or higher (means lower level))!, this is not handled here.
- var nodeMoved = false;
- if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
- if (childNode.xFixed && childNode.level > parentLevel) {
- childNode.xFixed = false;
- childNode.x = distribution[childNode.level].minPos;
- nodeMoved = true;
- }
- }
- else {
- if (childNode.yFixed && childNode.level > parentLevel) {
- childNode.yFixed = false;
- childNode.y = distribution[childNode.level].minPos;
- nodeMoved = true;
- }
- }
-
- if (nodeMoved == true) {
- distribution[childNode.level].minPos += distribution[childNode.level].nodeSpacing;
- if (childNode.edges.length > 1) {
- this._placeBranchNodes(childNode.edges,childNode.id,distribution,childNode.level);
- }
+ exports._clearMixin = function (sourceVariable) {
+ for (var mixinFunction in sourceVariable) {
+ if (sourceVariable.hasOwnProperty(mixinFunction)) {
+ this[mixinFunction] = undefined;
}
}
};
/**
- * this function is called recursively to enumerate the barnches of the largest hubs and give each node a level.
+ * Mixin the physics system and initialize the parameters required.
*
- * @param level
- * @param edges
- * @param parentId
* @private
*/
- exports._setLevel = function(level, edges, parentId) {
- for (var i = 0; i < edges.length; i++) {
- var childNode = null;
- if (edges[i].toId == parentId) {
- childNode = edges[i].from;
- }
- else {
- childNode = edges[i].to;
- }
- if (childNode.level == -1 || childNode.level > level) {
- childNode.level = level;
- if (edges.length > 1) {
- this._setLevel(level+1, childNode.edges, childNode.id);
- }
- }
+ exports._loadPhysicsSystem = function () {
+ this._loadMixin(PhysicsMixin);
+ this._loadSelectedForceSolver();
+ if (this.constants.configurePhysics == true) {
+ this._loadPhysicsConfiguration();
}
};
/**
- * Unfix nodes
+ * Mixin the cluster system and initialize the parameters required.
*
* @private
*/
- exports._restoreNodes = function() {
- for (var nodeId in this.nodes) {
- if (this.nodes.hasOwnProperty(nodeId)) {
- this.nodes[nodeId].xFixed = false;
- this.nodes[nodeId].yFixed = false;
- }
- }
+ exports._loadClusterSystem = function () {
+ this.clusterSession = 0;
+ this.hubThreshold = 5;
+ this._loadMixin(ClusterMixin);
};
-/***/ },
-/* 53 */
-/***/ function(module, exports, __webpack_require__) {
-
/**
- * Canvas shapes used by Network
+ * Mixin the sector system and initialize the parameters required
+ *
+ * @private
*/
- if (typeof CanvasRenderingContext2D !== 'undefined') {
-
- /**
- * Draw a circle shape
- */
- CanvasRenderingContext2D.prototype.circle = function(x, y, r) {
- this.beginPath();
- this.arc(x, y, r, 0, 2*Math.PI, false);
- };
-
- /**
- * Draw a square shape
- * @param {Number} x horizontal center
- * @param {Number} y vertical center
- * @param {Number} r size, width and height of the square
- */
- CanvasRenderingContext2D.prototype.square = function(x, y, r) {
- this.beginPath();
- this.rect(x - r, y - r, r * 2, r * 2);
- };
-
- /**
- * Draw a triangle shape
- * @param {Number} x horizontal center
- * @param {Number} y vertical center
- * @param {Number} r radius, half the length of the sides of the triangle
- */
- CanvasRenderingContext2D.prototype.triangle = function(x, y, r) {
- // http://en.wikipedia.org/wiki/Equilateral_triangle
- this.beginPath();
-
- var s = r * 2;
- var s2 = s / 2;
- var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
- var h = Math.sqrt(s * s - s2 * s2); // height
-
- this.moveTo(x, y - (h - ir));
- this.lineTo(x + s2, y + ir);
- this.lineTo(x - s2, y + ir);
- this.lineTo(x, y - (h - ir));
- this.closePath();
- };
-
- /**
- * Draw a triangle shape in downward orientation
- * @param {Number} x horizontal center
- * @param {Number} y vertical center
- * @param {Number} r radius
- */
- CanvasRenderingContext2D.prototype.triangleDown = function(x, y, r) {
- // http://en.wikipedia.org/wiki/Equilateral_triangle
- this.beginPath();
-
- var s = r * 2;
- var s2 = s / 2;
- var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
- var h = Math.sqrt(s * s - s2 * s2); // height
-
- this.moveTo(x, y + (h - ir));
- this.lineTo(x + s2, y - ir);
- this.lineTo(x - s2, y - ir);
- this.lineTo(x, y + (h - ir));
- this.closePath();
- };
-
- /**
- * Draw a star shape, a star with 5 points
- * @param {Number} x horizontal center
- * @param {Number} y vertical center
- * @param {Number} r radius, half the length of the sides of the triangle
- */
- CanvasRenderingContext2D.prototype.star = function(x, y, r) {
- // http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
- this.beginPath();
-
- for (var n = 0; n < 10; n++) {
- var radius = (n % 2 === 0) ? r * 1.3 : r * 0.5;
- this.lineTo(
- x + radius * Math.sin(n * 2 * Math.PI / 10),
- y - radius * Math.cos(n * 2 * Math.PI / 10)
- );
- }
-
- this.closePath();
- };
-
- /**
- * http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
- */
- CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) {
- var r2d = Math.PI/180;
- if( w - ( 2 * r ) < 0 ) { r = ( w / 2 ); } //ensure that the radius isn't too large for x
- if( h - ( 2 * r ) < 0 ) { r = ( h / 2 ); } //ensure that the radius isn't too large for y
- this.beginPath();
- this.moveTo(x+r,y);
- this.lineTo(x+w-r,y);
- this.arc(x+w-r,y+r,r,r2d*270,r2d*360,false);
- this.lineTo(x+w,y+h-r);
- this.arc(x+w-r,y+h-r,r,0,r2d*90,false);
- this.lineTo(x+r,y+h);
- this.arc(x+r,y+h-r,r,r2d*90,r2d*180,false);
- this.lineTo(x,y+r);
- this.arc(x+r,y+r,r,r2d*180,r2d*270,false);
- };
-
- /**
- * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- */
- CanvasRenderingContext2D.prototype.ellipse = function(x, y, w, h) {
- var kappa = .5522848,
- ox = (w / 2) * kappa, // control point offset horizontal
- oy = (h / 2) * kappa, // control point offset vertical
- xe = x + w, // x-end
- ye = y + h, // y-end
- xm = x + w / 2, // x-middle
- ym = y + h / 2; // y-middle
-
- this.beginPath();
- this.moveTo(x, ym);
- this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
- this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
- this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
- this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
- };
+ exports._loadSectorSystem = function () {
+ this.sectors = {};
+ this.activeSector = ["default"];
+ this.sectors["active"] = {};
+ this.sectors["active"]["default"] = {"nodes": {},
+ "edges": {},
+ "nodeIndices": [],
+ "formationScale": 1.0,
+ "drawingNode": undefined };
+ this.sectors["frozen"] = {};
+ this.sectors["support"] = {"nodes": {},
+ "edges": {},
+ "nodeIndices": [],
+ "formationScale": 1.0,
+ "drawingNode": undefined };
+ this.nodeIndices = this.sectors["active"]["default"]["nodeIndices"]; // the node indices list is used to speed up the computation of the repulsion fields
+ this._loadMixin(SectorsMixin);
+ };
- /**
- * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- */
- CanvasRenderingContext2D.prototype.database = function(x, y, w, h) {
- var f = 1/3;
- var wEllipse = w;
- var hEllipse = h * f;
- var kappa = .5522848,
- ox = (wEllipse / 2) * kappa, // control point offset horizontal
- oy = (hEllipse / 2) * kappa, // control point offset vertical
- xe = x + wEllipse, // x-end
- ye = y + hEllipse, // y-end
- xm = x + wEllipse / 2, // x-middle
- ym = y + hEllipse / 2, // y-middle
- ymb = y + (h - hEllipse/2), // y-midlle, bottom ellipse
- yeb = y + h; // y-end, bottom ellipse
+ /**
+ * Mixin the selection system and initialize the parameters required
+ *
+ * @private
+ */
+ exports._loadSelectionSystem = function () {
+ this.selectionObj = {nodes: {}, edges: {}};
- this.beginPath();
- this.moveTo(xe, ym);
+ this._loadMixin(SelectionMixin);
+ };
- this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
- this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
- this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
- this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
+ /**
+ * Mixin the navigationUI (User Interface) system and initialize the parameters required
+ *
+ * @private
+ */
+ exports._loadManipulationSystem = function () {
+ // reset global variables -- these are used by the selection of nodes and edges.
+ this.blockConnectingEdgeSelection = false;
+ this.forceAppendSelection = false;
- this.lineTo(xe, ymb);
+ if (this.constants.dataManipulation.enabled == true) {
+ // load the manipulator HTML elements. All styling done in css.
+ if (this.manipulationDiv === undefined) {
+ this.manipulationDiv = document.createElement('div');
+ this.manipulationDiv.className = 'network-manipulationDiv';
+ this.manipulationDiv.id = 'network-manipulationDiv';
+ if (this.editMode == true) {
+ this.manipulationDiv.style.display = "block";
+ }
+ else {
+ this.manipulationDiv.style.display = "none";
+ }
+ this.containerElement.insertBefore(this.manipulationDiv, this.frame);
+ }
- this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb);
- this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb);
+ if (this.editModeDiv === undefined) {
+ this.editModeDiv = document.createElement('div');
+ this.editModeDiv.className = 'network-manipulation-editMode';
+ this.editModeDiv.id = 'network-manipulation-editMode';
+ if (this.editMode == true) {
+ this.editModeDiv.style.display = "none";
+ }
+ else {
+ this.editModeDiv.style.display = "block";
+ }
+ this.containerElement.insertBefore(this.editModeDiv, this.frame);
+ }
- this.lineTo(x, ym);
- };
+ if (this.closeDiv === undefined) {
+ this.closeDiv = document.createElement('div');
+ this.closeDiv.className = 'network-manipulation-closeDiv';
+ this.closeDiv.id = 'network-manipulation-closeDiv';
+ this.closeDiv.style.display = this.manipulationDiv.style.display;
+ this.containerElement.insertBefore(this.closeDiv, this.frame);
+ }
+ // load the manipulation functions
+ this._loadMixin(ManipulationMixin);
- /**
- * Draw an arrow point (no line)
- */
- CanvasRenderingContext2D.prototype.arrow = function(x, y, angle, length) {
- // tail
- var xt = x - length * Math.cos(angle);
- var yt = y - length * Math.sin(angle);
+ // create the manipulator toolbar
+ this._createManipulatorBar();
+ }
+ else {
+ if (this.manipulationDiv !== undefined) {
+ // removes all the bindings and overloads
+ this._createManipulatorBar();
+ // remove the manipulation divs
+ this.containerElement.removeChild(this.manipulationDiv);
+ this.containerElement.removeChild(this.editModeDiv);
+ this.containerElement.removeChild(this.closeDiv);
- // inner tail
- // TODO: allow to customize different shapes
- var xi = x - length * 0.9 * Math.cos(angle);
- var yi = y - length * 0.9 * Math.sin(angle);
+ this.manipulationDiv = undefined;
+ this.editModeDiv = undefined;
+ this.closeDiv = undefined;
+ // remove the mixin functions
+ this._clearMixin(ManipulationMixin);
+ }
+ }
+ };
- // left
- var xl = xt + length / 3 * Math.cos(angle + 0.5 * Math.PI);
- var yl = yt + length / 3 * Math.sin(angle + 0.5 * Math.PI);
- // right
- var xr = xt + length / 3 * Math.cos(angle - 0.5 * Math.PI);
- var yr = yt + length / 3 * Math.sin(angle - 0.5 * Math.PI);
+ /**
+ * Mixin the navigation (User Interface) system and initialize the parameters required
+ *
+ * @private
+ */
+ exports._loadNavigationControls = function () {
+ this._loadMixin(NavigationMixin);
- this.beginPath();
- this.moveTo(x, y);
- this.lineTo(xl, yl);
- this.lineTo(xi, yi);
- this.lineTo(xr, yr);
- this.closePath();
- };
+ // the clean function removes the button divs, this is done to remove the bindings.
+ this._cleanNavigation();
+ if (this.constants.navigation.enabled == true) {
+ this._loadNavigationElements();
+ }
+ };
- /**
- * Sets up the dashedLine functionality for drawing
- * Original code came from http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas
- * @author David Jordan
- * @date 2012-08-08
- */
- CanvasRenderingContext2D.prototype.dashedLine = function(x,y,x2,y2,dashArray){
- if (!dashArray) dashArray=[10,5];
- if (dashLength==0) dashLength = 0.001; // Hack for Safari
- var dashCount = dashArray.length;
- this.moveTo(x, y);
- var dx = (x2-x), dy = (y2-y);
- var slope = dy/dx;
- var distRemaining = Math.sqrt( dx*dx + dy*dy );
- var dashIndex=0, draw=true;
- while (distRemaining>=0.1){
- var dashLength = dashArray[dashIndex++%dashCount];
- if (dashLength > distRemaining) dashLength = distRemaining;
- var xStep = Math.sqrt( dashLength*dashLength / (1 + slope*slope) );
- if (dx<0) xStep = -xStep;
- x += xStep;
- y += slope*xStep;
- this[draw ? 'lineTo' : 'moveTo'](x,y);
- distRemaining -= dashLength;
- draw = !draw;
- }
- };
- // TODO: add diamond shape
- }
+ /**
+ * Mixin the hierarchical layout system.
+ *
+ * @private
+ */
+ exports._loadHierarchySystem = function () {
+ this._loadMixin(HierarchicalLayoutMixin);
+ };
/***/ },
-/* 54 */
+/* 120 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Moroccan Arabic (ar-ma)
- // author : ElFadili Yassine : https://github.com/ElFadiliY
- // author : Abdel Said : https://github.com/abdelsaid
+ var util = __webpack_require__(1);
+ var RepulsionMixin = __webpack_require__(121);
+ var HierarchialRepulsionMixin = __webpack_require__(122);
+ var BarnesHutMixin = __webpack_require__(123);
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('ar-ma', {
- months : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),
- monthsShort : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),
- weekdays : "الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
- weekdaysShort : "احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),
- weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[اليوم على الساعة] LT",
- nextDay: '[غدا على الساعة] LT',
- nextWeek: 'dddd [على الساعة] LT',
- lastDay: '[أمس على الساعة] LT',
- lastWeek: 'dddd [على الساعة] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "في %s",
- past : "منذ %s",
- s : "ثوان",
- m : "دقيقة",
- mm : "%d دقائق",
- h : "ساعة",
- hh : "%d ساعات",
- d : "يوم",
- dd : "%d أيام",
- M : "شهر",
- MM : "%d أشهر",
- y : "سنة",
- yy : "%d سنوات"
- },
- week : {
- dow : 6, // Saturday is the first day of the week.
- doy : 12 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * Toggling barnes Hut calculation on and off.
+ *
+ * @private
+ */
+ exports._toggleBarnesHut = function () {
+ this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled;
+ this._loadSelectedForceSolver();
+ this.moving = true;
+ this.start();
+ };
-/***/ },
-/* 55 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This loads the node force solver based on the barnes hut or repulsion algorithm
+ *
+ * @private
+ */
+ exports._loadSelectedForceSolver = function () {
+ // this overloads the this._calculateNodeForces
+ if (this.constants.physics.barnesHut.enabled == true) {
+ this._clearMixin(RepulsionMixin);
+ this._clearMixin(HierarchialRepulsionMixin);
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Arabic Saudi Arabia (ar-sa)
- // author : Suhail Alkowaileet : https://github.com/xsoh
+ this.constants.physics.centralGravity = this.constants.physics.barnesHut.centralGravity;
+ this.constants.physics.springLength = this.constants.physics.barnesHut.springLength;
+ this.constants.physics.springConstant = this.constants.physics.barnesHut.springConstant;
+ this.constants.physics.damping = this.constants.physics.barnesHut.damping;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var symbolMap = {
- '1': '١',
- '2': '٢',
- '3': '٣',
- '4': '٤',
- '5': '٥',
- '6': '٦',
- '7': '٧',
- '8': '٨',
- '9': '٩',
- '0': '٠'
- }, numberMap = {
- '١': '1',
- '٢': '2',
- '٣': '3',
- '٤': '4',
- '٥': '5',
- '٦': '6',
- '٧': '7',
- '٨': '8',
- '٩': '9',
- '٠': '0'
- };
+ this._loadMixin(BarnesHutMixin);
+ }
+ else if (this.constants.physics.hierarchicalRepulsion.enabled == true) {
+ this._clearMixin(BarnesHutMixin);
+ this._clearMixin(RepulsionMixin);
- return moment.lang('ar-sa', {
- months : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),
- monthsShort : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),
- weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
- weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),
- weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 12) {
- return "ص";
- } else {
- return "م";
- }
- },
- calendar : {
- sameDay: "[اليوم على الساعة] LT",
- nextDay: '[غدا على الساعة] LT',
- nextWeek: 'dddd [على الساعة] LT',
- lastDay: '[أمس على الساعة] LT',
- lastWeek: 'dddd [على الساعة] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "في %s",
- past : "منذ %s",
- s : "ثوان",
- m : "دقيقة",
- mm : "%d دقائق",
- h : "ساعة",
- hh : "%d ساعات",
- d : "يوم",
- dd : "%d أيام",
- M : "شهر",
- MM : "%d أشهر",
- y : "سنة",
- yy : "%d سنوات"
- },
- preparse: function (string) {
- return string.replace(/[۰-۹]/g, function (match) {
- return numberMap[match];
- }).replace(/،/g, ',');
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- }).replace(/,/g, '،');
- },
- week : {
- dow : 6, // Saturday is the first day of the week.
- doy : 12 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ this.constants.physics.centralGravity = this.constants.physics.hierarchicalRepulsion.centralGravity;
+ this.constants.physics.springLength = this.constants.physics.hierarchicalRepulsion.springLength;
+ this.constants.physics.springConstant = this.constants.physics.hierarchicalRepulsion.springConstant;
+ this.constants.physics.damping = this.constants.physics.hierarchicalRepulsion.damping;
+ this._loadMixin(HierarchialRepulsionMixin);
+ }
+ else {
+ this._clearMixin(BarnesHutMixin);
+ this._clearMixin(HierarchialRepulsionMixin);
+ this.barnesHutTree = undefined;
-/***/ },
-/* 56 */
-/***/ function(module, exports, __webpack_require__) {
+ this.constants.physics.centralGravity = this.constants.physics.repulsion.centralGravity;
+ this.constants.physics.springLength = this.constants.physics.repulsion.springLength;
+ this.constants.physics.springConstant = this.constants.physics.repulsion.springConstant;
+ this.constants.physics.damping = this.constants.physics.repulsion.damping;
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Arabic (ar)
- // author : Abdel Said : https://github.com/abdelsaid
- // changes in months, weekdays : Ahmed Elkhatib
+ this._loadMixin(RepulsionMixin);
+ }
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * Before calculating the forces, we check if we need to cluster to keep up performance and we check
+ * if there is more than one node. If it is just one node, we dont calculate anything.
+ *
+ * @private
+ */
+ exports._initializeForceCalculation = function () {
+ // stop calculation if there is only one node
+ if (this.nodeIndices.length == 1) {
+ this.nodes[this.nodeIndices[0]]._setForce(0, 0);
+ }
+ else {
+ // if there are too many nodes on screen, we cluster without repositioning
+ if (this.nodeIndices.length > this.constants.clustering.clusterThreshold && this.constants.clustering.enabled == true) {
+ this.clusterToFit(this.constants.clustering.reduceToNodes, false);
}
- }(function (moment) {
- var symbolMap = {
- '1': '١',
- '2': '٢',
- '3': '٣',
- '4': '٤',
- '5': '٥',
- '6': '٦',
- '7': '٧',
- '8': '٨',
- '9': '٩',
- '0': '٠'
- }, numberMap = {
- '١': '1',
- '٢': '2',
- '٣': '3',
- '٤': '4',
- '٥': '5',
- '٦': '6',
- '٧': '7',
- '٨': '8',
- '٩': '9',
- '٠': '0'
- };
- return moment.lang('ar', {
- months : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"),
- monthsShort : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"),
- weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
- weekdaysShort : "أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),
- weekdaysMin : "ح_ن_ث_ر_خ_ج_س".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 12) {
- return "ص";
- } else {
- return "م";
- }
- },
- calendar : {
- sameDay: "[اليوم على الساعة] LT",
- nextDay: '[غدا على الساعة] LT',
- nextWeek: 'dddd [على الساعة] LT',
- lastDay: '[أمس على الساعة] LT',
- lastWeek: 'dddd [على الساعة] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "في %s",
- past : "منذ %s",
- s : "ثوان",
- m : "دقيقة",
- mm : "%d دقائق",
- h : "ساعة",
- hh : "%d ساعات",
- d : "يوم",
- dd : "%d أيام",
- M : "شهر",
- MM : "%d أشهر",
- y : "سنة",
- yy : "%d سنوات"
- },
- preparse: function (string) {
- return string.replace(/[۰-۹]/g, function (match) {
- return numberMap[match];
- }).replace(/،/g, ',');
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- }).replace(/,/g, '،');
- },
- week : {
- dow : 6, // Saturday is the first day of the week.
- doy : 12 // The week that contains Jan 1st is the first week of the year.
+ // we now start the force calculation
+ this._calculateForces();
+ }
+ };
+
+
+ /**
+ * Calculate the external forces acting on the nodes
+ * Forces are caused by: edges, repulsing forces between nodes, gravity
+ * @private
+ */
+ exports._calculateForces = function () {
+ // Gravity is required to keep separated groups from floating off
+ // the forces are reset to zero in this loop by using _setForce instead
+ // of _addForce
+
+ this._calculateGravitationalForces();
+ this._calculateNodeForces();
+
+ if (this.constants.physics.springConstant > 0) {
+ if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) {
+ this._calculateSpringForcesWithSupport();
+ }
+ else {
+ if (this.constants.physics.hierarchicalRepulsion.enabled == true) {
+ this._calculateHierarchicalSpringForces();
+ }
+ else {
+ this._calculateSpringForces();
+ }
+ }
+ }
+ };
+
+
+ /**
+ * Smooth curves are created by adding invisible nodes in the center of the edges. These nodes are also
+ * handled in the calculateForces function. We then use a quadratic curve with the center node as control.
+ * This function joins the datanodes and invisible (called support) nodes into one object.
+ * We do this so we do not contaminate this.nodes with the support nodes.
+ *
+ * @private
+ */
+ exports._updateCalculationNodes = function () {
+ if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) {
+ this.calculationNodes = {};
+ this.calculationNodeIndices = [];
+
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ this.calculationNodes[nodeId] = this.nodes[nodeId];
+ }
+ }
+ var supportNodes = this.sectors['support']['nodes'];
+ for (var supportNodeId in supportNodes) {
+ if (supportNodes.hasOwnProperty(supportNodeId)) {
+ if (this.edges.hasOwnProperty(supportNodes[supportNodeId].parentEdgeId)) {
+ this.calculationNodes[supportNodeId] = supportNodes[supportNodeId];
}
- });
- }));
+ else {
+ supportNodes[supportNodeId]._setForce(0, 0);
+ }
+ }
+ }
+ for (var idx in this.calculationNodes) {
+ if (this.calculationNodes.hasOwnProperty(idx)) {
+ this.calculationNodeIndices.push(idx);
+ }
+ }
+ }
+ else {
+ this.calculationNodes = this.nodes;
+ this.calculationNodeIndices = this.nodeIndices;
+ }
+ };
-/***/ },
-/* 57 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : azerbaijani (az)
- // author : topchiyev : https://github.com/topchiyev
+ /**
+ * this function applies the central gravity effect to keep groups from floating off
+ *
+ * @private
+ */
+ exports._calculateGravitationalForces = function () {
+ var dx, dy, distance, node, i;
+ var nodes = this.calculationNodes;
+ var gravity = this.constants.physics.centralGravity;
+ var gravityForce = 0;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ for (i = 0; i < this.calculationNodeIndices.length; i++) {
+ node = nodes[this.calculationNodeIndices[i]];
+ node.damping = this.constants.physics.damping; // possibly add function to alter damping properties of clusters.
+ // gravity does not apply when we are in a pocket sector
+ if (this._sector() == "default" && gravity != 0) {
+ dx = -node.x;
+ dy = -node.y;
+ distance = Math.sqrt(dx * dx + dy * dy);
+
+ gravityForce = (distance == 0) ? 0 : (gravity / distance);
+ node.fx = dx * gravityForce;
+ node.fy = dy * gravityForce;
}
- }(function (moment) {
+ else {
+ node.fx = 0;
+ node.fy = 0;
+ }
+ }
+ };
- var suffixes = {
- 1: "-inci",
- 5: "-inci",
- 8: "-inci",
- 70: "-inci",
- 80: "-inci",
- 2: "-nci",
- 7: "-nci",
- 20: "-nci",
- 50: "-nci",
- 3: "-üncü",
- 4: "-üncü",
- 100: "-üncü",
- 6: "-ncı",
+ /**
+ * this function calculates the effects of the springs in the case of unsmooth curves.
+ *
+ * @private
+ */
+ exports._calculateSpringForces = function () {
+ var edgeLength, edge, edgeId;
+ var dx, dy, fx, fy, springForce, distance;
+ var edges = this.edges;
- 9: "-uncu",
- 10: "-uncu",
- 30: "-uncu",
+ // forces caused by the edges, modelled as springs
+ for (edgeId in edges) {
+ if (edges.hasOwnProperty(edgeId)) {
+ edge = edges[edgeId];
+ if (edge.connected) {
+ // only calculate forces if nodes are in the same sector
+ if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
+ edgeLength = edge.customLength ? edge.length : this.constants.physics.springLength;
+ // this implies that the edges between big clusters are longer
+ edgeLength += (edge.to.clusterSize + edge.from.clusterSize - 2) * this.constants.clustering.edgeGrowth;
- 60: "-ıncı",
- 90: "-ıncı"
- };
- return moment.lang('az', {
- months : "yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),
- monthsShort : "yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),
- weekdays : "Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),
- weekdaysShort : "Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"),
- weekdaysMin : "Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[bugün saat] LT',
- nextDay : '[sabah saat] LT',
- nextWeek : '[gələn həftə] dddd [saat] LT',
- lastDay : '[dünən] LT',
- lastWeek : '[keçən həftə] dddd [saat] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s sonra",
- past : "%s əvvəl",
- s : "birneçə saniyyə",
- m : "bir dəqiqə",
- mm : "%d dəqiqə",
- h : "bir saat",
- hh : "%d saat",
- d : "bir gün",
- dd : "%d gün",
- M : "bir ay",
- MM : "%d ay",
- y : "bir il",
- yy : "%d il"
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 4) {
- return "gecə";
- } else if (hour < 12) {
- return "səhər";
- } else if (hour < 17) {
- return "gündüz";
- } else {
- return "axşam";
- }
- },
- ordinal : function (number) {
- if (number === 0) { // special case for zero
- return number + "-ıncı";
- }
- var a = number % 10,
- b = number % 100 - a,
- c = number >= 100 ? 100 : null;
+ dx = (edge.from.x - edge.to.x);
+ dy = (edge.from.y - edge.to.y);
+ distance = Math.sqrt(dx * dx + dy * dy);
- return number + (suffixes[a] || suffixes[b] || suffixes[c]);
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
+ if (distance == 0) {
+ distance = 0.01;
+ }
+
+ // the 1/distance is so the fx and fy can be calculated without sine or cosine.
+ springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
+
+ fx = dx * springForce;
+ fy = dy * springForce;
+
+ edge.from.fx += fx;
+ edge.from.fy += fy;
+ edge.to.fx -= fx;
+ edge.to.fy -= fy;
}
- });
- }));
+ }
+ }
+ }
+ };
-/***/ },
-/* 58 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : bulgarian (bg)
- // author : Krasen Borisov : https://github.com/kraz
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('bg', {
- months : "януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),
- monthsShort : "янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),
- weekdays : "неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),
- weekdaysShort : "нед_пон_вто_сря_чет_пет_съб".split("_"),
- weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "D.MM.YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[Днес в] LT',
- nextDay : '[Утре в] LT',
- nextWeek : 'dddd [в] LT',
- lastDay : '[Вчера в] LT',
- lastWeek : function () {
- switch (this.day()) {
- case 0:
- case 3:
- case 6:
- return '[В изминалата] dddd [в] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[В изминалия] dddd [в] LT';
- }
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "след %s",
- past : "преди %s",
- s : "няколко секунди",
- m : "минута",
- mm : "%d минути",
- h : "час",
- hh : "%d часа",
- d : "ден",
- dd : "%d дни",
- M : "месец",
- MM : "%d месеца",
- y : "година",
- yy : "%d години"
- },
- ordinal : function (number) {
- var lastDigit = number % 10,
- last2Digits = number % 100;
- if (number === 0) {
- return number + '-ев';
- } else if (last2Digits === 0) {
- return number + '-ен';
- } else if (last2Digits > 10 && last2Digits < 20) {
- return number + '-ти';
- } else if (lastDigit === 1) {
- return number + '-ви';
- } else if (lastDigit === 2) {
- return number + '-ри';
- } else if (lastDigit === 7 || lastDigit === 8) {
- return number + '-ми';
- } else {
- return number + '-ти';
- }
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * This function calculates the springforces on the nodes, accounting for the support nodes.
+ *
+ * @private
+ */
+ exports._calculateSpringForcesWithSupport = function () {
+ var edgeLength, edge, edgeId, combinedClusterSize;
+ var edges = this.edges;
+ // forces caused by the edges, modelled as springs
+ for (edgeId in edges) {
+ if (edges.hasOwnProperty(edgeId)) {
+ edge = edges[edgeId];
+ if (edge.connected) {
+ // only calculate forces if nodes are in the same sector
+ if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
+ if (edge.via != null) {
+ var node1 = edge.to;
+ var node2 = edge.via;
+ var node3 = edge.from;
-/***/ },
-/* 59 */
-/***/ function(module, exports, __webpack_require__) {
+ edgeLength = edge.customLength ? edge.length : this.constants.physics.springLength;
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Bengali (bn)
- // author : Kaushik Gandhi : https://github.com/kaushikgandhi
+ combinedClusterSize = node1.clusterSize + node3.clusterSize - 2;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // this implies that the edges between big clusters are longer
+ edgeLength += combinedClusterSize * this.constants.clustering.edgeGrowth;
+ this._calculateSpringForce(node1, node2, 0.5 * edgeLength);
+ this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
+ }
+ }
+ }
}
- }(function (moment) {
- var symbolMap = {
- '1': '১',
- '2': '২',
- '3': '৩',
- '4': '৪',
- '5': '৫',
- '6': '৬',
- '7': '৭',
- '8': '৮',
- '9': '৯',
- '0': '০'
- },
- numberMap = {
- '১': '1',
- '২': '2',
- '৩': '3',
- '৪': '4',
- '৫': '5',
- '৬': '6',
- '৭': '7',
- '৮': '8',
- '৯': '9',
- '০': '0'
- };
+ }
+ };
- return moment.lang('bn', {
- months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split("_"),
- monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split("_"),
- weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split("_"),
- weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split("_"),
- weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split("_"),
- longDateFormat : {
- LT : "A h:mm সময়",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY, LT",
- LLLL : "dddd, D MMMM YYYY, LT"
- },
- calendar : {
- sameDay : '[আজ] LT',
- nextDay : '[আগামীকাল] LT',
- nextWeek : 'dddd, LT',
- lastDay : '[গতকাল] LT',
- lastWeek : '[গত] dddd, LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s পরে",
- past : "%s আগে",
- s : "কএক সেকেন্ড",
- m : "এক মিনিট",
- mm : "%d মিনিট",
- h : "এক ঘন্টা",
- hh : "%d ঘন্টা",
- d : "এক দিন",
- dd : "%d দিন",
- M : "এক মাস",
- MM : "%d মাস",
- y : "এক বছর",
- yy : "%d বছর"
- },
- preparse: function (string) {
- return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
- return numberMap[match];
- });
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- });
- },
- //Bengali is a vast language its spoken
- //in different forms in various parts of the world.
- //I have just generalized with most common one used
- meridiem : function (hour, minute, isLower) {
- if (hour < 4) {
- return "রাত";
- } else if (hour < 10) {
- return "শকাল";
- } else if (hour < 17) {
- return "দুপুর";
- } else if (hour < 20) {
- return "বিকেল";
- } else {
- return "রাত";
- }
- },
- week : {
- dow : 0, // Sunday is the first day of the week.
- doy : 6 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * This is the code actually performing the calculation for the function above. It is split out to avoid repetition.
+ *
+ * @param node1
+ * @param node2
+ * @param edgeLength
+ * @private
+ */
+ exports._calculateSpringForce = function (node1, node2, edgeLength) {
+ var dx, dy, fx, fy, springForce, distance;
+
+ dx = (node1.x - node2.x);
+ dy = (node1.y - node2.y);
+ distance = Math.sqrt(dx * dx + dy * dy);
+
+ if (distance == 0) {
+ distance = 0.01;
+ }
+
+ // the 1/distance is so the fx and fy can be calculated without sine or cosine.
+ springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
+
+ fx = dx * springForce;
+ fy = dy * springForce;
+
+ node1.fx += fx;
+ node1.fy += fy;
+ node2.fx -= fx;
+ node2.fy -= fy;
+ };
+
+
+ /**
+ * Load the HTML for the physics config and bind it
+ * @private
+ */
+ exports._loadPhysicsConfiguration = function () {
+ if (this.physicsConfiguration === undefined) {
+ this.backupConstants = {};
+ util.deepExtend(this.backupConstants,this.constants);
+
+ var hierarchicalLayoutDirections = ["LR", "RL", "UD", "DU"];
+ this.physicsConfiguration = document.createElement('div');
+ this.physicsConfiguration.className = "PhysicsConfiguration";
+ this.physicsConfiguration.innerHTML = '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ ''
+ this.containerElement.parentElement.insertBefore(this.physicsConfiguration, this.containerElement);
+ this.optionsDiv = document.createElement("div");
+ this.optionsDiv.style.fontSize = "14px";
+ this.optionsDiv.style.fontFamily = "verdana";
+ this.containerElement.parentElement.insertBefore(this.optionsDiv, this.containerElement);
+
+ var rangeElement;
+ rangeElement = document.getElementById('graph_BH_gc');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_gc', -1, "physics_barnesHut_gravitationalConstant");
+ rangeElement = document.getElementById('graph_BH_cg');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_cg', 1, "physics_centralGravity");
+ rangeElement = document.getElementById('graph_BH_sc');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_sc', 1, "physics_springConstant");
+ rangeElement = document.getElementById('graph_BH_sl');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_sl', 1, "physics_springLength");
+ rangeElement = document.getElementById('graph_BH_damp');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_BH_damp', 1, "physics_damping");
-/***/ },
-/* 60 */
-/***/ function(module, exports, __webpack_require__) {
+ rangeElement = document.getElementById('graph_R_nd');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_nd', 1, "physics_repulsion_nodeDistance");
+ rangeElement = document.getElementById('graph_R_cg');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_cg', 1, "physics_centralGravity");
+ rangeElement = document.getElementById('graph_R_sc');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_sc', 1, "physics_springConstant");
+ rangeElement = document.getElementById('graph_R_sl');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_sl', 1, "physics_springLength");
+ rangeElement = document.getElementById('graph_R_damp');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_R_damp', 1, "physics_damping");
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : breton (br)
- // author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
+ rangeElement = document.getElementById('graph_H_nd');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_nd', 1, "physics_hierarchicalRepulsion_nodeDistance");
+ rangeElement = document.getElementById('graph_H_cg');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_cg', 1, "physics_centralGravity");
+ rangeElement = document.getElementById('graph_H_sc');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_sc', 1, "physics_springConstant");
+ rangeElement = document.getElementById('graph_H_sl');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_sl', 1, "physics_springLength");
+ rangeElement = document.getElementById('graph_H_damp');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_damp', 1, "physics_damping");
+ rangeElement = document.getElementById('graph_H_direction');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_direction', hierarchicalLayoutDirections, "hierarchicalLayout_direction");
+ rangeElement = document.getElementById('graph_H_levsep');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_levsep', 1, "hierarchicalLayout_levelSeparation");
+ rangeElement = document.getElementById('graph_H_nspac');
+ rangeElement.onchange = showValueOfRange.bind(this, 'graph_H_nspac', 1, "hierarchicalLayout_nodeSpacing");
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ var radioButton1 = document.getElementById("graph_physicsMethod1");
+ var radioButton2 = document.getElementById("graph_physicsMethod2");
+ var radioButton3 = document.getElementById("graph_physicsMethod3");
+ radioButton2.checked = true;
+ if (this.constants.physics.barnesHut.enabled) {
+ radioButton1.checked = true;
}
- }(function (moment) {
- function relativeTimeWithMutation(number, withoutSuffix, key) {
- var format = {
- 'mm': "munutenn",
- 'MM': "miz",
- 'dd': "devezh"
- };
- return number + ' ' + mutation(format[key], number);
+ if (this.constants.hierarchicalLayout.enabled) {
+ radioButton3.checked = true;
}
- function specialMutationForYears(number) {
- switch (lastNumber(number)) {
- case 1:
- case 3:
- case 4:
- case 5:
- case 9:
- return number + ' bloaz';
- default:
- return number + ' vloaz';
- }
- }
+ var graph_toggleSmooth = document.getElementById("graph_toggleSmooth");
+ var graph_repositionNodes = document.getElementById("graph_repositionNodes");
+ var graph_generateOptions = document.getElementById("graph_generateOptions");
- function lastNumber(number) {
- if (number > 9) {
- return lastNumber(number % 10);
- }
- return number;
+ graph_toggleSmooth.onclick = graphToggleSmoothCurves.bind(this);
+ graph_repositionNodes.onclick = graphRepositionNodes.bind(this);
+ graph_generateOptions.onclick = graphGenerateOptions.bind(this);
+ if (this.constants.smoothCurves == true && this.constants.dynamicSmoothCurves == false) {
+ graph_toggleSmooth.style.background = "#A4FF56";
}
-
- function mutation(text, number) {
- if (number === 2) {
- return softMutation(text);
- }
- return text;
+ else {
+ graph_toggleSmooth.style.background = "#FF8532";
}
- function softMutation(text) {
- var mutationTable = {
- 'm': 'v',
- 'b': 'v',
- 'd': 'z'
- };
- if (mutationTable[text.charAt(0)] === undefined) {
- return text;
- }
- return mutationTable[text.charAt(0)] + text.substring(1);
- }
- return moment.lang('br', {
- months : "Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),
- monthsShort : "Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),
- weekdays : "Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),
- weekdaysShort : "Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),
- weekdaysMin : "Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),
- longDateFormat : {
- LT : "h[e]mm A",
- L : "DD/MM/YYYY",
- LL : "D [a viz] MMMM YYYY",
- LLL : "D [a viz] MMMM YYYY LT",
- LLLL : "dddd, D [a viz] MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[Hiziv da] LT',
- nextDay : '[Warc\'hoazh da] LT',
- nextWeek : 'dddd [da] LT',
- lastDay : '[Dec\'h da] LT',
- lastWeek : 'dddd [paset da] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "a-benn %s",
- past : "%s 'zo",
- s : "un nebeud segondennoù",
- m : "ur vunutenn",
- mm : relativeTimeWithMutation,
- h : "un eur",
- hh : "%d eur",
- d : "un devezh",
- dd : relativeTimeWithMutation,
- M : "ur miz",
- MM : relativeTimeWithMutation,
- y : "ur bloaz",
- yy : specialMutationForYears
- },
- ordinal : function (number) {
- var output = (number === 1) ? 'añ' : 'vet';
- return number + output;
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ switchConfigurations.apply(this);
+ radioButton1.onchange = switchConfigurations.bind(this);
+ radioButton2.onchange = switchConfigurations.bind(this);
+ radioButton3.onchange = switchConfigurations.bind(this);
+ }
+ };
-/***/ },
-/* 61 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This overwrites the this.constants.
+ *
+ * @param constantsVariableName
+ * @param value
+ * @private
+ */
+ exports._overWriteGraphConstants = function (constantsVariableName, value) {
+ var nameArray = constantsVariableName.split("_");
+ if (nameArray.length == 1) {
+ this.constants[nameArray[0]] = value;
+ }
+ else if (nameArray.length == 2) {
+ this.constants[nameArray[0]][nameArray[1]] = value;
+ }
+ else if (nameArray.length == 3) {
+ this.constants[nameArray[0]][nameArray[1]][nameArray[2]] = value;
+ }
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : bosnian (bs)
- // author : Nedim Cholich : https://github.com/frontyard
- // based on (hr) translation by Bojan Marković
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * this function is bound to the toggle smooth curves button. That is also why it is not in the prototype.
+ */
+ function graphToggleSmoothCurves () {
+ this.constants.smoothCurves.enabled = !this.constants.smoothCurves.enabled;
+ var graph_toggleSmooth = document.getElementById("graph_toggleSmooth");
+ if (this.constants.smoothCurves.enabled == true) {graph_toggleSmooth.style.background = "#A4FF56";}
+ else {graph_toggleSmooth.style.background = "#FF8532";}
+
+ this._configureSmoothCurves(false);
+ }
+
+ /**
+ * this function is used to scramble the nodes
+ *
+ */
+ function graphRepositionNodes () {
+ for (var nodeId in this.calculationNodes) {
+ if (this.calculationNodes.hasOwnProperty(nodeId)) {
+ this.calculationNodes[nodeId].vx = 0; this.calculationNodes[nodeId].vy = 0;
+ this.calculationNodes[nodeId].fx = 0; this.calculationNodes[nodeId].fy = 0;
}
- }(function (moment) {
+ }
+ if (this.constants.hierarchicalLayout.enabled == true) {
+ this._setupHierarchicalLayout();
+ }
+ else {
+ this.repositionNodes();
+ }
+ this.moving = true;
+ this.start();
+ }
- function translate(number, withoutSuffix, key) {
- var result = number + " ";
- switch (key) {
- case 'm':
- return withoutSuffix ? 'jedna minuta' : 'jedne minute';
- case 'mm':
- if (number === 1) {
- result += 'minuta';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'minute';
- } else {
- result += 'minuta';
- }
- return result;
- case 'h':
- return withoutSuffix ? 'jedan sat' : 'jednog sata';
- case 'hh':
- if (number === 1) {
- result += 'sat';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'sata';
- } else {
- result += 'sati';
- }
- return result;
- case 'dd':
- if (number === 1) {
- result += 'dan';
- } else {
- result += 'dana';
- }
- return result;
- case 'MM':
- if (number === 1) {
- result += 'mjesec';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'mjeseca';
- } else {
- result += 'mjeseci';
- }
- return result;
- case 'yy':
- if (number === 1) {
- result += 'godina';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'godine';
- } else {
- result += 'godina';
- }
- return result;
+ /**
+ * this is used to generate an options file from the playing with physics system.
+ */
+ function graphGenerateOptions () {
+ var options = "No options are required, default values used.";
+ var optionsSpecific = [];
+ var radioButton1 = document.getElementById("graph_physicsMethod1");
+ var radioButton2 = document.getElementById("graph_physicsMethod2");
+ if (radioButton1.checked == true) {
+ if (this.constants.physics.barnesHut.gravitationalConstant != this.backupConstants.physics.barnesHut.gravitationalConstant) {optionsSpecific.push("gravitationalConstant: " + this.constants.physics.barnesHut.gravitationalConstant);}
+ if (this.constants.physics.centralGravity != this.backupConstants.physics.barnesHut.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
+ if (this.constants.physics.springLength != this.backupConstants.physics.barnesHut.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);}
+ if (this.constants.physics.springConstant != this.backupConstants.physics.barnesHut.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
+ if (this.constants.physics.damping != this.backupConstants.physics.barnesHut.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
+ if (optionsSpecific.length != 0) {
+ options = "var options = {";
+ options += "physics: {barnesHut: {";
+ for (var i = 0; i < optionsSpecific.length; i++) {
+ options += optionsSpecific[i];
+ if (i < optionsSpecific.length - 1) {
+ options += ", "
+ }
+ }
+ options += '}}'
+ }
+ if (this.constants.smoothCurves.enabled != this.backupConstants.smoothCurves.enabled) {
+ if (optionsSpecific.length == 0) {options = "var options = {";}
+ else {options += ", "}
+ options += "smoothCurves: " + this.constants.smoothCurves.enabled;
+ }
+ if (options != "No options are required, default values used.") {
+ options += '};'
+ }
+ }
+ else if (radioButton2.checked == true) {
+ options = "var options = {";
+ options += "physics: {barnesHut: {enabled: false}";
+ if (this.constants.physics.repulsion.nodeDistance != this.backupConstants.physics.repulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.repulsion.nodeDistance);}
+ if (this.constants.physics.centralGravity != this.backupConstants.physics.repulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
+ if (this.constants.physics.springLength != this.backupConstants.physics.repulsion.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);}
+ if (this.constants.physics.springConstant != this.backupConstants.physics.repulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
+ if (this.constants.physics.damping != this.backupConstants.physics.repulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
+ if (optionsSpecific.length != 0) {
+ options += ", repulsion: {";
+ for (var i = 0; i < optionsSpecific.length; i++) {
+ options += optionsSpecific[i];
+ if (i < optionsSpecific.length - 1) {
+ options += ", "
+ }
+ }
+ options += '}}'
+ }
+ if (optionsSpecific.length == 0) {options += "}"}
+ if (this.constants.smoothCurves != this.backupConstants.smoothCurves) {
+ options += ", smoothCurves: " + this.constants.smoothCurves;
+ }
+ options += '};'
+ }
+ else {
+ options = "var options = {";
+ if (this.constants.physics.hierarchicalRepulsion.nodeDistance != this.backupConstants.physics.hierarchicalRepulsion.nodeDistance) {optionsSpecific.push("nodeDistance: " + this.constants.physics.hierarchicalRepulsion.nodeDistance);}
+ if (this.constants.physics.centralGravity != this.backupConstants.physics.hierarchicalRepulsion.centralGravity) {optionsSpecific.push("centralGravity: " + this.constants.physics.centralGravity);}
+ if (this.constants.physics.springLength != this.backupConstants.physics.hierarchicalRepulsion.springLength) {optionsSpecific.push("springLength: " + this.constants.physics.springLength);}
+ if (this.constants.physics.springConstant != this.backupConstants.physics.hierarchicalRepulsion.springConstant) {optionsSpecific.push("springConstant: " + this.constants.physics.springConstant);}
+ if (this.constants.physics.damping != this.backupConstants.physics.hierarchicalRepulsion.damping) {optionsSpecific.push("damping: " + this.constants.physics.damping);}
+ if (optionsSpecific.length != 0) {
+ options += "physics: {hierarchicalRepulsion: {";
+ for (var i = 0; i < optionsSpecific.length; i++) {
+ options += optionsSpecific[i];
+ if (i < optionsSpecific.length - 1) {
+ options += ", ";
+ }
+ }
+ options += '}},';
+ }
+ options += 'hierarchicalLayout: {';
+ optionsSpecific = [];
+ if (this.constants.hierarchicalLayout.direction != this.backupConstants.hierarchicalLayout.direction) {optionsSpecific.push("direction: " + this.constants.hierarchicalLayout.direction);}
+ if (Math.abs(this.constants.hierarchicalLayout.levelSeparation) != this.backupConstants.hierarchicalLayout.levelSeparation) {optionsSpecific.push("levelSeparation: " + this.constants.hierarchicalLayout.levelSeparation);}
+ if (this.constants.hierarchicalLayout.nodeSpacing != this.backupConstants.hierarchicalLayout.nodeSpacing) {optionsSpecific.push("nodeSpacing: " + this.constants.hierarchicalLayout.nodeSpacing);}
+ if (optionsSpecific.length != 0) {
+ for (var i = 0; i < optionsSpecific.length; i++) {
+ options += optionsSpecific[i];
+ if (i < optionsSpecific.length - 1) {
+ options += ", "
}
+ }
+ options += '}'
+ }
+ else {
+ options += "enabled:true}";
}
+ options += '};'
+ }
- return moment.lang('bs', {
- months : "januar_februar_mart_april_maj_juni_juli_avgust_septembar_oktobar_novembar_decembar".split("_"),
- monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
- weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),
- weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"),
- weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD. MM. YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd, D. MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[danas u] LT',
- nextDay : '[sutra u] LT',
- nextWeek : function () {
- switch (this.day()) {
- case 0:
- return '[u] [nedjelju] [u] LT';
- case 3:
- return '[u] [srijedu] [u] LT';
- case 6:
- return '[u] [subotu] [u] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[u] dddd [u] LT';
- }
- },
- lastDay : '[jučer u] LT',
- lastWeek : function () {
- switch (this.day()) {
- case 0:
- case 3:
- return '[prošlu] dddd [u] LT';
- case 6:
- return '[prošle] [subote] [u] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[prošli] dddd [u] LT';
- }
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "za %s",
- past : "prije %s",
- s : "par sekundi",
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : "dan",
- dd : translate,
- M : "mjesec",
- MM : translate,
- y : "godinu",
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ this.optionsDiv.innerHTML = options;
+ }
+
+ /**
+ * this is used to switch between barnesHut, repulsion and hierarchical.
+ *
+ */
+ function switchConfigurations () {
+ var ids = ["graph_BH_table", "graph_R_table", "graph_H_table"];
+ var radioButton = document.querySelector('input[name="graph_physicsMethod"]:checked').value;
+ var tableId = "graph_" + radioButton + "_table";
+ var table = document.getElementById(tableId);
+ table.style.display = "block";
+ for (var i = 0; i < ids.length; i++) {
+ if (ids[i] != tableId) {
+ table = document.getElementById(ids[i]);
+ table.style.display = "none";
+ }
+ }
+ this._restoreNodes();
+ if (radioButton == "R") {
+ this.constants.hierarchicalLayout.enabled = false;
+ this.constants.physics.hierarchicalRepulsion.enabled = false;
+ this.constants.physics.barnesHut.enabled = false;
+ }
+ else if (radioButton == "H") {
+ if (this.constants.hierarchicalLayout.enabled == false) {
+ this.constants.hierarchicalLayout.enabled = true;
+ this.constants.physics.hierarchicalRepulsion.enabled = true;
+ this.constants.physics.barnesHut.enabled = false;
+ this.constants.smoothCurves.enabled = false;
+ this._setupHierarchicalLayout();
+ }
+ }
+ else {
+ this.constants.hierarchicalLayout.enabled = false;
+ this.constants.physics.hierarchicalRepulsion.enabled = false;
+ this.constants.physics.barnesHut.enabled = true;
+ }
+ this._loadSelectedForceSolver();
+ var graph_toggleSmooth = document.getElementById("graph_toggleSmooth");
+ if (this.constants.smoothCurves.enabled == true) {graph_toggleSmooth.style.background = "#A4FF56";}
+ else {graph_toggleSmooth.style.background = "#FF8532";}
+ this.moving = true;
+ this.start();
+ }
-/***/ },
-/* 62 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * this generates the ranges depending on the iniital values.
+ *
+ * @param id
+ * @param map
+ * @param constantsVariableName
+ */
+ function showValueOfRange (id,map,constantsVariableName) {
+ var valueId = id + "_value";
+ var rangeValue = document.getElementById(id).value;
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : catalan (ca)
- // author : Juan G. Hurtado : https://github.com/juanghurtado
+ if (map instanceof Array) {
+ document.getElementById(valueId).value = map[parseInt(rangeValue)];
+ this._overWriteGraphConstants(constantsVariableName,map[parseInt(rangeValue)]);
+ }
+ else {
+ document.getElementById(valueId).value = parseInt(map) * parseFloat(rangeValue);
+ this._overWriteGraphConstants(constantsVariableName, parseInt(map) * parseFloat(rangeValue));
+ }
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('ca', {
- months : "gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),
- monthsShort : "gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),
- weekdays : "diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),
- weekdaysShort : "dg._dl._dt._dc._dj._dv._ds.".split("_"),
- weekdaysMin : "Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay : function () {
- return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
- },
- nextDay : function () {
- return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
- },
- nextWeek : function () {
- return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
- },
- lastDay : function () {
- return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
- },
- lastWeek : function () {
- return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "en %s",
- past : "fa %s",
- s : "uns segons",
- m : "un minut",
- mm : "%d minuts",
- h : "una hora",
- hh : "%d hores",
- d : "un dia",
- dd : "%d dies",
- M : "un mes",
- MM : "%d mesos",
- y : "un any",
- yy : "%d anys"
- },
- ordinal : '%dº',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ if (constantsVariableName == "hierarchicalLayout_direction" ||
+ constantsVariableName == "hierarchicalLayout_levelSeparation" ||
+ constantsVariableName == "hierarchicalLayout_nodeSpacing") {
+ this._setupHierarchicalLayout();
+ }
+ this.moving = true;
+ this.start();
+ }
/***/ },
-/* 63 */
+/* 121 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : czech (cs)
- // author : petrbela : https://github.com/petrbela
+ /**
+ * Calculate the forces the nodes apply on each other based on a repulsion field.
+ * This field is linearly approximated.
+ *
+ * @private
+ */
+ exports._calculateNodeForces = function () {
+ var dx, dy, angle, distance, fx, fy, combinedClusterSize,
+ repulsingForce, node1, node2, i, j;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var months = "leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),
- monthsShort = "led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_");
+ var nodes = this.calculationNodes;
+ var nodeIndices = this.calculationNodeIndices;
- function plural(n) {
- return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
- }
+ // approximation constants
+ var a_base = -2 / 3;
+ var b = 4 / 3;
- function translate(number, withoutSuffix, key, isFuture) {
- var result = number + " ";
- switch (key) {
- case 's': // a few seconds / in a few seconds / a few seconds ago
- return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
- case 'm': // a minute / in a minute / a minute ago
- return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
- case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'minuty' : 'minut');
- } else {
- return result + 'minutami';
- }
- break;
- case 'h': // an hour / in an hour / an hour ago
- return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
- case 'hh': // 9 hours / in 9 hours / 9 hours ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'hodiny' : 'hodin');
- } else {
- return result + 'hodinami';
- }
- break;
- case 'd': // a day / in a day / a day ago
- return (withoutSuffix || isFuture) ? 'den' : 'dnem';
- case 'dd': // 9 days / in 9 days / 9 days ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'dny' : 'dní');
- } else {
- return result + 'dny';
- }
- break;
- case 'M': // a month / in a month / a month ago
- return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
- case 'MM': // 9 months / in 9 months / 9 months ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'měsíce' : 'měsíců');
- } else {
- return result + 'měsíci';
- }
- break;
- case 'y': // a year / in a year / a year ago
- return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
- case 'yy': // 9 years / in 9 years / 9 years ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'roky' : 'let');
- } else {
- return result + 'lety';
- }
- break;
- }
- }
+ // repulsing forces between nodes
+ var nodeDistance = this.constants.physics.repulsion.nodeDistance;
+ var minimumDistance = nodeDistance;
- return moment.lang('cs', {
- months : months,
- monthsShort : monthsShort,
- monthsParse : (function (months, monthsShort) {
- var i, _monthsParse = [];
- for (i = 0; i < 12; i++) {
- // use custom parser to solve problem with July (červenec)
- _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
- }
- return _monthsParse;
- }(months, monthsShort)),
- weekdays : "neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),
- weekdaysShort : "ne_po_út_st_čt_pá_so".split("_"),
- weekdaysMin : "ne_po_út_st_čt_pá_so".split("_"),
- longDateFormat : {
- LT: "H.mm",
- L : "DD. MM. YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd D. MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[dnes v] LT",
- nextDay: '[zítra v] LT',
- nextWeek: function () {
- switch (this.day()) {
- case 0:
- return '[v neděli v] LT';
- case 1:
- case 2:
- return '[v] dddd [v] LT';
- case 3:
- return '[ve středu v] LT';
- case 4:
- return '[ve čtvrtek v] LT';
- case 5:
- return '[v pátek v] LT';
- case 6:
- return '[v sobotu v] LT';
- }
- },
- lastDay: '[včera v] LT',
- lastWeek: function () {
- switch (this.day()) {
- case 0:
- return '[minulou neděli v] LT';
- case 1:
- case 2:
- return '[minulé] dddd [v] LT';
- case 3:
- return '[minulou středu v] LT';
- case 4:
- case 5:
- return '[minulý] dddd [v] LT';
- case 6:
- return '[minulou sobotu v] LT';
- }
- },
- sameElse: "L"
- },
- relativeTime : {
- future : "za %s",
- past : "před %s",
- s : translate,
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : translate,
- dd : translate,
- M : translate,
- MM : translate,
- y : translate,
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ // we loop from i over all but the last entree in the array
+ // j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j
+ for (i = 0; i < nodeIndices.length - 1; i++) {
+ node1 = nodes[nodeIndices[i]];
+ for (j = i + 1; j < nodeIndices.length; j++) {
+ node2 = nodes[nodeIndices[j]];
+ combinedClusterSize = node1.clusterSize + node2.clusterSize - 2;
+ dx = node2.x - node1.x;
+ dy = node2.y - node1.y;
+ distance = Math.sqrt(dx * dx + dy * dy);
-/***/ },
-/* 64 */
-/***/ function(module, exports, __webpack_require__) {
+ minimumDistance = (combinedClusterSize == 0) ? nodeDistance : (nodeDistance * (1 + combinedClusterSize * this.constants.clustering.distanceAmplification));
+ var a = a_base / minimumDistance;
+ if (distance < 2 * minimumDistance) {
+ if (distance < 0.5 * minimumDistance) {
+ repulsingForce = 1.0;
+ }
+ else {
+ repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / minimumDistance - 1) * steepness))
+ }
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : chuvash (cv)
- // author : Anatoly Mironov : https://github.com/mirontoli
+ // amplify the repulsion for clusters.
+ repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification;
+ repulsingForce = repulsingForce / distance;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ fx = dx * repulsingForce;
+ fy = dy * repulsingForce;
+
+ node1.fx -= fx;
+ node1.fy -= fy;
+ node2.fx += fx;
+ node2.fy += fy;
+ }
}
- }(function (moment) {
- return moment.lang('cv', {
- months : "кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"),
- monthsShort : "кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"),
- weekdays : "вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун".split("_"),
- weekdaysShort : "выр_тун_ытл_юн_кĕç_эрн_шăм".split("_"),
- weekdaysMin : "вр_тн_ыт_юн_кç_эр_шм".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD-MM-YYYY",
- LL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]",
- LLL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT",
- LLLL : "dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT"
- },
- calendar : {
- sameDay: '[Паян] LT [сехетре]',
- nextDay: '[Ыран] LT [сехетре]',
- lastDay: '[Ĕнер] LT [сехетре]',
- nextWeek: '[Çитес] dddd LT [сехетре]',
- lastWeek: '[Иртнĕ] dddd LT [сехетре]',
- sameElse: 'L'
- },
- relativeTime : {
- future : function (output) {
- var affix = /сехет$/i.exec(output) ? "рен" : /çул$/i.exec(output) ? "тан" : "ран";
- return output + affix;
- },
- past : "%s каялла",
- s : "пĕр-ик çеккунт",
- m : "пĕр минут",
- mm : "%d минут",
- h : "пĕр сехет",
- hh : "%d сехет",
- d : "пĕр кун",
- dd : "%d кун",
- M : "пĕр уйăх",
- MM : "%d уйăх",
- y : "пĕр çул",
- yy : "%d çул"
- },
- ordinal : '%d-мĕш',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ }
+ };
/***/ },
-/* 65 */
+/* 122 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Welsh (cy)
- // author : Robert Allen
+ /**
+ * Calculate the forces the nodes apply on eachother based on a repulsion field.
+ * This field is linearly approximated.
+ *
+ * @private
+ */
+ exports._calculateNodeForces = function () {
+ var dx, dy, distance, fx, fy, combinedClusterSize,
+ repulsingForce, node1, node2, i, j;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ var nodes = this.calculationNodes;
+ var nodeIndices = this.calculationNodeIndices;
+
+ // approximation constants
+ var b = 5;
+ var a_base = 0.5 * -b;
+
+
+ // repulsing forces between nodes
+ var nodeDistance = this.constants.physics.hierarchicalRepulsion.nodeDistance;
+ var minimumDistance = nodeDistance;
+ var a = a_base / minimumDistance;
+
+ // we loop from i over all but the last entree in the array
+ // j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j
+ for (i = 0; i < nodeIndices.length - 1; i++) {
+
+ node1 = nodes[nodeIndices[i]];
+ for (j = i + 1; j < nodeIndices.length; j++) {
+ node2 = nodes[nodeIndices[j]];
+ if (node1.level == node2.level) {
+
+ dx = node2.x - node1.x;
+ dy = node2.y - node1.y;
+ distance = Math.sqrt(dx * dx + dy * dy);
+
+
+ if (distance < 2 * minimumDistance) {
+ repulsingForce = a * distance + b;
+ var c = 0.05;
+ var d = 2 * minimumDistance * 2 * c;
+ repulsingForce = c * Math.pow(distance,2) - d * distance + d*d/(4*c);
+
+ // normalize force with
+ if (distance == 0) {
+ distance = 0.01;
+ }
+ else {
+ repulsingForce = repulsingForce / distance;
+ }
+ fx = dx * repulsingForce;
+ fy = dy * repulsingForce;
+
+ node1.fx -= fx;
+ node1.fy -= fy;
+ node2.fx += fx;
+ node2.fy += fy;
+ }
+ }
}
- }(function (moment) {
- return moment.lang("cy", {
- months: "Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),
- monthsShort: "Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),
- weekdays: "Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),
- weekdaysShort: "Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),
- weekdaysMin: "Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),
- // time formats are the same as en-gb
- longDateFormat: {
- LT: "HH:mm",
- L: "DD/MM/YYYY",
- LL: "D MMMM YYYY",
- LLL: "D MMMM YYYY LT",
- LLLL: "dddd, D MMMM YYYY LT"
- },
- calendar: {
- sameDay: '[Heddiw am] LT',
- nextDay: '[Yfory am] LT',
- nextWeek: 'dddd [am] LT',
- lastDay: '[Ddoe am] LT',
- lastWeek: 'dddd [diwethaf am] LT',
- sameElse: 'L'
- },
- relativeTime: {
- future: "mewn %s",
- past: "%s yn ôl",
- s: "ychydig eiliadau",
- m: "munud",
- mm: "%d munud",
- h: "awr",
- hh: "%d awr",
- d: "diwrnod",
- dd: "%d diwrnod",
- M: "mis",
- MM: "%d mis",
- y: "blwyddyn",
- yy: "%d flynedd"
- },
- // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
- ordinal: function (number) {
- var b = number,
- output = '',
- lookup = [
- '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
- 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
- ];
+ }
+ };
+
+
+ /**
+ * this function calculates the effects of the springs in the case of unsmooth curves.
+ *
+ * @private
+ */
+ exports._calculateHierarchicalSpringForces = function () {
+ var edgeLength, edge, edgeId;
+ var dx, dy, fx, fy, springForce, distance;
+ var edges = this.edges;
- if (b > 20) {
- if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
- output = 'fed'; // not 30ain, 70ain or 90ain
- } else {
- output = 'ain';
- }
- } else if (b > 0) {
- output = lookup[b];
- }
+ // forces caused by the edges, modelled as springs
+ for (edgeId in edges) {
+ if (edges.hasOwnProperty(edgeId)) {
+ edge = edges[edgeId];
+ if (edge.connected) {
+ // only calculate forces if nodes are in the same sector
+ if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
+ edgeLength = edge.customLength ? edge.length : this.constants.physics.springLength;
+ // this implies that the edges between big clusters are longer
+ edgeLength += (edge.to.clusterSize + edge.from.clusterSize - 2) * this.constants.clustering.edgeGrowth;
- return number + output;
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ dx = (edge.from.x - edge.to.x);
+ dy = (edge.from.y - edge.to.y);
+ distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance == 0) {
+ distance = 0.01;
+ }
-/***/ },
-/* 66 */
-/***/ function(module, exports, __webpack_require__) {
+ distance = Math.max(0.8*edgeLength,Math.min(5*edgeLength, distance));
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : danish (da)
- // author : Ulrik Nielsen : https://github.com/mrbase
+ // the 1/distance is so the fx and fy can be calculated without sine or cosine.
+ springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('da', {
- months : "januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),
- monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),
- weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),
- weekdaysShort : "søn_man_tir_ons_tor_fre_lør".split("_"),
- weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd [d.] D. MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[I dag kl.] LT',
- nextDay : '[I morgen kl.] LT',
- nextWeek : 'dddd [kl.] LT',
- lastDay : '[I går kl.] LT',
- lastWeek : '[sidste] dddd [kl] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "om %s",
- past : "%s siden",
- s : "få sekunder",
- m : "et minut",
- mm : "%d minutter",
- h : "en time",
- hh : "%d timer",
- d : "en dag",
- dd : "%d dage",
- M : "en måned",
- MM : "%d måneder",
- y : "et år",
- yy : "%d år"
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ fx = dx * springForce;
+ fy = dy * springForce;
+ edge.to.fx -= fx;
+ edge.to.fy -= fy;
+ edge.from.fx += fx;
+ edge.from.fy += fy;
+
+
+ var factor = 5;
+ if (distance > edgeLength) {
+ factor = 25;
+ }
+
+ if (edge.from.level > edge.to.level) {
+ edge.to.fx -= factor*fx;
+ edge.to.fy -= factor*fy;
+ }
+ else if (edge.from.level < edge.to.level) {
+ edge.from.fx += factor*fx;
+ edge.from.fy += factor*fy;
+ }
+ }
+ }
+ }
+ }
+ };
/***/ },
-/* 67 */
+/* 123 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : austrian german (de-at)
- // author : lluchs : https://github.com/lluchs
- // author: Menelion Elensúle: https://github.com/Oire
- // author : Martin Groller : https://github.com/MadMG
+ /**
+ * This function calculates the forces the nodes apply on eachother based on a gravitational model.
+ * The Barnes Hut method is used to speed up this N-body simulation.
+ *
+ * @private
+ */
+ exports._calculateNodeForces = function() {
+ if (this.constants.physics.barnesHut.gravitationalConstant != 0) {
+ var node;
+ var nodes = this.calculationNodes;
+ var nodeIndices = this.calculationNodeIndices;
+ var nodeCount = nodeIndices.length;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- function processRelativeTime(number, withoutSuffix, key, isFuture) {
- var format = {
- 'm': ['eine Minute', 'einer Minute'],
- 'h': ['eine Stunde', 'einer Stunde'],
- 'd': ['ein Tag', 'einem Tag'],
- 'dd': [number + ' Tage', number + ' Tagen'],
- 'M': ['ein Monat', 'einem Monat'],
- 'MM': [number + ' Monate', number + ' Monaten'],
- 'y': ['ein Jahr', 'einem Jahr'],
- 'yy': [number + ' Jahre', number + ' Jahren']
- };
- return withoutSuffix ? format[key][0] : format[key][1];
- }
+ this._formBarnesHutTree(nodes,nodeIndices);
- return moment.lang('de-at', {
- months : "Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
- monthsShort : "Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
- weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),
- weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),
- weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"),
- longDateFormat : {
- LT: "HH:mm [Uhr]",
- L : "DD.MM.YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd, D. MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[Heute um] LT",
- sameElse: "L",
- nextDay: '[Morgen um] LT',
- nextWeek: 'dddd [um] LT',
- lastDay: '[Gestern um] LT',
- lastWeek: '[letzten] dddd [um] LT'
- },
- relativeTime : {
- future : "in %s",
- past : "vor %s",
- s : "ein paar Sekunden",
- m : processRelativeTime,
- mm : "%d Minuten",
- h : processRelativeTime,
- hh : "%d Stunden",
- d : processRelativeTime,
- dd : processRelativeTime,
- M : processRelativeTime,
- MM : processRelativeTime,
- y : processRelativeTime,
- yy : processRelativeTime
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ var barnesHutTree = this.barnesHutTree;
+ // place the nodes one by one recursively
+ for (var i = 0; i < nodeCount; i++) {
+ node = nodes[nodeIndices[i]];
+ // starting with root is irrelevant, it never passes the BarnesHut condition
+ this._getForceContribution(barnesHutTree.root.children.NW,node);
+ this._getForceContribution(barnesHutTree.root.children.NE,node);
+ this._getForceContribution(barnesHutTree.root.children.SW,node);
+ this._getForceContribution(barnesHutTree.root.children.SE,node);
+ }
+ }
+ };
-/***/ },
-/* 68 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : german (de)
- // author : lluchs : https://github.com/lluchs
- // author: Menelion Elensúle: https://github.com/Oire
+ /**
+ * This function traverses the barnesHutTree. It checks when it can approximate distant nodes with their center of mass.
+ * If a region contains a single node, we check if it is not itself, then we apply the force.
+ *
+ * @param parentBranch
+ * @param node
+ * @private
+ */
+ exports._getForceContribution = function(parentBranch,node) {
+ // we get no force contribution from an empty region
+ if (parentBranch.childrenCount > 0) {
+ var dx,dy,distance;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // get the distance from the center of mass to the node.
+ dx = parentBranch.centerOfMass.x - node.x;
+ dy = parentBranch.centerOfMass.y - node.y;
+ distance = Math.sqrt(dx * dx + dy * dy);
+
+ // BarnesHut condition
+ // original condition : s/d < theta = passed === d/s > 1/theta = passed
+ // calcSize = 1/s --> d * 1/s > 1/theta = passed
+ if (distance * parentBranch.calcSize > this.constants.physics.barnesHut.theta) {
+ // duplicate code to reduce function calls to speed up program
+ if (distance == 0) {
+ distance = 0.1*Math.random();
+ dx = distance;
+ }
+ var gravityForce = this.constants.physics.barnesHut.gravitationalConstant * parentBranch.mass * node.mass / (distance * distance * distance);
+ var fx = dx * gravityForce;
+ var fy = dy * gravityForce;
+ node.fx += fx;
+ node.fy += fy;
}
- }(function (moment) {
- function processRelativeTime(number, withoutSuffix, key, isFuture) {
- var format = {
- 'm': ['eine Minute', 'einer Minute'],
- 'h': ['eine Stunde', 'einer Stunde'],
- 'd': ['ein Tag', 'einem Tag'],
- 'dd': [number + ' Tage', number + ' Tagen'],
- 'M': ['ein Monat', 'einem Monat'],
- 'MM': [number + ' Monate', number + ' Monaten'],
- 'y': ['ein Jahr', 'einem Jahr'],
- 'yy': [number + ' Jahre', number + ' Jahren']
- };
- return withoutSuffix ? format[key][0] : format[key][1];
+ else {
+ // Did not pass the condition, go into children if available
+ if (parentBranch.childrenCount == 4) {
+ this._getForceContribution(parentBranch.children.NW,node);
+ this._getForceContribution(parentBranch.children.NE,node);
+ this._getForceContribution(parentBranch.children.SW,node);
+ this._getForceContribution(parentBranch.children.SE,node);
+ }
+ else { // parentBranch must have only one node, if it was empty we wouldnt be here
+ if (parentBranch.children.data.id != node.id) { // if it is not self
+ // duplicate code to reduce function calls to speed up program
+ if (distance == 0) {
+ distance = 0.5*Math.random();
+ dx = distance;
+ }
+ var gravityForce = this.constants.physics.barnesHut.gravitationalConstant * parentBranch.mass * node.mass / (distance * distance * distance);
+ var fx = dx * gravityForce;
+ var fy = dy * gravityForce;
+ node.fx += fx;
+ node.fy += fy;
+ }
+ }
}
+ }
+ };
- return moment.lang('de', {
- months : "Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
- monthsShort : "Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
- weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),
- weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),
- weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"),
- longDateFormat : {
- LT: "HH:mm [Uhr]",
- L : "DD.MM.YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd, D. MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[Heute um] LT",
- sameElse: "L",
- nextDay: '[Morgen um] LT',
- nextWeek: 'dddd [um] LT',
- lastDay: '[Gestern um] LT',
- lastWeek: '[letzten] dddd [um] LT'
- },
- relativeTime : {
- future : "in %s",
- past : "vor %s",
- s : "ein paar Sekunden",
- m : processRelativeTime,
- mm : "%d Minuten",
- h : processRelativeTime,
- hh : "%d Stunden",
- d : processRelativeTime,
- dd : processRelativeTime,
- M : processRelativeTime,
- MM : processRelativeTime,
- y : processRelativeTime,
- yy : processRelativeTime
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ /**
+ * This function constructs the barnesHut tree recursively. It creates the root, splits it and starts placing the nodes.
+ *
+ * @param nodes
+ * @param nodeIndices
+ * @private
+ */
+ exports._formBarnesHutTree = function(nodes,nodeIndices) {
+ var node;
+ var nodeCount = nodeIndices.length;
+ var minX = Number.MAX_VALUE,
+ minY = Number.MAX_VALUE,
+ maxX =-Number.MAX_VALUE,
+ maxY =-Number.MAX_VALUE;
-/***/ },
-/* 69 */
-/***/ function(module, exports, __webpack_require__) {
+ // get the range of the nodes
+ for (var i = 0; i < nodeCount; i++) {
+ var x = nodes[nodeIndices[i]].x;
+ var y = nodes[nodeIndices[i]].y;
+ if (x < minX) { minX = x; }
+ if (x > maxX) { maxX = x; }
+ if (y < minY) { minY = y; }
+ if (y > maxY) { maxY = y; }
+ }
+ // make the range a square
+ var sizeDiff = Math.abs(maxX - minX) - Math.abs(maxY - minY); // difference between X and Y
+ if (sizeDiff > 0) {minY -= 0.5 * sizeDiff; maxY += 0.5 * sizeDiff;} // xSize > ySize
+ else {minX += 0.5 * sizeDiff; maxX -= 0.5 * sizeDiff;} // xSize < ySize
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : modern greek (el)
- // author : Aggelos Karalias : https://github.com/mehiel
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ var minimumTreeSize = 1e-5;
+ var rootSize = Math.max(minimumTreeSize,Math.abs(maxX - minX));
+ var halfRootSize = 0.5 * rootSize;
+ var centerX = 0.5 * (minX + maxX), centerY = 0.5 * (minY + maxY);
+
+ // construct the barnesHutTree
+ var barnesHutTree = {
+ root:{
+ centerOfMass: {x:0, y:0},
+ mass:0,
+ range: {
+ minX: centerX-halfRootSize,maxX:centerX+halfRootSize,
+ minY: centerY-halfRootSize,maxY:centerY+halfRootSize
+ },
+ size: rootSize,
+ calcSize: 1 / rootSize,
+ children: { data:null},
+ maxWidth: 0,
+ level: 0,
+ childrenCount: 4
}
- }(function (moment) {
- return moment.lang('el', {
- monthsNominativeEl : "Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),
- monthsGenitiveEl : "Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),
- months : function (momentToFormat, format) {
- if (/D/.test(format.substring(0, format.indexOf("MMMM")))) { // if there is a day number before 'MMMM'
- return this._monthsGenitiveEl[momentToFormat.month()];
- } else {
- return this._monthsNominativeEl[momentToFormat.month()];
- }
- },
- monthsShort : "Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),
- weekdays : "Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),
- weekdaysShort : "Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),
- weekdaysMin : "Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),
- meridiem : function (hours, minutes, isLower) {
- if (hours > 11) {
- return isLower ? 'μμ' : 'ΜΜ';
- } else {
- return isLower ? 'πμ' : 'ΠΜ';
- }
- },
- longDateFormat : {
- LT : "h:mm A",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendarEl : {
- sameDay : '[Σήμερα {}] LT',
- nextDay : '[Αύριο {}] LT',
- nextWeek : 'dddd [{}] LT',
- lastDay : '[Χθες {}] LT',
- lastWeek : function() {
- switch (this.day()) {
- case 6:
- return '[το προηγούμενο] dddd [{}] LT';
- default:
- return '[την προηγούμενη] dddd [{}] LT';
- }
- },
- sameElse : 'L'
- },
- calendar : function (key, mom) {
- var output = this._calendarEl[key],
- hours = mom && mom.hours();
+ };
+ this._splitBranch(barnesHutTree.root);
- if (typeof output === 'function') {
- output = output.apply(mom);
- }
+ // place the nodes one by one recursively
+ for (i = 0; i < nodeCount; i++) {
+ node = nodes[nodeIndices[i]];
+ this._placeInTree(barnesHutTree.root,node);
+ }
- return output.replace("{}", (hours % 12 === 1 ? "στη" : "στις"));
- },
- relativeTime : {
- future : "σε %s",
- past : "%s πριν",
- s : "δευτερόλεπτα",
- m : "ένα λεπτό",
- mm : "%d λεπτά",
- h : "μία ώρα",
- hh : "%d ώρες",
- d : "μία μέρα",
- dd : "%d μέρες",
- M : "ένας μήνας",
- MM : "%d μήνες",
- y : "ένας χρόνος",
- yy : "%d χρόνια"
- },
- ordinal : function (number) {
- return number + 'η';
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4st is the first week of the year.
- }
- });
- }));
+ // make global
+ this.barnesHutTree = barnesHutTree
+ };
-/***/ },
-/* 70 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * this updates the mass of a branch. this is increased by adding a node.
+ *
+ * @param parentBranch
+ * @param node
+ * @private
+ */
+ exports._updateBranchMass = function(parentBranch, node) {
+ var totalMass = parentBranch.mass + node.mass;
+ var totalMassInv = 1/totalMass;
+
+ parentBranch.centerOfMass.x = parentBranch.centerOfMass.x * parentBranch.mass + node.x * node.mass;
+ parentBranch.centerOfMass.x *= totalMassInv;
+
+ parentBranch.centerOfMass.y = parentBranch.centerOfMass.y * parentBranch.mass + node.y * node.mass;
+ parentBranch.centerOfMass.y *= totalMassInv;
+
+ parentBranch.mass = totalMass;
+ var biggestSize = Math.max(Math.max(node.height,node.radius),node.width);
+ parentBranch.maxWidth = (parentBranch.maxWidth < biggestSize) ? biggestSize : parentBranch.maxWidth;
+
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : australian english (en-au)
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * determine in which branch the node will be placed.
+ *
+ * @param parentBranch
+ * @param node
+ * @param skipMassUpdate
+ * @private
+ */
+ exports._placeInTree = function(parentBranch,node,skipMassUpdate) {
+ if (skipMassUpdate != true || skipMassUpdate === undefined) {
+ // update the mass of the branch.
+ this._updateBranchMass(parentBranch,node);
+ }
+
+ if (parentBranch.children.NW.range.maxX > node.x) { // in NW or SW
+ if (parentBranch.children.NW.range.maxY > node.y) { // in NW
+ this._placeInRegion(parentBranch,node,"NW");
}
- }(function (moment) {
- return moment.lang('en-au', {
- months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
- monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
- weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
- weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
- weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
- longDateFormat : {
- LT : "h:mm A",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[Today at] LT',
- nextDay : '[Tomorrow at] LT',
- nextWeek : 'dddd [at] LT',
- lastDay : '[Yesterday at] LT',
- lastWeek : '[Last] dddd [at] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "in %s",
- past : "%s ago",
- s : "a few seconds",
- m : "a minute",
- mm : "%d minutes",
- h : "an hour",
- hh : "%d hours",
- d : "a day",
- dd : "%d days",
- M : "a month",
- MM : "%d months",
- y : "a year",
- yy : "%d years"
- },
- ordinal : function (number) {
- var b = number % 10,
- output = (~~ (number % 100 / 10) === 1) ? 'th' :
- (b === 1) ? 'st' :
- (b === 2) ? 'nd' :
- (b === 3) ? 'rd' : 'th';
- return number + output;
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ else { // in SW
+ this._placeInRegion(parentBranch,node,"SW");
+ }
+ }
+ else { // in NE or SE
+ if (parentBranch.children.NW.range.maxY > node.y) { // in NE
+ this._placeInRegion(parentBranch,node,"NE");
+ }
+ else { // in SE
+ this._placeInRegion(parentBranch,node,"SE");
+ }
+ }
+ };
-/***/ },
-/* 71 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * actually place the node in a region (or branch)
+ *
+ * @param parentBranch
+ * @param node
+ * @param region
+ * @private
+ */
+ exports._placeInRegion = function(parentBranch,node,region) {
+ switch (parentBranch.children[region].childrenCount) {
+ case 0: // place node here
+ parentBranch.children[region].children.data = node;
+ parentBranch.children[region].childrenCount = 1;
+ this._updateBranchMass(parentBranch.children[region],node);
+ break;
+ case 1: // convert into children
+ // if there are two nodes exactly overlapping (on init, on opening of cluster etc.)
+ // we move one node a pixel and we do not put it in the tree.
+ if (parentBranch.children[region].children.data.x == node.x &&
+ parentBranch.children[region].children.data.y == node.y) {
+ node.x += Math.random();
+ node.y += Math.random();
+ }
+ else {
+ this._splitBranch(parentBranch.children[region]);
+ this._placeInTree(parentBranch.children[region],node);
+ }
+ break;
+ case 4: // place in branch
+ this._placeInTree(parentBranch.children[region],node);
+ break;
+ }
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : canadian english (en-ca)
- // author : Jonathan Abourbih : https://github.com/jonbca
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('en-ca', {
- months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
- monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
- weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
- weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
- weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
- longDateFormat : {
- LT : "h:mm A",
- L : "YYYY-MM-DD",
- LL : "D MMMM, YYYY",
- LLL : "D MMMM, YYYY LT",
- LLLL : "dddd, D MMMM, YYYY LT"
- },
- calendar : {
- sameDay : '[Today at] LT',
- nextDay : '[Tomorrow at] LT',
- nextWeek : 'dddd [at] LT',
- lastDay : '[Yesterday at] LT',
- lastWeek : '[Last] dddd [at] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "in %s",
- past : "%s ago",
- s : "a few seconds",
- m : "a minute",
- mm : "%d minutes",
- h : "an hour",
- hh : "%d hours",
- d : "a day",
- dd : "%d days",
- M : "a month",
- MM : "%d months",
- y : "a year",
- yy : "%d years"
- },
- ordinal : function (number) {
- var b = number % 10,
- output = (~~ (number % 100 / 10) === 1) ? 'th' :
- (b === 1) ? 'st' :
- (b === 2) ? 'nd' :
- (b === 3) ? 'rd' : 'th';
- return number + output;
- }
- });
- }));
+ /**
+ * this function splits a branch into 4 sub branches. If the branch contained a node, we place it in the subbranch
+ * after the split is complete.
+ *
+ * @param parentBranch
+ * @private
+ */
+ exports._splitBranch = function(parentBranch) {
+ // if the branch is shaded with a node, replace the node in the new subset.
+ var containedNode = null;
+ if (parentBranch.childrenCount == 1) {
+ containedNode = parentBranch.children.data;
+ parentBranch.mass = 0; parentBranch.centerOfMass.x = 0; parentBranch.centerOfMass.y = 0;
+ }
+ parentBranch.childrenCount = 4;
+ parentBranch.children.data = null;
+ this._insertRegion(parentBranch,"NW");
+ this._insertRegion(parentBranch,"NE");
+ this._insertRegion(parentBranch,"SW");
+ this._insertRegion(parentBranch,"SE");
+ if (containedNode != null) {
+ this._placeInTree(parentBranch,containedNode);
+ }
+ };
-/***/ },
-/* 72 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : great britain english (en-gb)
- // author : Chris Gedrim : https://github.com/chrisgedrim
+ /**
+ * This function subdivides the region into four new segments.
+ * Specifically, this inserts a single new segment.
+ * It fills the children section of the parentBranch
+ *
+ * @param parentBranch
+ * @param region
+ * @param parentRange
+ * @private
+ */
+ exports._insertRegion = function(parentBranch, region) {
+ var minX,maxX,minY,maxY;
+ var childSize = 0.5 * parentBranch.size;
+ switch (region) {
+ case "NW":
+ minX = parentBranch.range.minX;
+ maxX = parentBranch.range.minX + childSize;
+ minY = parentBranch.range.minY;
+ maxY = parentBranch.range.minY + childSize;
+ break;
+ case "NE":
+ minX = parentBranch.range.minX + childSize;
+ maxX = parentBranch.range.maxX;
+ minY = parentBranch.range.minY;
+ maxY = parentBranch.range.minY + childSize;
+ break;
+ case "SW":
+ minX = parentBranch.range.minX;
+ maxX = parentBranch.range.minX + childSize;
+ minY = parentBranch.range.minY + childSize;
+ maxY = parentBranch.range.maxY;
+ break;
+ case "SE":
+ minX = parentBranch.range.minX + childSize;
+ maxX = parentBranch.range.maxX;
+ minY = parentBranch.range.minY + childSize;
+ maxY = parentBranch.range.maxY;
+ break;
+ }
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('en-gb', {
- months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
- monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
- weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
- weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
- weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[Today at] LT',
- nextDay : '[Tomorrow at] LT',
- nextWeek : 'dddd [at] LT',
- lastDay : '[Yesterday at] LT',
- lastWeek : '[Last] dddd [at] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "in %s",
- past : "%s ago",
- s : "a few seconds",
- m : "a minute",
- mm : "%d minutes",
- h : "an hour",
- hh : "%d hours",
- d : "a day",
- dd : "%d days",
- M : "a month",
- MM : "%d months",
- y : "a year",
- yy : "%d years"
- },
- ordinal : function (number) {
- var b = number % 10,
- output = (~~ (number % 100 / 10) === 1) ? 'th' :
- (b === 1) ? 'st' :
- (b === 2) ? 'nd' :
- (b === 3) ? 'rd' : 'th';
- return number + output;
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ parentBranch.children[region] = {
+ centerOfMass:{x:0,y:0},
+ mass:0,
+ range:{minX:minX,maxX:maxX,minY:minY,maxY:maxY},
+ size: 0.5 * parentBranch.size,
+ calcSize: 2 * parentBranch.calcSize,
+ children: {data:null},
+ maxWidth: 0,
+ level: parentBranch.level+1,
+ childrenCount: 0
+ };
+ };
-/***/ },
-/* 73 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : esperanto (eo)
- // author : Colin Dean : https://github.com/colindean
- // komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko.
- // Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!
+ /**
+ * This function is for debugging purposed, it draws the tree.
+ *
+ * @param ctx
+ * @param color
+ * @private
+ */
+ exports._drawTree = function(ctx,color) {
+ if (this.barnesHutTree !== undefined) {
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('eo', {
- months : "januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"),
- monthsShort : "jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec".split("_"),
- weekdays : "Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato".split("_"),
- weekdaysShort : "Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab".split("_"),
- weekdaysMin : "Di_Lu_Ma_Me_Ĵa_Ve_Sa".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "YYYY-MM-DD",
- LL : "D[-an de] MMMM, YYYY",
- LLL : "D[-an de] MMMM, YYYY LT",
- LLLL : "dddd, [la] D[-an de] MMMM, YYYY LT"
- },
- meridiem : function (hours, minutes, isLower) {
- if (hours > 11) {
- return isLower ? 'p.t.m.' : 'P.T.M.';
- } else {
- return isLower ? 'a.t.m.' : 'A.T.M.';
- }
- },
- calendar : {
- sameDay : '[Hodiaŭ je] LT',
- nextDay : '[Morgaŭ je] LT',
- nextWeek : 'dddd [je] LT',
- lastDay : '[Hieraŭ je] LT',
- lastWeek : '[pasinta] dddd [je] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "je %s",
- past : "antaŭ %s",
- s : "sekundoj",
- m : "minuto",
- mm : "%d minutoj",
- h : "horo",
- hh : "%d horoj",
- d : "tago",//ne 'diurno', ĉar estas uzita por proksimumo
- dd : "%d tagoj",
- M : "monato",
- MM : "%d monatoj",
- y : "jaro",
- yy : "%d jaroj"
- },
- ordinal : "%da",
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ ctx.lineWidth = 1;
+ this._drawBranch(this.barnesHutTree.root,ctx,color);
+ }
+ };
-/***/ },
-/* 74 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : spanish (es)
- // author : Julio Napurí : https://github.com/julionc
+ /**
+ * This function is for debugging purposes. It draws the branches recursively.
+ *
+ * @param branch
+ * @param ctx
+ * @param color
+ * @private
+ */
+ exports._drawBranch = function(branch,ctx,color) {
+ if (color === undefined) {
+ color = "#FF0000";
+ }
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var monthsShortDot = "ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),
- monthsShort = "ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");
+ if (branch.childrenCount == 4) {
+ this._drawBranch(branch.children.NW,ctx);
+ this._drawBranch(branch.children.NE,ctx);
+ this._drawBranch(branch.children.SE,ctx);
+ this._drawBranch(branch.children.SW,ctx);
+ }
+ ctx.strokeStyle = color;
+ ctx.beginPath();
+ ctx.moveTo(branch.range.minX,branch.range.minY);
+ ctx.lineTo(branch.range.maxX,branch.range.minY);
+ ctx.stroke();
- return moment.lang('es', {
- months : "enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),
- monthsShort : function (m, format) {
- if (/-MMM-/.test(format)) {
- return monthsShort[m.month()];
- } else {
- return monthsShortDot[m.month()];
- }
- },
- weekdays : "domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),
- weekdaysShort : "dom._lun._mar._mié._jue._vie._sáb.".split("_"),
- weekdaysMin : "Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD/MM/YYYY",
- LL : "D [de] MMMM [del] YYYY",
- LLL : "D [de] MMMM [del] YYYY LT",
- LLLL : "dddd, D [de] MMMM [del] YYYY LT"
- },
- calendar : {
- sameDay : function () {
- return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
- },
- nextDay : function () {
- return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
- },
- nextWeek : function () {
- return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
- },
- lastDay : function () {
- return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
- },
- lastWeek : function () {
- return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "en %s",
- past : "hace %s",
- s : "unos segundos",
- m : "un minuto",
- mm : "%d minutos",
- h : "una hora",
- hh : "%d horas",
- d : "un día",
- dd : "%d días",
- M : "un mes",
- MM : "%d meses",
- y : "un año",
- yy : "%d años"
- },
- ordinal : '%dº',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ ctx.beginPath();
+ ctx.moveTo(branch.range.maxX,branch.range.minY);
+ ctx.lineTo(branch.range.maxX,branch.range.maxY);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(branch.range.maxX,branch.range.maxY);
+ ctx.lineTo(branch.range.minX,branch.range.maxY);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(branch.range.minX,branch.range.maxY);
+ ctx.lineTo(branch.range.minX,branch.range.minY);
+ ctx.stroke();
+
+ /*
+ if (branch.mass > 0) {
+ ctx.circle(branch.centerOfMass.x, branch.centerOfMass.y, 3*branch.mass);
+ ctx.stroke();
+ }
+ */
+ };
/***/ },
-/* 75 */
+/* 124 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : estonian (et)
- // author : Henry Kehlmann : https://github.com/madhenry
- // improvements : Illimar Tambek : https://github.com/ragulka
+ /**
+ * Creation of the ClusterMixin var.
+ *
+ * This contains all the functions the Network object can use to employ clustering
+ */
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- function processRelativeTime(number, withoutSuffix, key, isFuture) {
- var format = {
- 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
- 'm' : ['ühe minuti', 'üks minut'],
- 'mm': [number + ' minuti', number + ' minutit'],
- 'h' : ['ühe tunni', 'tund aega', 'üks tund'],
- 'hh': [number + ' tunni', number + ' tundi'],
- 'd' : ['ühe päeva', 'üks päev'],
- 'M' : ['kuu aja', 'kuu aega', 'üks kuu'],
- 'MM': [number + ' kuu', number + ' kuud'],
- 'y' : ['ühe aasta', 'aasta', 'üks aasta'],
- 'yy': [number + ' aasta', number + ' aastat']
- };
- if (withoutSuffix) {
- return format[key][2] ? format[key][2] : format[key][1];
- }
- return isFuture ? format[key][0] : format[key][1];
- }
+ /**
+ * This is only called in the constructor of the network object
+ *
+ */
+ exports.startWithClustering = function() {
+ // cluster if the data set is big
+ this.clusterToFit(this.constants.clustering.initialMaxNodes, true);
- return moment.lang('et', {
- months : "jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),
- monthsShort : "jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),
- weekdays : "pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"),
- weekdaysShort : "P_E_T_K_N_R_L".split("_"),
- weekdaysMin : "P_E_T_K_N_R_L".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD.MM.YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd, D. MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[Täna,] LT',
- nextDay : '[Homme,] LT',
- nextWeek : '[Järgmine] dddd LT',
- lastDay : '[Eile,] LT',
- lastWeek : '[Eelmine] dddd LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s pärast",
- past : "%s tagasi",
- s : processRelativeTime,
- m : processRelativeTime,
- mm : processRelativeTime,
- h : processRelativeTime,
- hh : processRelativeTime,
- d : processRelativeTime,
- dd : '%d päeva',
- M : processRelativeTime,
- MM : processRelativeTime,
- y : processRelativeTime,
- yy : processRelativeTime
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ // updates the lables after clustering
+ this.updateLabels();
+ // this is called here because if clusterin is disabled, the start and stabilize are called in
+ // the setData function.
+ if (this.stabilize) {
+ this._stabilize();
+ }
+ this.start();
+ };
-/***/ },
-/* 76 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This function clusters until the initialMaxNodes has been reached
+ *
+ * @param {Number} maxNumberOfNodes
+ * @param {Boolean} reposition
+ */
+ exports.clusterToFit = function(maxNumberOfNodes, reposition) {
+ var numberOfNodes = this.nodeIndices.length;
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : euskara (eu)
- // author : Eneko Illarramendi : https://github.com/eillarra
+ var maxLevels = 50;
+ var level = 0;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // we first cluster the hubs, then we pull in the outliers, repeat
+ while (numberOfNodes > maxNumberOfNodes && level < maxLevels) {
+ if (level % 3 == 0) {
+ this.forceAggregateHubs(true);
+ this.normalizeClusterLevels();
+ }
+ else {
+ this.increaseClusterLevel(); // this also includes a cluster normalization
}
- }(function (moment) {
- return moment.lang('eu', {
- months : "urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),
- monthsShort : "urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),
- weekdays : "igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),
- weekdaysShort : "ig._al._ar._az._og._ol._lr.".split("_"),
- weekdaysMin : "ig_al_ar_az_og_ol_lr".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "YYYY-MM-DD",
- LL : "YYYY[ko] MMMM[ren] D[a]",
- LLL : "YYYY[ko] MMMM[ren] D[a] LT",
- LLLL : "dddd, YYYY[ko] MMMM[ren] D[a] LT",
- l : "YYYY-M-D",
- ll : "YYYY[ko] MMM D[a]",
- lll : "YYYY[ko] MMM D[a] LT",
- llll : "ddd, YYYY[ko] MMM D[a] LT"
- },
- calendar : {
- sameDay : '[gaur] LT[etan]',
- nextDay : '[bihar] LT[etan]',
- nextWeek : 'dddd LT[etan]',
- lastDay : '[atzo] LT[etan]',
- lastWeek : '[aurreko] dddd LT[etan]',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s barru",
- past : "duela %s",
- s : "segundo batzuk",
- m : "minutu bat",
- mm : "%d minutu",
- h : "ordu bat",
- hh : "%d ordu",
- d : "egun bat",
- dd : "%d egun",
- M : "hilabete bat",
- MM : "%d hilabete",
- y : "urte bat",
- yy : "%d urte"
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ numberOfNodes = this.nodeIndices.length;
+ level += 1;
+ }
-/***/ },
-/* 77 */
-/***/ function(module, exports, __webpack_require__) {
+ // after the clustering we reposition the nodes to reduce the initial chaos
+ if (level > 0 && reposition == true) {
+ this.repositionNodes();
+ }
+ this._updateCalculationNodes();
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Persian Language
- // author : Ebrahim Byagowi : https://github.com/ebraminio
+ /**
+ * This function can be called to open up a specific cluster. It is only called by
+ * It will unpack the cluster back one level.
+ *
+ * @param node | Node object: cluster to open.
+ */
+ exports.openCluster = function(node) {
+ var isMovingBeforeClustering = this.moving;
+ if (node.clusterSize > this.constants.clustering.sectorThreshold && this._nodeInActiveArea(node) &&
+ !(this._sector() == "default" && this.nodeIndices.length == 1)) {
+ // this loads a new sector, loads the nodes and edges and nodeIndices of it.
+ this._addSector(node);
+ var level = 0;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // we decluster until we reach a decent number of nodes
+ while ((this.nodeIndices.length < this.constants.clustering.initialMaxNodes) && (level < 10)) {
+ this.decreaseClusterLevel();
+ level += 1;
}
- }(function (moment) {
- var symbolMap = {
- '1': '۱',
- '2': '۲',
- '3': '۳',
- '4': '۴',
- '5': '۵',
- '6': '۶',
- '7': '۷',
- '8': '۸',
- '9': '۹',
- '0': '۰'
- }, numberMap = {
- '۱': '1',
- '۲': '2',
- '۳': '3',
- '۴': '4',
- '۵': '5',
- '۶': '6',
- '۷': '7',
- '۸': '8',
- '۹': '9',
- '۰': '0'
- };
- return moment.lang('fa', {
- months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
- monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
- weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
- weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
- weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
- longDateFormat : {
- LT : 'HH:mm',
- L : 'DD/MM/YYYY',
- LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 12) {
- return "قبل از ظهر";
- } else {
- return "بعد از ظهر";
- }
- },
- calendar : {
- sameDay : '[امروز ساعت] LT',
- nextDay : '[فردا ساعت] LT',
- nextWeek : 'dddd [ساعت] LT',
- lastDay : '[دیروز ساعت] LT',
- lastWeek : 'dddd [پیش] [ساعت] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : 'در %s',
- past : '%s پیش',
- s : 'چندین ثانیه',
- m : 'یک دقیقه',
- mm : '%d دقیقه',
- h : 'یک ساعت',
- hh : '%d ساعت',
- d : 'یک روز',
- dd : '%d روز',
- M : 'یک ماه',
- MM : '%d ماه',
- y : 'یک سال',
- yy : '%d سال'
- },
- preparse: function (string) {
- return string.replace(/[۰-۹]/g, function (match) {
- return numberMap[match];
- }).replace(/،/g, ',');
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- }).replace(/,/g, '،');
- },
- ordinal : '%dم',
- week : {
- dow : 6, // Saturday is the first day of the week.
- doy : 12 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ }
+ else {
+ this._expandClusterNode(node,false,true);
+ // update the index list, dynamic edges and labels
+ this._updateNodeIndexList();
+ this._updateDynamicEdges();
+ this._updateCalculationNodes();
+ this.updateLabels();
+ }
-/***/ },
-/* 78 */
-/***/ function(module, exports, __webpack_require__) {
+ // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
+ if (this.moving != isMovingBeforeClustering) {
+ this.start();
+ }
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : finnish (fi)
- // author : Tarmo Aidantausta : https://github.com/bleadof
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),
- numbersFuture = ['nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
- numbersPast[7], numbersPast[8], numbersPast[9]];
+ /**
+ * This calls the updateClustes with default arguments
+ */
+ exports.updateClustersDefault = function() {
+ if (this.constants.clustering.enabled == true) {
+ this.updateClusters(0,false,false);
+ }
+ };
- function translate(number, withoutSuffix, key, isFuture) {
- var result = "";
- switch (key) {
- case 's':
- return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
- case 'm':
- return isFuture ? 'minuutin' : 'minuutti';
- case 'mm':
- result = isFuture ? 'minuutin' : 'minuuttia';
- break;
- case 'h':
- return isFuture ? 'tunnin' : 'tunti';
- case 'hh':
- result = isFuture ? 'tunnin' : 'tuntia';
- break;
- case 'd':
- return isFuture ? 'päivän' : 'päivä';
- case 'dd':
- result = isFuture ? 'päivän' : 'päivää';
- break;
- case 'M':
- return isFuture ? 'kuukauden' : 'kuukausi';
- case 'MM':
- result = isFuture ? 'kuukauden' : 'kuukautta';
- break;
- case 'y':
- return isFuture ? 'vuoden' : 'vuosi';
- case 'yy':
- result = isFuture ? 'vuoden' : 'vuotta';
- break;
- }
- result = verbalNumber(number, isFuture) + " " + result;
- return result;
- }
- function verbalNumber(number, isFuture) {
- return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;
+ /**
+ * This function can be called to increase the cluster level. This means that the nodes with only one edge connection will
+ * be clustered with their connected node. This can be repeated as many times as needed.
+ * This can be called externally (by a keybind for instance) to reduce the complexity of big datasets.
+ */
+ exports.increaseClusterLevel = function() {
+ this.updateClusters(-1,false,true);
+ };
+
+
+ /**
+ * This function can be called to decrease the cluster level. This means that the nodes with only one edge connection will
+ * be unpacked if they are a cluster. This can be repeated as many times as needed.
+ * This can be called externally (by a key-bind for instance) to look into clusters without zooming.
+ */
+ exports.decreaseClusterLevel = function() {
+ this.updateClusters(1,false,true);
+ };
+
+
+ /**
+ * This is the main clustering function. It clusters and declusters on zoom or forced
+ * This function clusters on zoom, it can be called with a predefined zoom direction
+ * If out, check if we can form clusters, if in, check if we can open clusters.
+ * This function is only called from _zoom()
+ *
+ * @param {Number} zoomDirection | -1 / 0 / +1 for zoomOut / determineByZoom / zoomIn
+ * @param {Boolean} recursive | enabled or disable recursive calling of the opening of clusters
+ * @param {Boolean} force | enabled or disable forcing
+ * @param {Boolean} doNotStart | if true do not call start
+ *
+ */
+ exports.updateClusters = function(zoomDirection,recursive,force,doNotStart) {
+ var isMovingBeforeClustering = this.moving;
+ var amountOfNodes = this.nodeIndices.length;
+
+ // on zoom out collapse the sector if the scale is at the level the sector was made
+ if (this.previousScale > this.scale && zoomDirection == 0) {
+ this._collapseSector();
+ }
+
+ // check if we zoom in or out
+ if (this.previousScale > this.scale || zoomDirection == -1) { // zoom out
+ // forming clusters when forced pulls outliers in. When not forced, the edge length of the
+ // outer nodes determines if it is being clustered
+ this._formClusters(force);
+ }
+ else if (this.previousScale < this.scale || zoomDirection == 1) { // zoom in
+ if (force == true) {
+ // _openClusters checks for each node if the formationScale of the cluster is smaller than
+ // the current scale and if so, declusters. When forced, all clusters are reduced by one step
+ this._openClusters(recursive,force);
+ }
+ else {
+ // if a cluster takes up a set percentage of the active window
+ this._openClustersBySize();
}
+ }
+ this._updateNodeIndexList();
- return moment.lang('fi', {
- months : "tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),
- monthsShort : "tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),
- weekdays : "sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),
- weekdaysShort : "su_ma_ti_ke_to_pe_la".split("_"),
- weekdaysMin : "su_ma_ti_ke_to_pe_la".split("_"),
- longDateFormat : {
- LT : "HH.mm",
- L : "DD.MM.YYYY",
- LL : "Do MMMM[ta] YYYY",
- LLL : "Do MMMM[ta] YYYY, [klo] LT",
- LLLL : "dddd, Do MMMM[ta] YYYY, [klo] LT",
- l : "D.M.YYYY",
- ll : "Do MMM YYYY",
- lll : "Do MMM YYYY, [klo] LT",
- llll : "ddd, Do MMM YYYY, [klo] LT"
- },
- calendar : {
- sameDay : '[tänään] [klo] LT',
- nextDay : '[huomenna] [klo] LT',
- nextWeek : 'dddd [klo] LT',
- lastDay : '[eilen] [klo] LT',
- lastWeek : '[viime] dddd[na] [klo] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s päästä",
- past : "%s sitten",
- s : translate,
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : translate,
- dd : translate,
- M : translate,
- MM : translate,
- y : translate,
- yy : translate
- },
- ordinal : "%d.",
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ // if a cluster was NOT formed and the user zoomed out, we try clustering by hubs
+ if (this.nodeIndices.length == amountOfNodes && (this.previousScale > this.scale || zoomDirection == -1)) {
+ this._aggregateHubs(force);
+ this._updateNodeIndexList();
+ }
+
+ // we now reduce chains.
+ if (this.previousScale > this.scale || zoomDirection == -1) { // zoom out
+ this.handleChains();
+ this._updateNodeIndexList();
+ }
+
+ this.previousScale = this.scale;
+
+ // rest of the update the index list, dynamic edges and labels
+ this._updateDynamicEdges();
+ this.updateLabels();
+
+ // if a cluster was formed, we increase the clusterSession
+ if (this.nodeIndices.length < amountOfNodes) { // this means a clustering operation has taken place
+ this.clusterSession += 1;
+ // if clusters have been made, we normalize the cluster level
+ this.normalizeClusterLevels();
+ }
+ if (doNotStart == false || doNotStart === undefined) {
+ // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
+ if (this.moving != isMovingBeforeClustering) {
+ this.start();
+ }
+ }
-/***/ },
-/* 79 */
-/***/ function(module, exports, __webpack_require__) {
+ this._updateCalculationNodes();
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : faroese (fo)
- // author : Ragnar Johannesen : https://github.com/ragnar123
+ /**
+ * This function handles the chains. It is called on every updateClusters().
+ */
+ exports.handleChains = function() {
+ // after clustering we check how many chains there are
+ var chainPercentage = this._getChainFraction();
+ if (chainPercentage > this.constants.clustering.chainThreshold) {
+ this._reduceAmountOfChains(1 - this.constants.clustering.chainThreshold / chainPercentage)
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('fo', {
- months : "januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"),
- monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),
- weekdays : "sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"),
- weekdaysShort : "sun_mán_týs_mik_hós_frí_ley".split("_"),
- weekdaysMin : "su_má_tý_mi_hó_fr_le".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D. MMMM, YYYY LT"
- },
- calendar : {
- sameDay : '[Í dag kl.] LT',
- nextDay : '[Í morgin kl.] LT',
- nextWeek : 'dddd [kl.] LT',
- lastDay : '[Í gjár kl.] LT',
- lastWeek : '[síðstu] dddd [kl] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "um %s",
- past : "%s síðani",
- s : "fá sekund",
- m : "ein minutt",
- mm : "%d minuttir",
- h : "ein tími",
- hh : "%d tímar",
- d : "ein dagur",
- dd : "%d dagar",
- M : "ein mánaði",
- MM : "%d mánaðir",
- y : "eitt ár",
- yy : "%d ár"
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ }
+ };
+ /**
+ * this functions starts clustering by hubs
+ * The minimum hub threshold is set globally
+ *
+ * @private
+ */
+ exports._aggregateHubs = function(force) {
+ this._getHubSize();
+ this._formClustersByHub(force,false);
+ };
-/***/ },
-/* 80 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : canadian french (fr-ca)
- // author : Jonathan Abourbih : https://github.com/jonbca
+ /**
+ * This function is fired by keypress. It forces hubs to form.
+ *
+ */
+ exports.forceAggregateHubs = function(doNotStart) {
+ var isMovingBeforeClustering = this.moving;
+ var amountOfNodes = this.nodeIndices.length;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ this._aggregateHubs(true);
+
+ // update the index list, dynamic edges and labels
+ this._updateNodeIndexList();
+ this._updateDynamicEdges();
+ this.updateLabels();
+
+ // if a cluster was formed, we increase the clusterSession
+ if (this.nodeIndices.length != amountOfNodes) {
+ this.clusterSession += 1;
+ }
+
+ if (doNotStart == false || doNotStart === undefined) {
+ // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
+ if (this.moving != isMovingBeforeClustering) {
+ this.start();
}
- }(function (moment) {
- return moment.lang('fr-ca', {
- months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
- monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
- weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
- weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"),
- weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "YYYY-MM-DD",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[Aujourd'hui à] LT",
- nextDay: '[Demain à] LT',
- nextWeek: 'dddd [à] LT',
- lastDay: '[Hier à] LT',
- lastWeek: 'dddd [dernier à] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "dans %s",
- past : "il y a %s",
- s : "quelques secondes",
- m : "une minute",
- mm : "%d minutes",
- h : "une heure",
- hh : "%d heures",
- d : "un jour",
- dd : "%d jours",
- M : "un mois",
- MM : "%d mois",
- y : "un an",
- yy : "%d ans"
- },
- ordinal : function (number) {
- return number + (number === 1 ? 'er' : '');
- }
- });
- }));
+ }
+ };
+ /**
+ * If a cluster takes up more than a set percentage of the screen, open the cluster
+ *
+ * @private
+ */
+ exports._openClustersBySize = function() {
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ var node = this.nodes[nodeId];
+ if (node.inView() == true) {
+ if ((node.width*this.scale > this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientWidth) ||
+ (node.height*this.scale > this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientHeight)) {
+ this.openCluster(node);
+ }
+ }
+ }
+ }
+ };
-/***/ },
-/* 81 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : french (fr)
- // author : John Fischer : https://github.com/jfroffice
+ /**
+ * This function loops over all nodes in the nodeIndices list. For each node it checks if it is a cluster and if it
+ * has to be opened based on the current zoom level.
+ *
+ * @private
+ */
+ exports._openClusters = function(recursive,force) {
+ for (var i = 0; i < this.nodeIndices.length; i++) {
+ var node = this.nodes[this.nodeIndices[i]];
+ this._expandClusterNode(node,recursive,force);
+ this._updateCalculationNodes();
+ }
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * This function checks if a node has to be opened. This is done by checking the zoom level.
+ * If the node contains child nodes, this function is recursively called on the child nodes as well.
+ * This recursive behaviour is optional and can be set by the recursive argument.
+ *
+ * @param {Node} parentNode | to check for cluster and expand
+ * @param {Boolean} recursive | enabled or disable recursive calling
+ * @param {Boolean} force | enabled or disable forcing
+ * @param {Boolean} [openAll] | This will recursively force all nodes in the parent to be released
+ * @private
+ */
+ exports._expandClusterNode = function(parentNode, recursive, force, openAll) {
+ // first check if node is a cluster
+ if (parentNode.clusterSize > 1) {
+ // this means that on a double tap event or a zoom event, the cluster fully unpacks if it is smaller than 20
+ if (parentNode.clusterSize < this.constants.clustering.sectorThreshold) {
+ openAll = true;
}
- }(function (moment) {
- return moment.lang('fr', {
- months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
- monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
- weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
- weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"),
- weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[Aujourd'hui à] LT",
- nextDay: '[Demain à] LT',
- nextWeek: 'dddd [à] LT',
- lastDay: '[Hier à] LT',
- lastWeek: 'dddd [dernier à] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "dans %s",
- past : "il y a %s",
- s : "quelques secondes",
- m : "une minute",
- mm : "%d minutes",
- h : "une heure",
- hh : "%d heures",
- d : "un jour",
- dd : "%d jours",
- M : "un mois",
- MM : "%d mois",
- y : "un an",
- yy : "%d ans"
- },
- ordinal : function (number) {
- return number + (number === 1 ? 'er' : '');
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
+ recursive = openAll ? true : recursive;
+
+ // if the last child has been added on a smaller scale than current scale decluster
+ if (parentNode.formationScale < this.scale || force == true) {
+ // we will check if any of the contained child nodes should be removed from the cluster
+ for (var containedNodeId in parentNode.containedNodes) {
+ if (parentNode.containedNodes.hasOwnProperty(containedNodeId)) {
+ var childNode = parentNode.containedNodes[containedNodeId];
+
+ // force expand will expand the largest cluster size clusters. Since we cluster from outside in, we assume that
+ // the largest cluster is the one that comes from outside
+ if (force == true) {
+ if (childNode.clusterSession == parentNode.clusterSessions[parentNode.clusterSessions.length-1]
+ || openAll) {
+ this._expelChildFromParent(parentNode,containedNodeId,recursive,force,openAll);
+ }
+ }
+ else {
+ if (this._nodeInActiveArea(parentNode)) {
+ this._expelChildFromParent(parentNode,containedNodeId,recursive,force,openAll);
+ }
+ }
}
- });
- }));
+ }
+ }
+ }
+ };
+ /**
+ * ONLY CALLED FROM _expandClusterNode
+ *
+ * This function will expel a child_node from a parent_node. This is to de-cluster the node. This function will remove
+ * the child node from the parent contained_node object and put it back into the global nodes object.
+ * The same holds for the edge that was connected to the child node. It is moved back into the global edges object.
+ *
+ * @param {Node} parentNode | the parent node
+ * @param {String} containedNodeId | child_node id as it is contained in the containedNodes object of the parent node
+ * @param {Boolean} recursive | This will also check if the child needs to be expanded.
+ * With force and recursive both true, the entire cluster is unpacked
+ * @param {Boolean} force | This will disregard the zoom level and will expel this child from the parent
+ * @param {Boolean} openAll | This will recursively force all nodes in the parent to be released
+ * @private
+ */
+ exports._expelChildFromParent = function(parentNode, containedNodeId, recursive, force, openAll) {
+ var childNode = parentNode.containedNodes[containedNodeId];
-/***/ },
-/* 82 */
-/***/ function(module, exports, __webpack_require__) {
+ // if child node has been added on smaller scale than current, kick out
+ if (childNode.formationScale < this.scale || force == true) {
+ // unselect all selected items
+ this._unselectAll();
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : galician (gl)
- // author : Juan G. Hurtado : https://github.com/juanghurtado
+ // put the child node back in the global nodes object
+ this.nodes[containedNodeId] = childNode;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('gl', {
- months : "Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro".split("_"),
- monthsShort : "Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"),
- weekdays : "Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"),
- weekdaysShort : "Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"),
- weekdaysMin : "Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay : function () {
- return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
- },
- nextDay : function () {
- return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
- },
- nextWeek : function () {
- return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
- },
- lastDay : function () {
- return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';
- },
- lastWeek : function () {
- return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : function (str) {
- if (str === "uns segundos") {
- return "nuns segundos";
- }
- return "en " + str;
- },
- past : "hai %s",
- s : "uns segundos",
- m : "un minuto",
- mm : "%d minutos",
- h : "unha hora",
- hh : "%d horas",
- d : "un día",
- dd : "%d días",
- M : "un mes",
- MM : "%d meses",
- y : "un ano",
- yy : "%d anos"
- },
- ordinal : '%dº',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ // release the contained edges from this childNode back into the global edges
+ this._releaseContainedEdges(parentNode,childNode);
+ // reconnect rerouted edges to the childNode
+ this._connectEdgeBackToChild(parentNode,childNode);
-/***/ },
-/* 83 */
-/***/ function(module, exports, __webpack_require__) {
+ // validate all edges in dynamicEdges
+ this._validateEdges(parentNode);
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Hebrew (he)
- // author : Tomer Cohen : https://github.com/tomer
- // author : Moshe Simantov : https://github.com/DevelopmentIL
- // author : Tal Ater : https://github.com/TalAter
+ // undo the changes from the clustering operation on the parent node
+ parentNode.mass -= childNode.mass;
+ parentNode.clusterSize -= childNode.clusterSize;
+ parentNode.fontSize = Math.min(this.constants.clustering.maxFontSize, this.constants.nodes.fontSize + this.constants.clustering.fontSizeMultiplier*parentNode.clusterSize);
+ parentNode.dynamicEdgesLength = parentNode.dynamicEdges.length;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('he', {
- months : "ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),
- monthsShort : "ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),
- weekdays : "ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),
- weekdaysShort : "א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),
- weekdaysMin : "א_ב_ג_ד_ה_ו_ש".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D [ב]MMMM YYYY",
- LLL : "D [ב]MMMM YYYY LT",
- LLLL : "dddd, D [ב]MMMM YYYY LT",
- l : "D/M/YYYY",
- ll : "D MMM YYYY",
- lll : "D MMM YYYY LT",
- llll : "ddd, D MMM YYYY LT"
- },
- calendar : {
- sameDay : '[היום ב־]LT',
- nextDay : '[מחר ב־]LT',
- nextWeek : 'dddd [בשעה] LT',
- lastDay : '[אתמול ב־]LT',
- lastWeek : '[ביום] dddd [האחרון בשעה] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "בעוד %s",
- past : "לפני %s",
- s : "מספר שניות",
- m : "דקה",
- mm : "%d דקות",
- h : "שעה",
- hh : function (number) {
- if (number === 2) {
- return "שעתיים";
- }
- return number + " שעות";
- },
- d : "יום",
- dd : function (number) {
- if (number === 2) {
- return "יומיים";
- }
- return number + " ימים";
- },
- M : "חודש",
- MM : function (number) {
- if (number === 2) {
- return "חודשיים";
- }
- return number + " חודשים";
- },
- y : "שנה",
- yy : function (number) {
- if (number === 2) {
- return "שנתיים";
- }
- return number + " שנים";
- }
+ // place the child node near the parent, not at the exact same location to avoid chaos in the system
+ childNode.x = parentNode.x + parentNode.growthIndicator * (0.5 - Math.random());
+ childNode.y = parentNode.y + parentNode.growthIndicator * (0.5 - Math.random());
+
+ // remove node from the list
+ delete parentNode.containedNodes[containedNodeId];
+
+ // check if there are other childs with this clusterSession in the parent.
+ var othersPresent = false;
+ for (var childNodeId in parentNode.containedNodes) {
+ if (parentNode.containedNodes.hasOwnProperty(childNodeId)) {
+ if (parentNode.containedNodes[childNodeId].clusterSession == childNode.clusterSession) {
+ othersPresent = true;
+ break;
}
- });
- }));
+ }
+ }
+ // if there are no others, remove the cluster session from the list
+ if (othersPresent == false) {
+ parentNode.clusterSessions.pop();
+ }
+
+ this._repositionBezierNodes(childNode);
+ // this._repositionBezierNodes(parentNode);
+ // remove the clusterSession from the child node
+ childNode.clusterSession = 0;
-/***/ },
-/* 84 */
-/***/ function(module, exports, __webpack_require__) {
+ // recalculate the size of the node on the next time the node is rendered
+ parentNode.clearSizeCache();
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : hindi (hi)
- // author : Mayank Singhal : https://github.com/mayanksinghal
+ // restart the simulation to reorganise all nodes
+ this.moving = true;
+ }
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var symbolMap = {
- '1': '१',
- '2': '२',
- '3': '३',
- '4': '४',
- '5': '५',
- '6': '६',
- '7': '७',
- '8': '८',
- '9': '९',
- '0': '०'
- },
- numberMap = {
- '१': '1',
- '२': '2',
- '३': '3',
- '४': '4',
- '५': '5',
- '६': '6',
- '७': '7',
- '८': '8',
- '९': '9',
- '०': '0'
- };
+ // check if a further expansion step is possible if recursivity is enabled
+ if (recursive == true) {
+ this._expandClusterNode(childNode,recursive,force,openAll);
+ }
+ };
- return moment.lang('hi', {
- months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split("_"),
- monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split("_"),
- weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"),
- weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split("_"),
- weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"),
- longDateFormat : {
- LT : "A h:mm बजे",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY, LT",
- LLLL : "dddd, D MMMM YYYY, LT"
- },
- calendar : {
- sameDay : '[आज] LT',
- nextDay : '[कल] LT',
- nextWeek : 'dddd, LT',
- lastDay : '[कल] LT',
- lastWeek : '[पिछले] dddd, LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s में",
- past : "%s पहले",
- s : "कुछ ही क्षण",
- m : "एक मिनट",
- mm : "%d मिनट",
- h : "एक घंटा",
- hh : "%d घंटे",
- d : "एक दिन",
- dd : "%d दिन",
- M : "एक महीने",
- MM : "%d महीने",
- y : "एक वर्ष",
- yy : "%d वर्ष"
- },
- preparse: function (string) {
- return string.replace(/[१२३४५६७८९०]/g, function (match) {
- return numberMap[match];
- });
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- });
- },
- // Hindi notation for meridiems are quite fuzzy in practice. While there exists
- // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
- meridiem : function (hour, minute, isLower) {
- if (hour < 4) {
- return "रात";
- } else if (hour < 10) {
- return "सुबह";
- } else if (hour < 17) {
- return "दोपहर";
- } else if (hour < 20) {
- return "शाम";
- } else {
- return "रात";
- }
- },
- week : {
- dow : 0, // Sunday is the first day of the week.
- doy : 6 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+
+ /**
+ * position the bezier nodes at the center of the edges
+ *
+ * @param node
+ * @private
+ */
+ exports._repositionBezierNodes = function(node) {
+ for (var i = 0; i < node.dynamicEdges.length; i++) {
+ node.dynamicEdges[i].positionBezierNode();
+ }
+ };
-/***/ },
-/* 85 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This function checks if any nodes at the end of their trees have edges below a threshold length
+ * This function is called only from updateClusters()
+ * forceLevelCollapse ignores the length of the edge and collapses one level
+ * This means that a node with only one edge will be clustered with its connected node
+ *
+ * @private
+ * @param {Boolean} force
+ */
+ exports._formClusters = function(force) {
+ if (force == false) {
+ this._formClustersByZoom();
+ }
+ else {
+ this._forceClustersByZoom();
+ }
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : hrvatski (hr)
- // author : Bojan Marković : https://github.com/bmarkovic
- // based on (sl) translation by Robert Sedovšek
+ /**
+ * This function handles the clustering by zooming out, this is based on a minimum edge distance
+ *
+ * @private
+ */
+ exports._formClustersByZoom = function() {
+ var dx,dy,length,
+ minLength = this.constants.clustering.clusterEdgeThreshold/this.scale;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
+ // check if any edges are shorter than minLength and start the clustering
+ // the clustering favours the node with the larger mass
+ for (var edgeId in this.edges) {
+ if (this.edges.hasOwnProperty(edgeId)) {
+ var edge = this.edges[edgeId];
+ if (edge.connected) {
+ if (edge.toId != edge.fromId) {
+ dx = (edge.to.x - edge.from.x);
+ dy = (edge.to.y - edge.from.y);
+ length = Math.sqrt(dx * dx + dy * dy);
- function translate(number, withoutSuffix, key) {
- var result = number + " ";
- switch (key) {
- case 'm':
- return withoutSuffix ? 'jedna minuta' : 'jedne minute';
- case 'mm':
- if (number === 1) {
- result += 'minuta';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'minute';
- } else {
- result += 'minuta';
- }
- return result;
- case 'h':
- return withoutSuffix ? 'jedan sat' : 'jednog sata';
- case 'hh':
- if (number === 1) {
- result += 'sat';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'sata';
- } else {
- result += 'sati';
- }
- return result;
- case 'dd':
- if (number === 1) {
- result += 'dan';
- } else {
- result += 'dana';
+
+ if (length < minLength) {
+ // first check which node is larger
+ var parentNode = edge.from;
+ var childNode = edge.to;
+ if (edge.to.mass > edge.from.mass) {
+ parentNode = edge.to;
+ childNode = edge.from;
}
- return result;
- case 'MM':
- if (number === 1) {
- result += 'mjesec';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'mjeseca';
- } else {
- result += 'mjeseci';
+
+ if (childNode.dynamicEdgesLength == 1) {
+ this._addToCluster(parentNode,childNode,false);
}
- return result;
- case 'yy':
- if (number === 1) {
- result += 'godina';
- } else if (number === 2 || number === 3 || number === 4) {
- result += 'godine';
- } else {
- result += 'godina';
+ else if (parentNode.dynamicEdgesLength == 1) {
+ this._addToCluster(childNode,parentNode,false);
}
- return result;
+ }
}
+ }
}
+ }
+ };
- return moment.lang('hr', {
- months : "sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_"),
- monthsShort : "sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),
- weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),
- weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"),
- weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD. MM. YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd, D. MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[danas u] LT',
- nextDay : '[sutra u] LT',
+ /**
+ * This function forces the network to cluster all nodes with only one connecting edge to their
+ * connected node.
+ *
+ * @private
+ */
+ exports._forceClustersByZoom = function() {
+ for (var nodeId in this.nodes) {
+ // another node could have absorbed this child.
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ var childNode = this.nodes[nodeId];
- nextWeek : function () {
- switch (this.day()) {
- case 0:
- return '[u] [nedjelju] [u] LT';
- case 3:
- return '[u] [srijedu] [u] LT';
- case 6:
- return '[u] [subotu] [u] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[u] dddd [u] LT';
- }
- },
- lastDay : '[jučer u] LT',
- lastWeek : function () {
- switch (this.day()) {
- case 0:
- case 3:
- return '[prošlu] dddd [u] LT';
- case 6:
- return '[prošle] [subote] [u] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[prošli] dddd [u] LT';
- }
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "za %s",
- past : "prije %s",
- s : "par sekundi",
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : "dan",
- dd : translate,
- M : "mjesec",
- MM : translate,
- y : "godinu",
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
+ // the edges can be swallowed by another decrease
+ if (childNode.dynamicEdgesLength == 1 && childNode.dynamicEdges.length != 0) {
+ var edge = childNode.dynamicEdges[0];
+ var parentNode = (edge.toId == childNode.id) ? this.nodes[edge.fromId] : this.nodes[edge.toId];
+
+ // group to the largest node
+ if (childNode.id != parentNode.id) {
+ if (parentNode.mass > childNode.mass) {
+ this._addToCluster(parentNode,childNode,true);
+ }
+ else {
+ this._addToCluster(childNode,parentNode,true);
+ }
}
- });
- }));
+ }
+ }
+ }
+ };
-/***/ },
-/* 86 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * To keep the nodes of roughly equal size we normalize the cluster levels.
+ * This function clusters a node to its smallest connected neighbour.
+ *
+ * @param node
+ * @private
+ */
+ exports._clusterToSmallestNeighbour = function(node) {
+ var smallestNeighbour = -1;
+ var smallestNeighbourNode = null;
+ for (var i = 0; i < node.dynamicEdges.length; i++) {
+ if (node.dynamicEdges[i] !== undefined) {
+ var neighbour = null;
+ if (node.dynamicEdges[i].fromId != node.id) {
+ neighbour = node.dynamicEdges[i].from;
+ }
+ else if (node.dynamicEdges[i].toId != node.id) {
+ neighbour = node.dynamicEdges[i].to;
+ }
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : hungarian (hu)
- // author : Adam Brunner : https://github.com/adambrunner
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ if (neighbour != null && smallestNeighbour > neighbour.clusterSessions.length) {
+ smallestNeighbour = neighbour.clusterSessions.length;
+ smallestNeighbourNode = neighbour;
+ }
}
- }(function (moment) {
- var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
-
- function translate(number, withoutSuffix, key, isFuture) {
- var num = number,
- suffix;
+ }
- switch (key) {
- case 's':
- return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
- case 'm':
- return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
- case 'mm':
- return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
- case 'h':
- return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
- case 'hh':
- return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
- case 'd':
- return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
- case 'dd':
- return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
- case 'M':
- return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
- case 'MM':
- return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
- case 'y':
- return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
- case 'yy':
- return num + (isFuture || withoutSuffix ? ' év' : ' éve');
- }
+ if (neighbour != null && this.nodes[neighbour.id] !== undefined) {
+ this._addToCluster(neighbour, node, true);
+ }
+ };
- return '';
- }
- function week(isFuture) {
- return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
+ /**
+ * This function forms clusters from hubs, it loops over all nodes
+ *
+ * @param {Boolean} force | Disregard zoom level
+ * @param {Boolean} onlyEqual | This only clusters a hub with a specific number of edges
+ * @private
+ */
+ exports._formClustersByHub = function(force, onlyEqual) {
+ // we loop over all nodes in the list
+ for (var nodeId in this.nodes) {
+ // we check if it is still available since it can be used by the clustering in this loop
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ this._formClusterFromHub(this.nodes[nodeId],force,onlyEqual);
}
+ }
+ };
- return moment.lang('hu', {
- months : "január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),
- monthsShort : "jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),
- weekdays : "vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),
- weekdaysShort : "vas_hét_kedd_sze_csüt_pén_szo".split("_"),
- weekdaysMin : "v_h_k_sze_cs_p_szo".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "YYYY.MM.DD.",
- LL : "YYYY. MMMM D.",
- LLL : "YYYY. MMMM D., LT",
- LLLL : "YYYY. MMMM D., dddd LT"
- },
- meridiem : function (hours, minutes, isLower) {
- if (hours < 12) {
- return isLower === true ? 'de' : 'DE';
- } else {
- return isLower === true ? 'du' : 'DU';
- }
- },
- calendar : {
- sameDay : '[ma] LT[-kor]',
- nextDay : '[holnap] LT[-kor]',
- nextWeek : function () {
- return week.call(this, true);
- },
- lastDay : '[tegnap] LT[-kor]',
- lastWeek : function () {
- return week.call(this, false);
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s múlva",
- past : "%s",
- s : translate,
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : translate,
- dd : translate,
- M : translate,
- MM : translate,
- y : translate,
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * This function forms a cluster from a specific preselected hub node
+ *
+ * @param {Node} hubNode | the node we will cluster as a hub
+ * @param {Boolean} force | Disregard zoom level
+ * @param {Boolean} onlyEqual | This only clusters a hub with a specific number of edges
+ * @param {Number} [absorptionSizeOffset] |
+ * @private
+ */
+ exports._formClusterFromHub = function(hubNode, force, onlyEqual, absorptionSizeOffset) {
+ if (absorptionSizeOffset === undefined) {
+ absorptionSizeOffset = 0;
+ }
+ // we decide if the node is a hub
+ if ((hubNode.dynamicEdgesLength >= this.hubThreshold && onlyEqual == false) ||
+ (hubNode.dynamicEdgesLength == this.hubThreshold && onlyEqual == true)) {
+ // initialize variables
+ var dx,dy,length;
+ var minLength = this.constants.clustering.clusterEdgeThreshold/this.scale;
+ var allowCluster = false;
+ // we create a list of edges because the dynamicEdges change over the course of this loop
+ var edgesIdarray = [];
+ var amountOfInitialEdges = hubNode.dynamicEdges.length;
+ for (var j = 0; j < amountOfInitialEdges; j++) {
+ edgesIdarray.push(hubNode.dynamicEdges[j].id);
+ }
-/***/ },
-/* 87 */
-/***/ function(module, exports, __webpack_require__) {
+ // if the hub clustering is not forces, we check if one of the edges connected
+ // to a cluster is small enough based on the constants.clustering.clusterEdgeThreshold
+ if (force == false) {
+ allowCluster = false;
+ for (j = 0; j < amountOfInitialEdges; j++) {
+ var edge = this.edges[edgesIdarray[j]];
+ if (edge !== undefined) {
+ if (edge.connected) {
+ if (edge.toId != edge.fromId) {
+ dx = (edge.to.x - edge.from.x);
+ dy = (edge.to.y - edge.from.y);
+ length = Math.sqrt(dx * dx + dy * dy);
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Armenian (hy-am)
- // author : Armendarabyan : https://github.com/armendarabyan
+ if (length < minLength) {
+ allowCluster = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // start the clustering if allowed
+ if ((!force && allowCluster) || force) {
+ // we loop over all edges INITIALLY connected to this hub
+ for (j = 0; j < amountOfInitialEdges; j++) {
+ edge = this.edges[edgesIdarray[j]];
+ // the edge can be clustered by this function in a previous loop
+ if (edge !== undefined) {
+ var childNode = this.nodes[(edge.fromId == hubNode.id) ? edge.toId : edge.fromId];
+ // we do not want hubs to merge with other hubs nor do we want to cluster itself.
+ if ((childNode.dynamicEdges.length <= (this.hubThreshold + absorptionSizeOffset)) &&
+ (childNode.id != hubNode.id)) {
+ this._addToCluster(hubNode,childNode,force);
+ }
+ }
+ }
}
- }(function (moment) {
+ }
+ };
- function monthsCaseReplace(m, format) {
- var months = {
- 'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),
- 'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')
- },
- nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
- 'accusative' :
- 'nominative';
- return months[nounCase][m.month()];
+ /**
+ * This function adds the child node to the parent node, creating a cluster if it is not already.
+ *
+ * @param {Node} parentNode | this is the node that will house the child node
+ * @param {Node} childNode | this node will be deleted from the global this.nodes and stored in the parent node
+ * @param {Boolean} force | true will only update the remainingEdges at the very end of the clustering, ensuring single level collapse
+ * @private
+ */
+ exports._addToCluster = function(parentNode, childNode, force) {
+ // join child node in the parent node
+ parentNode.containedNodes[childNode.id] = childNode;
+
+ // manage all the edges connected to the child and parent nodes
+ for (var i = 0; i < childNode.dynamicEdges.length; i++) {
+ var edge = childNode.dynamicEdges[i];
+ if (edge.toId == parentNode.id || edge.fromId == parentNode.id) { // edge connected to parentNode
+ this._addToContainedEdges(parentNode,childNode,edge);
+ }
+ else {
+ this._connectEdgeToCluster(parentNode,childNode,edge);
}
+ }
+ // a contained node has no dynamic edges.
+ childNode.dynamicEdges = [];
- function monthsShortCaseReplace(m, format) {
- var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');
+ // remove circular edges from clusters
+ this._containCircularEdgesFromNode(parentNode,childNode);
- return monthsShort[m.month()];
- }
- function weekdaysCaseReplace(m, format) {
- var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');
+ // remove the childNode from the global nodes object
+ delete this.nodes[childNode.id];
- return weekdays[m.day()];
- }
+ // update the properties of the child and parent
+ var massBefore = parentNode.mass;
+ childNode.clusterSession = this.clusterSession;
+ parentNode.mass += childNode.mass;
+ parentNode.clusterSize += childNode.clusterSize;
+ parentNode.fontSize = Math.min(this.constants.clustering.maxFontSize, this.constants.nodes.fontSize + this.constants.clustering.fontSizeMultiplier*parentNode.clusterSize);
- return moment.lang('hy-am', {
- months : monthsCaseReplace,
- monthsShort : monthsShortCaseReplace,
- weekdays : weekdaysCaseReplace,
- weekdaysShort : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),
- weekdaysMin : "կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY թ.",
- LLL : "D MMMM YYYY թ., LT",
- LLLL : "dddd, D MMMM YYYY թ., LT"
- },
- calendar : {
- sameDay: '[այսօր] LT',
- nextDay: '[վաղը] LT',
- lastDay: '[երեկ] LT',
- nextWeek: function () {
- return 'dddd [օրը ժամը] LT';
- },
- lastWeek: function () {
- return '[անցած] dddd [օրը ժամը] LT';
- },
- sameElse: 'L'
- },
- relativeTime : {
- future : "%s հետո",
- past : "%s առաջ",
- s : "մի քանի վայրկյան",
- m : "րոպե",
- mm : "%d րոպե",
- h : "ժամ",
- hh : "%d ժամ",
- d : "օր",
- dd : "%d օր",
- M : "ամիս",
- MM : "%d ամիս",
- y : "տարի",
- yy : "%d տարի"
- },
+ // keep track of the clustersessions so we can open the cluster up as it has been formed.
+ if (parentNode.clusterSessions[parentNode.clusterSessions.length - 1] != this.clusterSession) {
+ parentNode.clusterSessions.push(this.clusterSession);
+ }
- meridiem : function (hour) {
- if (hour < 4) {
- return "գիշերվա";
- } else if (hour < 12) {
- return "առավոտվա";
- } else if (hour < 17) {
- return "ցերեկվա";
- } else {
- return "երեկոյան";
- }
- },
+ // forced clusters only open from screen size and double tap
+ if (force == true) {
+ // parentNode.formationScale = Math.pow(1 - (1.0/11.0),this.clusterSession+3);
+ parentNode.formationScale = 0;
+ }
+ else {
+ parentNode.formationScale = this.scale; // The latest child has been added on this scale
+ }
- ordinal: function (number, period) {
- switch (period) {
- case 'DDD':
- case 'w':
- case 'W':
- case 'DDDo':
- if (number === 1) {
- return number + '-ին';
- }
- return number + '-րդ';
- default:
- return number;
- }
- },
+ // recalculate the size of the node on the next time the node is rendered
+ parentNode.clearSizeCache();
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ // set the pop-out scale for the childnode
+ parentNode.containedNodes[childNode.id].formationScale = parentNode.formationScale;
+ // nullify the movement velocity of the child, this is to avoid hectic behaviour
+ childNode.clearVelocity();
-/***/ },
-/* 88 */
-/***/ function(module, exports, __webpack_require__) {
+ // the mass has altered, preservation of energy dictates the velocity to be updated
+ parentNode.updateVelocity(massBefore);
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Bahasa Indonesia (id)
- // author : Mohammad Satrio Utomo : https://github.com/tyok
- // reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
+ // restart the simulation to reorganise all nodes
+ this.moving = true;
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('id', {
- months : "Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),
- monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),
- weekdays : "Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),
- weekdaysShort : "Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),
- weekdaysMin : "Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),
- longDateFormat : {
- LT : "HH.mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY [pukul] LT",
- LLLL : "dddd, D MMMM YYYY [pukul] LT"
- },
- meridiem : function (hours, minutes, isLower) {
- if (hours < 11) {
- return 'pagi';
- } else if (hours < 15) {
- return 'siang';
- } else if (hours < 19) {
- return 'sore';
- } else {
- return 'malam';
- }
- },
- calendar : {
- sameDay : '[Hari ini pukul] LT',
- nextDay : '[Besok pukul] LT',
- nextWeek : 'dddd [pukul] LT',
- lastDay : '[Kemarin pukul] LT',
- lastWeek : 'dddd [lalu pukul] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "dalam %s",
- past : "%s yang lalu",
- s : "beberapa detik",
- m : "semenit",
- mm : "%d menit",
- h : "sejam",
- hh : "%d jam",
- d : "sehari",
- dd : "%d hari",
- M : "sebulan",
- MM : "%d bulan",
- y : "setahun",
- yy : "%d tahun"
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
+
+ /**
+ * This function will apply the changes made to the remainingEdges during the formation of the clusters.
+ * This is a seperate function to allow for level-wise collapsing of the node barnesHutTree.
+ * It has to be called if a level is collapsed. It is called by _formClusters().
+ * @private
+ */
+ exports._updateDynamicEdges = function() {
+ for (var i = 0; i < this.nodeIndices.length; i++) {
+ var node = this.nodes[this.nodeIndices[i]];
+ node.dynamicEdgesLength = node.dynamicEdges.length;
+
+ // this corrects for multiple edges pointing at the same other node
+ var correction = 0;
+ if (node.dynamicEdgesLength > 1) {
+ for (var j = 0; j < node.dynamicEdgesLength - 1; j++) {
+ var edgeToId = node.dynamicEdges[j].toId;
+ var edgeFromId = node.dynamicEdges[j].fromId;
+ for (var k = j+1; k < node.dynamicEdgesLength; k++) {
+ if ((node.dynamicEdges[k].toId == edgeToId && node.dynamicEdges[k].fromId == edgeFromId) ||
+ (node.dynamicEdges[k].fromId == edgeToId && node.dynamicEdges[k].toId == edgeFromId)) {
+ correction += 1;
+ }
}
- });
- }));
+ }
+ }
+ node.dynamicEdgesLength -= correction;
+ }
+ };
-/***/ },
-/* 89 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This adds an edge from the childNode to the contained edges of the parent node
+ *
+ * @param parentNode | Node object
+ * @param childNode | Node object
+ * @param edge | Edge object
+ * @private
+ */
+ exports._addToContainedEdges = function(parentNode, childNode, edge) {
+ // create an array object if it does not yet exist for this childNode
+ if (!(parentNode.containedEdges.hasOwnProperty(childNode.id))) {
+ parentNode.containedEdges[childNode.id] = []
+ }
+ // add this edge to the list
+ parentNode.containedEdges[childNode.id].push(edge);
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : icelandic (is)
- // author : Hinrik Örn Sigurðsson : https://github.com/hinrik
+ // remove the edge from the global edges object
+ delete this.edges[edge.id];
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // remove the edge from the parent object
+ for (var i = 0; i < parentNode.dynamicEdges.length; i++) {
+ if (parentNode.dynamicEdges[i].id == edge.id) {
+ parentNode.dynamicEdges.splice(i,1);
+ break;
}
- }(function (moment) {
- function plural(n) {
- if (n % 100 === 11) {
- return true;
- } else if (n % 10 === 1) {
- return false;
- }
- return true;
+ }
+ };
+
+ /**
+ * This function connects an edge that was connected to a child node to the parent node.
+ * It keeps track of which nodes it has been connected to with the originalId array.
+ *
+ * @param {Node} parentNode | Node object
+ * @param {Node} childNode | Node object
+ * @param {Edge} edge | Edge object
+ * @private
+ */
+ exports._connectEdgeToCluster = function(parentNode, childNode, edge) {
+ // handle circular edges
+ if (edge.toId == edge.fromId) {
+ this._addToContainedEdges(parentNode, childNode, edge);
+ }
+ else {
+ if (edge.toId == childNode.id) { // edge connected to other node on the "to" side
+ edge.originalToId.push(childNode.id);
+ edge.to = parentNode;
+ edge.toId = parentNode.id;
}
+ else { // edge connected to other node with the "from" side
- function translate(number, withoutSuffix, key, isFuture) {
- var result = number + " ";
- switch (key) {
- case 's':
- return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';
- case 'm':
- return withoutSuffix ? 'mínúta' : 'mínútu';
- case 'mm':
- if (plural(number)) {
- return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');
- } else if (withoutSuffix) {
- return result + 'mínúta';
- }
- return result + 'mínútu';
- case 'hh':
- if (plural(number)) {
- return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');
- }
- return result + 'klukkustund';
- case 'd':
- if (withoutSuffix) {
- return 'dagur';
- }
- return isFuture ? 'dag' : 'degi';
- case 'dd':
- if (plural(number)) {
- if (withoutSuffix) {
- return result + 'dagar';
- }
- return result + (isFuture ? 'daga' : 'dögum');
- } else if (withoutSuffix) {
- return result + 'dagur';
- }
- return result + (isFuture ? 'dag' : 'degi');
- case 'M':
- if (withoutSuffix) {
- return 'mánuður';
- }
- return isFuture ? 'mánuð' : 'mánuði';
- case 'MM':
- if (plural(number)) {
- if (withoutSuffix) {
- return result + 'mánuðir';
- }
- return result + (isFuture ? 'mánuði' : 'mánuðum');
- } else if (withoutSuffix) {
- return result + 'mánuður';
- }
- return result + (isFuture ? 'mánuð' : 'mánuði');
- case 'y':
- return withoutSuffix || isFuture ? 'ár' : 'ári';
- case 'yy':
- if (plural(number)) {
- return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
- }
- return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
- }
+ edge.originalFromId.push(childNode.id);
+ edge.from = parentNode;
+ edge.fromId = parentNode.id;
}
- return moment.lang('is', {
- months : "janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),
- monthsShort : "jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),
- weekdays : "sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),
- weekdaysShort : "sun_mán_þri_mið_fim_fös_lau".split("_"),
- weekdaysMin : "Su_Má_Þr_Mi_Fi_Fö_La".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD/MM/YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY [kl.] LT",
- LLLL : "dddd, D. MMMM YYYY [kl.] LT"
- },
- calendar : {
- sameDay : '[í dag kl.] LT',
- nextDay : '[á morgun kl.] LT',
- nextWeek : 'dddd [kl.] LT',
- lastDay : '[í gær kl.] LT',
- lastWeek : '[síðasta] dddd [kl.] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "eftir %s",
- past : "fyrir %s síðan",
- s : translate,
- m : translate,
- mm : translate,
- h : "klukkustund",
- hh : translate,
- d : translate,
- dd : translate,
- M : translate,
- MM : translate,
- y : translate,
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ this._addToReroutedEdges(parentNode,childNode,edge);
+ }
+ };
+
+
+ /**
+ * If a node is connected to itself, a circular edge is drawn. When clustering we want to contain
+ * these edges inside of the cluster.
+ *
+ * @param parentNode
+ * @param childNode
+ * @private
+ */
+ exports._containCircularEdgesFromNode = function(parentNode, childNode) {
+ // manage all the edges connected to the child and parent nodes
+ for (var i = 0; i < parentNode.dynamicEdges.length; i++) {
+ var edge = parentNode.dynamicEdges[i];
+ // handle circular edges
+ if (edge.toId == edge.fromId) {
+ this._addToContainedEdges(parentNode, childNode, edge);
+ }
+ }
+ };
+
+
+ /**
+ * This adds an edge from the childNode to the rerouted edges of the parent node
+ *
+ * @param parentNode | Node object
+ * @param childNode | Node object
+ * @param edge | Edge object
+ * @private
+ */
+ exports._addToReroutedEdges = function(parentNode, childNode, edge) {
+ // create an array object if it does not yet exist for this childNode
+ // we store the edge in the rerouted edges so we can restore it when the cluster pops open
+ if (!(parentNode.reroutedEdges.hasOwnProperty(childNode.id))) {
+ parentNode.reroutedEdges[childNode.id] = [];
+ }
+ parentNode.reroutedEdges[childNode.id].push(edge);
+
+ // this edge becomes part of the dynamicEdges of the cluster node
+ parentNode.dynamicEdges.push(edge);
+ };
+
+
+
+ /**
+ * This function connects an edge that was connected to a cluster node back to the child node.
+ *
+ * @param parentNode | Node object
+ * @param childNode | Node object
+ * @private
+ */
+ exports._connectEdgeBackToChild = function(parentNode, childNode) {
+ if (parentNode.reroutedEdges.hasOwnProperty(childNode.id)) {
+ for (var i = 0; i < parentNode.reroutedEdges[childNode.id].length; i++) {
+ var edge = parentNode.reroutedEdges[childNode.id][i];
+ if (edge.originalFromId[edge.originalFromId.length-1] == childNode.id) {
+ edge.originalFromId.pop();
+ edge.fromId = childNode.id;
+ edge.from = childNode;
+ }
+ else {
+ edge.originalToId.pop();
+ edge.toId = childNode.id;
+ edge.to = childNode;
+ }
+ // append this edge to the list of edges connecting to the childnode
+ childNode.dynamicEdges.push(edge);
-/***/ },
-/* 90 */
-/***/ function(module, exports, __webpack_require__) {
+ // remove the edge from the parent object
+ for (var j = 0; j < parentNode.dynamicEdges.length; j++) {
+ if (parentNode.dynamicEdges[j].id == edge.id) {
+ parentNode.dynamicEdges.splice(j,1);
+ break;
+ }
+ }
+ }
+ // remove the entry from the rerouted edges
+ delete parentNode.reroutedEdges[childNode.id];
+ }
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : italian (it)
- // author : Lorenzo : https://github.com/aliem
- // author: Mattia Larentis: https://github.com/nostalgiaz
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * When loops are clustered, an edge can be both in the rerouted array and the contained array.
+ * This function is called last to verify that all edges in dynamicEdges are in fact connected to the
+ * parentNode
+ *
+ * @param parentNode | Node object
+ * @private
+ */
+ exports._validateEdges = function(parentNode) {
+ for (var i = 0; i < parentNode.dynamicEdges.length; i++) {
+ var edge = parentNode.dynamicEdges[i];
+ if (parentNode.id != edge.toId && parentNode.id != edge.fromId) {
+ parentNode.dynamicEdges.splice(i,1);
}
- }(function (moment) {
- return moment.lang('it', {
- months : "gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),
- monthsShort : "gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),
- weekdays : "Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),
- weekdaysShort : "Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),
- weekdaysMin : "D_L_Ma_Me_G_V_S".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay: '[Oggi alle] LT',
- nextDay: '[Domani alle] LT',
- nextWeek: 'dddd [alle] LT',
- lastDay: '[Ieri alle] LT',
- lastWeek: '[lo scorso] dddd [alle] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : function (s) {
- return ((/^[0-9].+$/).test(s) ? "tra" : "in") + " " + s;
- },
- past : "%s fa",
- s : "alcuni secondi",
- m : "un minuto",
- mm : "%d minuti",
- h : "un'ora",
- hh : "%d ore",
- d : "un giorno",
- dd : "%d giorni",
- M : "un mese",
- MM : "%d mesi",
- y : "un anno",
- yy : "%d anni"
- },
- ordinal: '%dº',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ }
+ };
-/***/ },
-/* 91 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This function released the contained edges back into the global domain and puts them back into the
+ * dynamic edges of both parent and child.
+ *
+ * @param {Node} parentNode |
+ * @param {Node} childNode |
+ * @private
+ */
+ exports._releaseContainedEdges = function(parentNode, childNode) {
+ for (var i = 0; i < parentNode.containedEdges[childNode.id].length; i++) {
+ var edge = parentNode.containedEdges[childNode.id][i];
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : japanese (ja)
- // author : LI Long : https://github.com/baryon
+ // put the edge back in the global edges object
+ this.edges[edge.id] = edge;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('ja', {
- months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
- monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
- weekdays : "日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),
- weekdaysShort : "日_月_火_水_木_金_土".split("_"),
- weekdaysMin : "日_月_火_水_木_金_土".split("_"),
- longDateFormat : {
- LT : "Ah時m分",
- L : "YYYY/MM/DD",
- LL : "YYYY年M月D日",
- LLL : "YYYY年M月D日LT",
- LLLL : "YYYY年M月D日LT dddd"
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 12) {
- return "午前";
- } else {
- return "午後";
- }
- },
- calendar : {
- sameDay : '[今日] LT',
- nextDay : '[明日] LT',
- nextWeek : '[来週]dddd LT',
- lastDay : '[昨日] LT',
- lastWeek : '[前週]dddd LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s後",
- past : "%s前",
- s : "数秒",
- m : "1分",
- mm : "%d分",
- h : "1時間",
- hh : "%d時間",
- d : "1日",
- dd : "%d日",
- M : "1ヶ月",
- MM : "%dヶ月",
- y : "1年",
- yy : "%d年"
- }
- });
- }));
+ // put the edge back in the dynamic edges of the child and parent
+ childNode.dynamicEdges.push(edge);
+ parentNode.dynamicEdges.push(edge);
+ }
+ // remove the entry from the contained edges
+ delete parentNode.containedEdges[childNode.id];
+ };
-/***/ },
-/* 92 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Georgian (ka)
- // author : Irakli Janiashvili : https://github.com/irakli-janiashvili
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- function monthsCaseReplace(m, format) {
- var months = {
- 'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
- 'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')
- },
+ // ------------------- UTILITY FUNCTIONS ---------------------------- //
- nounCase = (/D[oD] *MMMM?/).test(format) ?
- 'accusative' :
- 'nominative';
- return months[nounCase][m.month()];
+ /**
+ * This updates the node labels for all nodes (for debugging purposes)
+ */
+ exports.updateLabels = function() {
+ var nodeId;
+ // update node labels
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ var node = this.nodes[nodeId];
+ if (node.clusterSize > 1) {
+ node.label = "[".concat(String(node.clusterSize),"]");
+ }
}
+ }
- function weekdaysCaseReplace(m, format) {
- var weekdays = {
- 'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),
- 'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')
- },
+ // update node labels
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ node = this.nodes[nodeId];
+ if (node.clusterSize == 1) {
+ if (node.originalLabel !== undefined) {
+ node.label = node.originalLabel;
+ }
+ else {
+ node.label = String(node.id);
+ }
+ }
+ }
+ }
- nounCase = (/(წინა|შემდეგ)/).test(format) ?
- 'accusative' :
- 'nominative';
+ // /* Debug Override */
+ // for (nodeId in this.nodes) {
+ // if (this.nodes.hasOwnProperty(nodeId)) {
+ // node = this.nodes[nodeId];
+ // node.label = String(node.level);
+ // }
+ // }
- return weekdays[nounCase][m.day()];
- }
+ };
- return moment.lang('ka', {
- months : monthsCaseReplace,
- monthsShort : "იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),
- weekdays : weekdaysCaseReplace,
- weekdaysShort : "კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"),
- weekdaysMin : "კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"),
- longDateFormat : {
- LT : "h:mm A",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[დღეს] LT[-ზე]',
- nextDay : '[ხვალ] LT[-ზე]',
- lastDay : '[გუშინ] LT[-ზე]',
- nextWeek : '[შემდეგ] dddd LT[-ზე]',
- lastWeek : '[წინა] dddd LT-ზე',
- sameElse : 'L'
- },
- relativeTime : {
- future : function (s) {
- return (/(წამი|წუთი|საათი|წელი)/).test(s) ?
- s.replace(/ი$/, "ში") :
- s + "ში";
- },
- past : function (s) {
- if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {
- return s.replace(/(ი|ე)$/, "ის წინ");
- }
- if ((/წელი/).test(s)) {
- return s.replace(/წელი$/, "წლის წინ");
- }
- },
- s : "რამდენიმე წამი",
- m : "წუთი",
- mm : "%d წუთი",
- h : "საათი",
- hh : "%d საათი",
- d : "დღე",
- dd : "%d დღე",
- M : "თვე",
- MM : "%d თვე",
- y : "წელი",
- yy : "%d წელი"
- },
- ordinal : function (number) {
- if (number === 0) {
- return number;
- }
- if (number === 1) {
- return number + "-ლი";
- }
+ /**
+ * We want to keep the cluster level distribution rather small. This means we do not want unclustered nodes
+ * if the rest of the nodes are already a few cluster levels in.
+ * To fix this we use this function. It determines the min and max cluster level and sends nodes that have not
+ * clustered enough to the clusterToSmallestNeighbours function.
+ */
+ exports.normalizeClusterLevels = function() {
+ var maxLevel = 0;
+ var minLevel = 1e9;
+ var clusterLevel = 0;
+ var nodeId;
- if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {
- return "მე-" + number;
- }
+ // we loop over all nodes in the list
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ clusterLevel = this.nodes[nodeId].clusterSessions.length;
+ if (maxLevel < clusterLevel) {maxLevel = clusterLevel;}
+ if (minLevel > clusterLevel) {minLevel = clusterLevel;}
+ }
+ }
- return number + "-ე";
- },
- week : {
- dow : 1,
- doy : 7
+ if (maxLevel - minLevel > this.constants.clustering.clusterLevelDifference) {
+ var amountOfNodes = this.nodeIndices.length;
+ var targetLevel = maxLevel - this.constants.clustering.clusterLevelDifference;
+ // we loop over all nodes in the list
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ if (this.nodes[nodeId].clusterSessions.length < targetLevel) {
+ this._clusterToSmallestNeighbour(this.nodes[nodeId]);
}
- });
- }));
+ }
+ }
+ this._updateNodeIndexList();
+ this._updateDynamicEdges();
+ // if a cluster was formed, we increase the clusterSession
+ if (this.nodeIndices.length != amountOfNodes) {
+ this.clusterSession += 1;
+ }
+ }
+ };
-/***/ },
-/* 93 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : khmer (km)
- // author : Kruy Vanna : https://github.com/kruyvanna
+ /**
+ * This function determines if the cluster we want to decluster is in the active area
+ * this means around the zoom center
+ *
+ * @param {Node} node
+ * @returns {boolean}
+ * @private
+ */
+ exports._nodeInActiveArea = function(node) {
+ return (
+ Math.abs(node.x - this.areaCenter.x) <= this.constants.clustering.activeAreaBoxSize/this.scale
+ &&
+ Math.abs(node.y - this.areaCenter.y) <= this.constants.clustering.activeAreaBoxSize/this.scale
+ )
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('km', {
- months: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),
- monthsShort: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),
- weekdays: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),
- weekdaysShort: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),
- weekdaysMin: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),
- longDateFormat: {
- LT: "HH:mm",
- L: "DD/MM/YYYY",
- LL: "D MMMM YYYY",
- LLL: "D MMMM YYYY LT",
- LLLL: "dddd, D MMMM YYYY LT"
- },
- calendar: {
- sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',
- nextDay: '[ស្អែក ម៉ោង] LT',
- nextWeek: 'dddd [ម៉ោង] LT',
- lastDay: '[ម្សិលមិញ ម៉ោង] LT',
- lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',
- sameElse: 'L'
- },
- relativeTime: {
- future: "%sទៀត",
- past: "%sមុន",
- s: "ប៉ុន្មានវិនាទី",
- m: "មួយនាទី",
- mm: "%d នាទី",
- h: "មួយម៉ោង",
- hh: "%d ម៉ោង",
- d: "មួយថ្ងៃ",
- dd: "%d ថ្ងៃ",
- M: "មួយខែ",
- MM: "%d ខែ",
- y: "មួយឆ្នាំ",
- yy: "%d ឆ្នាំ"
- },
- week: {
- dow: 1, // Monday is the first day of the week.
- doy: 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ /**
+ * This is an adaptation of the original repositioning function. This is called if the system is clustered initially
+ * It puts large clusters away from the center and randomizes the order.
+ *
+ */
+ exports.repositionNodes = function() {
+ for (var i = 0; i < this.nodeIndices.length; i++) {
+ var node = this.nodes[this.nodeIndices[i]];
+ if ((node.xFixed == false || node.yFixed == false)) {
+ var radius = 10 * 0.1*this.nodeIndices.length * Math.min(100,node.mass);
+ var angle = 2 * Math.PI * Math.random();
+ if (node.xFixed == false) {node.x = radius * Math.cos(angle);}
+ if (node.yFixed == false) {node.y = radius * Math.sin(angle);}
+ this._repositionBezierNodes(node);
+ }
+ }
+ };
-/***/ },
-/* 94 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : korean (ko)
- //
- // authors
- //
- // - Kyungwook, Park : https://github.com/kyungw00k
- // - Jeeeyul Lee
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('ko', {
- months : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),
- monthsShort : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),
- weekdays : "일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),
- weekdaysShort : "일_월_화_수_목_금_토".split("_"),
- weekdaysMin : "일_월_화_수_목_금_토".split("_"),
- longDateFormat : {
- LT : "A h시 mm분",
- L : "YYYY.MM.DD",
- LL : "YYYY년 MMMM D일",
- LLL : "YYYY년 MMMM D일 LT",
- LLLL : "YYYY년 MMMM D일 dddd LT"
- },
- meridiem : function (hour, minute, isUpper) {
- return hour < 12 ? '오전' : '오후';
- },
- calendar : {
- sameDay : '오늘 LT',
- nextDay : '내일 LT',
- nextWeek : 'dddd LT',
- lastDay : '어제 LT',
- lastWeek : '지난주 dddd LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s 후",
- past : "%s 전",
- s : "몇초",
- ss : "%d초",
- m : "일분",
- mm : "%d분",
- h : "한시간",
- hh : "%d시간",
- d : "하루",
- dd : "%d일",
- M : "한달",
- MM : "%d달",
- y : "일년",
- yy : "%d년"
- },
- ordinal : '%d일',
- meridiemParse : /(오전|오후)/,
- isPM : function (token) {
- return token === "오후";
- }
- });
- }));
+ /**
+ * We determine how many connections denote an important hub.
+ * We take the mean + 2*std as the important hub size. (Assuming a normal distribution of data, ~2.2%)
+ *
+ * @private
+ */
+ exports._getHubSize = function() {
+ var average = 0;
+ var averageSquared = 0;
+ var hubCounter = 0;
+ var largestHub = 0;
+ for (var i = 0; i < this.nodeIndices.length; i++) {
-/***/ },
-/* 95 */
-/***/ function(module, exports, __webpack_require__) {
+ var node = this.nodes[this.nodeIndices[i]];
+ if (node.dynamicEdgesLength > largestHub) {
+ largestHub = node.dynamicEdgesLength;
+ }
+ average += node.dynamicEdgesLength;
+ averageSquared += Math.pow(node.dynamicEdgesLength,2);
+ hubCounter += 1;
+ }
+ average = average / hubCounter;
+ averageSquared = averageSquared / hubCounter;
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Luxembourgish (lb)
- // author : mweimerskirch : https://github.com/mweimerskirch
+ var variance = averageSquared - Math.pow(average,2);
- // Note: Luxembourgish has a very particular phonological rule ("Eifeler Regel") that causes the
- // deletion of the final "n" in certain contexts. That's what the "eifelerRegelAppliesToWeekday"
- // and "eifelerRegelAppliesToNumber" methods are meant for
+ var standardDeviation = Math.sqrt(variance);
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- function processRelativeTime(number, withoutSuffix, key, isFuture) {
- var format = {
- 'm': ['eng Minutt', 'enger Minutt'],
- 'h': ['eng Stonn', 'enger Stonn'],
- 'd': ['een Dag', 'engem Dag'],
- 'dd': [number + ' Deeg', number + ' Deeg'],
- 'M': ['ee Mount', 'engem Mount'],
- 'MM': [number + ' Méint', number + ' Méint'],
- 'y': ['ee Joer', 'engem Joer'],
- 'yy': [number + ' Joer', number + ' Joer']
- };
- return withoutSuffix ? format[key][0] : format[key][1];
- }
+ this.hubThreshold = Math.floor(average + 2*standardDeviation);
- function processFutureTime(string) {
- var number = string.substr(0, string.indexOf(' '));
- if (eifelerRegelAppliesToNumber(number)) {
- return "a " + string;
- }
- return "an " + string;
- }
+ // always have at least one to cluster
+ if (this.hubThreshold > largestHub) {
+ this.hubThreshold = largestHub;
+ }
- function processPastTime(string) {
- var number = string.substr(0, string.indexOf(' '));
- if (eifelerRegelAppliesToNumber(number)) {
- return "viru " + string;
- }
- return "virun " + string;
- }
+ // console.log("average",average,"averageSQ",averageSquared,"var",variance,"std",standardDeviation);
+ // console.log("hubThreshold:",this.hubThreshold);
+ };
- function processLastWeek(string1) {
- var weekday = this.format('d');
- if (eifelerRegelAppliesToWeekday(weekday)) {
- return '[Leschte] dddd [um] LT';
- }
- return '[Leschten] dddd [um] LT';
- }
- /**
- * Returns true if the word before the given week day loses the "-n" ending.
- * e.g. "Leschten Dënschdeg" but "Leschte Méindeg"
- *
- * @param weekday {integer}
- * @returns {boolean}
- */
- function eifelerRegelAppliesToWeekday(weekday) {
- weekday = parseInt(weekday, 10);
- switch (weekday) {
- case 0: // Sonndeg
- case 1: // Méindeg
- case 3: // Mëttwoch
- case 5: // Freideg
- case 6: // Samschdeg
- return true;
- default: // 2 Dënschdeg, 4 Donneschdeg
- return false;
+ /**
+ * We reduce the amount of "extension nodes" or chains. These are not quickly clustered with the outliers and hubs methods
+ * with this amount we can cluster specifically on these chains.
+ *
+ * @param {Number} fraction | between 0 and 1, the percentage of chains to reduce
+ * @private
+ */
+ exports._reduceAmountOfChains = function(fraction) {
+ this.hubThreshold = 2;
+ var reduceAmount = Math.floor(this.nodeIndices.length * fraction);
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ if (this.nodes[nodeId].dynamicEdgesLength == 2 && this.nodes[nodeId].dynamicEdges.length >= 2) {
+ if (reduceAmount > 0) {
+ this._formClusterFromHub(this.nodes[nodeId],true,true,1);
+ reduceAmount -= 1;
}
+ }
}
+ }
+ };
- /**
- * Returns true if the word before the given number loses the "-n" ending.
- * e.g. "an 10 Deeg" but "a 5 Deeg"
- *
- * @param number {integer}
- * @returns {boolean}
- */
- function eifelerRegelAppliesToNumber(number) {
- number = parseInt(number, 10);
- if (isNaN(number)) {
- return false;
- }
- if (number < 0) {
- // Negative Number --> always true
- return true;
- } else if (number < 10) {
- // Only 1 digit
- if (4 <= number && number <= 7) {
- return true;
- }
- return false;
- } else if (number < 100) {
- // 2 digits
- var lastDigit = number % 10, firstDigit = number / 10;
- if (lastDigit === 0) {
- return eifelerRegelAppliesToNumber(firstDigit);
- }
- return eifelerRegelAppliesToNumber(lastDigit);
- } else if (number < 10000) {
- // 3 or 4 digits --> recursively check first digit
- while (number >= 10) {
- number = number / 10;
- }
- return eifelerRegelAppliesToNumber(number);
- } else {
- // Anything larger than 4 digits: recursively check first n-3 digits
- number = number / 1000;
- return eifelerRegelAppliesToNumber(number);
- }
+ /**
+ * We get the amount of "extension nodes" or chains. These are not quickly clustered with the outliers and hubs methods
+ * with this amount we can cluster specifically on these chains.
+ *
+ * @private
+ */
+ exports._getChainFraction = function() {
+ var chains = 0;
+ var total = 0;
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ if (this.nodes[nodeId].dynamicEdgesLength == 2 && this.nodes[nodeId].dynamicEdges.length >= 2) {
+ chains += 1;
+ }
+ total += 1;
}
-
- return moment.lang('lb', {
- months: "Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
- monthsShort: "Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
- weekdays: "Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),
- weekdaysShort: "So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),
- weekdaysMin: "So_Mé_Dë_Më_Do_Fr_Sa".split("_"),
- longDateFormat: {
- LT: "H:mm [Auer]",
- L: "DD.MM.YYYY",
- LL: "D. MMMM YYYY",
- LLL: "D. MMMM YYYY LT",
- LLLL: "dddd, D. MMMM YYYY LT"
- },
- calendar: {
- sameDay: "[Haut um] LT",
- sameElse: "L",
- nextDay: '[Muer um] LT',
- nextWeek: 'dddd [um] LT',
- lastDay: '[Gëschter um] LT',
- lastWeek: processLastWeek
- },
- relativeTime: {
- future: processFutureTime,
- past: processPastTime,
- s: "e puer Sekonnen",
- m: processRelativeTime,
- mm: "%d Minutten",
- h: processRelativeTime,
- hh: "%d Stonnen",
- d: processRelativeTime,
- dd: processRelativeTime,
- M: processRelativeTime,
- MM: processRelativeTime,
- y: processRelativeTime,
- yy: processRelativeTime
- },
- ordinal: '%d.',
- week: {
- dow: 1, // Monday is the first day of the week.
- doy: 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ }
+ return chains/total;
+ };
/***/ },
-/* 96 */
+/* 125 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Lithuanian (lt)
- // author : Mindaugas Mozūras : https://github.com/mmozuras
+ var util = __webpack_require__(1);
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var units = {
- "m" : "minutė_minutės_minutę",
- "mm": "minutės_minučių_minutes",
- "h" : "valanda_valandos_valandą",
- "hh": "valandos_valandų_valandas",
- "d" : "diena_dienos_dieną",
- "dd": "dienos_dienų_dienas",
- "M" : "mėnuo_mėnesio_mėnesį",
- "MM": "mėnesiai_mėnesių_mėnesius",
- "y" : "metai_metų_metus",
- "yy": "metai_metų_metus"
- },
- weekDays = "sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_");
+ /**
+ * Creation of the SectorMixin var.
+ *
+ * This contains all the functions the Network object can use to employ the sector system.
+ * The sector system is always used by Network, though the benefits only apply to the use of clustering.
+ * If clustering is not used, there is no overhead except for a duplicate object with references to nodes and edges.
+ */
- function translateSeconds(number, withoutSuffix, key, isFuture) {
- if (withoutSuffix) {
- return "kelios sekundės";
- } else {
- return isFuture ? "kelių sekundžių" : "kelias sekundes";
- }
- }
+ /**
+ * This function is only called by the setData function of the Network object.
+ * This loads the global references into the active sector. This initializes the sector.
+ *
+ * @private
+ */
+ exports._putDataInSector = function() {
+ this.sectors["active"][this._sector()].nodes = this.nodes;
+ this.sectors["active"][this._sector()].edges = this.edges;
+ this.sectors["active"][this._sector()].nodeIndices = this.nodeIndices;
+ };
- function translateSingular(number, withoutSuffix, key, isFuture) {
- return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
- }
- function special(number) {
- return number % 10 === 0 || (number > 10 && number < 20);
- }
+ /**
+ * /**
+ * This function sets the global references to nodes, edges and nodeIndices back to
+ * those of the supplied (active) sector. If a type is defined, do the specific type
+ *
+ * @param {String} sectorId
+ * @param {String} [sectorType] | "active" or "frozen"
+ * @private
+ */
+ exports._switchToSector = function(sectorId, sectorType) {
+ if (sectorType === undefined || sectorType == "active") {
+ this._switchToActiveSector(sectorId);
+ }
+ else {
+ this._switchToFrozenSector(sectorId);
+ }
+ };
- function forms(key) {
- return units[key].split("_");
- }
- function translate(number, withoutSuffix, key, isFuture) {
- var result = number + " ";
- if (number === 1) {
- return result + translateSingular(number, withoutSuffix, key[0], isFuture);
- } else if (withoutSuffix) {
- return result + (special(number) ? forms(key)[1] : forms(key)[0]);
- } else {
- if (isFuture) {
- return result + forms(key)[1];
- } else {
- return result + (special(number) ? forms(key)[1] : forms(key)[2]);
- }
- }
- }
+ /**
+ * This function sets the global references to nodes, edges and nodeIndices back to
+ * those of the supplied active sector.
+ *
+ * @param sectorId
+ * @private
+ */
+ exports._switchToActiveSector = function(sectorId) {
+ this.nodeIndices = this.sectors["active"][sectorId]["nodeIndices"];
+ this.nodes = this.sectors["active"][sectorId]["nodes"];
+ this.edges = this.sectors["active"][sectorId]["edges"];
+ };
- function relativeWeekDay(moment, format) {
- var nominative = format.indexOf('dddd HH:mm') === -1,
- weekDay = weekDays[moment.day()];
- return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + "į";
- }
+ /**
+ * This function sets the global references to nodes, edges and nodeIndices back to
+ * those of the supplied active sector.
+ *
+ * @private
+ */
+ exports._switchToSupportSector = function() {
+ this.nodeIndices = this.sectors["support"]["nodeIndices"];
+ this.nodes = this.sectors["support"]["nodes"];
+ this.edges = this.sectors["support"]["edges"];
+ };
- return moment.lang("lt", {
- months : "sausio_vasario_kovo_balandžio_gegužės_biržėlio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),
- monthsShort : "sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),
- weekdays : relativeWeekDay,
- weekdaysShort : "Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),
- weekdaysMin : "S_P_A_T_K_Pn_Š".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "YYYY-MM-DD",
- LL : "YYYY [m.] MMMM D [d.]",
- LLL : "YYYY [m.] MMMM D [d.], LT [val.]",
- LLLL : "YYYY [m.] MMMM D [d.], dddd, LT [val.]",
- l : "YYYY-MM-DD",
- ll : "YYYY [m.] MMMM D [d.]",
- lll : "YYYY [m.] MMMM D [d.], LT [val.]",
- llll : "YYYY [m.] MMMM D [d.], ddd, LT [val.]"
- },
- calendar : {
- sameDay : "[Šiandien] LT",
- nextDay : "[Rytoj] LT",
- nextWeek : "dddd LT",
- lastDay : "[Vakar] LT",
- lastWeek : "[Praėjusį] dddd LT",
- sameElse : "L"
- },
- relativeTime : {
- future : "po %s",
- past : "prieš %s",
- s : translateSeconds,
- m : translateSingular,
- mm : translate,
- h : translateSingular,
- hh : translate,
- d : translateSingular,
- dd : translate,
- M : translateSingular,
- MM : translate,
- y : translateSingular,
- yy : translate
- },
- ordinal : function (number) {
- return number + '-oji';
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ /**
+ * This function sets the global references to nodes, edges and nodeIndices back to
+ * those of the supplied frozen sector.
+ *
+ * @param sectorId
+ * @private
+ */
+ exports._switchToFrozenSector = function(sectorId) {
+ this.nodeIndices = this.sectors["frozen"][sectorId]["nodeIndices"];
+ this.nodes = this.sectors["frozen"][sectorId]["nodes"];
+ this.edges = this.sectors["frozen"][sectorId]["edges"];
+ };
-/***/ },
-/* 97 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : latvian (lv)
- // author : Kristaps Karlsons : https://github.com/skakri
+ /**
+ * This function sets the global references to nodes, edges and nodeIndices back to
+ * those of the currently active sector.
+ *
+ * @private
+ */
+ exports._loadLatestSector = function() {
+ this._switchToSector(this._sector());
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var units = {
- 'mm': 'minūti_minūtes_minūte_minūtes',
- 'hh': 'stundu_stundas_stunda_stundas',
- 'dd': 'dienu_dienas_diena_dienas',
- 'MM': 'mēnesi_mēnešus_mēnesis_mēneši',
- 'yy': 'gadu_gadus_gads_gadi'
- };
- function format(word, number, withoutSuffix) {
- var forms = word.split('_');
- if (withoutSuffix) {
- return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];
- } else {
- return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];
- }
- }
+ /**
+ * This function returns the currently active sector Id
+ *
+ * @returns {String}
+ * @private
+ */
+ exports._sector = function() {
+ return this.activeSector[this.activeSector.length-1];
+ };
- function relativeTimeWithPlural(number, withoutSuffix, key) {
- return number + ' ' + format(units[key], number, withoutSuffix);
- }
- return moment.lang('lv', {
- months : "janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),
- monthsShort : "jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),
- weekdays : "svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),
- weekdaysShort : "Sv_P_O_T_C_Pk_S".split("_"),
- weekdaysMin : "Sv_P_O_T_C_Pk_S".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "YYYY. [gada] D. MMMM",
- LLL : "YYYY. [gada] D. MMMM, LT",
- LLLL : "YYYY. [gada] D. MMMM, dddd, LT"
- },
- calendar : {
- sameDay : '[Šodien pulksten] LT',
- nextDay : '[Rīt pulksten] LT',
- nextWeek : 'dddd [pulksten] LT',
- lastDay : '[Vakar pulksten] LT',
- lastWeek : '[Pagājušā] dddd [pulksten] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s vēlāk",
- past : "%s agrāk",
- s : "dažas sekundes",
- m : "minūti",
- mm : relativeTimeWithPlural,
- h : "stundu",
- hh : relativeTimeWithPlural,
- d : "dienu",
- dd : relativeTimeWithPlural,
- M : "mēnesi",
- MM : relativeTimeWithPlural,
- y : "gadu",
- yy : relativeTimeWithPlural
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ /**
+ * This function returns the previously active sector Id
+ *
+ * @returns {String}
+ * @private
+ */
+ exports._previousSector = function() {
+ if (this.activeSector.length > 1) {
+ return this.activeSector[this.activeSector.length-2];
+ }
+ else {
+ throw new TypeError('there are not enough sectors in the this.activeSector array.');
+ }
+ };
-/***/ },
-/* 98 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * We add the active sector at the end of the this.activeSector array
+ * This ensures it is the currently active sector returned by _sector() and it reaches the top
+ * of the activeSector stack. When we reverse our steps we move from the end to the beginning of this stack.
+ *
+ * @param newId
+ * @private
+ */
+ exports._setActiveSector = function(newId) {
+ this.activeSector.push(newId);
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : macedonian (mk)
- // author : Borislav Mickov : https://github.com/B0k0
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('mk', {
- months : "јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),
- monthsShort : "јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),
- weekdays : "недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),
- weekdaysShort : "нед_пон_вто_сре_чет_пет_саб".split("_"),
- weekdaysMin : "нe_пo_вт_ср_че_пе_сa".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "D.MM.YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[Денес во] LT',
- nextDay : '[Утре во] LT',
- nextWeek : 'dddd [во] LT',
- lastDay : '[Вчера во] LT',
- lastWeek : function () {
- switch (this.day()) {
- case 0:
- case 3:
- case 6:
- return '[Во изминатата] dddd [во] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[Во изминатиот] dddd [во] LT';
- }
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "после %s",
- past : "пред %s",
- s : "неколку секунди",
- m : "минута",
- mm : "%d минути",
- h : "час",
- hh : "%d часа",
- d : "ден",
- dd : "%d дена",
- M : "месец",
- MM : "%d месеци",
- y : "година",
- yy : "%d години"
- },
- ordinal : function (number) {
- var lastDigit = number % 10,
- last2Digits = number % 100;
- if (number === 0) {
- return number + '-ев';
- } else if (last2Digits === 0) {
- return number + '-ен';
- } else if (last2Digits > 10 && last2Digits < 20) {
- return number + '-ти';
- } else if (lastDigit === 1) {
- return number + '-ви';
- } else if (lastDigit === 2) {
- return number + '-ри';
- } else if (lastDigit === 7 || lastDigit === 8) {
- return number + '-ми';
- } else {
- return number + '-ти';
- }
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
+ /**
+ * We remove the currently active sector id from the active sector stack. This happens when
+ * we reactivate the previously active sector
+ *
+ * @private
+ */
+ exports._forgetLastSector = function() {
+ this.activeSector.pop();
+ };
+
+
+ /**
+ * This function creates a new active sector with the supplied newId. This newId
+ * is the expanding node id.
+ *
+ * @param {String} newId | Id of the new active sector
+ * @private
+ */
+ exports._createNewSector = function(newId) {
+ // create the new sector
+ this.sectors["active"][newId] = {"nodes":{},
+ "edges":{},
+ "nodeIndices":[],
+ "formationScale": this.scale,
+ "drawingNode": undefined};
+
+ // create the new sector render node. This gives visual feedback that you are in a new sector.
+ this.sectors["active"][newId]['drawingNode'] = new Node(
+ {id:newId,
+ color: {
+ background: "#eaefef",
+ border: "495c5e"
}
- });
- }));
+ },{},{},this.constants);
+ this.sectors["active"][newId]['drawingNode'].clusterSize = 2;
+ };
-/***/ },
-/* 99 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This function removes the currently active sector. This is called when we create a new
+ * active sector.
+ *
+ * @param {String} sectorId | Id of the active sector that will be removed
+ * @private
+ */
+ exports._deleteActiveSector = function(sectorId) {
+ delete this.sectors["active"][sectorId];
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : malayalam (ml)
- // author : Floyd Pink : https://github.com/floydpink
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('ml', {
- months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split("_"),
- monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split("_"),
- weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split("_"),
- weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split("_"),
- weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split("_"),
- longDateFormat : {
- LT : "A h:mm -നു",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY, LT",
- LLLL : "dddd, D MMMM YYYY, LT"
- },
- calendar : {
- sameDay : '[ഇന്ന്] LT',
- nextDay : '[നാളെ] LT',
- nextWeek : 'dddd, LT',
- lastDay : '[ഇന്നലെ] LT',
- lastWeek : '[കഴിഞ്ഞ] dddd, LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s കഴിഞ്ഞ്",
- past : "%s മുൻപ്",
- s : "അൽപ നിമിഷങ്ങൾ",
- m : "ഒരു മിനിറ്റ്",
- mm : "%d മിനിറ്റ്",
- h : "ഒരു മണിക്കൂർ",
- hh : "%d മണിക്കൂർ",
- d : "ഒരു ദിവസം",
- dd : "%d ദിവസം",
- M : "ഒരു മാസം",
- MM : "%d മാസം",
- y : "ഒരു വർഷം",
- yy : "%d വർഷം"
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 4) {
- return "രാത്രി";
- } else if (hour < 12) {
- return "രാവിലെ";
- } else if (hour < 17) {
- return "ഉച്ച കഴിഞ്ഞ്";
- } else if (hour < 20) {
- return "വൈകുന്നേരം";
- } else {
- return "രാത്രി";
- }
- }
- });
- }));
+ /**
+ * This function removes the currently active sector. This is called when we reactivate
+ * the previously active sector.
+ *
+ * @param {String} sectorId | Id of the active sector that will be removed
+ * @private
+ */
+ exports._deleteFrozenSector = function(sectorId) {
+ delete this.sectors["frozen"][sectorId];
+ };
-/***/ },
-/* 100 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * Freezing an active sector means moving it from the "active" object to the "frozen" object.
+ * We copy the references, then delete the active entree.
+ *
+ * @param sectorId
+ * @private
+ */
+ exports._freezeSector = function(sectorId) {
+ // we move the set references from the active to the frozen stack.
+ this.sectors["frozen"][sectorId] = this.sectors["active"][sectorId];
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Marathi (mr)
- // author : Harshad Kale : https://github.com/kalehv
+ // we have moved the sector data into the frozen set, we now remove it from the active set
+ this._deleteActiveSector(sectorId);
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var symbolMap = {
- '1': '१',
- '2': '२',
- '3': '३',
- '4': '४',
- '5': '५',
- '6': '६',
- '7': '७',
- '8': '८',
- '9': '९',
- '0': '०'
- },
- numberMap = {
- '१': '1',
- '२': '2',
- '३': '3',
- '४': '4',
- '५': '5',
- '६': '6',
- '७': '7',
- '८': '8',
- '९': '9',
- '०': '0'
- };
- return moment.lang('mr', {
- months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split("_"),
- monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split("_"),
- weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"),
- weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split("_"),
- weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split("_"),
- longDateFormat : {
- LT : "A h:mm वाजता",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY, LT",
- LLLL : "dddd, D MMMM YYYY, LT"
- },
- calendar : {
- sameDay : '[आज] LT',
- nextDay : '[उद्या] LT',
- nextWeek : 'dddd, LT',
- lastDay : '[काल] LT',
- lastWeek: '[मागील] dddd, LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s नंतर",
- past : "%s पूर्वी",
- s : "सेकंद",
- m: "एक मिनिट",
- mm: "%d मिनिटे",
- h : "एक तास",
- hh : "%d तास",
- d : "एक दिवस",
- dd : "%d दिवस",
- M : "एक महिना",
- MM : "%d महिने",
- y : "एक वर्ष",
- yy : "%d वर्षे"
- },
- preparse: function (string) {
- return string.replace(/[१२३४५६७८९०]/g, function (match) {
- return numberMap[match];
- });
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- });
- },
- meridiem: function (hour, minute, isLower)
- {
- if (hour < 4) {
- return "रात्री";
- } else if (hour < 10) {
- return "सकाळी";
- } else if (hour < 17) {
- return "दुपारी";
- } else if (hour < 20) {
- return "सायंकाळी";
- } else {
- return "रात्री";
- }
- },
- week : {
- dow : 0, // Sunday is the first day of the week.
- doy : 6 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * This is the reverse operation of _freezeSector. Activating means moving the sector from the "frozen"
+ * object to the "active" object.
+ *
+ * @param sectorId
+ * @private
+ */
+ exports._activateSector = function(sectorId) {
+ // we move the set references from the frozen to the active stack.
+ this.sectors["active"][sectorId] = this.sectors["frozen"][sectorId];
+ // we have moved the sector data into the active set, we now remove it from the frozen stack
+ this._deleteFrozenSector(sectorId);
+ };
-/***/ },
-/* 101 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Bahasa Malaysia (ms-MY)
- // author : Weldan Jamili : https://github.com/weldan
+ /**
+ * This function merges the data from the currently active sector with a frozen sector. This is used
+ * in the process of reverting back to the previously active sector.
+ * The data that is placed in the frozen (the previously active) sector is the node that has been removed from it
+ * upon the creation of a new active sector.
+ *
+ * @param sectorId
+ * @private
+ */
+ exports._mergeThisWithFrozen = function(sectorId) {
+ // copy all nodes
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ this.sectors["frozen"][sectorId]["nodes"][nodeId] = this.nodes[nodeId];
+ }
+ }
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // copy all edges (if not fully clustered, else there are no edges)
+ for (var edgeId in this.edges) {
+ if (this.edges.hasOwnProperty(edgeId)) {
+ this.sectors["frozen"][sectorId]["edges"][edgeId] = this.edges[edgeId];
}
- }(function (moment) {
- return moment.lang('ms-my', {
- months : "Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),
- monthsShort : "Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),
- weekdays : "Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),
- weekdaysShort : "Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),
- weekdaysMin : "Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),
- longDateFormat : {
- LT : "HH.mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY [pukul] LT",
- LLLL : "dddd, D MMMM YYYY [pukul] LT"
- },
- meridiem : function (hours, minutes, isLower) {
- if (hours < 11) {
- return 'pagi';
- } else if (hours < 15) {
- return 'tengahari';
- } else if (hours < 19) {
- return 'petang';
- } else {
- return 'malam';
- }
- },
- calendar : {
- sameDay : '[Hari ini pukul] LT',
- nextDay : '[Esok pukul] LT',
- nextWeek : 'dddd [pukul] LT',
- lastDay : '[Kelmarin pukul] LT',
- lastWeek : 'dddd [lepas pukul] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "dalam %s",
- past : "%s yang lepas",
- s : "beberapa saat",
- m : "seminit",
- mm : "%d minit",
- h : "sejam",
- hh : "%d jam",
- d : "sehari",
- dd : "%d hari",
- M : "sebulan",
- MM : "%d bulan",
- y : "setahun",
- yy : "%d tahun"
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ }
+ // merge the nodeIndices
+ for (var i = 0; i < this.nodeIndices.length; i++) {
+ this.sectors["frozen"][sectorId]["nodeIndices"].push(this.nodeIndices[i]);
+ }
+ };
-/***/ },
-/* 102 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : norwegian bokmål (nb)
- // authors : Espen Hovlandsdal : https://github.com/rexxars
- // Sigurd Gartmann : https://github.com/sigurdga
+ /**
+ * This clusters the sector to one cluster. It was a single cluster before this process started so
+ * we revert to that state. The clusterToFit function with a maximum size of 1 node does this.
+ *
+ * @private
+ */
+ exports._collapseThisToSingleCluster = function() {
+ this.clusterToFit(1,false);
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('nb', {
- months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),
- monthsShort : "jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),
- weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),
- weekdaysShort : "sø._ma._ti._on._to._fr._lø.".split("_"),
- weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"),
- longDateFormat : {
- LT : "H.mm",
- L : "DD.MM.YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY [kl.] LT",
- LLLL : "dddd D. MMMM YYYY [kl.] LT"
- },
- calendar : {
- sameDay: '[i dag kl.] LT',
- nextDay: '[i morgen kl.] LT',
- nextWeek: 'dddd [kl.] LT',
- lastDay: '[i går kl.] LT',
- lastWeek: '[forrige] dddd [kl.] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "om %s",
- past : "for %s siden",
- s : "noen sekunder",
- m : "ett minutt",
- mm : "%d minutter",
- h : "en time",
- hh : "%d timer",
- d : "en dag",
- dd : "%d dager",
- M : "en måned",
- MM : "%d måneder",
- y : "ett år",
- yy : "%d år"
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ /**
+ * We create a new active sector from the node that we want to open.
+ *
+ * @param node
+ * @private
+ */
+ exports._addSector = function(node) {
+ // this is the currently active sector
+ var sector = this._sector();
+
+ // // this should allow me to select nodes from a frozen set.
+ // if (this.sectors['active'][sector]["nodes"].hasOwnProperty(node.id)) {
+ // console.log("the node is part of the active sector");
+ // }
+ // else {
+ // console.log("I dont know what the fuck happened!!");
+ // }
-/***/ },
-/* 103 */
-/***/ function(module, exports, __webpack_require__) {
+ // when we switch to a new sector, we remove the node that will be expanded from the current nodes list.
+ delete this.nodes[node.id];
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : nepali/nepalese
- // author : suvash : https://github.com/suvash
+ var unqiueIdentifier = util.randomUUID();
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var symbolMap = {
- '1': '१',
- '2': '२',
- '3': '३',
- '4': '४',
- '5': '५',
- '6': '६',
- '7': '७',
- '8': '८',
- '9': '९',
- '0': '०'
- },
- numberMap = {
- '१': '1',
- '२': '2',
- '३': '3',
- '४': '4',
- '५': '5',
- '६': '6',
- '७': '7',
- '८': '8',
- '९': '9',
- '०': '0'
- };
+ // we fully freeze the currently active sector
+ this._freezeSector(sector);
- return moment.lang('ne', {
- months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split("_"),
- monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split("_"),
- weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split("_"),
- weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split("_"),
- weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split("_"),
- longDateFormat : {
- LT : "Aको h:mm बजे",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY, LT",
- LLLL : "dddd, D MMMM YYYY, LT"
- },
- preparse: function (string) {
- return string.replace(/[१२३४५६७८९०]/g, function (match) {
- return numberMap[match];
- });
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- });
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 3) {
- return "राती";
- } else if (hour < 10) {
- return "बिहान";
- } else if (hour < 15) {
- return "दिउँसो";
- } else if (hour < 18) {
- return "बेलुका";
- } else if (hour < 20) {
- return "साँझ";
- } else {
- return "राती";
- }
- },
- calendar : {
- sameDay : '[आज] LT',
- nextDay : '[भोली] LT',
- nextWeek : '[आउँदो] dddd[,] LT',
- lastDay : '[हिजो] LT',
- lastWeek : '[गएको] dddd[,] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%sमा",
- past : "%s अगाडी",
- s : "केही समय",
- m : "एक मिनेट",
- mm : "%d मिनेट",
- h : "एक घण्टा",
- hh : "%d घण्टा",
- d : "एक दिन",
- dd : "%d दिन",
- M : "एक महिना",
- MM : "%d महिना",
- y : "एक बर्ष",
- yy : "%d बर्ष"
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ // we create a new active sector. This sector has the Id of the node to ensure uniqueness
+ this._createNewSector(unqiueIdentifier);
+ // we add the active sector to the sectors array to be able to revert these steps later on
+ this._setActiveSector(unqiueIdentifier);
-/***/ },
-/* 104 */
-/***/ function(module, exports, __webpack_require__) {
+ // we redirect the global references to the new sector's references. this._sector() now returns unqiueIdentifier
+ this._switchToSector(this._sector());
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : dutch (nl)
- // author : Joris Röling : https://github.com/jjupiter
+ // finally we add the node we removed from our previous active sector to the new active sector
+ this.nodes[node.id] = node;
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var monthsShortWithDots = "jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),
- monthsShortWithoutDots = "jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_");
- return moment.lang('nl', {
- months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),
- monthsShort : function (m, format) {
- if (/-MMM-/.test(format)) {
- return monthsShortWithoutDots[m.month()];
- } else {
- return monthsShortWithDots[m.month()];
- }
- },
- weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),
- weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"),
- weekdaysMin : "Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD-MM-YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: '[vandaag om] LT',
- nextDay: '[morgen om] LT',
- nextWeek: 'dddd [om] LT',
- lastDay: '[gisteren om] LT',
- lastWeek: '[afgelopen] dddd [om] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "over %s",
- past : "%s geleden",
- s : "een paar seconden",
- m : "één minuut",
- mm : "%d minuten",
- h : "één uur",
- hh : "%d uur",
- d : "één dag",
- dd : "%d dagen",
- M : "één maand",
- MM : "%d maanden",
- y : "één jaar",
- yy : "%d jaar"
- },
- ordinal : function (number) {
- return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ /**
+ * We close the sector that is currently open and revert back to the one before.
+ * If the active sector is the "default" sector, nothing happens.
+ *
+ * @private
+ */
+ exports._collapseSector = function() {
+ // the currently active sector
+ var sector = this._sector();
+ // we cannot collapse the default sector
+ if (sector != "default") {
+ if ((this.nodeIndices.length == 1) ||
+ (this.sectors["active"][sector]["drawingNode"].width*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientWidth) ||
+ (this.sectors["active"][sector]["drawingNode"].height*this.scale < this.constants.clustering.screenSizeThreshold * this.frame.canvas.clientHeight)) {
+ var previousSector = this._previousSector();
-/***/ },
-/* 105 */
-/***/ function(module, exports, __webpack_require__) {
+ // we collapse the sector back to a single cluster
+ this._collapseThisToSingleCluster();
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : norwegian nynorsk (nn)
- // author : https://github.com/mechuwind
+ // we move the remaining nodes, edges and nodeIndices to the previous sector.
+ // This previous sector is the one we will reactivate
+ this._mergeThisWithFrozen(previousSector);
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('nn', {
- months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),
- monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),
- weekdays : "sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),
- weekdaysShort : "sun_mån_tys_ons_tor_fre_lau".split("_"),
- weekdaysMin : "su_må_ty_on_to_fr_lø".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: '[I dag klokka] LT',
- nextDay: '[I morgon klokka] LT',
- nextWeek: 'dddd [klokka] LT',
- lastDay: '[I går klokka] LT',
- lastWeek: '[Føregåande] dddd [klokka] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "om %s",
- past : "for %s sidan",
- s : "nokre sekund",
- m : "eit minutt",
- mm : "%d minutt",
- h : "ein time",
- hh : "%d timar",
- d : "ein dag",
- dd : "%d dagar",
- M : "ein månad",
- MM : "%d månader",
- y : "eit år",
- yy : "%d år"
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ // the previously active (frozen) sector now has all the data from the currently active sector.
+ // we can now delete the active sector.
+ this._deleteActiveSector(sector);
+ // we activate the previously active (and currently frozen) sector.
+ this._activateSector(previousSector);
-/***/ },
-/* 106 */
-/***/ function(module, exports, __webpack_require__) {
+ // we load the references from the newly active sector into the global references
+ this._switchToSector(previousSector);
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : polish (pl)
- // author : Rafal Hirsz : https://github.com/evoL
+ // we forget the previously active sector because we reverted to the one before
+ this._forgetLastSector();
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var monthsNominative = "styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),
- monthsSubjective = "stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_");
+ // finally, we update the node index list.
+ this._updateNodeIndexList();
- function plural(n) {
- return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);
+ // we refresh the list with calulation nodes and calculation node indices.
+ this._updateCalculationNodes();
}
+ }
+ };
- function translate(number, withoutSuffix, key) {
- var result = number + " ";
- switch (key) {
- case 'm':
- return withoutSuffix ? 'minuta' : 'minutę';
- case 'mm':
- return result + (plural(number) ? 'minuty' : 'minut');
- case 'h':
- return withoutSuffix ? 'godzina' : 'godzinę';
- case 'hh':
- return result + (plural(number) ? 'godziny' : 'godzin');
- case 'MM':
- return result + (plural(number) ? 'miesiące' : 'miesięcy');
- case 'yy':
- return result + (plural(number) ? 'lata' : 'lat');
- }
- }
- return moment.lang('pl', {
- months : function (momentToFormat, format) {
- if (/D MMMM/.test(format)) {
- return monthsSubjective[momentToFormat.month()];
- } else {
- return monthsNominative[momentToFormat.month()];
- }
- },
- monthsShort : "sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),
- weekdays : "niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),
- weekdaysShort : "nie_pon_wt_śr_czw_pt_sb".split("_"),
- weekdaysMin : "N_Pn_Wt_Śr_Cz_Pt_So".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay: '[Dziś o] LT',
- nextDay: '[Jutro o] LT',
- nextWeek: '[W] dddd [o] LT',
- lastDay: '[Wczoraj o] LT',
- lastWeek: function () {
- switch (this.day()) {
- case 0:
- return '[W zeszłą niedzielę o] LT';
- case 3:
- return '[W zeszłą środę o] LT';
- case 6:
- return '[W zeszłą sobotę o] LT';
- default:
- return '[W zeszły] dddd [o] LT';
- }
- },
- sameElse: 'L'
- },
- relativeTime : {
- future : "za %s",
- past : "%s temu",
- s : "kilka sekund",
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : "1 dzień",
- dd : '%d dni',
- M : "miesiąc",
- MM : translate,
- y : "rok",
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
+ /**
+ * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation().
+ *
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
+ * | we dont pass the function itself because then the "this" is the window object
+ * | instead of the Network object
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
+ * @private
+ */
+ exports._doInAllActiveSectors = function(runFunction,argument) {
+ if (argument === undefined) {
+ for (var sector in this.sectors["active"]) {
+ if (this.sectors["active"].hasOwnProperty(sector)) {
+ // switch the global references to those of this sector
+ this._switchToActiveSector(sector);
+ this[runFunction]();
+ }
+ }
+ }
+ else {
+ for (var sector in this.sectors["active"]) {
+ if (this.sectors["active"].hasOwnProperty(sector)) {
+ // switch the global references to those of this sector
+ this._switchToActiveSector(sector);
+ var args = Array.prototype.splice.call(arguments, 1);
+ if (args.length > 1) {
+ this[runFunction](args[0],args[1]);
}
- });
- }));
-
-
-/***/ },
-/* 107 */
-/***/ function(module, exports, __webpack_require__) {
+ else {
+ this[runFunction](argument);
+ }
+ }
+ }
+ }
+ // we revert the global references back to our active sector
+ this._loadLatestSector();
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : brazilian portuguese (pt-br)
- // author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation().
+ *
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
+ * | we dont pass the function itself because then the "this" is the window object
+ * | instead of the Network object
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
+ * @private
+ */
+ exports._doInSupportSector = function(runFunction,argument) {
+ if (argument === undefined) {
+ this._switchToSupportSector();
+ this[runFunction]();
+ }
+ else {
+ this._switchToSupportSector();
+ var args = Array.prototype.splice.call(arguments, 1);
+ if (args.length > 1) {
+ this[runFunction](args[0],args[1]);
}
- }(function (moment) {
- return moment.lang('pt-br', {
- months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),
- monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),
- weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),
- weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"),
- weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D [de] MMMM [de] YYYY",
- LLL : "D [de] MMMM [de] YYYY [às] LT",
- LLLL : "dddd, D [de] MMMM [de] YYYY [às] LT"
- },
- calendar : {
- sameDay: '[Hoje às] LT',
- nextDay: '[Amanhã às] LT',
- nextWeek: 'dddd [às] LT',
- lastDay: '[Ontem às] LT',
- lastWeek: function () {
- return (this.day() === 0 || this.day() === 6) ?
- '[Último] dddd [às] LT' : // Saturday + Sunday
- '[Última] dddd [às] LT'; // Monday - Friday
- },
- sameElse: 'L'
- },
- relativeTime : {
- future : "em %s",
- past : "%s atrás",
- s : "segundos",
- m : "um minuto",
- mm : "%d minutos",
- h : "uma hora",
- hh : "%d horas",
- d : "um dia",
- dd : "%d dias",
- M : "um mês",
- MM : "%d meses",
- y : "um ano",
- yy : "%d anos"
- },
- ordinal : '%dº'
- });
- }));
+ else {
+ this[runFunction](argument);
+ }
+ }
+ // we revert the global references back to our active sector
+ this._loadLatestSector();
+ };
-/***/ },
-/* 108 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This runs a function in all frozen sectors. This is used in the _redraw().
+ *
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
+ * | we don't pass the function itself because then the "this" is the window object
+ * | instead of the Network object
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
+ * @private
+ */
+ exports._doInAllFrozenSectors = function(runFunction,argument) {
+ if (argument === undefined) {
+ for (var sector in this.sectors["frozen"]) {
+ if (this.sectors["frozen"].hasOwnProperty(sector)) {
+ // switch the global references to those of this sector
+ this._switchToFrozenSector(sector);
+ this[runFunction]();
+ }
+ }
+ }
+ else {
+ for (var sector in this.sectors["frozen"]) {
+ if (this.sectors["frozen"].hasOwnProperty(sector)) {
+ // switch the global references to those of this sector
+ this._switchToFrozenSector(sector);
+ var args = Array.prototype.splice.call(arguments, 1);
+ if (args.length > 1) {
+ this[runFunction](args[0],args[1]);
+ }
+ else {
+ this[runFunction](argument);
+ }
+ }
+ }
+ }
+ this._loadLatestSector();
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : portuguese (pt)
- // author : Jefferson : https://github.com/jalex79
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * This runs a function in all sectors. This is used in the _redraw().
+ *
+ * @param {String} runFunction | This is the NAME of a function we want to call in all active sectors
+ * | we don't pass the function itself because then the "this" is the window object
+ * | instead of the Network object
+ * @param {*} [argument] | Optional: arguments to pass to the runFunction
+ * @private
+ */
+ exports._doInAllSectors = function(runFunction,argument) {
+ var args = Array.prototype.splice.call(arguments, 1);
+ if (argument === undefined) {
+ this._doInAllActiveSectors(runFunction);
+ this._doInAllFrozenSectors(runFunction);
+ }
+ else {
+ if (args.length > 1) {
+ this._doInAllActiveSectors(runFunction,args[0],args[1]);
+ this._doInAllFrozenSectors(runFunction,args[0],args[1]);
}
- }(function (moment) {
- return moment.lang('pt', {
- months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),
- monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),
- weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),
- weekdaysShort : "dom_seg_ter_qua_qui_sex_sáb".split("_"),
- weekdaysMin : "dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D [de] MMMM [de] YYYY",
- LLL : "D [de] MMMM [de] YYYY LT",
- LLLL : "dddd, D [de] MMMM [de] YYYY LT"
- },
- calendar : {
- sameDay: '[Hoje às] LT',
- nextDay: '[Amanhã às] LT',
- nextWeek: 'dddd [às] LT',
- lastDay: '[Ontem às] LT',
- lastWeek: function () {
- return (this.day() === 0 || this.day() === 6) ?
- '[Último] dddd [às] LT' : // Saturday + Sunday
- '[Última] dddd [às] LT'; // Monday - Friday
- },
- sameElse: 'L'
- },
- relativeTime : {
- future : "em %s",
- past : "há %s",
- s : "segundos",
- m : "um minuto",
- mm : "%d minutos",
- h : "uma hora",
- hh : "%d horas",
- d : "um dia",
- dd : "%d dias",
- M : "um mês",
- MM : "%d meses",
- y : "um ano",
- yy : "%d anos"
- },
- ordinal : '%dº',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ else {
+ this._doInAllActiveSectors(runFunction,argument);
+ this._doInAllFrozenSectors(runFunction,argument);
+ }
+ }
+ };
-/***/ },
-/* 109 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * This clears the nodeIndices list. We cannot use this.nodeIndices = [] because we would break the link with the
+ * active sector. Thus we clear the nodeIndices in the active sector, then reconnect the this.nodeIndices to it.
+ *
+ * @private
+ */
+ exports._clearNodeIndexList = function() {
+ var sector = this._sector();
+ this.sectors["active"][sector]["nodeIndices"] = [];
+ this.nodeIndices = this.sectors["active"][sector]["nodeIndices"];
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : romanian (ro)
- // author : Vlad Gurdiga : https://github.com/gurdiga
- // author : Valentin Agachi : https://github.com/avaly
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- function relativeTimeWithPlural(number, withoutSuffix, key) {
- var format = {
- 'mm': 'minute',
- 'hh': 'ore',
- 'dd': 'zile',
- 'MM': 'luni',
- 'yy': 'ani'
- },
- separator = ' ';
- if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
- separator = ' de ';
- }
+ /**
+ * Draw the encompassing sector node
+ *
+ * @param ctx
+ * @param sectorType
+ * @private
+ */
+ exports._drawSectorNodes = function(ctx,sectorType) {
+ var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node;
+ for (var sector in this.sectors[sectorType]) {
+ if (this.sectors[sectorType].hasOwnProperty(sector)) {
+ if (this.sectors[sectorType][sector]["drawingNode"] !== undefined) {
- return number + separator + format[key];
- }
+ this._switchToSector(sector,sectorType);
- return moment.lang('ro', {
- months : "ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),
- monthsShort : "ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),
- weekdays : "duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),
- weekdaysShort : "Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),
- weekdaysMin : "Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY H:mm",
- LLLL : "dddd, D MMMM YYYY H:mm"
- },
- calendar : {
- sameDay: "[azi la] LT",
- nextDay: '[mâine la] LT',
- nextWeek: 'dddd [la] LT',
- lastDay: '[ieri la] LT',
- lastWeek: '[fosta] dddd [la] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "peste %s",
- past : "%s în urmă",
- s : "câteva secunde",
- m : "un minut",
- mm : relativeTimeWithPlural,
- h : "o oră",
- hh : relativeTimeWithPlural,
- d : "o zi",
- dd : relativeTimeWithPlural,
- M : "o lună",
- MM : relativeTimeWithPlural,
- y : "un an",
- yy : relativeTimeWithPlural
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
+ minY = 1e9; maxY = -1e9; minX = 1e9; maxX = -1e9;
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ node = this.nodes[nodeId];
+ node.resize(ctx);
+ if (minX > node.x - 0.5 * node.width) {minX = node.x - 0.5 * node.width;}
+ if (maxX < node.x + 0.5 * node.width) {maxX = node.x + 0.5 * node.width;}
+ if (minY > node.y - 0.5 * node.height) {minY = node.y - 0.5 * node.height;}
+ if (maxY < node.y + 0.5 * node.height) {maxY = node.y + 0.5 * node.height;}
+ }
}
- });
- }));
+ node = this.sectors[sectorType][sector]["drawingNode"];
+ node.x = 0.5 * (maxX + minX);
+ node.y = 0.5 * (maxY + minY);
+ node.width = 2 * (node.x - minX);
+ node.height = 2 * (node.y - minY);
+ node.radius = Math.sqrt(Math.pow(0.5*node.width,2) + Math.pow(0.5*node.height,2));
+ node.setScale(this.scale);
+ node._drawCircle(ctx);
+ }
+ }
+ }
+ };
+
+ exports._drawAllSectorNodes = function(ctx) {
+ this._drawSectorNodes(ctx,"frozen");
+ this._drawSectorNodes(ctx,"active");
+ this._loadLatestSector();
+ };
/***/ },
-/* 110 */
+/* 126 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : russian (ru)
- // author : Viktorminator : https://github.com/Viktorminator
- // Author : Menelion Elensúle : https://github.com/Oire
-
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- function plural(word, num) {
- var forms = word.split('_');
- return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
- }
+ var Node = __webpack_require__(39);
- function relativeTimeWithPlural(number, withoutSuffix, key) {
- var format = {
- 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
- 'hh': 'час_часа_часов',
- 'dd': 'день_дня_дней',
- 'MM': 'месяц_месяца_месяцев',
- 'yy': 'год_года_лет'
- };
- if (key === 'm') {
- return withoutSuffix ? 'минута' : 'минуту';
- }
- else {
- return number + ' ' + plural(format[key], +number);
- }
+ /**
+ * This function can be called from the _doInAllSectors function
+ *
+ * @param object
+ * @param overlappingNodes
+ * @private
+ */
+ exports._getNodesOverlappingWith = function(object, overlappingNodes) {
+ var nodes = this.nodes;
+ for (var nodeId in nodes) {
+ if (nodes.hasOwnProperty(nodeId)) {
+ if (nodes[nodeId].isOverlappingWith(object)) {
+ overlappingNodes.push(nodeId);
+ }
}
+ }
+ };
- function monthsCaseReplace(m, format) {
- var months = {
- 'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
- 'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')
- },
+ /**
+ * retrieve all nodes overlapping with given object
+ * @param {Object} object An object with parameters left, top, right, bottom
+ * @return {Number[]} An array with id's of the overlapping nodes
+ * @private
+ */
+ exports._getAllNodesOverlappingWith = function (object) {
+ var overlappingNodes = [];
+ this._doInAllActiveSectors("_getNodesOverlappingWith",object,overlappingNodes);
+ return overlappingNodes;
+ };
- nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
- 'accusative' :
- 'nominative';
- return months[nounCase][m.month()];
- }
+ /**
+ * Return a position object in canvasspace from a single point in screenspace
+ *
+ * @param pointer
+ * @returns {{left: number, top: number, right: number, bottom: number}}
+ * @private
+ */
+ exports._pointerToPositionObject = function(pointer) {
+ var x = this._XconvertDOMtoCanvas(pointer.x);
+ var y = this._YconvertDOMtoCanvas(pointer.y);
- function monthsShortCaseReplace(m, format) {
- var monthsShort = {
- 'nominative': 'янв_фев_мар_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),
- 'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')
- },
+ return {
+ left: x,
+ top: y,
+ right: x,
+ bottom: y
+ };
+ };
- nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
- 'accusative' :
- 'nominative';
- return monthsShort[nounCase][m.month()];
- }
+ /**
+ * Get the top node at the a specific point (like a click)
+ *
+ * @param {{x: Number, y: Number}} pointer
+ * @return {Node | null} node
+ * @private
+ */
+ exports._getNodeAt = function (pointer) {
+ // we first check if this is an navigation controls element
+ var positionObject = this._pointerToPositionObject(pointer);
+ var overlappingNodes = this._getAllNodesOverlappingWith(positionObject);
- function weekdaysCaseReplace(m, format) {
- var weekdays = {
- 'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
- 'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')
- },
+ // if there are overlapping nodes, select the last one, this is the
+ // one which is drawn on top of the others
+ if (overlappingNodes.length > 0) {
+ return this.nodes[overlappingNodes[overlappingNodes.length - 1]];
+ }
+ else {
+ return null;
+ }
+ };
- nounCase = (/\[ ?[Вв] ?(?:прошлую|следующую)? ?\] ?dddd/).test(format) ?
- 'accusative' :
- 'nominative';
- return weekdays[nounCase][m.day()];
+ /**
+ * retrieve all edges overlapping with given object, selector is around center
+ * @param {Object} object An object with parameters left, top, right, bottom
+ * @return {Number[]} An array with id's of the overlapping nodes
+ * @private
+ */
+ exports._getEdgesOverlappingWith = function (object, overlappingEdges) {
+ var edges = this.edges;
+ for (var edgeId in edges) {
+ if (edges.hasOwnProperty(edgeId)) {
+ if (edges[edgeId].isOverlappingWith(object)) {
+ overlappingEdges.push(edgeId);
+ }
}
+ }
+ };
- return moment.lang('ru', {
- months : monthsCaseReplace,
- monthsShort : monthsShortCaseReplace,
- weekdays : weekdaysCaseReplace,
- weekdaysShort : "вс_пн_вт_ср_чт_пт_сб".split("_"),
- weekdaysMin : "вс_пн_вт_ср_чт_пт_сб".split("_"),
- monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY г.",
- LLL : "D MMMM YYYY г., LT",
- LLLL : "dddd, D MMMM YYYY г., LT"
- },
- calendar : {
- sameDay: '[Сегодня в] LT',
- nextDay: '[Завтра в] LT',
- lastDay: '[Вчера в] LT',
- nextWeek: function () {
- return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';
- },
- lastWeek: function () {
- switch (this.day()) {
- case 0:
- return '[В прошлое] dddd [в] LT';
- case 1:
- case 2:
- case 4:
- return '[В прошлый] dddd [в] LT';
- case 3:
- case 5:
- case 6:
- return '[В прошлую] dddd [в] LT';
- }
- },
- sameElse: 'L'
- },
- relativeTime : {
- future : "через %s",
- past : "%s назад",
- s : "несколько секунд",
- m : relativeTimeWithPlural,
- mm : relativeTimeWithPlural,
- h : "час",
- hh : relativeTimeWithPlural,
- d : "день",
- dd : relativeTimeWithPlural,
- M : "месяц",
- MM : relativeTimeWithPlural,
- y : "год",
- yy : relativeTimeWithPlural
- },
- meridiemParse: /ночи|утра|дня|вечера/i,
- isPM : function (input) {
- return /^(дня|вечера)$/.test(input);
- },
+ /**
+ * retrieve all nodes overlapping with given object
+ * @param {Object} object An object with parameters left, top, right, bottom
+ * @return {Number[]} An array with id's of the overlapping nodes
+ * @private
+ */
+ exports._getAllEdgesOverlappingWith = function (object) {
+ var overlappingEdges = [];
+ this._doInAllActiveSectors("_getEdgesOverlappingWith",object,overlappingEdges);
+ return overlappingEdges;
+ };
- meridiem : function (hour, minute, isLower) {
- if (hour < 4) {
- return "ночи";
- } else if (hour < 12) {
- return "утра";
- } else if (hour < 17) {
- return "дня";
- } else {
- return "вечера";
- }
- },
+ /**
+ * Place holder. To implement change the _getNodeAt to a _getObjectAt. Have the _getObjectAt call
+ * _getNodeAt and _getEdgesAt, then priortize the selection to user preferences.
+ *
+ * @param pointer
+ * @returns {null}
+ * @private
+ */
+ exports._getEdgeAt = function(pointer) {
+ var positionObject = this._pointerToPositionObject(pointer);
+ var overlappingEdges = this._getAllEdgesOverlappingWith(positionObject);
- ordinal: function (number, period) {
- switch (period) {
- case 'M':
- case 'd':
- case 'DDD':
- return number + '-й';
- case 'D':
- return number + '-го';
- case 'w':
- case 'W':
- return number + '-я';
- default:
- return number;
- }
- },
+ if (overlappingEdges.length > 0) {
+ return this.edges[overlappingEdges[overlappingEdges.length - 1]];
+ }
+ else {
+ return null;
+ }
+ };
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * Add object to the selection array.
+ *
+ * @param obj
+ * @private
+ */
+ exports._addToSelection = function(obj) {
+ if (obj instanceof Node) {
+ this.selectionObj.nodes[obj.id] = obj;
+ }
+ else {
+ this.selectionObj.edges[obj.id] = obj;
+ }
+ };
+
+ /**
+ * Add object to the selection array.
+ *
+ * @param obj
+ * @private
+ */
+ exports._addToHover = function(obj) {
+ if (obj instanceof Node) {
+ this.hoverObj.nodes[obj.id] = obj;
+ }
+ else {
+ this.hoverObj.edges[obj.id] = obj;
+ }
+ };
-/***/ },
-/* 111 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : slovak (sk)
- // author : Martin Minka : https://github.com/k2s
- // based on work of petrbela : https://github.com/petrbela
+ /**
+ * Remove a single option from selection.
+ *
+ * @param {Object} obj
+ * @private
+ */
+ exports._removeFromSelection = function(obj) {
+ if (obj instanceof Node) {
+ delete this.selectionObj.nodes[obj.id];
+ }
+ else {
+ delete this.selectionObj.edges[obj.id];
+ }
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * Unselect all. The selectionObj is useful for this.
+ *
+ * @param {Boolean} [doNotTrigger] | ignore trigger
+ * @private
+ */
+ exports._unselectAll = function(doNotTrigger) {
+ if (doNotTrigger === undefined) {
+ doNotTrigger = false;
+ }
+ for(var nodeId in this.selectionObj.nodes) {
+ if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ this.selectionObj.nodes[nodeId].unselect();
}
- }(function (moment) {
- var months = "január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),
- monthsShort = "jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_");
-
- function plural(n) {
- return (n > 1) && (n < 5);
+ }
+ for(var edgeId in this.selectionObj.edges) {
+ if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
+ this.selectionObj.edges[edgeId].unselect();
}
+ }
- function translate(number, withoutSuffix, key, isFuture) {
- var result = number + " ";
- switch (key) {
- case 's': // a few seconds / in a few seconds / a few seconds ago
- return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';
- case 'm': // a minute / in a minute / a minute ago
- return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');
- case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'minúty' : 'minút');
- } else {
- return result + 'minútami';
- }
- break;
- case 'h': // an hour / in an hour / an hour ago
- return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
- case 'hh': // 9 hours / in 9 hours / 9 hours ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'hodiny' : 'hodín');
- } else {
- return result + 'hodinami';
- }
- break;
- case 'd': // a day / in a day / a day ago
- return (withoutSuffix || isFuture) ? 'deň' : 'dňom';
- case 'dd': // 9 days / in 9 days / 9 days ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'dni' : 'dní');
- } else {
- return result + 'dňami';
- }
- break;
- case 'M': // a month / in a month / a month ago
- return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';
- case 'MM': // 9 months / in 9 months / 9 months ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'mesiace' : 'mesiacov');
- } else {
- return result + 'mesiacmi';
- }
- break;
- case 'y': // a year / in a year / a year ago
- return (withoutSuffix || isFuture) ? 'rok' : 'rokom';
- case 'yy': // 9 years / in 9 years / 9 years ago
- if (withoutSuffix || isFuture) {
- return result + (plural(number) ? 'roky' : 'rokov');
- } else {
- return result + 'rokmi';
- }
- break;
- }
- }
+ this.selectionObj = {nodes:{},edges:{}};
- return moment.lang('sk', {
- months : months,
- monthsShort : monthsShort,
- monthsParse : (function (months, monthsShort) {
- var i, _monthsParse = [];
- for (i = 0; i < 12; i++) {
- // use custom parser to solve problem with July (červenec)
- _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
- }
- return _monthsParse;
- }(months, monthsShort)),
- weekdays : "nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),
- weekdaysShort : "ne_po_ut_st_št_pi_so".split("_"),
- weekdaysMin : "ne_po_ut_st_št_pi_so".split("_"),
- longDateFormat : {
- LT: "H:mm",
- L : "DD.MM.YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd D. MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[dnes o] LT",
- nextDay: '[zajtra o] LT',
- nextWeek: function () {
- switch (this.day()) {
- case 0:
- return '[v nedeľu o] LT';
- case 1:
- case 2:
- return '[v] dddd [o] LT';
- case 3:
- return '[v stredu o] LT';
- case 4:
- return '[vo štvrtok o] LT';
- case 5:
- return '[v piatok o] LT';
- case 6:
- return '[v sobotu o] LT';
- }
- },
- lastDay: '[včera o] LT',
- lastWeek: function () {
- switch (this.day()) {
- case 0:
- return '[minulú nedeľu o] LT';
- case 1:
- case 2:
- return '[minulý] dddd [o] LT';
- case 3:
- return '[minulú stredu o] LT';
- case 4:
- case 5:
- return '[minulý] dddd [o] LT';
- case 6:
- return '[minulú sobotu o] LT';
- }
- },
- sameElse: "L"
- },
- relativeTime : {
- future : "za %s",
- past : "pred %s",
- s : translate,
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : translate,
- dd : translate,
- M : translate,
- MM : translate,
- y : translate,
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ if (doNotTrigger == false) {
+ this.emit('select', this.getSelection());
+ }
+ };
+ /**
+ * Unselect all clusters. The selectionObj is useful for this.
+ *
+ * @param {Boolean} [doNotTrigger] | ignore trigger
+ * @private
+ */
+ exports._unselectClusters = function(doNotTrigger) {
+ if (doNotTrigger === undefined) {
+ doNotTrigger = false;
+ }
-/***/ },
-/* 112 */
-/***/ function(module, exports, __webpack_require__) {
+ for (var nodeId in this.selectionObj.nodes) {
+ if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
+ this.selectionObj.nodes[nodeId].unselect();
+ this._removeFromSelection(this.selectionObj.nodes[nodeId]);
+ }
+ }
+ }
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : slovenian (sl)
- // author : Robert Sedovšek : https://github.com/sedovsek
+ if (doNotTrigger == false) {
+ this.emit('select', this.getSelection());
+ }
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- function translate(number, withoutSuffix, key) {
- var result = number + " ";
- switch (key) {
- case 'm':
- return withoutSuffix ? 'ena minuta' : 'eno minuto';
- case 'mm':
- if (number === 1) {
- result += 'minuta';
- } else if (number === 2) {
- result += 'minuti';
- } else if (number === 3 || number === 4) {
- result += 'minute';
- } else {
- result += 'minut';
- }
- return result;
- case 'h':
- return withoutSuffix ? 'ena ura' : 'eno uro';
- case 'hh':
- if (number === 1) {
- result += 'ura';
- } else if (number === 2) {
- result += 'uri';
- } else if (number === 3 || number === 4) {
- result += 'ure';
- } else {
- result += 'ur';
- }
- return result;
- case 'dd':
- if (number === 1) {
- result += 'dan';
- } else {
- result += 'dni';
- }
- return result;
- case 'MM':
- if (number === 1) {
- result += 'mesec';
- } else if (number === 2) {
- result += 'meseca';
- } else if (number === 3 || number === 4) {
- result += 'mesece';
- } else {
- result += 'mesecev';
- }
- return result;
- case 'yy':
- if (number === 1) {
- result += 'leto';
- } else if (number === 2) {
- result += 'leti';
- } else if (number === 3 || number === 4) {
- result += 'leta';
- } else {
- result += 'let';
- }
- return result;
- }
+
+ /**
+ * return the number of selected nodes
+ *
+ * @returns {number}
+ * @private
+ */
+ exports._getSelectedNodeCount = function() {
+ var count = 0;
+ for (var nodeId in this.selectionObj.nodes) {
+ if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ count += 1;
}
+ }
+ return count;
+ };
- return moment.lang('sl', {
- months : "januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),
- monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
- weekdays : "nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),
- weekdaysShort : "ned._pon._tor._sre._čet._pet._sob.".split("_"),
- weekdaysMin : "ne_po_to_sr_če_pe_so".split("_"),
- longDateFormat : {
- LT : "H:mm",
- L : "DD. MM. YYYY",
- LL : "D. MMMM YYYY",
- LLL : "D. MMMM YYYY LT",
- LLLL : "dddd, D. MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[danes ob] LT',
- nextDay : '[jutri ob] LT',
+ /**
+ * return the selected node
+ *
+ * @returns {number}
+ * @private
+ */
+ exports._getSelectedNode = function() {
+ for (var nodeId in this.selectionObj.nodes) {
+ if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ return this.selectionObj.nodes[nodeId];
+ }
+ }
+ return null;
+ };
- nextWeek : function () {
- switch (this.day()) {
- case 0:
- return '[v] [nedeljo] [ob] LT';
- case 3:
- return '[v] [sredo] [ob] LT';
- case 6:
- return '[v] [soboto] [ob] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[v] dddd [ob] LT';
- }
- },
- lastDay : '[včeraj ob] LT',
- lastWeek : function () {
- switch (this.day()) {
- case 0:
- case 3:
- case 6:
- return '[prejšnja] dddd [ob] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[prejšnji] dddd [ob] LT';
- }
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "čez %s",
- past : "%s nazaj",
- s : "nekaj sekund",
- m : translate,
- mm : translate,
- h : translate,
- hh : translate,
- d : "en dan",
- dd : translate,
- M : "en mesec",
- MM : translate,
- y : "eno leto",
- yy : translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * return the selected edge
+ *
+ * @returns {number}
+ * @private
+ */
+ exports._getSelectedEdge = function() {
+ for (var edgeId in this.selectionObj.edges) {
+ if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
+ return this.selectionObj.edges[edgeId];
+ }
+ }
+ return null;
+ };
-/***/ },
-/* 113 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * return the number of selected edges
+ *
+ * @returns {number}
+ * @private
+ */
+ exports._getSelectedEdgeCount = function() {
+ var count = 0;
+ for (var edgeId in this.selectionObj.edges) {
+ if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
+ count += 1;
+ }
+ }
+ return count;
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Albanian (sq)
- // author : Flakërim Ismani : https://github.com/flakerimi
- // author: Menelion Elensúle: https://github.com/Oire (tests)
- // author : Oerd Cukalla : https://github.com/oerd (fixes)
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * return the number of selected objects.
+ *
+ * @returns {number}
+ * @private
+ */
+ exports._getSelectedObjectCount = function() {
+ var count = 0;
+ for(var nodeId in this.selectionObj.nodes) {
+ if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ count += 1;
}
- }(function (moment) {
- return moment.lang('sq', {
- months : "Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"),
- monthsShort : "Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"),
- weekdays : "E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"),
- weekdaysShort : "Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"),
- weekdaysMin : "D_H_Ma_Më_E_P_Sh".split("_"),
- meridiem : function (hours, minutes, isLower) {
- return hours < 12 ? 'PD' : 'MD';
- },
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[Sot në] LT',
- nextDay : '[Nesër në] LT',
- nextWeek : 'dddd [në] LT',
- lastDay : '[Dje në] LT',
- lastWeek : 'dddd [e kaluar në] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "në %s",
- past : "%s më parë",
- s : "disa sekonda",
- m : "një minutë",
- mm : "%d minuta",
- h : "një orë",
- hh : "%d orë",
- d : "një ditë",
- dd : "%d ditë",
- M : "një muaj",
- MM : "%d muaj",
- y : "një vit",
- yy : "%d vite"
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
-
+ }
+ for(var edgeId in this.selectionObj.edges) {
+ if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
+ count += 1;
+ }
+ }
+ return count;
+ };
-/***/ },
-/* 114 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * Check if anything is selected
+ *
+ * @returns {boolean}
+ * @private
+ */
+ exports._selectionIsEmpty = function() {
+ for(var nodeId in this.selectionObj.nodes) {
+ if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ return false;
+ }
+ }
+ for(var edgeId in this.selectionObj.edges) {
+ if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
+ return false;
+ }
+ }
+ return true;
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Serbian-cyrillic (sr-cyrl)
- // author : Milan Janačković : https://github.com/milan-j
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * check if one of the selected nodes is a cluster.
+ *
+ * @returns {boolean}
+ * @private
+ */
+ exports._clusterInSelection = function() {
+ for(var nodeId in this.selectionObj.nodes) {
+ if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
+ return true;
+ }
}
- }(function (moment) {
+ }
+ return false;
+ };
- var translator = {
- words: { //Different grammatical cases
- m: ['један минут', 'једне минуте'],
- mm: ['минут', 'минуте', 'минута'],
- h: ['један сат', 'једног сата'],
- hh: ['сат', 'сата', 'сати'],
- dd: ['дан', 'дана', 'дана'],
- MM: ['месец', 'месеца', 'месеци'],
- yy: ['година', 'године', 'година']
- },
- correctGrammaticalCase: function (number, wordKey) {
- return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
- },
- translate: function (number, withoutSuffix, key) {
- var wordKey = translator.words[key];
- if (key.length === 1) {
- return withoutSuffix ? wordKey[0] : wordKey[1];
- } else {
- return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
- }
- }
- };
+ /**
+ * select the edges connected to the node that is being selected
+ *
+ * @param {Node} node
+ * @private
+ */
+ exports._selectConnectedEdges = function(node) {
+ for (var i = 0; i < node.dynamicEdges.length; i++) {
+ var edge = node.dynamicEdges[i];
+ edge.select();
+ this._addToSelection(edge);
+ }
+ };
- return moment.lang('sr-cyrl', {
- months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],
- monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],
- weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],
- weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],
- weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],
- longDateFormat: {
- LT: "H:mm",
- L: "DD. MM. YYYY",
- LL: "D. MMMM YYYY",
- LLL: "D. MMMM YYYY LT",
- LLLL: "dddd, D. MMMM YYYY LT"
- },
- calendar: {
- sameDay: '[данас у] LT',
- nextDay: '[сутра у] LT',
+ /**
+ * select the edges connected to the node that is being selected
+ *
+ * @param {Node} node
+ * @private
+ */
+ exports._hoverConnectedEdges = function(node) {
+ for (var i = 0; i < node.dynamicEdges.length; i++) {
+ var edge = node.dynamicEdges[i];
+ edge.hover = true;
+ this._addToHover(edge);
+ }
+ };
- nextWeek: function () {
- switch (this.day()) {
- case 0:
- return '[у] [недељу] [у] LT';
- case 3:
- return '[у] [среду] [у] LT';
- case 6:
- return '[у] [суботу] [у] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[у] dddd [у] LT';
- }
- },
- lastDay : '[јуче у] LT',
- lastWeek : function () {
- var lastWeekDays = [
- '[прошле] [недеље] [у] LT',
- '[прошлог] [понедељка] [у] LT',
- '[прошлог] [уторка] [у] LT',
- '[прошле] [среде] [у] LT',
- '[прошлог] [четвртка] [у] LT',
- '[прошлог] [петка] [у] LT',
- '[прошле] [суботе] [у] LT'
- ];
- return lastWeekDays[this.day()];
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "за %s",
- past : "пре %s",
- s : "неколико секунди",
- m : translator.translate,
- mm : translator.translate,
- h : translator.translate,
- hh : translator.translate,
- d : "дан",
- dd : translator.translate,
- M : "месец",
- MM : translator.translate,
- y : "годину",
- yy : translator.translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ /**
+ * unselect the edges connected to the node that is being selected
+ *
+ * @param {Node} node
+ * @private
+ */
+ exports._unselectConnectedEdges = function(node) {
+ for (var i = 0; i < node.dynamicEdges.length; i++) {
+ var edge = node.dynamicEdges[i];
+ edge.unselect();
+ this._removeFromSelection(edge);
+ }
+ };
-/***/ },
-/* 115 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Serbian-latin (sr)
- // author : Milan Janačković : https://github.com/milan-j
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- var translator = {
- words: { //Different grammatical cases
- m: ['jedan minut', 'jedne minute'],
- mm: ['minut', 'minute', 'minuta'],
- h: ['jedan sat', 'jednog sata'],
- hh: ['sat', 'sata', 'sati'],
- dd: ['dan', 'dana', 'dana'],
- MM: ['mesec', 'meseca', 'meseci'],
- yy: ['godina', 'godine', 'godina']
- },
- correctGrammaticalCase: function (number, wordKey) {
- return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);
- },
- translate: function (number, withoutSuffix, key) {
- var wordKey = translator.words[key];
- if (key.length === 1) {
- return withoutSuffix ? wordKey[0] : wordKey[1];
- } else {
- return number + ' ' + translator.correctGrammaticalCase(number, wordKey);
- }
- }
- };
+ /**
+ * This is called when someone clicks on a node. either select or deselect it.
+ * If there is an existing selection and we don't want to append to it, clear the existing selection
+ *
+ * @param {Node || Edge} object
+ * @param {Boolean} append
+ * @param {Boolean} [doNotTrigger] | ignore trigger
+ * @private
+ */
+ exports._selectObject = function(object, append, doNotTrigger, highlightEdges) {
+ if (doNotTrigger === undefined) {
+ doNotTrigger = false;
+ }
+ if (highlightEdges === undefined) {
+ highlightEdges = true;
+ }
- return moment.lang('sr', {
- months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
- monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],
- weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],
- weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],
- weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
- longDateFormat: {
- LT: "H:mm",
- L: "DD. MM. YYYY",
- LL: "D. MMMM YYYY",
- LLL: "D. MMMM YYYY LT",
- LLLL: "dddd, D. MMMM YYYY LT"
- },
- calendar: {
- sameDay: '[danas u] LT',
- nextDay: '[sutra u] LT',
+ if (this._selectionIsEmpty() == false && append == false && this.forceAppendSelection == false) {
+ this._unselectAll(true);
+ }
- nextWeek: function () {
- switch (this.day()) {
- case 0:
- return '[u] [nedelju] [u] LT';
- case 3:
- return '[u] [sredu] [u] LT';
- case 6:
- return '[u] [subotu] [u] LT';
- case 1:
- case 2:
- case 4:
- case 5:
- return '[u] dddd [u] LT';
- }
- },
- lastDay : '[juče u] LT',
- lastWeek : function () {
- var lastWeekDays = [
- '[prošle] [nedelje] [u] LT',
- '[prošlog] [ponedeljka] [u] LT',
- '[prošlog] [utorka] [u] LT',
- '[prošle] [srede] [u] LT',
- '[prošlog] [četvrtka] [u] LT',
- '[prošlog] [petka] [u] LT',
- '[prošle] [subote] [u] LT'
- ];
- return lastWeekDays[this.day()];
- },
- sameElse : 'L'
- },
- relativeTime : {
- future : "za %s",
- past : "pre %s",
- s : "nekoliko sekundi",
- m : translator.translate,
- mm : translator.translate,
- h : translator.translate,
- hh : translator.translate,
- d : "dan",
- dd : translator.translate,
- M : "mesec",
- MM : translator.translate,
- y : "godinu",
- yy : translator.translate
- },
- ordinal : '%d.',
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ if (object.selected == false) {
+ object.select();
+ this._addToSelection(object);
+ if (object instanceof Node && this.blockConnectingEdgeSelection == false && highlightEdges == true) {
+ this._selectConnectedEdges(object);
+ }
+ }
+ else {
+ object.unselect();
+ this._removeFromSelection(object);
+ }
+ if (doNotTrigger == false) {
+ this.emit('select', this.getSelection());
+ }
+ };
-/***/ },
-/* 116 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : swedish (sv)
- // author : Jens Alm : https://github.com/ulmus
+ /**
+ * This is called when someone clicks on a node. either select or deselect it.
+ * If there is an existing selection and we don't want to append to it, clear the existing selection
+ *
+ * @param {Node || Edge} object
+ * @private
+ */
+ exports._blurObject = function(object) {
+ if (object.hover == true) {
+ object.hover = false;
+ this.emit("blurNode",{node:object.id});
+ }
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * This is called when someone clicks on a node. either select or deselect it.
+ * If there is an existing selection and we don't want to append to it, clear the existing selection
+ *
+ * @param {Node || Edge} object
+ * @private
+ */
+ exports._hoverObject = function(object) {
+ if (object.hover == false) {
+ object.hover = true;
+ this._addToHover(object);
+ if (object instanceof Node) {
+ this.emit("hoverNode",{node:object.id});
}
- }(function (moment) {
- return moment.lang('sv', {
- months : "januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),
- monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),
- weekdays : "söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),
- weekdaysShort : "sön_mån_tis_ons_tor_fre_lör".split("_"),
- weekdaysMin : "sö_må_ti_on_to_fr_lö".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "YYYY-MM-DD",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: '[Idag] LT',
- nextDay: '[Imorgon] LT',
- lastDay: '[Igår] LT',
- nextWeek: 'dddd LT',
- lastWeek: '[Förra] dddd[en] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "om %s",
- past : "för %s sedan",
- s : "några sekunder",
- m : "en minut",
- mm : "%d minuter",
- h : "en timme",
- hh : "%d timmar",
- d : "en dag",
- dd : "%d dagar",
- M : "en månad",
- MM : "%d månader",
- y : "ett år",
- yy : "%d år"
- },
- ordinal : function (number) {
- var b = number % 10,
- output = (~~ (number % 100 / 10) === 1) ? 'e' :
- (b === 1) ? 'a' :
- (b === 2) ? 'a' :
- (b === 3) ? 'e' : 'e';
- return number + output;
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ }
+ if (object instanceof Node) {
+ this._hoverConnectedEdges(object);
+ }
+ };
-/***/ },
-/* 117 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * handles the selection part of the touch, only for navigation controls elements;
+ * Touch is triggered before tap, also before hold. Hold triggers after a while.
+ * This is the most responsive solution
+ *
+ * @param {Object} pointer
+ * @private
+ */
+ exports._handleTouch = function(pointer) {
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : tamil (ta)
- // author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * handles the selection part of the tap;
+ *
+ * @param {Object} pointer
+ * @private
+ */
+ exports._handleTap = function(pointer) {
+ var node = this._getNodeAt(pointer);
+ if (node != null) {
+ this._selectObject(node,false);
+ }
+ else {
+ var edge = this._getEdgeAt(pointer);
+ if (edge != null) {
+ this._selectObject(edge,false);
}
- }(function (moment) {
- /*var symbolMap = {
- '1': '௧',
- '2': '௨',
- '3': '௩',
- '4': '௪',
- '5': '௫',
- '6': '௬',
- '7': '௭',
- '8': '௮',
- '9': '௯',
- '0': '௦'
- },
- numberMap = {
- '௧': '1',
- '௨': '2',
- '௩': '3',
- '௪': '4',
- '௫': '5',
- '௬': '6',
- '௭': '7',
- '௮': '8',
- '௯': '9',
- '௦': '0'
- }; */
+ else {
+ this._unselectAll();
+ }
+ }
+ this.emit("click", this.getSelection());
+ this._redraw();
+ };
+
+
+ /**
+ * handles the selection part of the double tap and opens a cluster if needed
+ *
+ * @param {Object} pointer
+ * @private
+ */
+ exports._handleDoubleTap = function(pointer) {
+ var node = this._getNodeAt(pointer);
+ if (node != null && node !== undefined) {
+ // we reset the areaCenter here so the opening of the node will occur
+ this.areaCenter = {"x" : this._XconvertDOMtoCanvas(pointer.x),
+ "y" : this._YconvertDOMtoCanvas(pointer.y)};
+ this.openCluster(node);
+ }
+ this.emit("doubleClick", this.getSelection());
+ };
+
+
+ /**
+ * Handle the onHold selection part
+ *
+ * @param pointer
+ * @private
+ */
+ exports._handleOnHold = function(pointer) {
+ var node = this._getNodeAt(pointer);
+ if (node != null) {
+ this._selectObject(node,true);
+ }
+ else {
+ var edge = this._getEdgeAt(pointer);
+ if (edge != null) {
+ this._selectObject(edge,true);
+ }
+ }
+ this._redraw();
+ };
- return moment.lang('ta', {
- months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"),
- monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"),
- weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split("_"),
- weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split("_"),
- weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY, LT",
- LLLL : "dddd, D MMMM YYYY, LT"
- },
- calendar : {
- sameDay : '[இன்று] LT',
- nextDay : '[நாளை] LT',
- nextWeek : 'dddd, LT',
- lastDay : '[நேற்று] LT',
- lastWeek : '[கடந்த வாரம்] dddd, LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s இல்",
- past : "%s முன்",
- s : "ஒரு சில விநாடிகள்",
- m : "ஒரு நிமிடம்",
- mm : "%d நிமிடங்கள்",
- h : "ஒரு மணி நேரம்",
- hh : "%d மணி நேரம்",
- d : "ஒரு நாள்",
- dd : "%d நாட்கள்",
- M : "ஒரு மாதம்",
- MM : "%d மாதங்கள்",
- y : "ஒரு வருடம்",
- yy : "%d ஆண்டுகள்"
- },
- /* preparse: function (string) {
- return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {
- return numberMap[match];
- });
- },
- postformat: function (string) {
- return string.replace(/\d/g, function (match) {
- return symbolMap[match];
- });
- },*/
- ordinal : function (number) {
- return number + 'வது';
- },
+ /**
+ * handle the onRelease event. These functions are here for the navigation controls module.
+ *
+ * @private
+ */
+ exports._handleOnRelease = function(pointer) {
- // refer http://ta.wikipedia.org/s/1er1
+ };
- meridiem : function (hour, minute, isLower) {
- if (hour >= 6 && hour <= 10) {
- return " காலை";
- } else if (hour >= 10 && hour <= 14) {
- return " நண்பகல்";
- } else if (hour >= 14 && hour <= 18) {
- return " எற்பாடு";
- } else if (hour >= 18 && hour <= 20) {
- return " மாலை";
- } else if (hour >= 20 && hour <= 24) {
- return " இரவு";
- } else if (hour >= 0 && hour <= 6) {
- return " வைகறை";
- }
- },
- week : {
- dow : 0, // Sunday is the first day of the week.
- doy : 6 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
-/***/ },
-/* 118 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ *
+ * retrieve the currently selected objects
+ * @return {{nodes: Array., edges: Array.}} selection
+ */
+ exports.getSelection = function() {
+ var nodeIds = this.getSelectedNodes();
+ var edgeIds = this.getSelectedEdges();
+ return {nodes:nodeIds, edges:edgeIds};
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : thai (th)
- // author : Kridsada Thanabulpong : https://github.com/sirn
+ /**
+ *
+ * retrieve the currently selected nodes
+ * @return {String[]} selection An array with the ids of the
+ * selected nodes.
+ */
+ exports.getSelectedNodes = function() {
+ var idArray = [];
+ for(var nodeId in this.selectionObj.nodes) {
+ if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ idArray.push(nodeId);
+ }
+ }
+ return idArray
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ *
+ * retrieve the currently selected edges
+ * @return {Array} selection An array with the ids of the
+ * selected nodes.
+ */
+ exports.getSelectedEdges = function() {
+ var idArray = [];
+ for(var edgeId in this.selectionObj.edges) {
+ if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
+ idArray.push(edgeId);
}
- }(function (moment) {
- return moment.lang('th', {
- months : "มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),
- monthsShort : "มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),
- weekdays : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),
- weekdaysShort : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"), // yes, three characters difference
- weekdaysMin : "อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),
- longDateFormat : {
- LT : "H นาฬิกา m นาที",
- L : "YYYY/MM/DD",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY เวลา LT",
- LLLL : "วันddddที่ D MMMM YYYY เวลา LT"
- },
- meridiem : function (hour, minute, isLower) {
- if (hour < 12) {
- return "ก่อนเที่ยง";
- } else {
- return "หลังเที่ยง";
- }
- },
- calendar : {
- sameDay : '[วันนี้ เวลา] LT',
- nextDay : '[พรุ่งนี้ เวลา] LT',
- nextWeek : 'dddd[หน้า เวลา] LT',
- lastDay : '[เมื่อวานนี้ เวลา] LT',
- lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "อีก %s",
- past : "%sที่แล้ว",
- s : "ไม่กี่วินาที",
- m : "1 นาที",
- mm : "%d นาที",
- h : "1 ชั่วโมง",
- hh : "%d ชั่วโมง",
- d : "1 วัน",
- dd : "%d วัน",
- M : "1 เดือน",
- MM : "%d เดือน",
- y : "1 ปี",
- yy : "%d ปี"
- }
- });
- }));
+ }
+ return idArray;
+ };
-/***/ },
-/* 119 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * select zero or more nodes
+ * @param {Number[] | String[]} selection An array with the ids of the
+ * selected nodes.
+ */
+ exports.setSelection = function(selection) {
+ var i, iMax, id;
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Tagalog/Filipino (tl-ph)
- // author : Dan Hagman
+ if (!selection || (selection.length == undefined))
+ throw 'Selection must be an array with ids';
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // first unselect any selected node
+ this._unselectAll(true);
+
+ for (i = 0, iMax = selection.length; i < iMax; i++) {
+ id = selection[i];
+
+ var node = this.nodes[id];
+ if (!node) {
+ throw new RangeError('Node with id "' + id + '" not found');
}
- }(function (moment) {
- return moment.lang('tl-ph', {
- months : "Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),
- monthsShort : "Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),
- weekdays : "Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),
- weekdaysShort : "Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),
- weekdaysMin : "Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "MM/D/YYYY",
- LL : "MMMM D, YYYY",
- LLL : "MMMM D, YYYY LT",
- LLLL : "dddd, MMMM DD, YYYY LT"
- },
- calendar : {
- sameDay: "[Ngayon sa] LT",
- nextDay: '[Bukas sa] LT',
- nextWeek: 'dddd [sa] LT',
- lastDay: '[Kahapon sa] LT',
- lastWeek: 'dddd [huling linggo] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "sa loob ng %s",
- past : "%s ang nakalipas",
- s : "ilang segundo",
- m : "isang minuto",
- mm : "%d minuto",
- h : "isang oras",
- hh : "%d oras",
- d : "isang araw",
- dd : "%d araw",
- M : "isang buwan",
- MM : "%d buwan",
- y : "isang taon",
- yy : "%d taon"
- },
- ordinal : function (number) {
- return number;
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ this._selectObject(node,true,true);
+ }
+ console.log("setSelection is deprecated. Please use selectNodes instead.")
-/***/ },
-/* 120 */
-/***/ function(module, exports, __webpack_require__) {
+ this.redraw();
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : turkish (tr)
- // authors : Erhan Gundogan : https://github.com/erhangundogan,
- // Burak Yiğit Kaya: https://github.com/BYK
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
+ /**
+ * select zero or more nodes with the option to highlight edges
+ * @param {Number[] | String[]} selection An array with the ids of the
+ * selected nodes.
+ * @param {boolean} [highlightEdges]
+ */
+ exports.selectNodes = function(selection, highlightEdges) {
+ var i, iMax, id;
- var suffixes = {
- 1: "'inci",
- 5: "'inci",
- 8: "'inci",
- 70: "'inci",
- 80: "'inci",
+ if (!selection || (selection.length == undefined))
+ throw 'Selection must be an array with ids';
- 2: "'nci",
- 7: "'nci",
- 20: "'nci",
- 50: "'nci",
+ // first unselect any selected node
+ this._unselectAll(true);
- 3: "'üncü",
- 4: "'üncü",
- 100: "'üncü",
+ for (i = 0, iMax = selection.length; i < iMax; i++) {
+ id = selection[i];
- 6: "'ncı",
+ var node = this.nodes[id];
+ if (!node) {
+ throw new RangeError('Node with id "' + id + '" not found');
+ }
+ this._selectObject(node,true,true,highlightEdges);
+ }
+ this.redraw();
+ };
- 9: "'uncu",
- 10: "'uncu",
- 30: "'uncu",
- 60: "'ıncı",
- 90: "'ıncı"
- };
+ /**
+ * select zero or more edges
+ * @param {Number[] | String[]} selection An array with the ids of the
+ * selected nodes.
+ */
+ exports.selectEdges = function(selection) {
+ var i, iMax, id;
- return moment.lang('tr', {
- months : "Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),
- monthsShort : "Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),
- weekdays : "Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),
- weekdaysShort : "Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),
- weekdaysMin : "Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd, D MMMM YYYY LT"
- },
- calendar : {
- sameDay : '[bugün saat] LT',
- nextDay : '[yarın saat] LT',
- nextWeek : '[haftaya] dddd [saat] LT',
- lastDay : '[dün] LT',
- lastWeek : '[geçen hafta] dddd [saat] LT',
- sameElse : 'L'
- },
- relativeTime : {
- future : "%s sonra",
- past : "%s önce",
- s : "birkaç saniye",
- m : "bir dakika",
- mm : "%d dakika",
- h : "bir saat",
- hh : "%d saat",
- d : "bir gün",
- dd : "%d gün",
- M : "bir ay",
- MM : "%d ay",
- y : "bir yıl",
- yy : "%d yıl"
- },
- ordinal : function (number) {
- if (number === 0) { // special case for zero
- return number + "'ıncı";
- }
- var a = number % 10,
- b = number % 100 - a,
- c = number >= 100 ? 100 : null;
+ if (!selection || (selection.length == undefined))
+ throw 'Selection must be an array with ids';
- return number + (suffixes[a] || suffixes[b] || suffixes[c]);
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ // first unselect any selected node
+ this._unselectAll(true);
+
+ for (i = 0, iMax = selection.length; i < iMax; i++) {
+ id = selection[i];
+
+ var edge = this.edges[id];
+ if (!edge) {
+ throw new RangeError('Edge with id "' + id + '" not found');
+ }
+ this._selectObject(edge,true,true,highlightEdges);
+ }
+ this.redraw();
+ };
+
+ /**
+ * Validate the selection: remove ids of nodes which no longer exist
+ * @private
+ */
+ exports._updateSelection = function () {
+ for(var nodeId in this.selectionObj.nodes) {
+ if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
+ if (!this.nodes.hasOwnProperty(nodeId)) {
+ delete this.selectionObj.nodes[nodeId];
+ }
+ }
+ }
+ for(var edgeId in this.selectionObj.edges) {
+ if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
+ if (!this.edges.hasOwnProperty(edgeId)) {
+ delete this.selectionObj.edges[edgeId];
+ }
+ }
+ }
+ };
/***/ },
-/* 121 */
+/* 127 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
- // author : Abdel Said : https://github.com/abdelsaid
+ var util = __webpack_require__(1);
+ var Node = __webpack_require__(39);
+ var Edge = __webpack_require__(38);
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ /**
+ * clears the toolbar div element of children
+ *
+ * @private
+ */
+ exports._clearManipulatorBar = function() {
+ while (this.manipulationDiv.hasChildNodes()) {
+ this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);
+ }
+ };
+
+ /**
+ * Manipulation UI temporarily overloads certain functions to extend or replace them. To be able to restore
+ * these functions to their original functionality, we saved them in this.cachedFunctions.
+ * This function restores these functions to their original function.
+ *
+ * @private
+ */
+ exports._restoreOverloadedFunctions = function() {
+ for (var functionName in this.cachedFunctions) {
+ if (this.cachedFunctions.hasOwnProperty(functionName)) {
+ this[functionName] = this.cachedFunctions[functionName];
}
- }(function (moment) {
- return moment.lang('tzm-latn', {
- months : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),
- monthsShort : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),
- weekdays : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
- weekdaysShort : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
- weekdaysMin : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[asdkh g] LT",
- nextDay: '[aska g] LT',
- nextWeek: 'dddd [g] LT',
- lastDay: '[assant g] LT',
- lastWeek: 'dddd [g] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "dadkh s yan %s",
- past : "yan %s",
- s : "imik",
- m : "minuḍ",
- mm : "%d minuḍ",
- h : "saɛa",
- hh : "%d tassaɛin",
- d : "ass",
- dd : "%d ossan",
- M : "ayowr",
- MM : "%d iyyirn",
- y : "asgas",
- yy : "%d isgasn"
- },
- week : {
- dow : 6, // Saturday is the first day of the week.
- doy : 12 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ }
+ };
+
+ /**
+ * Enable or disable edit-mode.
+ *
+ * @private
+ */
+ exports._toggleEditMode = function() {
+ this.editMode = !this.editMode;
+ var toolbar = document.getElementById("network-manipulationDiv");
+ var closeDiv = document.getElementById("network-manipulation-closeDiv");
+ var editModeDiv = document.getElementById("network-manipulation-editMode");
+ if (this.editMode == true) {
+ toolbar.style.display="block";
+ closeDiv.style.display="block";
+ editModeDiv.style.display="none";
+ closeDiv.onclick = this._toggleEditMode.bind(this);
+ }
+ else {
+ toolbar.style.display="none";
+ closeDiv.style.display="none";
+ editModeDiv.style.display="block";
+ closeDiv.onclick = null;
+ }
+ this._createManipulatorBar()
+ };
+ /**
+ * main function, creates the main toolbar. Removes functions bound to the select event. Binds all the buttons of the toolbar.
+ *
+ * @private
+ */
+ exports._createManipulatorBar = function() {
+ // remove bound functions
+ if (this.boundFunction) {
+ this.off('select', this.boundFunction);
+ }
-/***/ },
-/* 122 */
-/***/ function(module, exports, __webpack_require__) {
+ if (this.edgeBeingEdited !== undefined) {
+ this.edgeBeingEdited._disableControlNodes();
+ this.edgeBeingEdited = undefined;
+ this.selectedControlNode = null;
+ this.controlNodesActive = false;
+ }
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : Morocco Central Atlas Tamaziɣt (tzm)
- // author : Abdel Said : https://github.com/abdelsaid
+ // restore overloaded functions
+ this._restoreOverloadedFunctions();
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('tzm', {
- months : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),
- monthsShort : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),
- weekdays : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),
- weekdaysShort : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),
- weekdaysMin : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "dddd D MMMM YYYY LT"
- },
- calendar : {
- sameDay: "[ⴰⵙⴷⵅ ⴴ] LT",
- nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',
- nextWeek: 'dddd [ⴴ] LT',
- lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',
- lastWeek: 'dddd [ⴴ] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s",
- past : "ⵢⴰⵏ %s",
- s : "ⵉⵎⵉⴽ",
- m : "ⵎⵉⵏⵓⴺ",
- mm : "%d ⵎⵉⵏⵓⴺ",
- h : "ⵙⴰⵄⴰ",
- hh : "%d ⵜⴰⵙⵙⴰⵄⵉⵏ",
- d : "ⴰⵙⵙ",
- dd : "%d oⵙⵙⴰⵏ",
- M : "ⴰⵢoⵓⵔ",
- MM : "%d ⵉⵢⵢⵉⵔⵏ",
- y : "ⴰⵙⴳⴰⵙ",
- yy : "%d ⵉⵙⴳⴰⵙⵏ"
- },
- week : {
- dow : 6, // Saturday is the first day of the week.
- doy : 12 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ // resume calculation
+ this.freezeSimulation = false;
+ // reset global variables
+ this.blockConnectingEdgeSelection = false;
+ this.forceAppendSelection = false;
-/***/ },
-/* 123 */
-/***/ function(module, exports, __webpack_require__) {
+ if (this.editMode == true) {
+ while (this.manipulationDiv.hasChildNodes()) {
+ this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);
+ }
+ // add the icons to the manipulator div
+ this.manipulationDiv.innerHTML = "" +
+ "" +
+ ""+this.constants.labels['add'] +"" +
+ "" +
+ "" +
+ ""+this.constants.labels['link'] +"";
+ if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) {
+ this.manipulationDiv.innerHTML += "" +
+ "" +
+ "" +
+ ""+this.constants.labels['editNode'] +"";
+ }
+ else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) {
+ this.manipulationDiv.innerHTML += "" +
+ "" +
+ "" +
+ ""+this.constants.labels['editEdge'] +"";
+ }
+ if (this._selectionIsEmpty() == false) {
+ this.manipulationDiv.innerHTML += "" +
+ "" +
+ "" +
+ ""+this.constants.labels['del'] +"";
+ }
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : ukrainian (uk)
- // author : zemlanin : https://github.com/zemlanin
- // Author : Menelion Elensúle : https://github.com/Oire
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ // bind the icons
+ var addNodeButton = document.getElementById("network-manipulate-addNode");
+ addNodeButton.onclick = this._createAddNodeToolbar.bind(this);
+ var addEdgeButton = document.getElementById("network-manipulate-connectNode");
+ addEdgeButton.onclick = this._createAddEdgeToolbar.bind(this);
+ if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) {
+ var editButton = document.getElementById("network-manipulate-editNode");
+ editButton.onclick = this._editNode.bind(this);
}
- }(function (moment) {
- function plural(word, num) {
- var forms = word.split('_');
- return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
+ else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) {
+ var editButton = document.getElementById("network-manipulate-editEdge");
+ editButton.onclick = this._createEditEdgeToolbar.bind(this);
}
-
- function relativeTimeWithPlural(number, withoutSuffix, key) {
- var format = {
- 'mm': 'хвилина_хвилини_хвилин',
- 'hh': 'година_години_годин',
- 'dd': 'день_дні_днів',
- 'MM': 'місяць_місяці_місяців',
- 'yy': 'рік_роки_років'
- };
- if (key === 'm') {
- return withoutSuffix ? 'хвилина' : 'хвилину';
- }
- else if (key === 'h') {
- return withoutSuffix ? 'година' : 'годину';
- }
- else {
- return number + ' ' + plural(format[key], +number);
- }
+ if (this._selectionIsEmpty() == false) {
+ var deleteButton = document.getElementById("network-manipulate-delete");
+ deleteButton.onclick = this._deleteSelected.bind(this);
}
+ var closeDiv = document.getElementById("network-manipulation-closeDiv");
+ closeDiv.onclick = this._toggleEditMode.bind(this);
- function monthsCaseReplace(m, format) {
- var months = {
- 'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),
- 'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')
- },
+ this.boundFunction = this._createManipulatorBar.bind(this);
+ this.on('select', this.boundFunction);
+ }
+ else {
+ this.editModeDiv.innerHTML = "" +
+ "" +
+ "" + this.constants.labels['edit'] + "";
+ var editModeButton = document.getElementById("network-manipulate-editModeButton");
+ editModeButton.onclick = this._toggleEditMode.bind(this);
+ }
+ };
- nounCase = (/D[oD]? *MMMM?/).test(format) ?
- 'accusative' :
- 'nominative';
- return months[nounCase][m.month()];
- }
- function weekdaysCaseReplace(m, format) {
- var weekdays = {
- 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
- 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
- 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
- },
+ /**
+ * Create the toolbar for adding Nodes
+ *
+ * @private
+ */
+ exports._createAddNodeToolbar = function() {
+ // clear the toolbar
+ this._clearManipulatorBar();
+ if (this.boundFunction) {
+ this.off('select', this.boundFunction);
+ }
- nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
- 'accusative' :
- ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
- 'genitive' :
- 'nominative');
+ // create the toolbar contents
+ this.manipulationDiv.innerHTML = "" +
+ "" +
+ "" + this.constants.labels['back'] + " " +
+ "" +
+ "" +
+ "" + this.constants.labels['addDescription'] + "";
- return weekdays[nounCase][m.day()];
- }
+ // bind the icon
+ var backButton = document.getElementById("network-manipulate-back");
+ backButton.onclick = this._createManipulatorBar.bind(this);
- function processHoursFunction(str) {
- return function () {
- return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
- };
- }
+ // we use the boundFunction so we can reference it when we unbind it from the "select" event.
+ this.boundFunction = this._addNode.bind(this);
+ this.on('select', this.boundFunction);
+ };
- return moment.lang('uk', {
- months : monthsCaseReplace,
- monthsShort : "січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),
- weekdays : weekdaysCaseReplace,
- weekdaysShort : "нд_пн_вт_ср_чт_пт_сб".split("_"),
- weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD.MM.YYYY",
- LL : "D MMMM YYYY р.",
- LLL : "D MMMM YYYY р., LT",
- LLLL : "dddd, D MMMM YYYY р., LT"
- },
- calendar : {
- sameDay: processHoursFunction('[Сьогодні '),
- nextDay: processHoursFunction('[Завтра '),
- lastDay: processHoursFunction('[Вчора '),
- nextWeek: processHoursFunction('[У] dddd ['),
- lastWeek: function () {
- switch (this.day()) {
- case 0:
- case 3:
- case 5:
- case 6:
- return processHoursFunction('[Минулої] dddd [').call(this);
- case 1:
- case 2:
- case 4:
- return processHoursFunction('[Минулого] dddd [').call(this);
- }
- },
- sameElse: 'L'
- },
- relativeTime : {
- future : "за %s",
- past : "%s тому",
- s : "декілька секунд",
- m : relativeTimeWithPlural,
- mm : relativeTimeWithPlural,
- h : "годину",
- hh : relativeTimeWithPlural,
- d : "день",
- dd : relativeTimeWithPlural,
- M : "місяць",
- MM : relativeTimeWithPlural,
- y : "рік",
- yy : relativeTimeWithPlural
- },
- // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
+ /**
+ * create the toolbar to connect nodes
+ *
+ * @private
+ */
+ exports._createAddEdgeToolbar = function() {
+ // clear the toolbar
+ this._clearManipulatorBar();
+ this._unselectAll(true);
+ this.freezeSimulation = true;
- meridiem : function (hour, minute, isLower) {
- if (hour < 4) {
- return "ночі";
- } else if (hour < 12) {
- return "ранку";
- } else if (hour < 17) {
- return "дня";
- } else {
- return "вечора";
- }
- },
+ if (this.boundFunction) {
+ this.off('select', this.boundFunction);
+ }
- ordinal: function (number, period) {
- switch (period) {
- case 'M':
- case 'd':
- case 'DDD':
- case 'w':
- case 'W':
- return number + '-й';
- case 'D':
- return number + '-го';
- default:
- return number;
- }
- },
+ this._unselectAll();
+ this.forceAppendSelection = false;
+ this.blockConnectingEdgeSelection = true;
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 1st is the first week of the year.
- }
- });
- }));
+ this.manipulationDiv.innerHTML = "" +
+ "" +
+ "" + this.constants.labels['back'] + " " +
+ "" +
+ "" +
+ "" + this.constants.labels['linkDescription'] + "";
+ // bind the icon
+ var backButton = document.getElementById("network-manipulate-back");
+ backButton.onclick = this._createManipulatorBar.bind(this);
-/***/ },
-/* 124 */
-/***/ function(module, exports, __webpack_require__) {
+ // we use the boundFunction so we can reference it when we unbind it from the "select" event.
+ this.boundFunction = this._handleConnect.bind(this);
+ this.on('select', this.boundFunction);
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : uzbek
- // author : Sardor Muminov : https://github.com/muminoff
+ // temporarily overload functions
+ this.cachedFunctions["_handleTouch"] = this._handleTouch;
+ this.cachedFunctions["_handleOnRelease"] = this._handleOnRelease;
+ this._handleTouch = this._handleConnect;
+ this._handleOnRelease = this._finishConnect;
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('uz', {
- months : "январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),
- monthsShort : "янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),
- weekdays : "Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"),
- weekdaysShort : "Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"),
- weekdaysMin : "Як_Ду_Се_Чо_Па_Жу_Ша".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM YYYY",
- LLL : "D MMMM YYYY LT",
- LLLL : "D MMMM YYYY, dddd LT"
- },
- calendar : {
- sameDay : '[Бугун соат] LT [да]',
- nextDay : '[Эртага] LT [да]',
- nextWeek : 'dddd [куни соат] LT [да]',
- lastDay : '[Кеча соат] LT [да]',
- lastWeek : '[Утган] dddd [куни соат] LT [да]',
- sameElse : 'L'
- },
- relativeTime : {
- future : "Якин %s ичида",
- past : "Бир неча %s олдин",
- s : "фурсат",
- m : "бир дакика",
- mm : "%d дакика",
- h : "бир соат",
- hh : "%d соат",
- d : "бир кун",
- dd : "%d кун",
- M : "бир ой",
- MM : "%d ой",
- y : "бир йил",
- yy : "%d йил"
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 7 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ // redraw to show the unselect
+ this._redraw();
+ };
+ /**
+ * create the toolbar to edit edges
+ *
+ * @private
+ */
+ exports._createEditEdgeToolbar = function() {
+ // clear the toolbar
+ this._clearManipulatorBar();
+ this.controlNodesActive = true;
-/***/ },
-/* 125 */
-/***/ function(module, exports, __webpack_require__) {
+ if (this.boundFunction) {
+ this.off('select', this.boundFunction);
+ }
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : vietnamese (vi)
- // author : Bang Nguyen : https://github.com/bangnk
+ this.edgeBeingEdited = this._getSelectedEdge();
+ this.edgeBeingEdited._enableControlNodes();
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('vi', {
- months : "tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),
- monthsShort : "Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),
- weekdays : "chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),
- weekdaysShort : "CN_T2_T3_T4_T5_T6_T7".split("_"),
- weekdaysMin : "CN_T2_T3_T4_T5_T6_T7".split("_"),
- longDateFormat : {
- LT : "HH:mm",
- L : "DD/MM/YYYY",
- LL : "D MMMM [năm] YYYY",
- LLL : "D MMMM [năm] YYYY LT",
- LLLL : "dddd, D MMMM [năm] YYYY LT",
- l : "DD/M/YYYY",
- ll : "D MMM YYYY",
- lll : "D MMM YYYY LT",
- llll : "ddd, D MMM YYYY LT"
- },
- calendar : {
- sameDay: "[Hôm nay lúc] LT",
- nextDay: '[Ngày mai lúc] LT',
- nextWeek: 'dddd [tuần tới lúc] LT',
- lastDay: '[Hôm qua lúc] LT',
- lastWeek: 'dddd [tuần rồi lúc] LT',
- sameElse: 'L'
- },
- relativeTime : {
- future : "%s tới",
- past : "%s trước",
- s : "vài giây",
- m : "một phút",
- mm : "%d phút",
- h : "một giờ",
- hh : "%d giờ",
- d : "một ngày",
- dd : "%d ngày",
- M : "một tháng",
- MM : "%d tháng",
- y : "một năm",
- yy : "%d năm"
- },
- ordinal : function (number) {
- return number;
- },
- week : {
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
+ this.manipulationDiv.innerHTML = "" +
+ "" +
+ "" + this.constants.labels['back'] + " " +
+ "" +
+ "" +
+ "" + this.constants.labels['editEdgeDescription'] + "";
+
+ // bind the icon
+ var backButton = document.getElementById("network-manipulate-back");
+ backButton.onclick = this._createManipulatorBar.bind(this);
+
+ // temporarily overload functions
+ this.cachedFunctions["_handleTouch"] = this._handleTouch;
+ this.cachedFunctions["_handleOnRelease"] = this._handleOnRelease;
+ this.cachedFunctions["_handleTap"] = this._handleTap;
+ this.cachedFunctions["_handleDragStart"] = this._handleDragStart;
+ this.cachedFunctions["_handleOnDrag"] = this._handleOnDrag;
+ this._handleTouch = this._selectControlNode;
+ this._handleTap = function () {};
+ this._handleOnDrag = this._controlNodeDrag;
+ this._handleDragStart = function () {}
+ this._handleOnRelease = this._releaseControlNode;
+ // redraw to show the unselect
+ this._redraw();
+ };
-/***/ },
-/* 126 */
-/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : chinese
- // author : suupic : https://github.com/suupic
- // author : Zeno Zeng : https://github.com/zenozeng
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
- }
- }(function (moment) {
- return moment.lang('zh-cn', {
- months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
- monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
- weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
- weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"),
- weekdaysMin : "日_一_二_三_四_五_六".split("_"),
- longDateFormat : {
- LT : "Ah点mm",
- L : "YYYY-MM-DD",
- LL : "YYYY年MMMD日",
- LLL : "YYYY年MMMD日LT",
- LLLL : "YYYY年MMMD日ddddLT",
- l : "YYYY-MM-DD",
- ll : "YYYY年MMMD日",
- lll : "YYYY年MMMD日LT",
- llll : "YYYY年MMMD日ddddLT"
- },
- meridiem : function (hour, minute, isLower) {
- var hm = hour * 100 + minute;
- if (hm < 600) {
- return "凌晨";
- } else if (hm < 900) {
- return "早上";
- } else if (hm < 1130) {
- return "上午";
- } else if (hm < 1230) {
- return "中午";
- } else if (hm < 1800) {
- return "下午";
- } else {
- return "晚上";
- }
- },
- calendar : {
- sameDay : function () {
- return this.minutes() === 0 ? "[今天]Ah[点整]" : "[今天]LT";
- },
- nextDay : function () {
- return this.minutes() === 0 ? "[明天]Ah[点整]" : "[明天]LT";
- },
- lastDay : function () {
- return this.minutes() === 0 ? "[昨天]Ah[点整]" : "[昨天]LT";
- },
- nextWeek : function () {
- var startOfWeek, prefix;
- startOfWeek = moment().startOf('week');
- prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';
- return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm";
- },
- lastWeek : function () {
- var startOfWeek, prefix;
- startOfWeek = moment().startOf('week');
- prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]';
- return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm";
- },
- sameElse : 'LL'
- },
- ordinal : function (number, period) {
- switch (period) {
- case "d":
- case "D":
- case "DDD":
- return number + "日";
- case "M":
- return number + "月";
- case "w":
- case "W":
- return number + "周";
- default:
- return number;
- }
- },
- relativeTime : {
- future : "%s内",
- past : "%s前",
- s : "几秒",
- m : "1分钟",
- mm : "%d分钟",
- h : "1小时",
- hh : "%d小时",
- d : "1天",
- dd : "%d天",
- M : "1个月",
- MM : "%d个月",
- y : "1年",
- yy : "%d年"
- },
- week : {
- // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
- dow : 1, // Monday is the first day of the week.
- doy : 4 // The week that contains Jan 4th is the first week of the year.
- }
- });
- }));
-/***/ },
-/* 127 */
-/***/ function(module, exports, __webpack_require__) {
+ /**
+ * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
+ * to walk the user through the process.
+ *
+ * @private
+ */
+ exports._selectControlNode = function(pointer) {
+ this.edgeBeingEdited.controlNodes.from.unselect();
+ this.edgeBeingEdited.controlNodes.to.unselect();
+ this.selectedControlNode = this.edgeBeingEdited._getSelectedControlNode(this._XconvertDOMtoCanvas(pointer.x),this._YconvertDOMtoCanvas(pointer.y));
+ if (this.selectedControlNode !== null) {
+ this.selectedControlNode.select();
+ this.freezeSimulation = true;
+ }
+ this._redraw();
+ };
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// moment.js language configuration
- // language : traditional chinese (zh-tw)
- // author : Ben : https://github.com/ben-lin
+ /**
+ * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
+ * to walk the user through the process.
+ *
+ * @private
+ */
+ exports._controlNodeDrag = function(event) {
+ var pointer = this._getPointer(event.gesture.center);
+ if (this.selectedControlNode !== null && this.selectedControlNode !== undefined) {
+ this.selectedControlNode.x = this._XconvertDOMtoCanvas(pointer.x);
+ this.selectedControlNode.y = this._YconvertDOMtoCanvas(pointer.y);
+ }
+ this._redraw();
+ };
- (function (factory) {
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = (factory.apply(null, __WEBPACK_AMD_DEFINE_ARRAY__)), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // AMD
- } else if (typeof exports === 'object') {
- module.exports = factory(require('../moment')); // Node
- } else {
- factory(window.moment); // Browser global
+ exports._releaseControlNode = function(pointer) {
+ var newNode = this._getNodeAt(pointer);
+ if (newNode != null) {
+ if (this.edgeBeingEdited.controlNodes.from.selected == true) {
+ this._editEdge(newNode.id, this.edgeBeingEdited.to.id);
+ this.edgeBeingEdited.controlNodes.from.unselect();
}
- }(function (moment) {
- return moment.lang('zh-tw', {
- months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
- monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
- weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
- weekdaysShort : "週日_週一_週二_週三_週四_週五_週六".split("_"),
- weekdaysMin : "日_一_二_三_四_五_六".split("_"),
- longDateFormat : {
- LT : "Ah點mm",
- L : "YYYY年MMMD日",
- LL : "YYYY年MMMD日",
- LLL : "YYYY年MMMD日LT",
- LLLL : "YYYY年MMMD日ddddLT",
- l : "YYYY年MMMD日",
- ll : "YYYY年MMMD日",
- lll : "YYYY年MMMD日LT",
- llll : "YYYY年MMMD日ddddLT"
- },
- meridiem : function (hour, minute, isLower) {
- var hm = hour * 100 + minute;
- if (hm < 900) {
- return "早上";
- } else if (hm < 1130) {
- return "上午";
- } else if (hm < 1230) {
- return "中午";
- } else if (hm < 1800) {
- return "下午";
- } else {
- return "晚上";
- }
- },
- calendar : {
- sameDay : '[今天]LT',
- nextDay : '[明天]LT',
- nextWeek : '[下]ddddLT',
- lastDay : '[昨天]LT',
- lastWeek : '[上]ddddLT',
- sameElse : 'L'
- },
- ordinal : function (number, period) {
- switch (period) {
- case "d" :
- case "D" :
- case "DDD" :
- return number + "日";
- case "M" :
- return number + "月";
- case "w" :
- case "W" :
- return number + "週";
- default :
- return number;
- }
- },
- relativeTime : {
- future : "%s內",
- past : "%s前",
- s : "幾秒",
- m : "一分鐘",
- mm : "%d分鐘",
- h : "一小時",
- hh : "%d小時",
- d : "一天",
- dd : "%d天",
- M : "一個月",
- MM : "%d個月",
- y : "一年",
- yy : "%d年"
- }
- });
- }));
-
-
-/***/ },
-/* 128 */
-/***/ function(module, exports, __webpack_require__) {
+ if (this.edgeBeingEdited.controlNodes.to.selected == true) {
+ this._editEdge(this.edgeBeingEdited.from.id, newNode.id);
+ this.edgeBeingEdited.controlNodes.to.unselect();
+ }
+ }
+ else {
+ this.edgeBeingEdited._restoreControlNodes();
+ }
+ this.freezeSimulation = false;
+ this._redraw();
+ };
/**
- * Calculate the forces the nodes apply on each other based on a repulsion field.
- * This field is linearly approximated.
+ * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
+ * to walk the user through the process.
*
* @private
*/
- exports._calculateNodeForces = function () {
- var dx, dy, angle, distance, fx, fy, combinedClusterSize,
- repulsingForce, node1, node2, i, j;
+ exports._handleConnect = function(pointer) {
+ if (this._getSelectedNodeCount() == 0) {
+ var node = this._getNodeAt(pointer);
+ if (node != null) {
+ if (node.clusterSize > 1) {
+ alert("Cannot create edges to a cluster.")
+ }
+ else {
+ this._selectObject(node,false);
+ // create a node the temporary line can look at
+ this.sectors['support']['nodes']['targetNode'] = new Node({id:'targetNode'},{},{},this.constants);
+ this.sectors['support']['nodes']['targetNode'].x = node.x;
+ this.sectors['support']['nodes']['targetNode'].y = node.y;
+ this.sectors['support']['nodes']['targetViaNode'] = new Node({id:'targetViaNode'},{},{},this.constants);
+ this.sectors['support']['nodes']['targetViaNode'].x = node.x;
+ this.sectors['support']['nodes']['targetViaNode'].y = node.y;
+ this.sectors['support']['nodes']['targetViaNode'].parentEdgeId = "connectionEdge";
- var nodes = this.calculationNodes;
- var nodeIndices = this.calculationNodeIndices;
+ // create a temporary edge
+ this.edges['connectionEdge'] = new Edge({id:"connectionEdge",from:node.id,to:this.sectors['support']['nodes']['targetNode'].id}, this, this.constants);
+ this.edges['connectionEdge'].from = node;
+ this.edges['connectionEdge'].connected = true;
+ this.edges['connectionEdge'].smooth = true;
+ this.edges['connectionEdge'].selected = true;
+ this.edges['connectionEdge'].to = this.sectors['support']['nodes']['targetNode'];
+ this.edges['connectionEdge'].via = this.sectors['support']['nodes']['targetViaNode'];
- // approximation constants
- var a_base = -2 / 3;
- var b = 4 / 3;
+ this.cachedFunctions["_handleOnDrag"] = this._handleOnDrag;
+ this._handleOnDrag = function(event) {
+ var pointer = this._getPointer(event.gesture.center);
+ this.sectors['support']['nodes']['targetNode'].x = this._XconvertDOMtoCanvas(pointer.x);
+ this.sectors['support']['nodes']['targetNode'].y = this._YconvertDOMtoCanvas(pointer.y);
+ this.sectors['support']['nodes']['targetViaNode'].x = 0.5 * (this._XconvertDOMtoCanvas(pointer.x) + this.edges['connectionEdge'].from.x);
+ this.sectors['support']['nodes']['targetViaNode'].y = this._YconvertDOMtoCanvas(pointer.y);
+ };
- // repulsing forces between nodes
- var nodeDistance = this.constants.physics.repulsion.nodeDistance;
- var minimumDistance = nodeDistance;
+ this.moving = true;
+ this.start();
+ }
+ }
+ }
+ };
- // we loop from i over all but the last entree in the array
- // j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j
- for (i = 0; i < nodeIndices.length - 1; i++) {
- node1 = nodes[nodeIndices[i]];
- for (j = i + 1; j < nodeIndices.length; j++) {
- node2 = nodes[nodeIndices[j]];
- combinedClusterSize = node1.clusterSize + node2.clusterSize - 2;
+ exports._finishConnect = function(pointer) {
+ if (this._getSelectedNodeCount() == 1) {
- dx = node2.x - node1.x;
- dy = node2.y - node1.y;
- distance = Math.sqrt(dx * dx + dy * dy);
+ // restore the drag function
+ this._handleOnDrag = this.cachedFunctions["_handleOnDrag"];
+ delete this.cachedFunctions["_handleOnDrag"];
- minimumDistance = (combinedClusterSize == 0) ? nodeDistance : (nodeDistance * (1 + combinedClusterSize * this.constants.clustering.distanceAmplification));
- var a = a_base / minimumDistance;
- if (distance < 2 * minimumDistance) {
- if (distance < 0.5 * minimumDistance) {
- repulsingForce = 1.0;
- }
- else {
- repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / minimumDistance - 1) * steepness))
+ // remember the edge id
+ var connectFromId = this.edges['connectionEdge'].fromId;
+
+ // remove the temporary nodes and edge
+ delete this.edges['connectionEdge'];
+ delete this.sectors['support']['nodes']['targetNode'];
+ delete this.sectors['support']['nodes']['targetViaNode'];
+
+ var node = this._getNodeAt(pointer);
+ if (node != null) {
+ if (node.clusterSize > 1) {
+ alert("Cannot create edges to a cluster.")
+ }
+ else {
+ this._createEdge(connectFromId,node.id);
+ this._createManipulatorBar();
+ }
+ }
+ this._unselectAll();
+ }
+ };
+
+
+ /**
+ * Adds a node on the specified location
+ */
+ exports._addNode = function() {
+ if (this._selectionIsEmpty() && this.editMode == true) {
+ var positionObject = this._pointerToPositionObject(this.pointerPosition);
+ var defaultData = {id:util.randomUUID(),x:positionObject.left,y:positionObject.top,label:"new",allowedToMoveX:true,allowedToMoveY:true};
+ if (this.triggerFunctions.add) {
+ if (this.triggerFunctions.add.length == 2) {
+ var me = this;
+ this.triggerFunctions.add(defaultData, function(finalizedData) {
+ me.nodesData.add(finalizedData);
+ me._createManipulatorBar();
+ me.moving = true;
+ me.start();
+ });
+ }
+ else {
+ alert(this.constants.labels['addError']);
+ this._createManipulatorBar();
+ this.moving = true;
+ this.start();
+ }
+ }
+ else {
+ this.nodesData.add(defaultData);
+ this._createManipulatorBar();
+ this.moving = true;
+ this.start();
+ }
+ }
+ };
+
+
+ /**
+ * connect two nodes with a new edge.
+ *
+ * @private
+ */
+ exports._createEdge = function(sourceNodeId,targetNodeId) {
+ if (this.editMode == true) {
+ var defaultData = {from:sourceNodeId, to:targetNodeId};
+ if (this.triggerFunctions.connect) {
+ if (this.triggerFunctions.connect.length == 2) {
+ var me = this;
+ this.triggerFunctions.connect(defaultData, function(finalizedData) {
+ me.edgesData.add(finalizedData);
+ me.moving = true;
+ me.start();
+ });
+ }
+ else {
+ alert(this.constants.labels["linkError"]);
+ this.moving = true;
+ this.start();
+ }
+ }
+ else {
+ this.edgesData.add(defaultData);
+ this.moving = true;
+ this.start();
+ }
+ }
+ };
+
+ /**
+ * connect two nodes with a new edge.
+ *
+ * @private
+ */
+ exports._editEdge = function(sourceNodeId,targetNodeId) {
+ if (this.editMode == true) {
+ var defaultData = {id: this.edgeBeingEdited.id, from:sourceNodeId, to:targetNodeId};
+ if (this.triggerFunctions.editEdge) {
+ if (this.triggerFunctions.editEdge.length == 2) {
+ var me = this;
+ this.triggerFunctions.editEdge(defaultData, function(finalizedData) {
+ me.edgesData.update(finalizedData);
+ me.moving = true;
+ me.start();
+ });
+ }
+ else {
+ alert(this.constants.labels["linkError"]);
+ this.moving = true;
+ this.start();
+ }
+ }
+ else {
+ this.edgesData.update(defaultData);
+ this.moving = true;
+ this.start();
+ }
+ }
+ };
+
+ /**
+ * Create the toolbar to edit the selected node. The label and the color can be changed. Other colors are derived from the chosen color.
+ *
+ * @private
+ */
+ exports._editNode = function() {
+ if (this.triggerFunctions.edit && this.editMode == true) {
+ var node = this._getSelectedNode();
+ var data = {id:node.id,
+ label: node.label,
+ group: node.group,
+ shape: node.shape,
+ color: {
+ background:node.color.background,
+ border:node.color.border,
+ highlight: {
+ background:node.color.highlight.background,
+ border:node.color.highlight.border
}
+ }};
+ if (this.triggerFunctions.edit.length == 2) {
+ var me = this;
+ this.triggerFunctions.edit(data, function (finalizedData) {
+ me.nodesData.update(finalizedData);
+ me._createManipulatorBar();
+ me.moving = true;
+ me.start();
+ });
+ }
+ else {
+ alert(this.constants.labels["editError"]);
+ }
+ }
+ else {
+ alert(this.constants.labels["editBoundError"]);
+ }
+ };
- // amplify the repulsion for clusters.
- repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification;
- repulsingForce = repulsingForce / distance;
- fx = dx * repulsingForce;
- fy = dy * repulsingForce;
- node1.fx -= fx;
- node1.fy -= fy;
- node2.fx += fx;
- node2.fy += fy;
+
+ /**
+ * delete everything in the selection
+ *
+ * @private
+ */
+ exports._deleteSelected = function() {
+ if (!this._selectionIsEmpty() && this.editMode == true) {
+ if (!this._clusterInSelection()) {
+ var selectedNodes = this.getSelectedNodes();
+ var selectedEdges = this.getSelectedEdges();
+ if (this.triggerFunctions.del) {
+ var me = this;
+ var data = {nodes: selectedNodes, edges: selectedEdges};
+ if (this.triggerFunctions.del.length = 2) {
+ this.triggerFunctions.del(data, function (finalizedData) {
+ me.edgesData.remove(finalizedData.edges);
+ me.nodesData.remove(finalizedData.nodes);
+ me._unselectAll();
+ me.moving = true;
+ me.start();
+ });
+ }
+ else {
+ alert(this.constants.labels["deleteError"])
+ }
+ }
+ else {
+ this.edgesData.remove(selectedEdges);
+ this.nodesData.remove(selectedNodes);
+ this._unselectAll();
+ this.moving = true;
+ this.start();
}
}
+ else {
+ alert(this.constants.labels["deleteClusterError"]);
+ }
}
};
/***/ },
-/* 129 */
+/* 128 */
/***/ function(module, exports, __webpack_require__) {
+ exports._cleanNavigation = function() {
+ // clean up previous navigation items
+ var wrapper = document.getElementById('network-navigation_wrapper');
+ if (wrapper != null) {
+ this.containerElement.removeChild(wrapper);
+ }
+ document.onmouseup = null;
+ };
+
/**
- * Calculate the forces the nodes apply on eachother based on a repulsion field.
- * This field is linearly approximated.
+ * Creation of the navigation controls nodes. They are drawn over the rest of the nodes and are not affected by scale and translation
+ * they have a triggerFunction which is called on click. If the position of the navigation controls is dependent
+ * on this.frame.canvas.clientWidth or this.frame.canvas.clientHeight, we flag horizontalAlignLeft and verticalAlignTop false.
+ * This means that the location will be corrected by the _relocateNavigation function on a size change of the canvas.
*
* @private
*/
- exports._calculateNodeForces = function () {
- var dx, dy, distance, fx, fy, combinedClusterSize,
- repulsingForce, node1, node2, i, j;
+ exports._loadNavigationElements = function() {
+ this._cleanNavigation();
- var nodes = this.calculationNodes;
- var nodeIndices = this.calculationNodeIndices;
+ this.navigationDivs = {};
+ var navigationDivs = ['up','down','left','right','zoomIn','zoomOut','zoomExtends'];
+ var navigationDivActions = ['_moveUp','_moveDown','_moveLeft','_moveRight','_zoomIn','_zoomOut','zoomExtent'];
- // approximation constants
- var b = 5;
- var a_base = 0.5 * -b;
+ this.navigationDivs['wrapper'] = document.createElement('div');
+ this.navigationDivs['wrapper'].id = "network-navigation_wrapper";
+ this.navigationDivs['wrapper'].style.position = "absolute";
+ this.navigationDivs['wrapper'].style.width = this.frame.canvas.clientWidth + "px";
+ this.navigationDivs['wrapper'].style.height = this.frame.canvas.clientHeight + "px";
+ this.containerElement.insertBefore(this.navigationDivs['wrapper'],this.frame);
+ for (var i = 0; i < navigationDivs.length; i++) {
+ this.navigationDivs[navigationDivs[i]] = document.createElement('div');
+ this.navigationDivs[navigationDivs[i]].id = "network-navigation_" + navigationDivs[i];
+ this.navigationDivs[navigationDivs[i]].className = "network-navigation " + navigationDivs[i];
+ this.navigationDivs['wrapper'].appendChild(this.navigationDivs[navigationDivs[i]]);
+ this.navigationDivs[navigationDivs[i]].onmousedown = this[navigationDivActions[i]].bind(this);
+ }
- // repulsing forces between nodes
- var nodeDistance = this.constants.physics.hierarchicalRepulsion.nodeDistance;
- var minimumDistance = nodeDistance;
- var a = a_base / minimumDistance;
+ document.onmouseup = this._stopMovement.bind(this);
+ };
- // we loop from i over all but the last entree in the array
- // j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j
- for (i = 0; i < nodeIndices.length - 1; i++) {
+ /**
+ * this stops all movement induced by the navigation buttons
+ *
+ * @private
+ */
+ exports._stopMovement = function() {
+ this._xStopMoving();
+ this._yStopMoving();
+ this._stopZoom();
+ };
- node1 = nodes[nodeIndices[i]];
- for (j = i + 1; j < nodeIndices.length; j++) {
- node2 = nodes[nodeIndices[j]];
- if (node1.level == node2.level) {
- dx = node2.x - node1.x;
- dy = node2.y - node1.y;
- distance = Math.sqrt(dx * dx + dy * dy);
+ /**
+ * stops the actions performed by page up and down etc.
+ *
+ * @param event
+ * @private
+ */
+ exports._preventDefault = function(event) {
+ if (event !== undefined) {
+ if (event.preventDefault) {
+ event.preventDefault();
+ } else {
+ event.returnValue = false;
+ }
+ }
+ };
- if (distance < 2 * minimumDistance) {
- repulsingForce = a * distance + b;
- var c = 0.05;
- var d = 2 * minimumDistance * 2 * c;
- repulsingForce = c * Math.pow(distance,2) - d * distance + d*d/(4*c);
+ /**
+ * move the screen up
+ * By using the increments, instead of adding a fixed number to the translation, we keep fluent and
+ * instant movement. The onKeypress event triggers immediately, then pauses, then triggers frequently
+ * To avoid this behaviour, we do the translation in the start loop.
+ *
+ * @private
+ */
+ exports._moveUp = function(event) {
+ this.yIncrement = this.constants.keyboard.speed.y;
+ this.start(); // if there is no node movement, the calculation wont be done
+ this._preventDefault(event);
+ if (this.navigationDivs) {
+ this.navigationDivs['up'].className += " active";
+ }
+ };
- // normalize force with
- if (distance == 0) {
- distance = 0.01;
- }
- else {
- repulsingForce = repulsingForce / distance;
- }
- fx = dx * repulsingForce;
- fy = dy * repulsingForce;
- node1.fx -= fx;
- node1.fy -= fy;
- node2.fx += fx;
- node2.fy += fy;
- }
- }
- }
+ /**
+ * move the screen down
+ * @private
+ */
+ exports._moveDown = function(event) {
+ this.yIncrement = -this.constants.keyboard.speed.y;
+ this.start(); // if there is no node movement, the calculation wont be done
+ this._preventDefault(event);
+ if (this.navigationDivs) {
+ this.navigationDivs['down'].className += " active";
}
};
/**
- * this function calculates the effects of the springs in the case of unsmooth curves.
- *
+ * move the screen left
* @private
*/
- exports._calculateHierarchicalSpringForces = function () {
- var edgeLength, edge, edgeId;
- var dx, dy, fx, fy, springForce, distance;
- var edges = this.edges;
+ exports._moveLeft = function(event) {
+ this.xIncrement = this.constants.keyboard.speed.x;
+ this.start(); // if there is no node movement, the calculation wont be done
+ this._preventDefault(event);
+ if (this.navigationDivs) {
+ this.navigationDivs['left'].className += " active";
+ }
+ };
- // forces caused by the edges, modelled as springs
- for (edgeId in edges) {
- if (edges.hasOwnProperty(edgeId)) {
- edge = edges[edgeId];
- if (edge.connected) {
- // only calculate forces if nodes are in the same sector
- if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
- edgeLength = edge.customLength ? edge.length : this.constants.physics.springLength;
- // this implies that the edges between big clusters are longer
- edgeLength += (edge.to.clusterSize + edge.from.clusterSize - 2) * this.constants.clustering.edgeGrowth;
- dx = (edge.from.x - edge.to.x);
- dy = (edge.from.y - edge.to.y);
- distance = Math.sqrt(dx * dx + dy * dy);
+ /**
+ * move the screen right
+ * @private
+ */
+ exports._moveRight = function(event) {
+ this.xIncrement = -this.constants.keyboard.speed.y;
+ this.start(); // if there is no node movement, the calculation wont be done
+ this._preventDefault(event);
+ if (this.navigationDivs) {
+ this.navigationDivs['right'].className += " active";
+ }
+ };
- if (distance == 0) {
- distance = 0.01;
- }
- distance = Math.max(0.8*edgeLength,Math.min(5*edgeLength, distance));
+ /**
+ * Zoom in, using the same method as the movement.
+ * @private
+ */
+ exports._zoomIn = function(event) {
+ this.zoomIncrement = this.constants.keyboard.speed.zoom;
+ this.start(); // if there is no node movement, the calculation wont be done
+ this._preventDefault(event);
+ if (this.navigationDivs) {
+ this.navigationDivs['zoomIn'].className += " active";
+ }
+ };
- // the 1/distance is so the fx and fy can be calculated without sine or cosine.
- springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
- fx = dx * springForce;
- fy = dy * springForce;
+ /**
+ * Zoom out
+ * @private
+ */
+ exports._zoomOut = function() {
+ this.zoomIncrement = -this.constants.keyboard.speed.zoom;
+ this.start(); // if there is no node movement, the calculation wont be done
+ this._preventDefault(event);
+ if (this.navigationDivs) {
+ this.navigationDivs['zoomOut'].className += " active";
+ }
+ };
- edge.to.fx -= fx;
- edge.to.fy -= fy;
- edge.from.fx += fx;
- edge.from.fy += fy;
+ /**
+ * Stop zooming and unhighlight the zoom controls
+ * @private
+ */
+ exports._stopZoom = function() {
+ this.zoomIncrement = 0;
+ if (this.navigationDivs) {
+ this.navigationDivs['zoomIn'].className = this.navigationDivs['zoomIn'].className.replace(" active","");
+ this.navigationDivs['zoomOut'].className = this.navigationDivs['zoomOut'].className.replace(" active","");
+ }
+ };
- var factor = 5;
- if (distance > edgeLength) {
- factor = 25;
- }
- if (edge.from.level > edge.to.level) {
- edge.to.fx -= factor*fx;
- edge.to.fy -= factor*fy;
- }
- else if (edge.from.level < edge.to.level) {
- edge.from.fx += factor*fx;
- edge.from.fy += factor*fy;
- }
- }
- }
- }
+ /**
+ * Stop moving in the Y direction and unHighlight the up and down
+ * @private
+ */
+ exports._yStopMoving = function() {
+ this.yIncrement = 0;
+ if (this.navigationDivs) {
+ this.navigationDivs['up'].className = this.navigationDivs['up'].className.replace(" active","");
+ this.navigationDivs['down'].className = this.navigationDivs['down'].className.replace(" active","");
}
};
-/***/ },
-/* 130 */
-/***/ function(module, exports, __webpack_require__) {
/**
- * This function calculates the forces the nodes apply on eachother based on a gravitational model.
- * The Barnes Hut method is used to speed up this N-body simulation.
- *
+ * Stop moving in the X direction and unHighlight left and right.
* @private
*/
- exports._calculateNodeForces = function() {
- if (this.constants.physics.barnesHut.gravitationalConstant != 0) {
- var node;
- var nodes = this.calculationNodes;
- var nodeIndices = this.calculationNodeIndices;
- var nodeCount = nodeIndices.length;
+ exports._xStopMoving = function() {
+ this.xIncrement = 0;
+ if (this.navigationDivs) {
+ this.navigationDivs['left'].className = this.navigationDivs['left'].className.replace(" active","");
+ this.navigationDivs['right'].className = this.navigationDivs['right'].className.replace(" active","");
+ }
+ };
- this._formBarnesHutTree(nodes,nodeIndices);
- var barnesHutTree = this.barnesHutTree;
+/***/ },
+/* 129 */
+/***/ function(module, exports, __webpack_require__) {
- // place the nodes one by one recursively
- for (var i = 0; i < nodeCount; i++) {
- node = nodes[nodeIndices[i]];
- // starting with root is irrelevant, it never passes the BarnesHut condition
- this._getForceContribution(barnesHutTree.root.children.NW,node);
- this._getForceContribution(barnesHutTree.root.children.NE,node);
- this._getForceContribution(barnesHutTree.root.children.SW,node);
- this._getForceContribution(barnesHutTree.root.children.SE,node);
+ exports._resetLevels = function() {
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ var node = this.nodes[nodeId];
+ if (node.preassignedLevel == false) {
+ node.level = -1;
+ }
}
}
};
-
/**
- * This function traverses the barnesHutTree. It checks when it can approximate distant nodes with their center of mass.
- * If a region contains a single node, we check if it is not itself, then we apply the force.
+ * This is the main function to layout the nodes in a hierarchical way.
+ * It checks if the node details are supplied correctly
*
- * @param parentBranch
- * @param node
* @private
*/
- exports._getForceContribution = function(parentBranch,node) {
- // we get no force contribution from an empty region
- if (parentBranch.childrenCount > 0) {
- var dx,dy,distance;
-
- // get the distance from the center of mass to the node.
- dx = parentBranch.centerOfMass.x - node.x;
- dy = parentBranch.centerOfMass.y - node.y;
- distance = Math.sqrt(dx * dx + dy * dy);
+ exports._setupHierarchicalLayout = function() {
+ if (this.constants.hierarchicalLayout.enabled == true && this.nodeIndices.length > 0) {
+ if (this.constants.hierarchicalLayout.direction == "RL" || this.constants.hierarchicalLayout.direction == "DU") {
+ this.constants.hierarchicalLayout.levelSeparation *= -1;
+ }
+ else {
+ this.constants.hierarchicalLayout.levelSeparation = Math.abs(this.constants.hierarchicalLayout.levelSeparation);
+ }
- // BarnesHut condition
- // original condition : s/d < theta = passed === d/s > 1/theta = passed
- // calcSize = 1/s --> d * 1/s > 1/theta = passed
- if (distance * parentBranch.calcSize > this.constants.physics.barnesHut.theta) {
- // duplicate code to reduce function calls to speed up program
- if (distance == 0) {
- distance = 0.1*Math.random();
- dx = distance;
+ if (this.constants.hierarchicalLayout.direction == "RL" || this.constants.hierarchicalLayout.direction == "LR") {
+ if (this.constants.smoothCurves.enabled == true) {
+ this.constants.smoothCurves.type = "vertical";
}
- var gravityForce = this.constants.physics.barnesHut.gravitationalConstant * parentBranch.mass * node.mass / (distance * distance * distance);
- var fx = dx * gravityForce;
- var fy = dy * gravityForce;
- node.fx += fx;
- node.fy += fy;
}
else {
- // Did not pass the condition, go into children if available
- if (parentBranch.childrenCount == 4) {
- this._getForceContribution(parentBranch.children.NW,node);
- this._getForceContribution(parentBranch.children.NE,node);
- this._getForceContribution(parentBranch.children.SW,node);
- this._getForceContribution(parentBranch.children.SE,node);
+ if (this.constants.smoothCurves.enabled == true) {
+ this.constants.smoothCurves.type = "horizontal";
}
- else { // parentBranch must have only one node, if it was empty we wouldnt be here
- if (parentBranch.children.data.id != node.id) { // if it is not self
- // duplicate code to reduce function calls to speed up program
- if (distance == 0) {
- distance = 0.5*Math.random();
- dx = distance;
- }
- var gravityForce = this.constants.physics.barnesHut.gravitationalConstant * parentBranch.mass * node.mass / (distance * distance * distance);
- var fx = dx * gravityForce;
- var fy = dy * gravityForce;
- node.fx += fx;
- node.fy += fy;
+ }
+ // get the size of the largest hubs and check if the user has defined a level for a node.
+ var hubsize = 0;
+ var node, nodeId;
+ var definedLevel = false;
+ var undefinedLevel = false;
+
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ node = this.nodes[nodeId];
+ if (node.level != -1) {
+ definedLevel = true;
+ }
+ else {
+ undefinedLevel = true;
}
+ if (hubsize < node.edges.length) {
+ hubsize = node.edges.length;
+ }
+ }
+ }
+
+ // if the user defined some levels but not all, alert and run without hierarchical layout
+ if (undefinedLevel == true && definedLevel == true) {
+ alert("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");
+ this.zoomExtent(true,this.constants.clustering.enabled);
+ if (!this.constants.clustering.enabled) {
+ this.start();
+ }
+ }
+ else {
+ // setup the system to use hierarchical method.
+ this._changeConstants();
+
+ // define levels if undefined by the users. Based on hubsize
+ if (undefinedLevel == true) {
+ this._determineLevels(hubsize);
}
+ // check the distribution of the nodes per level.
+ var distribution = this._getDistribution();
+
+ // place the nodes on the canvas. This also stablilizes the system.
+ this._placeNodesByHierarchy(distribution);
+
+ // start the simulation.
+ this.start();
}
}
};
+
/**
- * This function constructs the barnesHut tree recursively. It creates the root, splits it and starts placing the nodes.
+ * This function places the nodes on the canvas based on the hierarchial distribution.
*
- * @param nodes
- * @param nodeIndices
+ * @param {Object} distribution | obtained by the function this._getDistribution()
* @private
*/
- exports._formBarnesHutTree = function(nodes,nodeIndices) {
- var node;
- var nodeCount = nodeIndices.length;
+ exports._placeNodesByHierarchy = function(distribution) {
+ var nodeId, node;
- var minX = Number.MAX_VALUE,
- minY = Number.MAX_VALUE,
- maxX =-Number.MAX_VALUE,
- maxY =-Number.MAX_VALUE;
+ // start placing all the level 0 nodes first. Then recursively position their branches.
+ for (nodeId in distribution[0].nodes) {
+ if (distribution[0].nodes.hasOwnProperty(nodeId)) {
+ node = distribution[0].nodes[nodeId];
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ if (node.xFixed) {
+ node.x = distribution[0].minPos;
+ node.xFixed = false;
- // get the range of the nodes
- for (var i = 0; i < nodeCount; i++) {
- var x = nodes[nodeIndices[i]].x;
- var y = nodes[nodeIndices[i]].y;
- if (x < minX) { minX = x; }
- if (x > maxX) { maxX = x; }
- if (y < minY) { minY = y; }
- if (y > maxY) { maxY = y; }
+ distribution[0].minPos += distribution[0].nodeSpacing;
+ }
+ }
+ else {
+ if (node.yFixed) {
+ node.y = distribution[0].minPos;
+ node.yFixed = false;
+
+ distribution[0].minPos += distribution[0].nodeSpacing;
+ }
+ }
+ this._placeBranchNodes(node.edges,node.id,distribution,node.level);
+ }
}
- // make the range a square
- var sizeDiff = Math.abs(maxX - minX) - Math.abs(maxY - minY); // difference between X and Y
- if (sizeDiff > 0) {minY -= 0.5 * sizeDiff; maxY += 0.5 * sizeDiff;} // xSize > ySize
- else {minX += 0.5 * sizeDiff; maxX -= 0.5 * sizeDiff;} // xSize < ySize
+ // stabilize the system after positioning. This function calls zoomExtent.
+ this._stabilize();
+ };
- var minimumTreeSize = 1e-5;
- var rootSize = Math.max(minimumTreeSize,Math.abs(maxX - minX));
- var halfRootSize = 0.5 * rootSize;
- var centerX = 0.5 * (minX + maxX), centerY = 0.5 * (minY + maxY);
- // construct the barnesHutTree
- var barnesHutTree = {
- root:{
- centerOfMass: {x:0, y:0},
- mass:0,
- range: {
- minX: centerX-halfRootSize,maxX:centerX+halfRootSize,
- minY: centerY-halfRootSize,maxY:centerY+halfRootSize
- },
- size: rootSize,
- calcSize: 1 / rootSize,
- children: { data:null},
- maxWidth: 0,
- level: 0,
- childrenCount: 4
+ /**
+ * This function get the distribution of levels based on hubsize
+ *
+ * @returns {Object}
+ * @private
+ */
+ exports._getDistribution = function() {
+ var distribution = {};
+ var nodeId, node, level;
+
+ // we fix Y because the hierarchy is vertical, we fix X so we do not give a node an x position for a second time.
+ // the fix of X is removed after the x value has been set.
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ node = this.nodes[nodeId];
+ node.xFixed = true;
+ node.yFixed = true;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ node.y = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ }
+ else {
+ node.x = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ }
+ if (!distribution.hasOwnProperty(node.level)) {
+ distribution[node.level] = {amount: 0, nodes: {}, minPos:0, nodeSpacing:0};
+ }
+ distribution[node.level].amount += 1;
+ distribution[node.level].nodes[node.id] = node;
+ }
+ }
+
+ // determine the largest amount of nodes of all levels
+ var maxCount = 0;
+ for (level in distribution) {
+ if (distribution.hasOwnProperty(level)) {
+ if (maxCount < distribution[level].amount) {
+ maxCount = distribution[level].amount;
+ }
}
- };
- this._splitBranch(barnesHutTree.root);
+ }
- // place the nodes one by one recursively
- for (i = 0; i < nodeCount; i++) {
- node = nodes[nodeIndices[i]];
- this._placeInTree(barnesHutTree.root,node);
+ // set the initial position and spacing of each nodes accordingly
+ for (level in distribution) {
+ if (distribution.hasOwnProperty(level)) {
+ distribution[level].nodeSpacing = (maxCount + 1) * this.constants.hierarchicalLayout.nodeSpacing;
+ distribution[level].nodeSpacing /= (distribution[level].amount + 1);
+ distribution[level].minPos = distribution[level].nodeSpacing - (0.5 * (distribution[level].amount + 1) * distribution[level].nodeSpacing);
+ }
}
- // make global
- this.barnesHutTree = barnesHutTree
+ return distribution;
};
/**
- * this updates the mass of a branch. this is increased by adding a node.
+ * this function allocates nodes in levels based on the recursive branching from the largest hubs.
*
- * @param parentBranch
- * @param node
+ * @param hubsize
* @private
*/
- exports._updateBranchMass = function(parentBranch, node) {
- var totalMass = parentBranch.mass + node.mass;
- var totalMassInv = 1/totalMass;
-
- parentBranch.centerOfMass.x = parentBranch.centerOfMass.x * parentBranch.mass + node.x * node.mass;
- parentBranch.centerOfMass.x *= totalMassInv;
-
- parentBranch.centerOfMass.y = parentBranch.centerOfMass.y * parentBranch.mass + node.y * node.mass;
- parentBranch.centerOfMass.y *= totalMassInv;
+ exports._determineLevels = function(hubsize) {
+ var nodeId, node;
- parentBranch.mass = totalMass;
- var biggestSize = Math.max(Math.max(node.height,node.radius),node.width);
- parentBranch.maxWidth = (parentBranch.maxWidth < biggestSize) ? biggestSize : parentBranch.maxWidth;
+ // determine hubs
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ node = this.nodes[nodeId];
+ if (node.edges.length == hubsize) {
+ node.level = 0;
+ }
+ }
+ }
+ // branch from hubs
+ for (nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ node = this.nodes[nodeId];
+ if (node.level == 0) {
+ this._setLevel(1,node.edges,node.id);
+ }
+ }
+ }
};
/**
- * determine in which branch the node will be placed.
+ * Since hierarchical layout does not support:
+ * - smooth curves (based on the physics),
+ * - clustering (based on dynamic node counts)
+ *
+ * We disable both features so there will be no problems.
*
- * @param parentBranch
- * @param node
- * @param skipMassUpdate
* @private
*/
- exports._placeInTree = function(parentBranch,node,skipMassUpdate) {
- if (skipMassUpdate != true || skipMassUpdate === undefined) {
- // update the mass of the branch.
- this._updateBranchMass(parentBranch,node);
+ exports._changeConstants = function() {
+ this.constants.clustering.enabled = false;
+ this.constants.physics.barnesHut.enabled = false;
+ this.constants.physics.hierarchicalRepulsion.enabled = true;
+ this._loadSelectedForceSolver();
+ if (this.constants.smoothCurves.enabled == true) {
+ this.constants.smoothCurves.dynamic = false;
}
+ this._configureSmoothCurves();
+ };
- if (parentBranch.children.NW.range.maxX > node.x) { // in NW or SW
- if (parentBranch.children.NW.range.maxY > node.y) { // in NW
- this._placeInRegion(parentBranch,node,"NW");
+
+ /**
+ * This is a recursively called function to enumerate the branches from the largest hubs and place the nodes
+ * on a X position that ensures there will be no overlap.
+ *
+ * @param edges
+ * @param parentId
+ * @param distribution
+ * @param parentLevel
+ * @private
+ */
+ exports._placeBranchNodes = function(edges, parentId, distribution, parentLevel) {
+ for (var i = 0; i < edges.length; i++) {
+ var childNode = null;
+ if (edges[i].toId == parentId) {
+ childNode = edges[i].from;
}
- else { // in SW
- this._placeInRegion(parentBranch,node,"SW");
+ else {
+ childNode = edges[i].to;
}
- }
- else { // in NE or SE
- if (parentBranch.children.NW.range.maxY > node.y) { // in NE
- this._placeInRegion(parentBranch,node,"NE");
+
+ // if a node is conneceted to another node on the same level (or higher (means lower level))!, this is not handled here.
+ var nodeMoved = false;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ if (childNode.xFixed && childNode.level > parentLevel) {
+ childNode.xFixed = false;
+ childNode.x = distribution[childNode.level].minPos;
+ nodeMoved = true;
+ }
}
- else { // in SE
- this._placeInRegion(parentBranch,node,"SE");
+ else {
+ if (childNode.yFixed && childNode.level > parentLevel) {
+ childNode.yFixed = false;
+ childNode.y = distribution[childNode.level].minPos;
+ nodeMoved = true;
+ }
+ }
+
+ if (nodeMoved == true) {
+ distribution[childNode.level].minPos += distribution[childNode.level].nodeSpacing;
+ if (childNode.edges.length > 1) {
+ this._placeBranchNodes(childNode.edges,childNode.id,distribution,childNode.level);
+ }
}
}
};
/**
- * actually place the node in a region (or branch)
+ * this function is called recursively to enumerate the barnches of the largest hubs and give each node a level.
*
- * @param parentBranch
- * @param node
- * @param region
+ * @param level
+ * @param edges
+ * @param parentId
* @private
*/
- exports._placeInRegion = function(parentBranch,node,region) {
- switch (parentBranch.children[region].childrenCount) {
- case 0: // place node here
- parentBranch.children[region].children.data = node;
- parentBranch.children[region].childrenCount = 1;
- this._updateBranchMass(parentBranch.children[region],node);
- break;
- case 1: // convert into children
- // if there are two nodes exactly overlapping (on init, on opening of cluster etc.)
- // we move one node a pixel and we do not put it in the tree.
- if (parentBranch.children[region].children.data.x == node.x &&
- parentBranch.children[region].children.data.y == node.y) {
- node.x += Math.random();
- node.y += Math.random();
- }
- else {
- this._splitBranch(parentBranch.children[region]);
- this._placeInTree(parentBranch.children[region],node);
+ exports._setLevel = function(level, edges, parentId) {
+ for (var i = 0; i < edges.length; i++) {
+ var childNode = null;
+ if (edges[i].toId == parentId) {
+ childNode = edges[i].from;
+ }
+ else {
+ childNode = edges[i].to;
+ }
+ if (childNode.level == -1 || childNode.level > level) {
+ childNode.level = level;
+ if (edges.length > 1) {
+ this._setLevel(level+1, childNode.edges, childNode.id);
}
- break;
- case 4: // place in branch
- this._placeInTree(parentBranch.children[region],node);
- break;
+ }
}
};
/**
- * this function splits a branch into 4 sub branches. If the branch contained a node, we place it in the subbranch
- * after the split is complete.
+ * Unfix nodes
*
- * @param parentBranch
* @private
*/
- exports._splitBranch = function(parentBranch) {
- // if the branch is shaded with a node, replace the node in the new subset.
- var containedNode = null;
- if (parentBranch.childrenCount == 1) {
- containedNode = parentBranch.children.data;
- parentBranch.mass = 0; parentBranch.centerOfMass.x = 0; parentBranch.centerOfMass.y = 0;
- }
- parentBranch.childrenCount = 4;
- parentBranch.children.data = null;
- this._insertRegion(parentBranch,"NW");
- this._insertRegion(parentBranch,"NE");
- this._insertRegion(parentBranch,"SW");
- this._insertRegion(parentBranch,"SE");
-
- if (containedNode != null) {
- this._placeInTree(parentBranch,containedNode);
+ exports._restoreNodes = function() {
+ for (var nodeId in this.nodes) {
+ if (this.nodes.hasOwnProperty(nodeId)) {
+ this.nodes[nodeId].xFixed = false;
+ this.nodes[nodeId].yFixed = false;
+ }
}
};
+/***/ },
+/* 130 */
+/***/ function(module, exports, __webpack_require__) {
+
/**
- * This function subdivides the region into four new segments.
- * Specifically, this inserts a single new segment.
- * It fills the children section of the parentBranch
- *
- * @param parentBranch
- * @param region
- * @param parentRange
- * @private
+ * Canvas shapes used by Network
*/
- exports._insertRegion = function(parentBranch, region) {
- var minX,maxX,minY,maxY;
- var childSize = 0.5 * parentBranch.size;
- switch (region) {
- case "NW":
- minX = parentBranch.range.minX;
- maxX = parentBranch.range.minX + childSize;
- minY = parentBranch.range.minY;
- maxY = parentBranch.range.minY + childSize;
- break;
- case "NE":
- minX = parentBranch.range.minX + childSize;
- maxX = parentBranch.range.maxX;
- minY = parentBranch.range.minY;
- maxY = parentBranch.range.minY + childSize;
- break;
- case "SW":
- minX = parentBranch.range.minX;
- maxX = parentBranch.range.minX + childSize;
- minY = parentBranch.range.minY + childSize;
- maxY = parentBranch.range.maxY;
- break;
- case "SE":
- minX = parentBranch.range.minX + childSize;
- maxX = parentBranch.range.maxX;
- minY = parentBranch.range.minY + childSize;
- maxY = parentBranch.range.maxY;
- break;
- }
+ if (typeof CanvasRenderingContext2D !== 'undefined') {
+ /**
+ * Draw a circle shape
+ */
+ CanvasRenderingContext2D.prototype.circle = function(x, y, r) {
+ this.beginPath();
+ this.arc(x, y, r, 0, 2*Math.PI, false);
+ };
- parentBranch.children[region] = {
- centerOfMass:{x:0,y:0},
- mass:0,
- range:{minX:minX,maxX:maxX,minY:minY,maxY:maxY},
- size: 0.5 * parentBranch.size,
- calcSize: 2 * parentBranch.calcSize,
- children: {data:null},
- maxWidth: 0,
- level: parentBranch.level+1,
- childrenCount: 0
+ /**
+ * Draw a square shape
+ * @param {Number} x horizontal center
+ * @param {Number} y vertical center
+ * @param {Number} r size, width and height of the square
+ */
+ CanvasRenderingContext2D.prototype.square = function(x, y, r) {
+ this.beginPath();
+ this.rect(x - r, y - r, r * 2, r * 2);
};
- };
+ /**
+ * Draw a triangle shape
+ * @param {Number} x horizontal center
+ * @param {Number} y vertical center
+ * @param {Number} r radius, half the length of the sides of the triangle
+ */
+ CanvasRenderingContext2D.prototype.triangle = function(x, y, r) {
+ // http://en.wikipedia.org/wiki/Equilateral_triangle
+ this.beginPath();
- /**
- * This function is for debugging purposed, it draws the tree.
- *
- * @param ctx
- * @param color
- * @private
- */
- exports._drawTree = function(ctx,color) {
- if (this.barnesHutTree !== undefined) {
+ var s = r * 2;
+ var s2 = s / 2;
+ var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
+ var h = Math.sqrt(s * s - s2 * s2); // height
- ctx.lineWidth = 1;
+ this.moveTo(x, y - (h - ir));
+ this.lineTo(x + s2, y + ir);
+ this.lineTo(x - s2, y + ir);
+ this.lineTo(x, y - (h - ir));
+ this.closePath();
+ };
- this._drawBranch(this.barnesHutTree.root,ctx,color);
- }
- };
+ /**
+ * Draw a triangle shape in downward orientation
+ * @param {Number} x horizontal center
+ * @param {Number} y vertical center
+ * @param {Number} r radius
+ */
+ CanvasRenderingContext2D.prototype.triangleDown = function(x, y, r) {
+ // http://en.wikipedia.org/wiki/Equilateral_triangle
+ this.beginPath();
+ var s = r * 2;
+ var s2 = s / 2;
+ var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
+ var h = Math.sqrt(s * s - s2 * s2); // height
- /**
- * This function is for debugging purposes. It draws the branches recursively.
- *
- * @param branch
- * @param ctx
- * @param color
- * @private
- */
- exports._drawBranch = function(branch,ctx,color) {
- if (color === undefined) {
- color = "#FF0000";
- }
+ this.moveTo(x, y + (h - ir));
+ this.lineTo(x + s2, y - ir);
+ this.lineTo(x - s2, y - ir);
+ this.lineTo(x, y + (h - ir));
+ this.closePath();
+ };
- if (branch.childrenCount == 4) {
- this._drawBranch(branch.children.NW,ctx);
- this._drawBranch(branch.children.NE,ctx);
- this._drawBranch(branch.children.SE,ctx);
- this._drawBranch(branch.children.SW,ctx);
- }
- ctx.strokeStyle = color;
- ctx.beginPath();
- ctx.moveTo(branch.range.minX,branch.range.minY);
- ctx.lineTo(branch.range.maxX,branch.range.minY);
- ctx.stroke();
+ /**
+ * Draw a star shape, a star with 5 points
+ * @param {Number} x horizontal center
+ * @param {Number} y vertical center
+ * @param {Number} r radius, half the length of the sides of the triangle
+ */
+ CanvasRenderingContext2D.prototype.star = function(x, y, r) {
+ // http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
+ this.beginPath();
- ctx.beginPath();
- ctx.moveTo(branch.range.maxX,branch.range.minY);
- ctx.lineTo(branch.range.maxX,branch.range.maxY);
- ctx.stroke();
+ for (var n = 0; n < 10; n++) {
+ var radius = (n % 2 === 0) ? r * 1.3 : r * 0.5;
+ this.lineTo(
+ x + radius * Math.sin(n * 2 * Math.PI / 10),
+ y - radius * Math.cos(n * 2 * Math.PI / 10)
+ );
+ }
- ctx.beginPath();
- ctx.moveTo(branch.range.maxX,branch.range.maxY);
- ctx.lineTo(branch.range.minX,branch.range.maxY);
- ctx.stroke();
+ this.closePath();
+ };
- ctx.beginPath();
- ctx.moveTo(branch.range.minX,branch.range.maxY);
- ctx.lineTo(branch.range.minX,branch.range.minY);
- ctx.stroke();
+ /**
+ * http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
+ */
+ CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) {
+ var r2d = Math.PI/180;
+ if( w - ( 2 * r ) < 0 ) { r = ( w / 2 ); } //ensure that the radius isn't too large for x
+ if( h - ( 2 * r ) < 0 ) { r = ( h / 2 ); } //ensure that the radius isn't too large for y
+ this.beginPath();
+ this.moveTo(x+r,y);
+ this.lineTo(x+w-r,y);
+ this.arc(x+w-r,y+r,r,r2d*270,r2d*360,false);
+ this.lineTo(x+w,y+h-r);
+ this.arc(x+w-r,y+h-r,r,0,r2d*90,false);
+ this.lineTo(x+r,y+h);
+ this.arc(x+r,y+h-r,r,r2d*90,r2d*180,false);
+ this.lineTo(x,y+r);
+ this.arc(x+r,y+r,r,r2d*180,r2d*270,false);
+ };
- /*
- if (branch.mass > 0) {
- ctx.circle(branch.centerOfMass.x, branch.centerOfMass.y, 3*branch.mass);
- ctx.stroke();
- }
+ /**
+ * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
*/
- };
+ CanvasRenderingContext2D.prototype.ellipse = function(x, y, w, h) {
+ var kappa = .5522848,
+ ox = (w / 2) * kappa, // control point offset horizontal
+ oy = (h / 2) * kappa, // control point offset vertical
+ xe = x + w, // x-end
+ ye = y + h, // y-end
+ xm = x + w / 2, // x-middle
+ ym = y + h / 2; // y-middle
+
+ this.beginPath();
+ this.moveTo(x, ym);
+ this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
+ this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
+ this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
+ this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
+ };
+
+
+
+ /**
+ * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
+ */
+ CanvasRenderingContext2D.prototype.database = function(x, y, w, h) {
+ var f = 1/3;
+ var wEllipse = w;
+ var hEllipse = h * f;
+
+ var kappa = .5522848,
+ ox = (wEllipse / 2) * kappa, // control point offset horizontal
+ oy = (hEllipse / 2) * kappa, // control point offset vertical
+ xe = x + wEllipse, // x-end
+ ye = y + hEllipse, // y-end
+ xm = x + wEllipse / 2, // x-middle
+ ym = y + hEllipse / 2, // y-middle
+ ymb = y + (h - hEllipse/2), // y-midlle, bottom ellipse
+ yeb = y + h; // y-end, bottom ellipse
+
+ this.beginPath();
+ this.moveTo(xe, ym);
+
+ this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
+ this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
+
+ this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
+ this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
+
+ this.lineTo(xe, ymb);
+
+ this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb);
+ this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb);
+
+ this.lineTo(x, ym);
+ };
+
+
+ /**
+ * Draw an arrow point (no line)
+ */
+ CanvasRenderingContext2D.prototype.arrow = function(x, y, angle, length) {
+ // tail
+ var xt = x - length * Math.cos(angle);
+ var yt = y - length * Math.sin(angle);
+
+ // inner tail
+ // TODO: allow to customize different shapes
+ var xi = x - length * 0.9 * Math.cos(angle);
+ var yi = y - length * 0.9 * Math.sin(angle);
+
+ // left
+ var xl = xt + length / 3 * Math.cos(angle + 0.5 * Math.PI);
+ var yl = yt + length / 3 * Math.sin(angle + 0.5 * Math.PI);
+
+ // right
+ var xr = xt + length / 3 * Math.cos(angle - 0.5 * Math.PI);
+ var yr = yt + length / 3 * Math.sin(angle - 0.5 * Math.PI);
+
+ this.beginPath();
+ this.moveTo(x, y);
+ this.lineTo(xl, yl);
+ this.lineTo(xi, yi);
+ this.lineTo(xr, yr);
+ this.closePath();
+ };
+
+ /**
+ * Sets up the dashedLine functionality for drawing
+ * Original code came from http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas
+ * @author David Jordan
+ * @date 2012-08-08
+ */
+ CanvasRenderingContext2D.prototype.dashedLine = function(x,y,x2,y2,dashArray){
+ if (!dashArray) dashArray=[10,5];
+ if (dashLength==0) dashLength = 0.001; // Hack for Safari
+ var dashCount = dashArray.length;
+ this.moveTo(x, y);
+ var dx = (x2-x), dy = (y2-y);
+ var slope = dy/dx;
+ var distRemaining = Math.sqrt( dx*dx + dy*dy );
+ var dashIndex=0, draw=true;
+ while (distRemaining>=0.1){
+ var dashLength = dashArray[dashIndex++%dashCount];
+ if (dashLength > distRemaining) dashLength = distRemaining;
+ var xStep = Math.sqrt( dashLength*dashLength / (1 + slope*slope) );
+ if (dx<0) xStep = -xStep;
+ x += xStep;
+ y += slope*xStep;
+ this[draw ? 'lineTo' : 'moveTo'](x,y);
+ distRemaining -= dashLength;
+ draw = !draw;
+ }
+ };
+
+ // TODO: add diamond shape
+ }
/***/ }
diff --git a/lib/network/Network.js b/lib/network/Network.js
index 7848d8e0..91e76026 100644
--- a/lib/network/Network.js
+++ b/lib/network/Network.js
@@ -186,7 +186,7 @@ function Network (container, data, options) {
roundness: 0.5
},
dynamicSmoothCurves: true,
- maxVelocity: 10,
+ maxVelocity: 30,
minVelocity: 0.1, // px/s
stabilizationIterations: 1000, // maximum number of iteration to stabilize
labels:{