From 18d2c4084a4985fcf6e5c6e68b80c31db791ba88 Mon Sep 17 00:00:00 2001 From: Alex de Mulder Date: Mon, 27 Oct 2014 12:55:04 +0100 Subject: [PATCH] new build --- dist/vis.js | 52045 +++++++++++++++++++++++----------------------- dist/vis.map | 2 +- dist/vis.min.js | 24 +- 3 files changed, 26035 insertions(+), 26036 deletions(-) diff --git a/dist/vis.js b/dist/vis.js index bff66b57..9121669f 100644 --- a/dist/vis.js +++ b/dist/vis.js @@ -81,66 +81,66 @@ return /******/ (function(modules) { // webpackBootstrap // utils exports.util = __webpack_require__(1); - exports.DOMutil = __webpack_require__(6); + exports.DOMutil = __webpack_require__(2); // data - exports.DataSet = __webpack_require__(7); - exports.DataView = __webpack_require__(8); + exports.DataSet = __webpack_require__(3); + exports.DataView = __webpack_require__(4); // Graph3d - exports.Graph3d = __webpack_require__(9); + exports.Graph3d = __webpack_require__(5); exports.graph3d = { - Camera: __webpack_require__(13), - Filter: __webpack_require__(14), - Point2d: __webpack_require__(12), - Point3d: __webpack_require__(11), - Slider: __webpack_require__(15), - StepNumber: __webpack_require__(16) + Camera: __webpack_require__(6), + Filter: __webpack_require__(7), + Point2d: __webpack_require__(8), + Point3d: __webpack_require__(9), + Slider: __webpack_require__(10), + StepNumber: __webpack_require__(11) }; // Timeline - exports.Timeline = __webpack_require__(17); - exports.Graph2d = __webpack_require__(41); + exports.Timeline = __webpack_require__(12); + exports.Graph2d = __webpack_require__(13); exports.timeline = { - DateUtil: __webpack_require__(23), - DataStep: __webpack_require__(44), - Range: __webpack_require__(20), - stack: __webpack_require__(32), - TimeStep: __webpack_require__(26), + DateUtil: __webpack_require__(14), + DataStep: __webpack_require__(15), + Range: __webpack_require__(16), + stack: __webpack_require__(17), + TimeStep: __webpack_require__(18), components: { items: { - Item: __webpack_require__(34), - BackgroundItem: __webpack_require__(38), - BoxItem: __webpack_require__(36), - PointItem: __webpack_require__(37), - RangeItem: __webpack_require__(33) + Item: __webpack_require__(30), + BackgroundItem: __webpack_require__(31), + BoxItem: __webpack_require__(32), + PointItem: __webpack_require__(33), + RangeItem: __webpack_require__(34) }, - Component: __webpack_require__(22), - CurrentTime: __webpack_require__(27), - CustomTime: __webpack_require__(29), - DataAxis: __webpack_require__(43), - GraphGroup: __webpack_require__(45), - Group: __webpack_require__(31), - BackgroundGroup: __webpack_require__(35), - ItemSet: __webpack_require__(30), - Legend: __webpack_require__(46), - LineGraph: __webpack_require__(42), - TimeAxis: __webpack_require__(25) + Component: __webpack_require__(19), + CurrentTime: __webpack_require__(20), + CustomTime: __webpack_require__(21), + DataAxis: __webpack_require__(22), + GraphGroup: __webpack_require__(23), + Group: __webpack_require__(24), + BackgroundGroup: __webpack_require__(25), + ItemSet: __webpack_require__(26), + Legend: __webpack_require__(27), + LineGraph: __webpack_require__(28), + TimeAxis: __webpack_require__(29) } }; // Network - exports.Network = __webpack_require__(47); + exports.Network = __webpack_require__(35); exports.network = { - Edge: __webpack_require__(53), - Groups: __webpack_require__(50), - Images: __webpack_require__(51), - Node: __webpack_require__(52), - Popup: __webpack_require__(54), - dotparser: __webpack_require__(48), - gephiParser: __webpack_require__(49) + Edge: __webpack_require__(36), + Groups: __webpack_require__(37), + Images: __webpack_require__(38), + Node: __webpack_require__(39), + Popup: __webpack_require__(40), + dotparser: __webpack_require__(41), + gephiParser: __webpack_require__(42) }; // Deprecated since v3.0.0 @@ -149,8 +149,8 @@ return /******/ (function(modules) { // webpackBootstrap }; // bundled external libraries - exports.moment = __webpack_require__(2); - exports.hammer = __webpack_require__(18); + exports.moment = __webpack_require__(43); + exports.hammer = __webpack_require__(44); /***/ }, @@ -161,7 +161,7 @@ return /******/ (function(modules) { // webpackBootstrap // first check if moment.js is already loaded in the browser window, if so, // use this instance. Else, load via commonjs. - var moment = __webpack_require__(2); + var moment = __webpack_require__(43); /** * Test whether given object is a number @@ -1513,12338 +1513,11928 @@ return /******/ (function(modules) { // webpackBootstrap /* 2 */ /***/ function(module, exports, __webpack_require__) { - // first check if moment.js is already loaded in the browser window, if so, - // use this instance. Else, load via commonjs. - module.exports = (typeof window !== 'undefined') && window['moment'] || __webpack_require__(3); + // DOM utility methods + + /** + * this prepares the JSON container for allocating SVG elements + * @param JSONcontainer + * @private + */ + exports.prepareElements = function(JSONcontainer) { + // cleanup the redundant svgElements; + for (var elementType in JSONcontainer) { + if (JSONcontainer.hasOwnProperty(elementType)) { + JSONcontainer[elementType].redundant = JSONcontainer[elementType].used; + JSONcontainer[elementType].used = []; + } + } + }; + + /** + * this cleans up all the unused SVG elements. By asking for the parentNode, we only need to supply the JSON container from + * which to remove the redundant elements. + * + * @param JSONcontainer + * @private + */ + exports.cleanupElements = function(JSONcontainer) { + // cleanup the redundant svgElements; + for (var elementType in JSONcontainer) { + if (JSONcontainer.hasOwnProperty(elementType)) { + if (JSONcontainer[elementType].redundant) { + for (var i = 0; i < JSONcontainer[elementType].redundant.length; i++) { + JSONcontainer[elementType].redundant[i].parentNode.removeChild(JSONcontainer[elementType].redundant[i]); + } + JSONcontainer[elementType].redundant = []; + } + } + } + }; + + /** + * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer + * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this. + * + * @param elementType + * @param JSONcontainer + * @param svgContainer + * @returns {*} + * @private + */ + exports.getSVGElement = function (elementType, JSONcontainer, svgContainer) { + var element; + // allocate SVG element, if it doesnt yet exist, create one. + if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before + // check if there is an redundant element + if (JSONcontainer[elementType].redundant.length > 0) { + element = JSONcontainer[elementType].redundant[0]; + JSONcontainer[elementType].redundant.shift(); + } + else { + // create a new element and add it to the SVG + element = document.createElementNS('http://www.w3.org/2000/svg', elementType); + svgContainer.appendChild(element); + } + } + else { + // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it. + element = document.createElementNS('http://www.w3.org/2000/svg', elementType); + JSONcontainer[elementType] = {used: [], redundant: []}; + svgContainer.appendChild(element); + } + JSONcontainer[elementType].used.push(element); + return element; + }; + + + /** + * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer + * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this. + * + * @param elementType + * @param JSONcontainer + * @param DOMContainer + * @returns {*} + * @private + */ + exports.getDOMElement = function (elementType, JSONcontainer, DOMContainer, insertBefore) { + var element; + // allocate DOM element, if it doesnt yet exist, create one. + if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before + // check if there is an redundant element + if (JSONcontainer[elementType].redundant.length > 0) { + element = JSONcontainer[elementType].redundant[0]; + JSONcontainer[elementType].redundant.shift(); + } + else { + // create a new element and add it to the SVG + element = document.createElement(elementType); + if (insertBefore !== undefined) { + DOMContainer.insertBefore(element, insertBefore); + } + else { + DOMContainer.appendChild(element); + } + } + } + else { + // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it. + element = document.createElement(elementType); + JSONcontainer[elementType] = {used: [], redundant: []}; + if (insertBefore !== undefined) { + DOMContainer.insertBefore(element, insertBefore); + } + else { + DOMContainer.appendChild(element); + } + } + JSONcontainer[elementType].used.push(element); + return element; + }; + + + + + /** + * draw a point object. this is a seperate function because it can also be called by the legend. + * The reason the JSONcontainer and the target SVG svgContainer have to be supplied is so the legend can use these functions + * as well. + * + * @param x + * @param y + * @param group + * @param JSONcontainer + * @param svgContainer + * @returns {*} + */ + exports.drawPoint = function(x, y, group, JSONcontainer, svgContainer) { + var point; + if (group.options.drawPoints.style == 'circle') { + point = exports.getSVGElement('circle',JSONcontainer,svgContainer); + point.setAttributeNS(null, "cx", x); + point.setAttributeNS(null, "cy", y); + point.setAttributeNS(null, "r", 0.5 * group.options.drawPoints.size); + point.setAttributeNS(null, "class", group.className + " point"); + } + else { + point = exports.getSVGElement('rect',JSONcontainer,svgContainer); + point.setAttributeNS(null, "x", x - 0.5*group.options.drawPoints.size); + point.setAttributeNS(null, "y", y - 0.5*group.options.drawPoints.size); + point.setAttributeNS(null, "width", group.options.drawPoints.size); + point.setAttributeNS(null, "height", group.options.drawPoints.size); + point.setAttributeNS(null, "class", group.className + " point"); + } + return point; + }; + /** + * draw a bar SVG element centered on the X coordinate + * + * @param x + * @param y + * @param className + */ + exports.drawBar = function (x, y, width, height, className, JSONcontainer, svgContainer) { + if (height != 0) { + if (height < 0) { + height *= -1; + y -= height; + } + var rect = exports.getSVGElement('rect',JSONcontainer, svgContainer); + rect.setAttributeNS(null, "x", x - 0.5 * width); + rect.setAttributeNS(null, "y", y); + rect.setAttributeNS(null, "width", width); + rect.setAttributeNS(null, "height", height); + rect.setAttributeNS(null, "class", className); + } + }; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { - var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global, module) {//! moment.js - //! version : 2.8.3 - //! authors : Tim Wood, Iskren Chernev, Moment.js contributors - //! license : MIT - //! momentjs.com - - (function (undefined) { - /************************************ - Constants - ************************************/ + var util = __webpack_require__(1); - var moment, - VERSION = '2.8.3', - // the global-scope this is NOT the global object in Node.js - globalScope = typeof global !== 'undefined' ? global : this, - oldGlobalMoment, - round = Math.round, - hasOwnProperty = Object.prototype.hasOwnProperty, - i, + /** + * DataSet + * + * Usage: + * var dataSet = new DataSet({ + * fieldId: '_id', + * type: { + * // ... + * } + * }); + * + * dataSet.add(item); + * dataSet.add(data); + * dataSet.update(item); + * dataSet.update(data); + * dataSet.remove(id); + * dataSet.remove(ids); + * var data = dataSet.get(); + * var data = dataSet.get(id); + * var data = dataSet.get(ids); + * var data = dataSet.get(ids, options, data); + * dataSet.clear(); + * + * A data set can: + * - add/remove/update data + * - gives triggers upon changes in the data + * - can import/export data in various data formats + * + * @param {Array | DataTable} [data] Optional array with initial data + * @param {Object} [options] Available options: + * {String} fieldId Field name of the id in the + * items, 'id' by default. + * {Object. ['10', '00'] or '-1530' > ['-15', '30'] - parseTimezoneChunker = /([\+\-]|\d\d)/gi, + /** + * Add data. + * Adding an item will fail when there already is an item with the same id. + * @param {Object | Array | DataTable} data + * @param {String} [senderId] Optional sender id + * @return {Array} addedIds Array with the ids of the added items + */ + DataSet.prototype.add = function (data, senderId) { + var addedIds = [], + id, + me = this; - // getter and setter names - proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), - unitMillisecondFactors = { - 'Milliseconds' : 1, - 'Seconds' : 1e3, - 'Minutes' : 6e4, - 'Hours' : 36e5, - 'Days' : 864e5, - 'Months' : 2592e6, - 'Years' : 31536e6 - }, + if (Array.isArray(data)) { + // Array + for (var i = 0, len = data.length; i < len; i++) { + id = me._addItem(data[i]); + addedIds.push(id); + } + } + else if (util.isDataTable(data)) { + // Google DataTable + var columns = this._getColumnNames(data); + for (var row = 0, rows = data.getNumberOfRows(); row < rows; row++) { + var item = {}; + for (var col = 0, cols = columns.length; col < cols; col++) { + var field = columns[col]; + item[field] = data.getValue(row, col); + } - unitAliases = { - ms : 'millisecond', - s : 'second', - m : 'minute', - h : 'hour', - d : 'day', - D : 'date', - w : 'week', - W : 'isoWeek', - M : 'month', - Q : 'quarter', - y : 'year', - DDD : 'dayOfYear', - e : 'weekday', - E : 'isoWeekday', - gg: 'weekYear', - GG: 'isoWeekYear' - }, + id = me._addItem(item); + addedIds.push(id); + } + } + else if (data instanceof Object) { + // Single item + id = me._addItem(data); + addedIds.push(id); + } + else { + throw new Error('Unknown dataType'); + } - camelFunctions = { - dayofyear : 'dayOfYear', - isoweekday : 'isoWeekday', - isoweek : 'isoWeek', - weekyear : 'weekYear', - isoweekyear : 'isoWeekYear' - }, + if (addedIds.length) { + this._trigger('add', {items: addedIds}, senderId); + } - // format function strings - formatFunctions = {}, + return addedIds; + }; - // default relative time thresholds - relativeTimeThresholds = { - s: 45, // seconds to minute - m: 45, // minutes to hour - h: 22, // hours to day - d: 26, // days to month - M: 11 // months to year - }, + /** + * Update existing items. When an item does not exist, it will be created + * @param {Object | Array | DataTable} data + * @param {String} [senderId] Optional sender id + * @return {Array} updatedIds The ids of the added or updated items + */ + DataSet.prototype.update = function (data, senderId) { + var addedIds = []; + var updatedIds = []; + var updatedData = []; + var me = this; + var fieldId = me._fieldId; - // tokens to ordinalize and pad - ordinalizeTokens = 'DDD w W M D d'.split(' '), - paddedTokens = 'M D H h m s w W'.split(' '), + var addOrUpdate = function (item) { + var id = item[fieldId]; + if (me._data[id]) { + // update item + id = me._updateItem(item); + updatedIds.push(id); + updatedData.push(item); + } + else { + // add new item + id = me._addItem(item); + addedIds.push(id); + } + }; - formatTokenFunctions = { - M : function () { - return this.month() + 1; - }, - MMM : function (format) { - return this.localeData().monthsShort(this, format); - }, - MMMM : function (format) { - return this.localeData().months(this, format); - }, - D : function () { - return this.date(); - }, - DDD : function () { - return this.dayOfYear(); - }, - d : function () { - return this.day(); - }, - dd : function (format) { - return this.localeData().weekdaysMin(this, format); - }, - ddd : function (format) { - return this.localeData().weekdaysShort(this, format); - }, - dddd : function (format) { - return this.localeData().weekdays(this, format); - }, - w : function () { - return this.week(); - }, - W : function () { - return this.isoWeek(); - }, - YY : function () { - return leftZeroFill(this.year() % 100, 2); - }, - YYYY : function () { - return leftZeroFill(this.year(), 4); - }, - YYYYY : function () { - return leftZeroFill(this.year(), 5); - }, - YYYYYY : function () { - var y = this.year(), sign = y >= 0 ? '+' : '-'; - return sign + leftZeroFill(Math.abs(y), 6); - }, - gg : function () { - return leftZeroFill(this.weekYear() % 100, 2); - }, - gggg : function () { - return leftZeroFill(this.weekYear(), 4); - }, - ggggg : function () { - return leftZeroFill(this.weekYear(), 5); - }, - GG : function () { - return leftZeroFill(this.isoWeekYear() % 100, 2); - }, - GGGG : function () { - return leftZeroFill(this.isoWeekYear(), 4); - }, - GGGGG : function () { - return leftZeroFill(this.isoWeekYear(), 5); - }, - e : function () { - return this.weekday(); - }, - E : function () { - return this.isoWeekday(); - }, - a : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), true); - }, - A : function () { - return this.localeData().meridiem(this.hours(), this.minutes(), false); - }, - H : function () { - return this.hours(); - }, - h : function () { - return this.hours() % 12 || 12; - }, - m : function () { - return this.minutes(); - }, - s : function () { - return this.seconds(); - }, - S : function () { - return toInt(this.milliseconds() / 100); - }, - SS : function () { - return leftZeroFill(toInt(this.milliseconds() / 10), 2); - }, - SSS : function () { - return leftZeroFill(this.milliseconds(), 3); - }, - SSSS : function () { - return leftZeroFill(this.milliseconds(), 3); - }, - Z : function () { - var a = -this.zone(), - b = '+'; - if (a < 0) { - a = -a; - b = '-'; - } - return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2); - }, - ZZ : function () { - var a = -this.zone(), - b = '+'; - if (a < 0) { - a = -a; - b = '-'; - } - return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); - }, - z : function () { - return this.zoneAbbr(); - }, - zz : function () { - return this.zoneName(); - }, - X : function () { - return this.unix(); - }, - Q : function () { - return this.quarter(); - } - }, + if (Array.isArray(data)) { + // Array + for (var i = 0, len = data.length; i < len; i++) { + addOrUpdate(data[i]); + } + } + else if (util.isDataTable(data)) { + // Google DataTable + var columns = this._getColumnNames(data); + for (var row = 0, rows = data.getNumberOfRows(); row < rows; row++) { + var item = {}; + for (var col = 0, cols = columns.length; col < cols; col++) { + var field = columns[col]; + item[field] = data.getValue(row, col); + } - deprecations = {}, + addOrUpdate(item); + } + } + else if (data instanceof Object) { + // Single item + addOrUpdate(data); + } + else { + throw new Error('Unknown dataType'); + } - lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; + if (addedIds.length) { + this._trigger('add', {items: addedIds}, senderId); + } + if (updatedIds.length) { + this._trigger('update', {items: updatedIds, data: updatedData}, senderId); + } - // Pick the first defined of two or three arguments. dfl comes from - // default. - function dfl(a, b, c) { - switch (arguments.length) { - case 2: return a != null ? a : b; - case 3: return a != null ? a : b != null ? b : c; - default: throw new Error('Implement me'); - } - } + return addedIds.concat(updatedIds); + }; - function hasOwnProp(a, b) { - return hasOwnProperty.call(a, b); - } + /** + * Get a data item or multiple items. + * + * Usage: + * + * get() + * get(options: Object) + * get(options: Object, data: Array | DataTable) + * + * get(id: Number | String) + * get(id: Number | String, options: Object) + * get(id: Number | String, options: Object, data: Array | DataTable) + * + * get(ids: Number[] | String[]) + * get(ids: Number[] | String[], options: Object) + * get(ids: Number[] | String[], options: Object, data: Array | DataTable) + * + * Where: + * + * {Number | String} id The id of an item + * {Number[] | String{}} ids An array with ids of items + * {Object} options An Object with options. Available options: + * {String} [returnType] Type of data to be + * returned. Can be 'DataTable' or 'Array' (default) + * {Object.} [type] + * {String[]} [fields] field names to be returned + * {function} [filter] filter items + * {String | function} [order] Order the items by + * a field name or custom sort function. + * {Array | DataTable} [data] If provided, items will be appended to this + * array or table. Required in case of Google + * DataTable. + * + * @throws Error + */ + DataSet.prototype.get = function (args) { + var me = this; - function defaultParsingFlags() { - // We need to deep clone this object, and es5 standard is not very - // helpful. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso: false - }; - } + // parse the arguments + var id, ids, options, data; + var firstType = util.getType(arguments[0]); + if (firstType == 'String' || firstType == 'Number') { + // get(id [, options] [, data]) + id = arguments[0]; + options = arguments[1]; + data = arguments[2]; + } + else if (firstType == 'Array') { + // get(ids [, options] [, data]) + ids = arguments[0]; + options = arguments[1]; + data = arguments[2]; + } + else { + // get([, options] [, data]) + options = arguments[0]; + data = arguments[1]; + } - function printMsg(msg) { - if (moment.suppressDeprecationWarnings === false && - typeof console !== 'undefined' && console.warn) { - console.warn('Deprecation warning: ' + msg); - } - } + // determine the return type + var returnType; + if (options && options.returnType) { + var allowedValues = ["DataTable", "Array", "Object"]; + returnType = allowedValues.indexOf(options.returnType) == -1 ? "Array" : options.returnType; - function deprecate(msg, fn) { - var firstTime = true; - return extend(function () { - if (firstTime) { - printMsg(msg); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); + if (data && (returnType != util.getType(data))) { + throw new Error('Type of parameter "data" (' + util.getType(data) + ') ' + + 'does not correspond with specified options.type (' + options.type + ')'); + } + if (returnType == 'DataTable' && !util.isDataTable(data)) { + throw new Error('Parameter "data" must be a DataTable ' + + 'when options.type is "DataTable"'); } + } + else if (data) { + returnType = (util.getType(data) == 'DataTable') ? 'DataTable' : 'Array'; + } + else { + returnType = 'Array'; + } - function deprecateSimple(name, msg) { - if (!deprecations[name]) { - printMsg(msg); - deprecations[name] = true; + // build options + var type = options && options.type || this._options.type; + var filter = options && options.filter; + var items = [], item, itemId, i, len; + + // convert items + if (id != undefined) { + // return a single item + item = me._getItem(id, type); + if (filter && !filter(item)) { + item = null; + } + } + else if (ids != undefined) { + // return a subset of items + for (i = 0, len = ids.length; i < len; i++) { + item = me._getItem(ids[i], type); + if (!filter || filter(item)) { + items.push(item); + } + } + } + else { + // return all items + for (itemId in this._data) { + if (this._data.hasOwnProperty(itemId)) { + item = me._getItem(itemId, type); + if (!filter || filter(item)) { + items.push(item); } + } } + } - function padToken(func, count) { - return function (a) { - return leftZeroFill(func.call(this, a), count); - }; + // order the results + if (options && options.order && id == undefined) { + this._sort(items, options.order); + } + + // filter fields of the items + if (options && options.fields) { + var fields = options.fields; + if (id != undefined) { + item = this._filterFields(item, fields); } - function ordinalizeToken(func, period) { - return function (a) { - return this.localeData().ordinal(func.call(this, a), period); - }; + else { + for (i = 0, len = items.length; i < len; i++) { + items[i] = this._filterFields(items[i], fields); + } } + } - while (ordinalizeTokens.length) { - i = ordinalizeTokens.pop(); - formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i); + // return the results + if (returnType == 'DataTable') { + var columns = this._getColumnNames(data); + if (id != undefined) { + // append a single item to the data table + me._appendRow(data, columns, item); } - while (paddedTokens.length) { - i = paddedTokens.pop(); - formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); + else { + // copy the items to the provided data table + for (i = 0; i < items.length; i++) { + me._appendRow(data, columns, items[i]); + } } - formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); - - - /************************************ - Constructors - ************************************/ - - function Locale() { + return data; + } + else if (returnType == "Object") { + var result = {}; + for (i = 0; i < items.length; i++) { + result[items[i].id] = items[i]; } - - // Moment prototype object - function Moment(config, skipOverflow) { - if (skipOverflow !== false) { - checkOverflow(config); + return result; + } + else { + // return an array + if (id != undefined) { + // a single item + return item; + } + else { + // multiple items + if (data) { + // copy the items to the provided array + for (i = 0, len = items.length; i < len; i++) { + data.push(items[i]); } - copyConfig(this, config); - this._d = new Date(+config._d); + return data; + } + else { + // just return our array + return items; + } } + } + }; - // Duration Constructor - function Duration(duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; - - // representation for dateAddRemove - this._milliseconds = +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 36e5; // 1000 * 60 * 60 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + - weeks * 7; - // It is impossible translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + - quarters * 3 + - years * 12; + /** + * Get ids of all items or from a filtered set of items. + * @param {Object} [options] An Object with options. Available options: + * {function} [filter] filter items + * {String | function} [order] Order the items by + * a field name or custom sort function. + * @return {Array} ids + */ + DataSet.prototype.getIds = function (options) { + var data = this._data, + filter = options && options.filter, + order = options && options.order, + type = options && options.type || this._options.type, + i, + len, + id, + item, + items, + ids = []; - this._data = {}; + if (filter) { + // get filtered items + if (order) { + // create ordered list + items = []; + for (id in data) { + if (data.hasOwnProperty(id)) { + item = this._getItem(id, type); + if (filter(item)) { + items.push(item); + } + } + } - this._locale = moment.localeData(); + this._sort(items, order); - this._bubble(); + for (i = 0, len = items.length; i < len; i++) { + ids[i] = items[i][this._fieldId]; + } } - - /************************************ - Helpers - ************************************/ - - - function extend(a, b) { - for (var i in b) { - if (hasOwnProp(b, i)) { - a[i] = b[i]; - } + else { + // create unordered list + for (id in data) { + if (data.hasOwnProperty(id)) { + item = this._getItem(id, type); + if (filter(item)) { + ids.push(item[this._fieldId]); + } } - - if (hasOwnProp(b, 'toString')) { - a.toString = b.toString; + } + } + } + else { + // get all items + if (order) { + // create an ordered list + items = []; + for (id in data) { + if (data.hasOwnProperty(id)) { + items.push(data[id]); } + } - if (hasOwnProp(b, 'valueOf')) { - a.valueOf = b.valueOf; - } + this._sort(items, order); - return a; + for (i = 0, len = items.length; i < len; i++) { + ids[i] = items[i][this._fieldId]; + } } - - function copyConfig(to, from) { - var i, prop, val; - - if (typeof from._isAMomentObject !== 'undefined') { - to._isAMomentObject = from._isAMomentObject; - } - if (typeof from._i !== 'undefined') { - to._i = from._i; - } - if (typeof from._f !== 'undefined') { - to._f = from._f; - } - if (typeof from._l !== 'undefined') { - to._l = from._l; - } - if (typeof from._strict !== 'undefined') { - to._strict = from._strict; - } - if (typeof from._tzm !== 'undefined') { - to._tzm = from._tzm; - } - if (typeof from._isUTC !== 'undefined') { - to._isUTC = from._isUTC; - } - if (typeof from._offset !== 'undefined') { - to._offset = from._offset; - } - if (typeof from._pf !== 'undefined') { - to._pf = from._pf; - } - if (typeof from._locale !== 'undefined') { - to._locale = from._locale; - } - - if (momentProperties.length > 0) { - for (i in momentProperties) { - prop = momentProperties[i]; - val = from[prop]; - if (typeof val !== 'undefined') { - to[prop] = val; - } - } - } - - return to; - } - - function absRound(number) { - if (number < 0) { - return Math.ceil(number); - } else { - return Math.floor(number); - } - } - - // left zero fill a number - // see http://jsperf.com/left-zero-filling for performance comparison - function leftZeroFill(number, targetLength, forceSign) { - var output = '' + Math.abs(number), - sign = number >= 0; - - while (output.length < targetLength) { - output = '0' + output; - } - return (sign ? (forceSign ? '+' : '') : '-') + output; - } - - function positiveMomentsDifference(base, other) { - var res = {milliseconds: 0, months: 0}; - - res.months = other.month() - base.month() + - (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; - } - - res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - - return res; - } - - function momentsDifference(base, other) { - var res; - other = makeAs(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } - - return res; - } - - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).'); - tmp = val; val = period; period = tmp; - } - - val = typeof val === 'string' ? +val : val; - dur = moment.duration(val, period); - addOrSubtractDurationFromMoment(this, dur, direction); - return this; - }; - } - - function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = duration._days, - months = duration._months; - updateOffset = updateOffset == null ? true : updateOffset; - - if (milliseconds) { - mom._d.setTime(+mom._d + milliseconds * isAdding); - } - if (days) { - rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); - } - if (months) { - rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); - } - if (updateOffset) { - moment.updateOffset(mom, days || months); - } - } - - // check if is an array - function isArray(input) { - return Object.prototype.toString.call(input) === '[object Array]'; - } - - function isDate(input) { - return Object.prototype.toString.call(input) === '[object Date]' || - input instanceof Date; - } - - // compare two arrays, return the number of differences - function compareArrays(array1, array2, dontConvert) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if ((dontConvert && array1[i] !== array2[i]) || - (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { - diffs++; - } - } - return diffs + lengthDiff; - } - - function normalizeUnits(units) { - if (units) { - var lowered = units.toLowerCase().replace(/(.)s$/, '$1'); - units = unitAliases[units] || camelFunctions[lowered] || lowered; - } - return units; - } - - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; - - for (prop in inputObject) { - if (hasOwnProp(inputObject, prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; - } - } - } - - return normalizedInput; - } - - function makeList(field) { - var count, setter; - - if (field.indexOf('week') === 0) { - count = 7; - setter = 'day'; - } - else if (field.indexOf('month') === 0) { - count = 12; - setter = 'month'; - } - else { - return; - } - - moment[field] = function (format, index) { - var i, getter, - method = moment._locale[field], - results = []; - - if (typeof format === 'number') { - index = format; - format = undefined; - } - - getter = function (i) { - var m = moment().utc().set(setter, i); - return method.call(moment._locale, m, format || ''); - }; - - if (index != null) { - return getter(index); - } - else { - for (i = 0; i < count; i++) { - results.push(getter(i)); - } - return results; - } - }; - } - - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; - - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - if (coercedNumber >= 0) { - value = Math.floor(coercedNumber); - } else { - value = Math.ceil(coercedNumber); - } - } - - return value; - } - - function daysInMonth(year, month) { - return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); - } - - function weeksInYear(year, dow, doy) { - return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; - } - - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; - } - - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } - - function checkOverflow(m) { - var overflow; - if (m._a && m._pf.overflow === -2) { - overflow = - m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : - m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : - m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : - m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : - m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : - m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : - -1; - - if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { - overflow = DATE; - } - - m._pf.overflow = overflow; + else { + // create unordered list + for (id in data) { + if (data.hasOwnProperty(id)) { + item = data[id]; + ids.push(item[this._fieldId]); } + } } + } - function isValid(m) { - if (m._isValid == null) { - m._isValid = !isNaN(m._d.getTime()) && - m._pf.overflow < 0 && - !m._pf.empty && - !m._pf.invalidMonth && - !m._pf.nullInput && - !m._pf.invalidFormat && - !m._pf.userInvalidated; + return ids; + }; - if (m._strict) { - m._isValid = m._isValid && - m._pf.charsLeftOver === 0 && - m._pf.unusedTokens.length === 0; - } - } - return m._isValid; - } + /** + * Returns the DataSet itself. Is overwritten for example by the DataView, + * which returns the DataSet it is connected to instead. + */ + DataSet.prototype.getDataSet = function () { + return this; + }; - function normalizeLocale(key) { - return key ? key.toLowerCase().replace('_', '-') : key; - } + /** + * Execute a callback function for every item in the dataset. + * @param {function} callback + * @param {Object} [options] Available options: + * {Object.} [type] + * {String[]} [fields] filter fields + * {function} [filter] filter items + * {String | function} [order] Order the items by + * a field name or custom sort function. + */ + DataSet.prototype.forEach = function (callback, options) { + var filter = options && options.filter, + type = options && options.type || this._options.type, + data = this._data, + item, + id; - // pick the locale from the array - // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - function chooseLocale(names) { - var i = 0, j, next, locale, split; + if (options && options.order) { + // execute forEach on ordered list + var items = this.get(options); - while (i < names.length) { - split = normalizeLocale(names[i]).split('-'); - j = split.length; - next = normalizeLocale(names[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - locale = loadLocale(split.slice(0, j).join('-')); - if (locale) { - return locale; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return null; + for (var i = 0, len = items.length; i < len; i++) { + item = items[i]; + id = item[this._fieldId]; + callback(item, id); } - - function loadLocale(name) { - var oldLocale = null; - if (!locales[name] && hasModule) { - try { - oldLocale = moment.locale(); - !(function webpackMissingModule() { var e = new Error("Cannot find module \"./locale\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()); - // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales - moment.locale(oldLocale); - } catch (e) { } + } + else { + // unordered + for (id in data) { + if (data.hasOwnProperty(id)) { + item = this._getItem(id, type); + if (!filter || filter(item)) { + callback(item, id); } - return locales[name]; - } - - // Return a moment from input, that is local/utc/zone equivalent to model. - function makeAs(input, model) { - return model._isUTC ? moment(input).zone(model._offset || 0) : - moment(input).local(); + } } + } + }; - /************************************ - Locale - ************************************/ - - - extend(Locale.prototype, { - - set : function (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (typeof prop === 'function') { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - }, - - _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - months : function (m) { - return this._months[m.month()]; - }, - - _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - monthsShort : function (m) { - return this._monthsShort[m.month()]; - }, - - monthsParse : function (monthName) { - var i, mom, regex; - - if (!this._monthsParse) { - this._monthsParse = []; - } - - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - if (!this._monthsParse[i]) { - mom = moment.utc([2000, i]); - regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (this._monthsParse[i].test(monthName)) { - return i; - } - } - }, - - _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdays : function (m) { - return this._weekdays[m.day()]; - }, - - _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysShort : function (m) { - return this._weekdaysShort[m.day()]; - }, - - _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - weekdaysMin : function (m) { - return this._weekdaysMin[m.day()]; - }, - - weekdaysParse : function (weekdayName) { - var i, mom, regex; - - if (!this._weekdaysParse) { - this._weekdaysParse = []; - } - - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - if (!this._weekdaysParse[i]) { - mom = moment([2000, 1]).day(i); - regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (this._weekdaysParse[i].test(weekdayName)) { - return i; - } - } - }, - - _longDateFormat : { - LT : 'h:mm A', - L : 'MM/DD/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY LT', - LLLL : 'dddd, MMMM D, YYYY LT' - }, - longDateFormat : function (key) { - var output = this._longDateFormat[key]; - if (!output && this._longDateFormat[key.toUpperCase()]) { - output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { - return val.slice(1); - }); - this._longDateFormat[key] = output; - } - return output; - }, - - isPM : function (input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return ((input + '').toLowerCase().charAt(0) === 'p'); - }, + /** + * Map every item in the dataset. + * @param {function} callback + * @param {Object} [options] Available options: + * {Object.} [type] + * {String[]} [fields] filter fields + * {function} [filter] filter items + * {String | function} [order] Order the items by + * a field name or custom sort function. + * @return {Object[]} mappedItems + */ + DataSet.prototype.map = function (callback, options) { + var filter = options && options.filter, + type = options && options.type || this._options.type, + mappedItems = [], + data = this._data, + item; - _meridiemParse : /[ap]\.?m?\.?/i, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - }, - - _calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - calendar : function (key, mom) { - var output = this._calendar[key]; - return typeof output === 'function' ? output.apply(mom) : output; - }, - - _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' - }, - - relativeTime : function (number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return (typeof output === 'function') ? - output(number, withoutSuffix, string, isFuture) : - output.replace(/%d/i, number); - }, - - pastFuture : function (diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); - }, - - ordinal : function (number) { - return this._ordinal.replace('%d', number); - }, - _ordinal : '%d', - - preparse : function (string) { - return string; - }, - - postformat : function (string) { - return string; - }, - - week : function (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - }, - - _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. - }, - - _invalidDate: 'Invalid date', - invalidDate: function () { - return this._invalidDate; - } - }); - - /************************************ - Formatting - ************************************/ - - - function removeFormattingTokens(input) { - if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ''); - } - return input.replace(/\\/g, ''); - } - - function makeFormatFunction(format) { - var array = format.match(formattingTokens), i, length; - - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } - } - - return function (mom) { - var output = ''; - for (i = 0; i < length; i++) { - output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; - } - return output; - }; - } - - // format date using native date object - function formatMoment(m, format) { - if (!m.isValid()) { - return m.localeData().invalidDate(); - } - - format = expandFormat(format, m.localeData()); - - if (!formatFunctions[format]) { - formatFunctions[format] = makeFormatFunction(format); - } - - return formatFunctions[format](m); - } - - function expandFormat(format, locale) { - var i = 5; - - function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; - } - - localFormattingTokens.lastIndex = 0; - while (i >= 0 && localFormattingTokens.test(format)) { - format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); - localFormattingTokens.lastIndex = 0; - i -= 1; - } - - return format; - } - - - /************************************ - Parsing - ************************************/ - - - // get the regex to find the next token - function getParseRegexForToken(token, config) { - var a, strict = config._strict; - switch (token) { - case 'Q': - return parseTokenOneDigit; - case 'DDDD': - return parseTokenThreeDigits; - case 'YYYY': - case 'GGGG': - case 'gggg': - return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; - case 'Y': - case 'G': - case 'g': - return parseTokenSignedNumber; - case 'YYYYYY': - case 'YYYYY': - case 'GGGGG': - case 'ggggg': - return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; - case 'S': - if (strict) { - return parseTokenOneDigit; - } - /* falls through */ - case 'SS': - if (strict) { - return parseTokenTwoDigits; - } - /* falls through */ - case 'SSS': - if (strict) { - return parseTokenThreeDigits; - } - /* falls through */ - case 'DDD': - return parseTokenOneToThreeDigits; - case 'MMM': - case 'MMMM': - case 'dd': - case 'ddd': - case 'dddd': - return parseTokenWord; - case 'a': - case 'A': - return config._locale._meridiemParse; - case 'X': - return parseTokenTimestampMs; - case 'Z': - case 'ZZ': - return parseTokenTimezone; - case 'T': - return parseTokenT; - case 'SSSS': - return parseTokenDigits; - case 'MM': - case 'DD': - case 'YY': - case 'GG': - case 'gg': - case 'HH': - case 'hh': - case 'mm': - case 'ss': - case 'ww': - case 'WW': - return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; - case 'M': - case 'D': - case 'd': - case 'H': - case 'h': - case 'm': - case 's': - case 'w': - case 'W': - case 'e': - case 'E': - return parseTokenOneOrTwoDigits; - case 'Do': - return parseTokenOrdinal; - default : - a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); - return a; - } - } - - function timezoneMinutesFromString(string) { - string = string || ''; - var possibleTzMatches = (string.match(parseTokenTimezone) || []), - tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], - parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], - minutes = +(parts[1] * 60) + toInt(parts[2]); - - return parts[0] === '+' ? -minutes : minutes; - } - - // function to convert string input to date - function addTimeToArrayFromToken(token, input, config) { - var a, datePartArray = config._a; - - switch (token) { - // QUARTER - case 'Q': - if (input != null) { - datePartArray[MONTH] = (toInt(input) - 1) * 3; - } - break; - // MONTH - case 'M' : // fall through to MM - case 'MM' : - if (input != null) { - datePartArray[MONTH] = toInt(input) - 1; - } - break; - case 'MMM' : // fall through to MMMM - case 'MMMM' : - a = config._locale.monthsParse(input); - // if we didn't find a month name, mark the date as invalid. - if (a != null) { - datePartArray[MONTH] = a; - } else { - config._pf.invalidMonth = input; - } - break; - // DAY OF MONTH - case 'D' : // fall through to DD - case 'DD' : - if (input != null) { - datePartArray[DATE] = toInt(input); - } - break; - case 'Do' : - if (input != null) { - datePartArray[DATE] = toInt(parseInt(input, 10)); - } - break; - // DAY OF YEAR - case 'DDD' : // fall through to DDDD - case 'DDDD' : - if (input != null) { - config._dayOfYear = toInt(input); - } - - break; - // YEAR - case 'YY' : - datePartArray[YEAR] = moment.parseTwoDigitYear(input); - break; - case 'YYYY' : - case 'YYYYY' : - case 'YYYYYY' : - datePartArray[YEAR] = toInt(input); - break; - // AM / PM - case 'a' : // fall through to A - case 'A' : - config._isPm = config._locale.isPM(input); - break; - // 24 HOUR - case 'H' : // fall through to hh - case 'HH' : // fall through to hh - case 'h' : // fall through to hh - case 'hh' : - datePartArray[HOUR] = toInt(input); - break; - // MINUTE - case 'm' : // fall through to mm - case 'mm' : - datePartArray[MINUTE] = toInt(input); - break; - // SECOND - case 's' : // fall through to ss - case 'ss' : - datePartArray[SECOND] = toInt(input); - break; - // MILLISECOND - case 'S' : - case 'SS' : - case 'SSS' : - case 'SSSS' : - datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); - break; - // UNIX TIMESTAMP WITH MS - case 'X': - config._d = new Date(parseFloat(input) * 1000); - break; - // TIMEZONE - case 'Z' : // fall through to ZZ - case 'ZZ' : - config._useUTC = true; - config._tzm = timezoneMinutesFromString(input); - break; - // WEEKDAY - human - case 'dd': - case 'ddd': - case 'dddd': - a = config._locale.weekdaysParse(input); - // if we didn't get a weekday name, mark the date as invalid - if (a != null) { - config._w = config._w || {}; - config._w['d'] = a; - } else { - config._pf.invalidWeekday = input; - } - break; - // WEEK, WEEK DAY - numeric - case 'w': - case 'ww': - case 'W': - case 'WW': - case 'd': - case 'e': - case 'E': - token = token.substr(0, 1); - /* falls through */ - case 'gggg': - case 'GGGG': - case 'GGGGG': - token = token.substr(0, 2); - if (input) { - config._w = config._w || {}; - config._w[token] = toInt(input); - } - break; - case 'gg': - case 'GG': - config._w = config._w || {}; - config._w[token] = moment.parseTwoDigitYear(input); - } - } - - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); - week = dfl(w.W, 1); - weekday = dfl(w.E, 1); - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); - week = dfl(w.w, 1); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < dow) { - ++week; - } - } else if (w.e != null) { - // local weekday -- counting starts from begining of week - weekday = w.e + dow; - } else { - // default to begining of week - weekday = dow; - } - } - temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function dateFromConfig(config) { - var i, date, input = [], currentDate, yearToUse; - - if (config._d) { - return; - } - - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); - } - - //if the day of the year is set, figure out what it is - if (config._dayOfYear) { - yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); - - if (config._dayOfYear > daysInYear(yearToUse)) { - config._pf._overflowDayOfYear = true; - } - - date = makeUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } - - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } - - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - - config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); - // Apply timezone offset from input. The actual zone can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); - } - } - - function dateFromObject(config) { - var normalizedInput; - - if (config._d) { - return; - } - - normalizedInput = normalizeObjectUnits(config._i); - config._a = [ - normalizedInput.year, - normalizedInput.month, - normalizedInput.day, - normalizedInput.hour, - normalizedInput.minute, - normalizedInput.second, - normalizedInput.millisecond - ]; - - dateFromConfig(config); - } - - function currentDateArray(config) { - var now = new Date(); - if (config._useUTC) { - return [ - now.getUTCFullYear(), - now.getUTCMonth(), - now.getUTCDate() - ]; - } else { - return [now.getFullYear(), now.getMonth(), now.getDate()]; - } - } - - // date from string and format string - function makeDateFromStringAndFormat(config) { - if (config._f === moment.ISO_8601) { - parseISO(config); - return; - } - - config._a = []; - config._pf.empty = true; - - // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, - i, parsedInput, tokens, token, skipped, - stringLength = string.length, - totalParsedInputLength = 0; - - tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - - for (i = 0; i < tokens.length; i++) { - token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; - if (parsedInput) { - skipped = string.substr(0, string.indexOf(parsedInput)); - if (skipped.length > 0) { - config._pf.unusedInput.push(skipped); - } - string = string.slice(string.indexOf(parsedInput) + parsedInput.length); - totalParsedInputLength += parsedInput.length; - } - // don't parse if it's not a known token - if (formatTokenFunctions[token]) { - if (parsedInput) { - config._pf.empty = false; - } - else { - config._pf.unusedTokens.push(token); - } - addTimeToArrayFromToken(token, parsedInput, config); - } - else if (config._strict && !parsedInput) { - config._pf.unusedTokens.push(token); - } - } - - // add remaining unparsed input length to the string - config._pf.charsLeftOver = stringLength - totalParsedInputLength; - if (string.length > 0) { - config._pf.unusedInput.push(string); - } - - // handle am pm - if (config._isPm && config._a[HOUR] < 12) { - config._a[HOUR] += 12; - } - // if is 12 am, change hours to 0 - if (config._isPm === false && config._a[HOUR] === 12) { - config._a[HOUR] = 0; - } - - dateFromConfig(config); - checkOverflow(config); - } - - function unescapeFormat(s) { - return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - }); - } - - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function regexpEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - } - - // date from string and array of format strings - function makeDateFromStringAndArray(config) { - var tempConfig, - bestMoment, - - scoreToBeat, - i, - currentScore; - - if (config._f.length === 0) { - config._pf.invalidFormat = true; - config._d = new Date(NaN); - return; - } - - for (i = 0; i < config._f.length; i++) { - currentScore = 0; - tempConfig = copyConfig({}, config); - if (config._useUTC != null) { - tempConfig._useUTC = config._useUTC; - } - tempConfig._pf = defaultParsingFlags(); - tempConfig._f = config._f[i]; - makeDateFromStringAndFormat(tempConfig); - - if (!isValid(tempConfig)) { - continue; - } - - // if there is any input that was not parsed add a penalty for that format - currentScore += tempConfig._pf.charsLeftOver; - - //or tokens - currentScore += tempConfig._pf.unusedTokens.length * 10; - - tempConfig._pf.score = currentScore; - - if (scoreToBeat == null || currentScore < scoreToBeat) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - } - } - - extend(config, bestMoment || tempConfig); - } - - // date from iso format - function parseISO(config) { - var i, l, - string = config._i, - match = isoRegex.exec(string); - - if (match) { - config._pf.iso = true; - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(string)) { - // match[5] should be 'T' or undefined - config._f = isoDates[i][0] + (match[6] || ' '); - break; - } - } - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(string)) { - config._f += isoTimes[i][0]; - break; - } - } - if (string.match(parseTokenTimezone)) { - config._f += 'Z'; - } - makeDateFromStringAndFormat(config); - } else { - config._isValid = false; - } - } - - // date from iso format or fallback - function makeDateFromString(config) { - parseISO(config); - if (config._isValid === false) { - delete config._isValid; - moment.createFromInputFallback(config); - } - } - - function map(arr, fn) { - var res = [], i; - for (i = 0; i < arr.length; ++i) { - res.push(fn(arr[i], i)); - } - return res; - } - - function makeDateFromInput(config) { - var input = config._i, matched; - if (input === undefined) { - config._d = new Date(); - } else if (isDate(input)) { - config._d = new Date(+input); - } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { - config._d = new Date(+matched[1]); - } else if (typeof input === 'string') { - makeDateFromString(config); - } else if (isArray(input)) { - config._a = map(input.slice(0), function (obj) { - return parseInt(obj, 10); - }); - dateFromConfig(config); - } else if (typeof(input) === 'object') { - dateFromObject(config); - } else if (typeof(input) === 'number') { - // from milliseconds - config._d = new Date(input); - } else { - moment.createFromInputFallback(config); - } - } - - function makeDate(y, m, d, h, M, s, ms) { - //can't just apply() to create a date: - //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply - var date = new Date(y, m, d, h, M, s, ms); - - //the date constructor doesn't accept years < 1970 - if (y < 1970) { - date.setFullYear(y); - } - return date; - } - - function makeUTCDate(y) { - var date = new Date(Date.UTC.apply(null, arguments)); - if (y < 1970) { - date.setUTCFullYear(y); - } - return date; - } - - function parseWeekday(input, locale) { - if (typeof input === 'string') { - if (!isNaN(input)) { - input = parseInt(input, 10); - } - else { - input = locale.weekdaysParse(input); - if (typeof input !== 'number') { - return null; - } - } - } - return input; - } - - /************************************ - Relative Time - ************************************/ - - - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } - - function relativeTime(posNegDuration, withoutSuffix, locale) { - var duration = moment.duration(posNegDuration).abs(), - seconds = round(duration.as('s')), - minutes = round(duration.as('m')), - hours = round(duration.as('h')), - days = round(duration.as('d')), - months = round(duration.as('M')), - years = round(duration.as('y')), - - args = seconds < relativeTimeThresholds.s && ['s', seconds] || - minutes === 1 && ['m'] || - minutes < relativeTimeThresholds.m && ['mm', minutes] || - hours === 1 && ['h'] || - hours < relativeTimeThresholds.h && ['hh', hours] || - days === 1 && ['d'] || - days < relativeTimeThresholds.d && ['dd', days] || - months === 1 && ['M'] || - months < relativeTimeThresholds.M && ['MM', months] || - years === 1 && ['y'] || ['yy', years]; - - args[2] = withoutSuffix; - args[3] = +posNegDuration > 0; - args[4] = locale; - return substituteTimeAgo.apply({}, args); - } - - - /************************************ - Week of Year - ************************************/ - - - // firstDayOfWeek 0 = sun, 6 = sat - // the day of the week that starts the week - // (usually sunday or monday) - // firstDayOfWeekOfYear 0 = sun, 6 = sat - // the first week is the week that contains the first - // of this day of the week - // (eg. ISO weeks use thursday (4)) - function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { - var end = firstDayOfWeekOfYear - firstDayOfWeek, - daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), - adjustedMoment; - - - if (daysToDayOfWeek > end) { - daysToDayOfWeek -= 7; - } - - if (daysToDayOfWeek < end - 7) { - daysToDayOfWeek += 7; - } - - adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); - return { - week: Math.ceil(adjustedMoment.dayOfYear() / 7), - year: adjustedMoment.year() - }; - } - - //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { - var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; - - d = d === 0 ? 7 : d; - weekday = weekday != null ? weekday : firstDayOfWeek; - daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); - dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; - - return { - year: dayOfYear > 0 ? year : year - 1, - dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear - }; - } - - /************************************ - Top Level Functions - ************************************/ - - function makeMoment(config) { - var input = config._i, - format = config._f; - - config._locale = config._locale || moment.localeData(config._l); - - if (input === null || (format === undefined && input === '')) { - return moment.invalid({nullInput: true}); - } - - if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); - } - - if (moment.isMoment(input)) { - return new Moment(input, true); - } else if (format) { - if (isArray(format)) { - makeDateFromStringAndArray(config); - } else { - makeDateFromStringAndFormat(config); - } - } else { - makeDateFromInput(config); - } - - return new Moment(config); - } - - moment = function (input, format, locale, strict) { - var c; - - if (typeof(locale) === 'boolean') { - strict = locale; - locale = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c = {}; - c._isAMomentObject = true; - c._i = input; - c._f = format; - c._l = locale; - c._strict = strict; - c._isUTC = false; - c._pf = defaultParsingFlags(); - - return makeMoment(c); - }; - - moment.suppressDeprecationWarnings = false; - - moment.createFromInputFallback = deprecate( - 'moment construction falls back to js Date. This is ' + - 'discouraged and will be removed in upcoming major ' + - 'release. Please refer to ' + - 'https://github.com/moment/moment/issues/1407 for more info.', - function (config) { - config._d = new Date(config._i); - } - ); - - // Pick a moment m from moments so that m[fn](other) is true for all - // other. This relies on the function fn to be transitive. - // - // moments should either be an array of moment objects or an array, whose - // first element is an array of moment objects. - function pickBy(fn, moments) { - var res, i; - if (moments.length === 1 && isArray(moments[0])) { - moments = moments[0]; - } - if (!moments.length) { - return moment(); - } - res = moments[0]; - for (i = 1; i < moments.length; ++i) { - if (moments[i][fn](res)) { - res = moments[i]; - } - } - return res; - } - - moment.min = function () { - var args = [].slice.call(arguments, 0); - - return pickBy('isBefore', args); - }; - - moment.max = function () { - var args = [].slice.call(arguments, 0); - - return pickBy('isAfter', args); - }; - - // creating with utc - moment.utc = function (input, format, locale, strict) { - var c; - - if (typeof(locale) === 'boolean') { - strict = locale; - locale = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c = {}; - c._isAMomentObject = true; - c._useUTC = true; - c._isUTC = true; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; - c._pf = defaultParsingFlags(); - - return makeMoment(c).utc(); - }; - - // creating with unix timestamp (in seconds) - moment.unix = function (input) { - return moment(input * 1000); - }; - - // duration - moment.duration = function (input, key) { - var duration = input, - // matching against regexp is expensive, do it on demand - match = null, - sign, - ret, - parseIso, - diffRes; - - if (moment.isDuration(input)) { - duration = { - ms: input._milliseconds, - d: input._days, - M: input._months - }; - } else if (typeof input === 'number') { - duration = {}; - if (key) { - duration[key] = input; - } else { - duration.milliseconds = input; - } - } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y: 0, - d: toInt(match[DATE]) * sign, - h: toInt(match[HOUR]) * sign, - m: toInt(match[MINUTE]) * sign, - s: toInt(match[SECOND]) * sign, - ms: toInt(match[MILLISECOND]) * sign - }; - } else if (!!(match = isoDurationRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - parseIso = function (inp) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - }; - duration = { - y: parseIso(match[2]), - M: parseIso(match[3]), - d: parseIso(match[4]), - h: parseIso(match[5]), - m: parseIso(match[6]), - s: parseIso(match[7]), - w: parseIso(match[8]) - }; - } else if (typeof duration === 'object' && - ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(moment(duration.from), moment(duration.to)); - - duration = {}; - duration.ms = diffRes.milliseconds; - duration.M = diffRes.months; - } - - ret = new Duration(duration); - - if (moment.isDuration(input) && hasOwnProp(input, '_locale')) { - ret._locale = input._locale; - } - - return ret; - }; - - // version number - moment.version = VERSION; - - // default format - moment.defaultFormat = isoFormat; - - // constant that refers to the ISO standard - moment.ISO_8601 = function () {}; - - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - moment.momentProperties = momentProperties; - - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - moment.updateOffset = function () {}; - - // This function allows you to set a threshold for relative time strings - moment.relativeTimeThreshold = function (threshold, limit) { - if (relativeTimeThresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return relativeTimeThresholds[threshold]; - } - relativeTimeThresholds[threshold] = limit; - return true; - }; - - moment.lang = deprecate( - 'moment.lang is deprecated. Use moment.locale instead.', - function (key, value) { - return moment.locale(key, value); - } - ); - - // This function will load locale and then set the global locale. If - // no arguments are passed in, it will simply return the current global - // locale key. - moment.locale = function (key, values) { - var data; - if (key) { - if (typeof(values) !== 'undefined') { - data = moment.defineLocale(key, values); - } - else { - data = moment.localeData(key); - } - - if (data) { - moment.duration._locale = moment._locale = data; - } - } - - return moment._locale._abbr; - }; - - moment.defineLocale = function (name, values) { - if (values !== null) { - values.abbr = name; - if (!locales[name]) { - locales[name] = new Locale(); - } - locales[name].set(values); - - // backwards compat for now: also set the locale - moment.locale(name); - - return locales[name]; - } else { - // useful for testing - delete locales[name]; - return null; - } - }; - - moment.langData = deprecate( - 'moment.langData is deprecated. Use moment.localeData instead.', - function (key) { - return moment.localeData(key); - } - ); - - // returns locale data - moment.localeData = function (key) { - var locale; - - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; - } - - if (!key) { - return moment._locale; - } - - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; - } - - return chooseLocale(key); - }; - - // compare moment object - moment.isMoment = function (obj) { - return obj instanceof Moment || - (obj != null && hasOwnProp(obj, '_isAMomentObject')); - }; - - // for typechecking Duration objects - moment.isDuration = function (obj) { - return obj instanceof Duration; - }; - - for (i = lists.length - 1; i >= 0; --i) { - makeList(lists[i]); - } - - moment.normalizeUnits = function (units) { - return normalizeUnits(units); - }; - - moment.invalid = function (flags) { - var m = moment.utc(NaN); - if (flags != null) { - extend(m._pf, flags); - } - else { - m._pf.userInvalidated = true; - } - - return m; - }; - - moment.parseZone = function () { - return moment.apply(null, arguments).parseZone(); - }; - - moment.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; - - /************************************ - Moment Prototype - ************************************/ - - - extend(moment.fn = Moment.prototype, { - - clone : function () { - return moment(this); - }, - - valueOf : function () { - return +this._d + ((this._offset || 0) * 60000); - }, - - unix : function () { - return Math.floor(+this / 1000); - }, - - toString : function () { - return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); - }, - - toDate : function () { - return this._offset ? new Date(+this) : this._d; - }, - - toISOString : function () { - var m = moment(this).utc(); - if (0 < m.year() && m.year() <= 9999) { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } else { - return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } - }, - - toArray : function () { - var m = this; - return [ - m.year(), - m.month(), - m.date(), - m.hours(), - m.minutes(), - m.seconds(), - m.milliseconds() - ]; - }, - - isValid : function () { - return isValid(this); - }, - - isDSTShifted : function () { - if (this._a) { - return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; - } - - return false; - }, - - parsingFlags : function () { - return extend({}, this._pf); - }, - - invalidAt: function () { - return this._pf.overflow; - }, - - utc : function (keepLocalTime) { - return this.zone(0, keepLocalTime); - }, - - local : function (keepLocalTime) { - if (this._isUTC) { - this.zone(0, keepLocalTime); - this._isUTC = false; - - if (keepLocalTime) { - this.add(this._dateTzOffset(), 'm'); - } - } - return this; - }, - - format : function (inputString) { - var output = formatMoment(this, inputString || moment.defaultFormat); - return this.localeData().postformat(output); - }, - - add : createAdder(1, 'add'), - - subtract : createAdder(-1, 'subtract'), - - diff : function (input, units, asFloat) { - var that = makeAs(input, this), - zoneDiff = (this.zone() - that.zone()) * 6e4, - diff, output, daysAdjust; - - units = normalizeUnits(units); - - if (units === 'year' || units === 'month') { - // average number of days in the months in the given dates - diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 - // difference in months - output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); - // adjust by taking difference in days, average number of days - // and dst in the given months. - daysAdjust = (this - moment(this).startOf('month')) - - (that - moment(that).startOf('month')); - // same as above but with zones, to negate all dst - daysAdjust -= ((this.zone() - moment(this).startOf('month').zone()) - - (that.zone() - moment(that).startOf('month').zone())) * 6e4; - output += daysAdjust / diff; - if (units === 'year') { - output = output / 12; - } - } else { - diff = (this - that); - output = units === 'second' ? diff / 1e3 : // 1000 - units === 'minute' ? diff / 6e4 : // 1000 * 60 - units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 - units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst - units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst - diff; - } - return asFloat ? output : absRound(output); - }, - - from : function (time, withoutSuffix) { - return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); - }, - - fromNow : function (withoutSuffix) { - return this.from(moment(), withoutSuffix); - }, - - calendar : function (time) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're zone'd or not. - var now = time || moment(), - sod = makeAs(now, this).startOf('day'), - diff = this.diff(sod, 'days', true), - format = diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.localeData().calendar(format, this)); - }, - - isLeapYear : function () { - return isLeapYear(this.year()); - }, - - isDST : function () { - return (this.zone() < this.clone().month(0).zone() || - this.zone() < this.clone().month(5).zone()); - }, - - day : function (input) { - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); - } else { - return day; - } - }, - - month : makeAccessor('Month', true), - - startOf : function (units) { - units = normalizeUnits(units); - // the following switch intentionally omits break keywords - // to utilize falling through the cases. - switch (units) { - case 'year': - this.month(0); - /* falls through */ - case 'quarter': - case 'month': - this.date(1); - /* falls through */ - case 'week': - case 'isoWeek': - case 'day': - this.hours(0); - /* falls through */ - case 'hour': - this.minutes(0); - /* falls through */ - case 'minute': - this.seconds(0); - /* falls through */ - case 'second': - this.milliseconds(0); - /* falls through */ - } - - // weeks are a special case - if (units === 'week') { - this.weekday(0); - } else if (units === 'isoWeek') { - this.isoWeekday(1); - } - - // quarters are also special - if (units === 'quarter') { - this.month(Math.floor(this.month() / 3) * 3); - } - - return this; - }, - - endOf: function (units) { - units = normalizeUnits(units); - return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); - }, - - isAfter: function (input, units) { - units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); - if (units === 'millisecond') { - input = moment.isMoment(input) ? input : moment(input); - return +this > +input; - } else { - return +this.clone().startOf(units) > +moment(input).startOf(units); - } - }, - - isBefore: function (input, units) { - units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); - if (units === 'millisecond') { - input = moment.isMoment(input) ? input : moment(input); - return +this < +input; - } else { - return +this.clone().startOf(units) < +moment(input).startOf(units); - } - }, - - isSame: function (input, units) { - units = normalizeUnits(units || 'millisecond'); - if (units === 'millisecond') { - input = moment.isMoment(input) ? input : moment(input); - return +this === +input; - } else { - return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); - } - }, - - min: deprecate( - 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', - function (other) { - other = moment.apply(null, arguments); - return other < this ? this : other; - } - ), - - max: deprecate( - 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', - function (other) { - other = moment.apply(null, arguments); - return other > this ? this : other; - } - ), - - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - zone : function (input, keepLocalTime) { - var offset = this._offset || 0, - localAdjust; - if (input != null) { - if (typeof input === 'string') { - input = timezoneMinutesFromString(input); - } - if (Math.abs(input) < 16) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = this._dateTzOffset(); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.subtract(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addOrSubtractDurationFromMoment(this, - moment.duration(offset - input, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - moment.updateOffset(this, true); - this._changeInProgress = null; - } - } - } else { - return this._isUTC ? offset : this._dateTzOffset(); - } - return this; - }, - - zoneAbbr : function () { - return this._isUTC ? 'UTC' : ''; - }, - - zoneName : function () { - return this._isUTC ? 'Coordinated Universal Time' : ''; - }, + // convert and filter items + for (var id in data) { + if (data.hasOwnProperty(id)) { + item = this._getItem(id, type); + if (!filter || filter(item)) { + mappedItems.push(callback(item, id)); + } + } + } - parseZone : function () { - if (this._tzm) { - this.zone(this._tzm); - } else if (typeof this._i === 'string') { - this.zone(this._i); - } - return this; - }, + // order items + if (options && options.order) { + this._sort(mappedItems, options.order); + } - hasAlignedHourOffset : function (input) { - if (!input) { - input = 0; - } - else { - input = moment(input).zone(); - } + return mappedItems; + }; - return (this.zone() - input) % 60 === 0; - }, + /** + * Filter the fields of an item + * @param {Object} item + * @param {String[]} fields Field names + * @return {Object} filteredItem + * @private + */ + DataSet.prototype._filterFields = function (item, fields) { + var filteredItem = {}; - daysInMonth : function () { - return daysInMonth(this.year(), this.month()); - }, + for (var field in item) { + if (item.hasOwnProperty(field) && (fields.indexOf(field) != -1)) { + filteredItem[field] = item[field]; + } + } - dayOfYear : function (input) { - var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - }, + return filteredItem; + }; - quarter : function (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - }, + /** + * Sort the provided array with items + * @param {Object[]} items + * @param {String | function} order A field name or custom sort function. + * @private + */ + DataSet.prototype._sort = function (items, order) { + if (util.isString(order)) { + // order by provided field name + var name = order; // field name + items.sort(function (a, b) { + var av = a[name]; + var bv = b[name]; + return (av > bv) ? 1 : ((av < bv) ? -1 : 0); + }); + } + else if (typeof order === 'function') { + // order by sort function + items.sort(order); + } + // TODO: extend order by an Object {field:String, direction:String} + // where direction can be 'asc' or 'desc' + else { + throw new TypeError('Order must be a function or a string'); + } + }; - weekYear : function (input) { - var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; - return input == null ? year : this.add((input - year), 'y'); - }, + /** + * Remove an object by pointer or by id + * @param {String | Number | Object | Array} id Object or id, or an array with + * objects or ids to be removed + * @param {String} [senderId] Optional sender id + * @return {Array} removedIds + */ + DataSet.prototype.remove = function (id, senderId) { + var removedIds = [], + i, len, removedId; - isoWeekYear : function (input) { - var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add((input - year), 'y'); - }, + if (Array.isArray(id)) { + for (i = 0, len = id.length; i < len; i++) { + removedId = this._remove(id[i]); + if (removedId != null) { + removedIds.push(removedId); + } + } + } + else { + removedId = this._remove(id); + if (removedId != null) { + removedIds.push(removedId); + } + } - week : function (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - }, + if (removedIds.length) { + this._trigger('remove', {items: removedIds}, senderId); + } - isoWeek : function (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - }, + return removedIds; + }; - weekday : function (input) { - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - }, + /** + * Remove an item by its id + * @param {Number | String | Object} id id or item + * @returns {Number | String | null} id + * @private + */ + DataSet.prototype._remove = function (id) { + if (util.isNumber(id) || util.isString(id)) { + if (this._data[id]) { + delete this._data[id]; + return id; + } + } + else if (id instanceof Object) { + var itemId = id[this._fieldId]; + if (itemId && this._data[itemId]) { + delete this._data[itemId]; + return itemId; + } + } + return null; + }; - isoWeekday : function (input) { - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. - return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); - }, + /** + * Clear the data + * @param {String} [senderId] Optional sender id + * @return {Array} removedIds The ids of all removed items + */ + DataSet.prototype.clear = function (senderId) { + var ids = Object.keys(this._data); - isoWeeksInYear : function () { - return weeksInYear(this.year(), 1, 4); - }, + this._data = {}; - weeksInYear : function () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - }, + this._trigger('remove', {items: ids}, senderId); - get : function (units) { - units = normalizeUnits(units); - return this[units](); - }, + return ids; + }; - set : function (units, value) { - units = normalizeUnits(units); - if (typeof this[units] === 'function') { - this[units](value); - } - return this; - }, + /** + * Find the item with maximum value of a specified field + * @param {String} field + * @return {Object | null} item Item containing max value, or null if no items + */ + DataSet.prototype.max = function (field) { + var data = this._data, + max = null, + maxField = null; - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - locale : function (key) { - var newLocaleData; + for (var id in data) { + if (data.hasOwnProperty(id)) { + var item = data[id]; + var itemField = item[field]; + if (itemField != null && (!max || itemField > maxField)) { + max = item; + maxField = itemField; + } + } + } - if (key === undefined) { - return this._locale._abbr; - } else { - newLocaleData = moment.localeData(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } - return this; - } - }, + return max; + }; - lang : deprecate( - 'moment().lang() is deprecated. Use moment().localeData() instead.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } - } - ), + /** + * Find the item with minimum value of a specified field + * @param {String} field + * @return {Object | null} item Item containing max value, or null if no items + */ + DataSet.prototype.min = function (field) { + var data = this._data, + min = null, + minField = null; - localeData : function () { - return this._locale; - }, + for (var id in data) { + if (data.hasOwnProperty(id)) { + var item = data[id]; + var itemField = item[field]; + if (itemField != null && (!min || itemField < minField)) { + min = item; + minField = itemField; + } + } + } - _dateTzOffset : function () { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return Math.round(this._d.getTimezoneOffset() / 15) * 15; - } - }); + return min; + }; - function rawMonthSetter(mom, value) { - var dayOfMonth; + /** + * Find all distinct values of a specified field + * @param {String} field + * @return {Array} values Array containing all distinct values. If data items + * do not contain the specified field are ignored. + * The returned array is unordered. + */ + DataSet.prototype.distinct = function (field) { + var data = this._data; + var values = []; + var fieldType = this._options.type && this._options.type[field] || null; + var count = 0; + var i; - // TODO: Move this out of here! - if (typeof value === 'string') { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (typeof value !== 'number') { - return mom; - } + for (var prop in data) { + if (data.hasOwnProperty(prop)) { + var item = data[prop]; + var value = item[field]; + var exists = false; + for (i = 0; i < count; i++) { + if (values[i] == value) { + exists = true; + break; } - - dayOfMonth = Math.min(mom.date(), - daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; + } + if (!exists && (value !== undefined)) { + values[count] = value; + count++; + } } + } - function rawGetter(mom, unit) { - return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); + if (fieldType) { + for (i = 0; i < values.length; i++) { + values[i] = util.convert(values[i], fieldType); } + } - function rawSetter(mom, unit, value) { - if (unit === 'Month') { - return rawMonthSetter(mom, value); - } else { - return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } + return values; + }; + + /** + * Add a single item. Will fail when an item with the same id already exists. + * @param {Object} item + * @return {String} id + * @private + */ + DataSet.prototype._addItem = function (item) { + var id = item[this._fieldId]; + + if (id != undefined) { + // check whether this id is already taken + if (this._data[id]) { + // item already exists + throw new Error('Cannot add item: item with id ' + id + ' already exists'); } + } + else { + // generate an id + id = util.randomUUID(); + item[this._fieldId] = id; + } - function makeAccessor(unit, keepTime) { - return function (value) { - if (value != null) { - rawSetter(this, unit, value); - moment.updateOffset(this, keepTime); - return this; - } else { - return rawGetter(this, unit); - } - }; + var d = {}; + for (var field in item) { + if (item.hasOwnProperty(field)) { + var fieldType = this._type[field]; // type may be undefined + d[field] = util.convert(item[field], fieldType); } + } + this._data[id] = d; - moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); - moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); - moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); - // Setting the hour should keep the time, because the user explicitly - // specified which hour he wants. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); - // moment.fn.month is defined separately - moment.fn.date = makeAccessor('Date', true); - moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); - moment.fn.year = makeAccessor('FullYear', true); - moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); + return id; + }; - // add plural methods - moment.fn.days = moment.fn.day; - moment.fn.months = moment.fn.month; - moment.fn.weeks = moment.fn.week; - moment.fn.isoWeeks = moment.fn.isoWeek; - moment.fn.quarters = moment.fn.quarter; + /** + * Get an item. Fields can be converted to a specific type + * @param {String} id + * @param {Object.} [types] field types to convert + * @return {Object | null} item + * @private + */ + DataSet.prototype._getItem = function (id, types) { + var field, value; - // add aliased format methods - moment.fn.toJSON = moment.fn.toISOString; + // get the item from the dataset + var raw = this._data[id]; + if (!raw) { + return null; + } - /************************************ - Duration Prototype - ************************************/ + // convert the items field types + var converted = {}; + if (types) { + for (field in raw) { + if (raw.hasOwnProperty(field)) { + value = raw[field]; + converted[field] = util.convert(value, types[field]); + } + } + } + else { + // no field types specified, no converting needed + for (field in raw) { + if (raw.hasOwnProperty(field)) { + value = raw[field]; + converted[field] = value; + } + } + } + return converted; + }; + /** + * Update a single item: merge with existing item. + * Will fail when the item has no id, or when there does not exist an item + * with the same id. + * @param {Object} item + * @return {String} id + * @private + */ + DataSet.prototype._updateItem = function (item) { + var id = item[this._fieldId]; + if (id == undefined) { + throw new Error('Cannot update item: item has no id (item: ' + JSON.stringify(item) + ')'); + } + var d = this._data[id]; + if (!d) { + // item doesn't exist + throw new Error('Cannot update item: no item with id ' + id + ' found'); + } - function daysToYears (days) { - // 400 years have 146097 days (taking into account leap year rules) - return days * 400 / 146097; + // merge with current item + for (var field in item) { + if (item.hasOwnProperty(field)) { + var fieldType = this._type[field]; // type may be undefined + d[field] = util.convert(item[field], fieldType); } + } - function yearsToDays (years) { - // years * 365 + absRound(years / 4) - - // absRound(years / 100) + absRound(years / 400); - return years * 146097 / 400; - } + return id; + }; - extend(moment.duration.fn = Duration.prototype, { + /** + * Get an array with the column names of a Google DataTable + * @param {DataTable} dataTable + * @return {String[]} columnNames + * @private + */ + DataSet.prototype._getColumnNames = function (dataTable) { + var columns = []; + for (var col = 0, cols = dataTable.getNumberOfColumns(); col < cols; col++) { + columns[col] = dataTable.getColumnId(col) || dataTable.getColumnLabel(col); + } + return columns; + }; - _bubble : function () { - var milliseconds = this._milliseconds, - days = this._days, - months = this._months, - data = this._data, - seconds, minutes, hours, years = 0; + /** + * Append an item as a row to the dataTable + * @param dataTable + * @param columns + * @param item + * @private + */ + DataSet.prototype._appendRow = function (dataTable, columns, item) { + var row = dataTable.addRow(); - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; + for (var col = 0, cols = columns.length; col < cols; col++) { + var field = columns[col]; + dataTable.setValue(row, col, item[field]); + } + }; - seconds = absRound(milliseconds / 1000); - data.seconds = seconds % 60; + module.exports = DataSet; - minutes = absRound(seconds / 60); - data.minutes = minutes % 60; - hours = absRound(minutes / 60); - data.hours = hours % 24; +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var DataSet = __webpack_require__(3); + + /** + * DataView + * + * a dataview offers a filtered view on a dataset or an other dataview. + * + * @param {DataSet | DataView} data + * @param {Object} [options] Available options: see method get + * + * @constructor DataView + */ + function DataView (data, options) { + this._data = null; + this._ids = {}; // ids of the items currently in memory (just contains a boolean true) + this._options = options || {}; + this._fieldId = 'id'; // name of the field containing id + this._subscribers = {}; // event subscribers + + var me = this; + this.listener = function () { + me._onEvent.apply(me, arguments); + }; - days += absRound(hours / 24); + this.setData(data); + } - // Accurately convert days to years, assume start from year 0. - years = absRound(daysToYears(days)); - days -= absRound(yearsToDays(years)); + // TODO: implement a function .config() to dynamically update things like configured filter + // and trigger changes accordingly - // 30 days to a month - // TODO (iskren): Use anchor date (like 1st Jan) to compute this. - months += absRound(days / 30); - days %= 30; + /** + * Set a data source for the view + * @param {DataSet | DataView} data + */ + DataView.prototype.setData = function (data) { + var ids, i, len; - // 12 months -> 1 year - years += absRound(months / 12); - months %= 12; + if (this._data) { + // unsubscribe from current dataset + if (this._data.unsubscribe) { + this._data.unsubscribe('*', this.listener); + } - data.days = days; - data.months = months; - data.years = years; - }, + // trigger a remove of all items in memory + ids = []; + for (var id in this._ids) { + if (this._ids.hasOwnProperty(id)) { + ids.push(id); + } + } + this._ids = {}; + this._trigger('remove', {items: ids}); + } - abs : function () { - this._milliseconds = Math.abs(this._milliseconds); - this._days = Math.abs(this._days); - this._months = Math.abs(this._months); + this._data = data; - this._data.milliseconds = Math.abs(this._data.milliseconds); - this._data.seconds = Math.abs(this._data.seconds); - this._data.minutes = Math.abs(this._data.minutes); - this._data.hours = Math.abs(this._data.hours); - this._data.months = Math.abs(this._data.months); - this._data.years = Math.abs(this._data.years); + if (this._data) { + // update fieldId + this._fieldId = this._options.fieldId || + (this._data && this._data.options && this._data.options.fieldId) || + 'id'; - return this; - }, + // trigger an add of all added items + ids = this._data.getIds({filter: this._options && this._options.filter}); + for (i = 0, len = ids.length; i < len; i++) { + id = ids[i]; + this._ids[id] = true; + } + this._trigger('add', {items: ids}); - weeks : function () { - return absRound(this.days() / 7); - }, + // subscribe to new dataset + if (this._data.on) { + this._data.on('*', this.listener); + } + } + }; - valueOf : function () { - return this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6; - }, + /** + * Get data from the data view + * + * Usage: + * + * get() + * get(options: Object) + * get(options: Object, data: Array | DataTable) + * + * get(id: Number) + * get(id: Number, options: Object) + * get(id: Number, options: Object, data: Array | DataTable) + * + * get(ids: Number[]) + * get(ids: Number[], options: Object) + * get(ids: Number[], options: Object, data: Array | DataTable) + * + * Where: + * + * {Number | String} id The id of an item + * {Number[] | String{}} ids An array with ids of items + * {Object} options An Object with options. Available options: + * {String} [type] Type of data to be returned. Can + * be 'DataTable' or 'Array' (default) + * {Object.} [convert] + * {String[]} [fields] field names to be returned + * {function} [filter] filter items + * {String | function} [order] Order the items by + * a field name or custom sort function. + * {Array | DataTable} [data] If provided, items will be appended to this + * array or table. Required in case of Google + * DataTable. + * @param args + */ + DataView.prototype.get = function (args) { + var me = this; - humanize : function (withSuffix) { - var output = relativeTime(this, !withSuffix, this.localeData()); + // parse the arguments + var ids, options, data; + var firstType = util.getType(arguments[0]); + if (firstType == 'String' || firstType == 'Number' || firstType == 'Array') { + // get(id(s) [, options] [, data]) + ids = arguments[0]; // can be a single id or an array with ids + options = arguments[1]; + data = arguments[2]; + } + else { + // get([, options] [, data]) + options = arguments[0]; + data = arguments[1]; + } - if (withSuffix) { - output = this.localeData().pastFuture(+this, output); - } + // extend the options with the default options and provided options + var viewOptions = util.extend({}, this._options, options); - return this.localeData().postformat(output); - }, + // create a combined filter method when needed + if (this._options.filter && options && options.filter) { + viewOptions.filter = function (item) { + return me._options.filter(item) && options.filter(item); + } + } - add : function (input, val) { - // supports only 2.0-style add(1, 's') or add(moment) - var dur = moment.duration(input, val); + // build up the call to the linked data set + var getArguments = []; + if (ids != undefined) { + getArguments.push(ids); + } + getArguments.push(viewOptions); + getArguments.push(data); - this._milliseconds += dur._milliseconds; - this._days += dur._days; - this._months += dur._months; + return this._data && this._data.get.apply(this._data, getArguments); + }; - this._bubble(); + /** + * Get ids of all items or from a filtered set of items. + * @param {Object} [options] An Object with options. Available options: + * {function} [filter] filter items + * {String | function} [order] Order the items by + * a field name or custom sort function. + * @return {Array} ids + */ + DataView.prototype.getIds = function (options) { + var ids; - return this; - }, + if (this._data) { + var defaultFilter = this._options.filter; + var filter; - subtract : function (input, val) { - var dur = moment.duration(input, val); + if (options && options.filter) { + if (defaultFilter) { + filter = function (item) { + return defaultFilter(item) && options.filter(item); + } + } + else { + filter = options.filter; + } + } + else { + filter = defaultFilter; + } - this._milliseconds -= dur._milliseconds; - this._days -= dur._days; - this._months -= dur._months; + ids = this._data.getIds({ + filter: filter, + order: options && options.order + }); + } + else { + ids = []; + } - this._bubble(); + return ids; + }; - return this; - }, + /** + * Get the DataSet to which this DataView is connected. In case there is a chain + * of multiple DataViews, the root DataSet of this chain is returned. + * @return {DataSet} dataSet + */ + DataView.prototype.getDataSet = function () { + var dataSet = this; + while (dataSet instanceof DataView) { + dataSet = dataSet._data; + } + return dataSet || null; + }; - get : function (units) { - units = normalizeUnits(units); - return this[units.toLowerCase() + 's'](); - }, + /** + * Event listener. Will propagate all events from the connected data set to + * the subscribers of the DataView, but will filter the items and only trigger + * when there are changes in the filtered data set. + * @param {String} event + * @param {Object | null} params + * @param {String} senderId + * @private + */ + DataView.prototype._onEvent = function (event, params, senderId) { + var i, len, id, item, + ids = params && params.items, + data = this._data, + added = [], + updated = [], + removed = []; - as : function (units) { - var days, months; - units = normalizeUnits(units); + if (ids && data) { + switch (event) { + case 'add': + // filter the ids of the added items + for (i = 0, len = ids.length; i < len; i++) { + id = ids[i]; + item = this.get(id); + if (item) { + this._ids[id] = true; + added.push(id); + } + } - if (units === 'month' || units === 'year') { - days = this._days + this._milliseconds / 864e5; - months = this._months + daysToYears(days) * 12; - return units === 'month' ? months : months / 12; - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + yearsToDays(this._months / 12); - switch (units) { - case 'week': return days / 7 + this._milliseconds / 6048e5; - case 'day': return days + this._milliseconds / 864e5; - case 'hour': return days * 24 + this._milliseconds / 36e5; - case 'minute': return days * 24 * 60 + this._milliseconds / 6e4; - case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds; - default: throw new Error('Unknown unit ' + units); - } - } - }, + break; - lang : moment.fn.lang, - locale : moment.fn.locale, + case 'update': + // determine the event from the views viewpoint: an updated + // item can be added, updated, or removed from this view. + for (i = 0, len = ids.length; i < len; i++) { + id = ids[i]; + item = this.get(id); - toIsoString : deprecate( - 'toIsoString() is deprecated. Please use toISOString() instead ' + - '(notice the capitals)', - function () { - return this.toISOString(); + if (item) { + if (this._ids[id]) { + updated.push(id); } - ), - - toISOString : function () { - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var years = Math.abs(this.years()), - months = Math.abs(this.months()), - days = Math.abs(this.days()), - hours = Math.abs(this.hours()), - minutes = Math.abs(this.minutes()), - seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); - - if (!this.asSeconds()) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; + else { + this._ids[id] = true; + added.push(id); + } + } + else { + if (this._ids[id]) { + delete this._ids[id]; + removed.push(id); + } + else { + // nothing interesting for me :-( } + } + } - return (this.asSeconds() < 0 ? '-' : '') + - 'P' + - (years ? years + 'Y' : '') + - (months ? months + 'M' : '') + - (days ? days + 'D' : '') + - ((hours || minutes || seconds) ? 'T' : '') + - (hours ? hours + 'H' : '') + - (minutes ? minutes + 'M' : '') + - (seconds ? seconds + 'S' : ''); - }, + break; - localeData : function () { - return this._locale; + case 'remove': + // filter the ids of the removed items + for (i = 0, len = ids.length; i < len; i++) { + id = ids[i]; + if (this._ids[id]) { + delete this._ids[id]; + removed.push(id); + } } - }); - moment.duration.fn.toString = moment.duration.fn.toISOString; - - function makeDurationGetter(name) { - moment.duration.fn[name] = function () { - return this._data[name]; - }; + break; } - for (i in unitMillisecondFactors) { - if (hasOwnProp(unitMillisecondFactors, i)) { - makeDurationGetter(i.toLowerCase()); - } + if (added.length) { + this._trigger('add', {items: added}, senderId); + } + if (updated.length) { + this._trigger('update', {items: updated}, senderId); } + if (removed.length) { + this._trigger('remove', {items: removed}, senderId); + } + } + }; - moment.duration.fn.asMilliseconds = function () { - return this.as('ms'); - }; - moment.duration.fn.asSeconds = function () { - return this.as('s'); - }; - moment.duration.fn.asMinutes = function () { - return this.as('m'); - }; - moment.duration.fn.asHours = function () { - return this.as('h'); - }; - moment.duration.fn.asDays = function () { - return this.as('d'); - }; - moment.duration.fn.asWeeks = function () { - return this.as('weeks'); - }; - moment.duration.fn.asMonths = function () { - return this.as('M'); - }; - moment.duration.fn.asYears = function () { - return this.as('y'); - }; + // copy subscription functionality from DataSet + DataView.prototype.on = DataSet.prototype.on; + DataView.prototype.off = DataSet.prototype.off; + DataView.prototype._trigger = DataSet.prototype._trigger; - /************************************ - Default Locale - ************************************/ + // TODO: make these functions deprecated (replaced with `on` and `off` since version 0.5) + DataView.prototype.subscribe = DataView.prototype.on; + DataView.prototype.unsubscribe = DataView.prototype.off; + module.exports = DataView; - // Set default locale, other locale will inherit from English. - moment.locale('en', { - ordinal : function (number) { - var b = number % 10, - output = (toInt(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { - /* EMBED_LOCALES */ + var Emitter = __webpack_require__(52); + var DataSet = __webpack_require__(3); + var DataView = __webpack_require__(4); + var util = __webpack_require__(1); + var Point3d = __webpack_require__(9); + var Point2d = __webpack_require__(8); + var Camera = __webpack_require__(6); + var Filter = __webpack_require__(7); + var Slider = __webpack_require__(10); + var StepNumber = __webpack_require__(11); - /************************************ - Exposing Moment - ************************************/ + /** + * @constructor Graph3d + * Graph3d displays data in 3d. + * + * Graph3d is developed in javascript as a Google Visualization Chart. + * + * @param {Element} container The DOM element in which the Graph3d will + * be created. Normally a div element. + * @param {DataSet | DataView | Array} [data] + * @param {Object} [options] + */ + function Graph3d(container, data, options) { + if (!(this instanceof Graph3d)) { + throw new SyntaxError('Constructor must be called with the new operator'); + } - function makeGlobal(shouldDeprecate) { - /*global ender:false */ - if (typeof ender !== 'undefined') { - return; - } - oldGlobalMoment = globalScope.moment; - if (shouldDeprecate) { - globalScope.moment = deprecate( - 'Accessing Moment through the global scope is ' + - 'deprecated, and will be removed in an upcoming ' + - 'release.', - moment); - } else { - globalScope.moment = moment; - } - } + // create variables and set default values + this.containerElement = container; + this.width = '400px'; + this.height = '400px'; + this.margin = 10; // px + this.defaultXCenter = '55%'; + this.defaultYCenter = '50%'; - // CommonJS module is defined - if (hasModule) { - module.exports = moment; - } else if (true) { - !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { - if (module.config && module.config() && module.config().noGlobal === true) { - // release the global variable - globalScope.moment = oldGlobalMoment; - } + this.xLabel = 'x'; + this.yLabel = 'y'; + this.zLabel = 'z'; - return moment; - }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - makeGlobal(true); - } else { - makeGlobal(); - } - }).call(this); - - /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(5)(module))) + var passValueFn = function(v) { return v; }; + this.xValueLabel = passValueFn; + this.yValueLabel = passValueFn; + this.zValueLabel = passValueFn; + + this.filterLabel = 'time'; + this.legendLabel = 'value'; -/***/ }, -/* 4 */ -/***/ function(module, exports, __webpack_require__) { + this.style = Graph3d.STYLE.DOT; + this.showPerspective = true; + this.showGrid = true; + this.keepAspectRatio = true; + this.showShadow = false; + this.showGrayBottom = false; // TODO: this does not work correctly + this.showTooltip = false; + this.verticalRatio = 0.5; // 0.1 to 1.0, where 1.0 results in a 'cube' - function webpackContext(req) { - throw new Error("Cannot find module '" + req + "'."); - } - webpackContext.keys = function() { return []; }; - webpackContext.resolve = webpackContext; - module.exports = webpackContext; - webpackContext.id = 4; + this.animationInterval = 1000; // milliseconds + this.animationPreload = false; + + this.camera = new Camera(); + this.eye = new Point3d(0, 0, -1); // TODO: set eye.z about 3/4 of the width of the window? + this.dataTable = null; // The original data table + this.dataPoints = null; // The table with point objects -/***/ }, -/* 5 */ -/***/ function(module, exports, __webpack_require__) { + // the column indexes + this.colX = undefined; + this.colY = undefined; + this.colZ = undefined; + this.colValue = undefined; + this.colFilter = undefined; - module.exports = function(module) { - if(!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - module.children = []; - module.webpackPolyfill = 1; - } - return module; - } + this.xMin = 0; + this.xStep = undefined; // auto by default + this.xMax = 1; + this.yMin = 0; + this.yStep = undefined; // auto by default + this.yMax = 1; + this.zMin = 0; + this.zStep = undefined; // auto by default + this.zMax = 1; + this.valueMin = 0; + this.valueMax = 1; + this.xBarWidth = 1; + this.yBarWidth = 1; + // TODO: customize axis range + // constants + this.colorAxis = '#4D4D4D'; + this.colorGrid = '#D3D3D3'; + this.colorDot = '#7DC1FF'; + this.colorDotBorder = '#3267D2'; -/***/ }, -/* 6 */ -/***/ function(module, exports, __webpack_require__) { + // create a frame and canvas + this.create(); - // DOM utility methods + // apply options (also when undefined) + this.setOptions(options); - /** - * this prepares the JSON container for allocating SVG elements - * @param JSONcontainer - * @private - */ - exports.prepareElements = function(JSONcontainer) { - // cleanup the redundant svgElements; - for (var elementType in JSONcontainer) { - if (JSONcontainer.hasOwnProperty(elementType)) { - JSONcontainer[elementType].redundant = JSONcontainer[elementType].used; - JSONcontainer[elementType].used = []; - } + // apply data + if (data) { + this.setData(data); } - }; + } - /** - * this cleans up all the unused SVG elements. By asking for the parentNode, we only need to supply the JSON container from - * which to remove the redundant elements. - * - * @param JSONcontainer - * @private - */ - exports.cleanupElements = function(JSONcontainer) { - // cleanup the redundant svgElements; - for (var elementType in JSONcontainer) { - if (JSONcontainer.hasOwnProperty(elementType)) { - if (JSONcontainer[elementType].redundant) { - for (var i = 0; i < JSONcontainer[elementType].redundant.length; i++) { - JSONcontainer[elementType].redundant[i].parentNode.removeChild(JSONcontainer[elementType].redundant[i]); - } - JSONcontainer[elementType].redundant = []; - } - } - } - }; + // Extend Graph3d with an Emitter mixin + Emitter(Graph3d.prototype); /** - * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer - * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this. - * - * @param elementType - * @param JSONcontainer - * @param svgContainer - * @returns {*} - * @private + * Calculate the scaling values, dependent on the range in x, y, and z direction */ - exports.getSVGElement = function (elementType, JSONcontainer, svgContainer) { - var element; - // allocate SVG element, if it doesnt yet exist, create one. - if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before - // check if there is an redundant element - if (JSONcontainer[elementType].redundant.length > 0) { - element = JSONcontainer[elementType].redundant[0]; - JSONcontainer[elementType].redundant.shift(); + Graph3d.prototype._setScale = function() { + this.scale = new Point3d(1 / (this.xMax - this.xMin), + 1 / (this.yMax - this.yMin), + 1 / (this.zMax - this.zMin)); + + // keep aspect ration between x and y scale if desired + if (this.keepAspectRatio) { + if (this.scale.x < this.scale.y) { + //noinspection JSSuspiciousNameCombination + this.scale.y = this.scale.x; } else { - // create a new element and add it to the SVG - element = document.createElementNS('http://www.w3.org/2000/svg', elementType); - svgContainer.appendChild(element); + //noinspection JSSuspiciousNameCombination + this.scale.x = this.scale.y; } } - else { - // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it. - element = document.createElementNS('http://www.w3.org/2000/svg', elementType); - JSONcontainer[elementType] = {used: [], redundant: []}; - svgContainer.appendChild(element); - } - JSONcontainer[elementType].used.push(element); - return element; + + // scale the vertical axis + this.scale.z *= this.verticalRatio; + // TODO: can this be automated? verticalRatio? + + // determine scale for (optional) value + this.scale.value = 1 / (this.valueMax - this.valueMin); + + // position the camera arm + var xCenter = (this.xMax + this.xMin) / 2 * this.scale.x; + var yCenter = (this.yMax + this.yMin) / 2 * this.scale.y; + var zCenter = (this.zMax + this.zMin) / 2 * this.scale.z; + this.camera.setArmLocation(xCenter, yCenter, zCenter); }; /** - * Allocate or generate an SVG element if needed. Store a reference to it in the JSON container and draw it in the svgContainer - * the JSON container and the SVG container have to be supplied so other svg containers (like the legend) can use this. - * - * @param elementType - * @param JSONcontainer - * @param DOMContainer - * @returns {*} - * @private + * Convert a 3D location to a 2D location on screen + * http://en.wikipedia.org/wiki/3D_projection + * @param {Point3d} point3d A 3D point with parameters x, y, z + * @return {Point2d} point2d A 2D point with parameters x, y */ - exports.getDOMElement = function (elementType, JSONcontainer, DOMContainer, insertBefore) { - var element; - // allocate DOM element, if it doesnt yet exist, create one. - if (JSONcontainer.hasOwnProperty(elementType)) { // this element has been created before - // check if there is an redundant element - if (JSONcontainer[elementType].redundant.length > 0) { - element = JSONcontainer[elementType].redundant[0]; - JSONcontainer[elementType].redundant.shift(); - } - else { - // create a new element and add it to the SVG - element = document.createElement(elementType); - if (insertBefore !== undefined) { - DOMContainer.insertBefore(element, insertBefore); - } - else { - DOMContainer.appendChild(element); - } - } - } - else { - // create a new element and add it to the SVG, also create a new object in the svgElements to keep track of it. - element = document.createElement(elementType); - JSONcontainer[elementType] = {used: [], redundant: []}; - if (insertBefore !== undefined) { - DOMContainer.insertBefore(element, insertBefore); - } - else { - DOMContainer.appendChild(element); - } - } - JSONcontainer[elementType].used.push(element); - return element; + Graph3d.prototype._convert3Dto2D = function(point3d) { + var translation = this._convertPointToTranslation(point3d); + return this._convertTranslationToScreen(translation); }; + /** + * Convert a 3D location its translation seen from the camera + * http://en.wikipedia.org/wiki/3D_projection + * @param {Point3d} point3d A 3D point with parameters x, y, z + * @return {Point3d} translation A 3D point with parameters x, y, z This is + * the translation of the point, seen from the + * camera + */ + Graph3d.prototype._convertPointToTranslation = function(point3d) { + var ax = point3d.x * this.scale.x, + ay = point3d.y * this.scale.y, + az = point3d.z * this.scale.z, + + cx = this.camera.getCameraLocation().x, + cy = this.camera.getCameraLocation().y, + cz = this.camera.getCameraLocation().z, + + // calculate angles + sinTx = Math.sin(this.camera.getCameraRotation().x), + cosTx = Math.cos(this.camera.getCameraRotation().x), + sinTy = Math.sin(this.camera.getCameraRotation().y), + cosTy = Math.cos(this.camera.getCameraRotation().y), + sinTz = Math.sin(this.camera.getCameraRotation().z), + cosTz = Math.cos(this.camera.getCameraRotation().z), + // calculate translation + dx = cosTy * (sinTz * (ay - cy) + cosTz * (ax - cx)) - sinTy * (az - cz), + dy = sinTx * (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) + cosTx * (cosTz * (ay - cy) - sinTz * (ax-cx)), + dz = cosTx * (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) - sinTx * (cosTz * (ay - cy) - sinTz * (ax-cx)); + return new Point3d(dx, dy, dz); + }; /** - * draw a point object. this is a seperate function because it can also be called by the legend. - * The reason the JSONcontainer and the target SVG svgContainer have to be supplied is so the legend can use these functions - * as well. - * - * @param x - * @param y - * @param group - * @param JSONcontainer - * @param svgContainer - * @returns {*} + * Convert a translation point to a point on the screen + * @param {Point3d} translation A 3D point with parameters x, y, z This is + * the translation of the point, seen from the + * camera + * @return {Point2d} point2d A 2D point with parameters x, y */ - exports.drawPoint = function(x, y, group, JSONcontainer, svgContainer) { - var point; - if (group.options.drawPoints.style == 'circle') { - point = exports.getSVGElement('circle',JSONcontainer,svgContainer); - point.setAttributeNS(null, "cx", x); - point.setAttributeNS(null, "cy", y); - point.setAttributeNS(null, "r", 0.5 * group.options.drawPoints.size); - point.setAttributeNS(null, "class", group.className + " point"); + Graph3d.prototype._convertTranslationToScreen = function(translation) { + var ex = this.eye.x, + ey = this.eye.y, + ez = this.eye.z, + dx = translation.x, + dy = translation.y, + dz = translation.z; + + // calculate position on screen from translation + var bx; + var by; + if (this.showPerspective) { + bx = (dx - ex) * (ez / dz); + by = (dy - ey) * (ez / dz); } else { - point = exports.getSVGElement('rect',JSONcontainer,svgContainer); - point.setAttributeNS(null, "x", x - 0.5*group.options.drawPoints.size); - point.setAttributeNS(null, "y", y - 0.5*group.options.drawPoints.size); - point.setAttributeNS(null, "width", group.options.drawPoints.size); - point.setAttributeNS(null, "height", group.options.drawPoints.size); - point.setAttributeNS(null, "class", group.className + " point"); + bx = dx * -(ez / this.camera.getArmLength()); + by = dy * -(ez / this.camera.getArmLength()); } - return point; + + // shift and scale the point to the center of the screen + // use the width of the graph to scale both horizontally and vertically. + return new Point2d( + this.xcenter + bx * this.frame.canvas.clientWidth, + this.ycenter - by * this.frame.canvas.clientWidth); }; /** - * draw a bar SVG element centered on the X coordinate - * - * @param x - * @param y - * @param className + * Set the background styling for the graph + * @param {string | {fill: string, stroke: string, strokeWidth: string}} backgroundColor */ - exports.drawBar = function (x, y, width, height, className, JSONcontainer, svgContainer) { - if (height != 0) { - if (height < 0) { - height *= -1; - y -= height; - } - var rect = exports.getSVGElement('rect',JSONcontainer, svgContainer); - rect.setAttributeNS(null, "x", x - 0.5 * width); - rect.setAttributeNS(null, "y", y); - rect.setAttributeNS(null, "width", width); - rect.setAttributeNS(null, "height", height); - rect.setAttributeNS(null, "class", className); + Graph3d.prototype._setBackgroundColor = function(backgroundColor) { + var fill = 'white'; + var stroke = 'gray'; + var strokeWidth = 1; + + if (typeof(backgroundColor) === 'string') { + fill = backgroundColor; + stroke = 'none'; + strokeWidth = 0; + } + else if (typeof(backgroundColor) === 'object') { + if (backgroundColor.fill !== undefined) fill = backgroundColor.fill; + if (backgroundColor.stroke !== undefined) stroke = backgroundColor.stroke; + if (backgroundColor.strokeWidth !== undefined) strokeWidth = backgroundColor.strokeWidth; + } + else if (backgroundColor === undefined) { + // use use defaults } + else { + throw 'Unsupported type of backgroundColor'; + } + + this.frame.style.backgroundColor = fill; + this.frame.style.borderColor = stroke; + this.frame.style.borderWidth = strokeWidth + 'px'; + this.frame.style.borderStyle = 'solid'; }; -/***/ }, -/* 7 */ -/***/ function(module, exports, __webpack_require__) { - var util = __webpack_require__(1); + /// enumerate the available styles + Graph3d.STYLE = { + BAR: 0, + BARCOLOR: 1, + BARSIZE: 2, + DOT : 3, + DOTLINE : 4, + DOTCOLOR: 5, + DOTSIZE: 6, + GRID : 7, + LINE: 8, + SURFACE : 9 + }; /** - * DataSet - * - * Usage: - * var dataSet = new DataSet({ - * fieldId: '_id', - * type: { - * // ... - * } - * }); - * - * dataSet.add(item); - * dataSet.add(data); - * dataSet.update(item); - * dataSet.update(data); - * dataSet.remove(id); - * dataSet.remove(ids); - * var data = dataSet.get(); - * var data = dataSet.get(id); - * var data = dataSet.get(ids); - * var data = dataSet.get(ids, options, data); - * dataSet.clear(); - * - * A data set can: - * - add/remove/update data - * - gives triggers upon changes in the data - * - can import/export data in various data formats - * - * @param {Array | DataTable} [data] Optional array with initial data - * @param {Object} [options] Available options: - * {String} fieldId Field name of the id in the - * items, 'id' by default. - * {Object. 3) { + this.colFilter = 3; + } } + else if (this.style === Graph3d.STYLE.DOTCOLOR || + this.style === Graph3d.STYLE.DOTSIZE || + this.style === Graph3d.STYLE.BARCOLOR || + this.style === Graph3d.STYLE.BARSIZE) { + // 4 columns expected, and optionally a 5th with filter values + this.colX = 0; + this.colY = 1; + this.colZ = 2; + this.colValue = 3; - this._subscribers = {}; // event subscribers - - // add initial data when provided - if (data) { - this.add(data); + if (data.getNumberOfColumns() > 4) { + this.colFilter = 4; + } } - } - - /** - * Subscribe to an event, add an event listener - * @param {String} event Event name. Available events: 'put', 'update', - * 'remove' - * @param {function} callback Callback method. Called with three parameters: - * {String} event - * {Object | null} params - * {String | Number} senderId - */ - DataSet.prototype.on = function(event, callback) { - var subscribers = this._subscribers[event]; - if (!subscribers) { - subscribers = []; - this._subscribers[event] = subscribers; + else { + throw 'Unknown style "' + this.style + '"'; } - - subscribers.push({ - callback: callback - }); }; - // TODO: make this function deprecated (replaced with `on` since version 0.5) - DataSet.prototype.subscribe = DataSet.prototype.on; + Graph3d.prototype.getNumberOfRows = function(data) { + return data.length; + } - /** - * Unsubscribe from an event, remove an event listener - * @param {String} event - * @param {function} callback - */ - DataSet.prototype.off = function(event, callback) { - var subscribers = this._subscribers[event]; - if (subscribers) { - this._subscribers[event] = subscribers.filter(function (listener) { - return (listener.callback != callback); - }); + + Graph3d.prototype.getNumberOfColumns = function(data) { + var counter = 0; + for (var column in data[0]) { + if (data[0].hasOwnProperty(column)) { + counter++; + } } - }; + return counter; + } - // TODO: make this function deprecated (replaced with `on` since version 0.5) - DataSet.prototype.unsubscribe = DataSet.prototype.off; - /** - * Trigger an event - * @param {String} event - * @param {Object | null} params - * @param {String} [senderId] Optional id of the sender. - * @private - */ - DataSet.prototype._trigger = function (event, params, senderId) { - if (event == '*') { - throw new Error('Cannot trigger event *'); + Graph3d.prototype.getDistinctValues = function(data, column) { + var distinctValues = []; + for (var i = 0; i < data.length; i++) { + if (distinctValues.indexOf(data[i][column]) == -1) { + distinctValues.push(data[i][column]); + } } + return distinctValues; + } - var subscribers = []; - if (event in this._subscribers) { - subscribers = subscribers.concat(this._subscribers[event]); - } - if ('*' in this._subscribers) { - subscribers = subscribers.concat(this._subscribers['*']); - } - for (var i = 0; i < subscribers.length; i++) { - var subscriber = subscribers[i]; - if (subscriber.callback) { - subscriber.callback(event, params, senderId || null); - } + Graph3d.prototype.getColumnRange = function(data,column) { + var minMax = {min:data[0][column],max:data[0][column]}; + for (var i = 0; i < data.length; i++) { + if (minMax.min > data[i][column]) { minMax.min = data[i][column]; } + if (minMax.max < data[i][column]) { minMax.max = data[i][column]; } } + return minMax; }; /** - * Add data. - * Adding an item will fail when there already is an item with the same id. - * @param {Object | Array | DataTable} data - * @param {String} [senderId] Optional sender id - * @return {Array} addedIds Array with the ids of the added items + * Initialize the data from the data table. Calculate minimum and maximum values + * and column index values + * @param {Array | DataSet | DataView} rawData The data containing the items for the Graph. + * @param {Number} style Style Number */ - DataSet.prototype.add = function (data, senderId) { - var addedIds = [], - id, - me = this; + Graph3d.prototype._dataInitialize = function (rawData, style) { + var me = this; - if (Array.isArray(data)) { - // Array - for (var i = 0, len = data.length; i < len; i++) { - id = me._addItem(data[i]); - addedIds.push(id); - } + // unsubscribe from the dataTable + if (this.dataSet) { + this.dataSet.off('*', this._onChange); } - else if (util.isDataTable(data)) { - // Google DataTable - var columns = this._getColumnNames(data); - for (var row = 0, rows = data.getNumberOfRows(); row < rows; row++) { - var item = {}; - for (var col = 0, cols = columns.length; col < cols; col++) { - var field = columns[col]; - item[field] = data.getValue(row, col); - } - id = me._addItem(item); - addedIds.push(id); - } + if (rawData === undefined) + return; + + if (Array.isArray(rawData)) { + rawData = new DataSet(rawData); } - else if (data instanceof Object) { - // Single item - id = me._addItem(data); - addedIds.push(id); + + var data; + if (rawData instanceof DataSet || rawData instanceof DataView) { + data = rawData.get(); } else { - throw new Error('Unknown dataType'); + throw new Error('Array, DataSet, or DataView expected'); } - if (addedIds.length) { - this._trigger('add', {items: addedIds}, senderId); + if (data.length == 0) + return; + + this.dataSet = rawData; + this.dataTable = data; + + // subscribe to changes in the dataset + this._onChange = function () { + me.setData(me.dataSet); + }; + this.dataSet.on('*', this._onChange); + + // _determineColumnIndexes + // getNumberOfRows (points) + // getNumberOfColumns (x,y,z,v,t,t1,t2...) + // getDistinctValues (unique values?) + // getColumnRange + + // determine the location of x,y,z,value,filter columns + this.colX = 'x'; + this.colY = 'y'; + this.colZ = 'z'; + this.colValue = 'style'; + this.colFilter = 'filter'; + + + + // check if a filter column is provided + if (data[0].hasOwnProperty('filter')) { + if (this.dataFilter === undefined) { + this.dataFilter = new Filter(rawData, this.colFilter, this); + this.dataFilter.setOnLoadCallback(function() {me.redraw();}); + } } - return addedIds; - }; - /** - * Update existing items. When an item does not exist, it will be created - * @param {Object | Array | DataTable} data - * @param {String} [senderId] Optional sender id - * @return {Array} updatedIds The ids of the added or updated items - */ - DataSet.prototype.update = function (data, senderId) { - var addedIds = []; - var updatedIds = []; - var updatedData = []; - var me = this; - var fieldId = me._fieldId; + var withBars = this.style == Graph3d.STYLE.BAR || + this.style == Graph3d.STYLE.BARCOLOR || + this.style == Graph3d.STYLE.BARSIZE; - var addOrUpdate = function (item) { - var id = item[fieldId]; - if (me._data[id]) { - // update item - id = me._updateItem(item); - updatedIds.push(id); - updatedData.push(item); + // determine barWidth from data + if (withBars) { + if (this.defaultXBarWidth !== undefined) { + this.xBarWidth = this.defaultXBarWidth; } else { - // add new item - id = me._addItem(item); - addedIds.push(id); + var dataX = this.getDistinctValues(data,this.colX); + this.xBarWidth = (dataX[1] - dataX[0]) || 1; } - }; - if (Array.isArray(data)) { - // Array - for (var i = 0, len = data.length; i < len; i++) { - addOrUpdate(data[i]); + if (this.defaultYBarWidth !== undefined) { + this.yBarWidth = this.defaultYBarWidth; } - } - else if (util.isDataTable(data)) { - // Google DataTable - var columns = this._getColumnNames(data); - for (var row = 0, rows = data.getNumberOfRows(); row < rows; row++) { - var item = {}; - for (var col = 0, cols = columns.length; col < cols; col++) { - var field = columns[col]; - item[field] = data.getValue(row, col); - } - - addOrUpdate(item); + else { + var dataY = this.getDistinctValues(data,this.colY); + this.yBarWidth = (dataY[1] - dataY[0]) || 1; } } - else if (data instanceof Object) { - // Single item - addOrUpdate(data); - } - else { - throw new Error('Unknown dataType'); + + // calculate minimums and maximums + var xRange = this.getColumnRange(data,this.colX); + if (withBars) { + xRange.min -= this.xBarWidth / 2; + xRange.max += this.xBarWidth / 2; } + this.xMin = (this.defaultXMin !== undefined) ? this.defaultXMin : xRange.min; + this.xMax = (this.defaultXMax !== undefined) ? this.defaultXMax : xRange.max; + if (this.xMax <= this.xMin) this.xMax = this.xMin + 1; + this.xStep = (this.defaultXStep !== undefined) ? this.defaultXStep : (this.xMax-this.xMin)/5; - if (addedIds.length) { - this._trigger('add', {items: addedIds}, senderId); + var yRange = this.getColumnRange(data,this.colY); + if (withBars) { + yRange.min -= this.yBarWidth / 2; + yRange.max += this.yBarWidth / 2; } - if (updatedIds.length) { - this._trigger('update', {items: updatedIds, data: updatedData}, senderId); + this.yMin = (this.defaultYMin !== undefined) ? this.defaultYMin : yRange.min; + this.yMax = (this.defaultYMax !== undefined) ? this.defaultYMax : yRange.max; + if (this.yMax <= this.yMin) this.yMax = this.yMin + 1; + this.yStep = (this.defaultYStep !== undefined) ? this.defaultYStep : (this.yMax-this.yMin)/5; + + var zRange = this.getColumnRange(data,this.colZ); + this.zMin = (this.defaultZMin !== undefined) ? this.defaultZMin : zRange.min; + this.zMax = (this.defaultZMax !== undefined) ? this.defaultZMax : zRange.max; + if (this.zMax <= this.zMin) this.zMax = this.zMin + 1; + this.zStep = (this.defaultZStep !== undefined) ? this.defaultZStep : (this.zMax-this.zMin)/5; + + if (this.colValue !== undefined) { + var valueRange = this.getColumnRange(data,this.colValue); + this.valueMin = (this.defaultValueMin !== undefined) ? this.defaultValueMin : valueRange.min; + this.valueMax = (this.defaultValueMax !== undefined) ? this.defaultValueMax : valueRange.max; + if (this.valueMax <= this.valueMin) this.valueMax = this.valueMin + 1; } - return addedIds.concat(updatedIds); + // set the scale dependent on the ranges. + this._setScale(); }; + + /** - * Get a data item or multiple items. - * - * Usage: - * - * get() - * get(options: Object) - * get(options: Object, data: Array | DataTable) - * - * get(id: Number | String) - * get(id: Number | String, options: Object) - * get(id: Number | String, options: Object, data: Array | DataTable) - * - * get(ids: Number[] | String[]) - * get(ids: Number[] | String[], options: Object) - * get(ids: Number[] | String[], options: Object, data: Array | DataTable) - * - * Where: - * - * {Number | String} id The id of an item - * {Number[] | String{}} ids An array with ids of items - * {Object} options An Object with options. Available options: - * {String} [returnType] Type of data to be - * returned. Can be 'DataTable' or 'Array' (default) - * {Object.} [type] - * {String[]} [fields] field names to be returned - * {function} [filter] filter items - * {String | function} [order] Order the items by - * a field name or custom sort function. - * {Array | DataTable} [data] If provided, items will be appended to this - * array or table. Required in case of Google - * DataTable. - * - * @throws Error + * Filter the data based on the current filter + * @param {Array} data + * @return {Array} dataPoints Array with point objects which can be drawn on screen */ - DataSet.prototype.get = function (args) { - var me = this; + Graph3d.prototype._getDataPoints = function (data) { + // TODO: store the created matrix dataPoints in the filters instead of reloading each time + var x, y, i, z, obj, point; - // parse the arguments - var id, ids, options, data; - var firstType = util.getType(arguments[0]); - if (firstType == 'String' || firstType == 'Number') { - // get(id [, options] [, data]) - id = arguments[0]; - options = arguments[1]; - data = arguments[2]; - } - else if (firstType == 'Array') { - // get(ids [, options] [, data]) - ids = arguments[0]; - options = arguments[1]; - data = arguments[2]; - } - else { - // get([, options] [, data]) - options = arguments[0]; - data = arguments[1]; - } + var dataPoints = []; - // determine the return type - var returnType; - if (options && options.returnType) { - var allowedValues = ["DataTable", "Array", "Object"]; - returnType = allowedValues.indexOf(options.returnType) == -1 ? "Array" : options.returnType; + if (this.style === Graph3d.STYLE.GRID || + this.style === Graph3d.STYLE.SURFACE) { + // copy all values from the google data table to a matrix + // the provided values are supposed to form a grid of (x,y) positions - if (data && (returnType != util.getType(data))) { - throw new Error('Type of parameter "data" (' + util.getType(data) + ') ' + - 'does not correspond with specified options.type (' + options.type + ')'); + // create two lists with all present x and y values + var dataX = []; + var dataY = []; + for (i = 0; i < this.getNumberOfRows(data); i++) { + x = data[i][this.colX] || 0; + y = data[i][this.colY] || 0; + + if (dataX.indexOf(x) === -1) { + dataX.push(x); + } + if (dataY.indexOf(y) === -1) { + dataY.push(y); + } } - if (returnType == 'DataTable' && !util.isDataTable(data)) { - throw new Error('Parameter "data" must be a DataTable ' + - 'when options.type is "DataTable"'); + + function sortNumber(a, b) { + return a - b; } - } - else if (data) { - returnType = (util.getType(data) == 'DataTable') ? 'DataTable' : 'Array'; - } - else { - returnType = 'Array'; - } + dataX.sort(sortNumber); + dataY.sort(sortNumber); - // build options - var type = options && options.type || this._options.type; - var filter = options && options.filter; - var items = [], item, itemId, i, len; + // create a grid, a 2d matrix, with all values. + var dataMatrix = []; // temporary data matrix + for (i = 0; i < data.length; i++) { + x = data[i][this.colX] || 0; + y = data[i][this.colY] || 0; + z = data[i][this.colZ] || 0; - // convert items - if (id != undefined) { - // return a single item - item = me._getItem(id, type); - if (filter && !filter(item)) { - item = null; + var xIndex = dataX.indexOf(x); // TODO: implement Array().indexOf() for Internet Explorer + var yIndex = dataY.indexOf(y); + + if (dataMatrix[xIndex] === undefined) { + dataMatrix[xIndex] = []; + } + + var point3d = new Point3d(); + point3d.x = x; + point3d.y = y; + point3d.z = z; + + obj = {}; + obj.point = point3d; + obj.trans = undefined; + obj.screen = undefined; + obj.bottom = new Point3d(x, y, this.zMin); + + dataMatrix[xIndex][yIndex] = obj; + + dataPoints.push(obj); } - } - else if (ids != undefined) { - // return a subset of items - for (i = 0, len = ids.length; i < len; i++) { - item = me._getItem(ids[i], type); - if (!filter || filter(item)) { - items.push(item); + + // fill in the pointers to the neighbors. + for (x = 0; x < dataMatrix.length; x++) { + for (y = 0; y < dataMatrix[x].length; y++) { + if (dataMatrix[x][y]) { + dataMatrix[x][y].pointRight = (x < dataMatrix.length-1) ? dataMatrix[x+1][y] : undefined; + dataMatrix[x][y].pointTop = (y < dataMatrix[x].length-1) ? dataMatrix[x][y+1] : undefined; + dataMatrix[x][y].pointCross = + (x < dataMatrix.length-1 && y < dataMatrix[x].length-1) ? + dataMatrix[x+1][y+1] : + undefined; + } } } } - else { - // return all items - for (itemId in this._data) { - if (this._data.hasOwnProperty(itemId)) { - item = me._getItem(itemId, type); - if (!filter || filter(item)) { - items.push(item); - } + else { // 'dot', 'dot-line', etc. + // copy all values from the google data table to a list with Point3d objects + for (i = 0; i < data.length; i++) { + point = new Point3d(); + point.x = data[i][this.colX] || 0; + point.y = data[i][this.colY] || 0; + point.z = data[i][this.colZ] || 0; + + if (this.colValue !== undefined) { + point.value = data[i][this.colValue] || 0; } + + obj = {}; + obj.point = point; + obj.bottom = new Point3d(point.x, point.y, this.zMin); + obj.trans = undefined; + obj.screen = undefined; + + dataPoints.push(obj); } } - // order the results - if (options && options.order && id == undefined) { - this._sort(items, options.order); + return dataPoints; + }; + + /** + * Create the main frame for the Graph3d. + * This function is executed once when a Graph3d object is created. The frame + * contains a canvas, and this canvas contains all objects like the axis and + * nodes. + */ + Graph3d.prototype.create = function () { + // remove all elements from the container element. + while (this.containerElement.hasChildNodes()) { + this.containerElement.removeChild(this.containerElement.firstChild); + } + + this.frame = document.createElement('div'); + this.frame.style.position = 'relative'; + this.frame.style.overflow = 'hidden'; + + // create the graph canvas (HTML canvas element) + this.frame.canvas = document.createElement( 'canvas' ); + this.frame.canvas.style.position = 'relative'; + this.frame.appendChild(this.frame.canvas); + //if (!this.frame.canvas.getContext) { + { + var noCanvas = document.createElement( 'DIV' ); + noCanvas.style.color = 'red'; + noCanvas.style.fontWeight = 'bold' ; + noCanvas.style.padding = '10px'; + noCanvas.innerHTML = 'Error: your browser does not support HTML canvas'; + this.frame.canvas.appendChild(noCanvas); + } + + this.frame.filter = document.createElement( 'div' ); + this.frame.filter.style.position = 'absolute'; + this.frame.filter.style.bottom = '0px'; + this.frame.filter.style.left = '0px'; + this.frame.filter.style.width = '100%'; + this.frame.appendChild(this.frame.filter); + + // add event listeners to handle moving and zooming the contents + var me = this; + var onmousedown = function (event) {me._onMouseDown(event);}; + var ontouchstart = function (event) {me._onTouchStart(event);}; + var onmousewheel = function (event) {me._onWheel(event);}; + var ontooltip = function (event) {me._onTooltip(event);}; + // TODO: these events are never cleaned up... can give a 'memory leakage' + + util.addEventListener(this.frame.canvas, 'keydown', onkeydown); + util.addEventListener(this.frame.canvas, 'mousedown', onmousedown); + util.addEventListener(this.frame.canvas, 'touchstart', ontouchstart); + util.addEventListener(this.frame.canvas, 'mousewheel', onmousewheel); + util.addEventListener(this.frame.canvas, 'mousemove', ontooltip); + + // add the new graph to the container element + this.containerElement.appendChild(this.frame); + }; + + + /** + * Set a new size for the graph + * @param {string} width Width in pixels or percentage (for example '800px' + * or '50%') + * @param {string} height Height in pixels or percentage (for example '400px' + * or '30%') + */ + Graph3d.prototype.setSize = function(width, height) { + this.frame.style.width = width; + this.frame.style.height = height; + + this._resizeCanvas(); + }; + + /** + * Resize the canvas to the current size of the frame + */ + Graph3d.prototype._resizeCanvas = function() { + this.frame.canvas.style.width = '100%'; + this.frame.canvas.style.height = '100%'; + + this.frame.canvas.width = this.frame.canvas.clientWidth; + this.frame.canvas.height = this.frame.canvas.clientHeight; + + // adjust with for margin + this.frame.filter.style.width = (this.frame.canvas.clientWidth - 2 * 10) + 'px'; + }; + + /** + * Start animation + */ + Graph3d.prototype.animationStart = function() { + if (!this.frame.filter || !this.frame.filter.slider) + throw 'No animation available'; + + this.frame.filter.slider.play(); + }; + + + /** + * Stop animation + */ + Graph3d.prototype.animationStop = function() { + if (!this.frame.filter || !this.frame.filter.slider) return; + + this.frame.filter.slider.stop(); + }; + + + /** + * Resize the center position based on the current values in this.defaultXCenter + * and this.defaultYCenter (which are strings with a percentage or a value + * in pixels). The center positions are the variables this.xCenter + * and this.yCenter + */ + Graph3d.prototype._resizeCenter = function() { + // calculate the horizontal center position + if (this.defaultXCenter.charAt(this.defaultXCenter.length-1) === '%') { + this.xcenter = + parseFloat(this.defaultXCenter) / 100 * + this.frame.canvas.clientWidth; } - - // filter fields of the items - if (options && options.fields) { - var fields = options.fields; - if (id != undefined) { - item = this._filterFields(item, fields); - } - else { - for (i = 0, len = items.length; i < len; i++) { - items[i] = this._filterFields(items[i], fields); - } - } + else { + this.xcenter = parseFloat(this.defaultXCenter); // supposed to be in px } - // return the results - if (returnType == 'DataTable') { - var columns = this._getColumnNames(data); - if (id != undefined) { - // append a single item to the data table - me._appendRow(data, columns, item); - } - else { - // copy the items to the provided data table - for (i = 0; i < items.length; i++) { - me._appendRow(data, columns, items[i]); - } - } - return data; - } - else if (returnType == "Object") { - var result = {}; - for (i = 0; i < items.length; i++) { - result[items[i].id] = items[i]; - } - return result; + // calculate the vertical center position + if (this.defaultYCenter.charAt(this.defaultYCenter.length-1) === '%') { + this.ycenter = + parseFloat(this.defaultYCenter) / 100 * + (this.frame.canvas.clientHeight - this.frame.filter.clientHeight); } else { - // return an array - if (id != undefined) { - // a single item - return item; - } - else { - // multiple items - if (data) { - // copy the items to the provided array - for (i = 0, len = items.length; i < len; i++) { - data.push(items[i]); - } - return data; - } - else { - // just return our array - return items; - } - } + this.ycenter = parseFloat(this.defaultYCenter); // supposed to be in px } }; /** - * Get ids of all items or from a filtered set of items. - * @param {Object} [options] An Object with options. Available options: - * {function} [filter] filter items - * {String | function} [order] Order the items by - * a field name or custom sort function. - * @return {Array} ids + * Set the rotation and distance of the camera + * @param {Object} pos An object with the camera position. The object + * contains three parameters: + * - horizontal {Number} + * The horizontal rotation, between 0 and 2*PI. + * Optional, can be left undefined. + * - vertical {Number} + * The vertical rotation, between 0 and 0.5*PI + * if vertical=0.5*PI, the graph is shown from the + * top. Optional, can be left undefined. + * - distance {Number} + * The (normalized) distance of the camera to the + * center of the graph, a value between 0.71 and 5.0. + * Optional, can be left undefined. */ - DataSet.prototype.getIds = function (options) { - var data = this._data, - filter = options && options.filter, - order = options && options.order, - type = options && options.type || this._options.type, - i, - len, - id, - item, - items, - ids = []; - - if (filter) { - // get filtered items - if (order) { - // create ordered list - items = []; - for (id in data) { - if (data.hasOwnProperty(id)) { - item = this._getItem(id, type); - if (filter(item)) { - items.push(item); - } - } - } - - this._sort(items, order); - - for (i = 0, len = items.length; i < len; i++) { - ids[i] = items[i][this._fieldId]; - } - } - else { - // create unordered list - for (id in data) { - if (data.hasOwnProperty(id)) { - item = this._getItem(id, type); - if (filter(item)) { - ids.push(item[this._fieldId]); - } - } - } - } + Graph3d.prototype.setCameraPosition = function(pos) { + if (pos === undefined) { + return; } - else { - // get all items - if (order) { - // create an ordered list - items = []; - for (id in data) { - if (data.hasOwnProperty(id)) { - items.push(data[id]); - } - } - this._sort(items, order); + if (pos.horizontal !== undefined && pos.vertical !== undefined) { + this.camera.setArmRotation(pos.horizontal, pos.vertical); + } - for (i = 0, len = items.length; i < len; i++) { - ids[i] = items[i][this._fieldId]; - } - } - else { - // create unordered list - for (id in data) { - if (data.hasOwnProperty(id)) { - item = data[id]; - ids.push(item[this._fieldId]); - } - } - } + if (pos.distance !== undefined) { + this.camera.setArmLength(pos.distance); } - return ids; + this.redraw(); }; + /** - * Returns the DataSet itself. Is overwritten for example by the DataView, - * which returns the DataSet it is connected to instead. + * Retrieve the current camera rotation + * @return {object} An object with parameters horizontal, vertical, and + * distance */ - DataSet.prototype.getDataSet = function () { - return this; + Graph3d.prototype.getCameraPosition = function() { + var pos = this.camera.getArmRotation(); + pos.distance = this.camera.getArmLength(); + return pos; }; /** - * Execute a callback function for every item in the dataset. - * @param {function} callback - * @param {Object} [options] Available options: - * {Object.} [type] - * {String[]} [fields] filter fields - * {function} [filter] filter items - * {String | function} [order] Order the items by - * a field name or custom sort function. + * Load data into the 3D Graph */ - DataSet.prototype.forEach = function (callback, options) { - var filter = options && options.filter, - type = options && options.type || this._options.type, - data = this._data, - item, - id; + Graph3d.prototype._readData = function(data) { + // read the data + this._dataInitialize(data, this.style); - if (options && options.order) { - // execute forEach on ordered list - var items = this.get(options); - for (var i = 0, len = items.length; i < len; i++) { - item = items[i]; - id = item[this._fieldId]; - callback(item, id); - } + if (this.dataFilter) { + // apply filtering + this.dataPoints = this.dataFilter._getDataPoints(); } else { - // unordered - for (id in data) { - if (data.hasOwnProperty(id)) { - item = this._getItem(id, type); - if (!filter || filter(item)) { - callback(item, id); - } - } - } + // no filtering. load all data + this.dataPoints = this._getDataPoints(this.dataTable); } + + // draw the filter + this._redrawFilter(); }; /** - * Map every item in the dataset. - * @param {function} callback - * @param {Object} [options] Available options: - * {Object.} [type] - * {String[]} [fields] filter fields - * {function} [filter] filter items - * {String | function} [order] Order the items by - * a field name or custom sort function. - * @return {Object[]} mappedItems + * Replace the dataset of the Graph3d + * @param {Array | DataSet | DataView} data */ - DataSet.prototype.map = function (callback, options) { - var filter = options && options.filter, - type = options && options.type || this._options.type, - mappedItems = [], - data = this._data, - item; - - // convert and filter items - for (var id in data) { - if (data.hasOwnProperty(id)) { - item = this._getItem(id, type); - if (!filter || filter(item)) { - mappedItems.push(callback(item, id)); - } - } - } + Graph3d.prototype.setData = function (data) { + this._readData(data); + this.redraw(); - // order items - if (options && options.order) { - this._sort(mappedItems, options.order); + // start animation when option is true + if (this.animationAutoStart && this.dataFilter) { + this.animationStart(); } - - return mappedItems; }; /** - * Filter the fields of an item - * @param {Object} item - * @param {String[]} fields Field names - * @return {Object} filteredItem - * @private + * Update the options. Options will be merged with current options + * @param {Object} options */ - DataSet.prototype._filterFields = function (item, fields) { - var filteredItem = {}; + Graph3d.prototype.setOptions = function (options) { + var cameraPosition = undefined; - for (var field in item) { - if (item.hasOwnProperty(field) && (fields.indexOf(field) != -1)) { - filteredItem[field] = item[field]; + this.animationStop(); + + if (options !== undefined) { + // retrieve parameter values + if (options.width !== undefined) this.width = options.width; + if (options.height !== undefined) this.height = options.height; + + if (options.xCenter !== undefined) this.defaultXCenter = options.xCenter; + if (options.yCenter !== undefined) this.defaultYCenter = options.yCenter; + + if (options.filterLabel !== undefined) this.filterLabel = options.filterLabel; + if (options.legendLabel !== undefined) this.legendLabel = options.legendLabel; + if (options.xLabel !== undefined) this.xLabel = options.xLabel; + if (options.yLabel !== undefined) this.yLabel = options.yLabel; + if (options.zLabel !== undefined) this.zLabel = options.zLabel; + + if (options.xValueLabel !== undefined) this.xValueLabel = options.xValueLabel; + if (options.yValueLabel !== undefined) this.yValueLabel = options.yValueLabel; + if (options.zValueLabel !== undefined) this.zValueLabel = options.zValueLabel; + + if (options.style !== undefined) { + var styleNumber = this._getStyleNumber(options.style); + if (styleNumber !== -1) { + this.style = styleNumber; + } + } + if (options.showGrid !== undefined) this.showGrid = options.showGrid; + if (options.showPerspective !== undefined) this.showPerspective = options.showPerspective; + if (options.showShadow !== undefined) this.showShadow = options.showShadow; + if (options.tooltip !== undefined) this.showTooltip = options.tooltip; + if (options.showAnimationControls !== undefined) this.showAnimationControls = options.showAnimationControls; + if (options.keepAspectRatio !== undefined) this.keepAspectRatio = options.keepAspectRatio; + if (options.verticalRatio !== undefined) this.verticalRatio = options.verticalRatio; + + if (options.animationInterval !== undefined) this.animationInterval = options.animationInterval; + if (options.animationPreload !== undefined) this.animationPreload = options.animationPreload; + if (options.animationAutoStart !== undefined)this.animationAutoStart = options.animationAutoStart; + + if (options.xBarWidth !== undefined) this.defaultXBarWidth = options.xBarWidth; + if (options.yBarWidth !== undefined) this.defaultYBarWidth = options.yBarWidth; + + if (options.xMin !== undefined) this.defaultXMin = options.xMin; + if (options.xStep !== undefined) this.defaultXStep = options.xStep; + if (options.xMax !== undefined) this.defaultXMax = options.xMax; + if (options.yMin !== undefined) this.defaultYMin = options.yMin; + if (options.yStep !== undefined) this.defaultYStep = options.yStep; + if (options.yMax !== undefined) this.defaultYMax = options.yMax; + if (options.zMin !== undefined) this.defaultZMin = options.zMin; + if (options.zStep !== undefined) this.defaultZStep = options.zStep; + if (options.zMax !== undefined) this.defaultZMax = options.zMax; + if (options.valueMin !== undefined) this.defaultValueMin = options.valueMin; + if (options.valueMax !== undefined) this.defaultValueMax = options.valueMax; + + if (options.cameraPosition !== undefined) cameraPosition = options.cameraPosition; + + if (cameraPosition !== undefined) { + this.camera.setArmRotation(cameraPosition.horizontal, cameraPosition.vertical); + this.camera.setArmLength(cameraPosition.distance); + } + else { + this.camera.setArmRotation(1.0, 0.5); + this.camera.setArmLength(1.7); } } - return filteredItem; + this._setBackgroundColor(options && options.backgroundColor); + + this.setSize(this.width, this.height); + + // re-load the data + if (this.dataTable) { + this.setData(this.dataTable); + } + + // start animation when option is true + if (this.animationAutoStart && this.dataFilter) { + this.animationStart(); + } }; /** - * Sort the provided array with items - * @param {Object[]} items - * @param {String | function} order A field name or custom sort function. - * @private + * Redraw the Graph. */ - DataSet.prototype._sort = function (items, order) { - if (util.isString(order)) { - // order by provided field name - var name = order; // field name - items.sort(function (a, b) { - var av = a[name]; - var bv = b[name]; - return (av > bv) ? 1 : ((av < bv) ? -1 : 0); - }); + Graph3d.prototype.redraw = function() { + if (this.dataPoints === undefined) { + throw 'Error: graph data not initialized'; } - else if (typeof order === 'function') { - // order by sort function - items.sort(order); + + this._resizeCanvas(); + this._resizeCenter(); + this._redrawSlider(); + this._redrawClear(); + this._redrawAxis(); + + if (this.style === Graph3d.STYLE.GRID || + this.style === Graph3d.STYLE.SURFACE) { + this._redrawDataGrid(); + } + else if (this.style === Graph3d.STYLE.LINE) { + this._redrawDataLine(); + } + else if (this.style === Graph3d.STYLE.BAR || + this.style === Graph3d.STYLE.BARCOLOR || + this.style === Graph3d.STYLE.BARSIZE) { + this._redrawDataBar(); } - // TODO: extend order by an Object {field:String, direction:String} - // where direction can be 'asc' or 'desc' else { - throw new TypeError('Order must be a function or a string'); + // style is DOT, DOTLINE, DOTCOLOR, DOTSIZE + this._redrawDataDot(); } + + this._redrawInfo(); + this._redrawLegend(); }; /** - * Remove an object by pointer or by id - * @param {String | Number | Object | Array} id Object or id, or an array with - * objects or ids to be removed - * @param {String} [senderId] Optional sender id - * @return {Array} removedIds + * Clear the canvas before redrawing */ - DataSet.prototype.remove = function (id, senderId) { - var removedIds = [], - i, len, removedId; + Graph3d.prototype._redrawClear = function() { + var canvas = this.frame.canvas; + var ctx = canvas.getContext('2d'); - if (Array.isArray(id)) { - for (i = 0, len = id.length; i < len; i++) { - removedId = this._remove(id[i]); - if (removedId != null) { - removedIds.push(removedId); - } + ctx.clearRect(0, 0, canvas.width, canvas.height); + }; + + + /** + * Redraw the legend showing the colors + */ + Graph3d.prototype._redrawLegend = function() { + var y; + + if (this.style === Graph3d.STYLE.DOTCOLOR || + this.style === Graph3d.STYLE.DOTSIZE) { + + var dotSize = this.frame.clientWidth * 0.02; + + var widthMin, widthMax; + if (this.style === Graph3d.STYLE.DOTSIZE) { + widthMin = dotSize / 2; // px + widthMax = dotSize / 2 + dotSize * 2; // Todo: put this in one function } - } - else { - removedId = this._remove(id); - if (removedId != null) { - removedIds.push(removedId); + else { + widthMin = 20; // px + widthMax = 20; // px } - } - if (removedIds.length) { - this._trigger('remove', {items: removedIds}, senderId); + var height = Math.max(this.frame.clientHeight * 0.25, 100); + var top = this.margin; + var right = this.frame.clientWidth - this.margin; + var left = right - widthMax; + var bottom = top + height; } - return removedIds; - }; + var canvas = this.frame.canvas; + var ctx = canvas.getContext('2d'); + ctx.lineWidth = 1; + ctx.font = '14px arial'; // TODO: put in options - /** - * Remove an item by its id - * @param {Number | String | Object} id id or item - * @returns {Number | String | null} id - * @private - */ - DataSet.prototype._remove = function (id) { - if (util.isNumber(id) || util.isString(id)) { - if (this._data[id]) { - delete this._data[id]; - return id; + if (this.style === Graph3d.STYLE.DOTCOLOR) { + // draw the color bar + var ymin = 0; + var ymax = height; // Todo: make height customizable + for (y = ymin; y < ymax; y++) { + var f = (y - ymin) / (ymax - ymin); + + //var width = (dotSize / 2 + (1-f) * dotSize * 2); // Todo: put this in one function + var hue = f * 240; + var color = this._hsv2rgb(hue, 1, 1); + + ctx.strokeStyle = color; + ctx.beginPath(); + ctx.moveTo(left, top + y); + ctx.lineTo(right, top + y); + ctx.stroke(); } + + ctx.strokeStyle = this.colorAxis; + ctx.strokeRect(left, top, widthMax, height); } - else if (id instanceof Object) { - var itemId = id[this._fieldId]; - if (itemId && this._data[itemId]) { - delete this._data[itemId]; - return itemId; + + if (this.style === Graph3d.STYLE.DOTSIZE) { + // draw border around color bar + ctx.strokeStyle = this.colorAxis; + ctx.fillStyle = this.colorDot; + ctx.beginPath(); + ctx.moveTo(left, top); + ctx.lineTo(right, top); + ctx.lineTo(right - widthMax + widthMin, bottom); + ctx.lineTo(left, bottom); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + } + + if (this.style === Graph3d.STYLE.DOTCOLOR || + this.style === Graph3d.STYLE.DOTSIZE) { + // print values along the color bar + var gridLineLen = 5; // px + var step = new StepNumber(this.valueMin, this.valueMax, (this.valueMax-this.valueMin)/5, true); + step.start(); + if (step.getCurrent() < this.valueMin) { + step.next(); + } + while (!step.end()) { + y = bottom - (step.getCurrent() - this.valueMin) / (this.valueMax - this.valueMin) * height; + + ctx.beginPath(); + ctx.moveTo(left - gridLineLen, y); + ctx.lineTo(left, y); + ctx.stroke(); + + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + ctx.fillStyle = this.colorAxis; + ctx.fillText(step.getCurrent(), left - 2 * gridLineLen, y); + + step.next(); } + + ctx.textAlign = 'right'; + ctx.textBaseline = 'top'; + var label = this.legendLabel; + ctx.fillText(label, right, bottom + this.margin); } - return null; }; /** - * Clear the data - * @param {String} [senderId] Optional sender id - * @return {Array} removedIds The ids of all removed items + * Redraw the filter */ - DataSet.prototype.clear = function (senderId) { - var ids = Object.keys(this._data); + Graph3d.prototype._redrawFilter = function() { + this.frame.filter.innerHTML = ''; - this._data = {}; + if (this.dataFilter) { + var options = { + 'visible': this.showAnimationControls + }; + var slider = new Slider(this.frame.filter, options); + this.frame.filter.slider = slider; - this._trigger('remove', {items: ids}, senderId); + // TODO: css here is not nice here... + this.frame.filter.style.padding = '10px'; + //this.frame.filter.style.backgroundColor = '#EFEFEF'; - return ids; - }; + slider.setValues(this.dataFilter.values); + slider.setPlayInterval(this.animationInterval); - /** - * Find the item with maximum value of a specified field - * @param {String} field - * @return {Object | null} item Item containing max value, or null if no items - */ - DataSet.prototype.max = function (field) { - var data = this._data, - max = null, - maxField = null; + // create an event handler + var me = this; + var onchange = function () { + var index = slider.getIndex(); - for (var id in data) { - if (data.hasOwnProperty(id)) { - var item = data[id]; - var itemField = item[field]; - if (itemField != null && (!max || itemField > maxField)) { - max = item; - maxField = itemField; - } - } - } + me.dataFilter.selectValue(index); + me.dataPoints = me.dataFilter._getDataPoints(); - return max; + me.redraw(); + }; + slider.setOnChangeCallback(onchange); + } + else { + this.frame.filter.slider = undefined; + } }; /** - * Find the item with minimum value of a specified field - * @param {String} field - * @return {Object | null} item Item containing max value, or null if no items + * Redraw the slider */ - DataSet.prototype.min = function (field) { - var data = this._data, - min = null, - minField = null; - - for (var id in data) { - if (data.hasOwnProperty(id)) { - var item = data[id]; - var itemField = item[field]; - if (itemField != null && (!min || itemField < minField)) { - min = item; - minField = itemField; - } - } + Graph3d.prototype._redrawSlider = function() { + if ( this.frame.filter.slider !== undefined) { + this.frame.filter.slider.redraw(); } - - return min; }; + /** - * Find all distinct values of a specified field - * @param {String} field - * @return {Array} values Array containing all distinct values. If data items - * do not contain the specified field are ignored. - * The returned array is unordered. + * Redraw common information */ - DataSet.prototype.distinct = function (field) { - var data = this._data; - var values = []; - var fieldType = this._options.type && this._options.type[field] || null; - var count = 0; - var i; + Graph3d.prototype._redrawInfo = function() { + if (this.dataFilter) { + var canvas = this.frame.canvas; + var ctx = canvas.getContext('2d'); - for (var prop in data) { - if (data.hasOwnProperty(prop)) { - var item = data[prop]; - var value = item[field]; - var exists = false; - for (i = 0; i < count; i++) { - if (values[i] == value) { - exists = true; - break; - } - } - if (!exists && (value !== undefined)) { - values[count] = value; - count++; - } - } - } + ctx.font = '14px arial'; // TODO: put in options + ctx.lineStyle = 'gray'; + ctx.fillStyle = 'gray'; + ctx.textAlign = 'left'; + ctx.textBaseline = 'top'; - if (fieldType) { - for (i = 0; i < values.length; i++) { - values[i] = util.convert(values[i], fieldType); - } + var x = this.margin; + var y = this.margin; + ctx.fillText(this.dataFilter.getLabel() + ': ' + this.dataFilter.getSelectedValue(), x, y); } - - return values; }; + /** - * Add a single item. Will fail when an item with the same id already exists. - * @param {Object} item - * @return {String} id - * @private + * Redraw the axis */ - DataSet.prototype._addItem = function (item) { - var id = item[this._fieldId]; + Graph3d.prototype._redrawAxis = function() { + var canvas = this.frame.canvas, + ctx = canvas.getContext('2d'), + from, to, step, prettyStep, + text, xText, yText, zText, + offset, xOffset, yOffset, + xMin2d, xMax2d; - if (id != undefined) { - // check whether this id is already taken - if (this._data[id]) { - // item already exists - throw new Error('Cannot add item: item with id ' + id + ' already exists'); - } - } - else { - // generate an id - id = util.randomUUID(); - item[this._fieldId] = id; + // TODO: get the actual rendered style of the containerElement + //ctx.font = this.containerElement.style.font; + ctx.font = 24 / this.camera.getArmLength() + 'px arial'; + + // calculate the length for the short grid lines + var gridLenX = 0.025 / this.scale.x; + var gridLenY = 0.025 / this.scale.y; + var textMargin = 5 / this.camera.getArmLength(); // px + var armAngle = this.camera.getArmRotation().horizontal; + + // draw x-grid lines + ctx.lineWidth = 1; + prettyStep = (this.defaultXStep === undefined); + step = new StepNumber(this.xMin, this.xMax, this.xStep, prettyStep); + step.start(); + if (step.getCurrent() < this.xMin) { + step.next(); } + while (!step.end()) { + var x = step.getCurrent(); - var d = {}; - for (var field in item) { - if (item.hasOwnProperty(field)) { - var fieldType = this._type[field]; // type may be undefined - d[field] = util.convert(item[field], fieldType); + if (this.showGrid) { + from = this._convert3Dto2D(new Point3d(x, this.yMin, this.zMin)); + to = this._convert3Dto2D(new Point3d(x, this.yMax, this.zMin)); + ctx.strokeStyle = this.colorGrid; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); } - } - this._data[id] = d; + else { + from = this._convert3Dto2D(new Point3d(x, this.yMin, this.zMin)); + to = this._convert3Dto2D(new Point3d(x, this.yMin+gridLenX, this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); - return id; - }; + from = this._convert3Dto2D(new Point3d(x, this.yMax, this.zMin)); + to = this._convert3Dto2D(new Point3d(x, this.yMax-gridLenX, this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); + } - /** - * Get an item. Fields can be converted to a specific type - * @param {String} id - * @param {Object.} [types] field types to convert - * @return {Object | null} item - * @private - */ - DataSet.prototype._getItem = function (id, types) { - var field, value; + yText = (Math.cos(armAngle) > 0) ? this.yMin : this.yMax; + text = this._convert3Dto2D(new Point3d(x, yText, this.zMin)); + if (Math.cos(armAngle * 2) > 0) { + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + text.y += textMargin; + } + else if (Math.sin(armAngle * 2) < 0){ + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + } + else { + ctx.textAlign = 'left'; + ctx.textBaseline = 'middle'; + } + ctx.fillStyle = this.colorAxis; + ctx.fillText(' ' + this.xValueLabel(step.getCurrent()) + ' ', text.x, text.y); - // get the item from the dataset - var raw = this._data[id]; - if (!raw) { - return null; + step.next(); } - // convert the items field types - var converted = {}; - if (types) { - for (field in raw) { - if (raw.hasOwnProperty(field)) { - value = raw[field]; - converted[field] = util.convert(value, types[field]); - } - } + // draw y-grid lines + ctx.lineWidth = 1; + prettyStep = (this.defaultYStep === undefined); + step = new StepNumber(this.yMin, this.yMax, this.yStep, prettyStep); + step.start(); + if (step.getCurrent() < this.yMin) { + step.next(); } - else { - // no field types specified, no converting needed - for (field in raw) { - if (raw.hasOwnProperty(field)) { - value = raw[field]; - converted[field] = value; - } + while (!step.end()) { + if (this.showGrid) { + from = this._convert3Dto2D(new Point3d(this.xMin, step.getCurrent(), this.zMin)); + to = this._convert3Dto2D(new Point3d(this.xMax, step.getCurrent(), this.zMin)); + ctx.strokeStyle = this.colorGrid; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); + } + else { + from = this._convert3Dto2D(new Point3d(this.xMin, step.getCurrent(), this.zMin)); + to = this._convert3Dto2D(new Point3d(this.xMin+gridLenY, step.getCurrent(), this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); + + from = this._convert3Dto2D(new Point3d(this.xMax, step.getCurrent(), this.zMin)); + to = this._convert3Dto2D(new Point3d(this.xMax-gridLenY, step.getCurrent(), this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); + } + + xText = (Math.sin(armAngle ) > 0) ? this.xMin : this.xMax; + text = this._convert3Dto2D(new Point3d(xText, step.getCurrent(), this.zMin)); + if (Math.cos(armAngle * 2) < 0) { + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + text.y += textMargin; + } + else if (Math.sin(armAngle * 2) > 0){ + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + } + else { + ctx.textAlign = 'left'; + ctx.textBaseline = 'middle'; } + ctx.fillStyle = this.colorAxis; + ctx.fillText(' ' + this.yValueLabel(step.getCurrent()) + ' ', text.x, text.y); + + step.next(); } - return converted; - }; - /** - * Update a single item: merge with existing item. - * Will fail when the item has no id, or when there does not exist an item - * with the same id. - * @param {Object} item - * @return {String} id - * @private - */ - DataSet.prototype._updateItem = function (item) { - var id = item[this._fieldId]; - if (id == undefined) { - throw new Error('Cannot update item: item has no id (item: ' + JSON.stringify(item) + ')'); + // draw z-grid lines and axis + ctx.lineWidth = 1; + prettyStep = (this.defaultZStep === undefined); + step = new StepNumber(this.zMin, this.zMax, this.zStep, prettyStep); + step.start(); + if (step.getCurrent() < this.zMin) { + step.next(); } - var d = this._data[id]; - if (!d) { - // item doesn't exist - throw new Error('Cannot update item: no item with id ' + id + ' found'); + xText = (Math.cos(armAngle ) > 0) ? this.xMin : this.xMax; + yText = (Math.sin(armAngle ) < 0) ? this.yMin : this.yMax; + while (!step.end()) { + // TODO: make z-grid lines really 3d? + from = this._convert3Dto2D(new Point3d(xText, yText, step.getCurrent())); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(from.x - textMargin, from.y); + ctx.stroke(); + + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + ctx.fillStyle = this.colorAxis; + ctx.fillText(this.zValueLabel(step.getCurrent()) + ' ', from.x - 5, from.y); + + step.next(); } + ctx.lineWidth = 1; + from = this._convert3Dto2D(new Point3d(xText, yText, this.zMin)); + to = this._convert3Dto2D(new Point3d(xText, yText, this.zMax)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); - // merge with current item - for (var field in item) { - if (item.hasOwnProperty(field)) { - var fieldType = this._type[field]; // type may be undefined - d[field] = util.convert(item[field], fieldType); + // draw x-axis + ctx.lineWidth = 1; + // line at yMin + xMin2d = this._convert3Dto2D(new Point3d(this.xMin, this.yMin, this.zMin)); + xMax2d = this._convert3Dto2D(new Point3d(this.xMax, this.yMin, this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(xMin2d.x, xMin2d.y); + ctx.lineTo(xMax2d.x, xMax2d.y); + ctx.stroke(); + // line at ymax + xMin2d = this._convert3Dto2D(new Point3d(this.xMin, this.yMax, this.zMin)); + xMax2d = this._convert3Dto2D(new Point3d(this.xMax, this.yMax, this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(xMin2d.x, xMin2d.y); + ctx.lineTo(xMax2d.x, xMax2d.y); + ctx.stroke(); + + // draw y-axis + ctx.lineWidth = 1; + // line at xMin + from = this._convert3Dto2D(new Point3d(this.xMin, this.yMin, this.zMin)); + to = this._convert3Dto2D(new Point3d(this.xMin, this.yMax, this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); + // line at xMax + from = this._convert3Dto2D(new Point3d(this.xMax, this.yMin, this.zMin)); + to = this._convert3Dto2D(new Point3d(this.xMax, this.yMax, this.zMin)); + ctx.strokeStyle = this.colorAxis; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(to.x, to.y); + ctx.stroke(); + + // draw x-label + var xLabel = this.xLabel; + if (xLabel.length > 0) { + yOffset = 0.1 / this.scale.y; + xText = (this.xMin + this.xMax) / 2; + yText = (Math.cos(armAngle) > 0) ? this.yMin - yOffset: this.yMax + yOffset; + text = this._convert3Dto2D(new Point3d(xText, yText, this.zMin)); + if (Math.cos(armAngle * 2) > 0) { + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + } + else if (Math.sin(armAngle * 2) < 0){ + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + } + else { + ctx.textAlign = 'left'; + ctx.textBaseline = 'middle'; } + ctx.fillStyle = this.colorAxis; + ctx.fillText(xLabel, text.x, text.y); } - return id; - }; + // draw y-label + var yLabel = this.yLabel; + if (yLabel.length > 0) { + xOffset = 0.1 / this.scale.x; + xText = (Math.sin(armAngle ) > 0) ? this.xMin - xOffset : this.xMax + xOffset; + yText = (this.yMin + this.yMax) / 2; + text = this._convert3Dto2D(new Point3d(xText, yText, this.zMin)); + if (Math.cos(armAngle * 2) < 0) { + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + } + else if (Math.sin(armAngle * 2) > 0){ + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + } + else { + ctx.textAlign = 'left'; + ctx.textBaseline = 'middle'; + } + ctx.fillStyle = this.colorAxis; + ctx.fillText(yLabel, text.x, text.y); + } - /** - * Get an array with the column names of a Google DataTable - * @param {DataTable} dataTable - * @return {String[]} columnNames - * @private - */ - DataSet.prototype._getColumnNames = function (dataTable) { - var columns = []; - for (var col = 0, cols = dataTable.getNumberOfColumns(); col < cols; col++) { - columns[col] = dataTable.getColumnId(col) || dataTable.getColumnLabel(col); + // draw z-label + var zLabel = this.zLabel; + if (zLabel.length > 0) { + offset = 30; // pixels. // TODO: relate to the max width of the values on the z axis? + xText = (Math.cos(armAngle ) > 0) ? this.xMin : this.xMax; + yText = (Math.sin(armAngle ) < 0) ? this.yMin : this.yMax; + zText = (this.zMin + this.zMax) / 2; + text = this._convert3Dto2D(new Point3d(xText, yText, zText)); + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + ctx.fillStyle = this.colorAxis; + ctx.fillText(zLabel, text.x - offset, text.y); } - return columns; }; /** - * Append an item as a row to the dataTable - * @param dataTable - * @param columns - * @param item - * @private + * Calculate the color based on the given value. + * @param {Number} H Hue, a value be between 0 and 360 + * @param {Number} S Saturation, a value between 0 and 1 + * @param {Number} V Value, a value between 0 and 1 */ - DataSet.prototype._appendRow = function (dataTable, columns, item) { - var row = dataTable.addRow(); + Graph3d.prototype._hsv2rgb = function(H, S, V) { + var R, G, B, C, Hi, X; - for (var col = 0, cols = columns.length; col < cols; col++) { - var field = columns[col]; - dataTable.setValue(row, col, item[field]); + C = V * S; + Hi = Math.floor(H/60); // hi = 0,1,2,3,4,5 + X = C * (1 - Math.abs(((H/60) % 2) - 1)); + + switch (Hi) { + case 0: R = C; G = X; B = 0; break; + case 1: R = X; G = C; B = 0; break; + case 2: R = 0; G = C; B = X; break; + case 3: R = 0; G = X; B = C; break; + case 4: R = X; G = 0; B = C; break; + case 5: R = C; G = 0; B = X; break; + + default: R = 0; G = 0; B = 0; break; } + + return 'RGB(' + parseInt(R*255) + ',' + parseInt(G*255) + ',' + parseInt(B*255) + ')'; }; - module.exports = DataSet; + /** + * Draw all datapoints as a grid + * This function can be used when the style is 'grid' + */ + Graph3d.prototype._redrawDataGrid = function() { + var canvas = this.frame.canvas, + ctx = canvas.getContext('2d'), + point, right, top, cross, + i, + topSideVisible, fillStyle, strokeStyle, lineWidth, + h, s, v, zAvg; + + + if (this.dataPoints === undefined || this.dataPoints.length <= 0) + return; // TODO: throw exception? -/***/ }, -/* 8 */ -/***/ function(module, exports, __webpack_require__) { + // calculate the translations and screen position of all points + for (i = 0; i < this.dataPoints.length; i++) { + var trans = this._convertPointToTranslation(this.dataPoints[i].point); + var screen = this._convertTranslationToScreen(trans); - var util = __webpack_require__(1); - var DataSet = __webpack_require__(7); + this.dataPoints[i].trans = trans; + this.dataPoints[i].screen = screen; - /** - * DataView - * - * a dataview offers a filtered view on a dataset or an other dataview. - * - * @param {DataSet | DataView} data - * @param {Object} [options] Available options: see method get - * - * @constructor DataView - */ - function DataView (data, options) { - this._data = null; - this._ids = {}; // ids of the items currently in memory (just contains a boolean true) - this._options = options || {}; - this._fieldId = 'id'; // name of the field containing id - this._subscribers = {}; // event subscribers + // calculate the translation of the point at the bottom (needed for sorting) + var transBottom = this._convertPointToTranslation(this.dataPoints[i].bottom); + this.dataPoints[i].dist = this.showPerspective ? transBottom.length() : -transBottom.z; + } - var me = this; - this.listener = function () { - me._onEvent.apply(me, arguments); + // sort the points on depth of their (x,y) position (not on z) + var sortDepth = function (a, b) { + return b.dist - a.dist; }; + this.dataPoints.sort(sortDepth); - this.setData(data); - } + if (this.style === Graph3d.STYLE.SURFACE) { + for (i = 0; i < this.dataPoints.length; i++) { + point = this.dataPoints[i]; + right = this.dataPoints[i].pointRight; + top = this.dataPoints[i].pointTop; + cross = this.dataPoints[i].pointCross; - // TODO: implement a function .config() to dynamically update things like configured filter - // and trigger changes accordingly + if (point !== undefined && right !== undefined && top !== undefined && cross !== undefined) { - /** - * Set a data source for the view - * @param {DataSet | DataView} data - */ - DataView.prototype.setData = function (data) { - var ids, i, len; + if (this.showGrayBottom || this.showShadow) { + // calculate the cross product of the two vectors from center + // to left and right, in order to know whether we are looking at the + // bottom or at the top side. We can also use the cross product + // for calculating light intensity + var aDiff = Point3d.subtract(cross.trans, point.trans); + var bDiff = Point3d.subtract(top.trans, right.trans); + var crossproduct = Point3d.crossProduct(aDiff, bDiff); + var len = crossproduct.length(); + // FIXME: there is a bug with determining the surface side (shadow or colored) - if (this._data) { - // unsubscribe from current dataset - if (this._data.unsubscribe) { - this._data.unsubscribe('*', this.listener); - } + topSideVisible = (crossproduct.z > 0); + } + else { + topSideVisible = true; + } - // trigger a remove of all items in memory - ids = []; - for (var id in this._ids) { - if (this._ids.hasOwnProperty(id)) { - ids.push(id); + if (topSideVisible) { + // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 + zAvg = (point.point.z + right.point.z + top.point.z + cross.point.z) / 4; + h = (1 - (zAvg - this.zMin) * this.scale.z / this.verticalRatio) * 240; + s = 1; // saturation + + if (this.showShadow) { + v = Math.min(1 + (crossproduct.x / len) / 2, 1); // value. TODO: scale + fillStyle = this._hsv2rgb(h, s, v); + strokeStyle = fillStyle; + } + else { + v = 1; + fillStyle = this._hsv2rgb(h, s, v); + strokeStyle = this.colorAxis; + } + } + else { + fillStyle = 'gray'; + strokeStyle = this.colorAxis; + } + lineWidth = 0.5; + + ctx.lineWidth = lineWidth; + ctx.fillStyle = fillStyle; + ctx.strokeStyle = strokeStyle; + ctx.beginPath(); + ctx.moveTo(point.screen.x, point.screen.y); + ctx.lineTo(right.screen.x, right.screen.y); + ctx.lineTo(cross.screen.x, cross.screen.y); + ctx.lineTo(top.screen.x, top.screen.y); + ctx.closePath(); + ctx.fill(); + ctx.stroke(); } } - this._ids = {}; - this._trigger('remove', {items: ids}); } + else { // grid style + for (i = 0; i < this.dataPoints.length; i++) { + point = this.dataPoints[i]; + right = this.dataPoints[i].pointRight; + top = this.dataPoints[i].pointTop; - this._data = data; + if (point !== undefined) { + if (this.showPerspective) { + lineWidth = 2 / -point.trans.z; + } + else { + lineWidth = 2 * -(this.eye.z / this.camera.getArmLength()); + } + } - if (this._data) { - // update fieldId - this._fieldId = this._options.fieldId || - (this._data && this._data.options && this._data.options.fieldId) || - 'id'; + if (point !== undefined && right !== undefined) { + // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 + zAvg = (point.point.z + right.point.z) / 2; + h = (1 - (zAvg - this.zMin) * this.scale.z / this.verticalRatio) * 240; - // trigger an add of all added items - ids = this._data.getIds({filter: this._options && this._options.filter}); - for (i = 0, len = ids.length; i < len; i++) { - id = ids[i]; - this._ids[id] = true; - } - this._trigger('add', {items: ids}); + ctx.lineWidth = lineWidth; + ctx.strokeStyle = this._hsv2rgb(h, 1, 1); + ctx.beginPath(); + ctx.moveTo(point.screen.x, point.screen.y); + ctx.lineTo(right.screen.x, right.screen.y); + ctx.stroke(); + } - // subscribe to new dataset - if (this._data.on) { - this._data.on('*', this.listener); + if (point !== undefined && top !== undefined) { + // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 + zAvg = (point.point.z + top.point.z) / 2; + h = (1 - (zAvg - this.zMin) * this.scale.z / this.verticalRatio) * 240; + + ctx.lineWidth = lineWidth; + ctx.strokeStyle = this._hsv2rgb(h, 1, 1); + ctx.beginPath(); + ctx.moveTo(point.screen.x, point.screen.y); + ctx.lineTo(top.screen.x, top.screen.y); + ctx.stroke(); + } } } }; + /** - * Get data from the data view - * - * Usage: - * - * get() - * get(options: Object) - * get(options: Object, data: Array | DataTable) - * - * get(id: Number) - * get(id: Number, options: Object) - * get(id: Number, options: Object, data: Array | DataTable) - * - * get(ids: Number[]) - * get(ids: Number[], options: Object) - * get(ids: Number[], options: Object, data: Array | DataTable) - * - * Where: - * - * {Number | String} id The id of an item - * {Number[] | String{}} ids An array with ids of items - * {Object} options An Object with options. Available options: - * {String} [type] Type of data to be returned. Can - * be 'DataTable' or 'Array' (default) - * {Object.} [convert] - * {String[]} [fields] field names to be returned - * {function} [filter] filter items - * {String | function} [order] Order the items by - * a field name or custom sort function. - * {Array | DataTable} [data] If provided, items will be appended to this - * array or table. Required in case of Google - * DataTable. - * @param args + * Draw all datapoints as dots. + * This function can be used when the style is 'dot' or 'dot-line' */ - DataView.prototype.get = function (args) { - var me = this; + Graph3d.prototype._redrawDataDot = function() { + var canvas = this.frame.canvas; + var ctx = canvas.getContext('2d'); + var i; - // parse the arguments - var ids, options, data; - var firstType = util.getType(arguments[0]); - if (firstType == 'String' || firstType == 'Number' || firstType == 'Array') { - // get(id(s) [, options] [, data]) - ids = arguments[0]; // can be a single id or an array with ids - options = arguments[1]; - data = arguments[2]; - } - else { - // get([, options] [, data]) - options = arguments[0]; - data = arguments[1]; - } + if (this.dataPoints === undefined || this.dataPoints.length <= 0) + return; // TODO: throw exception? - // extend the options with the default options and provided options - var viewOptions = util.extend({}, this._options, options); + // calculate the translations of all points + for (i = 0; i < this.dataPoints.length; i++) { + var trans = this._convertPointToTranslation(this.dataPoints[i].point); + var screen = this._convertTranslationToScreen(trans); + this.dataPoints[i].trans = trans; + this.dataPoints[i].screen = screen; - // create a combined filter method when needed - if (this._options.filter && options && options.filter) { - viewOptions.filter = function (item) { - return me._options.filter(item) && options.filter(item); - } + // calculate the distance from the point at the bottom to the camera + var transBottom = this._convertPointToTranslation(this.dataPoints[i].bottom); + this.dataPoints[i].dist = this.showPerspective ? transBottom.length() : -transBottom.z; } - // build up the call to the linked data set - var getArguments = []; - if (ids != undefined) { - getArguments.push(ids); - } - getArguments.push(viewOptions); - getArguments.push(data); + // order the translated points by depth + var sortDepth = function (a, b) { + return b.dist - a.dist; + }; + this.dataPoints.sort(sortDepth); - return this._data && this._data.get.apply(this._data, getArguments); - }; + // draw the datapoints as colored circles + var dotSize = this.frame.clientWidth * 0.02; // px + for (i = 0; i < this.dataPoints.length; i++) { + var point = this.dataPoints[i]; - /** - * Get ids of all items or from a filtered set of items. - * @param {Object} [options] An Object with options. Available options: - * {function} [filter] filter items - * {String | function} [order] Order the items by - * a field name or custom sort function. - * @return {Array} ids - */ - DataView.prototype.getIds = function (options) { - var ids; + if (this.style === Graph3d.STYLE.DOTLINE) { + // draw a vertical line from the bottom to the graph value + //var from = this._convert3Dto2D(new Point3d(point.point.x, point.point.y, this.zMin)); + var from = this._convert3Dto2D(point.bottom); + ctx.lineWidth = 1; + ctx.strokeStyle = this.colorGrid; + ctx.beginPath(); + ctx.moveTo(from.x, from.y); + ctx.lineTo(point.screen.x, point.screen.y); + ctx.stroke(); + } - if (this._data) { - var defaultFilter = this._options.filter; - var filter; + // calculate radius for the circle + var size; + if (this.style === Graph3d.STYLE.DOTSIZE) { + size = dotSize/2 + 2*dotSize * (point.point.value - this.valueMin) / (this.valueMax - this.valueMin); + } + else { + size = dotSize; + } - if (options && options.filter) { - if (defaultFilter) { - filter = function (item) { - return defaultFilter(item) && options.filter(item); - } - } - else { - filter = options.filter; - } + var radius; + if (this.showPerspective) { + radius = size / -point.trans.z; } else { - filter = defaultFilter; + radius = size * -(this.eye.z / this.camera.getArmLength()); + } + if (radius < 0) { + radius = 0; } - ids = this._data.getIds({ - filter: filter, - order: options && options.order - }); - } - else { - ids = []; - } + var hue, color, borderColor; + if (this.style === Graph3d.STYLE.DOTCOLOR ) { + // calculate the color based on the value + hue = (1 - (point.point.value - this.valueMin) * this.scale.value) * 240; + color = this._hsv2rgb(hue, 1, 1); + borderColor = this._hsv2rgb(hue, 1, 0.8); + } + else if (this.style === Graph3d.STYLE.DOTSIZE) { + color = this.colorDot; + borderColor = this.colorDotBorder; + } + else { + // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 + hue = (1 - (point.point.z - this.zMin) * this.scale.z / this.verticalRatio) * 240; + color = this._hsv2rgb(hue, 1, 1); + borderColor = this._hsv2rgb(hue, 1, 0.8); + } - return ids; + // draw the circle + ctx.lineWidth = 1.0; + ctx.strokeStyle = borderColor; + ctx.fillStyle = color; + ctx.beginPath(); + ctx.arc(point.screen.x, point.screen.y, radius, 0, Math.PI*2, true); + ctx.fill(); + ctx.stroke(); + } }; /** - * Get the DataSet to which this DataView is connected. In case there is a chain - * of multiple DataViews, the root DataSet of this chain is returned. - * @return {DataSet} dataSet + * Draw all datapoints as bars. + * This function can be used when the style is 'bar', 'bar-color', or 'bar-size' */ - DataView.prototype.getDataSet = function () { - var dataSet = this; - while (dataSet instanceof DataView) { - dataSet = dataSet._data; + Graph3d.prototype._redrawDataBar = function() { + var canvas = this.frame.canvas; + var ctx = canvas.getContext('2d'); + var i, j, surface, corners; + + if (this.dataPoints === undefined || this.dataPoints.length <= 0) + return; // TODO: throw exception? + + // calculate the translations of all points + for (i = 0; i < this.dataPoints.length; i++) { + var trans = this._convertPointToTranslation(this.dataPoints[i].point); + var screen = this._convertTranslationToScreen(trans); + this.dataPoints[i].trans = trans; + this.dataPoints[i].screen = screen; + + // calculate the distance from the point at the bottom to the camera + var transBottom = this._convertPointToTranslation(this.dataPoints[i].bottom); + this.dataPoints[i].dist = this.showPerspective ? transBottom.length() : -transBottom.z; } - return dataSet || null; - }; - /** - * Event listener. Will propagate all events from the connected data set to - * the subscribers of the DataView, but will filter the items and only trigger - * when there are changes in the filtered data set. - * @param {String} event - * @param {Object | null} params - * @param {String} senderId - * @private - */ - DataView.prototype._onEvent = function (event, params, senderId) { - var i, len, id, item, - ids = params && params.items, - data = this._data, - added = [], - updated = [], - removed = []; + // order the translated points by depth + var sortDepth = function (a, b) { + return b.dist - a.dist; + }; + this.dataPoints.sort(sortDepth); - if (ids && data) { - switch (event) { - case 'add': - // filter the ids of the added items - for (i = 0, len = ids.length; i < len; i++) { - id = ids[i]; - item = this.get(id); - if (item) { - this._ids[id] = true; - added.push(id); - } - } + // draw the datapoints as bars + var xWidth = this.xBarWidth / 2; + var yWidth = this.yBarWidth / 2; + for (i = 0; i < this.dataPoints.length; i++) { + var point = this.dataPoints[i]; - break; + // determine color + var hue, color, borderColor; + if (this.style === Graph3d.STYLE.BARCOLOR ) { + // calculate the color based on the value + hue = (1 - (point.point.value - this.valueMin) * this.scale.value) * 240; + color = this._hsv2rgb(hue, 1, 1); + borderColor = this._hsv2rgb(hue, 1, 0.8); + } + else if (this.style === Graph3d.STYLE.BARSIZE) { + color = this.colorDot; + borderColor = this.colorDotBorder; + } + else { + // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 + hue = (1 - (point.point.z - this.zMin) * this.scale.z / this.verticalRatio) * 240; + color = this._hsv2rgb(hue, 1, 1); + borderColor = this._hsv2rgb(hue, 1, 0.8); + } - case 'update': - // determine the event from the views viewpoint: an updated - // item can be added, updated, or removed from this view. - for (i = 0, len = ids.length; i < len; i++) { - id = ids[i]; - item = this.get(id); + // calculate size for the bar + if (this.style === Graph3d.STYLE.BARSIZE) { + xWidth = (this.xBarWidth / 2) * ((point.point.value - this.valueMin) / (this.valueMax - this.valueMin) * 0.8 + 0.2); + yWidth = (this.yBarWidth / 2) * ((point.point.value - this.valueMin) / (this.valueMax - this.valueMin) * 0.8 + 0.2); + } - if (item) { - if (this._ids[id]) { - updated.push(id); - } - else { - this._ids[id] = true; - added.push(id); - } - } - else { - if (this._ids[id]) { - delete this._ids[id]; - removed.push(id); - } - else { - // nothing interesting for me :-( - } - } - } + // calculate all corner points + var me = this; + var point3d = point.point; + var top = [ + {point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, point3d.z)}, + {point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, point3d.z)}, + {point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, point3d.z)}, + {point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, point3d.z)} + ]; + var bottom = [ + {point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, this.zMin)}, + {point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, this.zMin)}, + {point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, this.zMin)}, + {point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, this.zMin)} + ]; + + // calculate screen location of the points + top.forEach(function (obj) { + obj.screen = me._convert3Dto2D(obj.point); + }); + bottom.forEach(function (obj) { + obj.screen = me._convert3Dto2D(obj.point); + }); + + // create five sides, calculate both corner points and center points + var surfaces = [ + {corners: top, center: Point3d.avg(bottom[0].point, bottom[2].point)}, + {corners: [top[0], top[1], bottom[1], bottom[0]], center: Point3d.avg(bottom[1].point, bottom[0].point)}, + {corners: [top[1], top[2], bottom[2], bottom[1]], center: Point3d.avg(bottom[2].point, bottom[1].point)}, + {corners: [top[2], top[3], bottom[3], bottom[2]], center: Point3d.avg(bottom[3].point, bottom[2].point)}, + {corners: [top[3], top[0], bottom[0], bottom[3]], center: Point3d.avg(bottom[0].point, bottom[3].point)} + ]; + point.surfaces = surfaces; + + // calculate the distance of each of the surface centers to the camera + for (j = 0; j < surfaces.length; j++) { + surface = surfaces[j]; + var transCenter = this._convertPointToTranslation(surface.center); + surface.dist = this.showPerspective ? transCenter.length() : -transCenter.z; + // TODO: this dept calculation doesn't work 100% of the cases due to perspective, + // but the current solution is fast/simple and works in 99.9% of all cases + // the issue is visible in example 14, with graph.setCameraPosition({horizontal: 2.97, vertical: 0.5, distance: 0.9}) + } - break; + // order the surfaces by their (translated) depth + surfaces.sort(function (a, b) { + var diff = b.dist - a.dist; + if (diff) return diff; - case 'remove': - // filter the ids of the removed items - for (i = 0, len = ids.length; i < len; i++) { - id = ids[i]; - if (this._ids[id]) { - delete this._ids[id]; - removed.push(id); - } - } + // if equal depth, sort the top surface last + if (a.corners === top) return 1; + if (b.corners === top) return -1; - break; - } + // both are equal + return 0; + }); - if (added.length) { - this._trigger('add', {items: added}, senderId); - } - if (updated.length) { - this._trigger('update', {items: updated}, senderId); - } - if (removed.length) { - this._trigger('remove', {items: removed}, senderId); + // draw the ordered surfaces + ctx.lineWidth = 1; + ctx.strokeStyle = borderColor; + ctx.fillStyle = color; + // NOTE: we start at j=2 instead of j=0 as we don't need to draw the two surfaces at the backside + for (j = 2; j < surfaces.length; j++) { + surface = surfaces[j]; + corners = surface.corners; + ctx.beginPath(); + ctx.moveTo(corners[3].screen.x, corners[3].screen.y); + ctx.lineTo(corners[0].screen.x, corners[0].screen.y); + ctx.lineTo(corners[1].screen.x, corners[1].screen.y); + ctx.lineTo(corners[2].screen.x, corners[2].screen.y); + ctx.lineTo(corners[3].screen.x, corners[3].screen.y); + ctx.fill(); + ctx.stroke(); } } }; - // copy subscription functionality from DataSet - DataView.prototype.on = DataSet.prototype.on; - DataView.prototype.off = DataSet.prototype.off; - DataView.prototype._trigger = DataSet.prototype._trigger; - // TODO: make these functions deprecated (replaced with `on` and `off` since version 0.5) - DataView.prototype.subscribe = DataView.prototype.on; - DataView.prototype.unsubscribe = DataView.prototype.off; + /** + * Draw a line through all datapoints. + * This function can be used when the style is 'line' + */ + Graph3d.prototype._redrawDataLine = function() { + var canvas = this.frame.canvas, + ctx = canvas.getContext('2d'), + point, i; - module.exports = DataView; + if (this.dataPoints === undefined || this.dataPoints.length <= 0) + return; // TODO: throw exception? -/***/ }, -/* 9 */ -/***/ function(module, exports, __webpack_require__) { + // calculate the translations of all points + for (i = 0; i < this.dataPoints.length; i++) { + var trans = this._convertPointToTranslation(this.dataPoints[i].point); + var screen = this._convertTranslationToScreen(trans); - var Emitter = __webpack_require__(10); - var DataSet = __webpack_require__(7); - var DataView = __webpack_require__(8); - var util = __webpack_require__(1); - var Point3d = __webpack_require__(11); - var Point2d = __webpack_require__(12); - var Camera = __webpack_require__(13); - var Filter = __webpack_require__(14); - var Slider = __webpack_require__(15); - var StepNumber = __webpack_require__(16); + this.dataPoints[i].trans = trans; + this.dataPoints[i].screen = screen; + } - /** - * @constructor Graph3d - * Graph3d displays data in 3d. - * - * Graph3d is developed in javascript as a Google Visualization Chart. - * - * @param {Element} container The DOM element in which the Graph3d will - * be created. Normally a div element. - * @param {DataSet | DataView | Array} [data] - * @param {Object} [options] - */ - function Graph3d(container, data, options) { - if (!(this instanceof Graph3d)) { - throw new SyntaxError('Constructor must be called with the new operator'); + // start the line + if (this.dataPoints.length > 0) { + point = this.dataPoints[0]; + + ctx.lineWidth = 1; // TODO: make customizable + ctx.strokeStyle = 'blue'; // TODO: make customizable + ctx.beginPath(); + ctx.moveTo(point.screen.x, point.screen.y); } - // create variables and set default values - this.containerElement = container; - this.width = '400px'; - this.height = '400px'; - this.margin = 10; // px - this.defaultXCenter = '55%'; - this.defaultYCenter = '50%'; + // draw the datapoints as colored circles + for (i = 1; i < this.dataPoints.length; i++) { + point = this.dataPoints[i]; + ctx.lineTo(point.screen.x, point.screen.y); + } - this.xLabel = 'x'; - this.yLabel = 'y'; - this.zLabel = 'z'; + // finish the line + if (this.dataPoints.length > 0) { + ctx.stroke(); + } + }; - var passValueFn = function(v) { return v; }; - this.xValueLabel = passValueFn; - this.yValueLabel = passValueFn; - this.zValueLabel = passValueFn; - - this.filterLabel = 'time'; - this.legendLabel = 'value'; + /** + * Start a moving operation inside the provided parent element + * @param {Event} event The event that occurred (required for + * retrieving the mouse position) + */ + Graph3d.prototype._onMouseDown = function(event) { + event = event || window.event; - this.style = Graph3d.STYLE.DOT; - this.showPerspective = true; - this.showGrid = true; - this.keepAspectRatio = true; - this.showShadow = false; - this.showGrayBottom = false; // TODO: this does not work correctly - this.showTooltip = false; - this.verticalRatio = 0.5; // 0.1 to 1.0, where 1.0 results in a 'cube' + // check if mouse is still down (may be up when focus is lost for example + // in an iframe) + if (this.leftButtonDown) { + this._onMouseUp(event); + } - this.animationInterval = 1000; // milliseconds - this.animationPreload = false; + // only react on left mouse button down + this.leftButtonDown = event.which ? (event.which === 1) : (event.button === 1); + if (!this.leftButtonDown && !this.touchDown) return; - this.camera = new Camera(); - this.eye = new Point3d(0, 0, -1); // TODO: set eye.z about 3/4 of the width of the window? + // get mouse position (different code for IE and all other browsers) + this.startMouseX = getMouseX(event); + this.startMouseY = getMouseY(event); - this.dataTable = null; // The original data table - this.dataPoints = null; // The table with point objects + this.startStart = new Date(this.start); + this.startEnd = new Date(this.end); + this.startArmRotation = this.camera.getArmRotation(); - // the column indexes - this.colX = undefined; - this.colY = undefined; - this.colZ = undefined; - this.colValue = undefined; - this.colFilter = undefined; + this.frame.style.cursor = 'move'; - this.xMin = 0; - this.xStep = undefined; // auto by default - this.xMax = 1; - this.yMin = 0; - this.yStep = undefined; // auto by default - this.yMax = 1; - this.zMin = 0; - this.zStep = undefined; // auto by default - this.zMax = 1; - this.valueMin = 0; - this.valueMax = 1; - this.xBarWidth = 1; - this.yBarWidth = 1; - // TODO: customize axis range + // add event listeners to handle moving the contents + // we store the function onmousemove and onmouseup in the graph, so we can + // remove the eventlisteners lateron in the function mouseUp() + var me = this; + this.onmousemove = function (event) {me._onMouseMove(event);}; + this.onmouseup = function (event) {me._onMouseUp(event);}; + util.addEventListener(document, 'mousemove', me.onmousemove); + util.addEventListener(document, 'mouseup', me.onmouseup); + util.preventDefault(event); + }; - // constants - this.colorAxis = '#4D4D4D'; - this.colorGrid = '#D3D3D3'; - this.colorDot = '#7DC1FF'; - this.colorDotBorder = '#3267D2'; - // create a frame and canvas - this.create(); + /** + * Perform moving operating. + * This function activated from within the funcion Graph.mouseDown(). + * @param {Event} event Well, eehh, the event + */ + Graph3d.prototype._onMouseMove = function (event) { + event = event || window.event; - // apply options (also when undefined) - this.setOptions(options); + // calculate change in mouse position + var diffX = parseFloat(getMouseX(event)) - this.startMouseX; + var diffY = parseFloat(getMouseY(event)) - this.startMouseY; - // apply data - if (data) { - this.setData(data); - } - } + var horizontalNew = this.startArmRotation.horizontal + diffX / 200; + var verticalNew = this.startArmRotation.vertical + diffY / 200; - // Extend Graph3d with an Emitter mixin - Emitter(Graph3d.prototype); + var snapAngle = 4; // degrees + var snapValue = Math.sin(snapAngle / 360 * 2 * Math.PI); - /** - * Calculate the scaling values, dependent on the range in x, y, and z direction - */ - Graph3d.prototype._setScale = function() { - this.scale = new Point3d(1 / (this.xMax - this.xMin), - 1 / (this.yMax - this.yMin), - 1 / (this.zMax - this.zMin)); + // snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc... + // the -0.001 is to take care that the vertical axis is always drawn at the left front corner + if (Math.abs(Math.sin(horizontalNew)) < snapValue) { + horizontalNew = Math.round((horizontalNew / Math.PI)) * Math.PI - 0.001; + } + if (Math.abs(Math.cos(horizontalNew)) < snapValue) { + horizontalNew = (Math.round((horizontalNew/ Math.PI - 0.5)) + 0.5) * Math.PI - 0.001; + } - // keep aspect ration between x and y scale if desired - if (this.keepAspectRatio) { - if (this.scale.x < this.scale.y) { - //noinspection JSSuspiciousNameCombination - this.scale.y = this.scale.x; - } - else { - //noinspection JSSuspiciousNameCombination - this.scale.x = this.scale.y; - } + // snap vertically to nice angles + if (Math.abs(Math.sin(verticalNew)) < snapValue) { + verticalNew = Math.round((verticalNew / Math.PI)) * Math.PI; + } + if (Math.abs(Math.cos(verticalNew)) < snapValue) { + verticalNew = (Math.round((verticalNew/ Math.PI - 0.5)) + 0.5) * Math.PI; } - // scale the vertical axis - this.scale.z *= this.verticalRatio; - // TODO: can this be automated? verticalRatio? + this.camera.setArmRotation(horizontalNew, verticalNew); + this.redraw(); - // determine scale for (optional) value - this.scale.value = 1 / (this.valueMax - this.valueMin); + // fire a cameraPositionChange event + var parameters = this.getCameraPosition(); + this.emit('cameraPositionChange', parameters); - // position the camera arm - var xCenter = (this.xMax + this.xMin) / 2 * this.scale.x; - var yCenter = (this.yMax + this.yMin) / 2 * this.scale.y; - var zCenter = (this.zMax + this.zMin) / 2 * this.scale.z; - this.camera.setArmLocation(xCenter, yCenter, zCenter); + util.preventDefault(event); }; /** - * Convert a 3D location to a 2D location on screen - * http://en.wikipedia.org/wiki/3D_projection - * @param {Point3d} point3d A 3D point with parameters x, y, z - * @return {Point2d} point2d A 2D point with parameters x, y + * Stop moving operating. + * This function activated from within the funcion Graph.mouseDown(). + * @param {event} event The event */ - Graph3d.prototype._convert3Dto2D = function(point3d) { - var translation = this._convertPointToTranslation(point3d); - return this._convertTranslationToScreen(translation); + Graph3d.prototype._onMouseUp = function (event) { + this.frame.style.cursor = 'auto'; + this.leftButtonDown = false; + + // remove event listeners here + util.removeEventListener(document, 'mousemove', this.onmousemove); + util.removeEventListener(document, 'mouseup', this.onmouseup); + util.preventDefault(event); }; /** - * Convert a 3D location its translation seen from the camera - * http://en.wikipedia.org/wiki/3D_projection - * @param {Point3d} point3d A 3D point with parameters x, y, z - * @return {Point3d} translation A 3D point with parameters x, y, z This is - * the translation of the point, seen from the - * camera + * After having moved the mouse, a tooltip should pop up when the mouse is resting on a data point + * @param {Event} event A mouse move event */ - Graph3d.prototype._convertPointToTranslation = function(point3d) { - var ax = point3d.x * this.scale.x, - ay = point3d.y * this.scale.y, - az = point3d.z * this.scale.z, + Graph3d.prototype._onTooltip = function (event) { + var delay = 300; // ms + var mouseX = getMouseX(event) - util.getAbsoluteLeft(this.frame); + var mouseY = getMouseY(event) - util.getAbsoluteTop(this.frame); - cx = this.camera.getCameraLocation().x, - cy = this.camera.getCameraLocation().y, - cz = this.camera.getCameraLocation().z, + if (!this.showTooltip) { + return; + } - // calculate angles - sinTx = Math.sin(this.camera.getCameraRotation().x), - cosTx = Math.cos(this.camera.getCameraRotation().x), - sinTy = Math.sin(this.camera.getCameraRotation().y), - cosTy = Math.cos(this.camera.getCameraRotation().y), - sinTz = Math.sin(this.camera.getCameraRotation().z), - cosTz = Math.cos(this.camera.getCameraRotation().z), + if (this.tooltipTimeout) { + clearTimeout(this.tooltipTimeout); + } - // calculate translation - dx = cosTy * (sinTz * (ay - cy) + cosTz * (ax - cx)) - sinTy * (az - cz), - dy = sinTx * (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) + cosTx * (cosTz * (ay - cy) - sinTz * (ax-cx)), - dz = cosTx * (cosTy * (az - cz) + sinTy * (sinTz * (ay - cy) + cosTz * (ax - cx))) - sinTx * (cosTz * (ay - cy) - sinTz * (ax-cx)); + // (delayed) display of a tooltip only if no mouse button is down + if (this.leftButtonDown) { + this._hideTooltip(); + return; + } - return new Point3d(dx, dy, dz); + if (this.tooltip && this.tooltip.dataPoint) { + // tooltip is currently visible + var dataPoint = this._dataPointFromXY(mouseX, mouseY); + if (dataPoint !== this.tooltip.dataPoint) { + // datapoint changed + if (dataPoint) { + this._showTooltip(dataPoint); + } + else { + this._hideTooltip(); + } + } + } + else { + // tooltip is currently not visible + var me = this; + this.tooltipTimeout = setTimeout(function () { + me.tooltipTimeout = null; + + // show a tooltip if we have a data point + var dataPoint = me._dataPointFromXY(mouseX, mouseY); + if (dataPoint) { + me._showTooltip(dataPoint); + } + }, delay); + } }; /** - * Convert a translation point to a point on the screen - * @param {Point3d} translation A 3D point with parameters x, y, z This is - * the translation of the point, seen from the - * camera - * @return {Point2d} point2d A 2D point with parameters x, y + * Event handler for touchstart event on mobile devices */ - Graph3d.prototype._convertTranslationToScreen = function(translation) { - var ex = this.eye.x, - ey = this.eye.y, - ez = this.eye.z, - dx = translation.x, - dy = translation.y, - dz = translation.z; + Graph3d.prototype._onTouchStart = function(event) { + this.touchDown = true; - // calculate position on screen from translation - var bx; - var by; - if (this.showPerspective) { - bx = (dx - ex) * (ez / dz); - by = (dy - ey) * (ez / dz); - } - else { - bx = dx * -(ez / this.camera.getArmLength()); - by = dy * -(ez / this.camera.getArmLength()); - } + var me = this; + this.ontouchmove = function (event) {me._onTouchMove(event);}; + this.ontouchend = function (event) {me._onTouchEnd(event);}; + util.addEventListener(document, 'touchmove', me.ontouchmove); + util.addEventListener(document, 'touchend', me.ontouchend); - // shift and scale the point to the center of the screen - // use the width of the graph to scale both horizontally and vertically. - return new Point2d( - this.xcenter + bx * this.frame.canvas.clientWidth, - this.ycenter - by * this.frame.canvas.clientWidth); + this._onMouseDown(event); }; /** - * Set the background styling for the graph - * @param {string | {fill: string, stroke: string, strokeWidth: string}} backgroundColor + * Event handler for touchmove event on mobile devices */ - Graph3d.prototype._setBackgroundColor = function(backgroundColor) { - var fill = 'white'; - var stroke = 'gray'; - var strokeWidth = 1; + Graph3d.prototype._onTouchMove = function(event) { + this._onMouseMove(event); + }; - if (typeof(backgroundColor) === 'string') { - fill = backgroundColor; - stroke = 'none'; - strokeWidth = 0; - } - else if (typeof(backgroundColor) === 'object') { - if (backgroundColor.fill !== undefined) fill = backgroundColor.fill; - if (backgroundColor.stroke !== undefined) stroke = backgroundColor.stroke; - if (backgroundColor.strokeWidth !== undefined) strokeWidth = backgroundColor.strokeWidth; - } - else if (backgroundColor === undefined) { - // use use defaults - } - else { - throw 'Unsupported type of backgroundColor'; - } + /** + * Event handler for touchend event on mobile devices + */ + Graph3d.prototype._onTouchEnd = function(event) { + this.touchDown = false; - this.frame.style.backgroundColor = fill; - this.frame.style.borderColor = stroke; - this.frame.style.borderWidth = strokeWidth + 'px'; - this.frame.style.borderStyle = 'solid'; + util.removeEventListener(document, 'touchmove', this.ontouchmove); + util.removeEventListener(document, 'touchend', this.ontouchend); + + this._onMouseUp(event); }; - /// enumerate the available styles - Graph3d.STYLE = { - BAR: 0, - BARCOLOR: 1, - BARSIZE: 2, - DOT : 3, - DOTLINE : 4, - DOTCOLOR: 5, - DOTSIZE: 6, - GRID : 7, - LINE: 8, - SURFACE : 9 + /** + * Event handler for mouse wheel event, used to zoom the graph + * Code from http://adomas.org/javascript-mouse-wheel/ + * @param {event} event The event + */ + Graph3d.prototype._onWheel = function(event) { + if (!event) /* For IE. */ + event = window.event; + + // retrieve delta + var delta = 0; + if (event.wheelDelta) { /* IE/Opera. */ + delta = event.wheelDelta/120; + } else if (event.detail) { /* Mozilla case. */ + // In Mozilla, sign of delta is different than in IE. + // Also, delta is multiple of 3. + delta = -event.detail/3; + } + + // If delta is nonzero, handle it. + // Basically, delta is now positive if wheel was scrolled up, + // and negative, if wheel was scrolled down. + if (delta) { + var oldLength = this.camera.getArmLength(); + var newLength = oldLength * (1 - delta / 10); + + this.camera.setArmLength(newLength); + this.redraw(); + + this._hideTooltip(); + } + + // fire a cameraPositionChange event + var parameters = this.getCameraPosition(); + this.emit('cameraPositionChange', parameters); + + // Prevent default actions caused by mouse wheel. + // That might be ugly, but we handle scrolls somehow + // anyway, so don't bother here.. + util.preventDefault(event); }; /** - * Retrieve the style index from given styleName - * @param {string} styleName Style name such as 'dot', 'grid', 'dot-line' - * @return {Number} styleNumber Enumeration value representing the style, or -1 - * when not found + * Test whether a point lies inside given 2D triangle + * @param {Point2d} point + * @param {Point2d[]} triangle + * @return {boolean} Returns true if given point lies inside or on the edge of the triangle + * @private */ - Graph3d.prototype._getStyleNumber = function(styleName) { - switch (styleName) { - case 'dot': return Graph3d.STYLE.DOT; - case 'dot-line': return Graph3d.STYLE.DOTLINE; - case 'dot-color': return Graph3d.STYLE.DOTCOLOR; - case 'dot-size': return Graph3d.STYLE.DOTSIZE; - case 'line': return Graph3d.STYLE.LINE; - case 'grid': return Graph3d.STYLE.GRID; - case 'surface': return Graph3d.STYLE.SURFACE; - case 'bar': return Graph3d.STYLE.BAR; - case 'bar-color': return Graph3d.STYLE.BARCOLOR; - case 'bar-size': return Graph3d.STYLE.BARSIZE; + Graph3d.prototype._insideTriangle = function (point, triangle) { + var a = triangle[0], + b = triangle[1], + c = triangle[2]; + + function sign (x) { + return x > 0 ? 1 : x < 0 ? -1 : 0; } - return -1; + var as = sign((b.x - a.x) * (point.y - a.y) - (b.y - a.y) * (point.x - a.x)); + var bs = sign((c.x - b.x) * (point.y - b.y) - (c.y - b.y) * (point.x - b.x)); + var cs = sign((a.x - c.x) * (point.y - c.y) - (a.y - c.y) * (point.x - c.x)); + + // each of the three signs must be either equal to each other or zero + return (as == 0 || bs == 0 || as == bs) && + (bs == 0 || cs == 0 || bs == cs) && + (as == 0 || cs == 0 || as == cs); }; /** - * Determine the indexes of the data columns, based on the given style and data - * @param {DataSet} data - * @param {Number} style + * Find a data point close to given screen position (x, y) + * @param {Number} x + * @param {Number} y + * @return {Object | null} The closest data point or null if not close to any data point + * @private */ - Graph3d.prototype._determineColumnIndexes = function(data, style) { - if (this.style === Graph3d.STYLE.DOT || - this.style === Graph3d.STYLE.DOTLINE || - this.style === Graph3d.STYLE.LINE || - this.style === Graph3d.STYLE.GRID || - this.style === Graph3d.STYLE.SURFACE || - this.style === Graph3d.STYLE.BAR) { - // 3 columns expected, and optionally a 4th with filter values - this.colX = 0; - this.colY = 1; - this.colZ = 2; - this.colValue = undefined; + Graph3d.prototype._dataPointFromXY = function (x, y) { + var i, + distMax = 100, // px + dataPoint = null, + closestDataPoint = null, + closestDist = null, + center = new Point2d(x, y); - if (data.getNumberOfColumns() > 3) { - this.colFilter = 3; - } - } - else if (this.style === Graph3d.STYLE.DOTCOLOR || - this.style === Graph3d.STYLE.DOTSIZE || + if (this.style === Graph3d.STYLE.BAR || this.style === Graph3d.STYLE.BARCOLOR || this.style === Graph3d.STYLE.BARSIZE) { - // 4 columns expected, and optionally a 5th with filter values - this.colX = 0; - this.colY = 1; - this.colZ = 2; - this.colValue = 3; - - if (data.getNumberOfColumns() > 4) { - this.colFilter = 4; + // the data points are ordered from far away to closest + for (i = this.dataPoints.length - 1; i >= 0; i--) { + dataPoint = this.dataPoints[i]; + var surfaces = dataPoint.surfaces; + if (surfaces) { + for (var s = surfaces.length - 1; s >= 0; s--) { + // split each surface in two triangles, and see if the center point is inside one of these + var surface = surfaces[s]; + var corners = surface.corners; + var triangle1 = [corners[0].screen, corners[1].screen, corners[2].screen]; + var triangle2 = [corners[2].screen, corners[3].screen, corners[0].screen]; + if (this._insideTriangle(center, triangle1) || + this._insideTriangle(center, triangle2)) { + // return immediately at the first hit + return dataPoint; + } + } + } } } else { - throw 'Unknown style "' + this.style + '"'; - } - }; - - Graph3d.prototype.getNumberOfRows = function(data) { - return data.length; - } - - - Graph3d.prototype.getNumberOfColumns = function(data) { - var counter = 0; - for (var column in data[0]) { - if (data[0].hasOwnProperty(column)) { - counter++; - } - } - return counter; - } - + // find the closest data point, using distance to the center of the point on 2d screen + for (i = 0; i < this.dataPoints.length; i++) { + dataPoint = this.dataPoints[i]; + var point = dataPoint.screen; + if (point) { + var distX = Math.abs(x - point.x); + var distY = Math.abs(y - point.y); + var dist = Math.sqrt(distX * distX + distY * distY); - Graph3d.prototype.getDistinctValues = function(data, column) { - var distinctValues = []; - for (var i = 0; i < data.length; i++) { - if (distinctValues.indexOf(data[i][column]) == -1) { - distinctValues.push(data[i][column]); + if ((closestDist === null || dist < closestDist) && dist < distMax) { + closestDist = dist; + closestDataPoint = dataPoint; + } + } } } - return distinctValues; - } - Graph3d.prototype.getColumnRange = function(data,column) { - var minMax = {min:data[0][column],max:data[0][column]}; - for (var i = 0; i < data.length; i++) { - if (minMax.min > data[i][column]) { minMax.min = data[i][column]; } - if (minMax.max < data[i][column]) { minMax.max = data[i][column]; } - } - return minMax; + return closestDataPoint; }; /** - * Initialize the data from the data table. Calculate minimum and maximum values - * and column index values - * @param {Array | DataSet | DataView} rawData The data containing the items for the Graph. - * @param {Number} style Style Number + * Display a tooltip for given data point + * @param {Object} dataPoint + * @private */ - Graph3d.prototype._dataInitialize = function (rawData, style) { - var me = this; + Graph3d.prototype._showTooltip = function (dataPoint) { + var content, line, dot; - // unsubscribe from the dataTable - if (this.dataSet) { - this.dataSet.off('*', this._onChange); - } + if (!this.tooltip) { + content = document.createElement('div'); + content.style.position = 'absolute'; + content.style.padding = '10px'; + content.style.border = '1px solid #4d4d4d'; + content.style.color = '#1a1a1a'; + content.style.background = 'rgba(255,255,255,0.7)'; + content.style.borderRadius = '2px'; + content.style.boxShadow = '5px 5px 10px rgba(128,128,128,0.5)'; - if (rawData === undefined) - return; + line = document.createElement('div'); + line.style.position = 'absolute'; + line.style.height = '40px'; + line.style.width = '0'; + line.style.borderLeft = '1px solid #4d4d4d'; - if (Array.isArray(rawData)) { - rawData = new DataSet(rawData); - } + dot = document.createElement('div'); + dot.style.position = 'absolute'; + dot.style.height = '0'; + dot.style.width = '0'; + dot.style.border = '5px solid #4d4d4d'; + dot.style.borderRadius = '5px'; - var data; - if (rawData instanceof DataSet || rawData instanceof DataView) { - data = rawData.get(); + this.tooltip = { + dataPoint: null, + dom: { + content: content, + line: line, + dot: dot + } + }; } else { - throw new Error('Array, DataSet, or DataView expected'); + content = this.tooltip.dom.content; + line = this.tooltip.dom.line; + dot = this.tooltip.dom.dot; } - if (data.length == 0) - return; + this._hideTooltip(); - this.dataSet = rawData; - this.dataTable = data; + this.tooltip.dataPoint = dataPoint; + if (typeof this.showTooltip === 'function') { + content.innerHTML = this.showTooltip(dataPoint.point); + } + else { + content.innerHTML = '' + + '' + + '' + + '' + + '
x:' + dataPoint.point.x + '
y:' + dataPoint.point.y + '
z:' + dataPoint.point.z + '
'; + } - // subscribe to changes in the dataset - this._onChange = function () { - me.setData(me.dataSet); - }; - this.dataSet.on('*', this._onChange); + content.style.left = '0'; + content.style.top = '0'; + this.frame.appendChild(content); + this.frame.appendChild(line); + this.frame.appendChild(dot); - // _determineColumnIndexes - // getNumberOfRows (points) - // getNumberOfColumns (x,y,z,v,t,t1,t2...) - // getDistinctValues (unique values?) - // getColumnRange + // calculate sizes + var contentWidth = content.offsetWidth; + var contentHeight = content.offsetHeight; + var lineHeight = line.offsetHeight; + var dotWidth = dot.offsetWidth; + var dotHeight = dot.offsetHeight; - // determine the location of x,y,z,value,filter columns - this.colX = 'x'; - this.colY = 'y'; - this.colZ = 'z'; - this.colValue = 'style'; - this.colFilter = 'filter'; + var left = dataPoint.screen.x - contentWidth / 2; + left = Math.min(Math.max(left, 10), this.frame.clientWidth - 10 - contentWidth); + line.style.left = dataPoint.screen.x + 'px'; + line.style.top = (dataPoint.screen.y - lineHeight) + 'px'; + content.style.left = left + 'px'; + content.style.top = (dataPoint.screen.y - lineHeight - contentHeight) + 'px'; + dot.style.left = (dataPoint.screen.x - dotWidth / 2) + 'px'; + dot.style.top = (dataPoint.screen.y - dotHeight / 2) + 'px'; + }; + /** + * Hide the tooltip when displayed + * @private + */ + Graph3d.prototype._hideTooltip = function () { + if (this.tooltip) { + this.tooltip.dataPoint = null; - // check if a filter column is provided - if (data[0].hasOwnProperty('filter')) { - if (this.dataFilter === undefined) { - this.dataFilter = new Filter(rawData, this.colFilter, this); - this.dataFilter.setOnLoadCallback(function() {me.redraw();}); + for (var prop in this.tooltip.dom) { + if (this.tooltip.dom.hasOwnProperty(prop)) { + var elem = this.tooltip.dom[prop]; + if (elem && elem.parentNode) { + elem.parentNode.removeChild(elem); + } + } } } + }; + /**--------------------------------------------------------------------------**/ - var withBars = this.style == Graph3d.STYLE.BAR || - this.style == Graph3d.STYLE.BARCOLOR || - this.style == Graph3d.STYLE.BARSIZE; - // determine barWidth from data - if (withBars) { - if (this.defaultXBarWidth !== undefined) { - this.xBarWidth = this.defaultXBarWidth; - } - else { - var dataX = this.getDistinctValues(data,this.colX); - this.xBarWidth = (dataX[1] - dataX[0]) || 1; - } + /** + * Get the horizontal mouse position from a mouse event + * @param {Event} event + * @return {Number} mouse x + */ + getMouseX = function(event) { + if ('clientX' in event) return event.clientX; + return event.targetTouches[0] && event.targetTouches[0].clientX || 0; + }; - if (this.defaultYBarWidth !== undefined) { - this.yBarWidth = this.defaultYBarWidth; - } - else { - var dataY = this.getDistinctValues(data,this.colY); - this.yBarWidth = (dataY[1] - dataY[0]) || 1; - } - } + /** + * Get the vertical mouse position from a mouse event + * @param {Event} event + * @return {Number} mouse y + */ + getMouseY = function(event) { + if ('clientY' in event) return event.clientY; + return event.targetTouches[0] && event.targetTouches[0].clientY || 0; + }; - // calculate minimums and maximums - var xRange = this.getColumnRange(data,this.colX); - if (withBars) { - xRange.min -= this.xBarWidth / 2; - xRange.max += this.xBarWidth / 2; - } - this.xMin = (this.defaultXMin !== undefined) ? this.defaultXMin : xRange.min; - this.xMax = (this.defaultXMax !== undefined) ? this.defaultXMax : xRange.max; - if (this.xMax <= this.xMin) this.xMax = this.xMin + 1; - this.xStep = (this.defaultXStep !== undefined) ? this.defaultXStep : (this.xMax-this.xMin)/5; + module.exports = Graph3d; - var yRange = this.getColumnRange(data,this.colY); - if (withBars) { - yRange.min -= this.yBarWidth / 2; - yRange.max += this.yBarWidth / 2; - } - this.yMin = (this.defaultYMin !== undefined) ? this.defaultYMin : yRange.min; - this.yMax = (this.defaultYMax !== undefined) ? this.defaultYMax : yRange.max; - if (this.yMax <= this.yMin) this.yMax = this.yMin + 1; - this.yStep = (this.defaultYStep !== undefined) ? this.defaultYStep : (this.yMax-this.yMin)/5; - var zRange = this.getColumnRange(data,this.colZ); - this.zMin = (this.defaultZMin !== undefined) ? this.defaultZMin : zRange.min; - this.zMax = (this.defaultZMax !== undefined) ? this.defaultZMax : zRange.max; - if (this.zMax <= this.zMin) this.zMax = this.zMin + 1; - this.zStep = (this.defaultZStep !== undefined) ? this.defaultZStep : (this.zMax-this.zMin)/5; +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { - if (this.colValue !== undefined) { - var valueRange = this.getColumnRange(data,this.colValue); - this.valueMin = (this.defaultValueMin !== undefined) ? this.defaultValueMin : valueRange.min; - this.valueMax = (this.defaultValueMax !== undefined) ? this.defaultValueMax : valueRange.max; - if (this.valueMax <= this.valueMin) this.valueMax = this.valueMin + 1; - } + var Point3d = __webpack_require__(9); - // set the scale dependent on the ranges. - this._setScale(); - }; + /** + * @class Camera + * The camera is mounted on a (virtual) camera arm. The camera arm can rotate + * The camera is always looking in the direction of the origin of the arm. + * This way, the camera always rotates around one fixed point, the location + * of the camera arm. + * + * Documentation: + * http://en.wikipedia.org/wiki/3D_projection + */ + Camera = function () { + this.armLocation = new Point3d(); + this.armRotation = {}; + this.armRotation.horizontal = 0; + this.armRotation.vertical = 0; + this.armLength = 1.7; + this.cameraLocation = new Point3d(); + this.cameraRotation = new Point3d(0.5*Math.PI, 0, 0); + this.calculateCameraOrientation(); + }; /** - * Filter the data based on the current filter - * @param {Array} data - * @return {Array} dataPoints Array with point objects which can be drawn on screen + * Set the location (origin) of the arm + * @param {Number} x Normalized value of x + * @param {Number} y Normalized value of y + * @param {Number} z Normalized value of z */ - Graph3d.prototype._getDataPoints = function (data) { - // TODO: store the created matrix dataPoints in the filters instead of reloading each time - var x, y, i, z, obj, point; + Camera.prototype.setArmLocation = function(x, y, z) { + this.armLocation.x = x; + this.armLocation.y = y; + this.armLocation.z = z; - var dataPoints = []; + this.calculateCameraOrientation(); + }; - if (this.style === Graph3d.STYLE.GRID || - this.style === Graph3d.STYLE.SURFACE) { - // copy all values from the google data table to a matrix - // the provided values are supposed to form a grid of (x,y) positions + /** + * Set the rotation of the camera arm + * @param {Number} horizontal The horizontal rotation, between 0 and 2*PI. + * Optional, can be left undefined. + * @param {Number} vertical The vertical rotation, between 0 and 0.5*PI + * if vertical=0.5*PI, the graph is shown from the + * top. Optional, can be left undefined. + */ + Camera.prototype.setArmRotation = function(horizontal, vertical) { + if (horizontal !== undefined) { + this.armRotation.horizontal = horizontal; + } - // create two lists with all present x and y values - var dataX = []; - var dataY = []; - for (i = 0; i < this.getNumberOfRows(data); i++) { - x = data[i][this.colX] || 0; - y = data[i][this.colY] || 0; + if (vertical !== undefined) { + this.armRotation.vertical = vertical; + if (this.armRotation.vertical < 0) this.armRotation.vertical = 0; + if (this.armRotation.vertical > 0.5*Math.PI) this.armRotation.vertical = 0.5*Math.PI; + } - if (dataX.indexOf(x) === -1) { - dataX.push(x); - } - if (dataY.indexOf(y) === -1) { - dataY.push(y); - } - } + if (horizontal !== undefined || vertical !== undefined) { + this.calculateCameraOrientation(); + } + }; - function sortNumber(a, b) { - return a - b; - } - dataX.sort(sortNumber); - dataY.sort(sortNumber); + /** + * Retrieve the current arm rotation + * @return {object} An object with parameters horizontal and vertical + */ + Camera.prototype.getArmRotation = function() { + var rot = {}; + rot.horizontal = this.armRotation.horizontal; + rot.vertical = this.armRotation.vertical; - // create a grid, a 2d matrix, with all values. - var dataMatrix = []; // temporary data matrix - for (i = 0; i < data.length; i++) { - x = data[i][this.colX] || 0; - y = data[i][this.colY] || 0; - z = data[i][this.colZ] || 0; + return rot; + }; - var xIndex = dataX.indexOf(x); // TODO: implement Array().indexOf() for Internet Explorer - var yIndex = dataY.indexOf(y); + /** + * Set the (normalized) length of the camera arm. + * @param {Number} length A length between 0.71 and 5.0 + */ + Camera.prototype.setArmLength = function(length) { + if (length === undefined) + return; - if (dataMatrix[xIndex] === undefined) { - dataMatrix[xIndex] = []; - } + this.armLength = length; - var point3d = new Point3d(); - point3d.x = x; - point3d.y = y; - point3d.z = z; + // Radius must be larger than the corner of the graph, + // which has a distance of sqrt(0.5^2+0.5^2) = 0.71 from the center of the + // graph + if (this.armLength < 0.71) this.armLength = 0.71; + if (this.armLength > 5.0) this.armLength = 5.0; - obj = {}; - obj.point = point3d; - obj.trans = undefined; - obj.screen = undefined; - obj.bottom = new Point3d(x, y, this.zMin); + this.calculateCameraOrientation(); + }; - dataMatrix[xIndex][yIndex] = obj; + /** + * Retrieve the arm length + * @return {Number} length + */ + Camera.prototype.getArmLength = function() { + return this.armLength; + }; - dataPoints.push(obj); - } + /** + * Retrieve the camera location + * @return {Point3d} cameraLocation + */ + Camera.prototype.getCameraLocation = function() { + return this.cameraLocation; + }; - // fill in the pointers to the neighbors. - for (x = 0; x < dataMatrix.length; x++) { - for (y = 0; y < dataMatrix[x].length; y++) { - if (dataMatrix[x][y]) { - dataMatrix[x][y].pointRight = (x < dataMatrix.length-1) ? dataMatrix[x+1][y] : undefined; - dataMatrix[x][y].pointTop = (y < dataMatrix[x].length-1) ? dataMatrix[x][y+1] : undefined; - dataMatrix[x][y].pointCross = - (x < dataMatrix.length-1 && y < dataMatrix[x].length-1) ? - dataMatrix[x+1][y+1] : - undefined; - } - } - } - } - else { // 'dot', 'dot-line', etc. - // copy all values from the google data table to a list with Point3d objects - for (i = 0; i < data.length; i++) { - point = new Point3d(); - point.x = data[i][this.colX] || 0; - point.y = data[i][this.colY] || 0; - point.z = data[i][this.colZ] || 0; + /** + * Retrieve the camera rotation + * @return {Point3d} cameraRotation + */ + Camera.prototype.getCameraRotation = function() { + return this.cameraRotation; + }; - if (this.colValue !== undefined) { - point.value = data[i][this.colValue] || 0; - } + /** + * Calculate the location and rotation of the camera based on the + * position and orientation of the camera arm + */ + Camera.prototype.calculateCameraOrientation = function() { + // calculate location of the camera + this.cameraLocation.x = this.armLocation.x - this.armLength * Math.sin(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical); + this.cameraLocation.y = this.armLocation.y - this.armLength * Math.cos(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical); + this.cameraLocation.z = this.armLocation.z + this.armLength * Math.sin(this.armRotation.vertical); - obj = {}; - obj.point = point; - obj.bottom = new Point3d(point.x, point.y, this.zMin); - obj.trans = undefined; - obj.screen = undefined; + // calculate rotation of the camera + this.cameraRotation.x = Math.PI/2 - this.armRotation.vertical; + this.cameraRotation.y = 0; + this.cameraRotation.z = -this.armRotation.horizontal; + }; + + module.exports = Camera; - dataPoints.push(obj); - } - } +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { - return dataPoints; - }; + var DataView = __webpack_require__(4); /** - * Create the main frame for the Graph3d. - * This function is executed once when a Graph3d object is created. The frame - * contains a canvas, and this canvas contains all objects like the axis and - * nodes. + * @class Filter + * + * @param {DataSet} data The google data table + * @param {Number} column The index of the column to be filtered + * @param {Graph} graph The graph */ - Graph3d.prototype.create = function () { - // remove all elements from the container element. - while (this.containerElement.hasChildNodes()) { - this.containerElement.removeChild(this.containerElement.firstChild); - } + function Filter (data, column, graph) { + this.data = data; + this.column = column; + this.graph = graph; // the parent graph - this.frame = document.createElement('div'); - this.frame.style.position = 'relative'; - this.frame.style.overflow = 'hidden'; + this.index = undefined; + this.value = undefined; - // create the graph canvas (HTML canvas element) - this.frame.canvas = document.createElement( 'canvas' ); - this.frame.canvas.style.position = 'relative'; - this.frame.appendChild(this.frame.canvas); - //if (!this.frame.canvas.getContext) { - { - var noCanvas = document.createElement( 'DIV' ); - noCanvas.style.color = 'red'; - noCanvas.style.fontWeight = 'bold' ; - noCanvas.style.padding = '10px'; - noCanvas.innerHTML = 'Error: your browser does not support HTML canvas'; - this.frame.canvas.appendChild(noCanvas); + // read all distinct values and select the first one + this.values = graph.getDistinctValues(data.get(), this.column); + + // sort both numeric and string values correctly + this.values.sort(function (a, b) { + return a > b ? 1 : a < b ? -1 : 0; + }); + + if (this.values.length > 0) { + this.selectValue(0); } - this.frame.filter = document.createElement( 'div' ); - this.frame.filter.style.position = 'absolute'; - this.frame.filter.style.bottom = '0px'; - this.frame.filter.style.left = '0px'; - this.frame.filter.style.width = '100%'; - this.frame.appendChild(this.frame.filter); + // create an array with the filtered datapoints. this will be loaded afterwards + this.dataPoints = []; - // add event listeners to handle moving and zooming the contents - var me = this; - var onmousedown = function (event) {me._onMouseDown(event);}; - var ontouchstart = function (event) {me._onTouchStart(event);}; - var onmousewheel = function (event) {me._onWheel(event);}; - var ontooltip = function (event) {me._onTooltip(event);}; - // TODO: these events are never cleaned up... can give a 'memory leakage' + this.loaded = false; + this.onLoadCallback = undefined; - util.addEventListener(this.frame.canvas, 'keydown', onkeydown); - util.addEventListener(this.frame.canvas, 'mousedown', onmousedown); - util.addEventListener(this.frame.canvas, 'touchstart', ontouchstart); - util.addEventListener(this.frame.canvas, 'mousewheel', onmousewheel); - util.addEventListener(this.frame.canvas, 'mousemove', ontooltip); + if (graph.animationPreload) { + this.loaded = false; + this.loadInBackground(); + } + else { + this.loaded = true; + } + }; - // add the new graph to the container element - this.containerElement.appendChild(this.frame); + + /** + * Return the label + * @return {string} label + */ + Filter.prototype.isLoaded = function() { + return this.loaded; }; /** - * Set a new size for the graph - * @param {string} width Width in pixels or percentage (for example '800px' - * or '50%') - * @param {string} height Height in pixels or percentage (for example '400px' - * or '30%') + * Return the loaded progress + * @return {Number} percentage between 0 and 100 */ - Graph3d.prototype.setSize = function(width, height) { - this.frame.style.width = width; - this.frame.style.height = height; + Filter.prototype.getLoadedProgress = function() { + var len = this.values.length; - this._resizeCanvas(); + var i = 0; + while (this.dataPoints[i]) { + i++; + } + + return Math.round(i / len * 100); }; + /** - * Resize the canvas to the current size of the frame + * Return the label + * @return {string} label */ - Graph3d.prototype._resizeCanvas = function() { - this.frame.canvas.style.width = '100%'; - this.frame.canvas.style.height = '100%'; + Filter.prototype.getLabel = function() { + return this.graph.filterLabel; + }; - this.frame.canvas.width = this.frame.canvas.clientWidth; - this.frame.canvas.height = this.frame.canvas.clientHeight; - // adjust with for margin - this.frame.filter.style.width = (this.frame.canvas.clientWidth - 2 * 10) + 'px'; + /** + * Return the columnIndex of the filter + * @return {Number} columnIndex + */ + Filter.prototype.getColumn = function() { + return this.column; }; /** - * Start animation + * Return the currently selected value. Returns undefined if there is no selection + * @return {*} value */ - Graph3d.prototype.animationStart = function() { - if (!this.frame.filter || !this.frame.filter.slider) - throw 'No animation available'; + Filter.prototype.getSelectedValue = function() { + if (this.index === undefined) + return undefined; - this.frame.filter.slider.play(); + return this.values[this.index]; }; + /** + * Retrieve all values of the filter + * @return {Array} values + */ + Filter.prototype.getValues = function() { + return this.values; + }; /** - * Stop animation + * Retrieve one value of the filter + * @param {Number} index + * @return {*} value */ - Graph3d.prototype.animationStop = function() { - if (!this.frame.filter || !this.frame.filter.slider) return; + Filter.prototype.getValue = function(index) { + if (index >= this.values.length) + throw 'Error: index out of range'; - this.frame.filter.slider.stop(); + return this.values[index]; }; /** - * Resize the center position based on the current values in this.defaultXCenter - * and this.defaultYCenter (which are strings with a percentage or a value - * in pixels). The center positions are the variables this.xCenter - * and this.yCenter + * Retrieve the (filtered) dataPoints for the currently selected filter index + * @param {Number} [index] (optional) + * @return {Array} dataPoints */ - Graph3d.prototype._resizeCenter = function() { - // calculate the horizontal center position - if (this.defaultXCenter.charAt(this.defaultXCenter.length-1) === '%') { - this.xcenter = - parseFloat(this.defaultXCenter) / 100 * - this.frame.canvas.clientWidth; - } - else { - this.xcenter = parseFloat(this.defaultXCenter); // supposed to be in px - } + Filter.prototype._getDataPoints = function(index) { + if (index === undefined) + index = this.index; - // calculate the vertical center position - if (this.defaultYCenter.charAt(this.defaultYCenter.length-1) === '%') { - this.ycenter = - parseFloat(this.defaultYCenter) / 100 * - (this.frame.canvas.clientHeight - this.frame.filter.clientHeight); + if (index === undefined) + return []; + + var dataPoints; + if (this.dataPoints[index]) { + dataPoints = this.dataPoints[index]; } else { - this.ycenter = parseFloat(this.defaultYCenter); // supposed to be in px + var f = {}; + f.column = this.column; + f.value = this.values[index]; + + var dataView = new DataView(this.data,{filter: function (item) {return (item[f.column] == f.value);}}).get(); + dataPoints = this.graph._getDataPoints(dataView); + + this.dataPoints[index] = dataPoints; } + + return dataPoints; }; + + /** - * Set the rotation and distance of the camera - * @param {Object} pos An object with the camera position. The object - * contains three parameters: - * - horizontal {Number} - * The horizontal rotation, between 0 and 2*PI. - * Optional, can be left undefined. - * - vertical {Number} - * The vertical rotation, between 0 and 0.5*PI - * if vertical=0.5*PI, the graph is shown from the - * top. Optional, can be left undefined. - * - distance {Number} - * The (normalized) distance of the camera to the - * center of the graph, a value between 0.71 and 5.0. - * Optional, can be left undefined. + * Set a callback function when the filter is fully loaded. */ - Graph3d.prototype.setCameraPosition = function(pos) { - if (pos === undefined) { - return; - } + Filter.prototype.setOnLoadCallback = function(callback) { + this.onLoadCallback = callback; + }; - if (pos.horizontal !== undefined && pos.vertical !== undefined) { - this.camera.setArmRotation(pos.horizontal, pos.vertical); - } - if (pos.distance !== undefined) { - this.camera.setArmLength(pos.distance); + /** + * Add a value to the list with available values for this filter + * No double entries will be created. + * @param {Number} index + */ + Filter.prototype.selectValue = function(index) { + if (index >= this.values.length) + throw 'Error: index out of range'; + + this.index = index; + this.value = this.values[index]; + }; + + /** + * Load all filtered rows in the background one by one + * Start this method without providing an index! + */ + Filter.prototype.loadInBackground = function(index) { + if (index === undefined) + index = 0; + + var frame = this.graph.frame; + + if (index < this.values.length) { + var dataPointsTemp = this._getDataPoints(index); + //this.graph.redrawInfo(); // TODO: not neat + + // create a progress box + if (frame.progress === undefined) { + frame.progress = document.createElement('DIV'); + frame.progress.style.position = 'absolute'; + frame.progress.style.color = 'gray'; + frame.appendChild(frame.progress); + } + var progress = this.getLoadedProgress(); + frame.progress.innerHTML = 'Loading animation... ' + progress + '%'; + // TODO: this is no nice solution... + frame.progress.style.bottom = 60 + 'px'; // TODO: use height of slider + frame.progress.style.left = 10 + 'px'; + + var me = this; + setTimeout(function() {me.loadInBackground(index+1);}, 10); + this.loaded = false; } + else { + this.loaded = true; - this.redraw(); + // remove the progress box + if (frame.progress !== undefined) { + frame.removeChild(frame.progress); + frame.progress = undefined; + } + + if (this.onLoadCallback) + this.onLoadCallback(); + } }; + module.exports = Filter; + + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { /** - * Retrieve the current camera rotation - * @return {object} An object with parameters horizontal, vertical, and - * distance + * @prototype Point2d + * @param {Number} [x] + * @param {Number} [y] */ - Graph3d.prototype.getCameraPosition = function() { - var pos = this.camera.getArmRotation(); - pos.distance = this.camera.getArmLength(); - return pos; + Point2d = function (x, y) { + this.x = x !== undefined ? x : 0; + this.y = y !== undefined ? y : 0; }; + module.exports = Point2d; + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + /** - * Load data into the 3D Graph + * @prototype Point3d + * @param {Number} [x] + * @param {Number} [y] + * @param {Number} [z] */ - Graph3d.prototype._readData = function(data) { - // read the data - this._dataInitialize(data, this.style); + function Point3d(x, y, z) { + this.x = x !== undefined ? x : 0; + this.y = y !== undefined ? y : 0; + this.z = z !== undefined ? z : 0; + }; + /** + * Subtract the two provided points, returns a-b + * @param {Point3d} a + * @param {Point3d} b + * @return {Point3d} a-b + */ + Point3d.subtract = function(a, b) { + var sub = new Point3d(); + sub.x = a.x - b.x; + sub.y = a.y - b.y; + sub.z = a.z - b.z; + return sub; + }; - if (this.dataFilter) { - // apply filtering - this.dataPoints = this.dataFilter._getDataPoints(); - } - else { - // no filtering. load all data - this.dataPoints = this._getDataPoints(this.dataTable); - } + /** + * Add the two provided points, returns a+b + * @param {Point3d} a + * @param {Point3d} b + * @return {Point3d} a+b + */ + Point3d.add = function(a, b) { + var sum = new Point3d(); + sum.x = a.x + b.x; + sum.y = a.y + b.y; + sum.z = a.z + b.z; + return sum; + }; - // draw the filter - this._redrawFilter(); + /** + * Calculate the average of two 3d points + * @param {Point3d} a + * @param {Point3d} b + * @return {Point3d} The average, (a+b)/2 + */ + Point3d.avg = function(a, b) { + return new Point3d( + (a.x + b.x) / 2, + (a.y + b.y) / 2, + (a.z + b.z) / 2 + ); }; /** - * Replace the dataset of the Graph3d - * @param {Array | DataSet | DataView} data + * Calculate the cross product of the two provided points, returns axb + * Documentation: http://en.wikipedia.org/wiki/Cross_product + * @param {Point3d} a + * @param {Point3d} b + * @return {Point3d} cross product axb */ - Graph3d.prototype.setData = function (data) { - this._readData(data); - this.redraw(); + Point3d.crossProduct = function(a, b) { + var crossproduct = new Point3d(); - // start animation when option is true - if (this.animationAutoStart && this.dataFilter) { - this.animationStart(); - } + crossproduct.x = a.y * b.z - a.z * b.y; + crossproduct.y = a.z * b.x - a.x * b.z; + crossproduct.z = a.x * b.y - a.y * b.x; + + return crossproduct; }; + /** - * Update the options. Options will be merged with current options - * @param {Object} options + * Rtrieve the length of the vector (or the distance from this point to the origin + * @return {Number} length */ - Graph3d.prototype.setOptions = function (options) { - var cameraPosition = undefined; + Point3d.prototype.length = function() { + return Math.sqrt( + this.x * this.x + + this.y * this.y + + this.z * this.z + ); + }; - this.animationStop(); + module.exports = Point3d; - if (options !== undefined) { - // retrieve parameter values - if (options.width !== undefined) this.width = options.width; - if (options.height !== undefined) this.height = options.height; - if (options.xCenter !== undefined) this.defaultXCenter = options.xCenter; - if (options.yCenter !== undefined) this.defaultYCenter = options.yCenter; +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { - if (options.filterLabel !== undefined) this.filterLabel = options.filterLabel; - if (options.legendLabel !== undefined) this.legendLabel = options.legendLabel; - if (options.xLabel !== undefined) this.xLabel = options.xLabel; - if (options.yLabel !== undefined) this.yLabel = options.yLabel; - if (options.zLabel !== undefined) this.zLabel = options.zLabel; + var util = __webpack_require__(1); - if (options.xValueLabel !== undefined) this.xValueLabel = options.xValueLabel; - if (options.yValueLabel !== undefined) this.yValueLabel = options.yValueLabel; - if (options.zValueLabel !== undefined) this.zValueLabel = options.zValueLabel; + /** + * @constructor Slider + * + * An html slider control with start/stop/prev/next buttons + * @param {Element} container The element where the slider will be created + * @param {Object} options Available options: + * {boolean} visible If true (default) the + * slider is visible. + */ + function Slider(container, options) { + if (container === undefined) { + throw 'Error: No container element defined'; + } + this.container = container; + this.visible = (options && options.visible != undefined) ? options.visible : true; - if (options.style !== undefined) { - var styleNumber = this._getStyleNumber(options.style); - if (styleNumber !== -1) { - this.style = styleNumber; - } - } - if (options.showGrid !== undefined) this.showGrid = options.showGrid; - if (options.showPerspective !== undefined) this.showPerspective = options.showPerspective; - if (options.showShadow !== undefined) this.showShadow = options.showShadow; - if (options.tooltip !== undefined) this.showTooltip = options.tooltip; - if (options.showAnimationControls !== undefined) this.showAnimationControls = options.showAnimationControls; - if (options.keepAspectRatio !== undefined) this.keepAspectRatio = options.keepAspectRatio; - if (options.verticalRatio !== undefined) this.verticalRatio = options.verticalRatio; + if (this.visible) { + this.frame = document.createElement('DIV'); + //this.frame.style.backgroundColor = '#E5E5E5'; + this.frame.style.width = '100%'; + this.frame.style.position = 'relative'; + this.container.appendChild(this.frame); - if (options.animationInterval !== undefined) this.animationInterval = options.animationInterval; - if (options.animationPreload !== undefined) this.animationPreload = options.animationPreload; - if (options.animationAutoStart !== undefined)this.animationAutoStart = options.animationAutoStart; + this.frame.prev = document.createElement('INPUT'); + this.frame.prev.type = 'BUTTON'; + this.frame.prev.value = 'Prev'; + this.frame.appendChild(this.frame.prev); - if (options.xBarWidth !== undefined) this.defaultXBarWidth = options.xBarWidth; - if (options.yBarWidth !== undefined) this.defaultYBarWidth = options.yBarWidth; + this.frame.play = document.createElement('INPUT'); + this.frame.play.type = 'BUTTON'; + this.frame.play.value = 'Play'; + this.frame.appendChild(this.frame.play); - if (options.xMin !== undefined) this.defaultXMin = options.xMin; - if (options.xStep !== undefined) this.defaultXStep = options.xStep; - if (options.xMax !== undefined) this.defaultXMax = options.xMax; - if (options.yMin !== undefined) this.defaultYMin = options.yMin; - if (options.yStep !== undefined) this.defaultYStep = options.yStep; - if (options.yMax !== undefined) this.defaultYMax = options.yMax; - if (options.zMin !== undefined) this.defaultZMin = options.zMin; - if (options.zStep !== undefined) this.defaultZStep = options.zStep; - if (options.zMax !== undefined) this.defaultZMax = options.zMax; - if (options.valueMin !== undefined) this.defaultValueMin = options.valueMin; - if (options.valueMax !== undefined) this.defaultValueMax = options.valueMax; + this.frame.next = document.createElement('INPUT'); + this.frame.next.type = 'BUTTON'; + this.frame.next.value = 'Next'; + this.frame.appendChild(this.frame.next); - if (options.cameraPosition !== undefined) cameraPosition = options.cameraPosition; + this.frame.bar = document.createElement('INPUT'); + this.frame.bar.type = 'BUTTON'; + this.frame.bar.style.position = 'absolute'; + this.frame.bar.style.border = '1px solid red'; + this.frame.bar.style.width = '100px'; + this.frame.bar.style.height = '6px'; + this.frame.bar.style.borderRadius = '2px'; + this.frame.bar.style.MozBorderRadius = '2px'; + this.frame.bar.style.border = '1px solid #7F7F7F'; + this.frame.bar.style.backgroundColor = '#E5E5E5'; + this.frame.appendChild(this.frame.bar); - if (cameraPosition !== undefined) { - this.camera.setArmRotation(cameraPosition.horizontal, cameraPosition.vertical); - this.camera.setArmLength(cameraPosition.distance); - } - else { - this.camera.setArmRotation(1.0, 0.5); - this.camera.setArmLength(1.7); - } + this.frame.slide = document.createElement('INPUT'); + this.frame.slide.type = 'BUTTON'; + this.frame.slide.style.margin = '0px'; + this.frame.slide.value = ' '; + this.frame.slide.style.position = 'relative'; + this.frame.slide.style.left = '-100px'; + this.frame.appendChild(this.frame.slide); + + // create events + var me = this; + this.frame.slide.onmousedown = function (event) {me._onMouseDown(event);}; + this.frame.prev.onclick = function (event) {me.prev(event);}; + this.frame.play.onclick = function (event) {me.togglePlay(event);}; + this.frame.next.onclick = function (event) {me.next(event);}; } - this._setBackgroundColor(options && options.backgroundColor); + this.onChangeCallback = undefined; - this.setSize(this.width, this.height); + this.values = []; + this.index = undefined; - // re-load the data - if (this.dataTable) { - this.setData(this.dataTable); - } + this.playTimeout = undefined; + this.playInterval = 1000; // milliseconds + this.playLoop = true; + } - // start animation when option is true - if (this.animationAutoStart && this.dataFilter) { - this.animationStart(); + /** + * Select the previous index + */ + Slider.prototype.prev = function() { + var index = this.getIndex(); + if (index > 0) { + index--; + this.setIndex(index); } }; /** - * Redraw the Graph. + * Select the next index */ - Graph3d.prototype.redraw = function() { - if (this.dataPoints === undefined) { - throw 'Error: graph data not initialized'; + Slider.prototype.next = function() { + var index = this.getIndex(); + if (index < this.values.length - 1) { + index++; + this.setIndex(index); } + }; - this._resizeCanvas(); - this._resizeCenter(); - this._redrawSlider(); - this._redrawClear(); - this._redrawAxis(); + /** + * Select the next index + */ + Slider.prototype.playNext = function() { + var start = new Date(); - if (this.style === Graph3d.STYLE.GRID || - this.style === Graph3d.STYLE.SURFACE) { - this._redrawDataGrid(); - } - else if (this.style === Graph3d.STYLE.LINE) { - this._redrawDataLine(); - } - else if (this.style === Graph3d.STYLE.BAR || - this.style === Graph3d.STYLE.BARCOLOR || - this.style === Graph3d.STYLE.BARSIZE) { - this._redrawDataBar(); + var index = this.getIndex(); + if (index < this.values.length - 1) { + index++; + this.setIndex(index); } - else { - // style is DOT, DOTLINE, DOTCOLOR, DOTSIZE - this._redrawDataDot(); + else if (this.playLoop) { + // jump to the start + index = 0; + this.setIndex(index); } - this._redrawInfo(); - this._redrawLegend(); + var end = new Date(); + var diff = (end - start); + + // calculate how much time it to to set the index and to execute the callback + // function. + var interval = Math.max(this.playInterval - diff, 0); + // document.title = diff // TODO: cleanup + + var me = this; + this.playTimeout = setTimeout(function() {me.playNext();}, interval); }; /** - * Clear the canvas before redrawing + * Toggle start or stop playing */ - Graph3d.prototype._redrawClear = function() { - var canvas = this.frame.canvas; - var ctx = canvas.getContext('2d'); - - ctx.clearRect(0, 0, canvas.width, canvas.height); + Slider.prototype.togglePlay = function() { + if (this.playTimeout === undefined) { + this.play(); + } else { + this.stop(); + } }; - /** - * Redraw the legend showing the colors + * Start playing */ - Graph3d.prototype._redrawLegend = function() { - var y; - - if (this.style === Graph3d.STYLE.DOTCOLOR || - this.style === Graph3d.STYLE.DOTSIZE) { - - var dotSize = this.frame.clientWidth * 0.02; + Slider.prototype.play = function() { + // Test whether already playing + if (this.playTimeout) return; - var widthMin, widthMax; - if (this.style === Graph3d.STYLE.DOTSIZE) { - widthMin = dotSize / 2; // px - widthMax = dotSize / 2 + dotSize * 2; // Todo: put this in one function - } - else { - widthMin = 20; // px - widthMax = 20; // px - } + this.playNext(); - var height = Math.max(this.frame.clientHeight * 0.25, 100); - var top = this.margin; - var right = this.frame.clientWidth - this.margin; - var left = right - widthMax; - var bottom = top + height; + if (this.frame) { + this.frame.play.value = 'Stop'; } + }; - var canvas = this.frame.canvas; - var ctx = canvas.getContext('2d'); - ctx.lineWidth = 1; - ctx.font = '14px arial'; // TODO: put in options - - if (this.style === Graph3d.STYLE.DOTCOLOR) { - // draw the color bar - var ymin = 0; - var ymax = height; // Todo: make height customizable - for (y = ymin; y < ymax; y++) { - var f = (y - ymin) / (ymax - ymin); - - //var width = (dotSize / 2 + (1-f) * dotSize * 2); // Todo: put this in one function - var hue = f * 240; - var color = this._hsv2rgb(hue, 1, 1); - - ctx.strokeStyle = color; - ctx.beginPath(); - ctx.moveTo(left, top + y); - ctx.lineTo(right, top + y); - ctx.stroke(); - } + /** + * Stop playing + */ + Slider.prototype.stop = function() { + clearInterval(this.playTimeout); + this.playTimeout = undefined; - ctx.strokeStyle = this.colorAxis; - ctx.strokeRect(left, top, widthMax, height); + if (this.frame) { + this.frame.play.value = 'Play'; } + }; - if (this.style === Graph3d.STYLE.DOTSIZE) { - // draw border around color bar - ctx.strokeStyle = this.colorAxis; - ctx.fillStyle = this.colorDot; - ctx.beginPath(); - ctx.moveTo(left, top); - ctx.lineTo(right, top); - ctx.lineTo(right - widthMax + widthMin, bottom); - ctx.lineTo(left, bottom); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - } + /** + * Set a callback function which will be triggered when the value of the + * slider bar has changed. + */ + Slider.prototype.setOnChangeCallback = function(callback) { + this.onChangeCallback = callback; + }; - if (this.style === Graph3d.STYLE.DOTCOLOR || - this.style === Graph3d.STYLE.DOTSIZE) { - // print values along the color bar - var gridLineLen = 5; // px - var step = new StepNumber(this.valueMin, this.valueMax, (this.valueMax-this.valueMin)/5, true); - step.start(); - if (step.getCurrent() < this.valueMin) { - step.next(); - } - while (!step.end()) { - y = bottom - (step.getCurrent() - this.valueMin) / (this.valueMax - this.valueMin) * height; + /** + * Set the interval for playing the list + * @param {Number} interval The interval in milliseconds + */ + Slider.prototype.setPlayInterval = function(interval) { + this.playInterval = interval; + }; - ctx.beginPath(); - ctx.moveTo(left - gridLineLen, y); - ctx.lineTo(left, y); - ctx.stroke(); + /** + * Retrieve the current play interval + * @return {Number} interval The interval in milliseconds + */ + Slider.prototype.getPlayInterval = function(interval) { + return this.playInterval; + }; - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - ctx.fillStyle = this.colorAxis; - ctx.fillText(step.getCurrent(), left - 2 * gridLineLen, y); + /** + * Set looping on or off + * @pararm {boolean} doLoop If true, the slider will jump to the start when + * the end is passed, and will jump to the end + * when the start is passed. + */ + Slider.prototype.setPlayLoop = function(doLoop) { + this.playLoop = doLoop; + }; - step.next(); - } - ctx.textAlign = 'right'; - ctx.textBaseline = 'top'; - var label = this.legendLabel; - ctx.fillText(label, right, bottom + this.margin); + /** + * Execute the onchange callback function + */ + Slider.prototype.onChange = function() { + if (this.onChangeCallback !== undefined) { + this.onChangeCallback(); } }; /** - * Redraw the filter + * redraw the slider on the correct place */ - Graph3d.prototype._redrawFilter = function() { - this.frame.filter.innerHTML = ''; + Slider.prototype.redraw = function() { + if (this.frame) { + // resize the bar + this.frame.bar.style.top = (this.frame.clientHeight/2 - + this.frame.bar.offsetHeight/2) + 'px'; + this.frame.bar.style.width = (this.frame.clientWidth - + this.frame.prev.clientWidth - + this.frame.play.clientWidth - + this.frame.next.clientWidth - 30) + 'px'; - if (this.dataFilter) { - var options = { - 'visible': this.showAnimationControls - }; - var slider = new Slider(this.frame.filter, options); - this.frame.filter.slider = slider; + // position the slider button + var left = this.indexToLeft(this.index); + this.frame.slide.style.left = (left) + 'px'; + } + }; - // TODO: css here is not nice here... - this.frame.filter.style.padding = '10px'; - //this.frame.filter.style.backgroundColor = '#EFEFEF'; - slider.setValues(this.dataFilter.values); - slider.setPlayInterval(this.animationInterval); + /** + * Set the list with values for the slider + * @param {Array} values A javascript array with values (any type) + */ + Slider.prototype.setValues = function(values) { + this.values = values; - // create an event handler - var me = this; - var onchange = function () { - var index = slider.getIndex(); + if (this.values.length > 0) + this.setIndex(0); + else + this.index = undefined; + }; - me.dataFilter.selectValue(index); - me.dataPoints = me.dataFilter._getDataPoints(); + /** + * Select a value by its index + * @param {Number} index + */ + Slider.prototype.setIndex = function(index) { + if (index < this.values.length) { + this.index = index; - me.redraw(); - }; - slider.setOnChangeCallback(onchange); + this.redraw(); + this.onChange(); } else { - this.frame.filter.slider = undefined; + throw 'Error: index out of range'; } }; /** - * Redraw the slider + * retrieve the index of the currently selected vaue + * @return {Number} index */ - Graph3d.prototype._redrawSlider = function() { - if ( this.frame.filter.slider !== undefined) { - this.frame.filter.slider.redraw(); - } + Slider.prototype.getIndex = function() { + return this.index; }; /** - * Redraw common information + * retrieve the currently selected value + * @return {*} value */ - Graph3d.prototype._redrawInfo = function() { - if (this.dataFilter) { - var canvas = this.frame.canvas; - var ctx = canvas.getContext('2d'); + Slider.prototype.get = function() { + return this.values[this.index]; + }; - ctx.font = '14px arial'; // TODO: put in options - ctx.lineStyle = 'gray'; - ctx.fillStyle = 'gray'; - ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; - var x = this.margin; - var y = this.margin; - ctx.fillText(this.dataFilter.getLabel() + ': ' + this.dataFilter.getSelectedValue(), x, y); - } + Slider.prototype._onMouseDown = function(event) { + // only react on left mouse button down + var leftButtonDown = event.which ? (event.which === 1) : (event.button === 1); + if (!leftButtonDown) return; + + this.startClientX = event.clientX; + this.startSlideX = parseFloat(this.frame.slide.style.left); + + this.frame.style.cursor = 'move'; + + // add event listeners to handle moving the contents + // we store the function onmousemove and onmouseup in the graph, so we can + // remove the eventlisteners lateron in the function mouseUp() + var me = this; + this.onmousemove = function (event) {me._onMouseMove(event);}; + this.onmouseup = function (event) {me._onMouseUp(event);}; + util.addEventListener(document, 'mousemove', this.onmousemove); + util.addEventListener(document, 'mouseup', this.onmouseup); + util.preventDefault(event); }; - /** - * Redraw the axis - */ - Graph3d.prototype._redrawAxis = function() { - var canvas = this.frame.canvas, - ctx = canvas.getContext('2d'), - from, to, step, prettyStep, - text, xText, yText, zText, - offset, xOffset, yOffset, - xMin2d, xMax2d; + Slider.prototype.leftToIndex = function (left) { + var width = parseFloat(this.frame.bar.style.width) - + this.frame.slide.clientWidth - 10; + var x = left - 3; - // TODO: get the actual rendered style of the containerElement - //ctx.font = this.containerElement.style.font; - ctx.font = 24 / this.camera.getArmLength() + 'px arial'; + var index = Math.round(x / width * (this.values.length-1)); + if (index < 0) index = 0; + if (index > this.values.length-1) index = this.values.length-1; - // calculate the length for the short grid lines - var gridLenX = 0.025 / this.scale.x; - var gridLenY = 0.025 / this.scale.y; - var textMargin = 5 / this.camera.getArmLength(); // px - var armAngle = this.camera.getArmRotation().horizontal; + return index; + }; - // draw x-grid lines - ctx.lineWidth = 1; - prettyStep = (this.defaultXStep === undefined); - step = new StepNumber(this.xMin, this.xMax, this.xStep, prettyStep); - step.start(); - if (step.getCurrent() < this.xMin) { - step.next(); - } - while (!step.end()) { - var x = step.getCurrent(); + Slider.prototype.indexToLeft = function (index) { + var width = parseFloat(this.frame.bar.style.width) - + this.frame.slide.clientWidth - 10; - if (this.showGrid) { - from = this._convert3Dto2D(new Point3d(x, this.yMin, this.zMin)); - to = this._convert3Dto2D(new Point3d(x, this.yMax, this.zMin)); - ctx.strokeStyle = this.colorGrid; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); - } - else { - from = this._convert3Dto2D(new Point3d(x, this.yMin, this.zMin)); - to = this._convert3Dto2D(new Point3d(x, this.yMin+gridLenX, this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); + var x = index / (this.values.length-1) * width; + var left = x + 3; - from = this._convert3Dto2D(new Point3d(x, this.yMax, this.zMin)); - to = this._convert3Dto2D(new Point3d(x, this.yMax-gridLenX, this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); - } + return left; + }; - yText = (Math.cos(armAngle) > 0) ? this.yMin : this.yMax; - text = this._convert3Dto2D(new Point3d(x, yText, this.zMin)); - if (Math.cos(armAngle * 2) > 0) { - ctx.textAlign = 'center'; - ctx.textBaseline = 'top'; - text.y += textMargin; - } - else if (Math.sin(armAngle * 2) < 0){ - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - } - else { - ctx.textAlign = 'left'; - ctx.textBaseline = 'middle'; - } - ctx.fillStyle = this.colorAxis; - ctx.fillText(' ' + this.xValueLabel(step.getCurrent()) + ' ', text.x, text.y); - step.next(); - } - // draw y-grid lines - ctx.lineWidth = 1; - prettyStep = (this.defaultYStep === undefined); - step = new StepNumber(this.yMin, this.yMax, this.yStep, prettyStep); - step.start(); - if (step.getCurrent() < this.yMin) { - step.next(); - } - while (!step.end()) { - if (this.showGrid) { - from = this._convert3Dto2D(new Point3d(this.xMin, step.getCurrent(), this.zMin)); - to = this._convert3Dto2D(new Point3d(this.xMax, step.getCurrent(), this.zMin)); - ctx.strokeStyle = this.colorGrid; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); - } - else { - from = this._convert3Dto2D(new Point3d(this.xMin, step.getCurrent(), this.zMin)); - to = this._convert3Dto2D(new Point3d(this.xMin+gridLenY, step.getCurrent(), this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); + Slider.prototype._onMouseMove = function (event) { + var diff = event.clientX - this.startClientX; + var x = this.startSlideX + diff; + + var index = this.leftToIndex(x); + + this.setIndex(index); + + util.preventDefault(); + }; + + + Slider.prototype._onMouseUp = function (event) { + this.frame.style.cursor = 'auto'; + + // remove event listeners + util.removeEventListener(document, 'mousemove', this.onmousemove); + util.removeEventListener(document, 'mouseup', this.onmouseup); + + util.preventDefault(); + }; + + module.exports = Slider; + + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * @prototype StepNumber + * The class StepNumber is an iterator for Numbers. You provide a start and end + * value, and a best step size. StepNumber itself rounds to fixed values and + * a finds the step that best fits the provided step. + * + * If prettyStep is true, the step size is chosen as close as possible to the + * provided step, but being a round value like 1, 2, 5, 10, 20, 50, .... + * + * Example usage: + * var step = new StepNumber(0, 10, 2.5, true); + * step.start(); + * while (!step.end()) { + * alert(step.getCurrent()); + * step.next(); + * } + * + * Version: 1.0 + * + * @param {Number} start The start value + * @param {Number} end The end value + * @param {Number} step Optional. Step size. Must be a positive value. + * @param {boolean} prettyStep Optional. If true, the step size is rounded + * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...) + */ + function StepNumber(start, end, step, prettyStep) { + // set default values + this._start = 0; + this._end = 0; + this._step = 1; + this.prettyStep = true; + this.precision = 5; - from = this._convert3Dto2D(new Point3d(this.xMax, step.getCurrent(), this.zMin)); - to = this._convert3Dto2D(new Point3d(this.xMax-gridLenY, step.getCurrent(), this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); - } + this._current = 0; + this.setRange(start, end, step, prettyStep); + }; - xText = (Math.sin(armAngle ) > 0) ? this.xMin : this.xMax; - text = this._convert3Dto2D(new Point3d(xText, step.getCurrent(), this.zMin)); - if (Math.cos(armAngle * 2) < 0) { - ctx.textAlign = 'center'; - ctx.textBaseline = 'top'; - text.y += textMargin; - } - else if (Math.sin(armAngle * 2) > 0){ - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - } - else { - ctx.textAlign = 'left'; - ctx.textBaseline = 'middle'; - } - ctx.fillStyle = this.colorAxis; - ctx.fillText(' ' + this.yValueLabel(step.getCurrent()) + ' ', text.x, text.y); + /** + * Set a new range: start, end and step. + * + * @param {Number} start The start value + * @param {Number} end The end value + * @param {Number} step Optional. Step size. Must be a positive value. + * @param {boolean} prettyStep Optional. If true, the step size is rounded + * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...) + */ + StepNumber.prototype.setRange = function(start, end, step, prettyStep) { + this._start = start ? start : 0; + this._end = end ? end : 0; - step.next(); - } + this.setStep(step, prettyStep); + }; - // draw z-grid lines and axis - ctx.lineWidth = 1; - prettyStep = (this.defaultZStep === undefined); - step = new StepNumber(this.zMin, this.zMax, this.zStep, prettyStep); - step.start(); - if (step.getCurrent() < this.zMin) { - step.next(); - } - xText = (Math.cos(armAngle ) > 0) ? this.xMin : this.xMax; - yText = (Math.sin(armAngle ) < 0) ? this.yMin : this.yMax; - while (!step.end()) { - // TODO: make z-grid lines really 3d? - from = this._convert3Dto2D(new Point3d(xText, yText, step.getCurrent())); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(from.x - textMargin, from.y); - ctx.stroke(); + /** + * Set a new step size + * @param {Number} step New step size. Must be a positive value + * @param {boolean} prettyStep Optional. If true, the provided step is rounded + * to a pretty step size (like 1, 2, 5, 10, 20, 50, ...) + */ + StepNumber.prototype.setStep = function(step, prettyStep) { + if (step === undefined || step <= 0) + return; - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - ctx.fillStyle = this.colorAxis; - ctx.fillText(this.zValueLabel(step.getCurrent()) + ' ', from.x - 5, from.y); + if (prettyStep !== undefined) + this.prettyStep = prettyStep; - step.next(); - } - ctx.lineWidth = 1; - from = this._convert3Dto2D(new Point3d(xText, yText, this.zMin)); - to = this._convert3Dto2D(new Point3d(xText, yText, this.zMax)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); + if (this.prettyStep === true) + this._step = StepNumber.calculatePrettyStep(step); + else + this._step = step; + }; - // draw x-axis - ctx.lineWidth = 1; - // line at yMin - xMin2d = this._convert3Dto2D(new Point3d(this.xMin, this.yMin, this.zMin)); - xMax2d = this._convert3Dto2D(new Point3d(this.xMax, this.yMin, this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(xMin2d.x, xMin2d.y); - ctx.lineTo(xMax2d.x, xMax2d.y); - ctx.stroke(); - // line at ymax - xMin2d = this._convert3Dto2D(new Point3d(this.xMin, this.yMax, this.zMin)); - xMax2d = this._convert3Dto2D(new Point3d(this.xMax, this.yMax, this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(xMin2d.x, xMin2d.y); - ctx.lineTo(xMax2d.x, xMax2d.y); - ctx.stroke(); + /** + * Calculate a nice step size, closest to the desired step size. + * Returns a value in one of the ranges 1*10^n, 2*10^n, or 5*10^n, where n is an + * integer Number. For example 1, 2, 5, 10, 20, 50, etc... + * @param {Number} step Desired step size + * @return {Number} Nice step size + */ + StepNumber.calculatePrettyStep = function (step) { + var log10 = function (x) {return Math.log(x) / Math.LN10;}; - // draw y-axis - ctx.lineWidth = 1; - // line at xMin - from = this._convert3Dto2D(new Point3d(this.xMin, this.yMin, this.zMin)); - to = this._convert3Dto2D(new Point3d(this.xMin, this.yMax, this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); - // line at xMax - from = this._convert3Dto2D(new Point3d(this.xMax, this.yMin, this.zMin)); - to = this._convert3Dto2D(new Point3d(this.xMax, this.yMax, this.zMin)); - ctx.strokeStyle = this.colorAxis; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(to.x, to.y); - ctx.stroke(); + // try three steps (multiple of 1, 2, or 5 + var step1 = Math.pow(10, Math.round(log10(step))), + step2 = 2 * Math.pow(10, Math.round(log10(step / 2))), + step5 = 5 * Math.pow(10, Math.round(log10(step / 5))); - // draw x-label - var xLabel = this.xLabel; - if (xLabel.length > 0) { - yOffset = 0.1 / this.scale.y; - xText = (this.xMin + this.xMax) / 2; - yText = (Math.cos(armAngle) > 0) ? this.yMin - yOffset: this.yMax + yOffset; - text = this._convert3Dto2D(new Point3d(xText, yText, this.zMin)); - if (Math.cos(armAngle * 2) > 0) { - ctx.textAlign = 'center'; - ctx.textBaseline = 'top'; - } - else if (Math.sin(armAngle * 2) < 0){ - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - } - else { - ctx.textAlign = 'left'; - ctx.textBaseline = 'middle'; - } - ctx.fillStyle = this.colorAxis; - ctx.fillText(xLabel, text.x, text.y); - } + // choose the best step (closest to minimum step) + var prettyStep = step1; + if (Math.abs(step2 - step) <= Math.abs(prettyStep - step)) prettyStep = step2; + if (Math.abs(step5 - step) <= Math.abs(prettyStep - step)) prettyStep = step5; - // draw y-label - var yLabel = this.yLabel; - if (yLabel.length > 0) { - xOffset = 0.1 / this.scale.x; - xText = (Math.sin(armAngle ) > 0) ? this.xMin - xOffset : this.xMax + xOffset; - yText = (this.yMin + this.yMax) / 2; - text = this._convert3Dto2D(new Point3d(xText, yText, this.zMin)); - if (Math.cos(armAngle * 2) < 0) { - ctx.textAlign = 'center'; - ctx.textBaseline = 'top'; - } - else if (Math.sin(armAngle * 2) > 0){ - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - } - else { - ctx.textAlign = 'left'; - ctx.textBaseline = 'middle'; - } - ctx.fillStyle = this.colorAxis; - ctx.fillText(yLabel, text.x, text.y); + // for safety + if (prettyStep <= 0) { + prettyStep = 1; } - // draw z-label - var zLabel = this.zLabel; - if (zLabel.length > 0) { - offset = 30; // pixels. // TODO: relate to the max width of the values on the z axis? - xText = (Math.cos(armAngle ) > 0) ? this.xMin : this.xMax; - yText = (Math.sin(armAngle ) < 0) ? this.yMin : this.yMax; - zText = (this.zMin + this.zMax) / 2; - text = this._convert3Dto2D(new Point3d(xText, yText, zText)); - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - ctx.fillStyle = this.colorAxis; - ctx.fillText(zLabel, text.x - offset, text.y); - } + return prettyStep; }; /** - * Calculate the color based on the given value. - * @param {Number} H Hue, a value be between 0 and 360 - * @param {Number} S Saturation, a value between 0 and 1 - * @param {Number} V Value, a value between 0 and 1 + * returns the current value of the step + * @return {Number} current value */ - Graph3d.prototype._hsv2rgb = function(H, S, V) { - var R, G, B, C, Hi, X; + StepNumber.prototype.getCurrent = function () { + return parseFloat(this._current.toPrecision(this.precision)); + }; - C = V * S; - Hi = Math.floor(H/60); // hi = 0,1,2,3,4,5 - X = C * (1 - Math.abs(((H/60) % 2) - 1)); + /** + * returns the current step size + * @return {Number} current step size + */ + StepNumber.prototype.getStep = function () { + return this._step; + }; - switch (Hi) { - case 0: R = C; G = X; B = 0; break; - case 1: R = X; G = C; B = 0; break; - case 2: R = 0; G = C; B = X; break; - case 3: R = 0; G = X; B = C; break; - case 4: R = X; G = 0; B = C; break; - case 5: R = C; G = 0; B = X; break; + /** + * Set the current value to the largest value smaller than start, which + * is a multiple of the step size + */ + StepNumber.prototype.start = function() { + this._current = this._start - this._start % this._step; + }; - default: R = 0; G = 0; B = 0; break; - } + /** + * Do a step, add the step size to the current value + */ + StepNumber.prototype.next = function () { + this._current += this._step; + }; - return 'RGB(' + parseInt(R*255) + ',' + parseInt(G*255) + ',' + parseInt(B*255) + ')'; + /** + * Returns true whether the end is reached + * @return {boolean} True if the current value has passed the end value. + */ + StepNumber.prototype.end = function () { + return (this._current > this._end); }; + module.exports = StepNumber; + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + var Emitter = __webpack_require__(52); + var Hammer = __webpack_require__(44); + var util = __webpack_require__(1); + var DataSet = __webpack_require__(3); + var DataView = __webpack_require__(4); + var Range = __webpack_require__(16); + var Core = __webpack_require__(45); + var TimeAxis = __webpack_require__(29); + var CurrentTime = __webpack_require__(20); + var CustomTime = __webpack_require__(21); + var ItemSet = __webpack_require__(26); /** - * Draw all datapoints as a grid - * This function can be used when the style is 'grid' + * Create a timeline visualization + * @param {HTMLElement} container + * @param {vis.DataSet | Array | google.visualization.DataTable} [items] + * @param {Object} [options] See Timeline.setOptions for the available options. + * @constructor + * @extends Core */ - Graph3d.prototype._redrawDataGrid = function() { - var canvas = this.frame.canvas, - ctx = canvas.getContext('2d'), - point, right, top, cross, - i, - topSideVisible, fillStyle, strokeStyle, lineWidth, - h, s, v, zAvg; + function Timeline (container, items, groups, options) { + if (!(this instanceof Timeline)) { + throw new SyntaxError('Constructor must be called with the new operator'); + } + // if the third element is options, the forth is groups (optionally); + if (!(Array.isArray(groups) || groups instanceof DataSet) && groups instanceof Object) { + var forthArgument = options; + options = groups; + groups = forthArgument; + } - if (this.dataPoints === undefined || this.dataPoints.length <= 0) - return; // TODO: throw exception? + var me = this; + this.defaultOptions = { + start: null, + end: null, - // calculate the translations and screen position of all points - for (i = 0; i < this.dataPoints.length; i++) { - var trans = this._convertPointToTranslation(this.dataPoints[i].point); - var screen = this._convertTranslationToScreen(trans); + autoResize: true, - this.dataPoints[i].trans = trans; - this.dataPoints[i].screen = screen; + orientation: 'bottom', + width: null, + height: null, + maxHeight: null, + minHeight: null + }; + this.options = util.deepExtend({}, this.defaultOptions); - // calculate the translation of the point at the bottom (needed for sorting) - var transBottom = this._convertPointToTranslation(this.dataPoints[i].bottom); - this.dataPoints[i].dist = this.showPerspective ? transBottom.length() : -transBottom.z; - } + // Create the DOM, props, and emitter + this._create(container); - // sort the points on depth of their (x,y) position (not on z) - var sortDepth = function (a, b) { - return b.dist - a.dist; + // all components listed here will be repainted automatically + this.components = []; + + this.body = { + dom: this.dom, + domProps: this.props, + emitter: { + on: this.on.bind(this), + off: this.off.bind(this), + emit: this.emit.bind(this) + }, + hiddenDates: [], + util: { + snap: null, // will be specified after TimeAxis is created + toScreen: me._toScreen.bind(me), + toGlobalScreen: me._toGlobalScreen.bind(me), // this refers to the root.width + toTime: me._toTime.bind(me), + toGlobalTime : me._toGlobalTime.bind(me) + } }; - this.dataPoints.sort(sortDepth); - if (this.style === Graph3d.STYLE.SURFACE) { - for (i = 0; i < this.dataPoints.length; i++) { - point = this.dataPoints[i]; - right = this.dataPoints[i].pointRight; - top = this.dataPoints[i].pointTop; - cross = this.dataPoints[i].pointCross; + // range + this.range = new Range(this.body); + this.components.push(this.range); + this.body.range = this.range; - if (point !== undefined && right !== undefined && top !== undefined && cross !== undefined) { + // time axis + this.timeAxis = new TimeAxis(this.body); + this.components.push(this.timeAxis); + this.body.util.snap = this.timeAxis.snap.bind(this.timeAxis); - if (this.showGrayBottom || this.showShadow) { - // calculate the cross product of the two vectors from center - // to left and right, in order to know whether we are looking at the - // bottom or at the top side. We can also use the cross product - // for calculating light intensity - var aDiff = Point3d.subtract(cross.trans, point.trans); - var bDiff = Point3d.subtract(top.trans, right.trans); - var crossproduct = Point3d.crossProduct(aDiff, bDiff); - var len = crossproduct.length(); - // FIXME: there is a bug with determining the surface side (shadow or colored) + // current time bar + this.currentTime = new CurrentTime(this.body); + this.components.push(this.currentTime); - topSideVisible = (crossproduct.z > 0); - } - else { - topSideVisible = true; - } + // custom time bar + // Note: time bar will be attached in this.setOptions when selected + this.customTime = new CustomTime(this.body); + this.components.push(this.customTime); - if (topSideVisible) { - // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 - zAvg = (point.point.z + right.point.z + top.point.z + cross.point.z) / 4; - h = (1 - (zAvg - this.zMin) * this.scale.z / this.verticalRatio) * 240; - s = 1; // saturation + // item set + this.itemSet = new ItemSet(this.body); + this.components.push(this.itemSet); - if (this.showShadow) { - v = Math.min(1 + (crossproduct.x / len) / 2, 1); // value. TODO: scale - fillStyle = this._hsv2rgb(h, s, v); - strokeStyle = fillStyle; - } - else { - v = 1; - fillStyle = this._hsv2rgb(h, s, v); - strokeStyle = this.colorAxis; - } - } - else { - fillStyle = 'gray'; - strokeStyle = this.colorAxis; - } - lineWidth = 0.5; + this.itemsData = null; // DataSet + this.groupsData = null; // DataSet - ctx.lineWidth = lineWidth; - ctx.fillStyle = fillStyle; - ctx.strokeStyle = strokeStyle; - ctx.beginPath(); - ctx.moveTo(point.screen.x, point.screen.y); - ctx.lineTo(right.screen.x, right.screen.y); - ctx.lineTo(cross.screen.x, cross.screen.y); - ctx.lineTo(top.screen.x, top.screen.y); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - } - } + // apply options + if (options) { + this.setOptions(options); } - else { // grid style - for (i = 0; i < this.dataPoints.length; i++) { - point = this.dataPoints[i]; - right = this.dataPoints[i].pointRight; - top = this.dataPoints[i].pointTop; - if (point !== undefined) { - if (this.showPerspective) { - lineWidth = 2 / -point.trans.z; - } - else { - lineWidth = 2 * -(this.eye.z / this.camera.getArmLength()); - } - } + // IMPORTANT: THIS HAPPENS BEFORE SET ITEMS! + if (groups) { + this.setGroups(groups); + } - if (point !== undefined && right !== undefined) { - // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 - zAvg = (point.point.z + right.point.z) / 2; - h = (1 - (zAvg - this.zMin) * this.scale.z / this.verticalRatio) * 240; + // create itemset + if (items) { + this.setItems(items); + } + else { + this.redraw(); + } + } - ctx.lineWidth = lineWidth; - ctx.strokeStyle = this._hsv2rgb(h, 1, 1); - ctx.beginPath(); - ctx.moveTo(point.screen.x, point.screen.y); - ctx.lineTo(right.screen.x, right.screen.y); - ctx.stroke(); - } + // Extend the functionality from Core + Timeline.prototype = new Core(); - if (point !== undefined && top !== undefined) { - // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 - zAvg = (point.point.z + top.point.z) / 2; - h = (1 - (zAvg - this.zMin) * this.scale.z / this.verticalRatio) * 240; + /** + * Set items + * @param {vis.DataSet | Array | google.visualization.DataTable | null} items + */ + Timeline.prototype.setItems = function(items) { + var initialLoad = (this.itemsData == null); - ctx.lineWidth = lineWidth; - ctx.strokeStyle = this._hsv2rgb(h, 1, 1); - ctx.beginPath(); - ctx.moveTo(point.screen.x, point.screen.y); - ctx.lineTo(top.screen.x, top.screen.y); - ctx.stroke(); + // convert to type DataSet when needed + var newDataSet; + if (!items) { + newDataSet = null; + } + else if (items instanceof DataSet || items instanceof DataView) { + newDataSet = items; + } + else { + // turn an array into a dataset + newDataSet = new DataSet(items, { + type: { + start: 'Date', + end: 'Date' } + }); + } + + // set items + this.itemsData = newDataSet; + this.itemSet && this.itemSet.setItems(newDataSet); + + if (initialLoad) { + if (this.options.start != undefined || this.options.end != undefined) { + var start = this.options.start != undefined ? this.options.start : null; + var end = this.options.end != undefined ? this.options.end : null; + + this.setWindow(start, end, {animate: false}); + } + else { + this.fit({animate: false}); } } }; - /** - * Draw all datapoints as dots. - * This function can be used when the style is 'dot' or 'dot-line' + * Set groups + * @param {vis.DataSet | Array | google.visualization.DataTable} groups */ - Graph3d.prototype._redrawDataDot = function() { - var canvas = this.frame.canvas; - var ctx = canvas.getContext('2d'); - var i; + Timeline.prototype.setGroups = function(groups) { + // convert to type DataSet when needed + var newDataSet; + if (!groups) { + newDataSet = null; + } + else if (groups instanceof DataSet || groups instanceof DataView) { + newDataSet = groups; + } + else { + // turn an array into a dataset + newDataSet = new DataSet(groups); + } - if (this.dataPoints === undefined || this.dataPoints.length <= 0) - return; // TODO: throw exception? + this.groupsData = newDataSet; + this.itemSet.setGroups(newDataSet); + }; - // calculate the translations of all points - for (i = 0; i < this.dataPoints.length; i++) { - var trans = this._convertPointToTranslation(this.dataPoints[i].point); - var screen = this._convertTranslationToScreen(trans); - this.dataPoints[i].trans = trans; - this.dataPoints[i].screen = screen; + /** + * Set selected items by their id. Replaces the current selection + * Unknown id's are silently ignored. + * @param {string[] | string} [ids] An array with zero or more id's of the items to be + * selected. If ids is an empty array, all items will be + * unselected. + * @param {Object} [options] Available options: + * `focus: boolean` + * If true, focus will be set to the selected item(s) + * `animate: boolean | number` + * If true (default), the range is animated + * smoothly to the new window. + * If a number, the number is taken as duration + * for the animation. Default duration is 500 ms. + * Only applicable when option focus is true. + */ + Timeline.prototype.setSelection = function(ids, options) { + this.itemSet && this.itemSet.setSelection(ids); - // calculate the distance from the point at the bottom to the camera - var transBottom = this._convertPointToTranslation(this.dataPoints[i].bottom); - this.dataPoints[i].dist = this.showPerspective ? transBottom.length() : -transBottom.z; + if (options && options.focus) { + this.focus(ids, options); } + }; - // order the translated points by depth - var sortDepth = function (a, b) { - return b.dist - a.dist; - }; - this.dataPoints.sort(sortDepth); + /** + * Get the selected items by their id + * @return {Array} ids The ids of the selected items + */ + Timeline.prototype.getSelection = function() { + return this.itemSet && this.itemSet.getSelection() || []; + }; - // draw the datapoints as colored circles - var dotSize = this.frame.clientWidth * 0.02; // px - for (i = 0; i < this.dataPoints.length; i++) { - var point = this.dataPoints[i]; + /** + * Adjust the visible window such that the selected item (or multiple items) + * are centered on screen. + * @param {String | String[]} id An item id or array with item ids + * @param {Object} [options] Available options: + * `animate: boolean | number` + * If true (default), the range is animated + * smoothly to the new window. + * If a number, the number is taken as duration + * for the animation. Default duration is 500 ms. + * Only applicable when option focus is true + */ + Timeline.prototype.focus = function(id, options) { + if (!this.itemsData || id == undefined) return; - if (this.style === Graph3d.STYLE.DOTLINE) { - // draw a vertical line from the bottom to the graph value - //var from = this._convert3Dto2D(new Point3d(point.point.x, point.point.y, this.zMin)); - var from = this._convert3Dto2D(point.bottom); - ctx.lineWidth = 1; - ctx.strokeStyle = this.colorGrid; - ctx.beginPath(); - ctx.moveTo(from.x, from.y); - ctx.lineTo(point.screen.x, point.screen.y); - ctx.stroke(); - } + var ids = Array.isArray(id) ? id : [id]; - // calculate radius for the circle - var size; - if (this.style === Graph3d.STYLE.DOTSIZE) { - size = dotSize/2 + 2*dotSize * (point.point.value - this.valueMin) / (this.valueMax - this.valueMin); - } - else { - size = dotSize; + // get the specified item(s) + var itemsData = this.itemsData.getDataSet().get(ids, { + type: { + start: 'Date', + end: 'Date' } + }); - var radius; - if (this.showPerspective) { - radius = size / -point.trans.z; - } - else { - radius = size * -(this.eye.z / this.camera.getArmLength()); - } - if (radius < 0) { - radius = 0; - } + // calculate minimum start and maximum end of specified items + var start = null; + var end = null; + itemsData.forEach(function (itemData) { + var s = itemData.start.valueOf(); + var e = 'end' in itemData ? itemData.end.valueOf() : itemData.start.valueOf(); - var hue, color, borderColor; - if (this.style === Graph3d.STYLE.DOTCOLOR ) { - // calculate the color based on the value - hue = (1 - (point.point.value - this.valueMin) * this.scale.value) * 240; - color = this._hsv2rgb(hue, 1, 1); - borderColor = this._hsv2rgb(hue, 1, 0.8); - } - else if (this.style === Graph3d.STYLE.DOTSIZE) { - color = this.colorDot; - borderColor = this.colorDotBorder; + if (start === null || s < start) { + start = s; } - else { - // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 - hue = (1 - (point.point.z - this.zMin) * this.scale.z / this.verticalRatio) * 240; - color = this._hsv2rgb(hue, 1, 1); - borderColor = this._hsv2rgb(hue, 1, 0.8); + + if (end === null || e > end) { + end = e; } + }); - // draw the circle - ctx.lineWidth = 1.0; - ctx.strokeStyle = borderColor; - ctx.fillStyle = color; - ctx.beginPath(); - ctx.arc(point.screen.x, point.screen.y, radius, 0, Math.PI*2, true); - ctx.fill(); - ctx.stroke(); + if (start !== null && end !== null) { + // calculate the new middle and interval for the window + var middle = (start + end) / 2; + var interval = Math.max((this.range.end - this.range.start), (end - start) * 1.1); + + var animate = (options && options.animate !== undefined) ? options.animate : true; + this.range.setRange(middle - interval / 2, middle + interval / 2, animate); } }; /** - * Draw all datapoints as bars. - * This function can be used when the style is 'bar', 'bar-color', or 'bar-size' + * Get the data range of the item set. + * @returns {{min: Date, max: Date}} range A range with a start and end Date. + * When no minimum is found, min==null + * When no maximum is found, max==null */ - Graph3d.prototype._redrawDataBar = function() { - var canvas = this.frame.canvas; - var ctx = canvas.getContext('2d'); - var i, j, surface, corners; - - if (this.dataPoints === undefined || this.dataPoints.length <= 0) - return; // TODO: throw exception? + Timeline.prototype.getItemRange = function() { + // calculate min from start filed + var dataset = this.itemsData.getDataSet(), + min = null, + max = null; - // calculate the translations of all points - for (i = 0; i < this.dataPoints.length; i++) { - var trans = this._convertPointToTranslation(this.dataPoints[i].point); - var screen = this._convertTranslationToScreen(trans); - this.dataPoints[i].trans = trans; - this.dataPoints[i].screen = screen; + if (dataset) { + // calculate the minimum value of the field 'start' + var minItem = dataset.min('start'); + min = minItem ? util.convert(minItem.start, 'Date').valueOf() : null; + // Note: we convert first to Date and then to number because else + // a conversion from ISODate to Number will fail - // calculate the distance from the point at the bottom to the camera - var transBottom = this._convertPointToTranslation(this.dataPoints[i].bottom); - this.dataPoints[i].dist = this.showPerspective ? transBottom.length() : -transBottom.z; + // calculate maximum value of fields 'start' and 'end' + var maxStartItem = dataset.max('start'); + if (maxStartItem) { + max = util.convert(maxStartItem.start, 'Date').valueOf(); + } + var maxEndItem = dataset.max('end'); + if (maxEndItem) { + if (max == null) { + max = util.convert(maxEndItem.end, 'Date').valueOf(); + } + else { + max = Math.max(max, util.convert(maxEndItem.end, 'Date').valueOf()); + } + } } - // order the translated points by depth - var sortDepth = function (a, b) { - return b.dist - a.dist; + return { + min: (min != null) ? new Date(min) : null, + max: (max != null) ? new Date(max) : null }; - this.dataPoints.sort(sortDepth); + }; - // draw the datapoints as bars - var xWidth = this.xBarWidth / 2; - var yWidth = this.yBarWidth / 2; - for (i = 0; i < this.dataPoints.length; i++) { - var point = this.dataPoints[i]; - // determine color - var hue, color, borderColor; - if (this.style === Graph3d.STYLE.BARCOLOR ) { - // calculate the color based on the value - hue = (1 - (point.point.value - this.valueMin) * this.scale.value) * 240; - color = this._hsv2rgb(hue, 1, 1); - borderColor = this._hsv2rgb(hue, 1, 0.8); - } - else if (this.style === Graph3d.STYLE.BARSIZE) { - color = this.colorDot; - borderColor = this.colorDotBorder; - } - else { - // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 - hue = (1 - (point.point.z - this.zMin) * this.scale.z / this.verticalRatio) * 240; - color = this._hsv2rgb(hue, 1, 1); - borderColor = this._hsv2rgb(hue, 1, 0.8); - } + module.exports = Timeline; - // calculate size for the bar - if (this.style === Graph3d.STYLE.BARSIZE) { - xWidth = (this.xBarWidth / 2) * ((point.point.value - this.valueMin) / (this.valueMax - this.valueMin) * 0.8 + 0.2); - yWidth = (this.yBarWidth / 2) * ((point.point.value - this.valueMin) / (this.valueMax - this.valueMin) * 0.8 + 0.2); - } - // calculate all corner points - var me = this; - var point3d = point.point; - var top = [ - {point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, point3d.z)}, - {point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, point3d.z)}, - {point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, point3d.z)}, - {point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, point3d.z)} - ]; - var bottom = [ - {point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, this.zMin)}, - {point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, this.zMin)}, - {point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, this.zMin)}, - {point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, this.zMin)} - ]; +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { - // calculate screen location of the points - top.forEach(function (obj) { - obj.screen = me._convert3Dto2D(obj.point); - }); - bottom.forEach(function (obj) { - obj.screen = me._convert3Dto2D(obj.point); - }); + var Emitter = __webpack_require__(52); + var Hammer = __webpack_require__(44); + var util = __webpack_require__(1); + var DataSet = __webpack_require__(3); + var DataView = __webpack_require__(4); + var Range = __webpack_require__(16); + var Core = __webpack_require__(45); + var TimeAxis = __webpack_require__(29); + var CurrentTime = __webpack_require__(20); + var CustomTime = __webpack_require__(21); + var LineGraph = __webpack_require__(28); - // create five sides, calculate both corner points and center points - var surfaces = [ - {corners: top, center: Point3d.avg(bottom[0].point, bottom[2].point)}, - {corners: [top[0], top[1], bottom[1], bottom[0]], center: Point3d.avg(bottom[1].point, bottom[0].point)}, - {corners: [top[1], top[2], bottom[2], bottom[1]], center: Point3d.avg(bottom[2].point, bottom[1].point)}, - {corners: [top[2], top[3], bottom[3], bottom[2]], center: Point3d.avg(bottom[3].point, bottom[2].point)}, - {corners: [top[3], top[0], bottom[0], bottom[3]], center: Point3d.avg(bottom[0].point, bottom[3].point)} - ]; - point.surfaces = surfaces; + /** + * Create a timeline visualization + * @param {HTMLElement} container + * @param {vis.DataSet | Array | google.visualization.DataTable} [items] + * @param {Object} [options] See Graph2d.setOptions for the available options. + * @constructor + * @extends Core + */ + function Graph2d (container, items, groups, options) { + // if the third element is options, the forth is groups (optionally); + if (!(Array.isArray(groups) || groups instanceof DataSet) && groups instanceof Object) { + var forthArgument = options; + options = groups; + groups = forthArgument; + } - // calculate the distance of each of the surface centers to the camera - for (j = 0; j < surfaces.length; j++) { - surface = surfaces[j]; - var transCenter = this._convertPointToTranslation(surface.center); - surface.dist = this.showPerspective ? transCenter.length() : -transCenter.z; - // TODO: this dept calculation doesn't work 100% of the cases due to perspective, - // but the current solution is fast/simple and works in 99.9% of all cases - // the issue is visible in example 14, with graph.setCameraPosition({horizontal: 2.97, vertical: 0.5, distance: 0.9}) - } + var me = this; + this.defaultOptions = { + start: null, + end: null, - // order the surfaces by their (translated) depth - surfaces.sort(function (a, b) { - var diff = b.dist - a.dist; - if (diff) return diff; + autoResize: true, - // if equal depth, sort the top surface last - if (a.corners === top) return 1; - if (b.corners === top) return -1; + orientation: 'bottom', + width: null, + height: null, + maxHeight: null, + minHeight: null + }; + this.options = util.deepExtend({}, this.defaultOptions); - // both are equal - return 0; - }); + // Create the DOM, props, and emitter + this._create(container); - // draw the ordered surfaces - ctx.lineWidth = 1; - ctx.strokeStyle = borderColor; - ctx.fillStyle = color; - // NOTE: we start at j=2 instead of j=0 as we don't need to draw the two surfaces at the backside - for (j = 2; j < surfaces.length; j++) { - surface = surfaces[j]; - corners = surface.corners; - ctx.beginPath(); - ctx.moveTo(corners[3].screen.x, corners[3].screen.y); - ctx.lineTo(corners[0].screen.x, corners[0].screen.y); - ctx.lineTo(corners[1].screen.x, corners[1].screen.y); - ctx.lineTo(corners[2].screen.x, corners[2].screen.y); - ctx.lineTo(corners[3].screen.x, corners[3].screen.y); - ctx.fill(); - ctx.stroke(); + // all components listed here will be repainted automatically + this.components = []; + + this.body = { + dom: this.dom, + domProps: this.props, + emitter: { + on: this.on.bind(this), + off: this.off.bind(this), + emit: this.emit.bind(this) + }, + hiddenDates: [], + util: { + snap: null, // will be specified after TimeAxis is created + toScreen: me._toScreen.bind(me), + toGlobalScreen: me._toGlobalScreen.bind(me), // this refers to the root.width + toTime: me._toTime.bind(me), + toGlobalTime : me._toGlobalTime.bind(me) } - } - }; + }; + // range + this.range = new Range(this.body); + this.components.push(this.range); + this.body.range = this.range; - /** - * Draw a line through all datapoints. - * This function can be used when the style is 'line' - */ - Graph3d.prototype._redrawDataLine = function() { - var canvas = this.frame.canvas, - ctx = canvas.getContext('2d'), - point, i; + // time axis + this.timeAxis = new TimeAxis(this.body); + this.components.push(this.timeAxis); + this.body.util.snap = this.timeAxis.snap.bind(this.timeAxis); - if (this.dataPoints === undefined || this.dataPoints.length <= 0) - return; // TODO: throw exception? + // current time bar + this.currentTime = new CurrentTime(this.body); + this.components.push(this.currentTime); - // calculate the translations of all points - for (i = 0; i < this.dataPoints.length; i++) { - var trans = this._convertPointToTranslation(this.dataPoints[i].point); - var screen = this._convertTranslationToScreen(trans); + // custom time bar + // Note: time bar will be attached in this.setOptions when selected + this.customTime = new CustomTime(this.body); + this.components.push(this.customTime); - this.dataPoints[i].trans = trans; - this.dataPoints[i].screen = screen; - } + // item set + this.linegraph = new LineGraph(this.body); + this.components.push(this.linegraph); - // start the line - if (this.dataPoints.length > 0) { - point = this.dataPoints[0]; + this.itemsData = null; // DataSet + this.groupsData = null; // DataSet - ctx.lineWidth = 1; // TODO: make customizable - ctx.strokeStyle = 'blue'; // TODO: make customizable - ctx.beginPath(); - ctx.moveTo(point.screen.x, point.screen.y); + // apply options + if (options) { + this.setOptions(options); } - // draw the datapoints as colored circles - for (i = 1; i < this.dataPoints.length; i++) { - point = this.dataPoints[i]; - ctx.lineTo(point.screen.x, point.screen.y); + // IMPORTANT: THIS HAPPENS BEFORE SET ITEMS! + if (groups) { + this.setGroups(groups); } - // finish the line - if (this.dataPoints.length > 0) { - ctx.stroke(); + // create itemset + if (items) { + this.setItems(items); } - }; - - /** - * Start a moving operation inside the provided parent element - * @param {Event} event The event that occurred (required for - * retrieving the mouse position) - */ - Graph3d.prototype._onMouseDown = function(event) { - event = event || window.event; - - // check if mouse is still down (may be up when focus is lost for example - // in an iframe) - if (this.leftButtonDown) { - this._onMouseUp(event); + else { + this.redraw(); } + } - // only react on left mouse button down - this.leftButtonDown = event.which ? (event.which === 1) : (event.button === 1); - if (!this.leftButtonDown && !this.touchDown) return; - - // get mouse position (different code for IE and all other browsers) - this.startMouseX = getMouseX(event); - this.startMouseY = getMouseY(event); - - this.startStart = new Date(this.start); - this.startEnd = new Date(this.end); - this.startArmRotation = this.camera.getArmRotation(); - - this.frame.style.cursor = 'move'; - - // add event listeners to handle moving the contents - // we store the function onmousemove and onmouseup in the graph, so we can - // remove the eventlisteners lateron in the function mouseUp() - var me = this; - this.onmousemove = function (event) {me._onMouseMove(event);}; - this.onmouseup = function (event) {me._onMouseUp(event);}; - util.addEventListener(document, 'mousemove', me.onmousemove); - util.addEventListener(document, 'mouseup', me.onmouseup); - util.preventDefault(event); - }; - + // Extend the functionality from Core + Graph2d.prototype = new Core(); /** - * Perform moving operating. - * This function activated from within the funcion Graph.mouseDown(). - * @param {Event} event Well, eehh, the event + * Set items + * @param {vis.DataSet | Array | google.visualization.DataTable | null} items */ - Graph3d.prototype._onMouseMove = function (event) { - event = event || window.event; - - // calculate change in mouse position - var diffX = parseFloat(getMouseX(event)) - this.startMouseX; - var diffY = parseFloat(getMouseY(event)) - this.startMouseY; - - var horizontalNew = this.startArmRotation.horizontal + diffX / 200; - var verticalNew = this.startArmRotation.vertical + diffY / 200; - - var snapAngle = 4; // degrees - var snapValue = Math.sin(snapAngle / 360 * 2 * Math.PI); - - // snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc... - // the -0.001 is to take care that the vertical axis is always drawn at the left front corner - if (Math.abs(Math.sin(horizontalNew)) < snapValue) { - horizontalNew = Math.round((horizontalNew / Math.PI)) * Math.PI - 0.001; - } - if (Math.abs(Math.cos(horizontalNew)) < snapValue) { - horizontalNew = (Math.round((horizontalNew/ Math.PI - 0.5)) + 0.5) * Math.PI - 0.001; - } + Graph2d.prototype.setItems = function(items) { + var initialLoad = (this.itemsData == null); - // snap vertically to nice angles - if (Math.abs(Math.sin(verticalNew)) < snapValue) { - verticalNew = Math.round((verticalNew / Math.PI)) * Math.PI; + // convert to type DataSet when needed + var newDataSet; + if (!items) { + newDataSet = null; } - if (Math.abs(Math.cos(verticalNew)) < snapValue) { - verticalNew = (Math.round((verticalNew/ Math.PI - 0.5)) + 0.5) * Math.PI; + else if (items instanceof DataSet || items instanceof DataView) { + newDataSet = items; + } + else { + // turn an array into a dataset + newDataSet = new DataSet(items, { + type: { + start: 'Date', + end: 'Date' + } + }); } - this.camera.setArmRotation(horizontalNew, verticalNew); - this.redraw(); + // set items + this.itemsData = newDataSet; + this.linegraph && this.linegraph.setItems(newDataSet); - // fire a cameraPositionChange event - var parameters = this.getCameraPosition(); - this.emit('cameraPositionChange', parameters); + if (initialLoad) { + if (this.options.start != undefined || this.options.end != undefined) { + var start = this.options.start != undefined ? this.options.start : null; + var end = this.options.end != undefined ? this.options.end : null; - util.preventDefault(event); + this.setWindow(start, end, {animate: false}); + } + else { + this.fit({animate: false}); + } + } }; - /** - * Stop moving operating. - * This function activated from within the funcion Graph.mouseDown(). - * @param {event} event The event + * Set groups + * @param {vis.DataSet | Array | google.visualization.DataTable} groups */ - Graph3d.prototype._onMouseUp = function (event) { - this.frame.style.cursor = 'auto'; - this.leftButtonDown = false; + Graph2d.prototype.setGroups = function(groups) { + // convert to type DataSet when needed + var newDataSet; + if (!groups) { + newDataSet = null; + } + else if (groups instanceof DataSet || groups instanceof DataView) { + newDataSet = groups; + } + else { + // turn an array into a dataset + newDataSet = new DataSet(groups); + } - // remove event listeners here - util.removeEventListener(document, 'mousemove', this.onmousemove); - util.removeEventListener(document, 'mouseup', this.onmouseup); - util.preventDefault(event); + this.groupsData = newDataSet; + this.linegraph.setGroups(newDataSet); }; /** - * After having moved the mouse, a tooltip should pop up when the mouse is resting on a data point - * @param {Event} event A mouse move event + * Returns an object containing an SVG element with the icon of the group (size determined by iconWidth and iconHeight), the label of the group (content) and the yAxisOrientation of the group (left or right). + * @param groupId + * @param width + * @param height */ - Graph3d.prototype._onTooltip = function (event) { - var delay = 300; // ms - var mouseX = getMouseX(event) - util.getAbsoluteLeft(this.frame); - var mouseY = getMouseY(event) - util.getAbsoluteTop(this.frame); - - if (!this.showTooltip) { - return; + Graph2d.prototype.getLegend = function(groupId, width, height) { + if (width === undefined) {width = 15;} + if (height === undefined) {height = 15;} + if (this.linegraph.groups[groupId] !== undefined) { + return this.linegraph.groups[groupId].getLegend(width,height); } - - if (this.tooltipTimeout) { - clearTimeout(this.tooltipTimeout); + else { + return "cannot find group:" + groupId; } + } - // (delayed) display of a tooltip only if no mouse button is down - if (this.leftButtonDown) { - this._hideTooltip(); - return; + /** + * This checks if the visible option of the supplied group (by ID) is true or false. + * @param groupId + * @returns {*} + */ + Graph2d.prototype.isGroupVisible = function(groupId) { + if (this.linegraph.groups[groupId] !== undefined) { + return (this.linegraph.groups[groupId].visible && (this.linegraph.options.groups.visibility[groupId] === undefined || this.linegraph.options.groups.visibility[groupId] == true)); } + else { + return false; + } + } - if (this.tooltip && this.tooltip.dataPoint) { - // tooltip is currently visible - var dataPoint = this._dataPointFromXY(mouseX, mouseY); - if (dataPoint !== this.tooltip.dataPoint) { - // datapoint changed - if (dataPoint) { - this._showTooltip(dataPoint); - } - else { - this._hideTooltip(); + + /** + * Get the data range of the item set. + * @returns {{min: Date, max: Date}} range A range with a start and end Date. + * When no minimum is found, min==null + * When no maximum is found, max==null + */ + Graph2d.prototype.getItemRange = function() { + var min = null; + var max = null; + + // calculate min from start filed + for (var groupId in this.linegraph.groups) { + if (this.linegraph.groups.hasOwnProperty(groupId)) { + if (this.linegraph.groups[groupId].visible == true) { + for (var i = 0; i < this.linegraph.groups[groupId].itemsData.length; i++) { + var item = this.linegraph.groups[groupId].itemsData[i]; + var value = util.convert(item.x, 'Date').valueOf(); + min = min == null ? value : min > value ? value : min; + max = max == null ? value : max < value ? value : max; + } } } } - else { - // tooltip is currently not visible - var me = this; - this.tooltipTimeout = setTimeout(function () { - me.tooltipTimeout = null; - // show a tooltip if we have a data point - var dataPoint = me._dataPointFromXY(mouseX, mouseY); - if (dataPoint) { - me._showTooltip(dataPoint); - } - }, delay); - } + return { + min: (min != null) ? new Date(min) : null, + max: (max != null) ? new Date(max) : null + }; }; - /** - * Event handler for touchstart event on mobile devices - */ - Graph3d.prototype._onTouchStart = function(event) { - this.touchDown = true; - var me = this; - this.ontouchmove = function (event) {me._onTouchMove(event);}; - this.ontouchend = function (event) {me._onTouchEnd(event);}; - util.addEventListener(document, 'touchmove', me.ontouchmove); - util.addEventListener(document, 'touchend', me.ontouchend); - this._onMouseDown(event); - }; + module.exports = Graph2d; - /** - * Event handler for touchmove event on mobile devices - */ - Graph3d.prototype._onTouchMove = function(event) { - this._onMouseMove(event); - }; + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { /** - * Event handler for touchend event on mobile devices + * Created by Alex on 10/3/2014. */ - Graph3d.prototype._onTouchEnd = function(event) { - this.touchDown = false; + var moment = __webpack_require__(43); - util.removeEventListener(document, 'touchmove', this.ontouchmove); - util.removeEventListener(document, 'touchend', this.ontouchend); - this._onMouseUp(event); + /** + * used in Core to convert the options into a volatile variable + * + * @param Core + */ + exports.convertHiddenOptions = function(body, hiddenDates) { + body.hiddenDates = []; + if (hiddenDates) { + if (Array.isArray(hiddenDates) == true) { + for (var i = 0; i < hiddenDates.length; i++) { + if (hiddenDates[i].repeat === undefined) { + var dateItem = {}; + dateItem.start = moment(hiddenDates[i].start).toDate().valueOf(); + dateItem.end = moment(hiddenDates[i].end).toDate().valueOf(); + body.hiddenDates.push(dateItem); + } + } + body.hiddenDates.sort(function (a, b) { + return a.start - b.start; + }); // sort by start time + } + } }; /** - * Event handler for mouse wheel event, used to zoom the graph - * Code from http://adomas.org/javascript-mouse-wheel/ - * @param {event} event The event + * create new entrees for the repeating hidden dates + * @param body + * @param hiddenDates */ - Graph3d.prototype._onWheel = function(event) { - if (!event) /* For IE. */ - event = window.event; + exports.updateHiddenDates = function (body, hiddenDates) { + if (hiddenDates && body.domProps.centerContainer.width !== undefined) { + exports.convertHiddenOptions(body, hiddenDates); - // retrieve delta - var delta = 0; - if (event.wheelDelta) { /* IE/Opera. */ - delta = event.wheelDelta/120; - } else if (event.detail) { /* Mozilla case. */ - // In Mozilla, sign of delta is different than in IE. - // Also, delta is multiple of 3. - delta = -event.detail/3; - } + var start = moment(body.range.start); + var end = moment(body.range.end); - // If delta is nonzero, handle it. - // Basically, delta is now positive if wheel was scrolled up, - // and negative, if wheel was scrolled down. - if (delta) { - var oldLength = this.camera.getArmLength(); - var newLength = oldLength * (1 - delta / 10); + var totalRange = (body.range.end - body.range.start); + var pixelTime = totalRange / body.domProps.centerContainer.width; - this.camera.setArmLength(newLength); - this.redraw(); + for (var i = 0; i < hiddenDates.length; i++) { + if (hiddenDates[i].repeat !== undefined) { + var startDate = moment(hiddenDates[i].start); + var endDate = moment(hiddenDates[i].end); - this._hideTooltip(); - } + if (startDate._d == "Invalid Date") { + throw new Error("Supplied start date is not valid: " + hiddenDates[i].start); + } + if (endDate._d == "Invalid Date") { + throw new Error("Supplied end date is not valid: " + hiddenDates[i].end); + } - // fire a cameraPositionChange event - var parameters = this.getCameraPosition(); - this.emit('cameraPositionChange', parameters); + var duration = endDate - startDate; + if (duration >= 4 * pixelTime) { - // Prevent default actions caused by mouse wheel. - // That might be ugly, but we handle scrolls somehow - // anyway, so don't bother here.. - util.preventDefault(event); - }; + var offset = 0; + var runUntil = end.clone(); + switch (hiddenDates[i].repeat) { + case "daily": // case of time + if (startDate.day() != endDate.day()) { + offset = 1; + } + startDate.dayOfYear(start.dayOfYear()); + startDate.year(start.year()); + startDate.subtract(7,'days'); - /** - * Test whether a point lies inside given 2D triangle - * @param {Point2d} point - * @param {Point2d[]} triangle - * @return {boolean} Returns true if given point lies inside or on the edge of the triangle - * @private - */ - Graph3d.prototype._insideTriangle = function (point, triangle) { - var a = triangle[0], - b = triangle[1], - c = triangle[2]; + endDate.dayOfYear(start.dayOfYear()); + endDate.year(start.year()); + endDate.subtract(7 - offset,'days'); - function sign (x) { - return x > 0 ? 1 : x < 0 ? -1 : 0; - } + runUntil.add(1, 'weeks'); + break; + case "weekly": + var dayOffset = endDate.diff(startDate,'days') + var day = startDate.day(); - var as = sign((b.x - a.x) * (point.y - a.y) - (b.y - a.y) * (point.x - a.x)); - var bs = sign((c.x - b.x) * (point.y - b.y) - (c.y - b.y) * (point.x - b.x)); - var cs = sign((a.x - c.x) * (point.y - c.y) - (a.y - c.y) * (point.x - c.x)); + // set the start date to the range.start + startDate.date(start.date()); + startDate.month(start.month()); + startDate.year(start.year()); + endDate = startDate.clone(); - // each of the three signs must be either equal to each other or zero - return (as == 0 || bs == 0 || as == bs) && - (bs == 0 || cs == 0 || bs == cs) && - (as == 0 || cs == 0 || as == cs); - }; + // force + startDate.day(day); + endDate.day(day); + endDate.add(dayOffset,'days'); - /** - * Find a data point close to given screen position (x, y) - * @param {Number} x - * @param {Number} y - * @return {Object | null} The closest data point or null if not close to any data point - * @private - */ - Graph3d.prototype._dataPointFromXY = function (x, y) { - var i, - distMax = 100, // px - dataPoint = null, - closestDataPoint = null, - closestDist = null, - center = new Point2d(x, y); + startDate.subtract(1,'weeks'); + endDate.subtract(1,'weeks'); - if (this.style === Graph3d.STYLE.BAR || - this.style === Graph3d.STYLE.BARCOLOR || - this.style === Graph3d.STYLE.BARSIZE) { - // the data points are ordered from far away to closest - for (i = this.dataPoints.length - 1; i >= 0; i--) { - dataPoint = this.dataPoints[i]; - var surfaces = dataPoint.surfaces; - if (surfaces) { - for (var s = surfaces.length - 1; s >= 0; s--) { - // split each surface in two triangles, and see if the center point is inside one of these - var surface = surfaces[s]; - var corners = surface.corners; - var triangle1 = [corners[0].screen, corners[1].screen, corners[2].screen]; - var triangle2 = [corners[2].screen, corners[3].screen, corners[0].screen]; - if (this._insideTriangle(center, triangle1) || - this._insideTriangle(center, triangle2)) { - // return immediately at the first hit - return dataPoint; + runUntil.add(1, 'weeks'); + break + case "monthly": + if (startDate.month() != endDate.month()) { + offset = 1; + } + startDate.month(start.month()); + startDate.year(start.year()); + startDate.subtract(1,'months'); + + endDate.month(start.month()); + endDate.year(start.year()); + endDate.subtract(1,'months'); + endDate.add(offset,'months'); + + runUntil.add(1, 'months'); + break; + case "yearly": + if (startDate.year() != endDate.year()) { + offset = 1; + } + startDate.year(start.year()); + startDate.subtract(1,'years'); + endDate.year(start.year()); + endDate.subtract(1,'years'); + endDate.add(offset,'years'); + + runUntil.add(1, 'years'); + break; + default: + console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:", hiddenDates[i].repeat); + return; + } + while (startDate < runUntil) { + body.hiddenDates.push({start: startDate.valueOf(), end: endDate.valueOf()}); + switch (hiddenDates[i].repeat) { + case "daily": + startDate.add(1, 'days'); + endDate.add(1, 'days'); + break; + case "weekly": + startDate.add(1, 'weeks'); + endDate.add(1, 'weeks'); + break + case "monthly": + startDate.add(1, 'months'); + endDate.add(1, 'months'); + break; + case "yearly": + startDate.add(1, 'y'); + endDate.add(1, 'y'); + break; + default: + console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:", hiddenDates[i].repeat); + return; + } } + body.hiddenDates.push({start: startDate.valueOf(), end: endDate.valueOf()}); } } } - } - else { - // find the closest data point, using distance to the center of the point on 2d screen - for (i = 0; i < this.dataPoints.length; i++) { - dataPoint = this.dataPoints[i]; - var point = dataPoint.screen; - if (point) { - var distX = Math.abs(x - point.x); - var distY = Math.abs(y - point.y); - var dist = Math.sqrt(distX * distX + distY * distY); - - if ((closestDist === null || dist < closestDist) && dist < distMax) { - closestDist = dist; - closestDataPoint = dataPoint; - } - } + // remove duplicates, merge where possible + exports.removeDuplicates(body); + // ensure the new positions are not on hidden dates + var startHidden = exports.isHidden(body.range.start, body.hiddenDates); + var endHidden = exports.isHidden(body.range.end,body.hiddenDates); + var rangeStart = body.range.start; + var rangeEnd = body.range.end; + if (startHidden.hidden == true) {rangeStart = body.range.startToFront == true ? startHidden.startDate - 1 : startHidden.endDate + 1;} + if (endHidden.hidden == true) {rangeEnd = body.range.endToFront == true ? endHidden.startDate - 1 : endHidden.endDate + 1;} + if (startHidden.hidden == true || endHidden.hidden == true) { + body.range._applyRange(rangeStart, rangeEnd); } } + } - return closestDataPoint; - }; /** - * Display a tooltip for given data point - * @param {Object} dataPoint - * @private + * remove duplicates from the hidden dates list. Duplicates are evil. They mess everything up. + * Scales with N^2 + * @param body */ - Graph3d.prototype._showTooltip = function (dataPoint) { - var content, line, dot; - - if (!this.tooltip) { - content = document.createElement('div'); - content.style.position = 'absolute'; - content.style.padding = '10px'; - content.style.border = '1px solid #4d4d4d'; - content.style.color = '#1a1a1a'; - content.style.background = 'rgba(255,255,255,0.7)'; - content.style.borderRadius = '2px'; - content.style.boxShadow = '5px 5px 10px rgba(128,128,128,0.5)'; - - line = document.createElement('div'); - line.style.position = 'absolute'; - line.style.height = '40px'; - line.style.width = '0'; - line.style.borderLeft = '1px solid #4d4d4d'; - - dot = document.createElement('div'); - dot.style.position = 'absolute'; - dot.style.height = '0'; - dot.style.width = '0'; - dot.style.border = '5px solid #4d4d4d'; - dot.style.borderRadius = '5px'; - - this.tooltip = { - dataPoint: null, - dom: { - content: content, - line: line, - dot: dot + exports.removeDuplicates = function(body) { + var hiddenDates = body.hiddenDates; + var safeDates = []; + for (var i = 0; i < hiddenDates.length; i++) { + for (var j = 0; j < hiddenDates.length; j++) { + if (i != j && hiddenDates[j].remove != true && hiddenDates[i].remove != true) { + // j inside i + if (hiddenDates[j].start >= hiddenDates[i].start && hiddenDates[j].end <= hiddenDates[i].end) { + hiddenDates[j].remove = true; + } + // j start inside i + else if (hiddenDates[j].start >= hiddenDates[i].start && hiddenDates[j].start <= hiddenDates[i].end) { + hiddenDates[i].end = hiddenDates[j].end; + hiddenDates[j].remove = true; + } + // j end inside i + else if (hiddenDates[j].end >= hiddenDates[i].start && hiddenDates[j].end <= hiddenDates[i].end) { + hiddenDates[i].start = hiddenDates[j].start; + hiddenDates[j].remove = true; + } } - }; - } - else { - content = this.tooltip.dom.content; - line = this.tooltip.dom.line; - dot = this.tooltip.dom.dot; - } - - this._hideTooltip(); - - this.tooltip.dataPoint = dataPoint; - if (typeof this.showTooltip === 'function') { - content.innerHTML = this.showTooltip(dataPoint.point); - } - else { - content.innerHTML = '' + - '' + - '' + - '' + - '
x:' + dataPoint.point.x + '
y:' + dataPoint.point.y + '
z:' + dataPoint.point.z + '
'; + } } - content.style.left = '0'; - content.style.top = '0'; - this.frame.appendChild(content); - this.frame.appendChild(line); - this.frame.appendChild(dot); - - // calculate sizes - var contentWidth = content.offsetWidth; - var contentHeight = content.offsetHeight; - var lineHeight = line.offsetHeight; - var dotWidth = dot.offsetWidth; - var dotHeight = dot.offsetHeight; - - var left = dataPoint.screen.x - contentWidth / 2; - left = Math.min(Math.max(left, 10), this.frame.clientWidth - 10 - contentWidth); + for (var i = 0; i < hiddenDates.length; i++) { + if (hiddenDates[i].remove !== true) { + safeDates.push(hiddenDates[i]); + } + } - line.style.left = dataPoint.screen.x + 'px'; - line.style.top = (dataPoint.screen.y - lineHeight) + 'px'; - content.style.left = left + 'px'; - content.style.top = (dataPoint.screen.y - lineHeight - contentHeight) + 'px'; - dot.style.left = (dataPoint.screen.x - dotWidth / 2) + 'px'; - dot.style.top = (dataPoint.screen.y - dotHeight / 2) + 'px'; - }; + body.hiddenDates = safeDates; + body.hiddenDates.sort(function (a, b) { + return a.start - b.start; + }); // sort by start time + } + + exports.printDates = function(dates) { + for (var i =0; i < dates.length; i++) { + console.log(i, new Date(dates[i].start),new Date(dates[i].end), dates[i].start, dates[i].end, dates[i].remove); + } + } /** - * Hide the tooltip when displayed - * @private + * Used in TimeStep to avoid the hidden times. + * @param timeStep + * @param previousTime */ - Graph3d.prototype._hideTooltip = function () { - if (this.tooltip) { - this.tooltip.dataPoint = null; - - for (var prop in this.tooltip.dom) { - if (this.tooltip.dom.hasOwnProperty(prop)) { - var elem = this.tooltip.dom[prop]; - if (elem && elem.parentNode) { - elem.parentNode.removeChild(elem); - } - } + exports.stepOverHiddenDates = function(timeStep, previousTime) { + var stepInHidden = false; + var currentValue = timeStep.current.valueOf(); + for (var i = 0; i < timeStep.hiddenDates.length; i++) { + var startDate = timeStep.hiddenDates[i].start; + var endDate = timeStep.hiddenDates[i].end; + if (currentValue >= startDate && currentValue < endDate) { + stepInHidden = true; + break; } } - }; - /**--------------------------------------------------------------------------**/ + if (stepInHidden == true && currentValue < timeStep._end.valueOf() && currentValue != previousTime) { + var prevValue = moment(previousTime); + var newValue = moment(endDate); + //check if the next step should be major + if (prevValue.year() != newValue.year()) {timeStep.switchedYear = true;} + else if (prevValue.month() != newValue.month()) {timeStep.switchedMonth = true;} + else if (prevValue.dayOfYear() != newValue.dayOfYear()) {timeStep.switchedDay = true;} + + timeStep.current = newValue.toDate(); + } + }; /** - * Get the horizontal mouse position from a mouse event - * @param {Event} event - * @return {Number} mouse x + * Used in TimeStep to avoid the hidden times. + * @param timeStep + * @param previousTime */ - getMouseX = function(event) { - if ('clientX' in event) return event.clientX; - return event.targetTouches[0] && event.targetTouches[0].clientX || 0; + exports.checkFirstStep = function(timeStep) { + var stepInHidden = false; + var currentValue = timeStep.current.valueOf(); + for (var i = 0; i < timeStep.hiddenDates.length; i++) { + var startDate = timeStep.hiddenDates[i].start; + var endDate = timeStep.hiddenDates[i].end; + if (currentValue >= startDate && currentValue < endDate) { + stepInHidden = true; + break; + } + } + + if (stepInHidden == true && currentValue <= timeStep._end.valueOf()) { + var newValue = moment(endDate); + timeStep.current = newValue.toDate(); + } }; /** - * Get the vertical mouse position from a mouse event - * @param {Event} event - * @return {Number} mouse y + * replaces the Core toScreen methods + * @param Core + * @param time + * @param width + * @returns {number} */ - getMouseY = function(event) { - if ('clientY' in event) return event.clientY; - return event.targetTouches[0] && event.targetTouches[0].clientY || 0; - }; + exports.toScreen = function(Core, time, width) { + var hidden = exports.isHidden(time, Core.body.hiddenDates) + if (hidden.hidden == true) { + time = hidden.startDate; + } - module.exports = Graph3d; + var duration = exports.getHiddenDurationBetween(Core.body.hiddenDates, Core.range.start, Core.range.end); + time = exports.correctTimeForHidden(Core.body.hiddenDates, Core.range, time); + var conversion = Core.range.conversion(width, duration); + return (time.valueOf() - conversion.offset) * conversion.scale; + }; -/***/ }, -/* 10 */ -/***/ function(module, exports, __webpack_require__) { - /** - * Expose `Emitter`. + * Replaces the core toTime methods + * @param body + * @param range + * @param x + * @param width + * @returns {Date} */ + exports.toTime = function(body, range, x, width) { + var hiddenDuration = exports.getHiddenDurationBetween(body.hiddenDates, range.start, range.end); + var totalDuration = range.end - range.start - hiddenDuration; + var partialDuration = totalDuration * x / width; + var accumulatedHiddenDuration = exports.getAccumulatedHiddenDuration(body.hiddenDates,range, partialDuration); + + var newTime = new Date(accumulatedHiddenDuration + partialDuration + range.start); + return newTime; + }; - module.exports = Emitter; /** - * Initialize a new `Emitter`. + * Support function * - * @api public + * @param hiddenDates + * @param range + * @returns {number} */ - - function Emitter(obj) { - if (obj) return mixin(obj); + exports.getHiddenDurationBetween = function(hiddenDates, start, end) { + var duration = 0; + for (var i = 0; i < hiddenDates.length; i++) { + var startDate = hiddenDates[i].start; + var endDate = hiddenDates[i].end; + // if time after the cutout, and the + if (startDate >= start && endDate < end) { + duration += endDate - startDate; + } + } + return duration; }; + /** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private + * Support function + * @param hiddenDates + * @param range + * @param time + * @returns {{duration: number, time: *, offset: number}} */ + exports.correctTimeForHidden = function(hiddenDates, range, time) { + time = moment(time).toDate().valueOf(); + time -= exports.getHiddenDurationBefore(hiddenDates,range,time); + return time; + }; - function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; + exports.getHiddenDurationBefore = function(hiddenDates, range, time) { + var timeOffset = 0; + time = moment(time).toDate().valueOf(); + + for (var i = 0; i < hiddenDates.length; i++) { + var startDate = hiddenDates[i].start; + var endDate = hiddenDates[i].end; + // if time after the cutout, and the + if (startDate >= range.start && endDate < range.end) { + if (time >= endDate) { + timeOffset += (endDate - startDate); + } + } } - return obj; + return timeOffset; } /** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public + * sum the duration from start to finish, including the hidden duration, + * until the required amount has been reached, return the accumulated hidden duration + * @param hiddenDates + * @param range + * @param time + * @returns {{duration: number, time: *, offset: number}} */ + exports.getAccumulatedHiddenDuration = function(hiddenDates, range, requiredDuration) { + var hiddenDuration = 0; + var duration = 0; + var previousPoint = range.start; + //exports.printDates(hiddenDates) + for (var i = 0; i < hiddenDates.length; i++) { + var startDate = hiddenDates[i].start; + var endDate = hiddenDates[i].end; + // if time after the cutout, and the + if (startDate >= range.start && endDate < range.end) { + duration += startDate - previousPoint; + previousPoint = endDate; + if (duration >= requiredDuration) { + break; + } + else { + hiddenDuration += endDate - startDate; + } + } + } - Emitter.prototype.on = - Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks[event] = this._callbacks[event] || []) - .push(fn); - return this; + return hiddenDuration; }; - /** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - - Emitter.prototype.once = function(event, fn){ - var self = this; - this._callbacks = this._callbacks || {}; - - function on() { - self.off(event, on); - fn.apply(this, arguments); - } - on.fn = fn; - this.on(event, on); - return this; - }; /** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public + * used to step over to either side of a hidden block. Correction is disabled on tablets, might be set to true + * @param hiddenDates + * @param time + * @param direction + * @param correctionEnabled + * @returns {*} */ - - Emitter.prototype.off = - Emitter.prototype.removeListener = - Emitter.prototype.removeAllListeners = - Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; + exports.snapAwayFromHidden = function(hiddenDates, time, direction, correctionEnabled) { + var isHidden = exports.isHidden(time, hiddenDates); + if (isHidden.hidden == true) { + if (direction < 0) { + if (correctionEnabled == true) { + return isHidden.startDate - (isHidden.endDate - time) - 1; + } + else { + return isHidden.startDate - 1; + } + } + else { + if (correctionEnabled == true) { + return isHidden.endDate + (time - isHidden.startDate) + 1; + } + else { + return isHidden.endDate + 1; + } + } } - - // specific event - var callbacks = this._callbacks[event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks[event]; - return this; + else { + return time; } - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; - }; + } + /** - * Emit `event` with the given args. + * Check if a time is hidden * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} + * @param time + * @param hiddenDates + * @returns {{hidden: boolean, startDate: Window.start, endDate: *}} */ + exports.isHidden = function(time, hiddenDates) { + for (var i = 0; i < hiddenDates.length; i++) { + var startDate = hiddenDates[i].start; + var endDate = hiddenDates[i].end; - Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks[event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); + if (time >= startDate && time < endDate) { // if the start is entering a hidden zone + return {hidden: true, startDate: startDate, endDate: endDate}; + break; } } + return {hidden: false, startDate: startDate, endDate: endDate}; + } - return this; - }; +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { /** - * Return array of callbacks for `event`. + * @constructor DataStep + * The class DataStep is an iterator for data for the lineGraph. You provide a start data point and an + * end data point. The class itself determines the best scale (step size) based on the + * provided start Date, end Date, and minimumStep. * - * @param {String} event - * @return {Array} - * @api public + * If minimumStep is provided, the step size is chosen as close as possible + * to the minimumStep but larger than minimumStep. If minimumStep is not + * provided, the scale is set to 1 DAY. + * The minimumStep should correspond with the onscreen size of about 6 characters + * + * Alternatively, you can set a scale by hand. + * After creation, you can initialize the class by executing first(). Then you + * can iterate from the start date to the end date via next(). You can check if + * the end date is reached with the function hasNext(). After each step, you can + * retrieve the current date via getCurrent(). + * The DataStep has scales ranging from milliseconds, seconds, minutes, hours, + * days, to years. + * + * Version: 1.2 + * + * @param {Date} [start] The start date, for example new Date(2010, 9, 21) + * or new Date(2010, 9, 21, 23, 45, 00) + * @param {Date} [end] The end date + * @param {Number} [minimumStep] Optional. Minimum step size in milliseconds */ + function DataStep(start, end, minimumStep, containerHeight, customRange) { + // variables + this.current = 0; - Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks[event] || []; - }; + this.autoScale = true; + this.stepIndex = 0; + this.step = 1; + this.scale = 1; - /** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ + this.marginStart; + this.marginEnd; + this.deadSpace = 0; - Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; - }; + this.majorSteps = [1, 2, 5, 10]; + this.minorSteps = [0.25, 0.5, 1, 2]; + this.setRange(start, end, minimumStep, containerHeight, customRange); + } -/***/ }, -/* 11 */ -/***/ function(module, exports, __webpack_require__) { - /** - * @prototype Point3d - * @param {Number} [x] - * @param {Number} [y] - * @param {Number} [z] - */ - function Point3d(x, y, z) { - this.x = x !== undefined ? x : 0; - this.y = y !== undefined ? y : 0; - this.z = z !== undefined ? z : 0; - }; /** - * Subtract the two provided points, returns a-b - * @param {Point3d} a - * @param {Point3d} b - * @return {Point3d} a-b + * Set a new range + * If minimumStep is provided, the step size is chosen as close as possible + * to the minimumStep but larger than minimumStep. If minimumStep is not + * provided, the scale is set to 1 DAY. + * The minimumStep should correspond with the onscreen size of about 6 characters + * @param {Number} [start] The start date and time. + * @param {Number} [end] The end date and time. + * @param {Number} [minimumStep] Optional. Minimum step size in milliseconds */ - Point3d.subtract = function(a, b) { - var sub = new Point3d(); - sub.x = a.x - b.x; - sub.y = a.y - b.y; - sub.z = a.z - b.z; - return sub; - }; + DataStep.prototype.setRange = function(start, end, minimumStep, containerHeight, customRange) { + this._start = customRange.min === undefined ? start : customRange.min; + this._end = customRange.max === undefined ? end : customRange.max; - /** - * Add the two provided points, returns a+b - * @param {Point3d} a - * @param {Point3d} b - * @return {Point3d} a+b - */ - Point3d.add = function(a, b) { - var sum = new Point3d(); - sum.x = a.x + b.x; - sum.y = a.y + b.y; - sum.z = a.z + b.z; - return sum; - }; + if (this._start == this._end) { + this._start -= 0.75; + this._end += 1; + } - /** - * Calculate the average of two 3d points - * @param {Point3d} a - * @param {Point3d} b - * @return {Point3d} The average, (a+b)/2 - */ - Point3d.avg = function(a, b) { - return new Point3d( - (a.x + b.x) / 2, - (a.y + b.y) / 2, - (a.z + b.z) / 2 - ); + if (this.autoScale) { + this.setMinimumStep(minimumStep, containerHeight); + } + this.setFirst(customRange); }; /** - * Calculate the cross product of the two provided points, returns axb - * Documentation: http://en.wikipedia.org/wiki/Cross_product - * @param {Point3d} a - * @param {Point3d} b - * @return {Point3d} cross product axb + * Automatically determine the scale that bests fits the provided minimum step + * @param {Number} [minimumStep] The minimum step size in milliseconds */ - Point3d.crossProduct = function(a, b) { - var crossproduct = new Point3d(); + DataStep.prototype.setMinimumStep = function(minimumStep, containerHeight) { + // round to floor + var size = this._end - this._start; + var safeSize = size * 1.2; + var minimumStepValue = minimumStep * (safeSize / containerHeight); + var orderOfMagnitude = Math.round(Math.log(safeSize)/Math.LN10); - crossproduct.x = a.y * b.z - a.z * b.y; - crossproduct.y = a.z * b.x - a.x * b.z; - crossproduct.z = a.x * b.y - a.y * b.x; + var minorStepIdx = -1; + var magnitudefactor = Math.pow(10,orderOfMagnitude); - return crossproduct; + var start = 0; + if (orderOfMagnitude < 0) { + start = orderOfMagnitude; + } + + var solutionFound = false; + for (var i = start; Math.abs(i) <= Math.abs(orderOfMagnitude); i++) { + magnitudefactor = Math.pow(10,i); + for (var j = 0; j < this.minorSteps.length; j++) { + var stepSize = magnitudefactor * this.minorSteps[j]; + if (stepSize >= minimumStepValue) { + solutionFound = true; + minorStepIdx = j; + break; + } + } + if (solutionFound == true) { + break; + } + } + this.stepIndex = minorStepIdx; + this.scale = magnitudefactor; + this.step = magnitudefactor * this.minorSteps[minorStepIdx]; }; + /** - * Rtrieve the length of the vector (or the distance from this point to the origin - * @return {Number} length + * Round the current date to the first minor date value + * This must be executed once when the current date is set to start Date */ - Point3d.prototype.length = function() { - return Math.sqrt( - this.x * this.x + - this.y * this.y + - this.z * this.z - ); - }; - - module.exports = Point3d; + DataStep.prototype.setFirst = function(customRange) { + if (customRange === undefined) { + customRange = {}; + } + var niceStart = customRange.min === undefined ? this._start - (this.scale * 2 * this.minorSteps[this.stepIndex]) : customRange.min; + var niceEnd = customRange.max === undefined ? this._end + (this.scale * this.minorSteps[this.stepIndex]) : customRange.max; + this.marginEnd = customRange.max === undefined ? this.roundToMinor(niceEnd) : customRange.max; + this.marginStart = customRange.min === undefined ? this.roundToMinor(niceStart) : customRange.min; + this.deadSpace = this.roundToMinor(niceEnd) - niceEnd + this.roundToMinor(niceStart) - niceStart; + this.marginRange = this.marginEnd - this.marginStart; -/***/ }, -/* 12 */ -/***/ function(module, exports, __webpack_require__) { + this.current = this.marginEnd; - /** - * @prototype Point2d - * @param {Number} [x] - * @param {Number} [y] - */ - Point2d = function (x, y) { - this.x = x !== undefined ? x : 0; - this.y = y !== undefined ? y : 0; }; - module.exports = Point2d; - - -/***/ }, -/* 13 */ -/***/ function(module, exports, __webpack_require__) { + DataStep.prototype.roundToMinor = function(value) { + var rounded = value - (value % (this.scale * this.minorSteps[this.stepIndex])); + if (value % (this.scale * this.minorSteps[this.stepIndex]) > 0.5 * (this.scale * this.minorSteps[this.stepIndex])) { + return rounded + (this.scale * this.minorSteps[this.stepIndex]); + } + else { + return rounded; + } + } - var Point3d = __webpack_require__(11); /** - * @class Camera - * The camera is mounted on a (virtual) camera arm. The camera arm can rotate - * The camera is always looking in the direction of the origin of the arm. - * This way, the camera always rotates around one fixed point, the location - * of the camera arm. - * - * Documentation: - * http://en.wikipedia.org/wiki/3D_projection + * Check if the there is a next step + * @return {boolean} true if the current date has not passed the end date */ - Camera = function () { - this.armLocation = new Point3d(); - this.armRotation = {}; - this.armRotation.horizontal = 0; - this.armRotation.vertical = 0; - this.armLength = 1.7; - - this.cameraLocation = new Point3d(); - this.cameraRotation = new Point3d(0.5*Math.PI, 0, 0); - - this.calculateCameraOrientation(); + DataStep.prototype.hasNext = function () { + return (this.current >= this.marginStart); }; /** - * Set the location (origin) of the arm - * @param {Number} x Normalized value of x - * @param {Number} y Normalized value of y - * @param {Number} z Normalized value of z + * Do the next step */ - Camera.prototype.setArmLocation = function(x, y, z) { - this.armLocation.x = x; - this.armLocation.y = y; - this.armLocation.z = z; + DataStep.prototype.next = function() { + var prev = this.current; + this.current -= this.step; - this.calculateCameraOrientation(); + // safety mechanism: if current time is still unchanged, move to the end + if (this.current == prev) { + this.current = this._end; + } }; /** - * Set the rotation of the camera arm - * @param {Number} horizontal The horizontal rotation, between 0 and 2*PI. - * Optional, can be left undefined. - * @param {Number} vertical The vertical rotation, between 0 and 0.5*PI - * if vertical=0.5*PI, the graph is shown from the - * top. Optional, can be left undefined. + * Do the next step */ - Camera.prototype.setArmRotation = function(horizontal, vertical) { - if (horizontal !== undefined) { - this.armRotation.horizontal = horizontal; - } - - if (vertical !== undefined) { - this.armRotation.vertical = vertical; - if (this.armRotation.vertical < 0) this.armRotation.vertical = 0; - if (this.armRotation.vertical > 0.5*Math.PI) this.armRotation.vertical = 0.5*Math.PI; - } - - if (horizontal !== undefined || vertical !== undefined) { - this.calculateCameraOrientation(); - } + DataStep.prototype.previous = function() { + this.current += this.step; + this.marginEnd += this.step; + this.marginRange = this.marginEnd - this.marginStart; }; - /** - * Retrieve the current arm rotation - * @return {object} An object with parameters horizontal and vertical - */ - Camera.prototype.getArmRotation = function() { - var rot = {}; - rot.horizontal = this.armRotation.horizontal; - rot.vertical = this.armRotation.vertical; - return rot; - }; /** - * Set the (normalized) length of the camera arm. - * @param {Number} length A length between 0.71 and 5.0 + * Get the current datetime + * @return {String} current The current date */ - Camera.prototype.setArmLength = function(length) { - if (length === undefined) - return; + DataStep.prototype.getCurrent = function() { + var toPrecision = '' + Number(this.current).toPrecision(5); + if (toPrecision.indexOf(",") != -1 || toPrecision.indexOf(".") != -1) { + for (var i = toPrecision.length-1; i > 0; i--) { + if (toPrecision[i] == "0") { + toPrecision = toPrecision.slice(0,i); + } + else if (toPrecision[i] == "." || toPrecision[i] == ",") { + toPrecision = toPrecision.slice(0,i); + break; + } + else{ + break; + } + } + } - this.armLength = length; + return toPrecision; + }; - // Radius must be larger than the corner of the graph, - // which has a distance of sqrt(0.5^2+0.5^2) = 0.71 from the center of the - // graph - if (this.armLength < 0.71) this.armLength = 0.71; - if (this.armLength > 5.0) this.armLength = 5.0; - this.calculateCameraOrientation(); - }; /** - * Retrieve the arm length - * @return {Number} length + * Snap a date to a rounded value. + * The snap intervals are dependent on the current scale and step. + * @param {Date} date the date to be snapped. + * @return {Date} snappedDate */ - Camera.prototype.getArmLength = function() { - return this.armLength; - }; + DataStep.prototype.snap = function(date) { - /** - * Retrieve the camera location - * @return {Point3d} cameraLocation - */ - Camera.prototype.getCameraLocation = function() { - return this.cameraLocation; }; /** - * Retrieve the camera rotation - * @return {Point3d} cameraRotation + * Check if the current value is a major value (for example when the step + * is DAY, a major value is each first day of the MONTH) + * @return {boolean} true if current date is major, else false. */ - Camera.prototype.getCameraRotation = function() { - return this.cameraRotation; + DataStep.prototype.isMajor = function() { + return (this.current % (this.scale * this.majorSteps[this.stepIndex]) == 0); }; - /** - * Calculate the location and rotation of the camera based on the - * position and orientation of the camera arm - */ - Camera.prototype.calculateCameraOrientation = function() { - // calculate location of the camera - this.cameraLocation.x = this.armLocation.x - this.armLength * Math.sin(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical); - this.cameraLocation.y = this.armLocation.y - this.armLength * Math.cos(this.armRotation.horizontal) * Math.cos(this.armRotation.vertical); - this.cameraLocation.z = this.armLocation.z + this.armLength * Math.sin(this.armRotation.vertical); - - // calculate rotation of the camera - this.cameraRotation.x = Math.PI/2 - this.armRotation.vertical; - this.cameraRotation.y = 0; - this.cameraRotation.z = -this.armRotation.horizontal; - }; + module.exports = DataStep; - module.exports = Camera; /***/ }, -/* 14 */ +/* 16 */ /***/ function(module, exports, __webpack_require__) { - var DataView = __webpack_require__(8); + var util = __webpack_require__(1); + var hammerUtil = __webpack_require__(46); + var moment = __webpack_require__(43); + var Component = __webpack_require__(19); + var DateUtil = __webpack_require__(14); /** - * @class Filter - * - * @param {DataSet} data The google data table - * @param {Number} column The index of the column to be filtered - * @param {Graph} graph The graph + * @constructor Range + * A Range controls a numeric range with a start and end value. + * The Range adjusts the range based on mouse events or programmatic changes, + * and triggers events when the range is changing or has been changed. + * @param {{dom: Object, domProps: Object, emitter: Emitter}} body + * @param {Object} [options] See description at Range.setOptions */ - function Filter (data, column, graph) { - this.data = data; - this.column = column; - this.graph = graph; // the parent graph - - this.index = undefined; - this.value = undefined; + function Range(body, options) { + var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0); + this.start = now.clone().add(-3, 'days').valueOf(); // Number + this.end = now.clone().add(4, 'days').valueOf(); // Number - // read all distinct values and select the first one - this.values = graph.getDistinctValues(data.get(), this.column); + this.body = body; + this.deltaDifference = 0; + this.scaleOffset = 0; + this.startToFront = false; + this.endToFront = true; - // sort both numeric and string values correctly - this.values.sort(function (a, b) { - return a > b ? 1 : a < b ? -1 : 0; - }); + // default options + this.defaultOptions = { + start: null, + end: null, + direction: 'horizontal', // 'horizontal' or 'vertical' + moveable: true, + zoomable: true, + min: null, + max: null, + zoomMin: 10, // milliseconds + zoomMax: 1000 * 60 * 60 * 24 * 365 * 10000 // milliseconds + }; + this.options = util.extend({}, this.defaultOptions); - if (this.values.length > 0) { - this.selectValue(0); - } + this.props = { + touch: {} + }; + this.animateTimer = null; - // create an array with the filtered datapoints. this will be loaded afterwards - this.dataPoints = []; + // drag listeners for dragging + this.body.emitter.on('dragstart', this._onDragStart.bind(this)); + this.body.emitter.on('drag', this._onDrag.bind(this)); + this.body.emitter.on('dragend', this._onDragEnd.bind(this)); - this.loaded = false; - this.onLoadCallback = undefined; + // ignore dragging when holding + this.body.emitter.on('hold', this._onHold.bind(this)); - if (graph.animationPreload) { - this.loaded = false; - this.loadInBackground(); - } - else { - this.loaded = true; - } - }; + // mouse wheel for zooming + this.body.emitter.on('mousewheel', this._onMouseWheel.bind(this)); + this.body.emitter.on('DOMMouseScroll', this._onMouseWheel.bind(this)); // For FF + // pinch to zoom + this.body.emitter.on('touch', this._onTouch.bind(this)); + this.body.emitter.on('pinch', this._onPinch.bind(this)); - /** - * Return the label - * @return {string} label - */ - Filter.prototype.isLoaded = function() { - return this.loaded; - }; + this.setOptions(options); + } + Range.prototype = new Component(); /** - * Return the loaded progress - * @return {Number} percentage between 0 and 100 + * Set options for the range controller + * @param {Object} options Available options: + * {Number | Date | String} start Start date for the range + * {Number | Date | String} end End date for the range + * {Number} min Minimum value for start + * {Number} max Maximum value for end + * {Number} zoomMin Set a minimum value for + * (end - start). + * {Number} zoomMax Set a maximum value for + * (end - start). + * {Boolean} moveable Enable moving of the range + * by dragging. True by default + * {Boolean} zoomable Enable zooming of the range + * by pinching/scrolling. True by default */ - Filter.prototype.getLoadedProgress = function() { - var len = this.values.length; + Range.prototype.setOptions = function (options) { + if (options) { + // copy the options that we know + var fields = ['direction', 'min', 'max', 'zoomMin', 'zoomMax', 'moveable', 'zoomable', 'activate', 'hiddenDates']; + util.selectiveExtend(fields, this.options, options); - var i = 0; - while (this.dataPoints[i]) { - i++; + if ('start' in options || 'end' in options) { + // apply a new range. both start and end are optional + this.setRange(options.start, options.end); + } } - - return Math.round(i / len * 100); }; - /** - * Return the label - * @return {string} label + * Test whether direction has a valid value + * @param {String} direction 'horizontal' or 'vertical' */ - Filter.prototype.getLabel = function() { - return this.graph.filterLabel; - }; - + function validateDirection (direction) { + if (direction != 'horizontal' && direction != 'vertical') { + throw new TypeError('Unknown direction "' + direction + '". ' + + 'Choose "horizontal" or "vertical".'); + } + } /** - * Return the columnIndex of the filter - * @return {Number} columnIndex + * Set a new start and end range + * @param {Date | Number | String} [start] + * @param {Date | Number | String} [end] + * @param {boolean | number} [animate=false] If true, the range is animated + * smoothly to the new window. + * If animate is a number, the + * number is taken as duration + * Default duration is 500 ms. + * */ - Filter.prototype.getColumn = function() { - return this.column; - }; + Range.prototype.setRange = function(start, end, animate) { + var _start = start != undefined ? util.convert(start, 'Date').valueOf() : null; + var _end = end != undefined ? util.convert(end, 'Date').valueOf() : null; + this._cancelAnimation(); - /** - * Return the currently selected value. Returns undefined if there is no selection - * @return {*} value - */ - Filter.prototype.getSelectedValue = function() { - if (this.index === undefined) - return undefined; + if (animate) { + var me = this; + var initStart = this.start; + var initEnd = this.end; + var duration = typeof animate === 'number' ? animate : 500; + var initTime = new Date().valueOf(); + var anyChanged = false; - return this.values[this.index]; + function next() { + if (!me.props.touch.dragging) { + var now = new Date().valueOf(); + var time = now - initTime; + var done = time > duration; + var s = (done || _start === null) ? _start : util.easeInOutQuad(time, initStart, _start, duration); + var e = (done || _end === null) ? _end : util.easeInOutQuad(time, initEnd, _end, duration); + + changed = me._applyRange(s, e); + DateUtil.updateHiddenDates(me.body, me.options.hiddenDates); + anyChanged = anyChanged || changed; + if (changed) { + me.body.emitter.emit('rangechange', {start: new Date(me.start), end: new Date(me.end)}); + } + + if (done) { + if (anyChanged) { + me.body.emitter.emit('rangechanged', {start: new Date(me.start), end: new Date(me.end)}); + } + } + else { + // animate with as high as possible frame rate, leave 20 ms in between + // each to prevent the browser from blocking + me.animateTimer = setTimeout(next, 20); + } + } + } + + return next(); + } + else { + var changed = this._applyRange(_start, _end); + DateUtil.updateHiddenDates(this.body, this.options.hiddenDates); + if (changed) { + var params = {start: new Date(this.start), end: new Date(this.end)}; + this.body.emitter.emit('rangechange', params); + this.body.emitter.emit('rangechanged', params); + } + } }; /** - * Retrieve all values of the filter - * @return {Array} values + * Stop an animation + * @private */ - Filter.prototype.getValues = function() { - return this.values; + Range.prototype._cancelAnimation = function () { + if (this.animateTimer) { + clearTimeout(this.animateTimer); + this.animateTimer = null; + } }; /** - * Retrieve one value of the filter - * @param {Number} index - * @return {*} value + * Set a new start and end range. This method is the same as setRange, but + * does not trigger a range change and range changed event, and it returns + * true when the range is changed + * @param {Number} [start] + * @param {Number} [end] + * @return {Boolean} changed + * @private */ - Filter.prototype.getValue = function(index) { - if (index >= this.values.length) - throw 'Error: index out of range'; + Range.prototype._applyRange = function(start, end) { + var newStart = (start != null) ? util.convert(start, 'Date').valueOf() : this.start, + newEnd = (end != null) ? util.convert(end, 'Date').valueOf() : this.end, + max = (this.options.max != null) ? util.convert(this.options.max, 'Date').valueOf() : null, + min = (this.options.min != null) ? util.convert(this.options.min, 'Date').valueOf() : null, + diff; - return this.values[index]; - }; + // check for valid number + if (isNaN(newStart) || newStart === null) { + throw new Error('Invalid start "' + start + '"'); + } + if (isNaN(newEnd) || newEnd === null) { + throw new Error('Invalid end "' + end + '"'); + } + // prevent start < end + if (newEnd < newStart) { + newEnd = newStart; + } - /** - * Retrieve the (filtered) dataPoints for the currently selected filter index - * @param {Number} [index] (optional) - * @return {Array} dataPoints - */ - Filter.prototype._getDataPoints = function(index) { - if (index === undefined) - index = this.index; + // prevent start < min + if (min !== null) { + if (newStart < min) { + diff = (min - newStart); + newStart += diff; + newEnd += diff; - if (index === undefined) - return []; + // prevent end > max + if (max != null) { + if (newEnd > max) { + newEnd = max; + } + } + } + } - var dataPoints; - if (this.dataPoints[index]) { - dataPoints = this.dataPoints[index]; + // prevent end > max + if (max !== null) { + if (newEnd > max) { + diff = (newEnd - max); + newStart -= diff; + newEnd -= diff; + + // prevent start < min + if (min != null) { + if (newStart < min) { + newStart = min; + } + } + } + } + + // prevent (end-start) < zoomMin + if (this.options.zoomMin !== null) { + var zoomMin = parseFloat(this.options.zoomMin); + if (zoomMin < 0) { + zoomMin = 0; + } + if ((newEnd - newStart) < zoomMin) { + if ((this.end - this.start) === zoomMin) { + // ignore this action, we are already zoomed to the minimum + newStart = this.start; + newEnd = this.end; + } + else { + // zoom to the minimum + diff = (zoomMin - (newEnd - newStart)); + newStart -= diff / 2; + newEnd += diff / 2; + } + } } - else { - var f = {}; - f.column = this.column; - f.value = this.values[index]; - var dataView = new DataView(this.data,{filter: function (item) {return (item[f.column] == f.value);}}).get(); - dataPoints = this.graph._getDataPoints(dataView); - - this.dataPoints[index] = dataPoints; + // prevent (end-start) > zoomMax + if (this.options.zoomMax !== null) { + var zoomMax = parseFloat(this.options.zoomMax); + if (zoomMax < 0) { + zoomMax = 0; + } + if ((newEnd - newStart) > zoomMax) { + if ((this.end - this.start) === zoomMax) { + // ignore this action, we are already zoomed to the maximum + newStart = this.start; + newEnd = this.end; + } + else { + // zoom to the maximum + diff = ((newEnd - newStart) - zoomMax); + newStart += diff / 2; + newEnd -= diff / 2; + } + } } - return dataPoints; - }; - + var changed = (this.start != newStart || this.end != newEnd); + this.start = newStart; + this.end = newEnd; + return changed; + }; /** - * Set a callback function when the filter is fully loaded. + * Retrieve the current range. + * @return {Object} An object with start and end properties */ - Filter.prototype.setOnLoadCallback = function(callback) { - this.onLoadCallback = callback; + Range.prototype.getRange = function() { + return { + start: this.start, + end: this.end + }; }; - /** - * Add a value to the list with available values for this filter - * No double entries will be created. - * @param {Number} index + * Calculate the conversion offset and scale for current range, based on + * the provided width + * @param {Number} width + * @returns {{offset: number, scale: number}} conversion */ - Filter.prototype.selectValue = function(index) { - if (index >= this.values.length) - throw 'Error: index out of range'; - - this.index = index; - this.value = this.values[index]; + Range.prototype.conversion = function (width, totalHidden) { + return Range.conversion(this.start, this.end, width, totalHidden); }; /** - * Load all filtered rows in the background one by one - * Start this method without providing an index! + * Static method to calculate the conversion offset and scale for a range, + * based on the provided start, end, and width + * @param {Number} start + * @param {Number} end + * @param {Number} width + * @returns {{offset: number, scale: number}} conversion */ - Filter.prototype.loadInBackground = function(index) { - if (index === undefined) - index = 0; - - var frame = this.graph.frame; - - if (index < this.values.length) { - var dataPointsTemp = this._getDataPoints(index); - //this.graph.redrawInfo(); // TODO: not neat - - // create a progress box - if (frame.progress === undefined) { - frame.progress = document.createElement('DIV'); - frame.progress.style.position = 'absolute'; - frame.progress.style.color = 'gray'; - frame.appendChild(frame.progress); + Range.conversion = function (start, end, width, totalHidden) { + if (totalHidden === undefined) { + totalHidden = 0; + } + if (width != 0 && (end - start != 0)) { + return { + offset: start, + scale: width / (end - start - totalHidden) } - var progress = this.getLoadedProgress(); - frame.progress.innerHTML = 'Loading animation... ' + progress + '%'; - // TODO: this is no nice solution... - frame.progress.style.bottom = 60 + 'px'; // TODO: use height of slider - frame.progress.style.left = 10 + 'px'; - - var me = this; - setTimeout(function() {me.loadInBackground(index+1);}, 10); - this.loaded = false; } else { - this.loaded = true; - - // remove the progress box - if (frame.progress !== undefined) { - frame.removeChild(frame.progress); - frame.progress = undefined; - } - - if (this.onLoadCallback) - this.onLoadCallback(); + return { + offset: 0, + scale: 1 + }; } }; - module.exports = Filter; + /** + * Start dragging horizontally or vertically + * @param {Event} event + * @private + */ + Range.prototype._onDragStart = function(event) { + this.deltaDifference = 0; + this.previousDelta = 0; + // only allow dragging when configured as movable + if (!this.options.moveable) return; + // refuse to drag when we where pinching to prevent the timeline make a jump + // when releasing the fingers in opposite order from the touch screen + if (!this.props.touch.allowDragging) return; -/***/ }, -/* 15 */ -/***/ function(module, exports, __webpack_require__) { + this.props.touch.start = this.start; + this.props.touch.end = this.end; + this.props.touch.dragging = true; - var util = __webpack_require__(1); + if (this.body.dom.root) { + this.body.dom.root.style.cursor = 'move'; + } + }; /** - * @constructor Slider - * - * An html slider control with start/stop/prev/next buttons - * @param {Element} container The element where the slider will be created - * @param {Object} options Available options: - * {boolean} visible If true (default) the - * slider is visible. + * Perform dragging operation + * @param {Event} event + * @private */ - function Slider(container, options) { - if (container === undefined) { - throw 'Error: No container element defined'; - } - this.container = container; - this.visible = (options && options.visible != undefined) ? options.visible : true; - - if (this.visible) { - this.frame = document.createElement('DIV'); - //this.frame.style.backgroundColor = '#E5E5E5'; - this.frame.style.width = '100%'; - this.frame.style.position = 'relative'; - this.container.appendChild(this.frame); + Range.prototype._onDrag = function (event) { + // only allow dragging when configured as movable + if (!this.options.moveable) return; + // refuse to drag when we where pinching to prevent the timeline make a jump + // when releasing the fingers in opposite order from the touch screen + if (!this.props.touch.allowDragging) return; - this.frame.prev = document.createElement('INPUT'); - this.frame.prev.type = 'BUTTON'; - this.frame.prev.value = 'Prev'; - this.frame.appendChild(this.frame.prev); + var direction = this.options.direction; + validateDirection(direction); - this.frame.play = document.createElement('INPUT'); - this.frame.play.type = 'BUTTON'; - this.frame.play.value = 'Play'; - this.frame.appendChild(this.frame.play); + var delta = (direction == 'horizontal') ? event.gesture.deltaX : event.gesture.deltaY; + delta -= this.deltaDifference; + var interval = (this.props.touch.end - this.props.touch.start); - this.frame.next = document.createElement('INPUT'); - this.frame.next.type = 'BUTTON'; - this.frame.next.value = 'Next'; - this.frame.appendChild(this.frame.next); + // normalize dragging speed if cutout is in between. + var duration = DateUtil.getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end); + interval -= duration; - this.frame.bar = document.createElement('INPUT'); - this.frame.bar.type = 'BUTTON'; - this.frame.bar.style.position = 'absolute'; - this.frame.bar.style.border = '1px solid red'; - this.frame.bar.style.width = '100px'; - this.frame.bar.style.height = '6px'; - this.frame.bar.style.borderRadius = '2px'; - this.frame.bar.style.MozBorderRadius = '2px'; - this.frame.bar.style.border = '1px solid #7F7F7F'; - this.frame.bar.style.backgroundColor = '#E5E5E5'; - this.frame.appendChild(this.frame.bar); + var width = (direction == 'horizontal') ? this.body.domProps.center.width : this.body.domProps.center.height; + var diffRange = -delta / width * interval; + var newStart = this.props.touch.start + diffRange; + var newEnd = this.props.touch.end + diffRange; - this.frame.slide = document.createElement('INPUT'); - this.frame.slide.type = 'BUTTON'; - this.frame.slide.style.margin = '0px'; - this.frame.slide.value = ' '; - this.frame.slide.style.position = 'relative'; - this.frame.slide.style.left = '-100px'; - this.frame.appendChild(this.frame.slide); - // create events - var me = this; - this.frame.slide.onmousedown = function (event) {me._onMouseDown(event);}; - this.frame.prev.onclick = function (event) {me.prev(event);}; - this.frame.play.onclick = function (event) {me.togglePlay(event);}; - this.frame.next.onclick = function (event) {me.next(event);}; + // snapping times away from hidden zones + var safeStart = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newStart, this.previousDelta-delta, true); + var safeEnd = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newEnd, this.previousDelta-delta, true); + if (safeStart != newStart || safeEnd != newEnd) { + this.deltaDifference += delta; + this.props.touch.start = safeStart; + this.props.touch.end = safeEnd; + this._onDrag(event); + return; } - this.onChangeCallback = undefined; - - this.values = []; - this.index = undefined; - - this.playTimeout = undefined; - this.playInterval = 1000; // milliseconds - this.playLoop = true; - } + this.previousDelta = delta; + this._applyRange(newStart, newEnd); - /** - * Select the previous index - */ - Slider.prototype.prev = function() { - var index = this.getIndex(); - if (index > 0) { - index--; - this.setIndex(index); - } + // fire a rangechange event + this.body.emitter.emit('rangechange', { + start: new Date(this.start), + end: new Date(this.end) + }); }; /** - * Select the next index + * Stop dragging operation + * @param {event} event + * @private */ - Slider.prototype.next = function() { - var index = this.getIndex(); - if (index < this.values.length - 1) { - index++; - this.setIndex(index); - } - }; + Range.prototype._onDragEnd = function (event) { + // only allow dragging when configured as movable + if (!this.options.moveable) return; - /** - * Select the next index - */ - Slider.prototype.playNext = function() { - var start = new Date(); + // refuse to drag when we where pinching to prevent the timeline make a jump + // when releasing the fingers in opposite order from the touch screen + if (!this.props.touch.allowDragging) return; - var index = this.getIndex(); - if (index < this.values.length - 1) { - index++; - this.setIndex(index); - } - else if (this.playLoop) { - // jump to the start - index = 0; - this.setIndex(index); + this.props.touch.dragging = false; + if (this.body.dom.root) { + this.body.dom.root.style.cursor = 'auto'; } - var end = new Date(); - var diff = (end - start); - - // calculate how much time it to to set the index and to execute the callback - // function. - var interval = Math.max(this.playInterval - diff, 0); - // document.title = diff // TODO: cleanup - - var me = this; - this.playTimeout = setTimeout(function() {me.playNext();}, interval); + // fire a rangechanged event + this.body.emitter.emit('rangechanged', { + start: new Date(this.start), + end: new Date(this.end) + }); }; /** - * Toggle start or stop playing + * Event handler for mouse wheel event, used to zoom + * Code from http://adomas.org/javascript-mouse-wheel/ + * @param {Event} event + * @private */ - Slider.prototype.togglePlay = function() { - if (this.playTimeout === undefined) { - this.play(); - } else { - this.stop(); - } - }; + Range.prototype._onMouseWheel = function(event) { + // only allow zooming when configured as zoomable and moveable + if (!(this.options.zoomable && this.options.moveable)) return; - /** - * Start playing - */ - Slider.prototype.play = function() { - // Test whether already playing - if (this.playTimeout) return; + // retrieve delta + var delta = 0; + if (event.wheelDelta) { /* IE/Opera. */ + delta = event.wheelDelta / 120; + } else if (event.detail) { /* Mozilla case. */ + // In Mozilla, sign of delta is different than in IE. + // Also, delta is multiple of 3. + delta = -event.detail / 3; + } - this.playNext(); + // If delta is nonzero, handle it. + // Basically, delta is now positive if wheel was scrolled up, + // and negative, if wheel was scrolled down. + if (delta) { + // perform the zoom action. Delta is normally 1 or -1 - if (this.frame) { - this.frame.play.value = 'Stop'; - } - }; + // adjust a negative delta such that zooming in with delta 0.1 + // equals zooming out with a delta -0.1 + var scale; + if (delta < 0) { + scale = 1 - (delta / 5); + } + else { + scale = 1 / (1 + (delta / 5)) ; + } - /** - * Stop playing - */ - Slider.prototype.stop = function() { - clearInterval(this.playTimeout); - this.playTimeout = undefined; + // calculate center, the date to zoom around + var gesture = hammerUtil.fakeGesture(this, event), + pointer = getPointer(gesture.center, this.body.dom.center), + pointerDate = this._pointerToDate(pointer); - if (this.frame) { - this.frame.play.value = 'Play'; + this.zoom(scale, pointerDate, delta); } - }; - /** - * Set a callback function which will be triggered when the value of the - * slider bar has changed. - */ - Slider.prototype.setOnChangeCallback = function(callback) { - this.onChangeCallback = callback; + // Prevent default actions caused by mouse wheel + // (else the page and timeline both zoom and scroll) + event.preventDefault(); }; /** - * Set the interval for playing the list - * @param {Number} interval The interval in milliseconds + * Start of a touch gesture + * @private */ - Slider.prototype.setPlayInterval = function(interval) { - this.playInterval = interval; + Range.prototype._onTouch = function (event) { + this.props.touch.start = this.start; + this.props.touch.end = this.end; + this.props.touch.allowDragging = true; + this.props.touch.center = null; + this.scaleOffset = 0; + this.deltaDifference = 0; }; /** - * Retrieve the current play interval - * @return {Number} interval The interval in milliseconds + * On start of a hold gesture + * @private */ - Slider.prototype.getPlayInterval = function(interval) { - return this.playInterval; + Range.prototype._onHold = function () { + this.props.touch.allowDragging = false; }; /** - * Set looping on or off - * @pararm {boolean} doLoop If true, the slider will jump to the start when - * the end is passed, and will jump to the end - * when the start is passed. + * Handle pinch event + * @param {Event} event + * @private */ - Slider.prototype.setPlayLoop = function(doLoop) { - this.playLoop = doLoop; - }; + Range.prototype._onPinch = function (event) { + // only allow zooming when configured as zoomable and moveable + if (!(this.options.zoomable && this.options.moveable)) return; + this.props.touch.allowDragging = false; - /** - * Execute the onchange callback function - */ - Slider.prototype.onChange = function() { - if (this.onChangeCallback !== undefined) { - this.onChangeCallback(); - } - }; + if (event.gesture.touches.length > 1) { + if (!this.props.touch.center) { + this.props.touch.center = getPointer(event.gesture.center, this.body.dom.center); + } - /** - * redraw the slider on the correct place - */ - Slider.prototype.redraw = function() { - if (this.frame) { - // resize the bar - this.frame.bar.style.top = (this.frame.clientHeight/2 - - this.frame.bar.offsetHeight/2) + 'px'; - this.frame.bar.style.width = (this.frame.clientWidth - - this.frame.prev.clientWidth - - this.frame.play.clientWidth - - this.frame.next.clientWidth - 30) + 'px'; + var scale = 1 / (event.gesture.scale + this.scaleOffset); + var center = this._pointerToDate(this.props.touch.center); - // position the slider button - var left = this.indexToLeft(this.index); - this.frame.slide.style.left = (left) + 'px'; - } - }; + var hiddenDuration = DateUtil.getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end); + var hiddenDurationBefore = DateUtil.getHiddenDurationBefore(this.body.hiddenDates, this, center); + var hiddenDurationAfter = hiddenDuration - hiddenDurationBefore; + // calculate new start and end + var newStart = (center-hiddenDurationBefore) + (this.start - (center-hiddenDurationBefore)) * scale; + var newEnd = (center+hiddenDurationAfter) + (this.end - (center+hiddenDurationAfter)) * scale; - /** - * Set the list with values for the slider - * @param {Array} values A javascript array with values (any type) - */ - Slider.prototype.setValues = function(values) { - this.values = values; + // snapping times away from hidden zones + this.startToFront = 1 - scale > 0 ? false : true; // used to do the right autocorrection with periodic hidden times + this.endToFront = scale - 1 > 0 ? false : true; // used to do the right autocorrection with periodic hidden times - if (this.values.length > 0) - this.setIndex(0); - else - this.index = undefined; - }; + var safeStart = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newStart, 1 - scale, true); + var safeEnd = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newEnd, scale - 1, true); + if (safeStart != newStart || safeEnd != newEnd) { + this.props.touch.start = safeStart; + this.props.touch.end = safeEnd; + this.scaleOffset = 1 - event.gesture.scale; + newStart = safeStart; + newEnd = safeEnd; + } - /** - * Select a value by its index - * @param {Number} index - */ - Slider.prototype.setIndex = function(index) { - if (index < this.values.length) { - this.index = index; + this.setRange(newStart, newEnd); - this.redraw(); - this.onChange(); - } - else { - throw 'Error: index out of range'; + this.startToFront = false; // revert to default + this.endToFront = true; // revert to default } }; /** - * retrieve the index of the currently selected vaue - * @return {Number} index - */ - Slider.prototype.getIndex = function() { - return this.index; - }; - - - /** - * retrieve the currently selected value - * @return {*} value - */ - Slider.prototype.get = function() { - return this.values[this.index]; - }; - - - Slider.prototype._onMouseDown = function(event) { - // only react on left mouse button down - var leftButtonDown = event.which ? (event.which === 1) : (event.button === 1); - if (!leftButtonDown) return; - - this.startClientX = event.clientX; - this.startSlideX = parseFloat(this.frame.slide.style.left); + * Helper function to calculate the center date for zooming + * @param {{x: Number, y: Number}} pointer + * @return {number} date + * @private + */ + Range.prototype._pointerToDate = function (pointer) { + var conversion; + var direction = this.options.direction; - this.frame.style.cursor = 'move'; + validateDirection(direction); - // add event listeners to handle moving the contents - // we store the function onmousemove and onmouseup in the graph, so we can - // remove the eventlisteners lateron in the function mouseUp() - var me = this; - this.onmousemove = function (event) {me._onMouseMove(event);}; - this.onmouseup = function (event) {me._onMouseUp(event);}; - util.addEventListener(document, 'mousemove', this.onmousemove); - util.addEventListener(document, 'mouseup', this.onmouseup); - util.preventDefault(event); + if (direction == 'horizontal') { + return this.body.util.toTime(pointer.x).valueOf(); + } + else { + var height = this.body.domProps.center.height; + conversion = this.conversion(height); + return pointer.y / conversion.scale + conversion.offset; + } }; + /** + * Get the pointer location relative to the location of the dom element + * @param {{pageX: Number, pageY: Number}} touch + * @param {Element} element HTML DOM element + * @return {{x: Number, y: Number}} pointer + * @private + */ + function getPointer (touch, element) { + return { + x: touch.pageX - util.getAbsoluteLeft(element), + y: touch.pageY - util.getAbsoluteTop(element) + }; + } - Slider.prototype.leftToIndex = function (left) { - var width = parseFloat(this.frame.bar.style.width) - - this.frame.slide.clientWidth - 10; - var x = left - 3; + /** + * Zoom the range the given scale in or out. Start and end date will + * be adjusted, and the timeline will be redrawn. You can optionally give a + * date around which to zoom. + * For example, try scale = 0.9 or 1.1 + * @param {Number} scale Scaling factor. Values above 1 will zoom out, + * values below 1 will zoom in. + * @param {Number} [center] Value representing a date around which will + * be zoomed. + */ + Range.prototype.zoom = function(scale, center, delta) { + // if centerDate is not provided, take it half between start Date and end Date + if (center == null) { + center = (this.start + this.end) / 2; + } - var index = Math.round(x / width * (this.values.length-1)); - if (index < 0) index = 0; - if (index > this.values.length-1) index = this.values.length-1; + var hiddenDuration = DateUtil.getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end); + var hiddenDurationBefore = DateUtil.getHiddenDurationBefore(this.body.hiddenDates, this, center); + var hiddenDurationAfter = hiddenDuration - hiddenDurationBefore; - return index; - }; + // calculate new start and end + var newStart = (center-hiddenDurationBefore) + (this.start - (center-hiddenDurationBefore)) * scale; + var newEnd = (center+hiddenDurationAfter) + (this.end - (center+hiddenDurationAfter)) * scale; - Slider.prototype.indexToLeft = function (index) { - var width = parseFloat(this.frame.bar.style.width) - - this.frame.slide.clientWidth - 10; + // snapping times away from hidden zones + this.startToFront = delta > 0 ? false : true; // used to do the right autocorrection with periodic hidden times + this.endToFront = -delta > 0 ? false : true; // used to do the right autocorrection with periodic hidden times + var safeStart = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newStart, delta, true); + var safeEnd = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newEnd, -delta, true); + if (safeStart != newStart || safeEnd != newEnd) { + newStart = safeStart; + newEnd = safeEnd; + } - var x = index / (this.values.length-1) * width; - var left = x + 3; + this.setRange(newStart, newEnd); - return left; + this.startToFront = false; // revert to default + this.endToFront = true; // revert to default }; - Slider.prototype._onMouseMove = function (event) { - var diff = event.clientX - this.startClientX; - var x = this.startSlideX + diff; + /** + * Move the range with a given delta to the left or right. Start and end + * value will be adjusted. For example, try delta = 0.1 or -0.1 + * @param {Number} delta Moving amount. Positive value will move right, + * negative value will move left + */ + Range.prototype.move = function(delta) { + // zoom start Date and end Date relative to the centerDate + var diff = (this.end - this.start); - var index = this.leftToIndex(x); + // apply new values + var newStart = this.start + diff * delta; + var newEnd = this.end + diff * delta; - this.setIndex(index); + // TODO: reckon with min and max range - util.preventDefault(); + this.start = newStart; + this.end = newEnd; }; + /** + * Move the range to a new center point + * @param {Number} moveTo New center point of the range + */ + Range.prototype.moveTo = function(moveTo) { + var center = (this.start + this.end) / 2; - Slider.prototype._onMouseUp = function (event) { - this.frame.style.cursor = 'auto'; + var diff = center - moveTo; - // remove event listeners - util.removeEventListener(document, 'mousemove', this.onmousemove); - util.removeEventListener(document, 'mouseup', this.onmouseup); + // calculate new start and end + var newStart = this.start - diff; + var newEnd = this.end - diff; - util.preventDefault(); + this.setRange(newStart, newEnd); }; - module.exports = Slider; + module.exports = Range; /***/ }, -/* 16 */ +/* 17 */ /***/ function(module, exports, __webpack_require__) { - /** - * @prototype StepNumber - * The class StepNumber is an iterator for Numbers. You provide a start and end - * value, and a best step size. StepNumber itself rounds to fixed values and - * a finds the step that best fits the provided step. - * - * If prettyStep is true, the step size is chosen as close as possible to the - * provided step, but being a round value like 1, 2, 5, 10, 20, 50, .... - * - * Example usage: - * var step = new StepNumber(0, 10, 2.5, true); - * step.start(); - * while (!step.end()) { - * alert(step.getCurrent()); - * step.next(); - * } - * - * Version: 1.0 - * - * @param {Number} start The start value - * @param {Number} end The end value - * @param {Number} step Optional. Step size. Must be a positive value. - * @param {boolean} prettyStep Optional. If true, the step size is rounded - * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...) - */ - function StepNumber(start, end, step, prettyStep) { - // set default values - this._start = 0; - this._end = 0; - this._step = 1; - this.prettyStep = true; - this.precision = 5; - - this._current = 0; - this.setRange(start, end, step, prettyStep); - }; + // Utility functions for ordering and stacking of items + var EPSILON = 0.001; // used when checking collisions, to prevent round-off errors /** - * Set a new range: start, end and step. - * - * @param {Number} start The start value - * @param {Number} end The end value - * @param {Number} step Optional. Step size. Must be a positive value. - * @param {boolean} prettyStep Optional. If true, the step size is rounded - * To a pretty step size (like 1, 2, 5, 10, 20, 50, ...) + * Order items by their start data + * @param {Item[]} items */ - StepNumber.prototype.setRange = function(start, end, step, prettyStep) { - this._start = start ? start : 0; - this._end = end ? end : 0; - - this.setStep(step, prettyStep); + exports.orderByStart = function(items) { + items.sort(function (a, b) { + return a.data.start - b.data.start; + }); }; /** - * Set a new step size - * @param {Number} step New step size. Must be a positive value - * @param {boolean} prettyStep Optional. If true, the provided step is rounded - * to a pretty step size (like 1, 2, 5, 10, 20, 50, ...) + * Order items by their end date. If they have no end date, their start date + * is used. + * @param {Item[]} items */ - StepNumber.prototype.setStep = function(step, prettyStep) { - if (step === undefined || step <= 0) - return; - - if (prettyStep !== undefined) - this.prettyStep = prettyStep; + exports.orderByEnd = function(items) { + items.sort(function (a, b) { + var aTime = ('end' in a.data) ? a.data.end : a.data.start, + bTime = ('end' in b.data) ? b.data.end : b.data.start; - if (this.prettyStep === true) - this._step = StepNumber.calculatePrettyStep(step); - else - this._step = step; + return aTime - bTime; + }); }; /** - * Calculate a nice step size, closest to the desired step size. - * Returns a value in one of the ranges 1*10^n, 2*10^n, or 5*10^n, where n is an - * integer Number. For example 1, 2, 5, 10, 20, 50, etc... - * @param {Number} step Desired step size - * @return {Number} Nice step size + * Adjust vertical positions of the items such that they don't overlap each + * other. + * @param {Item[]} items + * All visible items + * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin + * Margins between items and between items and the axis. + * @param {boolean} [force=false] + * If true, all items will be repositioned. If false (default), only + * items having a top===null will be re-stacked */ - StepNumber.calculatePrettyStep = function (step) { - var log10 = function (x) {return Math.log(x) / Math.LN10;}; - - // try three steps (multiple of 1, 2, or 5 - var step1 = Math.pow(10, Math.round(log10(step))), - step2 = 2 * Math.pow(10, Math.round(log10(step / 2))), - step5 = 5 * Math.pow(10, Math.round(log10(step / 5))); - - // choose the best step (closest to minimum step) - var prettyStep = step1; - if (Math.abs(step2 - step) <= Math.abs(prettyStep - step)) prettyStep = step2; - if (Math.abs(step5 - step) <= Math.abs(prettyStep - step)) prettyStep = step5; + exports.stack = function(items, margin, force) { + var i, iMax; - // for safety - if (prettyStep <= 0) { - prettyStep = 1; + if (force) { + // reset top position of all items + for (i = 0, iMax = items.length; i < iMax; i++) { + items[i].top = null; + } } - return prettyStep; - }; + // calculate new, non-overlapping positions + for (i = 0, iMax = items.length; i < iMax; i++) { + var item = items[i]; + if (item.stack && item.top === null) { + // initialize top position + item.top = margin.axis; - /** - * returns the current value of the step - * @return {Number} current value - */ - StepNumber.prototype.getCurrent = function () { - return parseFloat(this._current.toPrecision(this.precision)); - }; + do { + // TODO: optimize checking for overlap. when there is a gap without items, + // you only need to check for items from the next item on, not from zero + var collidingItem = null; + for (var j = 0, jj = items.length; j < jj; j++) { + var other = items[j]; + if (other.top !== null && other !== item && other.stack && exports.collision(item, other, margin.item)) { + collidingItem = other; + break; + } + } - /** - * returns the current step size - * @return {Number} current step size - */ - StepNumber.prototype.getStep = function () { - return this._step; + if (collidingItem != null) { + // There is a collision. Reposition the items above the colliding element + item.top = collidingItem.top + collidingItem.height + margin.item.vertical; + } + } while (collidingItem); + } + } }; - /** - * Set the current value to the largest value smaller than start, which - * is a multiple of the step size - */ - StepNumber.prototype.start = function() { - this._current = this._start - this._start % this._step; - }; /** - * Do a step, add the step size to the current value + * Adjust vertical positions of the items without stacking them + * @param {Item[]} items + * All visible items + * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin + * Margins between items and between items and the axis. */ - StepNumber.prototype.next = function () { - this._current += this._step; + exports.nostack = function(items, margin, subgroups) { + var i, iMax, newTop; + + // reset top position of all items + for (i = 0, iMax = items.length; i < iMax; i++) { + if (items[i].data.subgroup !== undefined) { + newTop = margin.axis; + for (var subgroup in subgroups) { + if (subgroups.hasOwnProperty(subgroup)) { + if (subgroups[subgroup].visible == true && subgroups[subgroup].index < subgroups[items[i].data.subgroup].index) { + newTop += subgroups[subgroup].height + margin.item.vertical; + } + } + } + items[i].top = newTop; + } + else { + items[i].top = margin.axis; + } + } }; /** - * Returns true whether the end is reached - * @return {boolean} True if the current value has passed the end value. + * Test if the two provided items collide + * The items must have parameters left, width, top, and height. + * @param {Item} a The first item + * @param {Item} b The second item + * @param {{horizontal: number, vertical: number}} margin + * An object containing a horizontal and vertical + * minimum required margin. + * @return {boolean} true if a and b collide, else false */ - StepNumber.prototype.end = function () { - return (this._current > this._end); + exports.collision = function(a, b, margin) { + return ((a.left - margin.horizontal + EPSILON) < (b.left + b.width) && + (a.left + a.width + margin.horizontal - EPSILON) > b.left && + (a.top - margin.vertical + EPSILON) < (b.top + b.height) && + (a.top + a.height + margin.vertical - EPSILON) > b.top); }; - module.exports = StepNumber; - /***/ }, -/* 17 */ +/* 18 */ /***/ function(module, exports, __webpack_require__) { - var Emitter = __webpack_require__(10); - var Hammer = __webpack_require__(18); - var util = __webpack_require__(1); - var DataSet = __webpack_require__(7); - var DataView = __webpack_require__(8); - var Range = __webpack_require__(20); - var Core = __webpack_require__(24); - var TimeAxis = __webpack_require__(25); - var CurrentTime = __webpack_require__(27); - var CustomTime = __webpack_require__(29); - var ItemSet = __webpack_require__(30); + var moment = __webpack_require__(43); + var DateUtil = __webpack_require__(14); /** - * Create a timeline visualization - * @param {HTMLElement} container - * @param {vis.DataSet | Array | google.visualization.DataTable} [items] - * @param {Object} [options] See Timeline.setOptions for the available options. - * @constructor - * @extends Core + * @constructor TimeStep + * The class TimeStep is an iterator for dates. You provide a start date and an + * end date. The class itself determines the best scale (step size) based on the + * provided start Date, end Date, and minimumStep. + * + * If minimumStep is provided, the step size is chosen as close as possible + * to the minimumStep but larger than minimumStep. If minimumStep is not + * provided, the scale is set to 1 DAY. + * The minimumStep should correspond with the onscreen size of about 6 characters + * + * Alternatively, you can set a scale by hand. + * After creation, you can initialize the class by executing first(). Then you + * can iterate from the start date to the end date via next(). You can check if + * the end date is reached with the function hasNext(). After each step, you can + * retrieve the current date via getCurrent(). + * The TimeStep has scales ranging from milliseconds, seconds, minutes, hours, + * days, to years. + * + * Version: 1.2 + * + * @param {Date} [start] The start date, for example new Date(2010, 9, 21) + * or new Date(2010, 9, 21, 23, 45, 00) + * @param {Date} [end] The end date + * @param {Number} [minimumStep] Optional. Minimum step size in milliseconds */ - function Timeline (container, items, groups, options) { - if (!(this instanceof Timeline)) { - throw new SyntaxError('Constructor must be called with the new operator'); - } - - // if the third element is options, the forth is groups (optionally); - if (!(Array.isArray(groups) || groups instanceof DataSet) && groups instanceof Object) { - var forthArgument = options; - options = groups; - groups = forthArgument; - } - - var me = this; - this.defaultOptions = { - start: null, - end: null, - - autoResize: true, - - orientation: 'bottom', - width: null, - height: null, - maxHeight: null, - minHeight: null - }; - this.options = util.deepExtend({}, this.defaultOptions); - - // Create the DOM, props, and emitter - this._create(container); - - // all components listed here will be repainted automatically - this.components = []; + function TimeStep(start, end, minimumStep, hiddenDates) { + // variables + this.current = new Date(); + this._start = new Date(); + this._end = new Date(); - this.body = { - dom: this.dom, - domProps: this.props, - emitter: { - on: this.on.bind(this), - off: this.off.bind(this), - emit: this.emit.bind(this) - }, - hiddenDates: [], - util: { - snap: null, // will be specified after TimeAxis is created - toScreen: me._toScreen.bind(me), - toGlobalScreen: me._toGlobalScreen.bind(me), // this refers to the root.width - toTime: me._toTime.bind(me), - toGlobalTime : me._toGlobalTime.bind(me) - } - }; + this.autoScale = true; + this.scale = TimeStep.SCALE.DAY; + this.step = 1; - // range - this.range = new Range(this.body); - this.components.push(this.range); - this.body.range = this.range; + // initialize the range + this.setRange(start, end, minimumStep); - // time axis - this.timeAxis = new TimeAxis(this.body); - this.components.push(this.timeAxis); - this.body.util.snap = this.timeAxis.snap.bind(this.timeAxis); + // hidden Dates options + this.switchedDay = false; + this.switchedMonth = false; + this.switchedYear = false; + this.hiddenDates = hiddenDates; + if (hiddenDates === undefined) { + this.hiddenDates = []; + } + } - // current time bar - this.currentTime = new CurrentTime(this.body); - this.components.push(this.currentTime); + /// enum scale + TimeStep.SCALE = { + MILLISECOND: 1, + SECOND: 2, + MINUTE: 3, + HOUR: 4, + DAY: 5, + WEEKDAY: 6, + MONTH: 7, + YEAR: 8 + }; - // custom time bar - // Note: time bar will be attached in this.setOptions when selected - this.customTime = new CustomTime(this.body); - this.components.push(this.customTime); - // item set - this.itemSet = new ItemSet(this.body); - this.components.push(this.itemSet); + /** + * Set a new range + * If minimumStep is provided, the step size is chosen as close as possible + * to the minimumStep but larger than minimumStep. If minimumStep is not + * provided, the scale is set to 1 DAY. + * The minimumStep should correspond with the onscreen size of about 6 characters + * @param {Date} [start] The start date and time. + * @param {Date} [end] The end date and time. + * @param {int} [minimumStep] Optional. Minimum step size in milliseconds + */ + TimeStep.prototype.setRange = function(start, end, minimumStep) { + if (!(start instanceof Date) || !(end instanceof Date)) { + throw "No legal start or end date in method setRange"; + } - this.itemsData = null; // DataSet - this.groupsData = null; // DataSet + this._start = (start != undefined) ? new Date(start.valueOf()) : new Date(); + this._end = (end != undefined) ? new Date(end.valueOf()) : new Date(); - // apply options - if (options) { - this.setOptions(options); + if (this.autoScale) { + this.setMinimumStep(minimumStep); } + }; - // IMPORTANT: THIS HAPPENS BEFORE SET ITEMS! - if (groups) { - this.setGroups(groups); + /** + * Set the range iterator to the start date. + */ + TimeStep.prototype.first = function() { + this.current = new Date(this._start.valueOf()); + this.roundToMinor(); + }; + + /** + * Round the current date to the first minor date value + * This must be executed once when the current date is set to start Date + */ + TimeStep.prototype.roundToMinor = function() { + // round to floor + // IMPORTANT: we have no breaks in this switch! (this is no bug) + //noinspection FallthroughInSwitchStatementJS + switch (this.scale) { + case TimeStep.SCALE.YEAR: + this.current.setFullYear(this.step * Math.floor(this.current.getFullYear() / this.step)); + this.current.setMonth(0); + case TimeStep.SCALE.MONTH: this.current.setDate(1); + case TimeStep.SCALE.DAY: // intentional fall through + case TimeStep.SCALE.WEEKDAY: this.current.setHours(0); + case TimeStep.SCALE.HOUR: this.current.setMinutes(0); + case TimeStep.SCALE.MINUTE: this.current.setSeconds(0); + case TimeStep.SCALE.SECOND: this.current.setMilliseconds(0); + //case TimeStep.SCALE.MILLISECOND: // nothing to do for milliseconds } - // create itemset - if (items) { - this.setItems(items); - } - else { - this.redraw(); + if (this.step != 1) { + // round down to the first minor value that is a multiple of the current step size + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND: this.current.setMilliseconds(this.current.getMilliseconds() - this.current.getMilliseconds() % this.step); break; + case TimeStep.SCALE.SECOND: this.current.setSeconds(this.current.getSeconds() - this.current.getSeconds() % this.step); break; + case TimeStep.SCALE.MINUTE: this.current.setMinutes(this.current.getMinutes() - this.current.getMinutes() % this.step); break; + case TimeStep.SCALE.HOUR: this.current.setHours(this.current.getHours() - this.current.getHours() % this.step); break; + case TimeStep.SCALE.WEEKDAY: // intentional fall through + case TimeStep.SCALE.DAY: this.current.setDate((this.current.getDate()-1) - (this.current.getDate()-1) % this.step + 1); break; + case TimeStep.SCALE.MONTH: this.current.setMonth(this.current.getMonth() - this.current.getMonth() % this.step); break; + case TimeStep.SCALE.YEAR: this.current.setFullYear(this.current.getFullYear() - this.current.getFullYear() % this.step); break; + default: break; + } } - } + }; - // Extend the functionality from Core - Timeline.prototype = new Core(); + /** + * Check if the there is a next step + * @return {boolean} true if the current date has not passed the end date + */ + TimeStep.prototype.hasNext = function () { + return (this.current.valueOf() <= this._end.valueOf()); + }; /** - * Set items - * @param {vis.DataSet | Array | google.visualization.DataTable | null} items + * Do the next step */ - Timeline.prototype.setItems = function(items) { - var initialLoad = (this.itemsData == null); + TimeStep.prototype.next = function() { + var prev = this.current.valueOf(); - // convert to type DataSet when needed - var newDataSet; - if (!items) { - newDataSet = null; - } - else if (items instanceof DataSet || items instanceof DataView) { - newDataSet = items; + // Two cases, needed to prevent issues with switching daylight savings + // (end of March and end of October) + if (this.current.getMonth() < 6) { + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND: + + this.current = new Date(this.current.valueOf() + this.step); break; + case TimeStep.SCALE.SECOND: this.current = new Date(this.current.valueOf() + this.step * 1000); break; + case TimeStep.SCALE.MINUTE: this.current = new Date(this.current.valueOf() + this.step * 1000 * 60); break; + case TimeStep.SCALE.HOUR: + this.current = new Date(this.current.valueOf() + this.step * 1000 * 60 * 60); + // in case of skipping an hour for daylight savings, adjust the hour again (else you get: 0h 5h 9h ... instead of 0h 4h 8h ...) + var h = this.current.getHours(); + this.current.setHours(h - (h % this.step)); + break; + case TimeStep.SCALE.WEEKDAY: // intentional fall through + case TimeStep.SCALE.DAY: this.current.setDate(this.current.getDate() + this.step); break; + case TimeStep.SCALE.MONTH: this.current.setMonth(this.current.getMonth() + this.step); break; + case TimeStep.SCALE.YEAR: this.current.setFullYear(this.current.getFullYear() + this.step); break; + default: break; + } } else { - // turn an array into a dataset - newDataSet = new DataSet(items, { - type: { - start: 'Date', - end: 'Date' - } - }); + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND: this.current = new Date(this.current.valueOf() + this.step); break; + case TimeStep.SCALE.SECOND: this.current.setSeconds(this.current.getSeconds() + this.step); break; + case TimeStep.SCALE.MINUTE: this.current.setMinutes(this.current.getMinutes() + this.step); break; + case TimeStep.SCALE.HOUR: this.current.setHours(this.current.getHours() + this.step); break; + case TimeStep.SCALE.WEEKDAY: // intentional fall through + case TimeStep.SCALE.DAY: this.current.setDate(this.current.getDate() + this.step); break; + case TimeStep.SCALE.MONTH: this.current.setMonth(this.current.getMonth() + this.step); break; + case TimeStep.SCALE.YEAR: this.current.setFullYear(this.current.getFullYear() + this.step); break; + default: break; + } } - // set items - this.itemsData = newDataSet; - this.itemSet && this.itemSet.setItems(newDataSet); - - if (initialLoad) { - if (this.options.start != undefined || this.options.end != undefined) { - var start = this.options.start != undefined ? this.options.start : null; - var end = this.options.end != undefined ? this.options.end : null; - - this.setWindow(start, end, {animate: false}); - } - else { - this.fit({animate: false}); + if (this.step != 1) { + // round down to the correct major value + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND: if(this.current.getMilliseconds() < this.step) this.current.setMilliseconds(0); break; + case TimeStep.SCALE.SECOND: if(this.current.getSeconds() < this.step) this.current.setSeconds(0); break; + case TimeStep.SCALE.MINUTE: if(this.current.getMinutes() < this.step) this.current.setMinutes(0); break; + case TimeStep.SCALE.HOUR: if(this.current.getHours() < this.step) this.current.setHours(0); break; + case TimeStep.SCALE.WEEKDAY: // intentional fall through + case TimeStep.SCALE.DAY: if(this.current.getDate() < this.step+1) this.current.setDate(1); break; + case TimeStep.SCALE.MONTH: if(this.current.getMonth() < this.step) this.current.setMonth(0); break; + case TimeStep.SCALE.YEAR: break; // nothing to do for year + default: break; } } + + // safety mechanism: if current time is still unchanged, move to the end + if (this.current.valueOf() == prev) { + this.current = new Date(this._end.valueOf()); + } + + DateUtil.stepOverHiddenDates(this, prev); }; + /** - * Set groups - * @param {vis.DataSet | Array | google.visualization.DataTable} groups + * Get the current datetime + * @return {Date} current The current date */ - Timeline.prototype.setGroups = function(groups) { - // convert to type DataSet when needed - var newDataSet; - if (!groups) { - newDataSet = null; - } - else if (groups instanceof DataSet || groups instanceof DataView) { - newDataSet = groups; - } - else { - // turn an array into a dataset - newDataSet = new DataSet(groups); - } - - this.groupsData = newDataSet; - this.itemSet.setGroups(newDataSet); + TimeStep.prototype.getCurrent = function() { + return this.current; }; /** - * Set selected items by their id. Replaces the current selection - * Unknown id's are silently ignored. - * @param {string[] | string} [ids] An array with zero or more id's of the items to be - * selected. If ids is an empty array, all items will be - * unselected. - * @param {Object} [options] Available options: - * `focus: boolean` - * If true, focus will be set to the selected item(s) - * `animate: boolean | number` - * If true (default), the range is animated - * smoothly to the new window. - * If a number, the number is taken as duration - * for the animation. Default duration is 500 ms. - * Only applicable when option focus is true. + * Set a custom scale. Autoscaling will be disabled. + * For example setScale(SCALE.MINUTES, 5) will result + * in minor steps of 5 minutes, and major steps of an hour. + * + * @param {TimeStep.SCALE} newScale + * A scale. Choose from SCALE.MILLISECOND, + * SCALE.SECOND, SCALE.MINUTE, SCALE.HOUR, + * SCALE.WEEKDAY, SCALE.DAY, SCALE.MONTH, + * SCALE.YEAR. + * @param {Number} newStep A step size, by default 1. Choose for + * example 1, 2, 5, or 10. */ - Timeline.prototype.setSelection = function(ids, options) { - this.itemSet && this.itemSet.setSelection(ids); + TimeStep.prototype.setScale = function(newScale, newStep) { + this.scale = newScale; - if (options && options.focus) { - this.focus(ids, options); + if (newStep > 0) { + this.step = newStep; } + + this.autoScale = false; }; /** - * Get the selected items by their id - * @return {Array} ids The ids of the selected items + * Enable or disable autoscaling + * @param {boolean} enable If true, autoascaling is set true */ - Timeline.prototype.getSelection = function() { - return this.itemSet && this.itemSet.getSelection() || []; + TimeStep.prototype.setAutoScale = function (enable) { + this.autoScale = enable; }; + /** - * Adjust the visible window such that the selected item (or multiple items) - * are centered on screen. - * @param {String | String[]} id An item id or array with item ids - * @param {Object} [options] Available options: - * `animate: boolean | number` - * If true (default), the range is animated - * smoothly to the new window. - * If a number, the number is taken as duration - * for the animation. Default duration is 500 ms. - * Only applicable when option focus is true + * Automatically determine the scale that bests fits the provided minimum step + * @param {Number} [minimumStep] The minimum step size in milliseconds */ - Timeline.prototype.focus = function(id, options) { - if (!this.itemsData || id == undefined) return; + TimeStep.prototype.setMinimumStep = function(minimumStep) { + if (minimumStep == undefined) { + return; + } - var ids = Array.isArray(id) ? id : [id]; + //var b = asc + ds; - // get the specified item(s) - var itemsData = this.itemsData.getDataSet().get(ids, { - type: { - start: 'Date', - end: 'Date' - } - }); + var stepYear = (1000 * 60 * 60 * 24 * 30 * 12); + var stepMonth = (1000 * 60 * 60 * 24 * 30); + var stepDay = (1000 * 60 * 60 * 24); + var stepHour = (1000 * 60 * 60); + var stepMinute = (1000 * 60); + var stepSecond = (1000); + var stepMillisecond= (1); - // calculate minimum start and maximum end of specified items - var start = null; - var end = null; - itemsData.forEach(function (itemData) { - var s = itemData.start.valueOf(); - var e = 'end' in itemData ? itemData.end.valueOf() : itemData.start.valueOf(); + // find the smallest step that is larger than the provided minimumStep + if (stepYear*1000 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 1000;} + if (stepYear*500 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 500;} + if (stepYear*100 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 100;} + if (stepYear*50 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 50;} + if (stepYear*10 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 10;} + if (stepYear*5 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 5;} + if (stepYear > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 1;} + if (stepMonth*3 > minimumStep) {this.scale = TimeStep.SCALE.MONTH; this.step = 3;} + if (stepMonth > minimumStep) {this.scale = TimeStep.SCALE.MONTH; this.step = 1;} + if (stepDay*5 > minimumStep) {this.scale = TimeStep.SCALE.DAY; this.step = 5;} + if (stepDay*2 > minimumStep) {this.scale = TimeStep.SCALE.DAY; this.step = 2;} + if (stepDay > minimumStep) {this.scale = TimeStep.SCALE.DAY; this.step = 1;} + if (stepDay/2 > minimumStep) {this.scale = TimeStep.SCALE.WEEKDAY; this.step = 1;} + if (stepHour*4 > minimumStep) {this.scale = TimeStep.SCALE.HOUR; this.step = 4;} + if (stepHour > minimumStep) {this.scale = TimeStep.SCALE.HOUR; this.step = 1;} + if (stepMinute*15 > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 15;} + if (stepMinute*10 > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 10;} + if (stepMinute*5 > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 5;} + if (stepMinute > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 1;} + if (stepSecond*15 > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 15;} + if (stepSecond*10 > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 10;} + if (stepSecond*5 > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 5;} + if (stepSecond > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 1;} + if (stepMillisecond*200 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 200;} + if (stepMillisecond*100 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 100;} + if (stepMillisecond*50 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 50;} + if (stepMillisecond*10 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 10;} + if (stepMillisecond*5 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 5;} + if (stepMillisecond > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 1;} + }; - if (start === null || s < start) { - start = s; - } + /** + * Snap a date to a rounded value. + * The snap intervals are dependent on the current scale and step. + * @param {Date} date the date to be snapped. + * @return {Date} snappedDate + */ + TimeStep.prototype.snap = function(date) { + var clone = new Date(date.valueOf()); - if (end === null || e > end) { - end = e; + if (this.scale == TimeStep.SCALE.YEAR) { + var year = clone.getFullYear() + Math.round(clone.getMonth() / 12); + clone.setFullYear(Math.round(year / this.step) * this.step); + clone.setMonth(0); + clone.setDate(0); + clone.setHours(0); + clone.setMinutes(0); + clone.setSeconds(0); + clone.setMilliseconds(0); + } + else if (this.scale == TimeStep.SCALE.MONTH) { + if (clone.getDate() > 15) { + clone.setDate(1); + clone.setMonth(clone.getMonth() + 1); + // important: first set Date to 1, after that change the month. + } + else { + clone.setDate(1); } - }); - - if (start !== null && end !== null) { - // calculate the new middle and interval for the window - var middle = (start + end) / 2; - var interval = Math.max((this.range.end - this.range.start), (end - start) * 1.1); - var animate = (options && options.animate !== undefined) ? options.animate : true; - this.range.setRange(middle - interval / 2, middle + interval / 2, animate); + clone.setHours(0); + clone.setMinutes(0); + clone.setSeconds(0); + clone.setMilliseconds(0); + } + else if (this.scale == TimeStep.SCALE.DAY) { + //noinspection FallthroughInSwitchStatementJS + switch (this.step) { + case 5: + case 2: + clone.setHours(Math.round(clone.getHours() / 24) * 24); break; + default: + clone.setHours(Math.round(clone.getHours() / 12) * 12); break; + } + clone.setMinutes(0); + clone.setSeconds(0); + clone.setMilliseconds(0); + } + else if (this.scale == TimeStep.SCALE.WEEKDAY) { + //noinspection FallthroughInSwitchStatementJS + switch (this.step) { + case 5: + case 2: + clone.setHours(Math.round(clone.getHours() / 12) * 12); break; + default: + clone.setHours(Math.round(clone.getHours() / 6) * 6); break; + } + clone.setMinutes(0); + clone.setSeconds(0); + clone.setMilliseconds(0); + } + else if (this.scale == TimeStep.SCALE.HOUR) { + switch (this.step) { + case 4: + clone.setMinutes(Math.round(clone.getMinutes() / 60) * 60); break; + default: + clone.setMinutes(Math.round(clone.getMinutes() / 30) * 30); break; + } + clone.setSeconds(0); + clone.setMilliseconds(0); + } else if (this.scale == TimeStep.SCALE.MINUTE) { + //noinspection FallthroughInSwitchStatementJS + switch (this.step) { + case 15: + case 10: + clone.setMinutes(Math.round(clone.getMinutes() / 5) * 5); + clone.setSeconds(0); + break; + case 5: + clone.setSeconds(Math.round(clone.getSeconds() / 60) * 60); break; + default: + clone.setSeconds(Math.round(clone.getSeconds() / 30) * 30); break; + } + clone.setMilliseconds(0); + } + else if (this.scale == TimeStep.SCALE.SECOND) { + //noinspection FallthroughInSwitchStatementJS + switch (this.step) { + case 15: + case 10: + clone.setSeconds(Math.round(clone.getSeconds() / 5) * 5); + clone.setMilliseconds(0); + break; + case 5: + clone.setMilliseconds(Math.round(clone.getMilliseconds() / 1000) * 1000); break; + default: + clone.setMilliseconds(Math.round(clone.getMilliseconds() / 500) * 500); break; + } + } + else if (this.scale == TimeStep.SCALE.MILLISECOND) { + var step = this.step > 5 ? this.step / 2 : 1; + clone.setMilliseconds(Math.round(clone.getMilliseconds() / step) * step); } + + return clone; }; /** - * Get the data range of the item set. - * @returns {{min: Date, max: Date}} range A range with a start and end Date. - * When no minimum is found, min==null - * When no maximum is found, max==null + * Check if the current value is a major value (for example when the step + * is DAY, a major value is each first day of the MONTH) + * @return {boolean} true if current date is major, else false. */ - Timeline.prototype.getItemRange = function() { - // calculate min from start filed - var dataset = this.itemsData.getDataSet(), - min = null, - max = null; - - if (dataset) { - // calculate the minimum value of the field 'start' - var minItem = dataset.min('start'); - min = minItem ? util.convert(minItem.start, 'Date').valueOf() : null; - // Note: we convert first to Date and then to number because else - // a conversion from ISODate to Number will fail - - // calculate maximum value of fields 'start' and 'end' - var maxStartItem = dataset.max('start'); - if (maxStartItem) { - max = util.convert(maxStartItem.start, 'Date').valueOf(); + TimeStep.prototype.isMajor = function() { + if (this.switchedYear == true) { + this.switchedYear = false; + switch (this.scale) { + case TimeStep.SCALE.YEAR: + case TimeStep.SCALE.MONTH: + case TimeStep.SCALE.WEEKDAY: + case TimeStep.SCALE.DAY: + case TimeStep.SCALE.HOUR: + case TimeStep.SCALE.MINUTE: + case TimeStep.SCALE.SECOND: + case TimeStep.SCALE.MILLISECOND: + return true; + default: + return false; } - var maxEndItem = dataset.max('end'); - if (maxEndItem) { - if (max == null) { - max = util.convert(maxEndItem.end, 'Date').valueOf(); - } - else { - max = Math.max(max, util.convert(maxEndItem.end, 'Date').valueOf()); - } + } + else if (this.switchedMonth == true) { + this.switchedMonth = false; + switch (this.scale) { + case TimeStep.SCALE.WEEKDAY: + case TimeStep.SCALE.DAY: + case TimeStep.SCALE.HOUR: + case TimeStep.SCALE.MINUTE: + case TimeStep.SCALE.SECOND: + case TimeStep.SCALE.MILLISECOND: + return true; + default: + return false; + } + } + else if (this.switchedDay == true) { + this.switchedDay = false; + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND: + case TimeStep.SCALE.SECOND: + case TimeStep.SCALE.MINUTE: + case TimeStep.SCALE.HOUR: + return true; + default: + return false; } } - return { - min: (min != null) ? new Date(min) : null, - max: (max != null) ? new Date(max) : null - }; + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND: + return (this.current.getMilliseconds() == 0); + case TimeStep.SCALE.SECOND: + return (this.current.getSeconds() == 0); + case TimeStep.SCALE.MINUTE: + return (this.current.getHours() == 0) && (this.current.getMinutes() == 0); + case TimeStep.SCALE.HOUR: + return (this.current.getHours() == 0); + case TimeStep.SCALE.WEEKDAY: // intentional fall through + case TimeStep.SCALE.DAY: + return (this.current.getDate() == 1); + case TimeStep.SCALE.MONTH: + return (this.current.getMonth() == 0); + case TimeStep.SCALE.YEAR: + return false; + default: + return false; + } }; - module.exports = Timeline; + /** + * Returns formatted text for the minor axislabel, depending on the current + * date and the scale. For example when scale is MINUTE, the current time is + * formatted as "hh:mm". + * @param {Date} [date] custom date. if not provided, current date is taken + */ + TimeStep.prototype.getLabelMinor = function(date) { + if (date == undefined) { + date = this.current; + } + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND: return moment(date).format('SSS'); + case TimeStep.SCALE.SECOND: return moment(date).format('s'); + case TimeStep.SCALE.MINUTE: return moment(date).format('HH:mm'); + case TimeStep.SCALE.HOUR: return moment(date).format('HH:mm'); + case TimeStep.SCALE.WEEKDAY: return moment(date).format('ddd D'); + case TimeStep.SCALE.DAY: return moment(date).format('D'); + case TimeStep.SCALE.MONTH: return moment(date).format('MMM'); + case TimeStep.SCALE.YEAR: return moment(date).format('YYYY'); + default: return ''; + } + }; -/***/ }, -/* 18 */ -/***/ function(module, exports, __webpack_require__) { - // Only load hammer.js when in a browser environment - // (loading hammer.js in a node.js environment gives errors) - if (typeof window !== 'undefined') { - module.exports = window['Hammer'] || __webpack_require__(19); - } - else { - module.exports = function () { - throw Error('hammer.js is only available in a browser, not in node.js.'); + /** + * Returns formatted text for the major axis label, depending on the current + * date and the scale. For example when scale is MINUTE, the major scale is + * hours, and the hour will be formatted as "hh". + * @param {Date} [date] custom date. if not provided, current date is taken + */ + TimeStep.prototype.getLabelMajor = function(date) { + if (date == undefined) { + date = this.current; } - } + + //noinspection FallthroughInSwitchStatementJS + switch (this.scale) { + case TimeStep.SCALE.MILLISECOND:return moment(date).format('HH:mm:ss'); + case TimeStep.SCALE.SECOND: return moment(date).format('D MMMM HH:mm'); + case TimeStep.SCALE.MINUTE: + case TimeStep.SCALE.HOUR: return moment(date).format('ddd D MMMM'); + case TimeStep.SCALE.WEEKDAY: + case TimeStep.SCALE.DAY: return moment(date).format('MMMM YYYY'); + case TimeStep.SCALE.MONTH: return moment(date).format('YYYY'); + case TimeStep.SCALE.YEAR: return ''; + default: return ''; + } + }; + + module.exports = TimeStep; /***/ }, /* 19 */ /***/ function(module, exports, __webpack_require__) { - var __WEBPACK_AMD_DEFINE_RESULT__;/*! Hammer.JS - v1.1.3 - 2014-05-20 - * http://eightmedia.github.io/hammer.js - * - * Copyright (c) 2014 Jorik Tangelder ; - * Licensed under the MIT license */ - - (function(window, undefined) { - 'use strict'; + /** + * Prototype for visual components + * @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} [body] + * @param {Object} [options] + */ + function Component (body, options) { + this.options = null; + this.props = null; + } /** - * @main - * @module hammer - * - * @class Hammer - * @static + * Set options for the component. The new options will be merged into the + * current options. + * @param {Object} options */ + Component.prototype.setOptions = function(options) { + if (options) { + util.extend(this.options, options); + } + }; /** - * Hammer, use this to create instances - * ```` - * var hammertime = new Hammer(myElement); - * ```` - * - * @method Hammer - * @param {HTMLElement} element - * @param {Object} [options={}] - * @return {Hammer.Instance} + * Repaint the component + * @return {boolean} Returns true if the component is resized */ - var Hammer = function Hammer(element, options) { - return new Hammer.Instance(element, options || {}); + Component.prototype.redraw = function() { + // should be implemented by the component + return false; }; /** - * version, as defined in package.json - * the value will be set at each build - * @property VERSION - * @final - * @type {String} + * Destroy the component. Cleanup DOM and event listeners */ - Hammer.VERSION = '1.1.3'; + Component.prototype.destroy = function() { + // should be implemented by the component + }; /** - * default settings. - * more settings are defined per gesture at `/gestures`. Each gesture can be disabled/enabled - * by setting it's name (like `swipe`) to false. - * You can set the defaults for all instances by changing this object before creating an instance. - * @example - * ```` - * Hammer.defaults.drag = false; - * Hammer.defaults.behavior.touchAction = 'pan-y'; - * delete Hammer.defaults.behavior.userSelect; - * ```` - * @property defaults - * @type {Object} + * Test whether the component is resized since the last time _isResized() was + * called. + * @return {Boolean} Returns true if the component is resized + * @protected */ - Hammer.defaults = { - /** - * this setting object adds styles and attributes to the element to prevent the browser from doing - * its native behavior. The css properties are auto prefixed for the browsers when needed. - * @property defaults.behavior - * @type {Object} - */ - behavior: { - /** - * Disables text selection to improve the dragging gesture. When the value is `none` it also sets - * `onselectstart=false` for IE on the element. Mainly for desktop browsers. - * @property defaults.behavior.userSelect - * @type {String} - * @default 'none' - */ - userSelect: 'none', + Component.prototype._isResized = function() { + var resized = (this.props._previousWidth !== this.props.width || + this.props._previousHeight !== this.props.height); - /** - * Specifies whether and how a given region can be manipulated by the user (for instance, by panning or zooming). - * Used by Chrome 35> and IE10>. By default this makes the element blocking any touch event. - * @property defaults.behavior.touchAction - * @type {String} - * @default: 'pan-y' - */ - touchAction: 'pan-y', + this.props._previousWidth = this.props.width; + this.props._previousHeight = this.props.height; - /** - * Disables the default callout shown when you touch and hold a touch target. - * On iOS, when you touch and hold a touch target such as a link, Safari displays - * a callout containing information about the link. This property allows you to disable that callout. - * @property defaults.behavior.touchCallout - * @type {String} - * @default 'none' - */ - touchCallout: 'none', + return resized; + }; - /** - * Specifies whether zooming is enabled. Used by IE10> - * @property defaults.behavior.contentZooming - * @type {String} - * @default 'none' - */ - contentZooming: 'none', + module.exports = Component; - /** - * Specifies that an entire element should be draggable instead of its contents. - * Mainly for desktop browsers. - * @property defaults.behavior.userDrag - * @type {String} - * @default 'none' - */ - userDrag: 'none', - /** - * Overrides the highlight color shown when the user taps a link or a JavaScript - * clickable element in Safari on iPhone. This property obeys the alpha value, if specified. - * - * If you don't specify an alpha value, Safari on iPhone applies a default alpha value - * to the color. To disable tap highlighting, set the alpha value to 0 (invisible). - * If you set the alpha value to 1.0 (opaque), the element is not visible when tapped. - * @property defaults.behavior.tapHighlightColor - * @type {String} - * @default 'rgba(0,0,0,0)' - */ - tapHighlightColor: 'rgba(0,0,0,0)' - } - }; +/***/ }, +/* 20 */ +/***/ function(module, exports, __webpack_require__) { - /** - * hammer document where the base events are added at - * @property DOCUMENT - * @type {HTMLElement} - * @default window.document - */ - Hammer.DOCUMENT = document; + var util = __webpack_require__(1); + var Component = __webpack_require__(19); + var moment = __webpack_require__(43); + var locales = __webpack_require__(47); /** - * detect support for pointer events - * @property HAS_POINTEREVENTS - * @type {Boolean} + * A current time bar + * @param {{range: Range, dom: Object, domProps: Object}} body + * @param {Object} [options] Available parameters: + * {Boolean} [showCurrentTime] + * @constructor CurrentTime + * @extends Component */ - Hammer.HAS_POINTEREVENTS = navigator.pointerEnabled || navigator.msPointerEnabled; + function CurrentTime (body, options) { + this.body = body; - /** - * detect support for touch events - * @property HAS_TOUCHEVENTS - * @type {Boolean} - */ - Hammer.HAS_TOUCHEVENTS = ('ontouchstart' in window); + // default options + this.defaultOptions = { + showCurrentTime: true, - /** - * detect mobile browsers - * @property IS_MOBILE - * @type {Boolean} - */ - Hammer.IS_MOBILE = /mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent); + locales: locales, + locale: 'en' + }; + this.options = util.extend({}, this.defaultOptions); + this.offset = 0; - /** - * detect if we want to support mouseevents at all - * @property NO_MOUSEEVENTS - * @type {Boolean} - */ - Hammer.NO_MOUSEEVENTS = (Hammer.HAS_TOUCHEVENTS && Hammer.IS_MOBILE) || Hammer.HAS_POINTEREVENTS; + this._create(); - /** - * interval in which Hammer recalculates current velocity/direction/angle in ms - * @property CALCULATE_INTERVAL - * @type {Number} - * @default 25 - */ - Hammer.CALCULATE_INTERVAL = 25; + this.setOptions(options); + } - /** - * eventtypes per touchevent (start, move, end) are filled by `Event.determineEventTypes` on `setup` - * the object contains the DOM event names per type (`EVENT_START`, `EVENT_MOVE`, `EVENT_END`) - * @property EVENT_TYPES - * @private - * @writeOnce - * @type {Object} - */ - var EVENT_TYPES = {}; + CurrentTime.prototype = new Component(); /** - * direction strings, for safe comparisons - * @property DIRECTION_DOWN|LEFT|UP|RIGHT - * @final - * @type {String} - * @default 'down' 'left' 'up' 'right' + * Create the HTML DOM for the current time bar + * @private */ - var DIRECTION_DOWN = Hammer.DIRECTION_DOWN = 'down'; - var DIRECTION_LEFT = Hammer.DIRECTION_LEFT = 'left'; - var DIRECTION_UP = Hammer.DIRECTION_UP = 'up'; - var DIRECTION_RIGHT = Hammer.DIRECTION_RIGHT = 'right'; + CurrentTime.prototype._create = function() { + var bar = document.createElement('div'); + bar.className = 'currenttime'; + bar.style.position = 'absolute'; + bar.style.top = '0px'; + bar.style.height = '100%'; - /** - * pointertype strings, for safe comparisons - * @property POINTER_MOUSE|TOUCH|PEN - * @final - * @type {String} - * @default 'mouse' 'touch' 'pen' - */ - var POINTER_MOUSE = Hammer.POINTER_MOUSE = 'mouse'; - var POINTER_TOUCH = Hammer.POINTER_TOUCH = 'touch'; - var POINTER_PEN = Hammer.POINTER_PEN = 'pen'; + this.bar = bar; + }; /** - * eventtypes - * @property EVENT_START|MOVE|END|RELEASE|TOUCH - * @final - * @type {String} - * @default 'start' 'change' 'move' 'end' 'release' 'touch' + * Destroy the CurrentTime bar */ - var EVENT_START = Hammer.EVENT_START = 'start'; - var EVENT_MOVE = Hammer.EVENT_MOVE = 'move'; - var EVENT_END = Hammer.EVENT_END = 'end'; - var EVENT_RELEASE = Hammer.EVENT_RELEASE = 'release'; - var EVENT_TOUCH = Hammer.EVENT_TOUCH = 'touch'; + CurrentTime.prototype.destroy = function () { + this.options.showCurrentTime = false; + this.redraw(); // will remove the bar from the DOM and stop refreshing - /** - * if the window events are set... - * @property READY - * @writeOnce - * @type {Boolean} - * @default false - */ - Hammer.READY = false; + this.body = null; + }; /** - * plugins namespace - * @property plugins - * @type {Object} + * Set options for the component. Options will be merged in current options. + * @param {Object} options Available parameters: + * {boolean} [showCurrentTime] */ - Hammer.plugins = Hammer.plugins || {}; + CurrentTime.prototype.setOptions = function(options) { + if (options) { + // copy all options that we know + util.selectiveExtend(['showCurrentTime', 'locale', 'locales'], this.options, options); + } + }; /** - * gestures namespace - * see `/gestures` for the definitions - * @property gestures - * @type {Object} + * Repaint the component + * @return {boolean} Returns true if the component is resized */ - Hammer.gestures = Hammer.gestures || {}; + CurrentTime.prototype.redraw = function() { + if (this.options.showCurrentTime) { + var parent = this.body.dom.backgroundVertical; + if (this.bar.parentNode != parent) { + // attach to the dom + if (this.bar.parentNode) { + this.bar.parentNode.removeChild(this.bar); + } + parent.appendChild(this.bar); - /** - * setup events to detect gestures on the document - * this function is called when creating an new instance - * @private - */ - function setup() { - if(Hammer.READY) { - return; + this.start(); } - // find what eventtypes we add listeners to - Event.determineEventTypes(); + var now = new Date(new Date().valueOf() + this.offset); + var x = this.body.util.toScreen(now); - // Register all gestures inside Hammer.gestures - Utils.each(Hammer.gestures, function(gesture) { - Detection.register(gesture); - }); + var locale = this.options.locales[this.options.locale]; + var title = locale.current + ' ' + locale.time + ': ' + moment(now).format('dddd, MMMM Do YYYY, H:mm:ss'); + title = title.charAt(0).toUpperCase() + title.substring(1); - // Add touch events on the document - Event.onTouch(Hammer.DOCUMENT, EVENT_MOVE, Detection.detect); - Event.onTouch(Hammer.DOCUMENT, EVENT_END, Detection.detect); + this.bar.style.left = x + 'px'; + this.bar.title = title; + } + else { + // remove the line from the DOM + if (this.bar.parentNode) { + this.bar.parentNode.removeChild(this.bar); + } + this.stop(); + } - // Hammer is ready...! - Hammer.READY = true; - } + return false; + }; /** - * @module hammer - * - * @class Utils - * @static + * Start auto refreshing the current time bar */ - var Utils = Hammer.utils = { - /** - * extend method, could also be used for cloning when `dest` is an empty object. - * changes the dest object - * @method extend - * @param {Object} dest - * @param {Object} src - * @param {Boolean} [merge=false] do a merge - * @return {Object} dest - */ - extend: function extend(dest, src, merge) { - for(var key in src) { - if(!src.hasOwnProperty(key) || (dest[key] !== undefined && merge)) { - continue; - } - dest[key] = src[key]; - } - return dest; - }, - - /** - * simple addEventListener wrapper - * @method on - * @param {HTMLElement} element - * @param {String} type - * @param {Function} handler - */ - on: function on(element, type, handler) { - element.addEventListener(type, handler, false); - }, - - /** - * simple removeEventListener wrapper - * @method off - * @param {HTMLElement} element - * @param {String} type - * @param {Function} handler - */ - off: function off(element, type, handler) { - element.removeEventListener(type, handler, false); - }, - - /** - * forEach over arrays and objects - * @method each - * @param {Object|Array} obj - * @param {Function} iterator - * @param {any} iterator.item - * @param {Number} iterator.index - * @param {Object|Array} iterator.obj the source object - * @param {Object} context value to use as `this` in the iterator - */ - each: function each(obj, iterator, context) { - var i, len; - - // native forEach on arrays - if('forEach' in obj) { - obj.forEach(iterator, context); - // arrays - } else if(obj.length !== undefined) { - for(i = 0, len = obj.length; i < len; i++) { - if(iterator.call(context, obj[i], i, obj) === false) { - return; - } - } - // objects - } else { - for(i in obj) { - if(obj.hasOwnProperty(i) && - iterator.call(context, obj[i], i, obj) === false) { - return; - } - } - } - }, - - /** - * find if a string contains the string using indexOf - * @method inStr - * @param {String} src - * @param {String} find - * @return {Boolean} found - */ - inStr: function inStr(src, find) { - return src.indexOf(find) > -1; - }, - - /** - * find if a array contains the object using indexOf or a simple polyfill - * @method inArray - * @param {String} src - * @param {String} find - * @return {Boolean|Number} false when not found, or the index - */ - inArray: function inArray(src, find) { - if(src.indexOf) { - var index = src.indexOf(find); - return (index === -1) ? false : index; - } else { - for(var i = 0, len = src.length; i < len; i++) { - if(src[i] === find) { - return i; - } - } - return false; - } - }, - - /** - * convert an array-like object (`arguments`, `touchlist`) to an array - * @method toArray - * @param {Object} obj - * @return {Array} - */ - toArray: function toArray(obj) { - return Array.prototype.slice.call(obj, 0); - }, - - /** - * find if a node is in the given parent - * @method hasParent - * @param {HTMLElement} node - * @param {HTMLElement} parent - * @return {Boolean} found - */ - hasParent: function hasParent(node, parent) { - while(node) { - if(node == parent) { - return true; - } - node = node.parentNode; - } - return false; - }, - - /** - * get the center of all the touches - * @method getCenter - * @param {Array} touches - * @return {Object} center contains `pageX`, `pageY`, `clientX` and `clientY` properties - */ - getCenter: function getCenter(touches) { - var pageX = [], - pageY = [], - clientX = [], - clientY = [], - min = Math.min, - max = Math.max; - - // no need to loop when only one touch - if(touches.length === 1) { - return { - pageX: touches[0].pageX, - pageY: touches[0].pageY, - clientX: touches[0].clientX, - clientY: touches[0].clientY - }; - } + CurrentTime.prototype.start = function() { + var me = this; - Utils.each(touches, function(touch) { - pageX.push(touch.pageX); - pageY.push(touch.pageY); - clientX.push(touch.clientX); - clientY.push(touch.clientY); - }); + function update () { + me.stop(); - return { - pageX: (min.apply(Math, pageX) + max.apply(Math, pageX)) / 2, - pageY: (min.apply(Math, pageY) + max.apply(Math, pageY)) / 2, - clientX: (min.apply(Math, clientX) + max.apply(Math, clientX)) / 2, - clientY: (min.apply(Math, clientY) + max.apply(Math, clientY)) / 2 - }; - }, + // determine interval to refresh + var scale = me.body.range.conversion(me.body.domProps.center.width).scale; + var interval = 1 / scale / 10; + if (interval < 30) interval = 30; + if (interval > 1000) interval = 1000; - /** - * calculate the velocity between two points. unit is in px per ms. - * @method getVelocity - * @param {Number} deltaTime - * @param {Number} deltaX - * @param {Number} deltaY - * @return {Object} velocity `x` and `y` - */ - getVelocity: function getVelocity(deltaTime, deltaX, deltaY) { - return { - x: Math.abs(deltaX / deltaTime) || 0, - y: Math.abs(deltaY / deltaTime) || 0 - }; - }, + me.redraw(); - /** - * calculate the angle between two coordinates - * @method getAngle - * @param {Touch} touch1 - * @param {Touch} touch2 - * @return {Number} angle - */ - getAngle: function getAngle(touch1, touch2) { - var x = touch2.clientX - touch1.clientX, - y = touch2.clientY - touch1.clientY; + // start a timer to adjust for the new time + me.currentTimeTimer = setTimeout(update, interval); + } - return Math.atan2(y, x) * 180 / Math.PI; - }, + update(); + }; - /** - * do a small comparision to get the direction between two touches. - * @method getDirection - * @param {Touch} touch1 - * @param {Touch} touch2 - * @return {String} direction matches `DIRECTION_LEFT|RIGHT|UP|DOWN` - */ - getDirection: function getDirection(touch1, touch2) { - var x = Math.abs(touch1.clientX - touch2.clientX), - y = Math.abs(touch1.clientY - touch2.clientY); + /** + * Stop auto refreshing the current time bar + */ + CurrentTime.prototype.stop = function() { + if (this.currentTimeTimer !== undefined) { + clearTimeout(this.currentTimeTimer); + delete this.currentTimeTimer; + } + }; - if(x >= y) { - return touch1.clientX - touch2.clientX > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; - } - return touch1.clientY - touch2.clientY > 0 ? DIRECTION_UP : DIRECTION_DOWN; - }, + /** + * Set a current time. This can be used for example to ensure that a client's + * time is synchronized with a shared server time. + * @param {Date | String | Number} time A Date, unix timestamp, or + * ISO date string. + */ + CurrentTime.prototype.setCurrentTime = function(time) { + var t = util.convert(time, 'Date').valueOf(); + var now = new Date().valueOf(); + this.offset = t - now; + this.redraw(); + }; - /** - * calculate the distance between two touches - * @method getDistance - * @param {Touch}touch1 - * @param {Touch} touch2 - * @return {Number} distance - */ - getDistance: function getDistance(touch1, touch2) { - var x = touch2.clientX - touch1.clientX, - y = touch2.clientY - touch1.clientY; + /** + * Get the current time. + * @return {Date} Returns the current time. + */ + CurrentTime.prototype.getCurrentTime = function() { + return new Date(new Date().valueOf() + this.offset); + }; - return Math.sqrt((x * x) + (y * y)); - }, + module.exports = CurrentTime; - /** - * calculate the scale factor between two touchLists - * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out - * @method getScale - * @param {Array} start array of touches - * @param {Array} end array of touches - * @return {Number} scale - */ - getScale: function getScale(start, end) { - // need two fingers... - if(start.length >= 2 && end.length >= 2) { - return this.getDistance(end[0], end[1]) / this.getDistance(start[0], start[1]); - } - return 1; - }, - /** - * calculate the rotation degrees between two touchLists - * @method getRotation - * @param {Array} start array of touches - * @param {Array} end array of touches - * @return {Number} rotation - */ - getRotation: function getRotation(start, end) { - // need two fingers - if(start.length >= 2 && end.length >= 2) { - return this.getAngle(end[1], end[0]) - this.getAngle(start[1], start[0]); - } - return 0; - }, +/***/ }, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { - /** - * find out if the direction is vertical * - * @method isVertical - * @param {String} direction matches `DIRECTION_UP|DOWN` - * @return {Boolean} is_vertical - */ - isVertical: function isVertical(direction) { - return direction == DIRECTION_UP || direction == DIRECTION_DOWN; - }, + var Hammer = __webpack_require__(44); + var util = __webpack_require__(1); + var Component = __webpack_require__(19); + var moment = __webpack_require__(43); + var locales = __webpack_require__(47); - /** - * set css properties with their prefixes - * @param {HTMLElement} element - * @param {String} prop - * @param {String} value - * @param {Boolean} [toggle=true] - * @return {Boolean} - */ - setPrefixedCss: function setPrefixedCss(element, prop, value, toggle) { - var prefixes = ['', 'Webkit', 'Moz', 'O', 'ms']; - prop = Utils.toCamelCase(prop); + /** + * A custom time bar + * @param {{range: Range, dom: Object}} body + * @param {Object} [options] Available parameters: + * {Boolean} [showCustomTime] + * @constructor CustomTime + * @extends Component + */ - for(var i = 0; i < prefixes.length; i++) { - var p = prop; - // prefixes - if(prefixes[i]) { - p = prefixes[i] + p.slice(0, 1).toUpperCase() + p.slice(1); - } + function CustomTime (body, options) { + this.body = body; - // test the style - if(p in element.style) { - element.style[p] = (toggle == null || toggle) && value || ''; - break; - } - } - }, + // default options + this.defaultOptions = { + showCustomTime: false, + locales: locales, + locale: 'en' + }; + this.options = util.extend({}, this.defaultOptions); - /** - * toggle browser default behavior by setting css properties. - * `userSelect='none'` also sets `element.onselectstart` to false - * `userDrag='none'` also sets `element.ondragstart` to false - * - * @method toggleBehavior - * @param {HtmlElement} element - * @param {Object} props - * @param {Boolean} [toggle=true] - */ - toggleBehavior: function toggleBehavior(element, props, toggle) { - if(!props || !element || !element.style) { - return; - } + this.customTime = new Date(); + this.eventParams = {}; // stores state parameters while dragging the bar - // set the css properties - Utils.each(props, function(value, prop) { - Utils.setPrefixedCss(element, prop, value, toggle); - }); + // create the DOM + this._create(); - var falseFn = toggle && function() { - return false; - }; + this.setOptions(options); + } - // also the disable onselectstart - if(props.userSelect == 'none') { - element.onselectstart = falseFn; - } - // and disable ondragstart - if(props.userDrag == 'none') { - element.ondragstart = falseFn; - } - }, + CustomTime.prototype = new Component(); - /** - * convert a string with underscores to camelCase - * so prevent_default becomes preventDefault - * @param {String} str - * @return {String} camelCaseStr - */ - toCamelCase: function toCamelCase(str) { - return str.replace(/[_-]([a-z])/g, function(s) { - return s[1].toUpperCase(); - }); - } + /** + * Set options for the component. Options will be merged in current options. + * @param {Object} options Available parameters: + * {boolean} [showCustomTime] + */ + CustomTime.prototype.setOptions = function(options) { + if (options) { + // copy all options that we know + util.selectiveExtend(['showCustomTime', 'locale', 'locales'], this.options, options); + } }; + /** + * Create the DOM for the custom time + * @private + */ + CustomTime.prototype._create = function() { + var bar = document.createElement('div'); + bar.className = 'customtime'; + bar.style.position = 'absolute'; + bar.style.top = '0px'; + bar.style.height = '100%'; + this.bar = bar; + + var drag = document.createElement('div'); + drag.style.position = 'relative'; + drag.style.top = '0px'; + drag.style.left = '-10px'; + drag.style.height = '100%'; + drag.style.width = '20px'; + bar.appendChild(drag); + + // attach event listeners + this.hammer = Hammer(bar, { + prevent_default: true + }); + this.hammer.on('dragstart', this._onDragStart.bind(this)); + this.hammer.on('drag', this._onDrag.bind(this)); + this.hammer.on('dragend', this._onDragEnd.bind(this)); + }; /** - * @module hammer + * Destroy the CustomTime bar */ + CustomTime.prototype.destroy = function () { + this.options.showCustomTime = false; + this.redraw(); // will remove the bar from the DOM + + this.hammer.enable(false); + this.hammer = null; + + this.body = null; + }; + /** - * @class Event - * @static + * Repaint the component + * @return {boolean} Returns true if the component is resized */ - var Event = Hammer.event = { - /** - * when touch events have been fired, this is true - * this is used to stop mouse events - * @property prevent_mouseevents - * @private - * @type {Boolean} - */ - preventMouseEvents: false, + CustomTime.prototype.redraw = function () { + if (this.options.showCustomTime) { + var parent = this.body.dom.backgroundVertical; + if (this.bar.parentNode != parent) { + // attach to the dom + if (this.bar.parentNode) { + this.bar.parentNode.removeChild(this.bar); + } + parent.appendChild(this.bar); + } - /** - * if EVENT_START has been fired - * @property started - * @private - * @type {Boolean} - */ - started: false, + var x = this.body.util.toScreen(this.customTime); - /** - * when the mouse is hold down, this is true - * @property should_detect - * @private - * @type {Boolean} - */ - shouldDetect: false, + var locale = this.options.locales[this.options.locale]; + var title = locale.time + ': ' + moment(this.customTime).format('dddd, MMMM Do YYYY, H:mm:ss'); + title = title.charAt(0).toUpperCase() + title.substring(1); - /** - * simple event binder with a hook and support for multiple types - * @method on - * @param {HTMLElement} element - * @param {String} type - * @param {Function} handler - * @param {Function} [hook] - * @param {Object} hook.type - */ - on: function on(element, type, handler, hook) { - var types = type.split(' '); - Utils.each(types, function(type) { - Utils.on(element, type, handler); - hook && hook(type); - }); - }, + this.bar.style.left = x + 'px'; + this.bar.title = title; + } + else { + // remove the line from the DOM + if (this.bar.parentNode) { + this.bar.parentNode.removeChild(this.bar); + } + } - /** - * simple event unbinder with a hook and support for multiple types - * @method off - * @param {HTMLElement} element - * @param {String} type - * @param {Function} handler - * @param {Function} [hook] - * @param {Object} hook.type - */ - off: function off(element, type, handler, hook) { - var types = type.split(' '); - Utils.each(types, function(type) { - Utils.off(element, type, handler); - hook && hook(type); - }); - }, + return false; + }; - /** - * the core touch event handler. - * this finds out if we should to detect gestures - * @method onTouch - * @param {HTMLElement} element - * @param {String} eventType matches `EVENT_START|MOVE|END` - * @param {Function} handler - * @return onTouchHandler {Function} the core event handler - */ - onTouch: function onTouch(element, eventType, handler) { - var self = this; + /** + * Set custom time. + * @param {Date | number | string} time + */ + CustomTime.prototype.setCustomTime = function(time) { + this.customTime = util.convert(time, 'Date'); + this.redraw(); + }; - var onTouchHandler = function onTouchHandler(ev) { - var srcType = ev.type.toLowerCase(), - isPointer = Hammer.HAS_POINTEREVENTS, - isMouse = Utils.inStr(srcType, 'mouse'), - triggerType; + /** + * Retrieve the current custom time. + * @return {Date} customTime + */ + CustomTime.prototype.getCustomTime = function() { + return new Date(this.customTime.valueOf()); + }; - // if we are in a mouseevent, but there has been a touchevent triggered in this session - // we want to do nothing. simply break out of the event. - if(isMouse && self.preventMouseEvents) { - return; + /** + * Start moving horizontally + * @param {Event} event + * @private + */ + CustomTime.prototype._onDragStart = function(event) { + this.eventParams.dragging = true; + this.eventParams.customTime = this.customTime; - // mousebutton must be down - } else if(isMouse && eventType == EVENT_START && ev.button === 0) { - self.preventMouseEvents = false; - self.shouldDetect = true; - } else if(isPointer && eventType == EVENT_START) { - self.shouldDetect = (ev.buttons === 1 || PointerEvent.matchType(POINTER_TOUCH, ev)); - // just a valid start event, but no mouse - } else if(!isMouse && eventType == EVENT_START) { - self.preventMouseEvents = true; - self.shouldDetect = true; - } + event.stopPropagation(); + event.preventDefault(); + }; - // update the pointer event before entering the detection - if(isPointer && eventType != EVENT_END) { - PointerEvent.updatePointer(eventType, ev); - } + /** + * Perform moving operating. + * @param {Event} event + * @private + */ + CustomTime.prototype._onDrag = function (event) { + if (!this.eventParams.dragging) return; - // we are in a touch/down state, so allowed detection of gestures - if(self.shouldDetect) { - triggerType = self.doDetect.call(self, ev, eventType, element, handler); - } + var deltaX = event.gesture.deltaX, + x = this.body.util.toScreen(this.eventParams.customTime) + deltaX, + time = this.body.util.toTime(x); - // ...and we are done with the detection - // so reset everything to start each detection totally fresh - if(triggerType == EVENT_END) { - self.preventMouseEvents = false; - self.shouldDetect = false; - PointerEvent.reset(); - // update the pointerevent object after the detection - } + this.setCustomTime(time); - if(isPointer && eventType == EVENT_END) { - PointerEvent.updatePointer(eventType, ev); - } - }; + // fire a timechange event + this.body.emitter.emit('timechange', { + time: new Date(this.customTime.valueOf()) + }); - this.on(element, EVENT_TYPES[eventType], onTouchHandler); - return onTouchHandler; - }, + event.stopPropagation(); + event.preventDefault(); + }; - /** - * the core detection method - * this finds out what hammer-touch-events to trigger - * @method doDetect - * @param {Object} ev - * @param {String} eventType matches `EVENT_START|MOVE|END` - * @param {HTMLElement} element - * @param {Function} handler - * @return {String} triggerType matches `EVENT_START|MOVE|END` - */ - doDetect: function doDetect(ev, eventType, element, handler) { - var touchList = this.getTouchList(ev, eventType); - var touchListLength = touchList.length; - var triggerType = eventType; - var triggerChange = touchList.trigger; // used by fakeMultitouch plugin - var changedLength = touchListLength; + /** + * Stop moving operating. + * @param {event} event + * @private + */ + CustomTime.prototype._onDragEnd = function (event) { + if (!this.eventParams.dragging) return; - // at each touchstart-like event we want also want to trigger a TOUCH event... - if(eventType == EVENT_START) { - triggerChange = EVENT_TOUCH; - // ...the same for a touchend-like event - } else if(eventType == EVENT_END) { - triggerChange = EVENT_RELEASE; + // fire a timechanged event + this.body.emitter.emit('timechanged', { + time: new Date(this.customTime.valueOf()) + }); - // keep track of how many touches have been removed - changedLength = touchList.length - ((ev.changedTouches) ? ev.changedTouches.length : 1); - } + event.stopPropagation(); + event.preventDefault(); + }; + + module.exports = CustomTime; - // after there are still touches on the screen, - // we just want to trigger a MOVE event. so change the START or END to a MOVE - // but only after detection has been started, the first time we actualy want a START - if(changedLength > 0 && this.started) { - triggerType = EVENT_MOVE; - } - // detection has been started, we keep track of this, see above - this.started = true; +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { - // generate some event data, some basic information - var evData = this.collectEventData(element, triggerType, touchList, ev); + var util = __webpack_require__(1); + var DOMutil = __webpack_require__(2); + var Component = __webpack_require__(19); + var DataStep = __webpack_require__(15); - // trigger the triggerType event before the change (TOUCH, RELEASE) events - // but the END event should be at last - if(eventType != EVENT_END) { - handler.call(Detection, evData); - } + /** + * A horizontal time axis + * @param {Object} [options] See DataAxis.setOptions for the available + * options. + * @constructor DataAxis + * @extends Component + * @param body + */ + function DataAxis (body, options, svg, linegraphOptions) { + this.id = util.randomUUID(); + this.body = body; - // trigger a change (TOUCH, RELEASE) event, this means the length of the touches changed - if(triggerChange) { - evData.changedLength = changedLength; - evData.eventType = triggerChange; + this.defaultOptions = { + orientation: 'left', // supported: 'left', 'right' + showMinorLabels: true, + showMajorLabels: true, + icons: true, + majorLinesOffset: 7, + minorLinesOffset: 4, + labelOffsetX: 10, + labelOffsetY: 2, + iconWidth: 20, + width: '40px', + visible: true, + customRange: { + left: {min:undefined, max:undefined}, + right: {min:undefined, max:undefined} + } + }; - handler.call(Detection, evData); + this.linegraphOptions = linegraphOptions; + this.linegraphSVG = svg; + this.props = {}; + this.DOMelements = { // dynamic elements + lines: {}, + labels: {} + }; - evData.eventType = triggerType; - delete evData.changedLength; - } + this.dom = {}; - // trigger the END event - if(triggerType == EVENT_END) { - handler.call(Detection, evData); + this.range = {start:0, end:0}; - // ...and we are done with the detection - // so reset everything to start each detection totally fresh - this.started = false; - } + this.options = util.extend({}, this.defaultOptions); + this.conversionFactor = 1; - return triggerType; - }, + this.setOptions(options); + this.width = Number(('' + this.options.width).replace("px","")); + this.minWidth = this.width; + this.height = this.linegraphSVG.offsetHeight; - /** - * we have different events for each device/browser - * determine what we need and set them in the EVENT_TYPES constant - * the `onTouch` method is bind to these properties. - * @method determineEventTypes - * @return {Object} events - */ - determineEventTypes: function determineEventTypes() { - var types; - if(Hammer.HAS_POINTEREVENTS) { - if(window.PointerEvent) { - types = [ - 'pointerdown', - 'pointermove', - 'pointerup pointercancel lostpointercapture' - ]; - } else { - types = [ - 'MSPointerDown', - 'MSPointerMove', - 'MSPointerUp MSPointerCancel MSLostPointerCapture' - ]; - } - } else if(Hammer.NO_MOUSEEVENTS) { - types = [ - 'touchstart', - 'touchmove', - 'touchend touchcancel' - ]; - } else { - types = [ - 'touchstart mousedown', - 'touchmove mousemove', - 'touchend touchcancel mouseup' - ]; - } + this.stepPixels = 25; + this.stepPixelsForced = 25; + this.lineOffset = 0; + this.master = true; + this.svgElements = {}; - EVENT_TYPES[EVENT_START] = types[0]; - EVENT_TYPES[EVENT_MOVE] = types[1]; - EVENT_TYPES[EVENT_END] = types[2]; - return EVENT_TYPES; - }, - /** - * create touchList depending on the event - * @method getTouchList - * @param {Object} ev - * @param {String} eventType - * @return {Array} touches - */ - getTouchList: function getTouchList(ev, eventType) { - // get the fake pointerEvent touchlist - if(Hammer.HAS_POINTEREVENTS) { - return PointerEvent.getTouchList(); - } + this.groups = {}; + this.amountOfGroups = 0; - // get the touchlist - if(ev.touches) { - if(eventType == EVENT_MOVE) { - return ev.touches; - } + // create the HTML DOM + this._create(); + } - var identifiers = []; - var concat = [].concat(Utils.toArray(ev.touches), Utils.toArray(ev.changedTouches)); - var touchList = []; + DataAxis.prototype = new Component(); - Utils.each(concat, function(touch) { - if(Utils.inArray(identifiers, touch.identifier) === false) { - touchList.push(touch); - } - identifiers.push(touch.identifier); - }); - return touchList; - } - // make fake touchList from mouse position - ev.identifier = 1; - return [ev]; - }, + DataAxis.prototype.addGroup = function(label, graphOptions) { + if (!this.groups.hasOwnProperty(label)) { + this.groups[label] = graphOptions; + } + this.amountOfGroups += 1; + }; - /** - * collect basic event data - * @method collectEventData - * @param {HTMLElement} element - * @param {String} eventType matches `EVENT_START|MOVE|END` - * @param {Array} touches - * @param {Object} ev - * @return {Object} ev - */ - collectEventData: function collectEventData(element, eventType, touches, ev) { - // find out pointerType - var pointerType = POINTER_TOUCH; - if(Utils.inStr(ev.type, 'mouse') || PointerEvent.matchType(POINTER_MOUSE, ev)) { - pointerType = POINTER_MOUSE; - } else if(PointerEvent.matchType(POINTER_PEN, ev)) { - pointerType = POINTER_PEN; - } + DataAxis.prototype.updateGroup = function(label, graphOptions) { + this.groups[label] = graphOptions; + }; - return { - center: Utils.getCenter(touches), - timeStamp: Date.now(), - target: ev.target, - touches: touches, - eventType: eventType, - pointerType: pointerType, - srcEvent: ev, + DataAxis.prototype.removeGroup = function(label) { + if (this.groups.hasOwnProperty(label)) { + delete this.groups[label]; + this.amountOfGroups -= 1; + } + }; - /** - * prevent the browser default actions - * mostly used to disable scrolling of the browser - */ - preventDefault: function() { - var srcEvent = this.srcEvent; - srcEvent.preventManipulation && srcEvent.preventManipulation(); - srcEvent.preventDefault && srcEvent.preventDefault(); - }, - /** - * stop bubbling the event up to its parents - */ - stopPropagation: function() { - this.srcEvent.stopPropagation(); - }, + DataAxis.prototype.setOptions = function (options) { + if (options) { + var redraw = false; + if (this.options.orientation != options.orientation && options.orientation !== undefined) { + redraw = true; + } + var fields = [ + 'orientation', + 'showMinorLabels', + 'showMajorLabels', + 'icons', + 'majorLinesOffset', + 'minorLinesOffset', + 'labelOffsetX', + 'labelOffsetY', + 'iconWidth', + 'width', + 'visible', + 'customRange' + ]; + util.selectiveExtend(fields, this.options, options); - /** - * immediately stop gesture detection - * might be useful after a swipe was detected - * @return {*} - */ - stopDetect: function() { - return Detection.stopDetect(); - } - }; + this.minWidth = Number(('' + this.options.width).replace("px","")); + + if (redraw == true && this.dom.frame) { + this.hide(); + this.show(); } + } }; /** - * @module hammer - * - * @class PointerEvent - * @static + * Create the HTML DOM for the DataAxis */ - var PointerEvent = Hammer.PointerEvent = { - /** - * holds all pointers, by `identifier` - * @property pointers - * @type {Object} - */ - pointers: {}, + DataAxis.prototype._create = function() { + this.dom.frame = document.createElement('div'); + this.dom.frame.style.width = this.options.width; + this.dom.frame.style.height = this.height; - /** - * get the pointers as an array - * @method getTouchList - * @return {Array} touchlist - */ - getTouchList: function getTouchList() { - var touchlist = []; - // we can use forEach since pointerEvents only is in IE10 - Utils.each(this.pointers, function(pointer) { - touchlist.push(pointer); - }); - return touchlist; - }, + this.dom.lineContainer = document.createElement('div'); + this.dom.lineContainer.style.width = '100%'; + this.dom.lineContainer.style.height = this.height; - /** - * update the position of a pointer - * @method updatePointer - * @param {String} eventType matches `EVENT_START|MOVE|END` - * @param {Object} pointerEvent - */ - updatePointer: function updatePointer(eventType, pointerEvent) { - if(eventType == EVENT_END || (eventType != EVENT_END && pointerEvent.buttons !== 1)) { - delete this.pointers[pointerEvent.pointerId]; - } else { - pointerEvent.identifier = pointerEvent.pointerId; - this.pointers[pointerEvent.pointerId] = pointerEvent; - } - }, + // create svg element for graph drawing. + this.svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); + this.svg.style.position = "absolute"; + this.svg.style.top = '0px'; + this.svg.style.height = '100%'; + this.svg.style.width = '100%'; + this.svg.style.display = "block"; + this.dom.frame.appendChild(this.svg); + }; - /** - * check if ev matches pointertype - * @method matchType - * @param {String} pointerType matches `POINTER_MOUSE|TOUCH|PEN` - * @param {PointerEvent} ev - */ - matchType: function matchType(pointerType, ev) { - if(!ev.pointerType) { - return false; - } + DataAxis.prototype._redrawGroupIcons = function () { + DOMutil.prepareElements(this.svgElements); - var pt = ev.pointerType, - types = {}; + var x; + var iconWidth = this.options.iconWidth; + var iconHeight = 15; + var iconOffset = 4; + var y = iconOffset + 0.5 * iconHeight; - types[POINTER_MOUSE] = (pt === (ev.MSPOINTER_TYPE_MOUSE || POINTER_MOUSE)); - types[POINTER_TOUCH] = (pt === (ev.MSPOINTER_TYPE_TOUCH || POINTER_TOUCH)); - types[POINTER_PEN] = (pt === (ev.MSPOINTER_TYPE_PEN || POINTER_PEN)); - return types[pointerType]; - }, + if (this.options.orientation == 'left') { + x = iconOffset; + } + else { + x = this.width - iconWidth - iconOffset; + } - /** - * reset the stored pointers - * @method reset - */ - reset: function resetList() { - this.pointers = {}; + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { + this.groups[groupId].drawIcon(x, y, this.svgElements, this.svg, iconWidth, iconHeight); + y += iconHeight + iconOffset; + } } + } + + DOMutil.cleanupElements(this.svgElements); }; + /** + * Create the HTML DOM for the DataAxis + */ + DataAxis.prototype.show = function() { + if (!this.dom.frame.parentNode) { + if (this.options.orientation == 'left') { + this.body.dom.left.appendChild(this.dom.frame); + } + else { + this.body.dom.right.appendChild(this.dom.frame); + } + } + + if (!this.dom.lineContainer.parentNode) { + this.body.dom.backgroundHorizontal.appendChild(this.dom.lineContainer); + } + }; /** - * @module hammer - * - * @class Detection - * @static + * Create the HTML DOM for the DataAxis */ - var Detection = Hammer.detection = { - // contains all registred Hammer.gestures in the correct order - gestures: [], + DataAxis.prototype.hide = function() { + if (this.dom.frame.parentNode) { + this.dom.frame.parentNode.removeChild(this.dom.frame); + } - // data of the current Hammer.gesture detection session - current: null, + if (this.dom.lineContainer.parentNode) { + this.dom.lineContainer.parentNode.removeChild(this.dom.lineContainer); + } + }; - // the previous Hammer.gesture session data - // is a full clone of the previous gesture.current object - previous: null, + /** + * Set a range (start and end) + * @param end + * @param start + * @param end + */ + DataAxis.prototype.setRange = function (start, end) { + this.range.start = start; + this.range.end = end; + }; - // when this becomes true, no gestures are fired - stopped: false, + /** + * Repaint the component + * @return {boolean} Returns true if the component is resized + */ + DataAxis.prototype.redraw = function () { + var changeCalled = false; + var activeGroups = 0; + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { + activeGroups++; + } + } + } + if (this.amountOfGroups == 0 || activeGroups == 0) { + this.hide(); + } + else { + this.show(); + this.height = Number(this.linegraphSVG.style.height.replace("px","")); + // svg offsetheight did not work in firefox and explorer... - /** - * start Hammer.gesture detection - * @method startDetect - * @param {Hammer.Instance} inst - * @param {Object} eventData - */ - startDetect: function startDetect(inst, eventData) { - // already busy with a Hammer.gesture detection on an element - if(this.current) { - return; - } + this.dom.lineContainer.style.height = this.height + 'px'; + this.width = this.options.visible == true ? Number(('' + this.options.width).replace("px","")) : 0; - this.stopped = false; + var props = this.props; + var frame = this.dom.frame; - // holds current session - this.current = { - inst: inst, // reference to HammerInstance we're working for - startEvent: Utils.extend({}, eventData), // start eventData for distances, timing etc - lastEvent: false, // last eventData - lastCalcEvent: false, // last eventData for calculations. - futureCalcEvent: false, // last eventData for calculations. - lastCalcData: {}, // last lastCalcData - name: '' // current gesture we're in/detected, can be 'tap', 'hold' etc - }; + // update classname + frame.className = 'dataaxis'; - this.detect(eventData); - }, + // calculate character width and height + this._calculateCharSize(); - /** - * Hammer.gesture detection - * @method detect - * @param {Object} eventData - * @return {any} - */ - detect: function detect(eventData) { - if(!this.current || this.stopped) { - return; - } + var orientation = this.options.orientation; + var showMinorLabels = this.options.showMinorLabels; + var showMajorLabels = this.options.showMajorLabels; - // extend event data with calculations about scale, distance etc - eventData = this.extendEventData(eventData); + // determine the width and height of the elemens for the axis + props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0; + props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0; - // hammer instance and instance options - var inst = this.current.inst, - instOptions = inst.options; + props.minorLineWidth = this.body.dom.backgroundHorizontal.offsetWidth - this.lineOffset - this.width + 2 * this.options.minorLinesOffset; + props.minorLineHeight = 1; + props.majorLineWidth = this.body.dom.backgroundHorizontal.offsetWidth - this.lineOffset - this.width + 2 * this.options.majorLinesOffset; + props.majorLineHeight = 1; - // call Hammer.gesture handlers - Utils.each(this.gestures, function triggerGesture(gesture) { - // only when the instance options have enabled this gesture - if(!this.stopped && inst.enabled && instOptions[gesture.name]) { - gesture.handler.call(gesture, eventData, inst); - } - }, this); + // take frame offline while updating (is almost twice as fast) + if (orientation == 'left') { + frame.style.top = '0'; + frame.style.left = '0'; + frame.style.bottom = ''; + frame.style.width = this.width + 'px'; + frame.style.height = this.height + "px"; + } + else { // right + frame.style.top = ''; + frame.style.bottom = '0'; + frame.style.left = '0'; + frame.style.width = this.width + 'px'; + frame.style.height = this.height + "px"; + } + changeCalled = this._redrawLabels(); + if (this.options.icons == true) { + this._redrawGroupIcons(); + } + } + return changeCalled; + }; - // store as previous event event - if(this.current) { - this.current.lastEvent = eventData; - } + /** + * Repaint major and minor text labels and vertical grid lines + * @private + */ + DataAxis.prototype._redrawLabels = function () { + DOMutil.prepareElements(this.DOMelements.lines); + DOMutil.prepareElements(this.DOMelements.labels); - if(eventData.eventType == EVENT_END) { - this.stopDetect(); - } + var orientation = this.options['orientation']; - return eventData; - }, + // calculate range and step (step such that we have space for 7 characters per label) + var minimumStep = this.master ? this.props.majorCharHeight || 10 : this.stepPixelsForced; - /** - * clear the Hammer.gesture vars - * this is called on endDetect, but can also be used when a final Hammer.gesture has been detected - * to stop other Hammer.gestures from being fired - * @method stopDetect - */ - stopDetect: function stopDetect() { - // clone current data to the store as the previous gesture - // used for the double tap gesture, since this is an other gesture detect session - this.previous = Utils.extend({}, this.current); + var step = new DataStep(this.range.start, this.range.end, minimumStep, this.dom.frame.offsetHeight, this.options.customRange[this.options.orientation]); + this.step = step; + // get the distance in pixels for a step + // dead space is space that is "left over" after a step + var stepPixels = (this.dom.frame.offsetHeight - (step.deadSpace * (this.dom.frame.offsetHeight / step.marginRange))) / (((step.marginRange - step.deadSpace) / step.step)); + this.stepPixels = stepPixels; - // reset the current - this.current = null; - this.stopped = true; - }, + var amountOfSteps = this.height / stepPixels; + var stepDifference = 0; - /** - * calculate velocity, angle and direction - * @method getVelocityData - * @param {Object} ev - * @param {Object} center - * @param {Number} deltaTime - * @param {Number} deltaX - * @param {Number} deltaY - */ - getCalculatedData: function getCalculatedData(ev, center, deltaTime, deltaX, deltaY) { - var cur = this.current, - recalc = false, - calcEv = cur.lastCalcEvent, - calcData = cur.lastCalcData; + if (this.master == false) { + stepPixels = this.stepPixelsForced; + stepDifference = Math.round((this.dom.frame.offsetHeight / stepPixels) - amountOfSteps); + for (var i = 0; i < 0.5 * stepDifference; i++) { + step.previous(); + } + amountOfSteps = this.height / stepPixels; + } + else { + amountOfSteps += 0.25; + } - if(calcEv && ev.timeStamp - calcEv.timeStamp > Hammer.CALCULATE_INTERVAL) { - center = calcEv.center; - deltaTime = ev.timeStamp - calcEv.timeStamp; - deltaX = ev.center.clientX - calcEv.center.clientX; - deltaY = ev.center.clientY - calcEv.center.clientY; - recalc = true; - } - if(ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) { - cur.futureCalcEvent = ev; - } + this.valueAtZero = step.marginEnd; + var marginStartPos = 0; - if(!cur.lastCalcEvent || recalc) { - calcData.velocity = Utils.getVelocity(deltaTime, deltaX, deltaY); - calcData.angle = Utils.getAngle(center, ev.center); - calcData.direction = Utils.getDirection(center, ev.center); + // do not draw the first label + var max = 1; - cur.lastCalcEvent = cur.futureCalcEvent || ev; - cur.futureCalcEvent = ev; - } + this.maxLabelSize = 0; + var y = 0; + while (max < Math.round(amountOfSteps)) { + step.next(); + y = Math.round(max * stepPixels); + marginStartPos = max * stepPixels; + var isMajor = step.isMajor(); - ev.velocityX = calcData.velocity.x; - ev.velocityY = calcData.velocity.y; - ev.interimAngle = calcData.angle; - ev.interimDirection = calcData.direction; - }, + if (this.options['showMinorLabels'] && isMajor == false || this.master == false && this.options['showMinorLabels'] == true) { + this._redrawLabel(y - 2, step.getCurrent(), orientation, 'yAxis minor', this.props.minorCharHeight); + } - /** - * extend eventData for Hammer.gestures - * @method extendEventData - * @param {Object} ev - * @return {Object} ev - */ - extendEventData: function extendEventData(ev) { - var cur = this.current, - startEv = cur.startEvent, - lastEv = cur.lastEvent || startEv; + if (isMajor && this.options['showMajorLabels'] && this.master == true || + this.options['showMinorLabels'] == false && this.master == false && isMajor == true) { + if (y >= 0) { + this._redrawLabel(y - 2, step.getCurrent(), orientation, 'yAxis major', this.props.majorCharHeight); + } + this._redrawLine(y, orientation, 'grid horizontal major', this.options.majorLinesOffset, this.props.majorLineWidth); + } + else { + this._redrawLine(y, orientation, 'grid horizontal minor', this.options.minorLinesOffset, this.props.minorLineWidth); + } - // update the start touchlist to calculate the scale/rotation - if(ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) { - startEv.touches = []; - Utils.each(ev.touches, function(touch) { - startEv.touches.push({ - clientX: touch.clientX, - clientY: touch.clientY - }); - }); - } + max++; + } - var deltaTime = ev.timeStamp - startEv.timeStamp, - deltaX = ev.center.clientX - startEv.center.clientX, - deltaY = ev.center.clientY - startEv.center.clientY; + if (this.master == false) { + this.conversionFactor = y / (this.valueAtZero - step.current); + } + else { + this.conversionFactor = this.dom.frame.offsetHeight / step.marginRange; + } - this.getCalculatedData(ev, lastEv.center, deltaTime, deltaX, deltaY); + var offset = this.options.icons == true ? this.options.iconWidth + this.options.labelOffsetX + 15 : this.options.labelOffsetX + 15; + // this will resize the yAxis to accomodate the labels. + if (this.maxLabelSize > (this.width - offset) && this.options.visible == true) { + this.width = this.maxLabelSize + offset; + this.options.width = this.width + "px"; + DOMutil.cleanupElements(this.DOMelements.lines); + DOMutil.cleanupElements(this.DOMelements.labels); + this.redraw(); + return true; + } + // this will resize the yAxis if it is too big for the labels. + else if (this.maxLabelSize < (this.width - offset) && this.options.visible == true && this.width > this.minWidth) { + this.width = Math.max(this.minWidth,this.maxLabelSize + offset); + this.options.width = this.width + "px"; + DOMutil.cleanupElements(this.DOMelements.lines); + DOMutil.cleanupElements(this.DOMelements.labels); + this.redraw(); + return true; + } + else { + DOMutil.cleanupElements(this.DOMelements.lines); + DOMutil.cleanupElements(this.DOMelements.labels); + return false; + } + }; - Utils.extend(ev, { - startEvent: startEv, + DataAxis.prototype.convertValue = function (value) { + var invertedValue = this.valueAtZero - value; + var convertedValue = invertedValue * this.conversionFactor; + return convertedValue; + }; - deltaTime: deltaTime, - deltaX: deltaX, - deltaY: deltaY, + /** + * Create a label for the axis at position x + * @private + * @param y + * @param text + * @param orientation + * @param className + * @param characterHeight + */ + DataAxis.prototype._redrawLabel = function (y, text, orientation, className, characterHeight) { + // reuse redundant label + var label = DOMutil.getDOMElement('div',this.DOMelements.labels, this.dom.frame); //this.dom.redundant.labels.shift(); + label.className = className; + label.innerHTML = text; + if (orientation == 'left') { + label.style.left = '-' + this.options.labelOffsetX + 'px'; + label.style.textAlign = "right"; + } + else { + label.style.right = '-' + this.options.labelOffsetX + 'px'; + label.style.textAlign = "left"; + } - distance: Utils.getDistance(startEv.center, ev.center), - angle: Utils.getAngle(startEv.center, ev.center), - direction: Utils.getDirection(startEv.center, ev.center), - scale: Utils.getScale(startEv.touches, ev.touches), - rotation: Utils.getRotation(startEv.touches, ev.touches) - }); + label.style.top = y - 0.5 * characterHeight + this.options.labelOffsetY + 'px'; - return ev; - }, + text += ''; - /** - * register new gesture - * @method register - * @param {Object} gesture object, see `gestures/` for documentation - * @return {Array} gestures - */ - register: function register(gesture) { - // add an enable gesture options if there is no given - var options = gesture.defaults || {}; - if(options[gesture.name] === undefined) { - options[gesture.name] = true; - } + var largestWidth = Math.max(this.props.majorCharWidth,this.props.minorCharWidth); + if (this.maxLabelSize < text.length * largestWidth) { + this.maxLabelSize = text.length * largestWidth; + } + }; - // extend Hammer default options with the Hammer.gesture options - Utils.extend(Hammer.defaults, options, true); + /** + * Create a minor line for the axis at position y + * @param y + * @param orientation + * @param className + * @param offset + * @param width + */ + DataAxis.prototype._redrawLine = function (y, orientation, className, offset, width) { + if (this.master == true) { + var line = DOMutil.getDOMElement('div',this.DOMelements.lines, this.dom.lineContainer);//this.dom.redundant.lines.shift(); + line.className = className; + line.innerHTML = ''; - // set its index - gesture.index = gesture.index || 1000; + if (orientation == 'left') { + line.style.left = (this.width - offset) + 'px'; + } + else { + line.style.right = (this.width - offset) + 'px'; + } - // add Hammer.gesture to the list - this.gestures.push(gesture); + line.style.width = width + 'px'; + line.style.top = y + 'px'; + } + }; - // sort the list by index - this.gestures.sort(function(a, b) { - if(a.index < b.index) { - return -1; - } - if(a.index > b.index) { - return 1; - } - return 0; - }); - return this.gestures; - } - }; - /** - * @module hammer - */ /** - * create new hammer instance - * all methods should return the instance itself, so it is chainable. - * - * @class Instance - * @constructor - * @param {HTMLElement} element - * @param {Object} [options={}] options are merged with `Hammer.defaults` - * @return {Hammer.Instance} + * Determine the size of text on the axis (both major and minor axis). + * The size is calculated only once and then cached in this.props. + * @private */ - Hammer.Instance = function(element, options) { - var self = this; - - // setup HammerJS window events and register all gestures - // this also sets up the default options - setup(); - - /** - * @property element - * @type {HTMLElement} - */ - this.element = element; + DataAxis.prototype._calculateCharSize = function () { + // determine the char width and height on the minor axis + if (!('minorCharHeight' in this.props)) { + var textMinor = document.createTextNode('0'); + var measureCharMinor = document.createElement('DIV'); + measureCharMinor.className = 'yAxis minor measure'; + measureCharMinor.appendChild(textMinor); + this.dom.frame.appendChild(measureCharMinor); - /** - * @property enabled - * @type {Boolean} - * @protected - */ - this.enabled = true; + this.props.minorCharHeight = measureCharMinor.clientHeight; + this.props.minorCharWidth = measureCharMinor.clientWidth; - /** - * options, merged with the defaults - * options with an _ are converted to camelCase - * @property options - * @type {Object} - */ - Utils.each(options, function(value, name) { - delete options[name]; - options[Utils.toCamelCase(name)] = value; - }); + this.dom.frame.removeChild(measureCharMinor); + } - this.options = Utils.extend(Utils.extend({}, Hammer.defaults), options || {}); + if (!('majorCharHeight' in this.props)) { + var textMajor = document.createTextNode('0'); + var measureCharMajor = document.createElement('DIV'); + measureCharMajor.className = 'yAxis major measure'; + measureCharMajor.appendChild(textMajor); + this.dom.frame.appendChild(measureCharMajor); - // add some css to the element to prevent the browser from doing its native behavoir - if(this.options.behavior) { - Utils.toggleBehavior(this.element, this.options.behavior, true); - } + this.props.majorCharHeight = measureCharMajor.clientHeight; + this.props.majorCharWidth = measureCharMajor.clientWidth; - /** - * event start handler on the element to start the detection - * @property eventStartHandler - * @type {Object} - */ - this.eventStartHandler = Event.onTouch(element, EVENT_START, function(ev) { - if(self.enabled && ev.eventType == EVENT_START) { - Detection.startDetect(self, ev); - } else if(ev.eventType == EVENT_TOUCH) { - Detection.detect(ev); - } - }); + this.dom.frame.removeChild(measureCharMajor); + } + }; - /** - * keep a list of user event handlers which needs to be removed when calling 'dispose' - * @property eventHandlers - * @type {Array} - */ - this.eventHandlers = []; + /** + * Snap a date to a rounded value. + * The snap intervals are dependent on the current scale and step. + * @param {Date} date the date to be snapped. + * @return {Date} snappedDate + */ + DataAxis.prototype.snap = function(date) { + return this.step.snap(date); }; - Hammer.Instance.prototype = { - /** - * bind events to the instance - * @method on - * @chainable - * @param {String} gestures multiple gestures by splitting with a space - * @param {Function} handler - * @param {Object} handler.ev event object - */ - on: function onEvent(gestures, handler) { - var self = this; - Event.on(self.element, gestures, handler, function(type) { - self.eventHandlers.push({ gesture: type, handler: handler }); - }); - return self; - }, + module.exports = DataAxis; - /** - * unbind events to the instance - * @method off - * @chainable - * @param {String} gestures - * @param {Function} handler - */ - off: function offEvent(gestures, handler) { - var self = this; - Event.off(self.element, gestures, handler, function(type) { - var index = Utils.inArray({ gesture: type, handler: handler }); - if(index !== false) { - self.eventHandlers.splice(index, 1); - } - }); - return self; - }, +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { - /** - * trigger gesture event - * @method trigger - * @chainable - * @param {String} gesture - * @param {Object} [eventData] - */ - trigger: function triggerEvent(gesture, eventData) { - // optional - if(!eventData) { - eventData = {}; - } + var util = __webpack_require__(1); + var DOMutil = __webpack_require__(2); - // create DOM event - var event = Hammer.DOCUMENT.createEvent('Event'); - event.initEvent(gesture, true, true); - event.gesture = eventData; + /** + * @constructor Group + * @param {Number | String} groupId + * @param {Object} data + * @param {ItemSet} itemSet + */ + function GraphGroup (group, groupId, options, groupsUsingDefaultStyles) { + this.id = groupId; + var fields = ['sampling','style','sort','yAxisOrientation','barChart','drawPoints','shaded','catmullRom'] + this.options = util.selectiveBridgeObject(fields,options); + this.usingDefaultStyle = group.className === undefined; + this.groupsUsingDefaultStyles = groupsUsingDefaultStyles; + this.zeroPosition = 0; + this.update(group); + if (this.usingDefaultStyle == true) { + this.groupsUsingDefaultStyles[0] += 1; + } + this.itemsData = []; + this.visible = group.visible === undefined ? true : group.visible; + } - // trigger on the target if it is in the instance element, - // this is for event delegation tricks - var element = this.element; - if(Utils.hasParent(eventData.target, element)) { - element = eventData.target; - } + GraphGroup.prototype.setItems = function(items) { + if (items != null) { + this.itemsData = items; + if (this.options.sort == true) { + this.itemsData.sort(function (a,b) {return a.x - b.x;}) + } + } + else { + this.itemsData = []; + } + }; - element.dispatchEvent(event); - return this; - }, + GraphGroup.prototype.setZeroPosition = function(pos) { + this.zeroPosition = pos; + }; - /** - * enable of disable hammer.js detection - * @method enable - * @chainable - * @param {Boolean} state - */ - enable: function enable(state) { - this.enabled = state; - return this; - }, + GraphGroup.prototype.setOptions = function(options) { + if (options !== undefined) { + var fields = ['sampling','style','sort','yAxisOrientation','barChart']; + util.selectiveDeepExtend(fields, this.options, options); - /** - * dispose this hammer instance - * @method dispose - * @return {Null} - */ - dispose: function dispose() { - var i, eh; + util.mergeOptions(this.options, options,'catmullRom'); + util.mergeOptions(this.options, options,'drawPoints'); + util.mergeOptions(this.options, options,'shaded'); - // undo all changes made by stop_browser_behavior - Utils.toggleBehavior(this.element, this.options.behavior, false); + if (options.catmullRom) { + if (typeof options.catmullRom == 'object') { + if (options.catmullRom.parametrization) { + if (options.catmullRom.parametrization == 'uniform') { + this.options.catmullRom.alpha = 0; + } + else if (options.catmullRom.parametrization == 'chordal') { + this.options.catmullRom.alpha = 1.0; + } + else { + this.options.catmullRom.parametrization = 'centripetal'; + this.options.catmullRom.alpha = 0.5; + } + } + } + } + } + }; + + GraphGroup.prototype.update = function(group) { + this.group = group; + this.content = group.content || 'graph'; + this.className = group.className || this.className || "graphGroup" + this.groupsUsingDefaultStyles[0] % 10; + this.visible = group.visible === undefined ? true : group.visible; + this.setOptions(group.options); + }; - // unbind all custom event handlers - for(i = -1; (eh = this.eventHandlers[++i]);) { - Utils.off(this.element, eh.gesture, eh.handler); - } + GraphGroup.prototype.drawIcon = function(x, y, JSONcontainer, SVGcontainer, iconWidth, iconHeight) { + var fillHeight = iconHeight * 0.5; + var path, fillPath; - this.eventHandlers = []; + var outline = DOMutil.getSVGElement("rect", JSONcontainer, SVGcontainer); + outline.setAttributeNS(null, "x", x); + outline.setAttributeNS(null, "y", y - fillHeight); + outline.setAttributeNS(null, "width", iconWidth); + outline.setAttributeNS(null, "height", 2*fillHeight); + outline.setAttributeNS(null, "class", "outline"); - // unbind the start event listener - Event.off(this.element, EVENT_TYPES[EVENT_START], this.eventStartHandler); + if (this.options.style == 'line') { + path = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer); + path.setAttributeNS(null, "class", this.className); + path.setAttributeNS(null, "d", "M" + x + ","+y+" L" + (x + iconWidth) + ","+y+""); + if (this.options.shaded.enabled == true) { + fillPath = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer); + if (this.options.shaded.orientation == 'top') { + fillPath.setAttributeNS(null, "d", "M"+x+", " + (y - fillHeight) + + "L"+x+","+y+" L"+ (x + iconWidth) + ","+y+" L"+ (x + iconWidth) + "," + (y - fillHeight)); + } + else { + fillPath.setAttributeNS(null, "d", "M"+x+","+y+" " + + "L"+x+"," + (y + fillHeight) + " " + + "L"+ (x + iconWidth) + "," + (y + fillHeight) + + "L"+ (x + iconWidth) + ","+y); + } + fillPath.setAttributeNS(null, "class", this.className + " iconFill"); + } - return null; + if (this.options.drawPoints.enabled == true) { + DOMutil.drawPoint(x + 0.5 * iconWidth,y, this, JSONcontainer, SVGcontainer); } - }; + } + else { + var barWidth = Math.round(0.3 * iconWidth); + var bar1Height = Math.round(0.4 * iconHeight); + var bar2Height = Math.round(0.75 * iconHeight); + var offset = Math.round((iconWidth - (2 * barWidth))/3); + + DOMutil.drawBar(x + 0.5*barWidth + offset , y + fillHeight - bar1Height - 1, barWidth, bar1Height, this.className + ' bar', JSONcontainer, SVGcontainer); + DOMutil.drawBar(x + 1.5*barWidth + offset + 2, y + fillHeight - bar2Height - 1, barWidth, bar2Height, this.className + ' bar', JSONcontainer, SVGcontainer); + } + }; /** - * @module gestures - */ - /** - * Move with x fingers (default 1) around on the page. - * Preventing the default browser behavior is a good way to improve feel and working. - * ```` - * hammertime.on("drag", function(ev) { - * console.log(ev); - * ev.gesture.preventDefault(); - * }); - * ```` * - * @class Drag - * @static - */ - /** - * @event drag - * @param {Object} ev - */ - /** - * @event dragstart - * @param {Object} ev - */ - /** - * @event dragend - * @param {Object} ev + * @param iconWidth + * @param iconHeight + * @returns {{icon: HTMLElement, label: (group.content|*|string), orientation: (.options.yAxisOrientation|*)}} */ + GraphGroup.prototype.getLegend = function(iconWidth, iconHeight) { + var svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); + this.drawIcon(0,0.5*iconHeight,[],svg,iconWidth,iconHeight); + return {icon: svg, label: this.content, orientation:this.options.yAxisOrientation}; + } + + module.exports = GraphGroup; + + +/***/ }, +/* 24 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var stack = __webpack_require__(17); + var RangeItem = __webpack_require__(34); + /** - * @event drapleft - * @param {Object} ev + * @constructor Group + * @param {Number | String} groupId + * @param {Object} data + * @param {ItemSet} itemSet */ + function Group (groupId, data, itemSet) { + this.groupId = groupId; + this.subgroups = {}; + this.subgroupIndex = 0; + this.subgroupOrderer = data && data.subgroupOrder; + this.itemSet = itemSet; + + this.dom = {}; + this.props = { + label: { + width: 0, + height: 0 + } + }; + this.className = null; + + this.items = {}; // items filtered by groupId of this group + this.visibleItems = []; // items currently visible in window + this.orderedItems = { // items sorted by start and by end + byStart: [], + byEnd: [] + }; + + this._create(); + + this.setData(data); + } + /** - * @event dragright - * @param {Object} ev + * Create DOM elements for the group + * @private */ + Group.prototype._create = function() { + var label = document.createElement('div'); + label.className = 'vlabel'; + this.dom.label = label; + + var inner = document.createElement('div'); + inner.className = 'inner'; + label.appendChild(inner); + this.dom.inner = inner; + + var foreground = document.createElement('div'); + foreground.className = 'group'; + foreground['timeline-group'] = this; + this.dom.foreground = foreground; + + this.dom.background = document.createElement('div'); + this.dom.background.className = 'group'; + + this.dom.axis = document.createElement('div'); + this.dom.axis.className = 'group'; + + // create a hidden marker to detect when the Timelines container is attached + // to the DOM, or the style of a parent of the Timeline is changed from + // display:none is changed to visible. + this.dom.marker = document.createElement('div'); + this.dom.marker.style.visibility = 'hidden'; // TODO: ask jos why this is not none? + this.dom.marker.innerHTML = '?'; + this.dom.background.appendChild(this.dom.marker); + }; + /** - * @event dragup - * @param {Object} ev + * Set the group data for this group + * @param {Object} data Group data, can contain properties content and className */ + Group.prototype.setData = function(data) { + // update contents + var content = data && data.content; + if (content instanceof Element) { + this.dom.inner.appendChild(content); + } + else if (content !== undefined && content !== null) { + this.dom.inner.innerHTML = content; + } + else { + this.dom.inner.innerHTML = this.groupId || ''; // groupId can be null + } + + // update title + this.dom.label.title = data && data.title || ''; + + if (!this.dom.inner.firstChild) { + util.addClassName(this.dom.inner, 'hidden'); + } + else { + util.removeClassName(this.dom.inner, 'hidden'); + } + + // update className + var className = data && data.className || null; + if (className != this.className) { + if (this.className) { + util.removeClassName(this.dom.label, this.className); + util.removeClassName(this.dom.foreground, this.className); + util.removeClassName(this.dom.background, this.className); + util.removeClassName(this.dom.axis, this.className); + } + util.addClassName(this.dom.label, className); + util.addClassName(this.dom.foreground, className); + util.addClassName(this.dom.background, className); + util.addClassName(this.dom.axis, className); + this.className = className; + } + + // update style + if (this.style) { + util.removeCssText(this.dom.label, this.style); + this.style = null; + } + if (data && data.style) { + util.addCssText(this.dom.label, data.style); + this.style = data.style; + } + }; + /** - * @event dragdown - * @param {Object} ev + * Get the width of the group label + * @return {number} width */ + Group.prototype.getLabelWidth = function() { + return this.props.label.width; + }; + /** - * @param {String} name + * Repaint this group + * @param {{start: number, end: number}} range + * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin + * @param {boolean} [restack=false] Force restacking of all items + * @return {boolean} Returns true if the group is resized */ - (function(name) { - var triggered = false; + Group.prototype.redraw = function(range, margin, restack) { + var resized = false; - function dragGesture(ev, inst) { - var cur = Detection.current; + this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range); - // max touches - if(inst.options.dragMaxTouches > 0 && - ev.touches.length > inst.options.dragMaxTouches) { - return; - } + // force recalculation of the height of the items when the marker height changed + // (due to the Timeline being attached to the DOM or changed from display:none to visible) + var markerHeight = this.dom.marker.clientHeight; + if (markerHeight != this.lastMarkerHeight) { + this.lastMarkerHeight = markerHeight; - switch(ev.eventType) { - case EVENT_START: - triggered = false; - break; + util.forEach(this.items, function (item) { + item.dirty = true; + if (item.displayed) item.redraw(); + }); - case EVENT_MOVE: - // when the distance we moved is too small we skip this gesture - // or we can be already in dragging - if(ev.distance < inst.options.dragMinDistance && - cur.name != name) { - return; - } + restack = true; + } - var startCenter = cur.startEvent.center; + // reposition visible items vertically + if (this.itemSet.options.stack) { // TODO: ugly way to access options... + stack.stack(this.visibleItems, margin, restack); + } + else { // no stacking + stack.nostack(this.visibleItems, margin, this.subgroups); + } - // we are dragging! - if(cur.name != name) { - cur.name = name; - if(inst.options.dragDistanceCorrection && ev.distance > 0) { - // When a drag is triggered, set the event center to dragMinDistance pixels from the original event center. - // Without this correction, the dragged distance would jumpstart at dragMinDistance pixels instead of at 0. - // It might be useful to save the original start point somewhere - var factor = Math.abs(inst.options.dragMinDistance / ev.distance); - startCenter.pageX += ev.deltaX * factor; - startCenter.pageY += ev.deltaY * factor; - startCenter.clientX += ev.deltaX * factor; - startCenter.clientY += ev.deltaY * factor; + // recalculate the height of the group + var height = this._calculateHeight(margin); - // recalculate event data using new start point - ev = Detection.extendEventData(ev); - } - } + // calculate actual size and position + var foreground = this.dom.foreground; + this.top = foreground.offsetTop; + this.left = foreground.offsetLeft; + this.width = foreground.offsetWidth; + resized = util.updateProperty(this, 'height', height) || resized; - // lock drag to axis? - if(cur.lastEvent.dragLockToAxis || - ( inst.options.dragLockToAxis && - inst.options.dragLockMinDistance <= ev.distance - )) { - ev.dragLockToAxis = true; - } + // recalculate size of label + resized = util.updateProperty(this.props.label, 'width', this.dom.inner.clientWidth) || resized; + resized = util.updateProperty(this.props.label, 'height', this.dom.inner.clientHeight) || resized; - // keep direction on the axis that the drag gesture started on - var lastDirection = cur.lastEvent.direction; - if(ev.dragLockToAxis && lastDirection !== ev.direction) { - if(Utils.isVertical(lastDirection)) { - ev.direction = (ev.deltaY < 0) ? DIRECTION_UP : DIRECTION_DOWN; - } else { - ev.direction = (ev.deltaX < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT; - } - } + // apply new height + this.dom.background.style.height = height + 'px'; + this.dom.foreground.style.height = height + 'px'; + this.dom.label.style.height = height + 'px'; - // first time, trigger dragstart event - if(!triggered) { - inst.trigger(name + 'start', ev); - triggered = true; - } + // update vertical position of items after they are re-stacked and the height of the group is calculated + for (var i = 0, ii = this.visibleItems.length; i < ii; i++) { + var item = this.visibleItems[i]; + item.repositionY(margin); + } - // trigger events - inst.trigger(name, ev); - inst.trigger(name + ev.direction, ev); + return resized; + }; - var isVertical = Utils.isVertical(ev.direction); + /** + * recalculate the height of the group + * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin + * @returns {number} Returns the height + * @private + */ + Group.prototype._calculateHeight = function (margin) { + // recalculate the height of the group + var height; + var visibleItems = this.visibleItems; + //var visibleSubgroups = []; + //this.visibleSubgroups = 0; + this.resetSubgroups(); + var me = this; + if (visibleItems.length) { + var min = visibleItems[0].top; + var max = visibleItems[0].top + visibleItems[0].height; + util.forEach(visibleItems, function (item) { + min = Math.min(min, item.top); + max = Math.max(max, (item.top + item.height)); + if (item.data.subgroup !== undefined) { + me.subgroups[item.data.subgroup].height = Math.max(me.subgroups[item.data.subgroup].height,item.height); + me.subgroups[item.data.subgroup].visible = true; + //if (visibleSubgroups.indexOf(item.data.subgroup) == -1){ + // visibleSubgroups.push(item.data.subgroup); + // me.visibleSubgroups += 1; + //} + } + }); + if (min > margin.axis) { + // there is an empty gap between the lowest item and the axis + var offset = min - margin.axis; + max -= offset; + util.forEach(visibleItems, function (item) { + item.top -= offset; + }); + } + height = max + margin.item.vertical / 2; + } + else { + height = margin.axis + margin.item.vertical; + } + height = Math.max(height, this.props.label.height); - // block the browser events - if((inst.options.dragBlockVertical && isVertical) || - (inst.options.dragBlockHorizontal && !isVertical)) { - ev.preventDefault(); - } - break; + return height; + }; - case EVENT_RELEASE: - if(triggered && ev.changedLength <= inst.options.dragMaxTouches) { - inst.trigger(name + 'end', ev); - triggered = false; - } - break; + /** + * Show this group: attach to the DOM + */ + Group.prototype.show = function() { + if (!this.dom.label.parentNode) { + this.itemSet.dom.labelSet.appendChild(this.dom.label); + } - case EVENT_END: - triggered = false; - break; - } - } + if (!this.dom.foreground.parentNode) { + this.itemSet.dom.foreground.appendChild(this.dom.foreground); + } - Hammer.gestures.Drag = { - name: name, - index: 50, - handler: dragGesture, - defaults: { - /** - * minimal movement that have to be made before the drag event gets triggered - * @property dragMinDistance - * @type {Number} - * @default 10 - */ - dragMinDistance: 10, + if (!this.dom.background.parentNode) { + this.itemSet.dom.background.appendChild(this.dom.background); + } - /** - * Set dragDistanceCorrection to true to make the starting point of the drag - * be calculated from where the drag was triggered, not from where the touch started. - * Useful to avoid a jerk-starting drag, which can make fine-adjustments - * through dragging difficult, and be visually unappealing. - * @property dragDistanceCorrection - * @type {Boolean} - * @default true - */ - dragDistanceCorrection: true, + if (!this.dom.axis.parentNode) { + this.itemSet.dom.axis.appendChild(this.dom.axis); + } + }; - /** - * set 0 for unlimited, but this can conflict with transform - * @property dragMaxTouches - * @type {Number} - * @default 1 - */ - dragMaxTouches: 1, + /** + * Hide this group: remove from the DOM + */ + Group.prototype.hide = function() { + var label = this.dom.label; + if (label.parentNode) { + label.parentNode.removeChild(label); + } - /** - * prevent default browser behavior when dragging occurs - * be careful with it, it makes the element a blocking element - * when you are using the drag gesture, it is a good practice to set this true - * @property dragBlockHorizontal - * @type {Boolean} - * @default false - */ - dragBlockHorizontal: false, + var foreground = this.dom.foreground; + if (foreground.parentNode) { + foreground.parentNode.removeChild(foreground); + } - /** - * same as `dragBlockHorizontal`, but for vertical movement - * @property dragBlockVertical - * @type {Boolean} - * @default false - */ - dragBlockVertical: false, + var background = this.dom.background; + if (background.parentNode) { + background.parentNode.removeChild(background); + } + + var axis = this.dom.axis; + if (axis.parentNode) { + axis.parentNode.removeChild(axis); + } + }; + + /** + * Add an item to the group + * @param {Item} item + */ + Group.prototype.add = function(item) { + this.items[item.id] = item; + item.setParent(this); + + // add to + if (item.data.subgroup !== undefined) { + if (this.subgroups[item.data.subgroup] === undefined) { + this.subgroups[item.data.subgroup] = {height:0, visible: false, index:this.subgroupIndex, items: []}; + this.subgroupIndex++; + } + this.subgroups[item.data.subgroup].items.push(item); + } + this.orderSubgroups(); + + if (this.visibleItems.indexOf(item) == -1) { + var range = this.itemSet.body.range; // TODO: not nice accessing the range like this + this._checkIfVisible(item, this.visibleItems, range); + } + }; + + Group.prototype.orderSubgroups = function() { + if (this.subgroupOrderer !== undefined) { + var sortArray = []; + if (typeof this.subgroupOrderer == 'string') { + for (var subgroup in this.subgroups) { + sortArray.push({subgroup: subgroup, sortField: this.subgroups[subgroup].items[0].data[this.subgroupOrderer]}) + } + sortArray.sort(function (a, b) { + return a.sortField - b.sortField; + }) + } + else if (typeof this.subgroupOrderer == 'function') { + for (var subgroup in this.subgroups) { + sortArray.push(this.subgroups[subgroup].items[0].data); + } + sortArray.sort(this.subgroupOrderer); + } - /** - * dragLockToAxis keeps the drag gesture on the axis that it started on, - * It disallows vertical directions if the initial direction was horizontal, and vice versa. - * @property dragLockToAxis - * @type {Boolean} - * @default false - */ - dragLockToAxis: false, + if (sortArray.length > 0) { + for (var i = 0; i < sortArray.length; i++) { + this.subgroups[sortArray[i].subgroup].index = i; + } + } + } + }; - /** - * drag lock only kicks in when distance > dragLockMinDistance - * This way, locking occurs only when the distance has become large enough to reliably determine the direction - * @property dragLockMinDistance - * @type {Number} - * @default 25 - */ - dragLockMinDistance: 25 - } - }; - })('drag'); + Group.prototype.resetSubgroups = function() { + for (var subgroup in this.subgroups) { + if (this.subgroups.hasOwnProperty(subgroup)) { + this.subgroups[subgroup].visible = false; + } + } + }; /** - * @module gestures - */ - /** - * trigger a simple gesture event, so you can do anything in your handler. - * only usable if you know what your doing... - * - * @class Gesture - * @static - */ - /** - * @event gesture - * @param {Object} ev + * Remove an item from the group + * @param {Item} item */ - Hammer.gestures.Gesture = { - name: 'gesture', - index: 1337, - handler: function releaseGesture(ev, inst) { - inst.trigger(this.name, ev); - } + Group.prototype.remove = function(item) { + delete this.items[item.id]; + item.setParent(null); + + // remove from visible items + var index = this.visibleItems.indexOf(item); + if (index != -1) this.visibleItems.splice(index, 1); + + // TODO: also remove from ordered items? }; /** - * @module gestures + * Remove an item from the corresponding DataSet + * @param {Item} item */ + Group.prototype.removeFromDataSet = function(item) { + this.itemSet.removeItem(item.id); + }; + /** - * Touch stays at the same place for x time - * - * @class Hold - * @static + * Reorder the items */ + Group.prototype.order = function() { + var array = util.toArray(this.items); + this.orderedItems.byStart = array; + this.orderedItems.byEnd = this._constructByEndArray(array); + + stack.orderByStart(this.orderedItems.byStart); + stack.orderByEnd(this.orderedItems.byEnd); + }; + /** - * @event hold - * @param {Object} ev + * Create an array containing all items being a range (having an end date) + * @param {Item[]} array + * @returns {RangeItem[]} + * @private */ + Group.prototype._constructByEndArray = function(array) { + var endArray = []; + + for (var i = 0; i < array.length; i++) { + if (array[i] instanceof RangeItem) { + endArray.push(array[i]); + } + } + return endArray; + }; /** - * @param {String} name + * Update the visible items + * @param {{byStart: Item[], byEnd: Item[]}} orderedItems All items ordered by start date and by end date + * @param {Item[]} visibleItems The previously visible items. + * @param {{start: number, end: number}} range Visible range + * @return {Item[]} visibleItems The new visible items. + * @private */ - (function(name) { - var timer; - - function holdGesture(ev, inst) { - var options = inst.options, - current = Detection.current; + Group.prototype._updateVisibleItems = function(orderedItems, visibleItems, range) { + var initialPosByStart, + newVisibleItems = [], + i; - switch(ev.eventType) { - case EVENT_START: - clearTimeout(timer); + // first check if the items that were in view previously are still in view. + // this handles the case for the RangeItem that is both before and after the current one. + if (visibleItems.length > 0) { + for (i = 0; i < visibleItems.length; i++) { + this._checkIfVisible(visibleItems[i], newVisibleItems, range); + } + } - // set the gesture so we can check in the timeout if it still is - current.name = name; + // If there were no visible items previously, use binarySearch to find a visible PointItem or RangeItem (based on startTime) + if (newVisibleItems.length == 0) { + initialPosByStart = util.binarySearch(orderedItems.byStart, range, 'data','start'); + } + else { + initialPosByStart = orderedItems.byStart.indexOf(newVisibleItems[0]); + } - // set timer and if after the timeout it still is hold, - // we trigger the hold event - timer = setTimeout(function() { - if(current && current.name == name) { - inst.trigger(name, ev); - } - }, options.holdTimeout); - break; + // use visible search to find a visible RangeItem (only based on endTime) + var initialPosByEnd = util.binarySearch(orderedItems.byEnd, range, 'data','end'); - case EVENT_MOVE: - if(ev.distance > options.holdThreshold) { - clearTimeout(timer); - } - break; + // if we found a initial ID to use, trace it up and down until we meet an invisible item. + if (initialPosByStart != -1) { + for (i = initialPosByStart; i >= 0; i--) { + if (this._checkIfInvisible(orderedItems.byStart[i], newVisibleItems, range)) {break;} + } + for (i = initialPosByStart + 1; i < orderedItems.byStart.length; i++) { + if (this._checkIfInvisible(orderedItems.byStart[i], newVisibleItems, range)) {break;} + } + } - case EVENT_RELEASE: - clearTimeout(timer); - break; - } + // if we found a initial ID to use, trace it up and down until we meet an invisible item. + if (initialPosByEnd != -1) { + for (i = initialPosByEnd; i >= 0; i--) { + if (this._checkIfInvisible(orderedItems.byEnd[i], newVisibleItems, range)) {break;} + } + for (i = initialPosByEnd + 1; i < orderedItems.byEnd.length; i++) { + if (this._checkIfInvisible(orderedItems.byEnd[i], newVisibleItems, range)) {break;} } + } + + return newVisibleItems; + }; - Hammer.gestures.Hold = { - name: name, - index: 10, - defaults: { - /** - * @property holdTimeout - * @type {Number} - * @default 500 - */ - holdTimeout: 500, - /** - * movement allowed while holding - * @property holdThreshold - * @type {Number} - * @default 2 - */ - holdThreshold: 2 - }, - handler: holdGesture - }; - })('hold'); /** - * @module gestures - */ - /** - * when a touch is being released from the page + * this function checks if an item is invisible. If it is NOT we make it visible + * and add it to the global visible items. If it is, return true. * - * @class Release - * @static - */ - /** - * @event release - * @param {Object} ev + * @param {Item} item + * @param {Item[]} visibleItems + * @param {{start:number, end:number}} range + * @returns {boolean} + * @private */ - Hammer.gestures.Release = { - name: 'release', - index: Infinity, - handler: function releaseGesture(ev, inst) { - if(ev.eventType == EVENT_RELEASE) { - inst.trigger(this.name, ev); - } + Group.prototype._checkIfInvisible = function(item, visibleItems, range) { + if (item.isVisible(range)) { + if (!item.displayed) item.show(); + item.repositionX(); + if (visibleItems.indexOf(item) == -1) { + visibleItems.push(item); + } + return false; + } + else { + if (item.displayed) item.hide(); + return true; } }; /** - * @module gestures - */ - /** - * triggers swipe events when the end velocity is above the threshold - * for best usage, set `preventDefault` (on the drag gesture) to `true` - * ```` - * hammertime.on("dragleft swipeleft", function(ev) { - * console.log(ev); - * ev.gesture.preventDefault(); - * }); - * ```` + * this function is very similar to the _checkIfInvisible() but it does not + * return booleans, hides the item if it should not be seen and always adds to + * the visibleItems. + * this one is for brute forcing and hiding. * - * @class Swipe - * @static - */ - /** - * @event swipe - * @param {Object} ev + * @param {Item} item + * @param {Array} visibleItems + * @param {{start:number, end:number}} range + * @private */ + Group.prototype._checkIfVisible = function(item, visibleItems, range) { + if (item.isVisible(range)) { + if (!item.displayed) item.show(); + // reposition item horizontally + item.repositionX(); + visibleItems.push(item); + } + else { + if (item.displayed) item.hide(); + } + }; + + module.exports = Group; + + +/***/ }, +/* 25 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var Group = __webpack_require__(24); + /** - * @event swipeleft - * @param {Object} ev + * @constructor BackgroundGroup + * @param {Number | String} groupId + * @param {Object} data + * @param {ItemSet} itemSet */ + function BackgroundGroup (groupId, data, itemSet) { + Group.call(this, groupId, data, itemSet); + + this.width = 0; + this.height = 0; + this.top = 0; + this.left = 0; + } + + BackgroundGroup.prototype = Object.create(Group.prototype); + /** - * @event swiperight - * @param {Object} ev + * Repaint this group + * @param {{start: number, end: number}} range + * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin + * @param {boolean} [restack=false] Force restacking of all items + * @return {boolean} Returns true if the group is resized */ + BackgroundGroup.prototype.redraw = function(range, margin, restack) { + var resized = false; + + this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range); + + // calculate actual size + this.width = this.dom.background.offsetWidth; + + // apply new height (just always zero for BackgroundGroup + this.dom.background.style.height = '0'; + + // update vertical position of items after they are re-stacked and the height of the group is calculated + for (var i = 0, ii = this.visibleItems.length; i < ii; i++) { + var item = this.visibleItems[i]; + item.repositionY(margin); + } + + return resized; + }; + /** - * @event swipeup - * @param {Object} ev + * Show this group: attach to the DOM */ + BackgroundGroup.prototype.show = function() { + if (!this.dom.background.parentNode) { + this.itemSet.dom.background.appendChild(this.dom.background); + } + }; + + module.exports = BackgroundGroup; + + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + var Hammer = __webpack_require__(44); + var util = __webpack_require__(1); + var DataSet = __webpack_require__(3); + var DataView = __webpack_require__(4); + var Component = __webpack_require__(19); + var Group = __webpack_require__(24); + var BackgroundGroup = __webpack_require__(25); + var BoxItem = __webpack_require__(32); + var PointItem = __webpack_require__(33); + var RangeItem = __webpack_require__(34); + var BackgroundItem = __webpack_require__(31); + + + var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items + var BACKGROUND = '__background__'; // reserved group id for background items without group + /** - * @event swipedown - * @param {Object} ev + * An ItemSet holds a set of items and ranges which can be displayed in a + * range. The width is determined by the parent of the ItemSet, and the height + * is determined by the size of the items. + * @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} body + * @param {Object} [options] See ItemSet.setOptions for the available options. + * @constructor ItemSet + * @extends Component */ - Hammer.gestures.Swipe = { - name: 'swipe', - index: 40, - defaults: { - /** - * @property swipeMinTouches - * @type {Number} - * @default 1 - */ - swipeMinTouches: 1, + function ItemSet(body, options) { + this.body = body; - /** - * @property swipeMaxTouches - * @type {Number} - * @default 1 - */ - swipeMaxTouches: 1, + this.defaultOptions = { + type: null, // 'box', 'point', 'range', 'background' + orientation: 'bottom', // 'top' or 'bottom' + align: 'auto', // alignment of box items + stack: true, + groupOrder: null, - /** - * horizontal swipe velocity - * @property swipeVelocityX - * @type {Number} - * @default 0.6 - */ - swipeVelocityX: 0.6, + selectable: true, + editable: { + updateTime: false, + updateGroup: false, + add: false, + remove: false + }, - /** - * vertical swipe velocity - * @property swipeVelocityY - * @type {Number} - * @default 0.6 - */ - swipeVelocityY: 0.6 + onAdd: function (item, callback) { + callback(item); + }, + onUpdate: function (item, callback) { + callback(item); + }, + onMove: function (item, callback) { + callback(item); + }, + onRemove: function (item, callback) { + callback(item); + }, + onMoving: function (item, callback) { + callback(item); }, - handler: function swipeGesture(ev, inst) { - if(ev.eventType == EVENT_RELEASE) { - var touches = ev.touches.length, - options = inst.options; + margin: { + item: { + horizontal: 10, + vertical: 10 + }, + axis: 20 + }, + padding: 5 + }; - // max touches - if(touches < options.swipeMinTouches || - touches > options.swipeMaxTouches) { - return; - } + // options is shared by this ItemSet and all its items + this.options = util.extend({}, this.defaultOptions); - // when the distance we moved is too small we skip this gesture - // or we can be already in dragging - if(ev.velocityX > options.swipeVelocityX || - ev.velocityY > options.swipeVelocityY) { - // trigger swipe events - inst.trigger(this.name, ev); - inst.trigger(this.name + ev.direction, ev); - } - } + // options for getting items from the DataSet with the correct type + this.itemOptions = { + type: {start: 'Date', end: 'Date'} + }; + + this.conversion = { + toScreen: body.util.toScreen, + toTime: body.util.toTime + }; + this.dom = {}; + this.props = {}; + this.hammer = null; + + var me = this; + this.itemsData = null; // DataSet + this.groupsData = null; // DataSet + + // listeners for the DataSet of the items + this.itemListeners = { + 'add': function (event, params, senderId) { + me._onAdd(params.items); + }, + 'update': function (event, params, senderId) { + me._onUpdate(params.items); + }, + 'remove': function (event, params, senderId) { + me._onRemove(params.items); + } + }; + + // listeners for the DataSet of the groups + this.groupListeners = { + 'add': function (event, params, senderId) { + me._onAddGroups(params.items); + }, + 'update': function (event, params, senderId) { + me._onUpdateGroups(params.items); + }, + 'remove': function (event, params, senderId) { + me._onRemoveGroups(params.items); } + }; + + this.items = {}; // object with an Item for every data item + this.groups = {}; // Group object for every group + this.groupIds = []; + + this.selection = []; // list with the ids of all selected nodes + this.stackDirty = true; // if true, all items will be restacked on next redraw + + this.touchParams = {}; // stores properties while dragging + // create the HTML DOM + + this._create(); + + this.setOptions(options); + } + + ItemSet.prototype = new Component(); + + // available item types will be registered here + ItemSet.types = { + background: BackgroundItem, + box: BoxItem, + range: RangeItem, + point: PointItem }; /** - * @module gestures - */ - /** - * Single tap and a double tap on a place - * - * @class Tap - * @static - */ - /** - * @event tap - * @param {Object} ev - */ - /** - * @event doubletap - * @param {Object} ev + * Create the HTML DOM for the ItemSet */ + ItemSet.prototype._create = function(){ + var frame = document.createElement('div'); + frame.className = 'itemset'; + frame['timeline-itemset'] = this; + this.dom.frame = frame; - /** - * @param {String} name - */ - (function(name) { - var hasMoved = false; + // create background panel + var background = document.createElement('div'); + background.className = 'background'; + frame.appendChild(background); + this.dom.background = background; - function tapGesture(ev, inst) { - var options = inst.options, - current = Detection.current, - prev = Detection.previous, - sincePrev, - didDoubleTap; + // create foreground panel + var foreground = document.createElement('div'); + foreground.className = 'foreground'; + frame.appendChild(foreground); + this.dom.foreground = foreground; - switch(ev.eventType) { - case EVENT_START: - hasMoved = false; - break; + // create axis panel + var axis = document.createElement('div'); + axis.className = 'axis'; + this.dom.axis = axis; - case EVENT_MOVE: - hasMoved = hasMoved || (ev.distance > options.tapMaxDistance); - break; + // create labelset + var labelSet = document.createElement('div'); + labelSet.className = 'labelset'; + this.dom.labelSet = labelSet; - case EVENT_END: - if(!Utils.inStr(ev.srcEvent.type, 'cancel') && ev.deltaTime < options.tapMaxTime && !hasMoved) { - // previous gesture, for the double tap since these are two different gesture detections - sincePrev = prev && prev.lastEvent && ev.timeStamp - prev.lastEvent.timeStamp; - didDoubleTap = false; + // create ungrouped Group + this._updateUngrouped(); - // check if double tap - if(prev && prev.name == name && - (sincePrev && sincePrev < options.doubleTapInterval) && - ev.distance < options.doubleTapDistance) { - inst.trigger('doubletap', ev); - didDoubleTap = true; - } + // create background Group + var backgroundGroup = new BackgroundGroup(BACKGROUND, null, this); + backgroundGroup.show(); + this.groups[BACKGROUND] = backgroundGroup; - // do a single tap - if(!didDoubleTap || options.tapAlways) { - current.name = name; - inst.trigger(current.name, ev); - } - } - break; - } - } + // attach event listeners + // Note: we bind to the centerContainer for the case where the height + // of the center container is larger than of the ItemSet, so we + // can click in the empty area to create a new item or deselect an item. + this.hammer = Hammer(this.body.dom.centerContainer, { + prevent_default: true + }); - Hammer.gestures.Tap = { - name: name, - index: 100, - handler: tapGesture, - defaults: { - /** - * max time of a tap, this is for the slow tappers - * @property tapMaxTime - * @type {Number} - * @default 250 - */ - tapMaxTime: 250, + // drag items when selected + this.hammer.on('touch', this._onTouch.bind(this)); + this.hammer.on('dragstart', this._onDragStart.bind(this)); + this.hammer.on('drag', this._onDrag.bind(this)); + this.hammer.on('dragend', this._onDragEnd.bind(this)); - /** - * max distance of movement of a tap, this is for the slow tappers - * @property tapMaxDistance - * @type {Number} - * @default 10 - */ - tapMaxDistance: 10, + // single select (or unselect) when tapping an item + this.hammer.on('tap', this._onSelectItem.bind(this)); - /** - * always trigger the `tap` event, even while double-tapping - * @property tapAlways - * @type {Boolean} - * @default true - */ - tapAlways: true, + // multi select when holding mouse/touch, or on ctrl+click + this.hammer.on('hold', this._onMultiSelectItem.bind(this)); - /** - * max distance between two taps - * @property doubleTapDistance - * @type {Number} - * @default 20 - */ - doubleTapDistance: 20, + // add item on doubletap + this.hammer.on('doubletap', this._onAddItem.bind(this)); - /** - * max time between two taps - * @property doubleTapInterval - * @type {Number} - * @default 300 - */ - doubleTapInterval: 300 - } - }; - })('tap'); + // attach to the DOM + this.show(); + }; /** - * @module gestures - */ - /** - * when a touch is being touched at the page - * - * @class Touch - * @static - */ - /** - * @event touch - * @param {Object} ev + * Set options for the ItemSet. Existing options will be extended/overwritten. + * @param {Object} [options] The following options are available: + * {String} type + * Default type for the items. Choose from 'box' + * (default), 'point', 'range', or 'background'. + * The default style can be overwritten by + * individual items. + * {String} align + * Alignment for the items, only applicable for + * BoxItem. Choose 'center' (default), 'left', or + * 'right'. + * {String} orientation + * Orientation of the item set. Choose 'top' or + * 'bottom' (default). + * {Function} groupOrder + * A sorting function for ordering groups + * {Boolean} stack + * If true (deafult), items will be stacked on + * top of each other. + * {Number} margin.axis + * Margin between the axis and the items in pixels. + * Default is 20. + * {Number} margin.item.horizontal + * Horizontal margin between items in pixels. + * Default is 10. + * {Number} margin.item.vertical + * Vertical Margin between items in pixels. + * Default is 10. + * {Number} margin.item + * Margin between items in pixels in both horizontal + * and vertical direction. Default is 10. + * {Number} margin + * Set margin for both axis and items in pixels. + * {Number} padding + * Padding of the contents of an item in pixels. + * Must correspond with the items css. Default is 5. + * {Boolean} selectable + * If true (default), items can be selected. + * {Boolean} editable + * Set all editable options to true or false + * {Boolean} editable.updateTime + * Allow dragging an item to an other moment in time + * {Boolean} editable.updateGroup + * Allow dragging an item to an other group + * {Boolean} editable.add + * Allow creating new items on double tap + * {Boolean} editable.remove + * Allow removing items by clicking the delete button + * top right of a selected item. + * {Function(item: Item, callback: Function)} onAdd + * Callback function triggered when an item is about to be added: + * when the user double taps an empty space in the Timeline. + * {Function(item: Item, callback: Function)} onUpdate + * Callback function fired when an item is about to be updated. + * This function typically has to show a dialog where the user + * change the item. If not implemented, nothing happens. + * {Function(item: Item, callback: Function)} onMove + * Fired when an item has been moved. If not implemented, + * the move action will be accepted. + * {Function(item: Item, callback: Function)} onRemove + * Fired when an item is about to be deleted. + * If not implemented, the item will be always removed. */ - Hammer.gestures.Touch = { - name: 'touch', - index: -Infinity, - defaults: { - /** - * call preventDefault at touchstart, and makes the element blocking by disabling the scrolling of the page, - * but it improves gestures like transforming and dragging. - * be careful with using this, it can be very annoying for users to be stuck on the page - * @property preventDefault - * @type {Boolean} - * @default false - */ - preventDefault: false, + ItemSet.prototype.setOptions = function(options) { + if (options) { + // copy all options that we know + var fields = ['type', 'align', 'orientation', 'padding', 'stack', 'selectable', 'groupOrder', 'dataAttributes', 'template','hide']; + util.selectiveExtend(fields, this.options, options); - /** - * disable mouse events, so only touch (or pen!) input triggers events - * @property preventMouse - * @type {Boolean} - * @default false - */ - preventMouse: false - }, - handler: function touchGesture(ev, inst) { - if(inst.options.preventMouse && ev.pointerType == POINTER_MOUSE) { - ev.stopDetect(); - return; + if ('margin' in options) { + if (typeof options.margin === 'number') { + this.options.margin.axis = options.margin; + this.options.margin.item.horizontal = options.margin; + this.options.margin.item.vertical = options.margin; + } + else if (typeof options.margin === 'object') { + util.selectiveExtend(['axis'], this.options.margin, options.margin); + if ('item' in options.margin) { + if (typeof options.margin.item === 'number') { + this.options.margin.item.horizontal = options.margin.item; + this.options.margin.item.vertical = options.margin.item; + } + else if (typeof options.margin.item === 'object') { + util.selectiveExtend(['horizontal', 'vertical'], this.options.margin.item, options.margin.item); + } } + } + } - if(inst.options.preventDefault) { - ev.preventDefault(); - } + if ('editable' in options) { + if (typeof options.editable === 'boolean') { + this.options.editable.updateTime = options.editable; + this.options.editable.updateGroup = options.editable; + this.options.editable.add = options.editable; + this.options.editable.remove = options.editable; + } + else if (typeof options.editable === 'object') { + util.selectiveExtend(['updateTime', 'updateGroup', 'add', 'remove'], this.options.editable, options.editable); + } + } - if(ev.eventType == EVENT_TOUCH) { - inst.trigger('touch', ev); + // callback functions + var addCallback = (function (name) { + var fn = options[name]; + if (fn) { + if (!(fn instanceof Function)) { + throw new Error('option ' + name + ' must be a function ' + name + '(item, callback)'); } - } + this.options[name] = fn; + } + }).bind(this); + ['onAdd', 'onUpdate', 'onRemove', 'onMove', 'onMoving'].forEach(addCallback); + + // force the itemSet to refresh: options like orientation and margins may be changed + this.markDirty(); + } }; /** - * @module gestures + * Mark the ItemSet dirty so it will refresh everything with next redraw */ + ItemSet.prototype.markDirty = function() { + this.groupIds = []; + this.stackDirty = true; + }; + /** - * User want to scale or rotate with 2 fingers - * Preventing the default browser behavior is a good way to improve feel and working. This can be done with the - * `preventDefault` option. - * - * @class Transform - * @static + * Destroy the ItemSet */ + ItemSet.prototype.destroy = function() { + this.hide(); + this.setItems(null); + this.setGroups(null); + + this.hammer = null; + + this.body = null; + this.conversion = null; + }; + /** - * @event transform - * @param {Object} ev + * Hide the component from the DOM */ + ItemSet.prototype.hide = function() { + // remove the frame containing the items + if (this.dom.frame.parentNode) { + this.dom.frame.parentNode.removeChild(this.dom.frame); + } + + // remove the axis with dots + if (this.dom.axis.parentNode) { + this.dom.axis.parentNode.removeChild(this.dom.axis); + } + + // remove the labelset containing all group labels + if (this.dom.labelSet.parentNode) { + this.dom.labelSet.parentNode.removeChild(this.dom.labelSet); + } + }; + /** - * @event transformstart - * @param {Object} ev + * Show the component in the DOM (when not already visible). + * @return {Boolean} changed */ + ItemSet.prototype.show = function() { + // show frame containing the items + if (!this.dom.frame.parentNode) { + this.body.dom.center.appendChild(this.dom.frame); + } + + // show axis with dots + if (!this.dom.axis.parentNode) { + this.body.dom.backgroundVertical.appendChild(this.dom.axis); + } + + // show labelset containing labels + if (!this.dom.labelSet.parentNode) { + this.body.dom.left.appendChild(this.dom.labelSet); + } + }; + /** - * @event transformend - * @param {Object} ev + * Set selected items by their id. Replaces the current selection + * Unknown id's are silently ignored. + * @param {string[] | string} [ids] An array with zero or more id's of the items to be + * selected, or a single item id. If ids is undefined + * or an empty array, all items will be unselected. */ + ItemSet.prototype.setSelection = function(ids) { + var i, ii, id, item; + + if (ids == undefined) ids = []; + if (!Array.isArray(ids)) ids = [ids]; + + // unselect currently selected items + for (i = 0, ii = this.selection.length; i < ii; i++) { + id = this.selection[i]; + item = this.items[id]; + if (item) item.unselect(); + } + + // select items + this.selection = []; + for (i = 0, ii = ids.length; i < ii; i++) { + id = ids[i]; + item = this.items[id]; + if (item) { + this.selection.push(id); + item.select(); + } + } + }; + /** - * @event pinchin - * @param {Object} ev + * Get the selected items by their id + * @return {Array} ids The ids of the selected items */ + ItemSet.prototype.getSelection = function() { + return this.selection.concat([]); + }; + /** - * @event pinchout - * @param {Object} ev + * Get the id's of the currently visible items. + * @returns {Array} The ids of the visible items */ + ItemSet.prototype.getVisibleItems = function() { + var range = this.body.range.getRange(); + var left = this.body.util.toScreen(range.start); + var right = this.body.util.toScreen(range.end); + + var ids = []; + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + var group = this.groups[groupId]; + var rawVisibleItems = group.visibleItems; + + // filter the "raw" set with visibleItems into a set which is really + // visible by pixels + for (var i = 0; i < rawVisibleItems.length; i++) { + var item = rawVisibleItems[i]; + // TODO: also check whether visible vertically + if ((item.left < right) && (item.left + item.width > left)) { + ids.push(item.id); + } + } + } + } + + return ids; + }; + /** - * @event rotate - * @param {Object} ev + * Deselect a selected item + * @param {String | Number} id + * @private */ + ItemSet.prototype._deselect = function(id) { + var selection = this.selection; + for (var i = 0, ii = selection.length; i < ii; i++) { + if (selection[i] == id) { // non-strict comparison! + selection.splice(i, 1); + break; + } + } + }; /** - * @param {String} name + * Repaint the component + * @return {boolean} Returns true if the component is resized */ - (function(name) { - var triggered = false; + ItemSet.prototype.redraw = function() { + var margin = this.options.margin, + range = this.body.range, + asSize = util.option.asSize, + options = this.options, + orientation = options.orientation, + resized = false, + frame = this.dom.frame, + editable = options.editable.updateTime || options.editable.updateGroup; - function transformGesture(ev, inst) { - switch(ev.eventType) { - case EVENT_START: - triggered = false; - break; + // recalculate absolute position (before redrawing groups) + this.props.top = this.body.domProps.top.height + this.body.domProps.border.top; + this.props.left = this.body.domProps.left.width + this.body.domProps.border.left; - case EVENT_MOVE: - // at least multitouch - if(ev.touches.length < 2) { - return; - } + // update class name + frame.className = 'itemset' + (editable ? ' editable' : ''); + + // reorder the groups (if needed) + resized = this._orderGroups() || resized; + + // check whether zoomed (in that case we need to re-stack everything) + // TODO: would be nicer to get this as a trigger from Range + var visibleInterval = range.end - range.start; + var zoomed = (visibleInterval != this.lastVisibleInterval) || (this.props.width != this.props.lastWidth); + if (zoomed) this.stackDirty = true; + this.lastVisibleInterval = visibleInterval; + this.props.lastWidth = this.props.width; + + var restack = this.stackDirty; + var firstGroup = this._firstGroup(); + var firstMargin = { + item: margin.item, + axis: margin.axis + }; + var nonFirstMargin = { + item: margin.item, + axis: margin.item.vertical / 2 + }; + var height = 0; + var minHeight = margin.axis + margin.item.vertical; + + // redraw the background group + this.groups[BACKGROUND].redraw(range, nonFirstMargin, restack); + + // redraw all regular groups + util.forEach(this.groups, function (group) { + var groupMargin = (group == firstGroup) ? firstMargin : nonFirstMargin; + var groupResized = group.redraw(range, groupMargin, restack); + resized = groupResized || resized; + height += group.height; + }); + height = Math.max(height, minHeight); + this.stackDirty = false; + + // update frame height + frame.style.height = asSize(height); - var scaleThreshold = Math.abs(1 - ev.scale); - var rotationThreshold = Math.abs(ev.rotation); + // calculate actual size + this.props.width = frame.offsetWidth; + this.props.height = height; - // when the distance we moved is too small we skip this gesture - // or we can be already in dragging - if(scaleThreshold < inst.options.transformMinScale && - rotationThreshold < inst.options.transformMinRotation) { - return; - } + // reposition axis + this.dom.axis.style.top = asSize((orientation == 'top') ? + (this.body.domProps.top.height + this.body.domProps.border.top) : + (this.body.domProps.top.height + this.body.domProps.centerContainer.height)); + this.dom.axis.style.left = '0'; - // we are transforming! - Detection.current.name = name; + // check if this component is resized + resized = this._isResized() || resized; - // first time, trigger dragstart event - if(!triggered) { - inst.trigger(name + 'start', ev); - triggered = true; - } + return resized; + }; - inst.trigger(name, ev); // basic transform event + /** + * Get the first group, aligned with the axis + * @return {Group | null} firstGroup + * @private + */ + ItemSet.prototype._firstGroup = function() { + var firstGroupIndex = (this.options.orientation == 'top') ? 0 : (this.groupIds.length - 1); + var firstGroupId = this.groupIds[firstGroupIndex]; + var firstGroup = this.groups[firstGroupId] || this.groups[UNGROUPED]; - // trigger rotate event - if(rotationThreshold > inst.options.transformMinRotation) { - inst.trigger('rotate', ev); - } + return firstGroup || null; + }; - // trigger pinch event - if(scaleThreshold > inst.options.transformMinScale) { - inst.trigger('pinch', ev); - inst.trigger('pinch' + (ev.scale < 1 ? 'in' : 'out'), ev); - } - break; + /** + * Create or delete the group holding all ungrouped items. This group is used when + * there are no groups specified. + * @protected + */ + ItemSet.prototype._updateUngrouped = function() { + var ungrouped = this.groups[UNGROUPED]; + var background = this.groups[BACKGROUND]; + var item, itemId; - case EVENT_RELEASE: - if(triggered && ev.changedLength < 2) { - inst.trigger(name + 'end', ev); - triggered = false; - } - break; + if (this.groupsData) { + // remove the group holding all ungrouped items + if (ungrouped) { + ungrouped.hide(); + delete this.groups[UNGROUPED]; + + for (itemId in this.items) { + if (this.items.hasOwnProperty(itemId)) { + item = this.items[itemId]; + item.parent && item.parent.remove(item); + var groupId = this._getGroupId(item.data); + var group = this.groups[groupId]; + group && group.add(item) || item.hide(); } + } } + } + else { + // create a group holding all (unfiltered) items + if (!ungrouped) { + var id = null; + var data = null; + ungrouped = new Group(id, data, this); + this.groups[UNGROUPED] = ungrouped; - Hammer.gestures.Transform = { - name: name, - index: 45, - defaults: { - /** - * minimal scale factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1 - * @property transformMinScale - * @type {Number} - * @default 0.01 - */ - transformMinScale: 0.01, + for (itemId in this.items) { + if (this.items.hasOwnProperty(itemId)) { + item = this.items[itemId]; + ungrouped.add(item); + } + } - /** - * rotation in degrees - * @property transformMinRotation - * @type {Number} - * @default 1 - */ - transformMinRotation: 1 - }, + ungrouped.show(); + } + } + }; - handler: transformGesture - }; - })('transform'); + /** + * Get the element for the labelset + * @return {HTMLElement} labelSet + */ + ItemSet.prototype.getLabelSet = function() { + return this.dom.labelSet; + }; /** - * @module hammer + * Set items + * @param {vis.DataSet | null} items */ + ItemSet.prototype.setItems = function(items) { + var me = this, + ids, + oldItemsData = this.itemsData; - // AMD export - if(true) { - !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { - return Hammer; - }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - // commonjs export - } else if(typeof module !== 'undefined' && module.exports) { - module.exports = Hammer; - // browser export - } else { - window.Hammer = Hammer; - } + // replace the dataset + if (!items) { + this.itemsData = null; + } + else if (items instanceof DataSet || items instanceof DataView) { + this.itemsData = items; + } + else { + throw new TypeError('Data must be an instance of DataSet or DataView'); + } - })(window); + if (oldItemsData) { + // unsubscribe from old dataset + util.forEach(this.itemListeners, function (callback, event) { + oldItemsData.off(event, callback); + }); -/***/ }, -/* 20 */ -/***/ function(module, exports, __webpack_require__) { + // remove all drawn items + ids = oldItemsData.getIds(); + this._onRemove(ids); + } - var util = __webpack_require__(1); - var hammerUtil = __webpack_require__(21); - var moment = __webpack_require__(2); - var Component = __webpack_require__(22); - var DateUtil = __webpack_require__(23); + if (this.itemsData) { + // subscribe to new dataset + var id = this.id; + util.forEach(this.itemListeners, function (callback, event) { + me.itemsData.on(event, callback, id); + }); - /** - * @constructor Range - * A Range controls a numeric range with a start and end value. - * The Range adjusts the range based on mouse events or programmatic changes, - * and triggers events when the range is changing or has been changed. - * @param {{dom: Object, domProps: Object, emitter: Emitter}} body - * @param {Object} [options] See description at Range.setOptions - */ - function Range(body, options) { - var now = moment().hours(0).minutes(0).seconds(0).milliseconds(0); - this.start = now.clone().add(-3, 'days').valueOf(); // Number - this.end = now.clone().add(4, 'days').valueOf(); // Number + // add all new items + ids = this.itemsData.getIds(); + this._onAdd(ids); - this.body = body; - this.deltaDifference = 0; - this.scaleOffset = 0; - this.startToFront = false; - this.endToFront = true; + // update the group holding all ungrouped items + this._updateUngrouped(); + } + }; - // default options - this.defaultOptions = { - start: null, - end: null, - direction: 'horizontal', // 'horizontal' or 'vertical' - moveable: true, - zoomable: true, - min: null, - max: null, - zoomMin: 10, // milliseconds - zoomMax: 1000 * 60 * 60 * 24 * 365 * 10000 // milliseconds - }; - this.options = util.extend({}, this.defaultOptions); + /** + * Get the current items + * @returns {vis.DataSet | null} + */ + ItemSet.prototype.getItems = function() { + return this.itemsData; + }; - this.props = { - touch: {} - }; - this.animateTimer = null; + /** + * Set groups + * @param {vis.DataSet} groups + */ + ItemSet.prototype.setGroups = function(groups) { + var me = this, + ids; - // drag listeners for dragging - this.body.emitter.on('dragstart', this._onDragStart.bind(this)); - this.body.emitter.on('drag', this._onDrag.bind(this)); - this.body.emitter.on('dragend', this._onDragEnd.bind(this)); + // unsubscribe from current dataset + if (this.groupsData) { + util.forEach(this.groupListeners, function (callback, event) { + me.groupsData.unsubscribe(event, callback); + }); - // ignore dragging when holding - this.body.emitter.on('hold', this._onHold.bind(this)); + // remove all drawn groups + ids = this.groupsData.getIds(); + this.groupsData = null; + this._onRemoveGroups(ids); // note: this will cause a redraw + } - // mouse wheel for zooming - this.body.emitter.on('mousewheel', this._onMouseWheel.bind(this)); - this.body.emitter.on('DOMMouseScroll', this._onMouseWheel.bind(this)); // For FF + // replace the dataset + if (!groups) { + this.groupsData = null; + } + else if (groups instanceof DataSet || groups instanceof DataView) { + this.groupsData = groups; + } + else { + throw new TypeError('Data must be an instance of DataSet or DataView'); + } - // pinch to zoom - this.body.emitter.on('touch', this._onTouch.bind(this)); - this.body.emitter.on('pinch', this._onPinch.bind(this)); + if (this.groupsData) { + // subscribe to new dataset + var id = this.id; + util.forEach(this.groupListeners, function (callback, event) { + me.groupsData.on(event, callback, id); + }); - this.setOptions(options); - } + // draw all ms + ids = this.groupsData.getIds(); + this._onAddGroups(ids); + } - Range.prototype = new Component(); + // update the group holding all ungrouped items + this._updateUngrouped(); - /** - * Set options for the range controller - * @param {Object} options Available options: - * {Number | Date | String} start Start date for the range - * {Number | Date | String} end End date for the range - * {Number} min Minimum value for start - * {Number} max Maximum value for end - * {Number} zoomMin Set a minimum value for - * (end - start). - * {Number} zoomMax Set a maximum value for - * (end - start). - * {Boolean} moveable Enable moving of the range - * by dragging. True by default - * {Boolean} zoomable Enable zooming of the range - * by pinching/scrolling. True by default - */ - Range.prototype.setOptions = function (options) { - if (options) { - // copy the options that we know - var fields = ['direction', 'min', 'max', 'zoomMin', 'zoomMax', 'moveable', 'zoomable', 'activate', 'hiddenDates']; - util.selectiveExtend(fields, this.options, options); + // update the order of all items in each group + this._order(); - if ('start' in options || 'end' in options) { - // apply a new range. both start and end are optional - this.setRange(options.start, options.end); - } - } + this.body.emitter.emit('change'); }; /** - * Test whether direction has a valid value - * @param {String} direction 'horizontal' or 'vertical' + * Get the current groups + * @returns {vis.DataSet | null} groups */ - function validateDirection (direction) { - if (direction != 'horizontal' && direction != 'vertical') { - throw new TypeError('Unknown direction "' + direction + '". ' + - 'Choose "horizontal" or "vertical".'); - } - } + ItemSet.prototype.getGroups = function() { + return this.groupsData; + }; /** - * Set a new start and end range - * @param {Date | Number | String} [start] - * @param {Date | Number | String} [end] - * @param {boolean | number} [animate=false] If true, the range is animated - * smoothly to the new window. - * If animate is a number, the - * number is taken as duration - * Default duration is 500 ms. - * + * Remove an item by its id + * @param {String | Number} id */ - Range.prototype.setRange = function(start, end, animate) { - var _start = start != undefined ? util.convert(start, 'Date').valueOf() : null; - var _end = end != undefined ? util.convert(end, 'Date').valueOf() : null; - this._cancelAnimation(); - - if (animate) { - var me = this; - var initStart = this.start; - var initEnd = this.end; - var duration = typeof animate === 'number' ? animate : 500; - var initTime = new Date().valueOf(); - var anyChanged = false; - - function next() { - if (!me.props.touch.dragging) { - var now = new Date().valueOf(); - var time = now - initTime; - var done = time > duration; - var s = (done || _start === null) ? _start : util.easeInOutQuad(time, initStart, _start, duration); - var e = (done || _end === null) ? _end : util.easeInOutQuad(time, initEnd, _end, duration); - - changed = me._applyRange(s, e); - DateUtil.updateHiddenDates(me.body, me.options.hiddenDates); - anyChanged = anyChanged || changed; - if (changed) { - me.body.emitter.emit('rangechange', {start: new Date(me.start), end: new Date(me.end)}); - } + ItemSet.prototype.removeItem = function(id) { + var item = this.itemsData.get(id), + dataset = this.itemsData.getDataSet(); - if (done) { - if (anyChanged) { - me.body.emitter.emit('rangechanged', {start: new Date(me.start), end: new Date(me.end)}); - } - } - else { - // animate with as high as possible frame rate, leave 20 ms in between - // each to prevent the browser from blocking - me.animateTimer = setTimeout(next, 20); - } + if (item) { + // confirm deletion + this.options.onRemove(item, function (item) { + if (item) { + // remove by id here, it is possible that an item has no id defined + // itself, so better not delete by the item itself + dataset.remove(id); } - } - - return next(); - } - else { - var changed = this._applyRange(_start, _end); - DateUtil.updateHiddenDates(this.body, this.options.hiddenDates); - if (changed) { - var params = {start: new Date(this.start), end: new Date(this.end)}; - this.body.emitter.emit('rangechange', params); - this.body.emitter.emit('rangechanged', params); - } + }); } }; /** - * Stop an animation + * Get the time of an item based on it's data and options.type + * @param {Object} itemData + * @returns {string} Returns the type * @private */ - Range.prototype._cancelAnimation = function () { - if (this.animateTimer) { - clearTimeout(this.animateTimer); - this.animateTimer = null; - } + ItemSet.prototype._getType = function (itemData) { + return itemData.type || this.options.type || (itemData.end ? 'range' : 'box'); }; + /** - * Set a new start and end range. This method is the same as setRange, but - * does not trigger a range change and range changed event, and it returns - * true when the range is changed - * @param {Number} [start] - * @param {Number} [end] - * @return {Boolean} changed + * Get the group id for an item + * @param {Object} itemData + * @returns {string} Returns the groupId * @private */ - Range.prototype._applyRange = function(start, end) { - var newStart = (start != null) ? util.convert(start, 'Date').valueOf() : this.start, - newEnd = (end != null) ? util.convert(end, 'Date').valueOf() : this.end, - max = (this.options.max != null) ? util.convert(this.options.max, 'Date').valueOf() : null, - min = (this.options.min != null) ? util.convert(this.options.min, 'Date').valueOf() : null, - diff; - - // check for valid number - if (isNaN(newStart) || newStart === null) { - throw new Error('Invalid start "' + start + '"'); - } - if (isNaN(newEnd) || newEnd === null) { - throw new Error('Invalid end "' + end + '"'); + ItemSet.prototype._getGroupId = function (itemData) { + var type = this._getType(itemData); + if (type == 'background' && itemData.group == undefined) { + return BACKGROUND; } - - // prevent start < end - if (newEnd < newStart) { - newEnd = newStart; + else { + return this.groupsData ? itemData.group : UNGROUPED; } + }; - // prevent start < min - if (min !== null) { - if (newStart < min) { - diff = (min - newStart); - newStart += diff; - newEnd += diff; - - // prevent end > max - if (max != null) { - if (newEnd > max) { - newEnd = max; - } - } - } - } + /** + * Handle updated items + * @param {Number[]} ids + * @protected + */ + ItemSet.prototype._onUpdate = function(ids) { + var me = this; - // prevent end > max - if (max !== null) { - if (newEnd > max) { - diff = (newEnd - max); - newStart -= diff; - newEnd -= diff; + ids.forEach(function (id) { + var itemData = me.itemsData.get(id, me.itemOptions); + var item = me.items[id]; + var type = me._getType(itemData); - // prevent start < min - if (min != null) { - if (newStart < min) { - newStart = min; - } - } - } - } + var constructor = ItemSet.types[type]; - // prevent (end-start) < zoomMin - if (this.options.zoomMin !== null) { - var zoomMin = parseFloat(this.options.zoomMin); - if (zoomMin < 0) { - zoomMin = 0; - } - if ((newEnd - newStart) < zoomMin) { - if ((this.end - this.start) === zoomMin) { - // ignore this action, we are already zoomed to the minimum - newStart = this.start; - newEnd = this.end; + if (item) { + // update item + if (!constructor || !(item instanceof constructor)) { + // item type has changed, delete the item and recreate it + me._removeItem(item); + item = null; } else { - // zoom to the minimum - diff = (zoomMin - (newEnd - newStart)); - newStart -= diff / 2; - newEnd += diff / 2; + me._updateItem(item, itemData); } } - } - // prevent (end-start) > zoomMax - if (this.options.zoomMax !== null) { - var zoomMax = parseFloat(this.options.zoomMax); - if (zoomMax < 0) { - zoomMax = 0; - } - if ((newEnd - newStart) > zoomMax) { - if ((this.end - this.start) === zoomMax) { - // ignore this action, we are already zoomed to the maximum - newStart = this.start; - newEnd = this.end; + if (!item) { + // create item + if (constructor) { + item = new constructor(itemData, me.conversion, me.options); + item.id = id; // TODO: not so nice setting id afterwards + me._addItem(item); + } + else if (type == 'rangeoverflow') { + // TODO: deprecated since version 2.1.0 (or 3.0.0?). cleanup some day + throw new TypeError('Item type "rangeoverflow" is deprecated. Use css styling instead: ' + + '.vis.timeline .item.range .content {overflow: visible;}'); } else { - // zoom to the maximum - diff = ((newEnd - newStart) - zoomMax); - newStart += diff / 2; - newEnd -= diff / 2; + throw new TypeError('Unknown item type "' + type + '"'); } } - } - - var changed = (this.start != newStart || this.end != newEnd); + }); - this.start = newStart; - this.end = newEnd; - return changed; + this._order(); + this.stackDirty = true; // force re-stacking of all items next redraw + this.body.emitter.emit('change'); }; /** - * Retrieve the current range. - * @return {Object} An object with start and end properties + * Handle added items + * @param {Number[]} ids + * @protected */ - Range.prototype.getRange = function() { - return { - start: this.start, - end: this.end - }; - }; + ItemSet.prototype._onAdd = ItemSet.prototype._onUpdate; /** - * Calculate the conversion offset and scale for current range, based on - * the provided width - * @param {Number} width - * @returns {{offset: number, scale: number}} conversion + * Handle removed items + * @param {Number[]} ids + * @protected */ - Range.prototype.conversion = function (width, totalHidden) { - return Range.conversion(this.start, this.end, width, totalHidden); + ItemSet.prototype._onRemove = function(ids) { + var count = 0; + var me = this; + ids.forEach(function (id) { + var item = me.items[id]; + if (item) { + count++; + me._removeItem(item); + } + }); + + if (count) { + // update order + this._order(); + this.stackDirty = true; // force re-stacking of all items next redraw + this.body.emitter.emit('change'); + } }; /** - * Static method to calculate the conversion offset and scale for a range, - * based on the provided start, end, and width - * @param {Number} start - * @param {Number} end - * @param {Number} width - * @returns {{offset: number, scale: number}} conversion + * Update the order of item in all groups + * @private */ - Range.conversion = function (start, end, width, totalHidden) { - if (totalHidden === undefined) { - totalHidden = 0; - } - if (width != 0 && (end - start != 0)) { - return { - offset: start, - scale: width / (end - start - totalHidden) - } - } - else { - return { - offset: 0, - scale: 1 - }; - } + ItemSet.prototype._order = function() { + // reorder the items in all groups + // TODO: optimization: only reorder groups affected by the changed items + util.forEach(this.groups, function (group) { + group.order(); + }); }; /** - * Start dragging horizontally or vertically - * @param {Event} event + * Handle updated groups + * @param {Number[]} ids * @private */ - Range.prototype._onDragStart = function(event) { - this.deltaDifference = 0; - this.previousDelta = 0; - // only allow dragging when configured as movable - if (!this.options.moveable) return; - - // refuse to drag when we where pinching to prevent the timeline make a jump - // when releasing the fingers in opposite order from the touch screen - if (!this.props.touch.allowDragging) return; - - this.props.touch.start = this.start; - this.props.touch.end = this.end; - this.props.touch.dragging = true; - - if (this.body.dom.root) { - this.body.dom.root.style.cursor = 'move'; - } + ItemSet.prototype._onUpdateGroups = function(ids) { + this._onAddGroups(ids); }; /** - * Perform dragging operation - * @param {Event} event + * Handle changed groups + * @param {Number[]} ids * @private */ - Range.prototype._onDrag = function (event) { - // only allow dragging when configured as movable - if (!this.options.moveable) return; - // refuse to drag when we where pinching to prevent the timeline make a jump - // when releasing the fingers in opposite order from the touch screen - if (!this.props.touch.allowDragging) return; + ItemSet.prototype._onAddGroups = function(ids) { + var me = this; - var direction = this.options.direction; - validateDirection(direction); + ids.forEach(function (id) { + var groupData = me.groupsData.get(id); + var group = me.groups[id]; - var delta = (direction == 'horizontal') ? event.gesture.deltaX : event.gesture.deltaY; - delta -= this.deltaDifference; - var interval = (this.props.touch.end - this.props.touch.start); + if (!group) { + // check for reserved ids + if (id == UNGROUPED || id == BACKGROUND) { + throw new Error('Illegal group id. ' + id + ' is a reserved id.'); + } - // normalize dragging speed if cutout is in between. - var duration = DateUtil.getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end); - interval -= duration; + var groupOptions = Object.create(me.options); + util.extend(groupOptions, { + height: null + }); - var width = (direction == 'horizontal') ? this.body.domProps.center.width : this.body.domProps.center.height; - var diffRange = -delta / width * interval; - var newStart = this.props.touch.start + diffRange; - var newEnd = this.props.touch.end + diffRange; + group = new Group(id, groupData, me); + me.groups[id] = group; + // add items with this groupId to the new group + for (var itemId in me.items) { + if (me.items.hasOwnProperty(itemId)) { + var item = me.items[itemId]; + if (item.data.group == id) { + group.add(item); + } + } + } - // snapping times away from hidden zones - var safeStart = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newStart, this.previousDelta-delta, true); - var safeEnd = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newEnd, this.previousDelta-delta, true); - if (safeStart != newStart || safeEnd != newEnd) { - this.deltaDifference += delta; - this.props.touch.start = safeStart; - this.props.touch.end = safeEnd; - this._onDrag(event); - return; - } + group.order(); + group.show(); + } + else { + // update group + group.setData(groupData); + } + }); - this.previousDelta = delta; - this._applyRange(newStart, newEnd); + this.body.emitter.emit('change'); + }; - // fire a rangechange event - this.body.emitter.emit('rangechange', { - start: new Date(this.start), - end: new Date(this.end) + /** + * Handle removed groups + * @param {Number[]} ids + * @private + */ + ItemSet.prototype._onRemoveGroups = function(ids) { + var groups = this.groups; + ids.forEach(function (id) { + var group = groups[id]; + + if (group) { + group.hide(); + delete groups[id]; + } }); + + this.markDirty(); + + this.body.emitter.emit('change'); }; /** - * Stop dragging operation - * @param {event} event + * Reorder the groups if needed + * @return {boolean} changed * @private */ - Range.prototype._onDragEnd = function (event) { - // only allow dragging when configured as movable - if (!this.options.moveable) return; + ItemSet.prototype._orderGroups = function () { + if (this.groupsData) { + // reorder the groups + var groupIds = this.groupsData.getIds({ + order: this.options.groupOrder + }); - // refuse to drag when we where pinching to prevent the timeline make a jump - // when releasing the fingers in opposite order from the touch screen - if (!this.props.touch.allowDragging) return; + var changed = !util.equalArray(groupIds, this.groupIds); + if (changed) { + // hide all groups, removes them from the DOM + var groups = this.groups; + groupIds.forEach(function (groupId) { + groups[groupId].hide(); + }); - this.props.touch.dragging = false; - if (this.body.dom.root) { - this.body.dom.root.style.cursor = 'auto'; - } + // show the groups again, attach them to the DOM in correct order + groupIds.forEach(function (groupId) { + groups[groupId].show(); + }); - // fire a rangechanged event - this.body.emitter.emit('rangechanged', { - start: new Date(this.start), - end: new Date(this.end) - }); + this.groupIds = groupIds; + } + + return changed; + } + else { + return false; + } }; /** - * Event handler for mouse wheel event, used to zoom - * Code from http://adomas.org/javascript-mouse-wheel/ - * @param {Event} event + * Add a new item + * @param {Item} item * @private */ - Range.prototype._onMouseWheel = function(event) { - // only allow zooming when configured as zoomable and moveable - if (!(this.options.zoomable && this.options.moveable)) return; + ItemSet.prototype._addItem = function(item) { + this.items[item.id] = item; - // retrieve delta - var delta = 0; - if (event.wheelDelta) { /* IE/Opera. */ - delta = event.wheelDelta / 120; - } else if (event.detail) { /* Mozilla case. */ - // In Mozilla, sign of delta is different than in IE. - // Also, delta is multiple of 3. - delta = -event.detail / 3; - } + // add to group + var groupId = this._getGroupId(item.data); + var group = this.groups[groupId]; + if (group) group.add(item); + }; - // If delta is nonzero, handle it. - // Basically, delta is now positive if wheel was scrolled up, - // and negative, if wheel was scrolled down. - if (delta) { - // perform the zoom action. Delta is normally 1 or -1 + /** + * Update an existing item + * @param {Item} item + * @param {Object} itemData + * @private + */ + ItemSet.prototype._updateItem = function(item, itemData) { + var oldGroupId = item.data.group; - // adjust a negative delta such that zooming in with delta 0.1 - // equals zooming out with a delta -0.1 - var scale; - if (delta < 0) { - scale = 1 - (delta / 5); - } - else { - scale = 1 / (1 + (delta / 5)) ; - } + // update the items data (will redraw the item when displayed) + item.setData(itemData); - // calculate center, the date to zoom around - var gesture = hammerUtil.fakeGesture(this, event), - pointer = getPointer(gesture.center, this.body.dom.center), - pointerDate = this._pointerToDate(pointer); + // update group + if (oldGroupId != item.data.group) { + var oldGroup = this.groups[oldGroupId]; + if (oldGroup) oldGroup.remove(item); - this.zoom(scale, pointerDate, delta); + var groupId = this._getGroupId(item.data); + var group = this.groups[groupId]; + if (group) group.add(item); } + }; - // Prevent default actions caused by mouse wheel - // (else the page and timeline both zoom and scroll) - event.preventDefault(); + /** + * Delete an item from the ItemSet: remove it from the DOM, from the map + * with items, and from the map with visible items, and from the selection + * @param {Item} item + * @private + */ + ItemSet.prototype._removeItem = function(item) { + // remove from DOM + item.hide(); + + // remove from items + delete this.items[item.id]; + + // remove from selection + var index = this.selection.indexOf(item.id); + if (index != -1) this.selection.splice(index, 1); + + // remove from group + item.parent && item.parent.remove(item); }; /** - * Start of a touch gesture + * Create an array containing all items being a range (having an end date) + * @param array + * @returns {Array} * @private */ - Range.prototype._onTouch = function (event) { - this.props.touch.start = this.start; - this.props.touch.end = this.end; - this.props.touch.allowDragging = true; - this.props.touch.center = null; - this.scaleOffset = 0; - this.deltaDifference = 0; + ItemSet.prototype._constructByEndArray = function(array) { + var endArray = []; + + for (var i = 0; i < array.length; i++) { + if (array[i] instanceof RangeItem) { + endArray.push(array[i]); + } + } + return endArray; }; /** - * On start of a hold gesture + * Register the clicked item on touch, before dragStart is initiated. + * + * dragStart is initiated from a mousemove event, which can have left the item + * already resulting in an item == null + * + * @param {Event} event * @private */ - Range.prototype._onHold = function () { - this.props.touch.allowDragging = false; + ItemSet.prototype._onTouch = function (event) { + // store the touched item, used in _onDragStart + this.touchParams.item = ItemSet.itemFromTarget(event); }; /** - * Handle pinch event + * Start dragging the selected events * @param {Event} event * @private */ - Range.prototype._onPinch = function (event) { - // only allow zooming when configured as zoomable and moveable - if (!(this.options.zoomable && this.options.moveable)) return; + ItemSet.prototype._onDragStart = function (event) { + if (!this.options.editable.updateTime && !this.options.editable.updateGroup) { + return; + } - this.props.touch.allowDragging = false; + var item = this.touchParams.item || null; + var me = this; + var props = {}; - if (event.gesture.touches.length > 1) { - if (!this.props.touch.center) { - this.props.touch.center = getPointer(event.gesture.center, this.body.dom.center); - } + props.initialX = event.gesture.center.clientX; + if (item && item.selected) { + var dragLeftItem = event.target.dragLeftItem; + var dragRightItem = event.target.dragRightItem; - var scale = 1 / (event.gesture.scale + this.scaleOffset); - var center = this._pointerToDate(this.props.touch.center); + if (dragLeftItem) { + props.item = dragLeftItem; - var hiddenDuration = DateUtil.getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end); - var hiddenDurationBefore = DateUtil.getHiddenDurationBefore(this.body.hiddenDates, this, center); - var hiddenDurationAfter = hiddenDuration - hiddenDurationBefore; + if (me.options.editable.updateTime) { + props.start = item.data.start.valueOf(); + } + if (me.options.editable.updateGroup) { + if ('group' in item.data) props.group = item.data.group; + } - // calculate new start and end - var newStart = (center-hiddenDurationBefore) + (this.start - (center-hiddenDurationBefore)) * scale; - var newEnd = (center+hiddenDurationAfter) + (this.end - (center+hiddenDurationAfter)) * scale; + this.touchParams.itemProps = [props]; + } + else if (dragRightItem) { + props.item = dragRightItem; - // snapping times away from hidden zones - this.startToFront = 1 - scale > 0 ? false : true; // used to do the right autocorrection with periodic hidden times - this.endToFront = scale - 1 > 0 ? false : true; // used to do the right autocorrection with periodic hidden times + if (me.options.editable.updateTime) { + props.end = item.data.end.valueOf(); + } + if (me.options.editable.updateGroup) { + if ('group' in item.data) props.group = item.data.group; + } - var safeStart = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newStart, 1 - scale, true); - var safeEnd = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newEnd, scale - 1, true); - if (safeStart != newStart || safeEnd != newEnd) { - this.props.touch.start = safeStart; - this.props.touch.end = safeEnd; - this.scaleOffset = 1 - event.gesture.scale; - newStart = safeStart; - newEnd = safeEnd; + this.touchParams.itemProps = [props]; } + else { + this.touchParams.itemProps = this.getSelection().map(function (id) { + var item = me.items[id]; + props.item = item; - this.setRange(newStart, newEnd); + if (me.options.editable.updateTime) { + if ('start' in item.data) props.start = item.data.start.valueOf(); + if ('end' in item.data) props.end = item.data.end.valueOf(); + } + if (me.options.editable.updateGroup) { + if ('group' in item.data) props.group = item.data.group; + } - this.startToFront = false; // revert to default - this.endToFront = true; // revert to default + return props; + }); + } + + event.stopPropagation(); + } + }; + + /** + * Drag selected items + * @param {Event} event + * @private + */ + ItemSet.prototype._onDrag = function (event) { + if (this.touchParams.itemProps) { + var me = this; + var snap = this.body.util.snap || null; + var xOffset = this.body.dom.root.offsetLeft + this.body.domProps.left.width; + + // move + this.touchParams.itemProps.forEach(function (props) { + var newProps = {}; + if ('start' in props && !('end' in props)) { // only start in props + var start = me.body.util.toTime(event.gesture.center.clientX - xOffset); + newProps.start = snap ? snap(start) : start; + } + else if ('start' in props) { // start and end in props + var current = me.body.util.toTime(event.gesture.center.clientX - xOffset); + var initial = me.body.util.toTime(props.initialX - xOffset); + var offset = current - initial; + var start = new Date(props.start + offset); + var end = new Date(props.end + offset); + + newProps.start = snap ? snap(start) : start; + newProps.end = snap ? snap(end) : end; + } + else if ('end' in props) { // only end in props + var end = me.body.util.toTime(event.gesture.center.clientX - xOffset); + newProps.end = snap ? snap(end) : end; + } + + if ('group' in props) { + // drag from one group to another + var group = ItemSet.groupFromTarget(event); + newProps.group = group && group.groupId; + } + + // confirm moving the item + var itemData = util.extend({}, props.item.data, newProps); + me.options.onMoving(itemData, function (itemData) { + if (itemData) { + me._updateItemProps(props.item, itemData); + } + }); + }); + + this.stackDirty = true; // force re-stacking of all items next redraw + this.body.emitter.emit('change'); + + event.stopPropagation(); + } + }; + + /** + * Update an items properties + * @param {Item} item + * @param {Object} props Can contain properties start, end, and group. + * @private + */ + ItemSet.prototype._updateItemProps = function(item, props) { + // TODO: copy all properties from props to item? (also new ones) + if ('start' in props) item.data.start = props.start; + if ('end' in props) item.data.end = props.end; + if ('group' in props && item.data.group != props.group) { + this._moveToGroup(item, props.group) } }; /** - * Helper function to calculate the center date for zooming - * @param {{x: Number, y: Number}} pointer - * @return {number} date + * Move an item to another group + * @param {Item} item + * @param {String | Number} groupId * @private */ - Range.prototype._pointerToDate = function (pointer) { - var conversion; - var direction = this.options.direction; - - validateDirection(direction); + ItemSet.prototype._moveToGroup = function(item, groupId) { + var group = this.groups[groupId]; + if (group && group.groupId != item.data.group) { + var oldGroup = item.parent; + oldGroup.remove(item); + oldGroup.order(); + group.add(item); + group.order(); - if (direction == 'horizontal') { - return this.body.util.toTime(pointer.x).valueOf(); - } - else { - var height = this.body.domProps.center.height; - conversion = this.conversion(height); - return pointer.y / conversion.scale + conversion.offset; + item.data.group = group.groupId; } }; /** - * Get the pointer location relative to the location of the dom element - * @param {{pageX: Number, pageY: Number}} touch - * @param {Element} element HTML DOM element - * @return {{x: Number, y: Number}} pointer + * End of dragging selected items + * @param {Event} event * @private */ - function getPointer (touch, element) { - return { - x: touch.pageX - util.getAbsoluteLeft(element), - y: touch.pageY - util.getAbsoluteTop(element) - }; - } + ItemSet.prototype._onDragEnd = function (event) { + if (this.touchParams.itemProps) { + // prepare a change set for the changed items + var changes = [], + me = this, + dataset = this.itemsData.getDataSet(); - /** - * Zoom the range the given scale in or out. Start and end date will - * be adjusted, and the timeline will be redrawn. You can optionally give a - * date around which to zoom. - * For example, try scale = 0.9 or 1.1 - * @param {Number} scale Scaling factor. Values above 1 will zoom out, - * values below 1 will zoom in. - * @param {Number} [center] Value representing a date around which will - * be zoomed. - */ - Range.prototype.zoom = function(scale, center, delta) { - // if centerDate is not provided, take it half between start Date and end Date - if (center == null) { - center = (this.start + this.end) / 2; - } + var itemProps = this.touchParams.itemProps ; + this.touchParams.itemProps = null; + itemProps.forEach(function (props) { + var id = props.item.id, + itemData = me.itemsData.get(id, me.itemOptions); - var hiddenDuration = DateUtil.getHiddenDurationBetween(this.body.hiddenDates, this.start, this.end); - var hiddenDurationBefore = DateUtil.getHiddenDurationBefore(this.body.hiddenDates, this, center); - var hiddenDurationAfter = hiddenDuration - hiddenDurationBefore; + var changed = false; + if ('start' in props.item.data) { + changed = (props.start != props.item.data.start.valueOf()); + itemData.start = util.convert(props.item.data.start, + dataset._options.type && dataset._options.type.start || 'Date'); + } + if ('end' in props.item.data) { + changed = changed || (props.end != props.item.data.end.valueOf()); + itemData.end = util.convert(props.item.data.end, + dataset._options.type && dataset._options.type.end || 'Date'); + } + if ('group' in props.item.data) { + changed = changed || (props.group != props.item.data.group); + itemData.group = props.item.data.group; + } - // calculate new start and end - var newStart = (center-hiddenDurationBefore) + (this.start - (center-hiddenDurationBefore)) * scale; - var newEnd = (center+hiddenDurationAfter) + (this.end - (center+hiddenDurationAfter)) * scale; + // only apply changes when start or end is actually changed + if (changed) { + me.options.onMove(itemData, function (itemData) { + if (itemData) { + // apply changes + itemData[dataset._fieldId] = id; // ensure the item contains its id (can be undefined) + changes.push(itemData); + } + else { + // restore original values + me._updateItemProps(props.item, props); - // snapping times away from hidden zones - this.startToFront = delta > 0 ? false : true; // used to do the right autocorrection with periodic hidden times - this.endToFront = -delta > 0 ? false : true; // used to do the right autocorrection with periodic hidden times - var safeStart = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newStart, delta, true); - var safeEnd = DateUtil.snapAwayFromHidden(this.body.hiddenDates, newEnd, -delta, true); - if (safeStart != newStart || safeEnd != newEnd) { - newStart = safeStart; - newEnd = safeEnd; - } + me.stackDirty = true; // force re-stacking of all items next redraw + me.body.emitter.emit('change'); + } + }); + } + }); - this.setRange(newStart, newEnd); + // apply the changes to the data (if there are changes) + if (changes.length) { + dataset.update(changes); + } - this.startToFront = false; // revert to default - this.endToFront = true; // revert to default + event.stopPropagation(); + } }; - - /** - * Move the range with a given delta to the left or right. Start and end - * value will be adjusted. For example, try delta = 0.1 or -0.1 - * @param {Number} delta Moving amount. Positive value will move right, - * negative value will move left + * Handle selecting/deselecting an item when tapping it + * @param {Event} event + * @private */ - Range.prototype.move = function(delta) { - // zoom start Date and end Date relative to the centerDate - var diff = (this.end - this.start); - - // apply new values - var newStart = this.start + diff * delta; - var newEnd = this.end + diff * delta; - - // TODO: reckon with min and max range + ItemSet.prototype._onSelectItem = function (event) { + if (!this.options.selectable) return; - this.start = newStart; - this.end = newEnd; - }; + var ctrlKey = event.gesture.srcEvent && event.gesture.srcEvent.ctrlKey; + var shiftKey = event.gesture.srcEvent && event.gesture.srcEvent.shiftKey; + if (ctrlKey || shiftKey) { + this._onMultiSelectItem(event); + return; + } - /** - * Move the range to a new center point - * @param {Number} moveTo New center point of the range - */ - Range.prototype.moveTo = function(moveTo) { - var center = (this.start + this.end) / 2; + var oldSelection = this.getSelection(); - var diff = center - moveTo; + var item = ItemSet.itemFromTarget(event); + var selection = item ? [item.id] : []; + this.setSelection(selection); - // calculate new start and end - var newStart = this.start - diff; - var newEnd = this.end - diff; + var newSelection = this.getSelection(); - this.setRange(newStart, newEnd); + // emit a select event, + // except when old selection is empty and new selection is still empty + if (newSelection.length > 0 || oldSelection.length > 0) { + this.body.emitter.emit('select', { + items: this.getSelection() + }); + } }; - module.exports = Range; - - -/***/ }, -/* 21 */ -/***/ function(module, exports, __webpack_require__) { - - var Hammer = __webpack_require__(18); - /** - * Fake a hammer.js gesture. Event can be a ScrollEvent or MouseMoveEvent - * @param {Element} element - * @param {Event} event + * Handle creation and updates of an item on double tap + * @param event + * @private */ - exports.fakeGesture = function(element, event) { - var eventType = null; + ItemSet.prototype._onAddItem = function (event) { + if (!this.options.selectable) return; + if (!this.options.editable.add) return; - // for hammer.js 1.0.5 - // var gesture = Hammer.event.collectEventData(this, eventType, event); + var me = this, + snap = this.body.util.snap || null, + item = ItemSet.itemFromTarget(event); - // for hammer.js 1.0.6+ - var touches = Hammer.event.getTouchList(event, eventType); - var gesture = Hammer.event.collectEventData(this, eventType, touches, event); + if (item) { + // update item - // on IE in standards mode, no touches are recognized by hammer.js, - // resulting in NaN values for center.pageX and center.pageY - if (isNaN(gesture.center.pageX)) { - gesture.center.pageX = event.pageX; - } - if (isNaN(gesture.center.pageY)) { - gesture.center.pageY = event.pageY; + // execute async handler to update the item (or cancel it) + var itemData = me.itemsData.get(item.id); // get a clone of the data from the dataset + this.options.onUpdate(itemData, function (itemData) { + if (itemData) { + me.itemsData.update(itemData); + } + }); } + else { + // add item + var xAbs = util.getAbsoluteLeft(this.dom.frame); + var x = event.gesture.center.pageX - xAbs; + var start = this.body.util.toTime(x); + var newItem = { + start: snap ? snap(start) : start, + content: 'new item' + }; - return gesture; - }; - + // when default type is a range, add a default end date to the new item + if (this.options.type === 'range') { + var end = this.body.util.toTime(x + this.props.width / 5); + newItem.end = snap ? snap(end) : end; + } -/***/ }, -/* 22 */ -/***/ function(module, exports, __webpack_require__) { + newItem[this.itemsData._fieldId] = util.randomUUID(); - /** - * Prototype for visual components - * @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} [body] - * @param {Object} [options] - */ - function Component (body, options) { - this.options = null; - this.props = null; - } + var group = ItemSet.groupFromTarget(event); + if (group) { + newItem.group = group.groupId; + } - /** - * Set options for the component. The new options will be merged into the - * current options. - * @param {Object} options - */ - Component.prototype.setOptions = function(options) { - if (options) { - util.extend(this.options, options); + // execute async handler to customize (or cancel) adding an item + this.options.onAdd(newItem, function (item) { + if (item) { + me.itemsData.add(item); + // TODO: need to trigger a redraw? + } + }); } }; /** - * Repaint the component - * @return {boolean} Returns true if the component is resized - */ - Component.prototype.redraw = function() { - // should be implemented by the component - return false; - }; - - /** - * Destroy the component. Cleanup DOM and event listeners + * Handle selecting/deselecting multiple items when holding an item + * @param {Event} event + * @private */ - Component.prototype.destroy = function() { - // should be implemented by the component - }; + ItemSet.prototype._onMultiSelectItem = function (event) { + if (!this.options.selectable) return; - /** - * Test whether the component is resized since the last time _isResized() was - * called. - * @return {Boolean} Returns true if the component is resized - * @protected - */ - Component.prototype._isResized = function() { - var resized = (this.props._previousWidth !== this.props.width || - this.props._previousHeight !== this.props.height); + var selection, + item = ItemSet.itemFromTarget(event); - this.props._previousWidth = this.props.width; - this.props._previousHeight = this.props.height; + if (item) { + // multi select items + selection = this.getSelection(); // current selection + var index = selection.indexOf(item.id); + if (index == -1) { + // item is not yet selected -> select it + selection.push(item.id); + } + else { + // item is already selected -> deselect it + selection.splice(index, 1); + } + this.setSelection(selection); - return resized; + this.body.emitter.emit('select', { + items: this.getSelection() + }); + } }; - module.exports = Component; - - -/***/ }, -/* 23 */ -/***/ function(module, exports, __webpack_require__) { - /** - * Created by Alex on 10/3/2014. + * Find an item from an event target: + * searches for the attribute 'timeline-item' in the event target's element tree + * @param {Event} event + * @return {Item | null} item */ - var moment = __webpack_require__(2); + ItemSet.itemFromTarget = function(event) { + var target = event.target; + while (target) { + if (target.hasOwnProperty('timeline-item')) { + return target['timeline-item']; + } + target = target.parentNode; + } + return null; + }; /** - * used in Core to convert the options into a volatile variable - * - * @param Core + * Find the Group from an event target: + * searches for the attribute 'timeline-group' in the event target's element tree + * @param {Event} event + * @return {Group | null} group */ - exports.convertHiddenOptions = function(body, hiddenDates) { - body.hiddenDates = []; - if (hiddenDates) { - if (Array.isArray(hiddenDates) == true) { - for (var i = 0; i < hiddenDates.length; i++) { - if (hiddenDates[i].repeat === undefined) { - var dateItem = {}; - dateItem.start = moment(hiddenDates[i].start).toDate().valueOf(); - dateItem.end = moment(hiddenDates[i].end).toDate().valueOf(); - body.hiddenDates.push(dateItem); - } - } - body.hiddenDates.sort(function (a, b) { - return a.start - b.start; - }); // sort by start time + ItemSet.groupFromTarget = function(event) { + var target = event.target; + while (target) { + if (target.hasOwnProperty('timeline-group')) { + return target['timeline-group']; } + target = target.parentNode; } - }; + return null; + }; /** - * create new entrees for the repeating hidden dates - * @param body - * @param hiddenDates + * Find the ItemSet from an event target: + * searches for the attribute 'timeline-itemset' in the event target's element tree + * @param {Event} event + * @return {ItemSet | null} item */ - exports.updateHiddenDates = function (body, hiddenDates) { - if (hiddenDates && body.domProps.centerContainer.width !== undefined) { - exports.convertHiddenOptions(body, hiddenDates); - - var start = moment(body.range.start); - var end = moment(body.range.end); - - var totalRange = (body.range.end - body.range.start); - var pixelTime = totalRange / body.domProps.centerContainer.width; - - for (var i = 0; i < hiddenDates.length; i++) { - if (hiddenDates[i].repeat !== undefined) { - var startDate = moment(hiddenDates[i].start); - var endDate = moment(hiddenDates[i].end); - - if (startDate._d == "Invalid Date") { - throw new Error("Supplied start date is not valid: " + hiddenDates[i].start); - } - if (endDate._d == "Invalid Date") { - throw new Error("Supplied end date is not valid: " + hiddenDates[i].end); - } - - var duration = endDate - startDate; - if (duration >= 4 * pixelTime) { - - var offset = 0; - var runUntil = end.clone(); - switch (hiddenDates[i].repeat) { - case "daily": // case of time - if (startDate.day() != endDate.day()) { - offset = 1; - } - startDate.dayOfYear(start.dayOfYear()); - startDate.year(start.year()); - startDate.subtract(7,'days'); - - endDate.dayOfYear(start.dayOfYear()); - endDate.year(start.year()); - endDate.subtract(7 - offset,'days'); - - runUntil.add(1, 'weeks'); - break; - case "weekly": - var dayOffset = endDate.diff(startDate,'days') - var day = startDate.day(); - - // set the start date to the range.start - startDate.date(start.date()); - startDate.month(start.month()); - startDate.year(start.year()); - endDate = startDate.clone(); - - // force - startDate.day(day); - endDate.day(day); - endDate.add(dayOffset,'days'); - - startDate.subtract(1,'weeks'); - endDate.subtract(1,'weeks'); - - runUntil.add(1, 'weeks'); - break - case "monthly": - if (startDate.month() != endDate.month()) { - offset = 1; - } - startDate.month(start.month()); - startDate.year(start.year()); - startDate.subtract(1,'months'); - - endDate.month(start.month()); - endDate.year(start.year()); - endDate.subtract(1,'months'); - endDate.add(offset,'months'); - - runUntil.add(1, 'months'); - break; - case "yearly": - if (startDate.year() != endDate.year()) { - offset = 1; - } - startDate.year(start.year()); - startDate.subtract(1,'years'); - endDate.year(start.year()); - endDate.subtract(1,'years'); - endDate.add(offset,'years'); - - runUntil.add(1, 'years'); - break; - default: - console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:", hiddenDates[i].repeat); - return; - } - while (startDate < runUntil) { - body.hiddenDates.push({start: startDate.valueOf(), end: endDate.valueOf()}); - switch (hiddenDates[i].repeat) { - case "daily": - startDate.add(1, 'days'); - endDate.add(1, 'days'); - break; - case "weekly": - startDate.add(1, 'weeks'); - endDate.add(1, 'weeks'); - break - case "monthly": - startDate.add(1, 'months'); - endDate.add(1, 'months'); - break; - case "yearly": - startDate.add(1, 'y'); - endDate.add(1, 'y'); - break; - default: - console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:", hiddenDates[i].repeat); - return; - } - } - body.hiddenDates.push({start: startDate.valueOf(), end: endDate.valueOf()}); - } - } - } - // remove duplicates, merge where possible - exports.removeDuplicates(body); - // ensure the new positions are not on hidden dates - var startHidden = exports.isHidden(body.range.start, body.hiddenDates); - var endHidden = exports.isHidden(body.range.end,body.hiddenDates); - var rangeStart = body.range.start; - var rangeEnd = body.range.end; - if (startHidden.hidden == true) {rangeStart = body.range.startToFront == true ? startHidden.startDate - 1 : startHidden.endDate + 1;} - if (endHidden.hidden == true) {rangeEnd = body.range.endToFront == true ? endHidden.startDate - 1 : endHidden.endDate + 1;} - if (startHidden.hidden == true || endHidden.hidden == true) { - body.range._applyRange(rangeStart, rangeEnd); + ItemSet.itemSetFromTarget = function(event) { + var target = event.target; + while (target) { + if (target.hasOwnProperty('timeline-itemset')) { + return target['timeline-itemset']; } + target = target.parentNode; } - } + return null; + }; + + module.exports = ItemSet; + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var DOMutil = __webpack_require__(2); + var Component = __webpack_require__(19); /** - * remove duplicates from the hidden dates list. Duplicates are evil. They mess everything up. - * Scales with N^2 - * @param body + * Legend for Graph2d */ - exports.removeDuplicates = function(body) { - var hiddenDates = body.hiddenDates; - var safeDates = []; - for (var i = 0; i < hiddenDates.length; i++) { - for (var j = 0; j < hiddenDates.length; j++) { - if (i != j && hiddenDates[j].remove != true && hiddenDates[i].remove != true) { - // j inside i - if (hiddenDates[j].start >= hiddenDates[i].start && hiddenDates[j].end <= hiddenDates[i].end) { - hiddenDates[j].remove = true; - } - // j start inside i - else if (hiddenDates[j].start >= hiddenDates[i].start && hiddenDates[j].start <= hiddenDates[i].end) { - hiddenDates[i].end = hiddenDates[j].end; - hiddenDates[j].remove = true; - } - // j end inside i - else if (hiddenDates[j].end >= hiddenDates[i].start && hiddenDates[j].end <= hiddenDates[i].end) { - hiddenDates[i].start = hiddenDates[j].start; - hiddenDates[j].remove = true; - } - } + function Legend(body, options, side, linegraphOptions) { + this.body = body; + this.defaultOptions = { + enabled: true, + icons: true, + iconSize: 20, + iconSpacing: 6, + left: { + visible: true, + position: 'top-left' // top/bottom - left,center,right + }, + right: { + visible: true, + position: 'top-left' // top/bottom - left,center,right } } + this.side = side; + this.options = util.extend({},this.defaultOptions); + this.linegraphOptions = linegraphOptions; - for (var i = 0; i < hiddenDates.length; i++) { - if (hiddenDates[i].remove !== true) { - safeDates.push(hiddenDates[i]); - } - } + this.svgElements = {}; + this.dom = {}; + this.groups = {}; + this.amountOfGroups = 0; + this._create(); - body.hiddenDates = safeDates; - body.hiddenDates.sort(function (a, b) { - return a.start - b.start; - }); // sort by start time + this.setOptions(options); } - exports.printDates = function(dates) { - for (var i =0; i < dates.length; i++) { - console.log(i, new Date(dates[i].start),new Date(dates[i].end), dates[i].start, dates[i].end, dates[i].remove); - } - } + Legend.prototype = new Component(); - /** - * Used in TimeStep to avoid the hidden times. - * @param timeStep - * @param previousTime - */ - exports.stepOverHiddenDates = function(timeStep, previousTime) { - var stepInHidden = false; - var currentValue = timeStep.current.valueOf(); - for (var i = 0; i < timeStep.hiddenDates.length; i++) { - var startDate = timeStep.hiddenDates[i].start; - var endDate = timeStep.hiddenDates[i].end; - if (currentValue >= startDate && currentValue < endDate) { - stepInHidden = true; - break; - } + + Legend.prototype.addGroup = function(label, graphOptions) { + if (!this.groups.hasOwnProperty(label)) { + this.groups[label] = graphOptions; } + this.amountOfGroups += 1; + }; - if (stepInHidden == true && currentValue < timeStep._end.valueOf() && currentValue != previousTime) { - var prevValue = moment(previousTime); - var newValue = moment(endDate); - //check if the next step should be major - if (prevValue.year() != newValue.year()) {timeStep.switchedYear = true;} - else if (prevValue.month() != newValue.month()) {timeStep.switchedMonth = true;} - else if (prevValue.dayOfYear() != newValue.dayOfYear()) {timeStep.switchedDay = true;} + Legend.prototype.updateGroup = function(label, graphOptions) { + this.groups[label] = graphOptions; + }; - timeStep.current = newValue.toDate(); + Legend.prototype.removeGroup = function(label) { + if (this.groups.hasOwnProperty(label)) { + delete this.groups[label]; + this.amountOfGroups -= 1; } }; + Legend.prototype._create = function() { + this.dom.frame = document.createElement('div'); + this.dom.frame.className = 'legend'; + this.dom.frame.style.position = "absolute"; + this.dom.frame.style.top = "10px"; + this.dom.frame.style.display = "block"; + + this.dom.textArea = document.createElement('div'); + this.dom.textArea.className = 'legendText'; + this.dom.textArea.style.position = "relative"; + this.dom.textArea.style.top = "0px"; + + this.svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); + this.svg.style.position = 'absolute'; + this.svg.style.top = 0 +'px'; + this.svg.style.width = this.options.iconSize + 5 + 'px'; + this.svg.style.height = '100%'; + + this.dom.frame.appendChild(this.svg); + this.dom.frame.appendChild(this.dom.textArea); + }; /** - * Used in TimeStep to avoid the hidden times. - * @param timeStep - * @param previousTime + * Hide the component from the DOM */ - exports.checkFirstStep = function(timeStep) { - var stepInHidden = false; - var currentValue = timeStep.current.valueOf(); - for (var i = 0; i < timeStep.hiddenDates.length; i++) { - var startDate = timeStep.hiddenDates[i].start; - var endDate = timeStep.hiddenDates[i].end; - if (currentValue >= startDate && currentValue < endDate) { - stepInHidden = true; - break; - } - } - - if (stepInHidden == true && currentValue <= timeStep._end.valueOf()) { - var newValue = moment(endDate); - timeStep.current = newValue.toDate(); + Legend.prototype.hide = function() { + // remove the frame containing the items + if (this.dom.frame.parentNode) { + this.dom.frame.parentNode.removeChild(this.dom.frame); } }; /** - * replaces the Core toScreen methods - * @param Core - * @param time - * @param width - * @returns {number} + * Show the component in the DOM (when not already visible). + * @return {Boolean} changed */ - exports.toScreen = function(Core, time, width) { - var hidden = exports.isHidden(time, Core.body.hiddenDates) - if (hidden.hidden == true) { - time = hidden.startDate; + Legend.prototype.show = function() { + // show frame containing the items + if (!this.dom.frame.parentNode) { + this.body.dom.center.appendChild(this.dom.frame); } + }; - var duration = exports.getHiddenDurationBetween(Core.body.hiddenDates, Core.range.start, Core.range.end); - time = exports.correctTimeForHidden(Core.body.hiddenDates, Core.range, time); - - var conversion = Core.range.conversion(width, duration); - return (time.valueOf() - conversion.offset) * conversion.scale; + Legend.prototype.setOptions = function(options) { + var fields = ['enabled','orientation','icons','left','right']; + util.selectiveDeepExtend(fields, this.options, options); }; + Legend.prototype.redraw = function() { + var activeGroups = 0; + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { + activeGroups++; + } + } + } - /** - * Replaces the core toTime methods - * @param body - * @param range - * @param x - * @param width - * @returns {Date} - */ - exports.toTime = function(body, range, x, width) { - var hiddenDuration = exports.getHiddenDurationBetween(body.hiddenDates, range.start, range.end); - var totalDuration = range.end - range.start - hiddenDuration; - var partialDuration = totalDuration * x / width; - var accumulatedHiddenDuration = exports.getAccumulatedHiddenDuration(body.hiddenDates,range, partialDuration); + if (this.options[this.side].visible == false || this.amountOfGroups == 0 || this.options.enabled == false || activeGroups == 0) { + this.hide(); + } + else { + this.show(); + if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'bottom-left') { + this.dom.frame.style.left = '4px'; + this.dom.frame.style.textAlign = "left"; + this.dom.textArea.style.textAlign = "left"; + this.dom.textArea.style.left = (this.options.iconSize + 15) + 'px'; + this.dom.textArea.style.right = ''; + this.svg.style.left = 0 +'px'; + this.svg.style.right = ''; + } + else { + this.dom.frame.style.right = '4px'; + this.dom.frame.style.textAlign = "right"; + this.dom.textArea.style.textAlign = "right"; + this.dom.textArea.style.right = (this.options.iconSize + 15) + 'px'; + this.dom.textArea.style.left = ''; + this.svg.style.right = 0 +'px'; + this.svg.style.left = ''; + } - var newTime = new Date(accumulatedHiddenDuration + partialDuration + range.start); - return newTime; + if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'top-right') { + this.dom.frame.style.top = 4 - Number(this.body.dom.center.style.top.replace("px","")) + 'px'; + this.dom.frame.style.bottom = ''; + } + else { + this.dom.frame.style.bottom = 4 - Number(this.body.dom.center.style.top.replace("px","")) + 'px'; + this.dom.frame.style.top = ''; + } + + if (this.options.icons == false) { + this.dom.frame.style.width = this.dom.textArea.offsetWidth + 10 + 'px'; + this.dom.textArea.style.right = ''; + this.dom.textArea.style.left = ''; + this.svg.style.width = '0px'; + } + else { + this.dom.frame.style.width = this.options.iconSize + 15 + this.dom.textArea.offsetWidth + 10 + 'px' + this.drawLegendIcons(); + } + + var content = ''; + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { + content += this.groups[groupId].content + '
'; + } + } + } + this.dom.textArea.innerHTML = content; + this.dom.textArea.style.lineHeight = ((0.75 * this.options.iconSize) + this.options.iconSpacing) + 'px'; + } }; + Legend.prototype.drawLegendIcons = function() { + if (this.dom.frame.parentNode) { + DOMutil.prepareElements(this.svgElements); + var padding = window.getComputedStyle(this.dom.frame).paddingTop; + var iconOffset = Number(padding.replace('px','')); + var x = iconOffset; + var iconWidth = this.options.iconSize; + var iconHeight = 0.75 * this.options.iconSize; + var y = iconOffset + 0.5 * iconHeight + 3; - /** - * Support function - * - * @param hiddenDates - * @param range - * @returns {number} - */ - exports.getHiddenDurationBetween = function(hiddenDates, start, end) { - var duration = 0; - for (var i = 0; i < hiddenDates.length; i++) { - var startDate = hiddenDates[i].start; - var endDate = hiddenDates[i].end; - // if time after the cutout, and the - if (startDate >= start && endDate < end) { - duration += endDate - startDate; + this.svg.style.width = iconWidth + 5 + iconOffset + 'px'; + + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { + this.groups[groupId].drawIcon(x, y, this.svgElements, this.svg, iconWidth, iconHeight); + y += iconHeight + this.options.iconSpacing; + } + } } + + DOMutil.cleanupElements(this.svgElements); } - return duration; }; + module.exports = Legend; + + +/***/ }, +/* 28 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var DOMutil = __webpack_require__(2); + var DataSet = __webpack_require__(3); + var DataView = __webpack_require__(4); + var Component = __webpack_require__(19); + var DataAxis = __webpack_require__(22); + var GraphGroup = __webpack_require__(23); + var Legend = __webpack_require__(27); + + var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items /** - * Support function - * @param hiddenDates - * @param range - * @param time - * @returns {{duration: number, time: *, offset: number}} + * This is the constructor of the LineGraph. It requires a Timeline body and options. + * + * @param body + * @param options + * @constructor */ - exports.correctTimeForHidden = function(hiddenDates, range, time) { - time = moment(time).toDate().valueOf(); - time -= exports.getHiddenDurationBefore(hiddenDates,range,time); - return time; - }; - - exports.getHiddenDurationBefore = function(hiddenDates, range, time) { - var timeOffset = 0; - time = moment(time).toDate().valueOf(); + function LineGraph(body, options) { + this.id = util.randomUUID(); + this.body = body; - for (var i = 0; i < hiddenDates.length; i++) { - var startDate = hiddenDates[i].start; - var endDate = hiddenDates[i].end; - // if time after the cutout, and the - if (startDate >= range.start && endDate < range.end) { - if (time >= endDate) { - timeOffset += (endDate - startDate); + this.defaultOptions = { + yAxisOrientation: 'left', + defaultGroup: 'default', + sort: true, + sampling: true, + graphHeight: '400px', + shaded: { + enabled: false, + orientation: 'bottom' // top, bottom + }, + style: 'line', // line, bar + barChart: { + width: 50, + handleOverlap: 'overlap', + align: 'center' // left, center, right + }, + catmullRom: { + enabled: true, + parametrization: 'centripetal', // uniform (alpha = 0.0), chordal (alpha = 1.0), centripetal (alpha = 0.5) + alpha: 0.5 + }, + drawPoints: { + enabled: true, + size: 6, + style: 'square' // square, circle + }, + dataAxis: { + showMinorLabels: true, + showMajorLabels: true, + icons: false, + width: '40px', + visible: true, + customRange: { + left: {min:undefined, max:undefined}, + right: {min:undefined, max:undefined} } + }, + legend: { + enabled: false, + icons: true, + left: { + visible: true, + position: 'top-left' // top/bottom - left,right + }, + right: { + visible: true, + position: 'top-right' // top/bottom - left,right + } + }, + groups: { + visibility: {} } - } - return timeOffset; + }; + + // options is shared by this ItemSet and all its items + this.options = util.extend({}, this.defaultOptions); + this.dom = {}; + this.props = {}; + this.hammer = null; + this.groups = {}; + this.abortedGraphUpdate = false; + + var me = this; + this.itemsData = null; // DataSet + this.groupsData = null; // DataSet + + // listeners for the DataSet of the items + this.itemListeners = { + 'add': function (event, params, senderId) { + me._onAdd(params.items); + }, + 'update': function (event, params, senderId) { + me._onUpdate(params.items); + }, + 'remove': function (event, params, senderId) { + me._onRemove(params.items); + } + }; + + // listeners for the DataSet of the groups + this.groupListeners = { + 'add': function (event, params, senderId) { + me._onAddGroups(params.items); + }, + 'update': function (event, params, senderId) { + me._onUpdateGroups(params.items); + }, + 'remove': function (event, params, senderId) { + me._onRemoveGroups(params.items); + } + }; + + this.items = {}; // object with an Item for every data item + this.selection = []; // list with the ids of all selected nodes + this.lastStart = this.body.range.start; + this.touchParams = {}; // stores properties while dragging + + this.svgElements = {}; + this.setOptions(options); + this.groupsUsingDefaultStyles = [0]; + + this.body.emitter.on("rangechanged", function() { + me.lastStart = me.body.range.start; + me.svg.style.left = util.option.asSize(-me.width); + me._updateGraph.apply(me); + }); + + // create the HTML DOM + this._create(); + this.body.emitter.emit("change"); } + LineGraph.prototype = new Component(); + /** - * sum the duration from start to finish, including the hidden duration, - * until the required amount has been reached, return the accumulated hidden duration - * @param hiddenDates - * @param range - * @param time - * @returns {{duration: number, time: *, offset: number}} + * Create the HTML DOM for the ItemSet */ - exports.getAccumulatedHiddenDuration = function(hiddenDates, range, requiredDuration) { - var hiddenDuration = 0; - var duration = 0; - var previousPoint = range.start; - //exports.printDates(hiddenDates) - for (var i = 0; i < hiddenDates.length; i++) { - var startDate = hiddenDates[i].start; - var endDate = hiddenDates[i].end; - // if time after the cutout, and the - if (startDate >= range.start && endDate < range.end) { - duration += startDate - previousPoint; - previousPoint = endDate; - if (duration >= requiredDuration) { - break; - } - else { - hiddenDuration += endDate - startDate; + LineGraph.prototype._create = function(){ + var frame = document.createElement('div'); + frame.className = 'LineGraph'; + this.dom.frame = frame; + + // create svg element for graph drawing. + this.svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); + this.svg.style.position = "relative"; + this.svg.style.height = ('' + this.options.graphHeight).replace("px",'') + 'px'; + this.svg.style.display = "block"; + frame.appendChild(this.svg); + + // data axis + this.options.dataAxis.orientation = 'left'; + this.yAxisLeft = new DataAxis(this.body, this.options.dataAxis, this.svg, this.options.groups); + + this.options.dataAxis.orientation = 'right'; + this.yAxisRight = new DataAxis(this.body, this.options.dataAxis, this.svg, this.options.groups); + delete this.options.dataAxis.orientation; + + // legends + this.legendLeft = new Legend(this.body, this.options.legend, 'left', this.options.groups); + this.legendRight = new Legend(this.body, this.options.legend, 'right', this.options.groups); + + this.show(); + }; + + /** + * set the options of the LineGraph. the mergeOptions is used for subObjects that have an enabled element. + * @param options + */ + LineGraph.prototype.setOptions = function(options) { + if (options) { + var fields = ['sampling','defaultGroup','graphHeight','yAxisOrientation','style','barChart','dataAxis','sort','groups']; + util.selectiveDeepExtend(fields, this.options, options); + util.mergeOptions(this.options, options,'catmullRom'); + util.mergeOptions(this.options, options,'drawPoints'); + util.mergeOptions(this.options, options,'shaded'); + util.mergeOptions(this.options, options,'legend'); + + if (options.catmullRom) { + if (typeof options.catmullRom == 'object') { + if (options.catmullRom.parametrization) { + if (options.catmullRom.parametrization == 'uniform') { + this.options.catmullRom.alpha = 0; + } + else if (options.catmullRom.parametrization == 'chordal') { + this.options.catmullRom.alpha = 1.0; + } + else { + this.options.catmullRom.parametrization = 'centripetal'; + this.options.catmullRom.alpha = 0.5; + } + } } } - } - - return hiddenDuration; - }; - - - /** - * used to step over to either side of a hidden block. Correction is disabled on tablets, might be set to true - * @param hiddenDates - * @param time - * @param direction - * @param correctionEnabled - * @returns {*} - */ - exports.snapAwayFromHidden = function(hiddenDates, time, direction, correctionEnabled) { - var isHidden = exports.isHidden(time, hiddenDates); - if (isHidden.hidden == true) { - if (direction < 0) { - if (correctionEnabled == true) { - return isHidden.startDate - (isHidden.endDate - time) - 1; - } - else { - return isHidden.startDate - 1; + if (this.yAxisLeft) { + if (options.dataAxis !== undefined) { + this.yAxisLeft.setOptions(this.options.dataAxis); + this.yAxisRight.setOptions(this.options.dataAxis); } } - else { - if (correctionEnabled == true) { - return isHidden.endDate + (time - isHidden.startDate) + 1; - } - else { - return isHidden.endDate + 1; + + if (this.legendLeft) { + if (options.legend !== undefined) { + this.legendLeft.setOptions(this.options.legend); + this.legendRight.setOptions(this.options.legend); } } + + if (this.groups.hasOwnProperty(UNGROUPED)) { + this.groups[UNGROUPED].setOptions(options); + } } - else { - return time; + if (this.dom.frame) { + this._updateGraph(); } - - } - + }; /** - * Check if a time is hidden - * - * @param time - * @param hiddenDates - * @returns {{hidden: boolean, startDate: Window.start, endDate: *}} + * Hide the component from the DOM */ - exports.isHidden = function(time, hiddenDates) { - for (var i = 0; i < hiddenDates.length; i++) { - var startDate = hiddenDates[i].start; - var endDate = hiddenDates[i].end; - - if (time >= startDate && time < endDate) { // if the start is entering a hidden zone - return {hidden: true, startDate: startDate, endDate: endDate}; - break; - } + LineGraph.prototype.hide = function() { + // remove the frame containing the items + if (this.dom.frame.parentNode) { + this.dom.frame.parentNode.removeChild(this.dom.frame); } - return {hidden: false, startDate: startDate, endDate: endDate}; - } - -/***/ }, -/* 24 */ -/***/ function(module, exports, __webpack_require__) { - - var Emitter = __webpack_require__(10); - var Hammer = __webpack_require__(18); - var util = __webpack_require__(1); - var DataSet = __webpack_require__(7); - var DataView = __webpack_require__(8); - var Range = __webpack_require__(20); - var TimeAxis = __webpack_require__(25); - var CurrentTime = __webpack_require__(27); - var CustomTime = __webpack_require__(29); - var ItemSet = __webpack_require__(30); - var Activator = __webpack_require__(39); - var DateUtil = __webpack_require__(23); + }; /** - * Create a timeline visualization - * @param {HTMLElement} container - * @param {vis.DataSet | Array | google.visualization.DataTable} [items] - * @param {Object} [options] See Core.setOptions for the available options. - * @constructor + * Show the component in the DOM (when not already visible). + * @return {Boolean} changed */ - function Core () {} + LineGraph.prototype.show = function() { + // show frame containing the items + if (!this.dom.frame.parentNode) { + this.body.dom.center.appendChild(this.dom.frame); + } + }; - // turn Core into an event emitter - Emitter(Core.prototype); /** - * Create the main DOM for the Core: a root panel containing left, right, - * top, bottom, content, and background panel. - * @param {Element} container The container element where the Core will - * be attached. - * @private + * Set items + * @param {vis.DataSet | null} items */ - Core.prototype._create = function (container) { - this.dom = {}; + LineGraph.prototype.setItems = function(items) { + var me = this, + ids, + oldItemsData = this.itemsData; - this.dom.root = document.createElement('div'); - this.dom.background = document.createElement('div'); - this.dom.backgroundVertical = document.createElement('div'); - this.dom.backgroundHorizontal = document.createElement('div'); - this.dom.centerContainer = document.createElement('div'); - this.dom.leftContainer = document.createElement('div'); - this.dom.rightContainer = document.createElement('div'); - this.dom.center = document.createElement('div'); - this.dom.left = document.createElement('div'); - this.dom.right = document.createElement('div'); - this.dom.top = document.createElement('div'); - this.dom.bottom = document.createElement('div'); - this.dom.shadowTop = document.createElement('div'); - this.dom.shadowBottom = document.createElement('div'); - this.dom.shadowTopLeft = document.createElement('div'); - this.dom.shadowBottomLeft = document.createElement('div'); - this.dom.shadowTopRight = document.createElement('div'); - this.dom.shadowBottomRight = document.createElement('div'); + // replace the dataset + if (!items) { + this.itemsData = null; + } + else if (items instanceof DataSet || items instanceof DataView) { + this.itemsData = items; + } + else { + throw new TypeError('Data must be an instance of DataSet or DataView'); + } - this.dom.root.className = 'vis timeline root'; - this.dom.background.className = 'vispanel background'; - this.dom.backgroundVertical.className = 'vispanel background vertical'; - this.dom.backgroundHorizontal.className = 'vispanel background horizontal'; - this.dom.centerContainer.className = 'vispanel center'; - this.dom.leftContainer.className = 'vispanel left'; - this.dom.rightContainer.className = 'vispanel right'; - this.dom.top.className = 'vispanel top'; - this.dom.bottom.className = 'vispanel bottom'; - this.dom.left.className = 'content'; - this.dom.center.className = 'content'; - this.dom.right.className = 'content'; - this.dom.shadowTop.className = 'shadow top'; - this.dom.shadowBottom.className = 'shadow bottom'; - this.dom.shadowTopLeft.className = 'shadow top'; - this.dom.shadowBottomLeft.className = 'shadow bottom'; - this.dom.shadowTopRight.className = 'shadow top'; - this.dom.shadowBottomRight.className = 'shadow bottom'; + if (oldItemsData) { + // unsubscribe from old dataset + util.forEach(this.itemListeners, function (callback, event) { + oldItemsData.off(event, callback); + }); - this.dom.root.appendChild(this.dom.background); - this.dom.root.appendChild(this.dom.backgroundVertical); - this.dom.root.appendChild(this.dom.backgroundHorizontal); - this.dom.root.appendChild(this.dom.centerContainer); - this.dom.root.appendChild(this.dom.leftContainer); - this.dom.root.appendChild(this.dom.rightContainer); - this.dom.root.appendChild(this.dom.top); - this.dom.root.appendChild(this.dom.bottom); + // remove all drawn items + ids = oldItemsData.getIds(); + this._onRemove(ids); + } - this.dom.centerContainer.appendChild(this.dom.center); - this.dom.leftContainer.appendChild(this.dom.left); - this.dom.rightContainer.appendChild(this.dom.right); + if (this.itemsData) { + // subscribe to new dataset + var id = this.id; + util.forEach(this.itemListeners, function (callback, event) { + me.itemsData.on(event, callback, id); + }); - this.dom.centerContainer.appendChild(this.dom.shadowTop); - this.dom.centerContainer.appendChild(this.dom.shadowBottom); - this.dom.leftContainer.appendChild(this.dom.shadowTopLeft); - this.dom.leftContainer.appendChild(this.dom.shadowBottomLeft); - this.dom.rightContainer.appendChild(this.dom.shadowTopRight); - this.dom.rightContainer.appendChild(this.dom.shadowBottomRight); + // add all new items + ids = this.itemsData.getIds(); + this._onAdd(ids); + } + this._updateUngrouped(); + this._updateGraph(); + this.redraw(); + }; - this.on('rangechange', this.redraw.bind(this)); - this.on('change', this.redraw.bind(this)); - this.on('touch', this._onTouch.bind(this)); - this.on('pinch', this._onPinch.bind(this)); - this.on('dragstart', this._onDragStart.bind(this)); - this.on('drag', this._onDrag.bind(this)); + /** + * Set groups + * @param {vis.DataSet} groups + */ + LineGraph.prototype.setGroups = function(groups) { + var me = this, + ids; - // create event listeners for all interesting events, these events will be - // emitted via emitter - this.hammer = Hammer(this.dom.root, { - preventDefault: true - }); - this.listeners = {}; + // unsubscribe from current dataset + if (this.groupsData) { + util.forEach(this.groupListeners, function (callback, event) { + me.groupsData.unsubscribe(event, callback); + }); - var me = this; - var events = [ - 'touch', 'pinch', - 'tap', 'doubletap', 'hold', - 'dragstart', 'drag', 'dragend', - 'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox - ]; - events.forEach(function (event) { - var listener = function () { - var args = [event].concat(Array.prototype.slice.call(arguments, 0)); - if (me.isActive()) { - me.emit.apply(me, args); - } - }; - me.hammer.on(event, listener); - me.listeners[event] = listener; - }); + // remove all drawn groups + ids = this.groupsData.getIds(); + this.groupsData = null; + this._onRemoveGroups(ids); // note: this will cause a redraw + } - // size properties of each of the panels - this.props = { - root: {}, - background: {}, - centerContainer: {}, - leftContainer: {}, - rightContainer: {}, - center: {}, - left: {}, - right: {}, - top: {}, - bottom: {}, - border: {}, - scrollTop: 0, - scrollTopMin: 0 - }; - this.touch = {}; // store state information needed for touch events + // replace the dataset + if (!groups) { + this.groupsData = null; + } + else if (groups instanceof DataSet || groups instanceof DataView) { + this.groupsData = groups; + } + else { + throw new TypeError('Data must be an instance of DataSet or DataView'); + } - // attach the root panel to the provided container - if (!container) throw new Error('No container provided'); - container.appendChild(this.dom.root); + if (this.groupsData) { + // subscribe to new dataset + var id = this.id; + util.forEach(this.groupListeners, function (callback, event) { + me.groupsData.on(event, callback, id); + }); + + // draw all ms + ids = this.groupsData.getIds(); + this._onAddGroups(ids); + } + this._onUpdate(); }; + /** - * Set options. Options will be passed to all components loaded in the Timeline. - * @param {Object} [options] - * {String} orientation - * Vertical orientation for the Timeline, - * can be 'bottom' (default) or 'top'. - * {String | Number} width - * Width for the timeline, a number in pixels or - * a css string like '1000px' or '75%'. '100%' by default. - * {String | Number} height - * Fixed height for the Timeline, a number in pixels or - * a css string like '400px' or '75%'. If undefined, - * The Timeline will automatically size such that - * its contents fit. - * {String | Number} minHeight - * Minimum height for the Timeline, a number in pixels or - * a css string like '400px' or '75%'. - * {String | Number} maxHeight - * Maximum height for the Timeline, a number in pixels or - * a css string like '400px' or '75%'. - * {Number | Date | String} start - * Start date for the visible window - * {Number | Date | String} end - * End date for the visible window + * Update the datapoints + * @param [ids] + * @private */ - Core.prototype.setOptions = function (options) { - if (options) { - // copy the known options - var fields = ['width', 'height', 'minHeight', 'maxHeight', 'autoResize', 'start', 'end', 'orientation', 'clickToUse', 'dataAttributes', 'hiddenDates']; - util.selectiveExtend(fields, this.options, options); + LineGraph.prototype._onUpdate = function(ids) { + this._updateUngrouped(); + this._updateAllGroupData(); + this._updateGraph(); + this.redraw(); + }; + LineGraph.prototype._onAdd = function (ids) {this._onUpdate(ids);}; + LineGraph.prototype._onRemove = function (ids) {this._onUpdate(ids);}; + LineGraph.prototype._onUpdateGroups = function (groupIds) { + for (var i = 0; i < groupIds.length; i++) { + var group = this.groupsData.get(groupIds[i]); + this._updateGroup(group, groupIds[i]); + } - if ('hiddenDates' in this.options) { - DateUtil.convertHiddenOptions(this.body, this.options.hiddenDates); - } + this._updateGraph(); + this.redraw(); + }; + LineGraph.prototype._onAddGroups = function (groupIds) {this._onUpdateGroups(groupIds);}; - if ('clickToUse' in options) { - if (options.clickToUse) { - this.activator = new Activator(this.dom.root); + LineGraph.prototype._onRemoveGroups = function (groupIds) { + for (var i = 0; i < groupIds.length; i++) { + if (!this.groups.hasOwnProperty(groupIds[i])) { + if (this.groups[groupIds[i]].options.yAxisOrientation == 'right') { + this.yAxisRight.removeGroup(groupIds[i]); + this.legendRight.removeGroup(groupIds[i]); + this.legendRight.redraw(); } else { - if (this.activator) { - this.activator.destroy(); - delete this.activator; - } + this.yAxisLeft.removeGroup(groupIds[i]); + this.legendLeft.removeGroup(groupIds[i]); + this.legendLeft.redraw(); } + delete this.groups[groupIds[i]]; } - - // enable/disable autoResize - this._initAutoResize(); - } - - // propagate options to all components - this.components.forEach(function (component) { - component.setOptions(options); - }); - - // TODO: remove deprecation error one day (deprecated since version 0.8.0) - if (options && options.order) { - throw new Error('Option order is deprecated. There is no replacement for this feature.'); } - - // redraw everything + this._updateUngrouped(); + this._updateGraph(); this.redraw(); }; /** - * Returns true when the Timeline is active. - * @returns {boolean} + * update a group object + * + * @param group + * @param groupId + * @private */ - Core.prototype.isActive = function () { - return !this.activator || this.activator.active; + LineGraph.prototype._updateGroup = function (group, groupId) { + if (!this.groups.hasOwnProperty(groupId)) { + this.groups[groupId] = new GraphGroup(group, groupId, this.options, this.groupsUsingDefaultStyles); + if (this.groups[groupId].options.yAxisOrientation == 'right') { + this.yAxisRight.addGroup(groupId, this.groups[groupId]); + this.legendRight.addGroup(groupId, this.groups[groupId]); + } + else { + this.yAxisLeft.addGroup(groupId, this.groups[groupId]); + this.legendLeft.addGroup(groupId, this.groups[groupId]); + } + } + else { + this.groups[groupId].update(group); + if (this.groups[groupId].options.yAxisOrientation == 'right') { + this.yAxisRight.updateGroup(groupId, this.groups[groupId]); + this.legendRight.updateGroup(groupId, this.groups[groupId]); + } + else { + this.yAxisLeft.updateGroup(groupId, this.groups[groupId]); + this.legendLeft.updateGroup(groupId, this.groups[groupId]); + } + } + this.legendLeft.redraw(); + this.legendRight.redraw(); }; - /** - * Destroy the Core, clean up all DOM elements and event listeners. - */ - Core.prototype.destroy = function () { - // unbind datasets - this.clear(); - - // remove all event listeners - this.off(); - - // stop checking for changed size - this._stopAutoResize(); - - // remove from DOM - if (this.dom.root.parentNode) { - this.dom.root.parentNode.removeChild(this.dom.root); + LineGraph.prototype._updateAllGroupData = function () { + if (this.itemsData != null) { + var groupsContent = {}; + var groupId; + for (groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + groupsContent[groupId] = []; + } + } + for (var itemId in this.itemsData._data) { + if (this.itemsData._data.hasOwnProperty(itemId)) { + var item = this.itemsData._data[itemId]; + item.x = util.convert(item.x,"Date"); + groupsContent[item.group].push(item); + } + } + for (groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + this.groups[groupId].setItems(groupsContent[groupId]); + } + } } - this.dom = null; + }; - // remove Activator - if (this.activator) { - this.activator.destroy(); - delete this.activator; - } + /** + * Create or delete the group holding all ungrouped items. This group is used when + * there are no groups specified. This anonymous group is called 'graph'. + * @protected + */ + LineGraph.prototype._updateUngrouped = function() { + if (this.itemsData && this.itemsData != null) { + var ungroupedCounter = 0; + for (var itemId in this.itemsData._data) { + if (this.itemsData._data.hasOwnProperty(itemId)) { + var item = this.itemsData._data[itemId]; + if (item != undefined) { + if (item.hasOwnProperty('group')) { + if (item.group === undefined) { + item.group = UNGROUPED; + } + } + else { + item.group = UNGROUPED; + } + ungroupedCounter = item.group == UNGROUPED ? ungroupedCounter + 1 : ungroupedCounter; + } + } + } - // cleanup hammer touch events - for (var event in this.listeners) { - if (this.listeners.hasOwnProperty(event)) { - delete this.listeners[event]; + if (ungroupedCounter == 0) { + delete this.groups[UNGROUPED]; + this.legendLeft.removeGroup(UNGROUPED); + this.legendRight.removeGroup(UNGROUPED); + this.yAxisLeft.removeGroup(UNGROUPED); + this.yAxisRight.removeGroup(UNGROUPED); + } + else { + var group = {id: UNGROUPED, content: this.options.defaultGroup}; + this._updateGroup(group, UNGROUPED); } } - this.listeners = null; - this.hammer = null; - - // give all components the opportunity to cleanup - this.components.forEach(function (component) { - component.destroy(); - }); + else { + delete this.groups[UNGROUPED]; + this.legendLeft.removeGroup(UNGROUPED); + this.legendRight.removeGroup(UNGROUPED); + this.yAxisLeft.removeGroup(UNGROUPED); + this.yAxisRight.removeGroup(UNGROUPED); + } - this.body = null; + this.legendLeft.redraw(); + this.legendRight.redraw(); }; /** - * Set a custom time bar - * @param {Date} time + * Redraw the component, mandatory function + * @return {boolean} Returns true if the component is resized */ - Core.prototype.setCustomTime = function (time) { - if (!this.customTime) { - throw new Error('Cannot get custom time: Custom time bar is not enabled'); + LineGraph.prototype.redraw = function() { + var resized = false; + + this.svg.style.height = ('' + this.options.graphHeight).replace('px','') + 'px'; + if (this.lastWidth === undefined && this.width || this.lastWidth != this.width) { + resized = true; } + // check if this component is resized + resized = this._isResized() || resized; + // check whether zoomed (in that case we need to re-stack everything) + var visibleInterval = this.body.range.end - this.body.range.start; + var zoomed = (visibleInterval != this.lastVisibleInterval) || (this.width != this.lastWidth); + this.lastVisibleInterval = visibleInterval; + this.lastWidth = this.width; - this.customTime.setCustomTime(time); - }; + // calculate actual size and position + this.width = this.dom.frame.offsetWidth; - /** - * Retrieve the current custom time. - * @return {Date} customTime - */ - Core.prototype.getCustomTime = function() { - if (!this.customTime) { - throw new Error('Cannot get custom time: Custom time bar is not enabled'); + // the svg element is three times as big as the width, this allows for fully dragging left and right + // without reloading the graph. the controls for this are bound to events in the constructor + if (resized == true) { + this.svg.style.width = util.option.asSize(3*this.width); + this.svg.style.left = util.option.asSize(-this.width); } - return this.customTime.getCustomTime(); - }; - + if (zoomed == true || this.abortedGraphUpdate == true) { + this._updateGraph(); + } + else { + // move the whole svg while dragging + if (this.lastStart != 0) { + var offset = this.body.range.start - this.lastStart; + var range = this.body.range.end - this.body.range.start; + if (this.width != 0) { + var rangePerPixelInv = this.width/range; + var xOffset = offset * rangePerPixelInv; + this.svg.style.left = (-this.width - xOffset) + "px"; + } + } - /** - * Get the id's of the currently visible items. - * @returns {Array} The ids of the visible items - */ - Core.prototype.getVisibleItems = function() { - return this.itemSet && this.itemSet.getVisibleItems() || []; - }; + } + this.legendLeft.redraw(); + this.legendRight.redraw(); + return resized; + }; /** - * Clear the Core. By Default, items, groups and options are cleared. - * Example usage: - * - * timeline.clear(); // clear items, groups, and options - * timeline.clear({options: true}); // clear options only + * Update and redraw the graph. * - * @param {Object} [what] Optionally specify what to clear. By default: - * {items: true, groups: true, options: true} */ - Core.prototype.clear = function(what) { - // clear items - if (!what || what.items) { - this.setItems(null); - } + LineGraph.prototype._updateGraph = function () { + // reset the svg elements + DOMutil.prepareElements(this.svgElements); + if (this.width != 0 && this.itemsData != null) { + var group, i; + var preprocessedGroupData = {}; + var processedGroupData = {}; + var groupRanges = {}; + var changeCalled = false; - // clear groups - if (!what || what.groups) { - this.setGroups(null); - } + // getting group Ids + var groupIds = []; + for (var groupId in this.groups) { + if (this.groups.hasOwnProperty(groupId)) { + group = this.groups[groupId]; + if (group.visible == true && (this.options.groups.visibility[groupId] === undefined || this.options.groups.visibility[groupId] == true)) { + groupIds.push(groupId); + } + } + } + if (groupIds.length > 0) { + // this is the range of the SVG canvas + var minDate = this.body.util.toGlobalTime(- this.body.domProps.root.width); + var maxDate = this.body.util.toGlobalTime(2 * this.body.domProps.root.width); + var groupsData = {}; + // fill groups data + this._getRelevantData(groupIds, groupsData, minDate, maxDate); + // we transform the X coordinates to detect collisions + for (i = 0; i < groupIds.length; i++) { + preprocessedGroupData[groupIds[i]] = this._convertXcoordinates(groupsData[groupIds[i]]); + } + // now all needed data has been collected we start the processing. + this._getYRanges(groupIds, preprocessedGroupData, groupRanges); - // clear options of timeline and of each of the components - if (!what || what.options) { - this.components.forEach(function (component) { - component.setOptions(component.defaultOptions); - }); + // update the Y axis first, we use this data to draw at the correct Y points + // changeCalled is required to clean the SVG on a change emit. + changeCalled = this._updateYAxis(groupIds, groupRanges); + if (changeCalled == true) { + DOMutil.cleanupElements(this.svgElements); + this.abortedGraphUpdate = true; + this.body.emitter.emit("change"); + return; + } + this.abortedGraphUpdate = false; - this.setOptions(this.defaultOptions); // this will also do a redraw - } - }; + // With the yAxis scaled correctly, use this to get the Y values of the points. + for (i = 0; i < groupIds.length; i++) { + group = this.groups[groupIds[i]]; + processedGroupData[groupIds[i]] = this._convertYcoordinates(groupsData[groupIds[i]], group); + } - /** - * Set Core window such that it fits all items - * @param {Object} [options] Available options: - * `animate: boolean | number` - * If true (default), the range is animated - * smoothly to the new window. - * If a number, the number is taken as duration - * for the animation. Default duration is 500 ms. - */ - Core.prototype.fit = function(options) { - // apply the data range as range - var dataRange = this.getItemRange(); - // add 5% space on both sides - var start = dataRange.min; - var end = dataRange.max; - if (start != null && end != null) { - var interval = (end.valueOf() - start.valueOf()); - if (interval <= 0) { - // prevent an empty interval - interval = 24 * 60 * 60 * 1000; // 1 day + // draw the groups + for (i = 0; i < groupIds.length; i++) { + group = this.groups[groupIds[i]]; + if (group.options.style == 'line') { + this._drawLineGraph(processedGroupData[groupIds[i]], group); + } + } + this._drawBarGraphs(groupIds, processedGroupData); } - start = new Date(start.valueOf() - interval * 0.05); - end = new Date(end.valueOf() + interval * 0.05); - } - - // skip range set if there is no start and end date - if (start === null && end === null) { - return; } - var animate = (options && options.animate !== undefined) ? options.animate : true; - this.range.setRange(start, end, animate); + // cleanup unused svg elements + DOMutil.cleanupElements(this.svgElements); }; - /** - * Set the visible window. Both parameters are optional, you can change only - * start or only end. Syntax: - * - * TimeLine.setWindow(start, end) - * TimeLine.setWindow(range) - * - * Where start and end can be a Date, number, or string, and range is an - * object with properties start and end. - * - * @param {Date | Number | String | Object} [start] Start date of visible window - * @param {Date | Number | String} [end] End date of visible window - * @param {Object} [options] Available options: - * `animate: boolean | number` - * If true (default), the range is animated - * smoothly to the new window. - * If a number, the number is taken as duration - * for the animation. Default duration is 500 ms. - */ - Core.prototype.setWindow = function(start, end, options) { - var animate = (options && options.animate !== undefined) ? options.animate : true; - if (arguments.length == 1) { - var range = arguments[0]; - this.range.setRange(range.start, range.end, animate); - } - else { - this.range.setRange(start, end, animate); + + LineGraph.prototype._getRelevantData = function (groupIds, groupsData, minDate, maxDate) { + // first select and preprocess the data from the datasets. + // the groups have their preselection of data, we now loop over this data to see + // what data we need to draw. Sorted data is much faster. + // more optimization is possible by doing the sampling before and using the binary search + // to find the end date to determine the increment. + var group, i, j, item; + if (groupIds.length > 0) { + for (i = 0; i < groupIds.length; i++) { + group = this.groups[groupIds[i]]; + groupsData[groupIds[i]] = []; + var dataContainer = groupsData[groupIds[i]]; + // optimization for sorted data + if (group.options.sort == true) { + var guess = Math.max(0, util.binarySearchGeneric(group.itemsData, minDate, 'x', 'before')); + for (j = guess; j < group.itemsData.length; j++) { + item = group.itemsData[j]; + if (item !== undefined) { + if (item.x > maxDate) { + dataContainer.push(item); + break; + } + else { + dataContainer.push(item); + } + } + } + } + else { + for (j = 0; j < group.itemsData.length; j++) { + item = group.itemsData[j]; + if (item !== undefined) { + if (item.x > minDate && item.x < maxDate) { + dataContainer.push(item); + } + } + } + } + } } + + this._applySampling(groupIds, groupsData); }; - /** - * Move the window such that given time is centered on screen. - * @param {Date | Number | String} time - * @param {Object} [options] Available options: - * `animate: boolean | number` - * If true (default), the range is animated - * smoothly to the new window. - * If a number, the number is taken as duration - * for the animation. Default duration is 500 ms. - */ - Core.prototype.moveTo = function(time, options) { - var interval = this.range.end - this.range.start; - var t = util.convert(time, 'Date').valueOf(); + LineGraph.prototype._applySampling = function (groupIds, groupsData) { + var group; + if (groupIds.length > 0) { + for (var i = 0; i < groupIds.length; i++) { + group = this.groups[groupIds[i]]; + if (group.options.sampling == true) { + var dataContainer = groupsData[groupIds[i]]; + if (dataContainer.length > 0) { + var increment = 1; + var amountOfPoints = dataContainer.length; - var start = t - interval / 2; - var end = t + interval / 2; - var animate = (options && options.animate !== undefined) ? options.animate : true; + // the global screen is used because changing the width of the yAxis may affect the increment, resulting in an endless loop + // of width changing of the yAxis. + var xDistance = this.body.util.toGlobalScreen(dataContainer[dataContainer.length - 1].x) - this.body.util.toGlobalScreen(dataContainer[0].x); + var pointsPerPixel = amountOfPoints / xDistance; + increment = Math.min(Math.ceil(0.2 * amountOfPoints), Math.max(1, Math.round(pointsPerPixel))); - this.range.setRange(start, end, animate); - }; + var sampledData = []; + for (var j = 0; j < amountOfPoints; j += increment) { + sampledData.push(dataContainer[j]); - /** - * Get the visible window - * @return {{start: Date, end: Date}} Visible range - */ - Core.prototype.getWindow = function() { - var range = this.range.getRange(); - return { - start: new Date(range.start), - end: new Date(range.end) - }; + } + groupsData[groupIds[i]] = sampledData; + } + } + } + } }; - /** - * Force a redraw of the Core. Can be useful to manually redraw when - * option autoResize=false - */ - Core.prototype.redraw = function() { - var resized = false; - var options = this.options; - var props = this.props; - var dom = this.dom; + LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) { + var groupData, group, i,j; + var barCombinedDataLeft = []; + var barCombinedDataRight = []; + var barCombinedData; + if (groupIds.length > 0) { + for (i = 0; i < groupIds.length; i++) { + groupData = groupsData[groupIds[i]]; + if (groupData.length > 0) { + group = this.groups[groupIds[i]]; + if (group.options.style == 'line' || group.options.barChart.handleOverlap != "stack") { + var yMin = groupData[0].y; + var yMax = groupData[0].y; + for (j = 0; j < groupData.length; j++) { + yMin = yMin > groupData[j].y ? groupData[j].y : yMin; + yMax = yMax < groupData[j].y ? groupData[j].y : yMax; + } + groupRanges[groupIds[i]] = {min: yMin, max: yMax, yAxisOrientation: group.options.yAxisOrientation}; + } + else if (group.options.style == 'bar') { + if (group.options.yAxisOrientation == 'left') { + barCombinedData = barCombinedDataLeft; + } + else { + barCombinedData = barCombinedDataRight; + } - if (!dom) return; // when destroyed + groupRanges[groupIds[i]] = {min: 0, max: 0, yAxisOrientation: group.options.yAxisOrientation, ignore: true}; - DateUtil.updateHiddenDates(this.body, this.options.hiddenDates); + // combine data + for (j = 0; j < groupData.length; j++) { + barCombinedData.push({ + x: groupData[j].x, + y: groupData[j].y, + groupId: groupIds[i] + }); + } + } + } + } - // update class names - if (options.orientation == 'top') { - util.addClassName(dom.root, 'top'); - util.removeClassName(dom.root, 'bottom'); - } - else { - util.removeClassName(dom.root, 'top'); - util.addClassName(dom.root, 'bottom'); + var intersections; + if (barCombinedDataLeft.length > 0) { + // sort by time and by group + barCombinedDataLeft.sort(function (a, b) { + if (a.x == b.x) { + return a.groupId - b.groupId; + } else { + return a.x - b.x; + } + }); + intersections = {}; + this._getDataIntersections(intersections, barCombinedDataLeft); + groupRanges["__barchartLeft"] = this._getStackedBarYRange(intersections, barCombinedDataLeft); + groupRanges["__barchartLeft"].yAxisOrientation = "left"; + groupIds.push("__barchartLeft"); + } + if (barCombinedDataRight.length > 0) { + // sort by time and by group + barCombinedDataRight.sort(function (a, b) { + if (a.x == b.x) { + return a.groupId - b.groupId; + } else { + return a.x - b.x; + } + }); + intersections = {}; + this._getDataIntersections(intersections, barCombinedDataRight); + groupRanges["__barchartRight"] = this._getStackedBarYRange(intersections, barCombinedDataRight); + groupRanges["__barchartRight"].yAxisOrientation = "right"; + groupIds.push("__barchartRight"); + } } + }; - // update root width and height options - dom.root.style.maxHeight = util.option.asSize(options.maxHeight, ''); - dom.root.style.minHeight = util.option.asSize(options.minHeight, ''); - dom.root.style.width = util.option.asSize(options.width, ''); - - // calculate border widths - props.border.left = (dom.centerContainer.offsetWidth - dom.centerContainer.clientWidth) / 2; - props.border.right = props.border.left; - props.border.top = (dom.centerContainer.offsetHeight - dom.centerContainer.clientHeight) / 2; - props.border.bottom = props.border.top; - var borderRootHeight= dom.root.offsetHeight - dom.root.clientHeight; - var borderRootWidth = dom.root.offsetWidth - dom.root.clientWidth; - - // workaround for a bug in IE: the clientWidth of an element with - // a height:0px and overflow:hidden is not calculated and always has value 0 - if (dom.centerContainer.clientHeight === 0) { - props.border.left = props.border.top; - props.border.right = props.border.left; + LineGraph.prototype._getStackedBarYRange = function (intersections, combinedData) { + var key; + var yMin = combinedData[0].y; + var yMax = combinedData[0].y; + for (var i = 0; i < combinedData.length; i++) { + key = combinedData[i].x; + if (intersections[key] === undefined) { + yMin = yMin > combinedData[i].y ? combinedData[i].y : yMin; + yMax = yMax < combinedData[i].y ? combinedData[i].y : yMax; + } + else { + intersections[key].accumulated += combinedData[i].y; + } } - if (dom.root.clientHeight === 0) { - borderRootWidth = borderRootHeight; + for (var xpos in intersections) { + if (intersections.hasOwnProperty(xpos)) { + yMin = yMin > intersections[xpos].accumulated ? intersections[xpos].accumulated : yMin; + yMax = yMax < intersections[xpos].accumulated ? intersections[xpos].accumulated : yMax; + } } - // calculate the heights. If any of the side panels is empty, we set the height to - // minus the border width, such that the border will be invisible - props.center.height = dom.center.offsetHeight; - props.left.height = dom.left.offsetHeight; - props.right.height = dom.right.offsetHeight; - props.top.height = dom.top.clientHeight || -props.border.top; - props.bottom.height = dom.bottom.clientHeight || -props.border.bottom; + return {min: yMin, max: yMax}; + }; - // TODO: compensate borders when any of the panels is empty. - // apply auto height - // TODO: only calculate autoHeight when needed (else we cause an extra reflow/repaint of the DOM) - var contentHeight = Math.max(props.left.height, props.center.height, props.right.height); - var autoHeight = props.top.height + contentHeight + props.bottom.height + - borderRootHeight + props.border.top + props.border.bottom; - dom.root.style.height = util.option.asSize(options.height, autoHeight + 'px'); + /** + * this sets the Y ranges for the Y axis. It also determines which of the axis should be shown or hidden. + * @param {Array} groupIds + * @param {Object} groupRanges + * @private + */ + LineGraph.prototype._updateYAxis = function (groupIds, groupRanges) { + var changeCalled = false; + var yAxisLeftUsed = false; + var yAxisRightUsed = false; + var minLeft = 1e9, minRight = 1e9, maxLeft = -1e9, maxRight = -1e9, minVal, maxVal; + // if groups are present + if (groupIds.length > 0) { + for (var i = 0; i < groupIds.length; i++) { + if (groupRanges.hasOwnProperty(groupIds[i])) { + if (groupRanges[groupIds[i]].ignore !== true) { + minVal = groupRanges[groupIds[i]].min; + maxVal = groupRanges[groupIds[i]].max; - // calculate heights of the content panels - props.root.height = dom.root.offsetHeight; - props.background.height = props.root.height - borderRootHeight; - var containerHeight = props.root.height - props.top.height - props.bottom.height - - borderRootHeight; - props.centerContainer.height = containerHeight; - props.leftContainer.height = containerHeight; - props.rightContainer.height = props.leftContainer.height; + if (groupRanges[groupIds[i]].yAxisOrientation == 'left') { + yAxisLeftUsed = true; + minLeft = minLeft > minVal ? minVal : minLeft; + maxLeft = maxLeft < maxVal ? maxVal : maxLeft; + } + else { + yAxisRightUsed = true; + minRight = minRight > minVal ? minVal : minRight; + maxRight = maxRight < maxVal ? maxVal : maxRight; + } + } + } + } - // calculate the widths of the panels - props.root.width = dom.root.offsetWidth; - props.background.width = props.root.width - borderRootWidth; - props.left.width = dom.leftContainer.clientWidth || -props.border.left; - props.leftContainer.width = props.left.width; - props.right.width = dom.rightContainer.clientWidth || -props.border.right; - props.rightContainer.width = props.right.width; - var centerWidth = props.root.width - props.left.width - props.right.width - borderRootWidth; - props.center.width = centerWidth; - props.centerContainer.width = centerWidth; - props.top.width = centerWidth; - props.bottom.width = centerWidth; + if (yAxisLeftUsed == true) { + this.yAxisLeft.setRange(minLeft, maxLeft); + } + if (yAxisRightUsed == true) { + this.yAxisRight.setRange(minRight, maxRight); + } + } - // resize the panels - dom.background.style.height = props.background.height + 'px'; - dom.backgroundVertical.style.height = props.background.height + 'px'; - dom.backgroundHorizontal.style.height = props.centerContainer.height + 'px'; - dom.centerContainer.style.height = props.centerContainer.height + 'px'; - dom.leftContainer.style.height = props.leftContainer.height + 'px'; - dom.rightContainer.style.height = props.rightContainer.height + 'px'; + changeCalled = this._toggleAxisVisiblity(yAxisLeftUsed , this.yAxisLeft) || changeCalled; + changeCalled = this._toggleAxisVisiblity(yAxisRightUsed, this.yAxisRight) || changeCalled; + + if (yAxisRightUsed == true && yAxisLeftUsed == true) { + this.yAxisLeft.drawIcons = true; + this.yAxisRight.drawIcons = true; + } + else { + this.yAxisLeft.drawIcons = false; + this.yAxisRight.drawIcons = false; + } - dom.background.style.width = props.background.width + 'px'; - dom.backgroundVertical.style.width = props.centerContainer.width + 'px'; - dom.backgroundHorizontal.style.width = props.background.width + 'px'; - dom.centerContainer.style.width = props.center.width + 'px'; - dom.top.style.width = props.top.width + 'px'; - dom.bottom.style.width = props.bottom.width + 'px'; + this.yAxisRight.master = !yAxisLeftUsed; - // reposition the panels - dom.background.style.left = '0'; - dom.background.style.top = '0'; - dom.backgroundVertical.style.left = (props.left.width + props.border.left) + 'px'; - dom.backgroundVertical.style.top = '0'; - dom.backgroundHorizontal.style.left = '0'; - dom.backgroundHorizontal.style.top = props.top.height + 'px'; - dom.centerContainer.style.left = props.left.width + 'px'; - dom.centerContainer.style.top = props.top.height + 'px'; - dom.leftContainer.style.left = '0'; - dom.leftContainer.style.top = props.top.height + 'px'; - dom.rightContainer.style.left = (props.left.width + props.center.width) + 'px'; - dom.rightContainer.style.top = props.top.height + 'px'; - dom.top.style.left = props.left.width + 'px'; - dom.top.style.top = '0'; - dom.bottom.style.left = props.left.width + 'px'; - dom.bottom.style.top = (props.top.height + props.centerContainer.height) + 'px'; + if (this.yAxisRight.master == false) { + if (yAxisRightUsed == true) {this.yAxisLeft.lineOffset = this.yAxisRight.width;} + else {this.yAxisLeft.lineOffset = 0;} - // update the scrollTop, feasible range for the offset can be changed - // when the height of the Core or of the contents of the center changed - this._updateScrollTop(); + changeCalled = this.yAxisLeft.redraw() || changeCalled; + this.yAxisRight.stepPixelsForced = this.yAxisLeft.stepPixels; + changeCalled = this.yAxisRight.redraw() || changeCalled; + } + else { + changeCalled = this.yAxisRight.redraw() || changeCalled; + } - // reposition the scrollable contents - var offset = this.props.scrollTop; - if (options.orientation == 'bottom') { - offset += Math.max(this.props.centerContainer.height - this.props.center.height - - this.props.border.top - this.props.border.bottom, 0); + // clean the accumulated lists + if (groupIds.indexOf("__barchartLeft") != -1) { + groupIds.splice(groupIds.indexOf("__barchartLeft"),1); + } + if (groupIds.indexOf("__barchartRight") != -1) { + groupIds.splice(groupIds.indexOf("__barchartRight"),1); } - dom.center.style.left = '0'; - dom.center.style.top = offset + 'px'; - dom.left.style.left = '0'; - dom.left.style.top = offset + 'px'; - dom.right.style.left = '0'; - dom.right.style.top = offset + 'px'; - // show shadows when vertical scrolling is available - var visibilityTop = this.props.scrollTop == 0 ? 'hidden' : ''; - var visibilityBottom = this.props.scrollTop == this.props.scrollTopMin ? 'hidden' : ''; - dom.shadowTop.style.visibility = visibilityTop; - dom.shadowBottom.style.visibility = visibilityBottom; - dom.shadowTopLeft.style.visibility = visibilityTop; - dom.shadowBottomLeft.style.visibility = visibilityBottom; - dom.shadowTopRight.style.visibility = visibilityTop; - dom.shadowBottomRight.style.visibility = visibilityBottom; + return changeCalled; + }; - // redraw all components - this.components.forEach(function (component) { - resized = component.redraw() || resized; - }); - if (resized) { - // keep repainting until all sizes are settled - this.redraw(); + /** + * This shows or hides the Y axis if needed. If there is a change, the changed event is emitted by the updateYAxis function + * + * @param {boolean} axisUsed + * @returns {boolean} + * @private + * @param axis + */ + LineGraph.prototype._toggleAxisVisiblity = function (axisUsed, axis) { + var changed = false; + if (axisUsed == false) { + if (axis.dom.frame.parentNode) { + axis.hide(); + changed = true; + } + } + else { + if (!axis.dom.frame.parentNode) { + axis.show(); + changed = true; + } } + return changed; }; - // TODO: deprecated since version 1.1.0, remove some day - Core.prototype.repaint = function () { - throw new Error('Function repaint is deprecated. Use redraw instead.'); - }; /** - * Set a current time. This can be used for example to ensure that a client's - * time is synchronized with a shared server time. - * Only applicable when option `showCurrentTime` is true. - * @param {Date | String | Number} time A Date, unix timestamp, or - * ISO date string. + * draw a bar graph + * + * @param groupIds + * @param processedGroupData */ - Core.prototype.setCurrentTime = function(time) { - if (!this.currentTime) { - throw new Error('Option showCurrentTime must be true'); + LineGraph.prototype._drawBarGraphs = function (groupIds, processedGroupData) { + var combinedData = []; + var intersections = {}; + var coreDistance; + var key, drawData; + var group; + var i,j; + var barPoints = 0; + + // combine all barchart data + for (i = 0; i < groupIds.length; i++) { + group = this.groups[groupIds[i]]; + if (group.options.style == 'bar') { + if (group.visible == true && (this.options.groups.visibility[groupIds[i]] === undefined || this.options.groups.visibility[groupIds[i]] == true)) { + for (j = 0; j < processedGroupData[groupIds[i]].length; j++) { + combinedData.push({ + x: processedGroupData[groupIds[i]][j].x, + y: processedGroupData[groupIds[i]][j].y, + groupId: groupIds[i] + }); + barPoints += 1; + } + } + } } - this.currentTime.setCurrentTime(time); + if (barPoints == 0) {return;} + + // sort by time and by group + combinedData.sort(function (a, b) { + if (a.x == b.x) { + return a.groupId - b.groupId; + } else { + return a.x - b.x; + } + }); + + // get intersections + this._getDataIntersections(intersections, combinedData); + + // plot barchart + for (i = 0; i < combinedData.length; i++) { + group = this.groups[combinedData[i].groupId]; + var minWidth = 0.1 * group.options.barChart.width; + + key = combinedData[i].x; + var heightOffset = 0; + if (intersections[key] === undefined) { + if (i+1 < combinedData.length) {coreDistance = Math.abs(combinedData[i+1].x - key);} + if (i > 0) {coreDistance = Math.min(coreDistance,Math.abs(combinedData[i-1].x - key));} + drawData = this._getSafeDrawData(coreDistance, group, minWidth); + } + else { + var nextKey = i + (intersections[key].amount - intersections[key].resolved); + var prevKey = i - (intersections[key].resolved + 1); + if (nextKey < combinedData.length) {coreDistance = Math.abs(combinedData[nextKey].x - key);} + if (prevKey > 0) {coreDistance = Math.min(coreDistance,Math.abs(combinedData[prevKey].x - key));} + drawData = this._getSafeDrawData(coreDistance, group, minWidth); + intersections[key].resolved += 1; + + if (group.options.barChart.handleOverlap == 'stack') { + heightOffset = intersections[key].accumulated; + intersections[key].accumulated += group.zeroPosition - combinedData[i].y; + } + else if (group.options.barChart.handleOverlap == 'sideBySide') { + drawData.width = drawData.width / intersections[key].amount; + drawData.offset += (intersections[key].resolved) * drawData.width - (0.5*drawData.width * (intersections[key].amount+1)); + if (group.options.barChart.align == 'left') {drawData.offset -= 0.5*drawData.width;} + else if (group.options.barChart.align == 'right') {drawData.offset += 0.5*drawData.width;} + } + } + DOMutil.drawBar(combinedData[i].x + drawData.offset, combinedData[i].y - heightOffset, drawData.width, group.zeroPosition - combinedData[i].y, group.className + ' bar', this.svgElements, this.svg); + // draw points + if (group.options.drawPoints.enabled == true) { + DOMutil.drawPoint(combinedData[i].x + drawData.offset, combinedData[i].y - heightOffset, group, this.svgElements, this.svg); + } + } }; /** - * Get the current time. - * Only applicable when option `showCurrentTime` is true. - * @return {Date} Returns the current time. + * Fill the intersections object with counters of how many datapoints share the same x coordinates + * @param intersections + * @param combinedData + * @private */ - Core.prototype.getCurrentTime = function() { - if (!this.currentTime) { - throw new Error('Option showCurrentTime must be true'); + LineGraph.prototype._getDataIntersections = function (intersections, combinedData) { + // get intersections + var coreDistance; + for (var i = 0; i < combinedData.length; i++) { + if (i + 1 < combinedData.length) { + coreDistance = Math.abs(combinedData[i + 1].x - combinedData[i].x); + } + if (i > 0) { + coreDistance = Math.min(coreDistance, Math.abs(combinedData[i - 1].x - combinedData[i].x)); + } + if (coreDistance == 0) { + if (intersections[combinedData[i].x] === undefined) { + intersections[combinedData[i].x] = {amount: 0, resolved: 0, accumulated: 0}; + } + intersections[combinedData[i].x].amount += 1; + } } - - return this.currentTime.getCurrentTime(); }; /** - * Convert a position on screen (pixels) to a datetime - * @param {int} x Position on the screen in pixels - * @return {Date} time The datetime the corresponds with given position x + * Get the width and offset for bargraphs based on the coredistance between datapoints + * + * @param coreDistance + * @param group + * @param minWidth + * @returns {{width: Number, offset: Number}} * @private */ - // TODO: move this function to Range - Core.prototype._toTime = function(x) { - return DateUtil.toTime(this.body, this.range, x, this.props.center.width); + LineGraph.prototype._getSafeDrawData = function (coreDistance, group, minWidth) { + var width, offset; + if (coreDistance < group.options.barChart.width && coreDistance > 0) { + width = coreDistance < minWidth ? minWidth : coreDistance; + + offset = 0; // recalculate offset with the new width; + if (group.options.barChart.align == 'left') { + offset -= 0.5 * coreDistance; + } + else if (group.options.barChart.align == 'right') { + offset += 0.5 * coreDistance; + } + } + else { + // default settings + width = group.options.barChart.width; + offset = 0; + if (group.options.barChart.align == 'left') { + offset -= 0.5 * group.options.barChart.width; + } + else if (group.options.barChart.align == 'right') { + offset += 0.5 * group.options.barChart.width; + } + } + + return {width: width, offset: offset}; }; + /** - * Convert a position on the global screen (pixels) to a datetime - * @param {int} x Position on the screen in pixels - * @return {Date} time The datetime the corresponds with given position x - * @private + * draw a line graph + * + * @param dataset + * @param group */ - // TODO: move this function to Range - Core.prototype._toGlobalTime = function(x) { - return DateUtil.toTime(this.body, this.range, x, this.props.root.width); - //var conversion = this.range.conversion(this.props.root.width); - //return new Date(x / conversion.scale + conversion.offset); + LineGraph.prototype._drawLineGraph = function (dataset, group) { + if (dataset != null) { + if (dataset.length > 0) { + var path, d; + var svgHeight = Number(this.svg.style.height.replace("px","")); + path = DOMutil.getSVGElement('path', this.svgElements, this.svg); + path.setAttributeNS(null, "class", group.className); + + // construct path from dataset + if (group.options.catmullRom.enabled == true) { + d = this._catmullRom(dataset, group); + } + else { + d = this._linear(dataset); + } + + // append with points for fill and finalize the path + if (group.options.shaded.enabled == true) { + var fillPath = DOMutil.getSVGElement('path',this.svgElements, this.svg); + var dFill; + if (group.options.shaded.orientation == 'top') { + dFill = "M" + dataset[0].x + "," + 0 + " " + d + "L" + dataset[dataset.length - 1].x + "," + 0; + } + else { + dFill = "M" + dataset[0].x + "," + svgHeight + " " + d + "L" + dataset[dataset.length - 1].x + "," + svgHeight; + } + fillPath.setAttributeNS(null, "class", group.className + " fill"); + fillPath.setAttributeNS(null, "d", dFill); + } + // copy properties to path for drawing. + path.setAttributeNS(null, "d", "M" + d); + + // draw points + if (group.options.drawPoints.enabled == true) { + this._drawPoints(dataset, group, this.svgElements, this.svg); + } + } + } }; /** - * Convert a datetime (Date object) into a position on the screen - * @param {Date} time A date - * @return {int} x The position on the screen in pixels which corresponds - * with the given date. - * @private + * draw the data points + * + * @param {Array} dataset + * @param {Object} JSONcontainer + * @param {Object} svg | SVG DOM element + * @param {GraphGroup} group + * @param {Number} [offset] */ - // TODO: move this function to Range - Core.prototype._toScreen = function(time) { - return DateUtil.toScreen(this, time, this.props.center.width); + LineGraph.prototype._drawPoints = function (dataset, group, JSONcontainer, svg, offset) { + if (offset === undefined) {offset = 0;} + for (var i = 0; i < dataset.length; i++) { + DOMutil.drawPoint(dataset[i].x + offset, dataset[i].y, group, JSONcontainer, svg); + } }; /** - * Convert a datetime (Date object) into a position on the root - * This is used to get the pixel density estimate for the screen, not the center panel - * @param {Date} time A date - * @return {int} x The position on root in pixels which corresponds - * with the given date. + * This uses the DataAxis object to generate the correct X coordinate on the SVG window. It uses the + * util function toScreen to get the x coordinate from the timestamp. It also pre-filters the data and get the minMax ranges for + * the yAxis. + * + * @param datapoints + * @returns {Array} * @private */ - // TODO: move this function to Range - Core.prototype._toGlobalScreen = function(time) { - return DateUtil.toScreen(this, time, this.props.root.width); - //var conversion = this.range.conversion(this.props.root.width); - //return (time.valueOf() - conversion.offset) * conversion.scale; + LineGraph.prototype._convertXcoordinates = function (datapoints) { + var extractedData = []; + var xValue, yValue; + var toScreen = this.body.util.toScreen; + + for (var i = 0; i < datapoints.length; i++) { + xValue = toScreen(datapoints[i].x) + this.width; + yValue = datapoints[i].y; + extractedData.push({x: xValue, y: yValue}); + } + + return extractedData; }; + /** - * Initialize watching when option autoResize is true + * This uses the DataAxis object to generate the correct X coordinate on the SVG window. It uses the + * util function toScreen to get the x coordinate from the timestamp. It also pre-filters the data and get the minMax ranges for + * the yAxis. + * + * @param datapoints + * @returns {Array} * @private */ - Core.prototype._initAutoResize = function () { - if (this.options.autoResize == true) { - this._startAutoResize(); + LineGraph.prototype._convertYcoordinates = function (datapoints, group) { + var extractedData = []; + var xValue, yValue; + var toScreen = this.body.util.toScreen; + var axis = this.yAxisLeft; + var svgHeight = Number(this.svg.style.height.replace("px","")); + if (group.options.yAxisOrientation == 'right') { + axis = this.yAxisRight; } - else { - this._stopAutoResize(); + + for (var i = 0; i < datapoints.length; i++) { + xValue = toScreen(datapoints[i].x) + this.width; + yValue = Math.round(axis.convertValue(datapoints[i].y)); + extractedData.push({x: xValue, y: yValue}); } + + group.setZeroPosition(Math.min(svgHeight, axis.convertValue(0))); + + return extractedData; }; /** - * Watch for changes in the size of the container. On resize, the Panel will - * automatically redraw itself. + * This uses an uniform parametrization of the CatmullRom algorithm: + * "On the Parameterization of Catmull-Rom Curves" by Cem Yuksel et al. + * @param data + * @returns {string} * @private */ - Core.prototype._startAutoResize = function () { - var me = this; + LineGraph.prototype._catmullRomUniform = function(data) { + // catmull rom + var p0, p1, p2, p3, bp1, bp2; + var d = Math.round(data[0].x) + "," + Math.round(data[0].y) + " "; + var normalization = 1/6; + var length = data.length; + for (var i = 0; i < length - 1; i++) { - this._stopAutoResize(); + p0 = (i == 0) ? data[0] : data[i-1]; + p1 = data[i]; + p2 = data[i+1]; + p3 = (i + 2 < length) ? data[i+2] : p2; - this._onResize = function() { - if (me.options.autoResize != true) { - // stop watching when the option autoResize is changed to false - me._stopAutoResize(); - return; - } - if (me.dom.root) { - // check whether the frame is resized - // Note: we compare offsetWidth here, not clientWidth. For some reason, - // IE does not restore the clientWidth from 0 to the actual width after - // changing the timeline's container display style from none to visible - if ((me.dom.root.offsetWidth != me.props.lastWidth) || - (me.dom.root.offsetHeight != me.props.lastHeight)) { - me.props.lastWidth = me.dom.root.offsetWidth; - me.props.lastHeight = me.dom.root.offsetHeight; + // Catmull-Rom to Cubic Bezier conversion matrix + // 0 1 0 0 + // -1/6 1 1/6 0 + // 0 1/6 1 -1/6 + // 0 0 1 0 - me.emit('change'); - } - } - }; + // bp0 = { x: p1.x, y: p1.y }; + bp1 = { x: ((-p0.x + 6*p1.x + p2.x) *normalization), y: ((-p0.y + 6*p1.y + p2.y) *normalization)}; + bp2 = { x: (( p1.x + 6*p2.x - p3.x) *normalization), y: (( p1.y + 6*p2.y - p3.y) *normalization)}; + // bp0 = { x: p2.x, y: p2.y }; - // add event listener to window resize - util.addEventListener(window, 'resize', this._onResize); + d += "C" + + bp1.x + "," + + bp1.y + " " + + bp2.x + "," + + bp2.y + " " + + p2.x + "," + + p2.y + " "; + } - this.watchTimer = setInterval(this._onResize, 1000); + return d; }; /** - * Stop watching for a resize of the frame. + * This uses either the chordal or centripetal parameterization of the catmull-rom algorithm. + * By default, the centripetal parameterization is used because this gives the nicest results. + * These parameterizations are relatively heavy because the distance between 4 points have to be calculated. + * + * One optimization can be used to reuse distances since this is a sliding window approach. + * @param data + * @returns {string} * @private */ - Core.prototype._stopAutoResize = function () { - if (this.watchTimer) { - clearInterval(this.watchTimer); - this.watchTimer = undefined; + LineGraph.prototype._catmullRom = function(data, group) { + var alpha = group.options.catmullRom.alpha; + if (alpha == 0 || alpha === undefined) { + return this._catmullRomUniform(data); } + else { + var p0, p1, p2, p3, bp1, bp2, d1,d2,d3, A, B, N, M; + var d3powA, d2powA, d3pow2A, d2pow2A, d1pow2A, d1powA; + var d = Math.round(data[0].x) + "," + Math.round(data[0].y) + " "; + var length = data.length; + for (var i = 0; i < length - 1; i++) { - // remove event listener on window.resize - util.removeEventListener(window, 'resize', this._onResize); - this._onResize = null; - }; - - /** - * Start moving the timeline vertically - * @param {Event} event - * @private - */ - Core.prototype._onTouch = function (event) { - this.touch.allowDragging = true; - }; + p0 = (i == 0) ? data[0] : data[i-1]; + p1 = data[i]; + p2 = data[i+1]; + p3 = (i + 2 < length) ? data[i+2] : p2; - /** - * Start moving the timeline vertically - * @param {Event} event - * @private - */ - Core.prototype._onPinch = function (event) { - this.touch.allowDragging = false; - }; + d1 = Math.sqrt(Math.pow(p0.x - p1.x,2) + Math.pow(p0.y - p1.y,2)); + d2 = Math.sqrt(Math.pow(p1.x - p2.x,2) + Math.pow(p1.y - p2.y,2)); + d3 = Math.sqrt(Math.pow(p2.x - p3.x,2) + Math.pow(p2.y - p3.y,2)); - /** - * Start moving the timeline vertically - * @param {Event} event - * @private - */ - Core.prototype._onDragStart = function (event) { - this.touch.initialScrollTop = this.props.scrollTop; - }; + // Catmull-Rom to Cubic Bezier conversion matrix + // + // A = 2d1^2a + 3d1^a * d2^a + d3^2a + // B = 2d3^2a + 3d3^a * d2^a + d2^2a + // + // [ 0 1 0 0 ] + // [ -d2^2a/N A/N d1^2a/N 0 ] + // [ 0 d3^2a/M B/M -d2^2a/M ] + // [ 0 0 1 0 ] - /** - * Move the timeline vertically - * @param {Event} event - * @private - */ - Core.prototype._onDrag = function (event) { - // refuse to drag when we where pinching to prevent the timeline make a jump - // when releasing the fingers in opposite order from the touch screen - if (!this.touch.allowDragging) return; + // [ 0 1 0 0 ] + // [ -d2pow2a/N A/N d1pow2a/N 0 ] + // [ 0 d3pow2a/M B/M -d2pow2a/M ] + // [ 0 0 1 0 ] - var delta = event.gesture.deltaY; + d3powA = Math.pow(d3, alpha); + d3pow2A = Math.pow(d3,2*alpha); + d2powA = Math.pow(d2, alpha); + d2pow2A = Math.pow(d2,2*alpha); + d1powA = Math.pow(d1, alpha); + d1pow2A = Math.pow(d1,2*alpha); - var oldScrollTop = this._getScrollTop(); - var newScrollTop = this._setScrollTop(this.touch.initialScrollTop + delta); + A = 2*d1pow2A + 3*d1powA * d2powA + d2pow2A; + B = 2*d3pow2A + 3*d3powA * d2powA + d2pow2A; + N = 3*d1powA * (d1powA + d2powA); + if (N > 0) {N = 1 / N;} + M = 3*d3powA * (d3powA + d2powA); + if (M > 0) {M = 1 / M;} - if (newScrollTop != oldScrollTop) { - this.redraw(); // TODO: this causes two redraws when dragging, the other is triggered by rangechange already - } - }; + bp1 = { x: ((-d2pow2A * p0.x + A*p1.x + d1pow2A * p2.x) * N), + y: ((-d2pow2A * p0.y + A*p1.y + d1pow2A * p2.y) * N)}; - /** - * Apply a scrollTop - * @param {Number} scrollTop - * @returns {Number} scrollTop Returns the applied scrollTop - * @private - */ - Core.prototype._setScrollTop = function (scrollTop) { - this.props.scrollTop = scrollTop; - this._updateScrollTop(); - return this.props.scrollTop; - }; + bp2 = { x: (( d3pow2A * p1.x + B*p2.x - d2pow2A * p3.x) * M), + y: (( d3pow2A * p1.y + B*p2.y - d2pow2A * p3.y) * M)}; - /** - * Update the current scrollTop when the height of the containers has been changed - * @returns {Number} scrollTop Returns the applied scrollTop - * @private - */ - Core.prototype._updateScrollTop = function () { - // recalculate the scrollTopMin - var scrollTopMin = Math.min(this.props.centerContainer.height - this.props.center.height, 0); // is negative or zero - if (scrollTopMin != this.props.scrollTopMin) { - // in case of bottom orientation, change the scrollTop such that the contents - // do not move relative to the time axis at the bottom - if (this.options.orientation == 'bottom') { - this.props.scrollTop += (scrollTopMin - this.props.scrollTopMin); + if (bp1.x == 0 && bp1.y == 0) {bp1 = p1;} + if (bp2.x == 0 && bp2.y == 0) {bp2 = p2;} + d += "C" + + bp1.x + "," + + bp1.y + " " + + bp2.x + "," + + bp2.y + " " + + p2.x + "," + + p2.y + " "; } - this.props.scrollTopMin = scrollTopMin; - } - // limit the scrollTop to the feasible scroll range - if (this.props.scrollTop > 0) this.props.scrollTop = 0; - if (this.props.scrollTop < scrollTopMin) this.props.scrollTop = scrollTopMin; - - return this.props.scrollTop; + return d; + } }; /** - * Get the current scrollTop - * @returns {number} scrollTop + * this generates the SVG path for a linear drawing between datapoints. + * @param data + * @returns {string} * @private */ - Core.prototype._getScrollTop = function () { - return this.props.scrollTop; + LineGraph.prototype._linear = function(data) { + // linear + var d = ""; + for (var i = 0; i < data.length; i++) { + if (i == 0) { + d += data[i].x + "," + data[i].y; + } + else { + d += " " + data[i].x + "," + data[i].y; + } + } + return d; }; - module.exports = Core; + module.exports = LineGraph; /***/ }, -/* 25 */ +/* 29 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(1); - var Component = __webpack_require__(22); - var TimeStep = __webpack_require__(26); - var DateUtil = __webpack_require__(23); - var moment = __webpack_require__(2); + var Component = __webpack_require__(19); + var TimeStep = __webpack_require__(18); + var DateUtil = __webpack_require__(14); + var moment = __webpack_require__(43); /** * A horizontal time axis @@ -13992,18835 +13582,19353 @@ return /******/ (function(modules) { // webpackBootstrap this._repaintLabels(); - // put DOM online again (at the same place) - if (foregroundNextSibling) { - parent.insertBefore(foreground, foregroundNextSibling); + // put DOM online again (at the same place) + if (foregroundNextSibling) { + parent.insertBefore(foreground, foregroundNextSibling); + } + else { + parent.appendChild(foreground) + } + if (backgroundNextSibling) { + this.body.dom.backgroundVertical.insertBefore(background, backgroundNextSibling); + } + else { + this.body.dom.backgroundVertical.appendChild(background) + } + + return this._isResized() || parentChanged; + }; + + /** + * Repaint major and minor text labels and vertical grid lines + * @private + */ + TimeAxis.prototype._repaintLabels = function () { + var orientation = this.options.orientation; + + // calculate range and step (step such that we have space for 7 characters per label) + var start = util.convert(this.body.range.start, 'Number'); + var end = util.convert(this.body.range.end, 'Number'); + var timeLabelsize = this.body.util.toTime((this.props.minorCharWidth || 10) * 7).valueOf(); + var minimumStep = timeLabelsize - DateUtil.getHiddenDurationBefore(this.body.hiddenDates, this.body.range, timeLabelsize); + minimumStep -= this.body.util.toTime(0).valueOf(); + + + var step = new TimeStep(new Date(start), new Date(end), minimumStep, this.body.hiddenDates); + this.step = step; + + // Move all DOM elements to a "redundant" list, where they + // can be picked for re-use, and clear the lists with lines and texts. + // At the end of the function _repaintLabels, left over elements will be cleaned up + var dom = this.dom; + dom.redundant.majorLines = dom.majorLines; + dom.redundant.majorTexts = dom.majorTexts; + dom.redundant.minorLines = dom.minorLines; + dom.redundant.minorTexts = dom.minorTexts; + dom.majorLines = []; + dom.majorTexts = []; + dom.minorLines = []; + dom.minorTexts = []; + + step.first(); + var xFirstMajorLabel = undefined; + var max = 0; + while (step.hasNext() && max < 1000) { + max++; + var cur = step.getCurrent(); + var x = this.body.util.toScreen(cur); + var isMajor = step.isMajor(); + + + // TODO: lines must have a width, such that we can create css backgrounds + + if (this.options.showMinorLabels) { + this._repaintMinorText(x, step.getLabelMinor(), orientation); + } + + if (isMajor && this.options.showMajorLabels) { + if (x > 0) { + if (xFirstMajorLabel == undefined) { + xFirstMajorLabel = x; + } + this._repaintMajorText(x, step.getLabelMajor(), orientation); + } + this._repaintMajorLine(x, orientation); + } + else { + this._repaintMinorLine(x, orientation); + } + + step.next(); + } + + // create a major label on the left when needed + if (this.options.showMajorLabels) { + var leftTime = this.body.util.toTime(0), + leftText = step.getLabelMajor(leftTime), + widthText = leftText.length * (this.props.majorCharWidth || 10) + 10; // upper bound estimation + + if (xFirstMajorLabel == undefined || widthText < xFirstMajorLabel) { + this._repaintMajorText(0, leftText, orientation); + } + } + + // Cleanup leftover DOM elements from the redundant list + util.forEach(this.dom.redundant, function (arr) { + while (arr.length) { + var elem = arr.pop(); + if (elem && elem.parentNode) { + elem.parentNode.removeChild(elem); + } + } + }); + }; + + /** + * Create a minor label for the axis at position x + * @param {Number} x + * @param {String} text + * @param {String} orientation "top" or "bottom" (default) + * @private + */ + TimeAxis.prototype._repaintMinorText = function (x, text, orientation) { + // reuse redundant label + var label = this.dom.redundant.minorTexts.shift(); + + if (!label) { + // create new label + var content = document.createTextNode(''); + label = document.createElement('div'); + label.appendChild(content); + label.className = 'text minor'; + this.dom.foreground.appendChild(label); + } + this.dom.minorTexts.push(label); + + label.childNodes[0].nodeValue = text; + + label.style.top = (orientation == 'top') ? (this.props.majorLabelHeight + 'px') : '0'; + label.style.left = x + 'px'; + //label.title = title; // TODO: this is a heavy operation + }; + + /** + * Create a Major label for the axis at position x + * @param {Number} x + * @param {String} text + * @param {String} orientation "top" or "bottom" (default) + * @private + */ + TimeAxis.prototype._repaintMajorText = function (x, text, orientation) { + // reuse redundant label + var label = this.dom.redundant.majorTexts.shift(); + + if (!label) { + // create label + var content = document.createTextNode(text); + label = document.createElement('div'); + label.className = 'text major'; + label.appendChild(content); + this.dom.foreground.appendChild(label); + } + this.dom.majorTexts.push(label); + + label.childNodes[0].nodeValue = text; + //label.title = title; // TODO: this is a heavy operation + + label.style.top = (orientation == 'top') ? '0' : (this.props.minorLabelHeight + 'px'); + label.style.left = x + 'px'; + }; + + /** + * Create a minor line for the axis at position x + * @param {Number} x + * @param {String} orientation "top" or "bottom" (default) + * @private + */ + TimeAxis.prototype._repaintMinorLine = function (x, orientation) { + // reuse redundant line + var line = this.dom.redundant.minorLines.shift(); + + if (!line) { + // create vertical line + line = document.createElement('div'); + line.className = 'grid vertical minor'; + this.dom.background.appendChild(line); + } + this.dom.minorLines.push(line); + + var props = this.props; + if (orientation == 'top') { + line.style.top = props.majorLabelHeight + 'px'; + } + else { + line.style.top = this.body.domProps.top.height + 'px'; + } + line.style.height = props.minorLineHeight + 'px'; + line.style.left = (x - props.minorLineWidth / 2) + 'px'; + }; + + /** + * Create a Major line for the axis at position x + * @param {Number} x + * @param {String} orientation "top" or "bottom" (default) + * @private + */ + TimeAxis.prototype._repaintMajorLine = function (x, orientation) { + // reuse redundant line + var line = this.dom.redundant.majorLines.shift(); + + if (!line) { + // create vertical line + line = document.createElement('DIV'); + line.className = 'grid vertical major'; + this.dom.background.appendChild(line); + } + this.dom.majorLines.push(line); + + var props = this.props; + if (orientation == 'top') { + line.style.top = '0'; + } + else { + line.style.top = this.body.domProps.top.height + 'px'; + } + line.style.left = (x - props.majorLineWidth / 2) + 'px'; + line.style.height = props.majorLineHeight + 'px'; + }; + + /** + * Determine the size of text on the axis (both major and minor axis). + * The size is calculated only once and then cached in this.props. + * @private + */ + TimeAxis.prototype._calculateCharSize = function () { + // Note: We calculate char size with every redraw. Size may change, for + // example when any of the timelines parents had display:none for example. + + // determine the char width and height on the minor axis + if (!this.dom.measureCharMinor) { + this.dom.measureCharMinor = document.createElement('DIV'); + this.dom.measureCharMinor.className = 'text minor measure'; + this.dom.measureCharMinor.style.position = 'absolute'; + + this.dom.measureCharMinor.appendChild(document.createTextNode('0')); + this.dom.foreground.appendChild(this.dom.measureCharMinor); + } + this.props.minorCharHeight = this.dom.measureCharMinor.clientHeight; + this.props.minorCharWidth = this.dom.measureCharMinor.clientWidth; + + // determine the char width and height on the major axis + if (!this.dom.measureCharMajor) { + this.dom.measureCharMajor = document.createElement('DIV'); + this.dom.measureCharMajor.className = 'text major measure'; + this.dom.measureCharMajor.style.position = 'absolute'; + + this.dom.measureCharMajor.appendChild(document.createTextNode('0')); + this.dom.foreground.appendChild(this.dom.measureCharMajor); + } + this.props.majorCharHeight = this.dom.measureCharMajor.clientHeight; + this.props.majorCharWidth = this.dom.measureCharMajor.clientWidth; + }; + + /** + * Snap a date to a rounded value. + * The snap intervals are dependent on the current scale and step. + * @param {Date} date the date to be snapped. + * @return {Date} snappedDate + */ + TimeAxis.prototype.snap = function(date) { + return this.step.snap(date); + }; + + module.exports = TimeAxis; + + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + var Hammer = __webpack_require__(44); + var util = __webpack_require__(1); + + /** + * @constructor Item + * @param {Object} data Object containing (optional) parameters type, + * start, end, content, group, className. + * @param {{toScreen: function, toTime: function}} conversion + * Conversion functions from time to screen and vice versa + * @param {Object} options Configuration options + * // TODO: describe available options + */ + function Item (data, conversion, options) { + this.id = null; + this.parent = null; + this.data = data; + this.dom = null; + this.conversion = conversion || {}; + this.options = options || {}; + + this.selected = false; + this.displayed = false; + this.dirty = true; + + this.top = null; + this.left = null; + this.width = null; + this.height = null; + } + + Item.prototype.stack = true; + + /** + * Select current item + */ + Item.prototype.select = function() { + this.selected = true; + this.dirty = true; + if (this.displayed) this.redraw(); + }; + + /** + * Unselect current item + */ + Item.prototype.unselect = function() { + this.selected = false; + this.dirty = true; + if (this.displayed) this.redraw(); + }; + + /** + * Set data for the item. Existing data will be updated. The id should not + * be changed. When the item is displayed, it will be redrawn immediately. + * @param {Object} data + */ + Item.prototype.setData = function(data) { + this.data = data; + this.dirty = true; + if (this.displayed) this.redraw(); + }; + + /** + * Set a parent for the item + * @param {ItemSet | Group} parent + */ + Item.prototype.setParent = function(parent) { + if (this.displayed) { + this.hide(); + this.parent = parent; + if (this.parent) { + this.show(); + } + } + else { + this.parent = parent; + } + }; + + /** + * Check whether this item is visible inside given range + * @returns {{start: Number, end: Number}} range with a timestamp for start and end + * @returns {boolean} True if visible + */ + Item.prototype.isVisible = function(range) { + // Should be implemented by Item implementations + return false; + }; + + /** + * Show the Item in the DOM (when not already visible) + * @return {Boolean} changed + */ + Item.prototype.show = function() { + return false; + }; + + /** + * Hide the Item from the DOM (when visible) + * @return {Boolean} changed + */ + Item.prototype.hide = function() { + return false; + }; + + /** + * Repaint the item + */ + Item.prototype.redraw = function() { + // should be implemented by the item + }; + + /** + * Reposition the Item horizontally + */ + Item.prototype.repositionX = function() { + // should be implemented by the item + }; + + /** + * Reposition the Item vertically + */ + Item.prototype.repositionY = function() { + // should be implemented by the item + }; + + /** + * Repaint a delete button on the top right of the item when the item is selected + * @param {HTMLElement} anchor + * @protected + */ + Item.prototype._repaintDeleteButton = function (anchor) { + if (this.selected && this.options.editable.remove && !this.dom.deleteButton) { + // create and show button + var me = this; + + var deleteButton = document.createElement('div'); + deleteButton.className = 'delete'; + deleteButton.title = 'Delete this item'; + + Hammer(deleteButton, { + preventDefault: true + }).on('tap', function (event) { + me.parent.removeFromDataSet(me); + event.stopPropagation(); + }); + + anchor.appendChild(deleteButton); + this.dom.deleteButton = deleteButton; } - else { - parent.appendChild(foreground) + else if (!this.selected && this.dom.deleteButton) { + // remove button + if (this.dom.deleteButton.parentNode) { + this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton); + } + this.dom.deleteButton = null; } - if (backgroundNextSibling) { - this.body.dom.backgroundVertical.insertBefore(background, backgroundNextSibling); + }; + + /** + * Set HTML contents for the item + * @param {Element} element HTML element to fill with the contents + * @private + */ + Item.prototype._updateContents = function (element) { + var content; + if (this.options.template) { + var itemData = this.parent.itemSet.itemsData.get(this.id); // get a clone of the data from the dataset + content = this.options.template(itemData); } else { - this.body.dom.backgroundVertical.appendChild(background) + content = this.data.content; } - return this._isResized() || parentChanged; + if(content !== this.content) { + // only replace the content when changed + if (content instanceof Element) { + element.innerHTML = ''; + element.appendChild(content); + } + else if (content != undefined) { + element.innerHTML = content; + } + else { + if (!(this.data.type == 'background' && this.data.content === undefined)) { + throw new Error('Property "content" missing in item ' + this.id); + } + } + + this.content = content; + } }; /** - * Repaint major and minor text labels and vertical grid lines + * Set HTML contents for the item + * @param {Element} element HTML element to fill with the contents * @private */ - TimeAxis.prototype._repaintLabels = function () { - var orientation = this.options.orientation; - - // calculate range and step (step such that we have space for 7 characters per label) - var start = util.convert(this.body.range.start, 'Number'); - var end = util.convert(this.body.range.end, 'Number'); - var timeLabelsize = this.body.util.toTime((this.props.minorCharWidth || 10) * 7).valueOf(); - var minimumStep = timeLabelsize - DateUtil.getHiddenDurationBefore(this.body.hiddenDates, this.body.range, timeLabelsize); - minimumStep -= this.body.util.toTime(0).valueOf(); - - - var step = new TimeStep(new Date(start), new Date(end), minimumStep, this.body.hiddenDates); - this.step = step; - - // Move all DOM elements to a "redundant" list, where they - // can be picked for re-use, and clear the lists with lines and texts. - // At the end of the function _repaintLabels, left over elements will be cleaned up - var dom = this.dom; - dom.redundant.majorLines = dom.majorLines; - dom.redundant.majorTexts = dom.majorTexts; - dom.redundant.minorLines = dom.minorLines; - dom.redundant.minorTexts = dom.minorTexts; - dom.majorLines = []; - dom.majorTexts = []; - dom.minorLines = []; - dom.minorTexts = []; - - step.first(); - var xFirstMajorLabel = undefined; - var max = 0; - while (step.hasNext() && max < 1000) { - max++; - var cur = step.getCurrent(); - var x = this.body.util.toScreen(cur); - var isMajor = step.isMajor(); - + Item.prototype._updateTitle = function (element) { + if (this.data.title != null) { + element.title = this.data.title || ''; + } + else { + element.removeAttribute('title'); + } + }; - // TODO: lines must have a width, such that we can create css backgrounds + /** + * Process dataAttributes timeline option and set as data- attributes on dom.content + * @param {Element} element HTML element to which the attributes will be attached + * @private + */ + Item.prototype._updateDataAttributes = function(element) { + if (this.options.dataAttributes && this.options.dataAttributes.length > 0) { + var attributes = []; - if (this.options.showMinorLabels) { - this._repaintMinorText(x, step.getLabelMinor(), orientation); + if (Array.isArray(this.options.dataAttributes)) { + attributes = this.options.dataAttributes; } - - if (isMajor && this.options.showMajorLabels) { - if (x > 0) { - if (xFirstMajorLabel == undefined) { - xFirstMajorLabel = x; - } - this._repaintMajorText(x, step.getLabelMajor(), orientation); - } - this._repaintMajorLine(x, orientation); + else if (this.options.dataAttributes == 'all') { + attributes = Object.keys(this.data); } else { - this._repaintMinorLine(x, orientation); + return; } - step.next(); - } - - // create a major label on the left when needed - if (this.options.showMajorLabels) { - var leftTime = this.body.util.toTime(0), - leftText = step.getLabelMajor(leftTime), - widthText = leftText.length * (this.props.majorCharWidth || 10) + 10; // upper bound estimation - - if (xFirstMajorLabel == undefined || widthText < xFirstMajorLabel) { - this._repaintMajorText(0, leftText, orientation); - } - } + for (var i = 0; i < attributes.length; i++) { + var name = attributes[i]; + var value = this.data[name]; - // Cleanup leftover DOM elements from the redundant list - util.forEach(this.dom.redundant, function (arr) { - while (arr.length) { - var elem = arr.pop(); - if (elem && elem.parentNode) { - elem.parentNode.removeChild(elem); + if (value != null) { + element.setAttribute('data-' + name, value); + } + else { + element.removeAttribute('data-' + name); } } - }); + } }; /** - * Create a minor label for the axis at position x - * @param {Number} x - * @param {String} text - * @param {String} orientation "top" or "bottom" (default) + * Update custom styles of the element + * @param element * @private */ - TimeAxis.prototype._repaintMinorText = function (x, text, orientation) { - // reuse redundant label - var label = this.dom.redundant.minorTexts.shift(); + Item.prototype._updateStyle = function(element) { + // remove old styles + if (this.style) { + util.removeCssText(element, this.style); + this.style = null; + } - if (!label) { - // create new label - var content = document.createTextNode(''); - label = document.createElement('div'); - label.appendChild(content); - label.className = 'text minor'; - this.dom.foreground.appendChild(label); + // append new styles + if (this.data.style) { + util.addCssText(element, this.data.style); + this.style = this.data.style; } - this.dom.minorTexts.push(label); + }; - label.childNodes[0].nodeValue = text; + module.exports = Item; - label.style.top = (orientation == 'top') ? (this.props.majorLabelHeight + 'px') : '0'; - label.style.left = x + 'px'; - //label.title = title; // TODO: this is a heavy operation - }; + +/***/ }, +/* 31 */ +/***/ function(module, exports, __webpack_require__) { + + var Hammer = __webpack_require__(44); + var Item = __webpack_require__(30); + var BackgroundGroup = __webpack_require__(25); + var RangeItem = __webpack_require__(34); /** - * Create a Major label for the axis at position x - * @param {Number} x - * @param {String} text - * @param {String} orientation "top" or "bottom" (default) - * @private + * @constructor BackgroundItem + * @extends Item + * @param {Object} data Object containing parameters start, end + * content, className. + * @param {{toScreen: function, toTime: function}} conversion + * Conversion functions from time to screen and vice versa + * @param {Object} [options] Configuration options + * // TODO: describe options */ - TimeAxis.prototype._repaintMajorText = function (x, text, orientation) { - // reuse redundant label - var label = this.dom.redundant.majorTexts.shift(); + // TODO: implement support for the BackgroundItem just having a start, then being displayed as a sort of an annotation + function BackgroundItem (data, conversion, options) { + this.props = { + content: { + width: 0 + } + }; + this.overflow = false; // if contents can overflow (css styling), this flag is set to true - if (!label) { - // create label - var content = document.createTextNode(text); - label = document.createElement('div'); - label.className = 'text major'; - label.appendChild(content); - this.dom.foreground.appendChild(label); + // validate data + if (data) { + if (data.start == undefined) { + throw new Error('Property "start" missing in item ' + data.id); + } + if (data.end == undefined) { + throw new Error('Property "end" missing in item ' + data.id); + } } - this.dom.majorTexts.push(label); - label.childNodes[0].nodeValue = text; - //label.title = title; // TODO: this is a heavy operation + Item.call(this, data, conversion, options); - label.style.top = (orientation == 'top') ? '0' : (this.props.minorLabelHeight + 'px'); - label.style.left = x + 'px'; - }; + this.emptyContent = false; + } - /** - * Create a minor line for the axis at position x - * @param {Number} x - * @param {String} orientation "top" or "bottom" (default) - * @private - */ - TimeAxis.prototype._repaintMinorLine = function (x, orientation) { - // reuse redundant line - var line = this.dom.redundant.minorLines.shift(); + BackgroundItem.prototype = new Item (null, null, null); - if (!line) { - // create vertical line - line = document.createElement('div'); - line.className = 'grid vertical minor'; - this.dom.background.appendChild(line); - } - this.dom.minorLines.push(line); + BackgroundItem.prototype.baseClassName = 'item background'; + BackgroundItem.prototype.stack = false; - var props = this.props; - if (orientation == 'top') { - line.style.top = props.majorLabelHeight + 'px'; - } - else { - line.style.top = this.body.domProps.top.height + 'px'; - } - line.style.height = props.minorLineHeight + 'px'; - line.style.left = (x - props.minorLineWidth / 2) + 'px'; + /** + * Check whether this item is visible inside given range + * @returns {{start: Number, end: Number}} range with a timestamp for start and end + * @returns {boolean} True if visible + */ + BackgroundItem.prototype.isVisible = function(range) { + // determine visibility + return (this.data.start < range.end) && (this.data.end > range.start); }; /** - * Create a Major line for the axis at position x - * @param {Number} x - * @param {String} orientation "top" or "bottom" (default) - * @private + * Repaint the item */ - TimeAxis.prototype._repaintMajorLine = function (x, orientation) { - // reuse redundant line - var line = this.dom.redundant.majorLines.shift(); + BackgroundItem.prototype.redraw = function() { + var dom = this.dom; + if (!dom) { + // create DOM + this.dom = {}; + dom = this.dom; - if (!line) { - // create vertical line - line = document.createElement('DIV'); - line.className = 'grid vertical major'; - this.dom.background.appendChild(line); + // background box + dom.box = document.createElement('div'); + // className is updated in redraw() + + // contents box + dom.content = document.createElement('div'); + dom.content.className = 'content'; + dom.box.appendChild(dom.content); + + // attach this item as attribute + dom.box['timeline-item'] = this; + + this.dirty = true; } - this.dom.majorLines.push(line); - var props = this.props; - if (orientation == 'top') { - line.style.top = '0'; + // append DOM to parent DOM + if (!this.parent) { + throw new Error('Cannot redraw item: no parent attached'); } - else { - line.style.top = this.body.domProps.top.height + 'px'; + if (!dom.box.parentNode) { + var background = this.parent.dom.background; + if (!background) { + throw new Error('Cannot redraw item: parent has no background container element'); + } + background.appendChild(dom.box); } - line.style.left = (x - props.majorLineWidth / 2) + 'px'; - line.style.height = props.majorLineHeight + 'px'; - }; + this.displayed = true; - /** - * Determine the size of text on the axis (both major and minor axis). - * The size is calculated only once and then cached in this.props. - * @private - */ - TimeAxis.prototype._calculateCharSize = function () { - // Note: We calculate char size with every redraw. Size may change, for - // example when any of the timelines parents had display:none for example. + // Update DOM when item is marked dirty. An item is marked dirty when: + // - the item is not yet rendered + // - the item's data is changed + // - the item is selected/deselected + if (this.dirty) { + this._updateContents(this.dom.content); + this._updateTitle(this.dom.content); + this._updateDataAttributes(this.dom.content); + this._updateStyle(this.dom.box); - // determine the char width and height on the minor axis - if (!this.dom.measureCharMinor) { - this.dom.measureCharMinor = document.createElement('DIV'); - this.dom.measureCharMinor.className = 'text minor measure'; - this.dom.measureCharMinor.style.position = 'absolute'; + // update class + var className = (this.data.className ? (' ' + this.data.className) : '') + + (this.selected ? ' selected' : ''); + dom.box.className = this.baseClassName + className; - this.dom.measureCharMinor.appendChild(document.createTextNode('0')); - this.dom.foreground.appendChild(this.dom.measureCharMinor); - } - this.props.minorCharHeight = this.dom.measureCharMinor.clientHeight; - this.props.minorCharWidth = this.dom.measureCharMinor.clientWidth; + // determine from css whether this box has overflow + this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden'; - // determine the char width and height on the major axis - if (!this.dom.measureCharMajor) { - this.dom.measureCharMajor = document.createElement('DIV'); - this.dom.measureCharMajor.className = 'text major measure'; - this.dom.measureCharMajor.style.position = 'absolute'; + // recalculate size + this.props.content.width = this.dom.content.offsetWidth; + this.height = 0; // set height zero, so this item will be ignored when stacking items - this.dom.measureCharMajor.appendChild(document.createTextNode('0')); - this.dom.foreground.appendChild(this.dom.measureCharMajor); + this.dirty = false; } - this.props.majorCharHeight = this.dom.measureCharMajor.clientHeight; - this.props.majorCharWidth = this.dom.measureCharMajor.clientWidth; }; /** - * Snap a date to a rounded value. - * The snap intervals are dependent on the current scale and step. - * @param {Date} date the date to be snapped. - * @return {Date} snappedDate + * Show the item in the DOM (when not already visible). The items DOM will + * be created when needed. */ - TimeAxis.prototype.snap = function(date) { - return this.step.snap(date); + BackgroundItem.prototype.show = RangeItem.prototype.show; + + /** + * Hide the item from the DOM (when visible) + * @return {Boolean} changed + */ + BackgroundItem.prototype.hide = RangeItem.prototype.hide; + + /** + * Reposition the item horizontally + * @Override + */ + BackgroundItem.prototype.repositionX = RangeItem.prototype.repositionX; + + /** + * Reposition the item vertically + * @Override + */ + BackgroundItem.prototype.repositionY = function(margin) { + var onTop = this.options.orientation === 'top'; + this.dom.content.style.top = onTop ? '' : '0'; + this.dom.content.style.bottom = onTop ? '0' : ''; + var height; + + // special positioning for subgroups + if (this.data.subgroup !== undefined) { + var itemSubgroup = this.data.subgroup; + var subgroups = this.parent.subgroups; + var subgroupIndex = subgroups[itemSubgroup].index; + // if the orientation is top, we need to take the difference in height into account. + if (onTop == true) { + // the first subgroup will have to account for the distance from the top to the first item. + height = this.parent.subgroups[itemSubgroup].height + margin.item.vertical; + height += subgroupIndex == 0 ? margin.axis - 0.5*margin.item.vertical : 0; + var newTop = this.parent.top; + for (var subgroup in subgroups) { + if (subgroups.hasOwnProperty(subgroup)) { + if (subgroups[subgroup].visible == true && subgroups[subgroup].index < subgroupIndex) { + newTop += subgroups[subgroup].height + margin.item.vertical; + } + } + } + + // the others will have to be offset downwards with this same distance. + newTop += subgroupIndex != 0 ? margin.axis - 0.5 * margin.item.vertical : 0; + this.dom.box.style.top = newTop + 'px'; + this.dom.box.style.bottom = ''; + } + // and when the orientation is bottom: + else { + var newTop = this.parent.top; + for (var subgroup in subgroups) { + if (subgroups.hasOwnProperty(subgroup)) { + if (subgroups[subgroup].visible == true && subgroups[subgroup].index > subgroupIndex) { + newTop += subgroups[subgroup].height + margin.item.vertical; + } + } + } + height = this.parent.subgroups[itemSubgroup].height + margin.item.vertical; + this.dom.box.style.top = newTop + 'px'; + this.dom.box.style.bottom = ''; + } + } + // and in the case of no subgroups: + else { + // we want backgrounds with groups to only show in groups. + if (this.parent instanceof BackgroundGroup) { + // if the item is not in a group: + height = Math.max(this.parent.height, this.parent.itemSet.body.domProps.centerContainer.height); + this.dom.box.style.top = onTop ? '0' : ''; + this.dom.box.style.bottom = onTop ? '' : '0'; + } + else { + height = this.parent.height; + // same alignment for items when orientation is top or bottom + this.dom.box.style.top = this.parent.top + 'px'; + this.dom.box.style.bottom = ''; + } + } + this.dom.box.style.height = height + 'px'; }; - module.exports = TimeAxis; + module.exports = BackgroundItem; /***/ }, -/* 26 */ +/* 32 */ /***/ function(module, exports, __webpack_require__) { - var moment = __webpack_require__(2); - var DateUtil = __webpack_require__(23); + var Item = __webpack_require__(30); + var util = __webpack_require__(1); /** - * @constructor TimeStep - * The class TimeStep is an iterator for dates. You provide a start date and an - * end date. The class itself determines the best scale (step size) based on the - * provided start Date, end Date, and minimumStep. - * - * If minimumStep is provided, the step size is chosen as close as possible - * to the minimumStep but larger than minimumStep. If minimumStep is not - * provided, the scale is set to 1 DAY. - * The minimumStep should correspond with the onscreen size of about 6 characters - * - * Alternatively, you can set a scale by hand. - * After creation, you can initialize the class by executing first(). Then you - * can iterate from the start date to the end date via next(). You can check if - * the end date is reached with the function hasNext(). After each step, you can - * retrieve the current date via getCurrent(). - * The TimeStep has scales ranging from milliseconds, seconds, minutes, hours, - * days, to years. - * - * Version: 1.2 - * - * @param {Date} [start] The start date, for example new Date(2010, 9, 21) - * or new Date(2010, 9, 21, 23, 45, 00) - * @param {Date} [end] The end date - * @param {Number} [minimumStep] Optional. Minimum step size in milliseconds + * @constructor BoxItem + * @extends Item + * @param {Object} data Object containing parameters start + * content, className. + * @param {{toScreen: function, toTime: function}} conversion + * Conversion functions from time to screen and vice versa + * @param {Object} [options] Configuration options + * // TODO: describe available options */ - function TimeStep(start, end, minimumStep, hiddenDates) { - // variables - this.current = new Date(); - this._start = new Date(); - this._end = new Date(); - - this.autoScale = true; - this.scale = TimeStep.SCALE.DAY; - this.step = 1; - - // initialize the range - this.setRange(start, end, minimumStep); + function BoxItem (data, conversion, options) { + this.props = { + dot: { + width: 0, + height: 0 + }, + line: { + width: 0, + height: 0 + } + }; - // hidden Dates options - this.switchedDay = false; - this.switchedMonth = false; - this.switchedYear = false; - this.hiddenDates = hiddenDates; - if (hiddenDates === undefined) { - this.hiddenDates = []; + // validate data + if (data) { + if (data.start == undefined) { + throw new Error('Property "start" missing in item ' + data); + } } + + Item.call(this, data, conversion, options); } - /// enum scale - TimeStep.SCALE = { - MILLISECOND: 1, - SECOND: 2, - MINUTE: 3, - HOUR: 4, - DAY: 5, - WEEKDAY: 6, - MONTH: 7, - YEAR: 8 - }; + BoxItem.prototype = new Item (null, null, null); + /** + * Check whether this item is visible inside given range + * @returns {{start: Number, end: Number}} range with a timestamp for start and end + * @returns {boolean} True if visible + */ + BoxItem.prototype.isVisible = function(range) { + // determine visibility + // TODO: account for the real width of the item. Right now we just add 1/4 to the window + var interval = (range.end - range.start) / 4; + return (this.data.start > range.start - interval) && (this.data.start < range.end + interval); + }; /** - * Set a new range - * If minimumStep is provided, the step size is chosen as close as possible - * to the minimumStep but larger than minimumStep. If minimumStep is not - * provided, the scale is set to 1 DAY. - * The minimumStep should correspond with the onscreen size of about 6 characters - * @param {Date} [start] The start date and time. - * @param {Date} [end] The end date and time. - * @param {int} [minimumStep] Optional. Minimum step size in milliseconds + * Repaint the item */ - TimeStep.prototype.setRange = function(start, end, minimumStep) { - if (!(start instanceof Date) || !(end instanceof Date)) { - throw "No legal start or end date in method setRange"; + BoxItem.prototype.redraw = function() { + var dom = this.dom; + if (!dom) { + // create DOM + this.dom = {}; + dom = this.dom; + + // create main box + dom.box = document.createElement('DIV'); + + // contents box (inside the background box). used for making margins + dom.content = document.createElement('DIV'); + dom.content.className = 'content'; + dom.box.appendChild(dom.content); + + // line to axis + dom.line = document.createElement('DIV'); + dom.line.className = 'line'; + + // dot on axis + dom.dot = document.createElement('DIV'); + dom.dot.className = 'dot'; + + // attach this item as attribute + dom.box['timeline-item'] = this; + + this.dirty = true; } - this._start = (start != undefined) ? new Date(start.valueOf()) : new Date(); - this._end = (end != undefined) ? new Date(end.valueOf()) : new Date(); + // append DOM to parent DOM + if (!this.parent) { + throw new Error('Cannot redraw item: no parent attached'); + } + if (!dom.box.parentNode) { + var foreground = this.parent.dom.foreground; + if (!foreground) throw new Error('Cannot redraw item: parent has no foreground container element'); + foreground.appendChild(dom.box); + } + if (!dom.line.parentNode) { + var background = this.parent.dom.background; + if (!background) throw new Error('Cannot redraw item: parent has no background container element'); + background.appendChild(dom.line); + } + if (!dom.dot.parentNode) { + var axis = this.parent.dom.axis; + if (!background) throw new Error('Cannot redraw item: parent has no axis container element'); + axis.appendChild(dom.dot); + } + this.displayed = true; - if (this.autoScale) { - this.setMinimumStep(minimumStep); + // Update DOM when item is marked dirty. An item is marked dirty when: + // - the item is not yet rendered + // - the item's data is changed + // - the item is selected/deselected + if (this.dirty) { + this._updateContents(this.dom.content); + this._updateTitle(this.dom.box); + this._updateDataAttributes(this.dom.box); + this._updateStyle(this.dom.box); + + // update class + var className = (this.data.className? ' ' + this.data.className : '') + + (this.selected ? ' selected' : ''); + dom.box.className = 'item box' + className; + dom.line.className = 'item line' + className; + dom.dot.className = 'item dot' + className; + + // recalculate size + this.props.dot.height = dom.dot.offsetHeight; + this.props.dot.width = dom.dot.offsetWidth; + this.props.line.width = dom.line.offsetWidth; + this.width = dom.box.offsetWidth; + this.height = dom.box.offsetHeight; + + this.dirty = false; } + + this._repaintDeleteButton(dom.box); }; /** - * Set the range iterator to the start date. + * Show the item in the DOM (when not already displayed). The items DOM will + * be created when needed. */ - TimeStep.prototype.first = function() { - this.current = new Date(this._start.valueOf()); - this.roundToMinor(); + BoxItem.prototype.show = function() { + if (!this.displayed) { + this.redraw(); + } }; /** - * Round the current date to the first minor date value - * This must be executed once when the current date is set to start Date + * Hide the item from the DOM (when visible) */ - TimeStep.prototype.roundToMinor = function() { - // round to floor - // IMPORTANT: we have no breaks in this switch! (this is no bug) - //noinspection FallthroughInSwitchStatementJS - switch (this.scale) { - case TimeStep.SCALE.YEAR: - this.current.setFullYear(this.step * Math.floor(this.current.getFullYear() / this.step)); - this.current.setMonth(0); - case TimeStep.SCALE.MONTH: this.current.setDate(1); - case TimeStep.SCALE.DAY: // intentional fall through - case TimeStep.SCALE.WEEKDAY: this.current.setHours(0); - case TimeStep.SCALE.HOUR: this.current.setMinutes(0); - case TimeStep.SCALE.MINUTE: this.current.setSeconds(0); - case TimeStep.SCALE.SECOND: this.current.setMilliseconds(0); - //case TimeStep.SCALE.MILLISECOND: // nothing to do for milliseconds - } + BoxItem.prototype.hide = function() { + if (this.displayed) { + var dom = this.dom; - if (this.step != 1) { - // round down to the first minor value that is a multiple of the current step size - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND: this.current.setMilliseconds(this.current.getMilliseconds() - this.current.getMilliseconds() % this.step); break; - case TimeStep.SCALE.SECOND: this.current.setSeconds(this.current.getSeconds() - this.current.getSeconds() % this.step); break; - case TimeStep.SCALE.MINUTE: this.current.setMinutes(this.current.getMinutes() - this.current.getMinutes() % this.step); break; - case TimeStep.SCALE.HOUR: this.current.setHours(this.current.getHours() - this.current.getHours() % this.step); break; - case TimeStep.SCALE.WEEKDAY: // intentional fall through - case TimeStep.SCALE.DAY: this.current.setDate((this.current.getDate()-1) - (this.current.getDate()-1) % this.step + 1); break; - case TimeStep.SCALE.MONTH: this.current.setMonth(this.current.getMonth() - this.current.getMonth() % this.step); break; - case TimeStep.SCALE.YEAR: this.current.setFullYear(this.current.getFullYear() - this.current.getFullYear() % this.step); break; - default: break; - } + if (dom.box.parentNode) dom.box.parentNode.removeChild(dom.box); + if (dom.line.parentNode) dom.line.parentNode.removeChild(dom.line); + if (dom.dot.parentNode) dom.dot.parentNode.removeChild(dom.dot); + + this.top = null; + this.left = null; + + this.displayed = false; } }; /** - * Check if the there is a next step - * @return {boolean} true if the current date has not passed the end date + * Reposition the item horizontally + * @Override */ - TimeStep.prototype.hasNext = function () { - return (this.current.valueOf() <= this._end.valueOf()); + BoxItem.prototype.repositionX = function() { + var start = this.conversion.toScreen(this.data.start); + var align = this.options.align; + var left; + var box = this.dom.box; + var line = this.dom.line; + var dot = this.dom.dot; + + // calculate left position of the box + if (align == 'right') { + this.left = start - this.width; + } + else if (align == 'left') { + this.left = start; + } + else { + // default or 'center' + this.left = start - this.width / 2; + } + + // reposition box + box.style.left = this.left + 'px'; + + // reposition line + line.style.left = (start - this.props.line.width / 2) + 'px'; + + // reposition dot + dot.style.left = (start - this.props.dot.width / 2) + 'px'; }; /** - * Do the next step + * Reposition the item vertically + * @Override */ - TimeStep.prototype.next = function() { - var prev = this.current.valueOf(); - - // Two cases, needed to prevent issues with switching daylight savings - // (end of March and end of October) - if (this.current.getMonth() < 6) { - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND: + BoxItem.prototype.repositionY = function() { + var orientation = this.options.orientation; + var box = this.dom.box; + var line = this.dom.line; + var dot = this.dom.dot; - this.current = new Date(this.current.valueOf() + this.step); break; - case TimeStep.SCALE.SECOND: this.current = new Date(this.current.valueOf() + this.step * 1000); break; - case TimeStep.SCALE.MINUTE: this.current = new Date(this.current.valueOf() + this.step * 1000 * 60); break; - case TimeStep.SCALE.HOUR: - this.current = new Date(this.current.valueOf() + this.step * 1000 * 60 * 60); - // in case of skipping an hour for daylight savings, adjust the hour again (else you get: 0h 5h 9h ... instead of 0h 4h 8h ...) - var h = this.current.getHours(); - this.current.setHours(h - (h % this.step)); - break; - case TimeStep.SCALE.WEEKDAY: // intentional fall through - case TimeStep.SCALE.DAY: this.current.setDate(this.current.getDate() + this.step); break; - case TimeStep.SCALE.MONTH: this.current.setMonth(this.current.getMonth() + this.step); break; - case TimeStep.SCALE.YEAR: this.current.setFullYear(this.current.getFullYear() + this.step); break; - default: break; - } - } - else { - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND: this.current = new Date(this.current.valueOf() + this.step); break; - case TimeStep.SCALE.SECOND: this.current.setSeconds(this.current.getSeconds() + this.step); break; - case TimeStep.SCALE.MINUTE: this.current.setMinutes(this.current.getMinutes() + this.step); break; - case TimeStep.SCALE.HOUR: this.current.setHours(this.current.getHours() + this.step); break; - case TimeStep.SCALE.WEEKDAY: // intentional fall through - case TimeStep.SCALE.DAY: this.current.setDate(this.current.getDate() + this.step); break; - case TimeStep.SCALE.MONTH: this.current.setMonth(this.current.getMonth() + this.step); break; - case TimeStep.SCALE.YEAR: this.current.setFullYear(this.current.getFullYear() + this.step); break; - default: break; - } - } + if (orientation == 'top') { + box.style.top = (this.top || 0) + 'px'; - if (this.step != 1) { - // round down to the correct major value - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND: if(this.current.getMilliseconds() < this.step) this.current.setMilliseconds(0); break; - case TimeStep.SCALE.SECOND: if(this.current.getSeconds() < this.step) this.current.setSeconds(0); break; - case TimeStep.SCALE.MINUTE: if(this.current.getMinutes() < this.step) this.current.setMinutes(0); break; - case TimeStep.SCALE.HOUR: if(this.current.getHours() < this.step) this.current.setHours(0); break; - case TimeStep.SCALE.WEEKDAY: // intentional fall through - case TimeStep.SCALE.DAY: if(this.current.getDate() < this.step+1) this.current.setDate(1); break; - case TimeStep.SCALE.MONTH: if(this.current.getMonth() < this.step) this.current.setMonth(0); break; - case TimeStep.SCALE.YEAR: break; // nothing to do for year - default: break; - } + line.style.top = '0'; + line.style.height = (this.parent.top + this.top + 1) + 'px'; + line.style.bottom = ''; } + else { // orientation 'bottom' + var itemSetHeight = this.parent.itemSet.props.height; // TODO: this is nasty + var lineHeight = itemSetHeight - this.parent.top - this.parent.height + this.top; - // safety mechanism: if current time is still unchanged, move to the end - if (this.current.valueOf() == prev) { - this.current = new Date(this._end.valueOf()); + box.style.top = (this.parent.height - this.top - this.height || 0) + 'px'; + line.style.top = (itemSetHeight - lineHeight) + 'px'; + line.style.bottom = '0'; } - DateUtil.stepOverHiddenDates(this, prev); + dot.style.top = (-this.props.dot.height / 2) + 'px'; }; + module.exports = BoxItem; + - /** - * Get the current datetime - * @return {Date} current The current date - */ - TimeStep.prototype.getCurrent = function() { - return this.current; - }; +/***/ }, +/* 33 */ +/***/ function(module, exports, __webpack_require__) { + + var Item = __webpack_require__(30); /** - * Set a custom scale. Autoscaling will be disabled. - * For example setScale(SCALE.MINUTES, 5) will result - * in minor steps of 5 minutes, and major steps of an hour. - * - * @param {TimeStep.SCALE} newScale - * A scale. Choose from SCALE.MILLISECOND, - * SCALE.SECOND, SCALE.MINUTE, SCALE.HOUR, - * SCALE.WEEKDAY, SCALE.DAY, SCALE.MONTH, - * SCALE.YEAR. - * @param {Number} newStep A step size, by default 1. Choose for - * example 1, 2, 5, or 10. + * @constructor PointItem + * @extends Item + * @param {Object} data Object containing parameters start + * content, className. + * @param {{toScreen: function, toTime: function}} conversion + * Conversion functions from time to screen and vice versa + * @param {Object} [options] Configuration options + * // TODO: describe available options */ - TimeStep.prototype.setScale = function(newScale, newStep) { - this.scale = newScale; + function PointItem (data, conversion, options) { + this.props = { + dot: { + top: 0, + width: 0, + height: 0 + }, + content: { + height: 0, + marginLeft: 0 + } + }; - if (newStep > 0) { - this.step = newStep; + // validate data + if (data) { + if (data.start == undefined) { + throw new Error('Property "start" missing in item ' + data); + } } - this.autoScale = false; - }; + Item.call(this, data, conversion, options); + } + + PointItem.prototype = new Item (null, null, null); /** - * Enable or disable autoscaling - * @param {boolean} enable If true, autoascaling is set true + * Check whether this item is visible inside given range + * @returns {{start: Number, end: Number}} range with a timestamp for start and end + * @returns {boolean} True if visible */ - TimeStep.prototype.setAutoScale = function (enable) { - this.autoScale = enable; + PointItem.prototype.isVisible = function(range) { + // determine visibility + // TODO: account for the real width of the item. Right now we just add 1/4 to the window + var interval = (range.end - range.start) / 4; + return (this.data.start > range.start - interval) && (this.data.start < range.end + interval); }; - /** - * Automatically determine the scale that bests fits the provided minimum step - * @param {Number} [minimumStep] The minimum step size in milliseconds + * Repaint the item */ - TimeStep.prototype.setMinimumStep = function(minimumStep) { - if (minimumStep == undefined) { - return; - } + PointItem.prototype.redraw = function() { + var dom = this.dom; + if (!dom) { + // create DOM + this.dom = {}; + dom = this.dom; - //var b = asc + ds; + // background box + dom.point = document.createElement('div'); + // className is updated in redraw() - var stepYear = (1000 * 60 * 60 * 24 * 30 * 12); - var stepMonth = (1000 * 60 * 60 * 24 * 30); - var stepDay = (1000 * 60 * 60 * 24); - var stepHour = (1000 * 60 * 60); - var stepMinute = (1000 * 60); - var stepSecond = (1000); - var stepMillisecond= (1); + // contents box, right from the dot + dom.content = document.createElement('div'); + dom.content.className = 'content'; + dom.point.appendChild(dom.content); - // find the smallest step that is larger than the provided minimumStep - if (stepYear*1000 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 1000;} - if (stepYear*500 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 500;} - if (stepYear*100 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 100;} - if (stepYear*50 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 50;} - if (stepYear*10 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 10;} - if (stepYear*5 > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 5;} - if (stepYear > minimumStep) {this.scale = TimeStep.SCALE.YEAR; this.step = 1;} - if (stepMonth*3 > minimumStep) {this.scale = TimeStep.SCALE.MONTH; this.step = 3;} - if (stepMonth > minimumStep) {this.scale = TimeStep.SCALE.MONTH; this.step = 1;} - if (stepDay*5 > minimumStep) {this.scale = TimeStep.SCALE.DAY; this.step = 5;} - if (stepDay*2 > minimumStep) {this.scale = TimeStep.SCALE.DAY; this.step = 2;} - if (stepDay > minimumStep) {this.scale = TimeStep.SCALE.DAY; this.step = 1;} - if (stepDay/2 > minimumStep) {this.scale = TimeStep.SCALE.WEEKDAY; this.step = 1;} - if (stepHour*4 > minimumStep) {this.scale = TimeStep.SCALE.HOUR; this.step = 4;} - if (stepHour > minimumStep) {this.scale = TimeStep.SCALE.HOUR; this.step = 1;} - if (stepMinute*15 > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 15;} - if (stepMinute*10 > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 10;} - if (stepMinute*5 > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 5;} - if (stepMinute > minimumStep) {this.scale = TimeStep.SCALE.MINUTE; this.step = 1;} - if (stepSecond*15 > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 15;} - if (stepSecond*10 > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 10;} - if (stepSecond*5 > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 5;} - if (stepSecond > minimumStep) {this.scale = TimeStep.SCALE.SECOND; this.step = 1;} - if (stepMillisecond*200 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 200;} - if (stepMillisecond*100 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 100;} - if (stepMillisecond*50 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 50;} - if (stepMillisecond*10 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 10;} - if (stepMillisecond*5 > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 5;} - if (stepMillisecond > minimumStep) {this.scale = TimeStep.SCALE.MILLISECOND; this.step = 1;} - }; + // dot at start + dom.dot = document.createElement('div'); + dom.point.appendChild(dom.dot); - /** - * Snap a date to a rounded value. - * The snap intervals are dependent on the current scale and step. - * @param {Date} date the date to be snapped. - * @return {Date} snappedDate - */ - TimeStep.prototype.snap = function(date) { - var clone = new Date(date.valueOf()); + // attach this item as attribute + dom.point['timeline-item'] = this; - if (this.scale == TimeStep.SCALE.YEAR) { - var year = clone.getFullYear() + Math.round(clone.getMonth() / 12); - clone.setFullYear(Math.round(year / this.step) * this.step); - clone.setMonth(0); - clone.setDate(0); - clone.setHours(0); - clone.setMinutes(0); - clone.setSeconds(0); - clone.setMilliseconds(0); + this.dirty = true; } - else if (this.scale == TimeStep.SCALE.MONTH) { - if (clone.getDate() > 15) { - clone.setDate(1); - clone.setMonth(clone.getMonth() + 1); - // important: first set Date to 1, after that change the month. - } - else { - clone.setDate(1); - } - clone.setHours(0); - clone.setMinutes(0); - clone.setSeconds(0); - clone.setMilliseconds(0); - } - else if (this.scale == TimeStep.SCALE.DAY) { - //noinspection FallthroughInSwitchStatementJS - switch (this.step) { - case 5: - case 2: - clone.setHours(Math.round(clone.getHours() / 24) * 24); break; - default: - clone.setHours(Math.round(clone.getHours() / 12) * 12); break; - } - clone.setMinutes(0); - clone.setSeconds(0); - clone.setMilliseconds(0); - } - else if (this.scale == TimeStep.SCALE.WEEKDAY) { - //noinspection FallthroughInSwitchStatementJS - switch (this.step) { - case 5: - case 2: - clone.setHours(Math.round(clone.getHours() / 12) * 12); break; - default: - clone.setHours(Math.round(clone.getHours() / 6) * 6); break; - } - clone.setMinutes(0); - clone.setSeconds(0); - clone.setMilliseconds(0); - } - else if (this.scale == TimeStep.SCALE.HOUR) { - switch (this.step) { - case 4: - clone.setMinutes(Math.round(clone.getMinutes() / 60) * 60); break; - default: - clone.setMinutes(Math.round(clone.getMinutes() / 30) * 30); break; - } - clone.setSeconds(0); - clone.setMilliseconds(0); - } else if (this.scale == TimeStep.SCALE.MINUTE) { - //noinspection FallthroughInSwitchStatementJS - switch (this.step) { - case 15: - case 10: - clone.setMinutes(Math.round(clone.getMinutes() / 5) * 5); - clone.setSeconds(0); - break; - case 5: - clone.setSeconds(Math.round(clone.getSeconds() / 60) * 60); break; - default: - clone.setSeconds(Math.round(clone.getSeconds() / 30) * 30); break; - } - clone.setMilliseconds(0); + // append DOM to parent DOM + if (!this.parent) { + throw new Error('Cannot redraw item: no parent attached'); } - else if (this.scale == TimeStep.SCALE.SECOND) { - //noinspection FallthroughInSwitchStatementJS - switch (this.step) { - case 15: - case 10: - clone.setSeconds(Math.round(clone.getSeconds() / 5) * 5); - clone.setMilliseconds(0); - break; - case 5: - clone.setMilliseconds(Math.round(clone.getMilliseconds() / 1000) * 1000); break; - default: - clone.setMilliseconds(Math.round(clone.getMilliseconds() / 500) * 500); break; + if (!dom.point.parentNode) { + var foreground = this.parent.dom.foreground; + if (!foreground) { + throw new Error('Cannot redraw item: parent has no foreground container element'); } + foreground.appendChild(dom.point); } - else if (this.scale == TimeStep.SCALE.MILLISECOND) { - var step = this.step > 5 ? this.step / 2 : 1; - clone.setMilliseconds(Math.round(clone.getMilliseconds() / step) * step); + this.displayed = true; + + // Update DOM when item is marked dirty. An item is marked dirty when: + // - the item is not yet rendered + // - the item's data is changed + // - the item is selected/deselected + if (this.dirty) { + this._updateContents(this.dom.content); + this._updateTitle(this.dom.point); + this._updateDataAttributes(this.dom.point); + this._updateStyle(this.dom.point); + + // update class + var className = (this.data.className? ' ' + this.data.className : '') + + (this.selected ? ' selected' : ''); + dom.point.className = 'item point' + className; + dom.dot.className = 'item dot' + className; + + // recalculate size + this.width = dom.point.offsetWidth; + this.height = dom.point.offsetHeight; + this.props.dot.width = dom.dot.offsetWidth; + this.props.dot.height = dom.dot.offsetHeight; + this.props.content.height = dom.content.offsetHeight; + + // resize contents + dom.content.style.marginLeft = 2 * this.props.dot.width + 'px'; + //dom.content.style.marginRight = ... + 'px'; // TODO: margin right + + dom.dot.style.top = ((this.height - this.props.dot.height) / 2) + 'px'; + dom.dot.style.left = (this.props.dot.width / 2) + 'px'; + + this.dirty = false; } - - return clone; + + this._repaintDeleteButton(dom.point); }; /** - * Check if the current value is a major value (for example when the step - * is DAY, a major value is each first day of the MONTH) - * @return {boolean} true if current date is major, else false. + * Show the item in the DOM (when not already visible). The items DOM will + * be created when needed. */ - TimeStep.prototype.isMajor = function() { - if (this.switchedYear == true) { - this.switchedYear = false; - switch (this.scale) { - case TimeStep.SCALE.YEAR: - case TimeStep.SCALE.MONTH: - case TimeStep.SCALE.WEEKDAY: - case TimeStep.SCALE.DAY: - case TimeStep.SCALE.HOUR: - case TimeStep.SCALE.MINUTE: - case TimeStep.SCALE.SECOND: - case TimeStep.SCALE.MILLISECOND: - return true; - default: - return false; - } - } - else if (this.switchedMonth == true) { - this.switchedMonth = false; - switch (this.scale) { - case TimeStep.SCALE.WEEKDAY: - case TimeStep.SCALE.DAY: - case TimeStep.SCALE.HOUR: - case TimeStep.SCALE.MINUTE: - case TimeStep.SCALE.SECOND: - case TimeStep.SCALE.MILLISECOND: - return true; - default: - return false; - } + PointItem.prototype.show = function() { + if (!this.displayed) { + this.redraw(); } - else if (this.switchedDay == true) { - this.switchedDay = false; - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND: - case TimeStep.SCALE.SECOND: - case TimeStep.SCALE.MINUTE: - case TimeStep.SCALE.HOUR: - return true; - default: - return false; + }; + + /** + * Hide the item from the DOM (when visible) + */ + PointItem.prototype.hide = function() { + if (this.displayed) { + if (this.dom.point.parentNode) { + this.dom.point.parentNode.removeChild(this.dom.point); } - } - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND: - return (this.current.getMilliseconds() == 0); - case TimeStep.SCALE.SECOND: - return (this.current.getSeconds() == 0); - case TimeStep.SCALE.MINUTE: - return (this.current.getHours() == 0) && (this.current.getMinutes() == 0); - case TimeStep.SCALE.HOUR: - return (this.current.getHours() == 0); - case TimeStep.SCALE.WEEKDAY: // intentional fall through - case TimeStep.SCALE.DAY: - return (this.current.getDate() == 1); - case TimeStep.SCALE.MONTH: - return (this.current.getMonth() == 0); - case TimeStep.SCALE.YEAR: - return false; - default: - return false; + this.top = null; + this.left = null; + + this.displayed = false; } }; - /** - * Returns formatted text for the minor axislabel, depending on the current - * date and the scale. For example when scale is MINUTE, the current time is - * formatted as "hh:mm". - * @param {Date} [date] custom date. if not provided, current date is taken + * Reposition the item horizontally + * @Override */ - TimeStep.prototype.getLabelMinor = function(date) { - if (date == undefined) { - date = this.current; - } + PointItem.prototype.repositionX = function() { + var start = this.conversion.toScreen(this.data.start); - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND: return moment(date).format('SSS'); - case TimeStep.SCALE.SECOND: return moment(date).format('s'); - case TimeStep.SCALE.MINUTE: return moment(date).format('HH:mm'); - case TimeStep.SCALE.HOUR: return moment(date).format('HH:mm'); - case TimeStep.SCALE.WEEKDAY: return moment(date).format('ddd D'); - case TimeStep.SCALE.DAY: return moment(date).format('D'); - case TimeStep.SCALE.MONTH: return moment(date).format('MMM'); - case TimeStep.SCALE.YEAR: return moment(date).format('YYYY'); - default: return ''; - } - }; + this.left = start - this.props.dot.width; + // reposition point + this.dom.point.style.left = this.left + 'px'; + }; /** - * Returns formatted text for the major axis label, depending on the current - * date and the scale. For example when scale is MINUTE, the major scale is - * hours, and the hour will be formatted as "hh". - * @param {Date} [date] custom date. if not provided, current date is taken + * Reposition the item vertically + * @Override */ - TimeStep.prototype.getLabelMajor = function(date) { - if (date == undefined) { - date = this.current; - } + PointItem.prototype.repositionY = function() { + var orientation = this.options.orientation, + point = this.dom.point; - //noinspection FallthroughInSwitchStatementJS - switch (this.scale) { - case TimeStep.SCALE.MILLISECOND:return moment(date).format('HH:mm:ss'); - case TimeStep.SCALE.SECOND: return moment(date).format('D MMMM HH:mm'); - case TimeStep.SCALE.MINUTE: - case TimeStep.SCALE.HOUR: return moment(date).format('ddd D MMMM'); - case TimeStep.SCALE.WEEKDAY: - case TimeStep.SCALE.DAY: return moment(date).format('MMMM YYYY'); - case TimeStep.SCALE.MONTH: return moment(date).format('YYYY'); - case TimeStep.SCALE.YEAR: return ''; - default: return ''; + if (orientation == 'top') { + point.style.top = this.top + 'px'; + } + else { + point.style.top = (this.parent.height - this.top - this.height) + 'px'; } }; - module.exports = TimeStep; + module.exports = PointItem; /***/ }, -/* 27 */ +/* 34 */ /***/ function(module, exports, __webpack_require__) { - var util = __webpack_require__(1); - var Component = __webpack_require__(22); - var moment = __webpack_require__(2); - var locales = __webpack_require__(28); + var Hammer = __webpack_require__(44); + var Item = __webpack_require__(30); /** - * A current time bar - * @param {{range: Range, dom: Object, domProps: Object}} body - * @param {Object} [options] Available parameters: - * {Boolean} [showCurrentTime] - * @constructor CurrentTime - * @extends Component + * @constructor RangeItem + * @extends Item + * @param {Object} data Object containing parameters start, end + * content, className. + * @param {{toScreen: function, toTime: function}} conversion + * Conversion functions from time to screen and vice versa + * @param {Object} [options] Configuration options + * // TODO: describe options */ - function CurrentTime (body, options) { - this.body = body; - - // default options - this.defaultOptions = { - showCurrentTime: true, - - locales: locales, - locale: 'en' + function RangeItem (data, conversion, options) { + this.props = { + content: { + width: 0 + } }; - this.options = util.extend({}, this.defaultOptions); - this.offset = 0; + this.overflow = false; // if contents can overflow (css styling), this flag is set to true - this._create(); + // validate data + if (data) { + if (data.start == undefined) { + throw new Error('Property "start" missing in item ' + data.id); + } + if (data.end == undefined) { + throw new Error('Property "end" missing in item ' + data.id); + } + } - this.setOptions(options); + Item.call(this, data, conversion, options); } - CurrentTime.prototype = new Component(); + RangeItem.prototype = new Item (null, null, null); + + RangeItem.prototype.baseClassName = 'item range'; /** - * Create the HTML DOM for the current time bar - * @private + * Check whether this item is visible inside given range + * @returns {{start: Number, end: Number}} range with a timestamp for start and end + * @returns {boolean} True if visible */ - CurrentTime.prototype._create = function() { - var bar = document.createElement('div'); - bar.className = 'currenttime'; - bar.style.position = 'absolute'; - bar.style.top = '0px'; - bar.style.height = '100%'; - - this.bar = bar; + RangeItem.prototype.isVisible = function(range) { + // determine visibility + return (this.data.start < range.end) && (this.data.end > range.start); }; /** - * Destroy the CurrentTime bar + * Repaint the item */ - CurrentTime.prototype.destroy = function () { - this.options.showCurrentTime = false; - this.redraw(); // will remove the bar from the DOM and stop refreshing + RangeItem.prototype.redraw = function() { + var dom = this.dom; + if (!dom) { + // create DOM + this.dom = {}; + dom = this.dom; - this.body = null; + // background box + dom.box = document.createElement('div'); + // className is updated in redraw() + + // contents box + dom.content = document.createElement('div'); + dom.content.className = 'content'; + dom.box.appendChild(dom.content); + + // attach this item as attribute + dom.box['timeline-item'] = this; + + this.dirty = true; + } + + // append DOM to parent DOM + if (!this.parent) { + throw new Error('Cannot redraw item: no parent attached'); + } + if (!dom.box.parentNode) { + var foreground = this.parent.dom.foreground; + if (!foreground) { + throw new Error('Cannot redraw item: parent has no foreground container element'); + } + foreground.appendChild(dom.box); + } + this.displayed = true; + + // Update DOM when item is marked dirty. An item is marked dirty when: + // - the item is not yet rendered + // - the item's data is changed + // - the item is selected/deselected + if (this.dirty) { + this._updateContents(this.dom.content); + this._updateTitle(this.dom.box); + this._updateDataAttributes(this.dom.box); + this._updateStyle(this.dom.box); + + // update class + var className = (this.data.className ? (' ' + this.data.className) : '') + + (this.selected ? ' selected' : ''); + dom.box.className = this.baseClassName + className; + + // determine from css whether this box has overflow + this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden'; + + // recalculate size + this.props.content.width = this.dom.content.offsetWidth; + this.height = this.dom.box.offsetHeight; + + this.dirty = false; + } + + this._repaintDeleteButton(dom.box); + this._repaintDragLeft(); + this._repaintDragRight(); }; /** - * Set options for the component. Options will be merged in current options. - * @param {Object} options Available parameters: - * {boolean} [showCurrentTime] + * Show the item in the DOM (when not already visible). The items DOM will + * be created when needed. */ - CurrentTime.prototype.setOptions = function(options) { - if (options) { - // copy all options that we know - util.selectiveExtend(['showCurrentTime', 'locale', 'locales'], this.options, options); + RangeItem.prototype.show = function() { + if (!this.displayed) { + this.redraw(); } }; /** - * Repaint the component - * @return {boolean} Returns true if the component is resized + * Hide the item from the DOM (when visible) + * @return {Boolean} changed */ - CurrentTime.prototype.redraw = function() { - if (this.options.showCurrentTime) { - var parent = this.body.dom.backgroundVertical; - if (this.bar.parentNode != parent) { - // attach to the dom - if (this.bar.parentNode) { - this.bar.parentNode.removeChild(this.bar); - } - parent.appendChild(this.bar); + RangeItem.prototype.hide = function() { + if (this.displayed) { + var box = this.dom.box; - this.start(); + if (box.parentNode) { + box.parentNode.removeChild(box); } - var now = new Date(new Date().valueOf() + this.offset); - var x = this.body.util.toScreen(now); - - var locale = this.options.locales[this.options.locale]; - var title = locale.current + ' ' + locale.time + ': ' + moment(now).format('dddd, MMMM Do YYYY, H:mm:ss'); - title = title.charAt(0).toUpperCase() + title.substring(1); + this.top = null; + this.left = null; - this.bar.style.left = x + 'px'; - this.bar.title = title; - } - else { - // remove the line from the DOM - if (this.bar.parentNode) { - this.bar.parentNode.removeChild(this.bar); - } - this.stop(); + this.displayed = false; } - - return false; }; /** - * Start auto refreshing the current time bar + * Reposition the item horizontally + * @Override */ - CurrentTime.prototype.start = function() { - var me = this; - - function update () { - me.stop(); + RangeItem.prototype.repositionX = function() { + var parentWidth = this.parent.width; + var start = this.conversion.toScreen(this.data.start); + var end = this.conversion.toScreen(this.data.end); + var contentLeft; + var contentWidth; - // determine interval to refresh - var scale = me.body.range.conversion(me.body.domProps.center.width).scale; - var interval = 1 / scale / 10; - if (interval < 30) interval = 30; - if (interval > 1000) interval = 1000; + // limit the width of the this, as browsers cannot draw very wide divs + if (start < -parentWidth) { + start = -parentWidth; + } + if (end > 2 * parentWidth) { + end = 2 * parentWidth; + } + var boxWidth = Math.max(end - start, 1); - me.redraw(); + if (this.overflow) { + this.left = start; + this.width = boxWidth + this.props.content.width; + contentWidth = this.props.content.width; - // start a timer to adjust for the new time - me.currentTimeTimer = setTimeout(update, interval); + // Note: The calculation of width is an optimistic calculation, giving + // a width which will not change when moving the Timeline + // So no re-stacking needed, which is nicer for the eye; + } + else { + this.left = start; + this.width = boxWidth; + contentWidth = Math.min(end - start, this.props.content.width); } - update(); + this.dom.box.style.left = this.left + 'px'; + this.dom.box.style.width = boxWidth + 'px'; + + switch (this.options.align) { + case 'left': + this.dom.content.style.left = '0'; + break; + + case 'right': + this.dom.content.style.left = Math.max((boxWidth - contentWidth - 2 * this.options.padding), 0) + 'px'; + break; + + case 'center': + this.dom.content.style.left = Math.max((boxWidth - contentWidth - 2 * this.options.padding) / 2, 0) + 'px'; + break; + + default: // 'auto' + if (this.overflow) { + // when range exceeds left of the window, position the contents at the left of the visible area + contentLeft = Math.max(-start, 0); + } + else { + // when range exceeds left of the window, position the contents at the left of the visible area + if (start < 0) { + contentLeft = Math.min(-start, + (end - start - this.props.content.width - 2 * this.options.padding)); + // TODO: remove the need for options.padding. it's terrible. + } + else { + contentLeft = 0; + } + } + this.dom.content.style.left = contentLeft + 'px'; + } }; /** - * Stop auto refreshing the current time bar + * Reposition the item vertically + * @Override */ - CurrentTime.prototype.stop = function() { - if (this.currentTimeTimer !== undefined) { - clearTimeout(this.currentTimeTimer); - delete this.currentTimeTimer; + RangeItem.prototype.repositionY = function() { + var orientation = this.options.orientation, + box = this.dom.box; + + if (orientation == 'top') { + box.style.top = this.top + 'px'; + } + else { + box.style.top = (this.parent.height - this.top - this.height) + 'px'; } }; /** - * Set a current time. This can be used for example to ensure that a client's - * time is synchronized with a shared server time. - * @param {Date | String | Number} time A Date, unix timestamp, or - * ISO date string. + * Repaint a drag area on the left side of the range when the range is selected + * @protected */ - CurrentTime.prototype.setCurrentTime = function(time) { - var t = util.convert(time, 'Date').valueOf(); - var now = new Date().valueOf(); - this.offset = t - now; - this.redraw(); + RangeItem.prototype._repaintDragLeft = function () { + if (this.selected && this.options.editable.updateTime && !this.dom.dragLeft) { + // create and show drag area + var dragLeft = document.createElement('div'); + dragLeft.className = 'drag-left'; + dragLeft.dragLeftItem = this; + + // TODO: this should be redundant? + Hammer(dragLeft, { + preventDefault: true + }).on('drag', function () { + //console.log('drag left') + }); + + this.dom.box.appendChild(dragLeft); + this.dom.dragLeft = dragLeft; + } + else if (!this.selected && this.dom.dragLeft) { + // delete drag area + if (this.dom.dragLeft.parentNode) { + this.dom.dragLeft.parentNode.removeChild(this.dom.dragLeft); + } + this.dom.dragLeft = null; + } }; /** - * Get the current time. - * @return {Date} Returns the current time. + * Repaint a drag area on the right side of the range when the range is selected + * @protected */ - CurrentTime.prototype.getCurrentTime = function() { - return new Date(new Date().valueOf() + this.offset); - }; - - module.exports = CurrentTime; - + RangeItem.prototype._repaintDragRight = function () { + if (this.selected && this.options.editable.updateTime && !this.dom.dragRight) { + // create and show drag area + var dragRight = document.createElement('div'); + dragRight.className = 'drag-right'; + dragRight.dragRightItem = this; -/***/ }, -/* 28 */ -/***/ function(module, exports, __webpack_require__) { + // TODO: this should be redundant? + Hammer(dragRight, { + preventDefault: true + }).on('drag', function () { + //console.log('drag right') + }); - // English - exports['en'] = { - current: 'current', - time: 'time' + this.dom.box.appendChild(dragRight); + this.dom.dragRight = dragRight; + } + else if (!this.selected && this.dom.dragRight) { + // delete drag area + if (this.dom.dragRight.parentNode) { + this.dom.dragRight.parentNode.removeChild(this.dom.dragRight); + } + this.dom.dragRight = null; + } }; - exports['en_EN'] = exports['en']; - exports['en_US'] = exports['en']; - // Dutch - exports['nl'] = { - custom: 'aangepaste', - time: 'tijd' - }; - exports['nl_NL'] = exports['nl']; - exports['nl_BE'] = exports['nl']; + module.exports = RangeItem; /***/ }, -/* 29 */ +/* 35 */ /***/ function(module, exports, __webpack_require__) { - var Hammer = __webpack_require__(18); + var Emitter = __webpack_require__(52); + var Hammer = __webpack_require__(44); + var mousetrap = __webpack_require__(55); var util = __webpack_require__(1); - var Component = __webpack_require__(22); - var moment = __webpack_require__(2); - var locales = __webpack_require__(28); + var hammerUtil = __webpack_require__(46); + var DataSet = __webpack_require__(3); + var DataView = __webpack_require__(4); + var dotparser = __webpack_require__(41); + var gephiParser = __webpack_require__(42); + var Groups = __webpack_require__(37); + var Images = __webpack_require__(38); + var Node = __webpack_require__(39); + var Edge = __webpack_require__(36); + var Popup = __webpack_require__(40); + var MixinLoader = __webpack_require__(50); + var Activator = __webpack_require__(51); + var locales = __webpack_require__(48); + + // Load custom shapes into CanvasRenderingContext2D + __webpack_require__(49); /** - * A custom time bar - * @param {{range: Range, dom: Object}} body - * @param {Object} [options] Available parameters: - * {Boolean} [showCustomTime] - * @constructor CustomTime - * @extends Component + * @constructor Network + * Create a network visualization, displaying nodes and edges. + * + * @param {Element} container The DOM element in which the Network will + * be created. Normally a div element. + * @param {Object} data An object containing parameters + * {Array} nodes + * {Array} edges + * @param {Object} options Options */ + function Network (container, data, options) { + if (!(this instanceof Network)) { + throw new SyntaxError('Constructor must be called with the new operator'); + } - function CustomTime (body, options) { - this.body = body; + this._initializeMixinLoaders(); - // default options + // create variables and set default values + this.containerElement = container; + + // render and calculation settings + this.renderRefreshRate = 60; // hz (fps) + this.renderTimestep = 1000 / this.renderRefreshRate; // ms -- saves calculation later on + this.renderTime = 0.5 * this.renderTimestep; // measured time it takes to render a frame + this.maxPhysicsTicksPerRender = 3; // max amount of physics ticks per render step. + this.physicsDiscreteStepsize = 0.50; // discrete stepsize of the simulation + + this.initializing = true; + + this.triggerFunctions = {add:null,edit:null,editEdge:null,connect:null,del:null}; + + // set constant values this.defaultOptions = { - showCustomTime: false, + nodes: { + mass: 1, + radiusMin: 10, + radiusMax: 30, + radius: 10, + shape: 'ellipse', + image: undefined, + widthMin: 16, // px + widthMax: 64, // px + fontColor: 'black', + fontSize: 14, // px + fontFace: 'verdana', + fontFill: undefined, + level: -1, + color: { + border: '#2B7CE9', + background: '#97C2FC', + highlight: { + border: '#2B7CE9', + background: '#D2E5FF' + }, + hover: { + border: '#2B7CE9', + background: '#D2E5FF' + } + }, + borderColor: '#2B7CE9', + backgroundColor: '#97C2FC', + highlightColor: '#D2E5FF', + group: undefined, + borderWidth: 1, + borderWidthSelected: undefined + }, + edges: { + widthMin: 1, // + widthMax: 15,// + width: 1, + widthSelectionMultiplier: 2, + hoverWidth: 1.5, + style: 'line', + color: { + color:'#848484', + highlight:'#848484', + hover: '#848484' + }, + fontColor: '#343434', + fontSize: 14, // px + fontFace: 'arial', + fontFill: 'white', + arrowScaleFactor: 1, + dash: { + length: 10, + gap: 5, + altLength: undefined + }, + inheritColor: "from" // to, from, false, true (== from) + }, + configurePhysics:false, + physics: { + barnesHut: { + enabled: true, + theta: 1 / 0.6, // inverted to save time during calculation + gravitationalConstant: -2000, + centralGravity: 0.3, + springLength: 95, + springConstant: 0.04, + damping: 0.09 + }, + repulsion: { + centralGravity: 0.0, + springLength: 200, + springConstant: 0.05, + nodeDistance: 100, + damping: 0.09 + }, + hierarchicalRepulsion: { + enabled: false, + centralGravity: 0.0, + springLength: 100, + springConstant: 0.01, + nodeDistance: 150, + damping: 0.09 + }, + damping: null, + centralGravity: null, + springLength: null, + springConstant: null + }, + clustering: { // Per Node in Cluster = PNiC + enabled: false, // (Boolean) | global on/off switch for clustering. + initialMaxNodes: 100, // (# nodes) | if the initial amount of nodes is larger than this, we cluster until the total number is less than this threshold. + clusterThreshold:500, // (# nodes) | during calculate forces, we check if the total number of nodes is larger than this. If it is, cluster until reduced to reduceToNodes + reduceToNodes:300, // (# nodes) | during calculate forces, we check if the total number of nodes is larger than clusterThreshold. If it is, cluster until reduced to this + chainThreshold: 0.4, // (% of all drawn nodes)| maximum percentage of allowed chainnodes (long strings of connected nodes) within all nodes. (lower means less chains). + clusterEdgeThreshold: 20, // (px) | edge length threshold. if smaller, this node is clustered. + sectorThreshold: 100, // (# nodes in cluster) | cluster size threshold. If larger, expanding in own sector. + screenSizeThreshold: 0.2, // (% of canvas) | relative size threshold. If the width or height of a clusternode takes up this much of the screen, decluster node. + fontSizeMultiplier: 4.0, // (px PNiC) | how much the cluster font size grows per node in cluster (in px). + maxFontSize: 1000, + forceAmplification: 0.1, // (multiplier PNiC) | factor of increase fo the repulsion force of a cluster (per node in cluster). + distanceAmplification: 0.1, // (multiplier PNiC) | factor how much the repulsion distance of a cluster increases (per node in cluster). + edgeGrowth: 20, // (px PNiC) | amount of clusterSize connected to the edge is multiplied with this and added to edgeLength. + nodeScaling: {width: 1, // (px PNiC) | growth of the width per node in cluster. + height: 1, // (px PNiC) | growth of the height per node in cluster. + radius: 1}, // (px PNiC) | growth of the radius per node in cluster. + maxNodeSizeIncrements: 600, // (# increments) | max growth of the width per node in cluster. + activeAreaBoxSize: 80, // (px) | box area around the curser where clusters are popped open. + clusterLevelDifference: 2 + }, + navigation: { + enabled: false + }, + keyboard: { + enabled: false, + speed: {x: 10, y: 10, zoom: 0.02} + }, + dataManipulation: { + enabled: false, + initiallyVisible: false + }, + hierarchicalLayout: { + enabled:false, + levelSeparation: 150, + nodeSpacing: 100, + direction: "UD", // UD, DU, LR, RL + layout: "hubsize" // hubsize, directed + }, + freezeForStabilization: false, + smoothCurves: { + enabled: true, + dynamic: true, + type: "continuous", + roundness: 0.5 + }, + dynamicSmoothCurves: true, + maxVelocity: 30, + minVelocity: 0.1, // px/s + stabilize: true, // stabilize before displaying the network + stabilizationIterations: 1000, // maximum number of iteration to stabilize + locale: 'en', locales: locales, - locale: 'en' + tooltip: { + delay: 300, + fontColor: 'black', + fontSize: 14, // px + fontFace: 'verdana', + color: { + border: '#666', + background: '#FFFFC6' + } + }, + dragNetwork: true, + dragNodes: true, + zoomable: true, + hover: false, + hideEdgesOnDrag: false, + hideNodesOnDrag: false, + width : '100%', + height : '100%', + selectable: true }; - this.options = util.extend({}, this.defaultOptions); + this.constants = util.extend({}, this.defaultOptions); - this.customTime = new Date(); - this.eventParams = {}; // stores state parameters while dragging the bar + this.hoverObj = {nodes:{},edges:{}}; + this.controlNodesActive = false; + this.navigationHammers = {existing:[], new: []}; - // create the DOM - this._create(); + // animation properties + this.animationSpeed = 1/this.renderRefreshRate; + this.animationEasingFunction = "easeInOutQuint"; + this.easingTime = 0; + this.sourceScale = 0; + this.targetScale = 0; + this.sourceTranslation = 0; + this.targetTranslation = 0; + this.lockedOnNodeId = null; + this.lockedOnNodeOffset = null; - this.setOptions(options); - } + // Node variables + var network = this; + this.groups = new Groups(); // object with groups + this.images = new Images(); // object with images + this.images.setOnloadCallback(function () { + network._redraw(); + }); - CustomTime.prototype = new Component(); + // keyboard navigation variables + this.xIncrement = 0; + this.yIncrement = 0; + this.zoomIncrement = 0; - /** - * Set options for the component. Options will be merged in current options. - * @param {Object} options Available parameters: - * {boolean} [showCustomTime] - */ - CustomTime.prototype.setOptions = function(options) { - if (options) { - // copy all options that we know - util.selectiveExtend(['showCustomTime', 'locale', 'locales'], this.options, options); - } - }; + // loading all the mixins: + // load the force calculation functions, grouped under the physics system. + this._loadPhysicsSystem(); + // create a frame and canvas + this._create(); + // load the sector system. (mandatory, fully integrated with Network) + this._loadSectorSystem(); + // load the cluster system. (mandatory, even when not using the cluster system, there are function calls to it) + this._loadClusterSystem(); + // load the selection system. (mandatory, required by Network) + this._loadSelectionSystem(); + // load the selection system. (mandatory, required by Network) + this._loadHierarchySystem(); - /** - * Create the DOM for the custom time - * @private - */ - CustomTime.prototype._create = function() { - var bar = document.createElement('div'); - bar.className = 'customtime'; - bar.style.position = 'absolute'; - bar.style.top = '0px'; - bar.style.height = '100%'; - this.bar = bar; - var drag = document.createElement('div'); - drag.style.position = 'relative'; - drag.style.top = '0px'; - drag.style.left = '-10px'; - drag.style.height = '100%'; - drag.style.width = '20px'; - bar.appendChild(drag); + // apply options + this._setTranslation(this.frame.clientWidth / 2, this.frame.clientHeight / 2); + this._setScale(1); + this.setOptions(options); - // attach event listeners - this.hammer = Hammer(bar, { - prevent_default: true - }); - this.hammer.on('dragstart', this._onDragStart.bind(this)); - this.hammer.on('drag', this._onDrag.bind(this)); - this.hammer.on('dragend', this._onDragEnd.bind(this)); - }; + // other vars + this.freezeSimulation = false;// freeze the simulation + this.cachedFunctions = {}; + this.startedStabilization = false; + this.stabilized = false; + this.stabilizationIterations = null; - /** - * Destroy the CustomTime bar - */ - CustomTime.prototype.destroy = function () { - this.options.showCustomTime = false; - this.redraw(); // will remove the bar from the DOM + // containers for nodes and edges + this.calculationNodes = {}; + this.calculationNodeIndices = []; + this.nodeIndices = []; // array with all the indices of the nodes. Used to speed up forces calculation + this.nodes = {}; // object with Node objects + this.edges = {}; // object with Edge objects - this.hammer.enable(false); - this.hammer = null; + // position and scale variables and objects + this.canvasTopLeft = {"x": 0,"y": 0}; // coordinates of the top left of the canvas. they will be set during _redraw. + this.canvasBottomRight = {"x": 0,"y": 0}; // coordinates of the bottom right of the canvas. they will be set during _redraw + this.pointerPosition = {"x": 0,"y": 0}; // coordinates of the bottom right of the canvas. they will be set during _redraw + this.areaCenter = {}; // object with x and y elements used for determining the center of the zoom action + this.scale = 1; // defining the global scale variable in the constructor + this.previousScale = this.scale; // this is used to check if the zoom operation is zooming in or out - this.body = null; - }; + // datasets or dataviews + this.nodesData = null; // A DataSet or DataView + this.edgesData = null; // A DataSet or DataView - /** - * Repaint the component - * @return {boolean} Returns true if the component is resized - */ - CustomTime.prototype.redraw = function () { - if (this.options.showCustomTime) { - var parent = this.body.dom.backgroundVertical; - if (this.bar.parentNode != parent) { - // attach to the dom - if (this.bar.parentNode) { - this.bar.parentNode.removeChild(this.bar); - } - parent.appendChild(this.bar); + // create event listeners used to subscribe on the DataSets of the nodes and edges + this.nodesListeners = { + 'add': function (event, params) { + network._addNodes(params.items); + network.start(); + }, + 'update': function (event, params) { + network._updateNodes(params.items, params.data); + network.start(); + }, + 'remove': function (event, params) { + network._removeNodes(params.items); + network.start(); + } + }; + this.edgesListeners = { + 'add': function (event, params) { + network._addEdges(params.items); + network.start(); + }, + 'update': function (event, params) { + network._updateEdges(params.items); + network.start(); + }, + 'remove': function (event, params) { + network._removeEdges(params.items); + network.start(); } + }; - var x = this.body.util.toScreen(this.customTime); + // properties for the animation + this.moving = true; + this.timer = undefined; // Scheduling function. Is definded in this.start(); - var locale = this.options.locales[this.options.locale]; - var title = locale.time + ': ' + moment(this.customTime).format('dddd, MMMM Do YYYY, H:mm:ss'); - title = title.charAt(0).toUpperCase() + title.substring(1); + // load data (the disable start variable will be the same as the enabled clustering) + this.setData(data,this.constants.clustering.enabled || this.constants.hierarchicalLayout.enabled); - this.bar.style.left = x + 'px'; - this.bar.title = title; + // hierarchical layout + this.initializing = false; + if (this.constants.hierarchicalLayout.enabled == true) { + this._setupHierarchicalLayout(); } else { - // remove the line from the DOM - if (this.bar.parentNode) { - this.bar.parentNode.removeChild(this.bar); + // zoom so all data will fit on the screen, if clustering is enabled, we do not want start to be called here. + if (this.constants.stabilize == false) { + this.zoomExtent(undefined, true,this.constants.clustering.enabled); } } - return false; - }; - - /** - * Set custom time. - * @param {Date | number | string} time - */ - CustomTime.prototype.setCustomTime = function(time) { - this.customTime = util.convert(time, 'Date'); - this.redraw(); - }; + // if clustering is disabled, the simulation will have started in the setData function + if (this.constants.clustering.enabled) { + this.startWithClustering(); + } + } - /** - * Retrieve the current custom time. - * @return {Date} customTime - */ - CustomTime.prototype.getCustomTime = function() { - return new Date(this.customTime.valueOf()); - }; + // Extend Network with an Emitter mixin + Emitter(Network.prototype); /** - * Start moving horizontally - * @param {Event} event + * Get the script path where the vis.js library is located + * + * @returns {string | null} path Path or null when not found. Path does not + * end with a slash. * @private */ - CustomTime.prototype._onDragStart = function(event) { - this.eventParams.dragging = true; - this.eventParams.customTime = this.customTime; + Network.prototype._getScriptPath = function() { + var scripts = document.getElementsByTagName( 'script' ); - event.stopPropagation(); - event.preventDefault(); + // find script named vis.js or vis.min.js + for (var i = 0; i < scripts.length; i++) { + var src = scripts[i].src; + var match = src && /\/?vis(.min)?\.js$/.exec(src); + if (match) { + // return path without the script name + return src.substring(0, src.length - match[0].length); + } + } + + return null; }; + /** - * Perform moving operating. - * @param {Event} event + * Find the center position of the network * @private */ - CustomTime.prototype._onDrag = function (event) { - if (!this.eventParams.dragging) return; - - var deltaX = event.gesture.deltaX, - x = this.body.util.toScreen(this.eventParams.customTime) + deltaX, - time = this.body.util.toTime(x); - - this.setCustomTime(time); - - // fire a timechange event - this.body.emitter.emit('timechange', { - time: new Date(this.customTime.valueOf()) - }); - - event.stopPropagation(); - event.preventDefault(); + Network.prototype._getRange = function() { + var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node; + for (var nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + node = this.nodes[nodeId]; + if (minX > (node.x)) {minX = node.x;} + if (maxX < (node.x)) {maxX = node.x;} + if (minY > (node.y)) {minY = node.y;} + if (maxY < (node.y)) {maxY = node.y;} + } + } + if (minX == 1e9 && maxX == -1e9 && minY == 1e9 && maxY == -1e9) { + minY = 0, maxY = 0, minX = 0, maxX = 0; + } + return {minX: minX, maxX: maxX, minY: minY, maxY: maxY}; }; + /** - * Stop moving operating. - * @param {event} event + * @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY}; + * @returns {{x: number, y: number}} * @private */ - CustomTime.prototype._onDragEnd = function (event) { - if (!this.eventParams.dragging) return; - - // fire a timechanged event - this.body.emitter.emit('timechanged', { - time: new Date(this.customTime.valueOf()) - }); - - event.stopPropagation(); - event.preventDefault(); + Network.prototype._findCenter = function(range) { + return {x: (0.5 * (range.maxX + range.minX)), + y: (0.5 * (range.maxY + range.minY))}; }; - module.exports = CustomTime; - - -/***/ }, -/* 30 */ -/***/ function(module, exports, __webpack_require__) { - - var Hammer = __webpack_require__(18); - var util = __webpack_require__(1); - var DataSet = __webpack_require__(7); - var DataView = __webpack_require__(8); - var Component = __webpack_require__(22); - var Group = __webpack_require__(31); - var BackgroundGroup = __webpack_require__(35); - var BoxItem = __webpack_require__(36); - var PointItem = __webpack_require__(37); - var RangeItem = __webpack_require__(33); - var BackgroundItem = __webpack_require__(38); - - - var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items - var BACKGROUND = '__background__'; // reserved group id for background items without group /** - * An ItemSet holds a set of items and ranges which can be displayed in a - * range. The width is determined by the parent of the ItemSet, and the height - * is determined by the size of the items. - * @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} body - * @param {Object} [options] See ItemSet.setOptions for the available options. - * @constructor ItemSet - * @extends Component + * This function zooms out to fit all data on screen based on amount of nodes + * + * @param {Boolean} [initialZoom] | zoom based on fitted formula or range, true = fitted, default = false; + * @param {Boolean} [disableStart] | If true, start is not called. */ - function ItemSet(body, options) { - this.body = body; + Network.prototype.zoomExtent = function(animationOptions, initialZoom, disableStart) { + if (initialZoom === undefined) { + initialZoom = false; + } + if (disableStart === undefined) { + disableStart = false; + } + if (animationOptions === undefined) { + animationOptions = false; + } - this.defaultOptions = { - type: null, // 'box', 'point', 'range', 'background' - orientation: 'bottom', // 'top' or 'bottom' - align: 'auto', // alignment of box items - stack: true, - groupOrder: null, + var range = this._getRange(); + var zoomLevel; - selectable: true, - editable: { - updateTime: false, - updateGroup: false, - add: false, - remove: false - }, + if (initialZoom == true) { + var numberOfNodes = this.nodeIndices.length; + if (this.constants.smoothCurves == true) { + if (this.constants.clustering.enabled == true && + numberOfNodes >= this.constants.clustering.initialMaxNodes) { + zoomLevel = 49.07548 / (numberOfNodes + 142.05338) + 9.1444e-04; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. + } + else { + zoomLevel = 12.662 / (numberOfNodes + 7.4147) + 0.0964822; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. + } + } + else { + if (this.constants.clustering.enabled == true && + numberOfNodes >= this.constants.clustering.initialMaxNodes) { + zoomLevel = 77.5271985 / (numberOfNodes + 187.266146) + 4.76710517e-05; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. + } + else { + zoomLevel = 30.5062972 / (numberOfNodes + 19.93597763) + 0.08413486; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. + } + } - onAdd: function (item, callback) { - callback(item); - }, - onUpdate: function (item, callback) { - callback(item); - }, - onMove: function (item, callback) { - callback(item); - }, - onRemove: function (item, callback) { - callback(item); - }, - onMoving: function (item, callback) { - callback(item); - }, + // correct for larger canvasses. + var factor = Math.min(this.frame.canvas.clientWidth / 600, this.frame.canvas.clientHeight / 600); + zoomLevel *= factor; + } + else { + var xDistance = Math.abs(range.maxX - range.minX) * 1.1; + var yDistance = Math.abs(range.maxY - range.minY) * 1.1; - margin: { - item: { - horizontal: 10, - vertical: 10 - }, - axis: 20 - }, - padding: 5 - }; + var xZoomLevel = this.frame.canvas.clientWidth / xDistance; + var yZoomLevel = this.frame.canvas.clientHeight / yDistance; - // options is shared by this ItemSet and all its items - this.options = util.extend({}, this.defaultOptions); + zoomLevel = (xZoomLevel <= yZoomLevel) ? xZoomLevel : yZoomLevel; + } - // options for getting items from the DataSet with the correct type - this.itemOptions = { - type: {start: 'Date', end: 'Date'} - }; + if (zoomLevel > 1.0) { + zoomLevel = 1.0; + } - this.conversion = { - toScreen: body.util.toScreen, - toTime: body.util.toTime - }; - this.dom = {}; - this.props = {}; - this.hammer = null; - var me = this; - this.itemsData = null; // DataSet - this.groupsData = null; // DataSet + var center = this._findCenter(range); + if (disableStart == false) { + var options = {position: center, scale: zoomLevel, animation: animationOptions}; + this.moveTo(options); + this.moving = true; + this.start(); + } + else { + center.x *= zoomLevel; + center.y *= zoomLevel; + center.x -= 0.5 * this.frame.canvas.clientWidth; + center.y -= 0.5 * this.frame.canvas.clientHeight; + this._setScale(zoomLevel); + this._setTranslation(-center.x,-center.y); + } + }; - // listeners for the DataSet of the items - this.itemListeners = { - 'add': function (event, params, senderId) { - me._onAdd(params.items); - }, - 'update': function (event, params, senderId) { - me._onUpdate(params.items); - }, - 'remove': function (event, params, senderId) { - me._onRemove(params.items); - } - }; - // listeners for the DataSet of the groups - this.groupListeners = { - 'add': function (event, params, senderId) { - me._onAddGroups(params.items); - }, - 'update': function (event, params, senderId) { - me._onUpdateGroups(params.items); - }, - 'remove': function (event, params, senderId) { - me._onRemoveGroups(params.items); + /** + * Update the this.nodeIndices with the most recent node index list + * @private + */ + Network.prototype._updateNodeIndexList = function() { + this._clearNodeIndexList(); + for (var idx in this.nodes) { + if (this.nodes.hasOwnProperty(idx)) { + this.nodeIndices.push(idx); } - }; - - this.items = {}; // object with an Item for every data item - this.groups = {}; // Group object for every group - this.groupIds = []; - - this.selection = []; // list with the ids of all selected nodes - this.stackDirty = true; // if true, all items will be restacked on next redraw - - this.touchParams = {}; // stores properties while dragging - // create the HTML DOM + } + }; - this._create(); - this.setOptions(options); - } + /** + * Set nodes and edges, and optionally options as well. + * + * @param {Object} data Object containing parameters: + * {Array | DataSet | DataView} [nodes] Array with nodes + * {Array | DataSet | DataView} [edges] Array with edges + * {String} [dot] String containing data in DOT format + * {String} [gephi] String containing data in gephi JSON format + * {Options} [options] Object with options + * @param {Boolean} [disableStart] | optional: disable the calling of the start function. + */ + Network.prototype.setData = function(data, disableStart) { + if (disableStart === undefined) { + disableStart = false; + } + // we set initializing to true to ensure that the hierarchical layout is not performed until both nodes and edges are added. + this.initializing = true; - ItemSet.prototype = new Component(); + if (data && data.dot && (data.nodes || data.edges)) { + throw new SyntaxError('Data must contain either parameter "dot" or ' + + ' parameter pair "nodes" and "edges", but not both.'); + } - // available item types will be registered here - ItemSet.types = { - background: BackgroundItem, - box: BoxItem, - range: RangeItem, - point: PointItem + // set options + this.setOptions(data && data.options); + // set all data + if (data && data.dot) { + // parse DOT file + if(data && data.dot) { + var dotData = dotparser.DOTToGraph(data.dot); + this.setData(dotData); + return; + } + } + else if (data && data.gephi) { + // parse DOT file + if(data && data.gephi) { + var gephiData = gephiParser.parseGephi(data.gephi); + this.setData(gephiData); + return; + } + } + else { + this._setNodes(data && data.nodes); + this._setEdges(data && data.edges); + } + this._putDataInSector(); + if (disableStart == false) { + if (this.constants.hierarchicalLayout.enabled == true) { + this._resetLevels(); + this._setupHierarchicalLayout(); + } + else { + // find a stable position or start animating to a stable position + if (this.constants.stabilize) { + this._stabilize(); + } + } + this.start(); + } + this.initializing = false; }; /** - * Create the HTML DOM for the ItemSet + * Set options + * @param {Object} options */ - ItemSet.prototype._create = function(){ - var frame = document.createElement('div'); - frame.className = 'itemset'; - frame['timeline-itemset'] = this; - this.dom.frame = frame; - - // create background panel - var background = document.createElement('div'); - background.className = 'background'; - frame.appendChild(background); - this.dom.background = background; - - // create foreground panel - var foreground = document.createElement('div'); - foreground.className = 'foreground'; - frame.appendChild(foreground); - this.dom.foreground = foreground; - - // create axis panel - var axis = document.createElement('div'); - axis.className = 'axis'; - this.dom.axis = axis; + Network.prototype.setOptions = function (options) { + if (options) { + var prop; - // create labelset - var labelSet = document.createElement('div'); - labelSet.className = 'labelset'; - this.dom.labelSet = labelSet; + var fields = ['nodes','edges','smoothCurves','hierarchicalLayout','clustering','navigation','keyboard','dataManipulation', + 'onAdd','onEdit','onEditEdge','onConnect','onDelete','clickToUse' + ]; + util.selectiveNotDeepExtend(fields,this.constants, options); + util.selectiveNotDeepExtend(['color'],this.constants.nodes, options.nodes); + util.selectiveNotDeepExtend(['color','length'],this.constants.edges, options.edges); - // create ungrouped Group - this._updateUngrouped(); + if (options.physics) { + util.mergeOptions(this.constants.physics, options.physics,'barnesHut'); + util.mergeOptions(this.constants.physics, options.physics,'repulsion'); - // create background Group - var backgroundGroup = new BackgroundGroup(BACKGROUND, null, this); - backgroundGroup.show(); - this.groups[BACKGROUND] = backgroundGroup; + if (options.physics.hierarchicalRepulsion) { + this.constants.hierarchicalLayout.enabled = true; + this.constants.physics.hierarchicalRepulsion.enabled = true; + this.constants.physics.barnesHut.enabled = false; + for (prop in options.physics.hierarchicalRepulsion) { + if (options.physics.hierarchicalRepulsion.hasOwnProperty(prop)) { + this.constants.physics.hierarchicalRepulsion[prop] = options.physics.hierarchicalRepulsion[prop]; + } + } + } + } - // attach event listeners - // Note: we bind to the centerContainer for the case where the height - // of the center container is larger than of the ItemSet, so we - // can click in the empty area to create a new item or deselect an item. - this.hammer = Hammer(this.body.dom.centerContainer, { - prevent_default: true - }); + if (options.onAdd) {this.triggerFunctions.add = options.onAdd;} + if (options.onEdit) {this.triggerFunctions.edit = options.onEdit;} + if (options.onEditEdge) {this.triggerFunctions.editEdge = options.onEditEdge;} + if (options.onConnect) {this.triggerFunctions.connect = options.onConnect;} + if (options.onDelete) {this.triggerFunctions.del = options.onDelete;} - // drag items when selected - this.hammer.on('touch', this._onTouch.bind(this)); - this.hammer.on('dragstart', this._onDragStart.bind(this)); - this.hammer.on('drag', this._onDrag.bind(this)); - this.hammer.on('dragend', this._onDragEnd.bind(this)); + util.mergeOptions(this.constants, options,'smoothCurves'); + util.mergeOptions(this.constants, options,'hierarchicalLayout'); + util.mergeOptions(this.constants, options,'clustering'); + util.mergeOptions(this.constants, options,'navigation'); + util.mergeOptions(this.constants, options,'keyboard'); + util.mergeOptions(this.constants, options,'dataManipulation'); - // single select (or unselect) when tapping an item - this.hammer.on('tap', this._onSelectItem.bind(this)); - // multi select when holding mouse/touch, or on ctrl+click - this.hammer.on('hold', this._onMultiSelectItem.bind(this)); + if (options.dataManipulation) { + this.editMode = this.constants.dataManipulation.initiallyVisible; + } - // add item on doubletap - this.hammer.on('doubletap', this._onAddItem.bind(this)); - // attach to the DOM - this.show(); - }; + // TODO: work out these options and document them + if (options.edges) { + if (options.edges.color !== undefined) { + if (util.isString(options.edges.color)) { + this.constants.edges.color = {}; + this.constants.edges.color.color = options.edges.color; + this.constants.edges.color.highlight = options.edges.color; + this.constants.edges.color.hover = options.edges.color; + } + else { + if (options.edges.color.color !== undefined) {this.constants.edges.color.color = options.edges.color.color;} + if (options.edges.color.highlight !== undefined) {this.constants.edges.color.highlight = options.edges.color.highlight;} + if (options.edges.color.hover !== undefined) {this.constants.edges.color.hover = options.edges.color.hover;} + } + } - /** - * Set options for the ItemSet. Existing options will be extended/overwritten. - * @param {Object} [options] The following options are available: - * {String} type - * Default type for the items. Choose from 'box' - * (default), 'point', 'range', or 'background'. - * The default style can be overwritten by - * individual items. - * {String} align - * Alignment for the items, only applicable for - * BoxItem. Choose 'center' (default), 'left', or - * 'right'. - * {String} orientation - * Orientation of the item set. Choose 'top' or - * 'bottom' (default). - * {Function} groupOrder - * A sorting function for ordering groups - * {Boolean} stack - * If true (deafult), items will be stacked on - * top of each other. - * {Number} margin.axis - * Margin between the axis and the items in pixels. - * Default is 20. - * {Number} margin.item.horizontal - * Horizontal margin between items in pixels. - * Default is 10. - * {Number} margin.item.vertical - * Vertical Margin between items in pixels. - * Default is 10. - * {Number} margin.item - * Margin between items in pixels in both horizontal - * and vertical direction. Default is 10. - * {Number} margin - * Set margin for both axis and items in pixels. - * {Number} padding - * Padding of the contents of an item in pixels. - * Must correspond with the items css. Default is 5. - * {Boolean} selectable - * If true (default), items can be selected. - * {Boolean} editable - * Set all editable options to true or false - * {Boolean} editable.updateTime - * Allow dragging an item to an other moment in time - * {Boolean} editable.updateGroup - * Allow dragging an item to an other group - * {Boolean} editable.add - * Allow creating new items on double tap - * {Boolean} editable.remove - * Allow removing items by clicking the delete button - * top right of a selected item. - * {Function(item: Item, callback: Function)} onAdd - * Callback function triggered when an item is about to be added: - * when the user double taps an empty space in the Timeline. - * {Function(item: Item, callback: Function)} onUpdate - * Callback function fired when an item is about to be updated. - * This function typically has to show a dialog where the user - * change the item. If not implemented, nothing happens. - * {Function(item: Item, callback: Function)} onMove - * Fired when an item has been moved. If not implemented, - * the move action will be accepted. - * {Function(item: Item, callback: Function)} onRemove - * Fired when an item is about to be deleted. - * If not implemented, the item will be always removed. - */ - ItemSet.prototype.setOptions = function(options) { - if (options) { - // copy all options that we know - var fields = ['type', 'align', 'orientation', 'padding', 'stack', 'selectable', 'groupOrder', 'dataAttributes', 'template','hide']; - util.selectiveExtend(fields, this.options, options); + if (!options.edges.fontColor) { + if (options.edges.color !== undefined) { + if (util.isString(options.edges.color)) {this.constants.edges.fontColor = options.edges.color;} + else if (options.edges.color.color !== undefined) {this.constants.edges.fontColor = options.edges.color.color;} + } + } + } - if ('margin' in options) { - if (typeof options.margin === 'number') { - this.options.margin.axis = options.margin; - this.options.margin.item.horizontal = options.margin; - this.options.margin.item.vertical = options.margin; + if (options.nodes) { + if (options.nodes.color) { + var newColorObj = util.parseColor(options.nodes.color); + this.constants.nodes.color.background = newColorObj.background; + this.constants.nodes.color.border = newColorObj.border; + this.constants.nodes.color.highlight.background = newColorObj.highlight.background; + this.constants.nodes.color.highlight.border = newColorObj.highlight.border; + this.constants.nodes.color.hover.background = newColorObj.hover.background; + this.constants.nodes.color.hover.border = newColorObj.hover.border; } - else if (typeof options.margin === 'object') { - util.selectiveExtend(['axis'], this.options.margin, options.margin); - if ('item' in options.margin) { - if (typeof options.margin.item === 'number') { - this.options.margin.item.horizontal = options.margin.item; - this.options.margin.item.vertical = options.margin.item; - } - else if (typeof options.margin.item === 'object') { - util.selectiveExtend(['horizontal', 'vertical'], this.options.margin.item, options.margin.item); - } + } + if (options.groups) { + for (var groupname in options.groups) { + if (options.groups.hasOwnProperty(groupname)) { + var group = options.groups[groupname]; + this.groups.add(groupname, group); } } } - if ('editable' in options) { - if (typeof options.editable === 'boolean') { - this.options.editable.updateTime = options.editable; - this.options.editable.updateGroup = options.editable; - this.options.editable.add = options.editable; - this.options.editable.remove = options.editable; + if (options.tooltip) { + for (prop in options.tooltip) { + if (options.tooltip.hasOwnProperty(prop)) { + this.constants.tooltip[prop] = options.tooltip[prop]; + } } - else if (typeof options.editable === 'object') { - util.selectiveExtend(['updateTime', 'updateGroup', 'add', 'remove'], this.options.editable, options.editable); + if (options.tooltip.color) { + this.constants.tooltip.color = util.parseColor(options.tooltip.color); + } + } + + if ('clickToUse' in options) { + if (options.clickToUse) { + this.activator = new Activator(this.frame); + this.activator.on('change', this._createKeyBinds.bind(this)); } - } - - // callback functions - var addCallback = (function (name) { - var fn = options[name]; - if (fn) { - if (!(fn instanceof Function)) { - throw new Error('option ' + name + ' must be a function ' + name + '(item, callback)'); + else { + if (this.activator) { + this.activator.destroy(); + delete this.activator; } - this.options[name] = fn; } - }).bind(this); - ['onAdd', 'onUpdate', 'onRemove', 'onMove', 'onMoving'].forEach(addCallback); + } - // force the itemSet to refresh: options like orientation and margins may be changed - this.markDirty(); + if (options.labels) { + throw new Error('Option "labels" is deprecated. Use options "locale" and "locales" instead.'); + } } - }; - - /** - * Mark the ItemSet dirty so it will refresh everything with next redraw - */ - ItemSet.prototype.markDirty = function() { - this.groupIds = []; - this.stackDirty = true; - }; - /** - * Destroy the ItemSet - */ - ItemSet.prototype.destroy = function() { - this.hide(); - this.setItems(null); - this.setGroups(null); + // (Re)loading the mixins that can be enabled or disabled in the options. + // load the force calculation functions, grouped under the physics system. + this._loadPhysicsSystem(); + // load the navigation system. + this._loadNavigationControls(); + // load the data manipulation system + this._loadManipulationSystem(); + // configure the smooth curves + this._configureSmoothCurves(); - this.hammer = null; - this.body = null; - this.conversion = null; + // bind keys. If disabled, this will not do anything; + this._createKeyBinds(); + this.setSize(this.constants.width, this.constants.height); + this.moving = true; + this.start(); }; /** - * Hide the component from the DOM + * Create the main frame for the Network. + * This function is executed once when a Network object is created. The frame + * contains a canvas, and this canvas contains all objects like the axis and + * nodes. + * @private */ - ItemSet.prototype.hide = function() { - // remove the frame containing the items - if (this.dom.frame.parentNode) { - this.dom.frame.parentNode.removeChild(this.dom.frame); + Network.prototype._create = function () { + // remove all elements from the container element. + while (this.containerElement.hasChildNodes()) { + this.containerElement.removeChild(this.containerElement.firstChild); } - // remove the axis with dots - if (this.dom.axis.parentNode) { - this.dom.axis.parentNode.removeChild(this.dom.axis); - } + this.frame = document.createElement('div'); + this.frame.className = 'vis network-frame'; + this.frame.style.position = 'relative'; + this.frame.style.overflow = 'hidden'; - // remove the labelset containing all group labels - if (this.dom.labelSet.parentNode) { - this.dom.labelSet.parentNode.removeChild(this.dom.labelSet); + // create the network canvas (HTML canvas element) + this.frame.canvas = document.createElement( 'canvas' ); + this.frame.canvas.style.position = 'relative'; + this.frame.appendChild(this.frame.canvas); + if (!this.frame.canvas.getContext) { + var noCanvas = document.createElement( 'DIV' ); + noCanvas.style.color = 'red'; + noCanvas.style.fontWeight = 'bold' ; + noCanvas.style.padding = '10px'; + noCanvas.innerHTML = 'Error: your browser does not support HTML canvas'; + this.frame.canvas.appendChild(noCanvas); } - }; - /** - * Show the component in the DOM (when not already visible). - * @return {Boolean} changed - */ - ItemSet.prototype.show = function() { - // show frame containing the items - if (!this.dom.frame.parentNode) { - this.body.dom.center.appendChild(this.dom.frame); - } + var me = this; + this.drag = {}; + this.pinch = {}; + this.hammer = Hammer(this.frame.canvas, { + prevent_default: true + }); + this.hammer.on('tap', me._onTap.bind(me) ); + this.hammer.on('doubletap', me._onDoubleTap.bind(me) ); + this.hammer.on('hold', me._onHold.bind(me) ); + this.hammer.on('pinch', me._onPinch.bind(me) ); + this.hammer.on('touch', me._onTouch.bind(me) ); + this.hammer.on('dragstart', me._onDragStart.bind(me) ); + this.hammer.on('drag', me._onDrag.bind(me) ); + this.hammer.on('dragend', me._onDragEnd.bind(me) ); + this.hammer.on('release', me._onRelease.bind(me) ); + this.hammer.on('mousewheel',me._onMouseWheel.bind(me) ); + this.hammer.on('DOMMouseScroll',me._onMouseWheel.bind(me) ); // for FF + this.hammer.on('mousemove', me._onMouseMoveTitle.bind(me) ); - // show axis with dots - if (!this.dom.axis.parentNode) { - this.body.dom.backgroundVertical.appendChild(this.dom.axis); - } + // add the frame to the container element + this.containerElement.appendChild(this.frame); - // show labelset containing labels - if (!this.dom.labelSet.parentNode) { - this.body.dom.left.appendChild(this.dom.labelSet); - } }; + /** - * Set selected items by their id. Replaces the current selection - * Unknown id's are silently ignored. - * @param {string[] | string} [ids] An array with zero or more id's of the items to be - * selected, or a single item id. If ids is undefined - * or an empty array, all items will be unselected. + * Binding the keys for keyboard navigation. These functions are defined in the NavigationMixin + * @private */ - ItemSet.prototype.setSelection = function(ids) { - var i, ii, id, item; + Network.prototype._createKeyBinds = function() { + var me = this; + this.mousetrap = mousetrap; - if (ids == undefined) ids = []; - if (!Array.isArray(ids)) ids = [ids]; + this.mousetrap.reset(); - // unselect currently selected items - for (i = 0, ii = this.selection.length; i < ii; i++) { - id = this.selection[i]; - item = this.items[id]; - if (item) item.unselect(); + if (this.constants.keyboard.enabled && this.isActive()) { + this.mousetrap.bind("up", this._moveUp.bind(me) , "keydown"); + this.mousetrap.bind("up", this._yStopMoving.bind(me), "keyup"); + this.mousetrap.bind("down", this._moveDown.bind(me) , "keydown"); + this.mousetrap.bind("down", this._yStopMoving.bind(me), "keyup"); + this.mousetrap.bind("left", this._moveLeft.bind(me) , "keydown"); + this.mousetrap.bind("left", this._xStopMoving.bind(me), "keyup"); + this.mousetrap.bind("right",this._moveRight.bind(me), "keydown"); + this.mousetrap.bind("right",this._xStopMoving.bind(me), "keyup"); + this.mousetrap.bind("=", this._zoomIn.bind(me), "keydown"); + this.mousetrap.bind("=", this._stopZoom.bind(me), "keyup"); + this.mousetrap.bind("-", this._zoomOut.bind(me), "keydown"); + this.mousetrap.bind("-", this._stopZoom.bind(me), "keyup"); + this.mousetrap.bind("[", this._zoomIn.bind(me), "keydown"); + this.mousetrap.bind("[", this._stopZoom.bind(me), "keyup"); + this.mousetrap.bind("]", this._zoomOut.bind(me), "keydown"); + this.mousetrap.bind("]", this._stopZoom.bind(me), "keyup"); + this.mousetrap.bind("pageup",this._zoomIn.bind(me), "keydown"); + this.mousetrap.bind("pageup",this._stopZoom.bind(me), "keyup"); + this.mousetrap.bind("pagedown",this._zoomOut.bind(me),"keydown"); + this.mousetrap.bind("pagedown",this._stopZoom.bind(me), "keyup"); } - // select items - this.selection = []; - for (i = 0, ii = ids.length; i < ii; i++) { - id = ids[i]; - item = this.items[id]; - if (item) { - this.selection.push(id); - item.select(); - } + if (this.constants.dataManipulation.enabled == true) { + this.mousetrap.bind("escape",this._createManipulatorBar.bind(me)); + this.mousetrap.bind("del",this._deleteSelected.bind(me)); } }; /** - * Get the selected items by their id - * @return {Array} ids The ids of the selected items + * Get the pointer location from a touch location + * @param {{pageX: Number, pageY: Number}} touch + * @return {{x: Number, y: Number}} pointer + * @private */ - ItemSet.prototype.getSelection = function() { - return this.selection.concat([]); + Network.prototype._getPointer = function (touch) { + return { + x: touch.pageX - util.getAbsoluteLeft(this.frame.canvas), + y: touch.pageY - util.getAbsoluteTop(this.frame.canvas) + }; }; /** - * Get the id's of the currently visible items. - * @returns {Array} The ids of the visible items + * On start of a touch gesture, store the pointer + * @param event + * @private */ - ItemSet.prototype.getVisibleItems = function() { - var range = this.body.range.getRange(); - var left = this.body.util.toScreen(range.start); - var right = this.body.util.toScreen(range.end); - - var ids = []; - for (var groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - var group = this.groups[groupId]; - var rawVisibleItems = group.visibleItems; - - // filter the "raw" set with visibleItems into a set which is really - // visible by pixels - for (var i = 0; i < rawVisibleItems.length; i++) { - var item = rawVisibleItems[i]; - // TODO: also check whether visible vertically - if ((item.left < right) && (item.left + item.width > left)) { - ids.push(item.id); - } - } - } - } + Network.prototype._onTouch = function (event) { + this.drag.pointer = this._getPointer(event.gesture.center); + this.drag.pinched = false; + this.pinch.scale = this._getScale(); - return ids; + this._handleTouch(this.drag.pointer); }; /** - * Deselect a selected item - * @param {String | Number} id + * handle drag start event * @private */ - ItemSet.prototype._deselect = function(id) { - var selection = this.selection; - for (var i = 0, ii = selection.length; i < ii; i++) { - if (selection[i] == id) { // non-strict comparison! - selection.splice(i, 1); - break; - } - } + Network.prototype._onDragStart = function () { + this._handleDragStart(); }; - /** - * Repaint the component - * @return {boolean} Returns true if the component is resized - */ - ItemSet.prototype.redraw = function() { - var margin = this.options.margin, - range = this.body.range, - asSize = util.option.asSize, - options = this.options, - orientation = options.orientation, - resized = false, - frame = this.dom.frame, - editable = options.editable.updateTime || options.editable.updateGroup; - - // recalculate absolute position (before redrawing groups) - this.props.top = this.body.domProps.top.height + this.body.domProps.border.top; - this.props.left = this.body.domProps.left.width + this.body.domProps.border.left; - - // update class name - frame.className = 'itemset' + (editable ? ' editable' : ''); - - // reorder the groups (if needed) - resized = this._orderGroups() || resized; - - // check whether zoomed (in that case we need to re-stack everything) - // TODO: would be nicer to get this as a trigger from Range - var visibleInterval = range.end - range.start; - var zoomed = (visibleInterval != this.lastVisibleInterval) || (this.props.width != this.props.lastWidth); - if (zoomed) this.stackDirty = true; - this.lastVisibleInterval = visibleInterval; - this.props.lastWidth = this.props.width; - - // redraw the background group - this.groups[BACKGROUND].redraw(range, nonFirstMargin, restack); - - // redraw all regular groups - var restack = this.stackDirty, - firstGroup = this._firstGroup(), - firstMargin = { - item: margin.item, - axis: margin.axis - }, - nonFirstMargin = { - item: margin.item, - axis: margin.item.vertical / 2 - }, - height = 0, - minHeight = margin.axis + margin.item.vertical; - util.forEach(this.groups, function (group) { - var groupMargin = (group == firstGroup) ? firstMargin : nonFirstMargin; - var groupResized = group.redraw(range, groupMargin, restack); - resized = groupResized || resized; - height += group.height; - }); - height = Math.max(height, minHeight); - this.stackDirty = false; - - // update frame height - frame.style.height = asSize(height); - - // calculate actual size - this.props.width = frame.offsetWidth; - this.props.height = height; - - // reposition axis - - // reposition axis - this.dom.axis.style.top = asSize((orientation == 'top') ? - (this.body.domProps.top.height + this.body.domProps.border.top) : - (this.body.domProps.top.height + this.body.domProps.centerContainer.height)); - this.dom.axis.style.left = '0'; - - // check if this component is resized - resized = this._isResized() || resized; - - return resized; - }; /** - * Get the first group, aligned with the axis - * @return {Group | null} firstGroup + * This function is called by _onDragStart. + * It is separated out because we can then overload it for the datamanipulation system. + * * @private */ - ItemSet.prototype._firstGroup = function() { - var firstGroupIndex = (this.options.orientation == 'top') ? 0 : (this.groupIds.length - 1); - var firstGroupId = this.groupIds[firstGroupIndex]; - var firstGroup = this.groups[firstGroupId] || this.groups[UNGROUPED]; + Network.prototype._handleDragStart = function() { + var drag = this.drag; + var node = this._getNodeAt(drag.pointer); + // note: drag.pointer is set in _onTouch to get the initial touch location - return firstGroup || null; - }; + drag.dragging = true; + drag.selection = []; + drag.translation = this._getTranslation(); + drag.nodeId = null; - /** - * Create or delete the group holding all ungrouped items. This group is used when - * there are no groups specified. - * @protected - */ - ItemSet.prototype._updateUngrouped = function() { - var ungrouped = this.groups[UNGROUPED]; - var background = this.groups[BACKGROUND]; - var item, itemId; + if (node != null && this.constants.dragNodes == true) { + drag.nodeId = node.id; + // select the clicked node if not yet selected + if (!node.isSelected()) { + this._selectObject(node,false); + } - if (this.groupsData) { - // remove the group holding all ungrouped items - if (ungrouped) { - ungrouped.hide(); - delete this.groups[UNGROUPED]; + this.emit("dragStart",{nodeIds:this.getSelection().nodes}); - for (itemId in this.items) { - if (this.items.hasOwnProperty(itemId)) { - item = this.items[itemId]; - item.parent && item.parent.remove(item); - var groupId = this._getGroupId(item.data); - var group = this.groups[groupId]; - group && group.add(item) || item.hide(); - } - } - } - } - else { - // create a group holding all (unfiltered) items - if (!ungrouped) { - var id = null; - var data = null; - ungrouped = new Group(id, data, this); - this.groups[UNGROUPED] = ungrouped; + // create an array with the selected nodes and their original location and status + for (var objectId in this.selectionObj.nodes) { + if (this.selectionObj.nodes.hasOwnProperty(objectId)) { + var object = this.selectionObj.nodes[objectId]; + var s = { + id: object.id, + node: object, - for (itemId in this.items) { - if (this.items.hasOwnProperty(itemId)) { - item = this.items[itemId]; - ungrouped.add(item); - } - } + // store original x, y, xFixed and yFixed, make the node temporarily Fixed + x: object.x, + y: object.y, + xFixed: object.xFixed, + yFixed: object.yFixed + }; - ungrouped.show(); + object.xFixed = true; + object.yFixed = true; + + drag.selection.push(s); + } } } }; - /** - * Get the element for the labelset - * @return {HTMLElement} labelSet - */ - ItemSet.prototype.getLabelSet = function() { - return this.dom.labelSet; - }; /** - * Set items - * @param {vis.DataSet | null} items + * handle drag event + * @private */ - ItemSet.prototype.setItems = function(items) { - var me = this, - ids, - oldItemsData = this.itemsData; - - // replace the dataset - if (!items) { - this.itemsData = null; - } - else if (items instanceof DataSet || items instanceof DataView) { - this.itemsData = items; - } - else { - throw new TypeError('Data must be an instance of DataSet or DataView'); - } - - if (oldItemsData) { - // unsubscribe from old dataset - util.forEach(this.itemListeners, function (callback, event) { - oldItemsData.off(event, callback); - }); - - // remove all drawn items - ids = oldItemsData.getIds(); - this._onRemove(ids); - } - - if (this.itemsData) { - // subscribe to new dataset - var id = this.id; - util.forEach(this.itemListeners, function (callback, event) { - me.itemsData.on(event, callback, id); - }); - - // add all new items - ids = this.itemsData.getIds(); - this._onAdd(ids); - - // update the group holding all ungrouped items - this._updateUngrouped(); - } + Network.prototype._onDrag = function (event) { + this._handleOnDrag(event) }; - /** - * Get the current items - * @returns {vis.DataSet | null} - */ - ItemSet.prototype.getItems = function() { - return this.itemsData; - }; /** - * Set groups - * @param {vis.DataSet} groups + * This function is called by _onDrag. + * It is separated out because we can then overload it for the datamanipulation system. + * + * @private */ - ItemSet.prototype.setGroups = function(groups) { - var me = this, - ids; + Network.prototype._handleOnDrag = function(event) { + if (this.drag.pinched) { + return; + } - // unsubscribe from current dataset - if (this.groupsData) { - util.forEach(this.groupListeners, function (callback, event) { - me.groupsData.unsubscribe(event, callback); - }); + // remove the focus on node if it is focussed on by the focusOnNode + this.releaseNode(); - // remove all drawn groups - ids = this.groupsData.getIds(); - this.groupsData = null; - this._onRemoveGroups(ids); // note: this will cause a redraw - } + var pointer = this._getPointer(event.gesture.center); + var me = this; + var drag = this.drag; + var selection = drag.selection; + if (selection && selection.length && this.constants.dragNodes == true) { + // calculate delta's and new location + var deltaX = pointer.x - drag.pointer.x; + var deltaY = pointer.y - drag.pointer.y; - // replace the dataset - if (!groups) { - this.groupsData = null; - } - else if (groups instanceof DataSet || groups instanceof DataView) { - this.groupsData = groups; - } - else { - throw new TypeError('Data must be an instance of DataSet or DataView'); - } + // update position of all selected nodes + selection.forEach(function (s) { + var node = s.node; - if (this.groupsData) { - // subscribe to new dataset - var id = this.id; - util.forEach(this.groupListeners, function (callback, event) { - me.groupsData.on(event, callback, id); - }); + if (!s.xFixed) { + node.x = me._XconvertDOMtoCanvas(me._XconvertCanvasToDOM(s.x) + deltaX); + } - // draw all ms - ids = this.groupsData.getIds(); - this._onAddGroups(ids); - } + if (!s.yFixed) { + node.y = me._YconvertDOMtoCanvas(me._YconvertCanvasToDOM(s.y) + deltaY); + } + }); - // update the group holding all ungrouped items - this._updateUngrouped(); - // update the order of all items in each group - this._order(); + // start _animationStep if not yet running + if (!this.moving) { + this.moving = true; + this.start(); + } + } + else { + if (this.constants.dragNetwork == true) { + // move the network + var diffX = pointer.x - this.drag.pointer.x; + var diffY = pointer.y - this.drag.pointer.y; - this.body.emitter.emit('change'); + this._setTranslation( + this.drag.translation.x + diffX, + this.drag.translation.y + diffY + ); + this._redraw(); + // this.moving = true; + // this.start(); + } + } }; /** - * Get the current groups - * @returns {vis.DataSet | null} groups + * handle drag start event + * @private */ - ItemSet.prototype.getGroups = function() { - return this.groupsData; + Network.prototype._onDragEnd = function (event) { + this._handleDragEnd(event); }; - /** - * Remove an item by its id - * @param {String | Number} id - */ - ItemSet.prototype.removeItem = function(id) { - var item = this.itemsData.get(id), - dataset = this.itemsData.getDataSet(); - if (item) { - // confirm deletion - this.options.onRemove(item, function (item) { - if (item) { - // remove by id here, it is possible that an item has no id defined - // itself, so better not delete by the item itself - dataset.remove(id); - } + Network.prototype._handleDragEnd = function(event) { + this.drag.dragging = false; + var selection = this.drag.selection; + if (selection && selection.length) { + selection.forEach(function (s) { + // restore original xFixed and yFixed + s.node.xFixed = s.xFixed; + s.node.yFixed = s.yFixed; }); + this.moving = true; + this.start(); + } + else { + this._redraw(); } + this.emit("dragEnd",{nodeIds:this.getSelection().nodes}); + } + /** + * handle tap/click event: select/unselect a node + * @private + */ + Network.prototype._onTap = function (event) { + var pointer = this._getPointer(event.gesture.center); + this.pointerPosition = pointer; + this._handleTap(pointer); + }; + /** - * Get the time of an item based on it's data and options.type - * @param {Object} itemData - * @returns {string} Returns the type + * handle doubletap event * @private */ - ItemSet.prototype._getType = function (itemData) { - return itemData.type || this.options.type || (itemData.end ? 'range' : 'box'); + Network.prototype._onDoubleTap = function (event) { + var pointer = this._getPointer(event.gesture.center); + this._handleDoubleTap(pointer); }; /** - * Get the group id for an item - * @param {Object} itemData - * @returns {string} Returns the groupId + * handle long tap event: multi select nodes * @private */ - ItemSet.prototype._getGroupId = function (itemData) { - var type = this._getType(itemData); - if (type == 'background' && itemData.group == undefined) { - return BACKGROUND; - } - else { - return this.groupsData ? itemData.group : UNGROUPED; - } + Network.prototype._onHold = function (event) { + var pointer = this._getPointer(event.gesture.center); + this.pointerPosition = pointer; + this._handleOnHold(pointer); }; /** - * Handle updated items - * @param {Number[]} ids - * @protected + * handle the release of the screen + * + * @private */ - ItemSet.prototype._onUpdate = function(ids) { - var me = this; + Network.prototype._onRelease = function (event) { + var pointer = this._getPointer(event.gesture.center); + this._handleOnRelease(pointer); + }; - ids.forEach(function (id) { - var itemData = me.itemsData.get(id, me.itemOptions); - var item = me.items[id]; - var type = me._getType(itemData); + /** + * Handle pinch event + * @param event + * @private + */ + Network.prototype._onPinch = function (event) { + var pointer = this._getPointer(event.gesture.center); - var constructor = ItemSet.types[type]; + this.drag.pinched = true; + if (!('scale' in this.pinch)) { + this.pinch.scale = 1; + } - if (item) { - // update item - if (!constructor || !(item instanceof constructor)) { - // item type has changed, delete the item and recreate it - me._removeItem(item); - item = null; - } - else { - me._updateItem(item, itemData); - } + // TODO: enabled moving while pinching? + var scale = this.pinch.scale * event.gesture.scale; + this._zoom(scale, pointer) + }; + + /** + * Zoom the network in or out + * @param {Number} scale a number around 1, and between 0.01 and 10 + * @param {{x: Number, y: Number}} pointer Position on screen + * @return {Number} appliedScale scale is limited within the boundaries + * @private + */ + Network.prototype._zoom = function(scale, pointer) { + if (this.constants.zoomable == true) { + var scaleOld = this._getScale(); + if (scale < 0.00001) { + scale = 0.00001; + } + if (scale > 10) { + scale = 10; } - if (!item) { - // create item - if (constructor) { - item = new constructor(itemData, me.conversion, me.options); - item.id = id; // TODO: not so nice setting id afterwards - me._addItem(item); - } - else if (type == 'rangeoverflow') { - // TODO: deprecated since version 2.1.0 (or 3.0.0?). cleanup some day - throw new TypeError('Item type "rangeoverflow" is deprecated. Use css styling instead: ' + - '.vis.timeline .item.range .content {overflow: visible;}'); - } - else { - throw new TypeError('Unknown item type "' + type + '"'); + var preScaleDragPointer = null; + if (this.drag !== undefined) { + if (this.drag.dragging == true) { + preScaleDragPointer = this.DOMtoCanvas(this.drag.pointer); } } - }); + // + this.frame.canvas.clientHeight / 2 + var translation = this._getTranslation(); - this._order(); - this.stackDirty = true; // force re-stacking of all items next redraw - this.body.emitter.emit('change'); - }; + var scaleFrac = scale / scaleOld; + var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac; + var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac; - /** - * Handle added items - * @param {Number[]} ids - * @protected - */ - ItemSet.prototype._onAdd = ItemSet.prototype._onUpdate; + this.areaCenter = {"x" : this._XconvertDOMtoCanvas(pointer.x), + "y" : this._YconvertDOMtoCanvas(pointer.y)}; - /** - * Handle removed items - * @param {Number[]} ids - * @protected - */ - ItemSet.prototype._onRemove = function(ids) { - var count = 0; - var me = this; - ids.forEach(function (id) { - var item = me.items[id]; - if (item) { - count++; - me._removeItem(item); + this._setScale(scale); + this._setTranslation(tx, ty); + this.updateClustersDefault(); + + if (preScaleDragPointer != null) { + var postScaleDragPointer = this.canvasToDOM(preScaleDragPointer); + this.drag.pointer.x = postScaleDragPointer.x; + this.drag.pointer.y = postScaleDragPointer.y; } - }); - if (count) { - // update order - this._order(); - this.stackDirty = true; // force re-stacking of all items next redraw - this.body.emitter.emit('change'); + this._redraw(); + + if (scaleOld < scale) { + this.emit("zoom", {direction:"+"}); + } + else { + this.emit("zoom", {direction:"-"}); + } + + return scale; } }; - /** - * Update the order of item in all groups - * @private - */ - ItemSet.prototype._order = function() { - // reorder the items in all groups - // TODO: optimization: only reorder groups affected by the changed items - util.forEach(this.groups, function (group) { - group.order(); - }); - }; /** - * Handle updated groups - * @param {Number[]} ids + * Event handler for mouse wheel event, used to zoom the timeline + * See http://adomas.org/javascript-mouse-wheel/ + * https://github.com/EightMedia/hammer.js/issues/256 + * @param {MouseEvent} event * @private */ - ItemSet.prototype._onUpdateGroups = function(ids) { - this._onAddGroups(ids); + Network.prototype._onMouseWheel = function(event) { + // retrieve delta + var delta = 0; + if (event.wheelDelta) { /* IE/Opera. */ + delta = event.wheelDelta/120; + } else if (event.detail) { /* Mozilla case. */ + // In Mozilla, sign of delta is different than in IE. + // Also, delta is multiple of 3. + delta = -event.detail/3; + } + + // If delta is nonzero, handle it. + // Basically, delta is now positive if wheel was scrolled up, + // and negative, if wheel was scrolled down. + if (delta) { + + // calculate the new scale + var scale = this._getScale(); + var zoom = delta / 10; + if (delta < 0) { + zoom = zoom / (1 - zoom); + } + scale *= (1 + zoom); + + // calculate the pointer location + var gesture = hammerUtil.fakeGesture(this, event); + var pointer = this._getPointer(gesture.center); + + // apply the new scale + this._zoom(scale, pointer); + } + + // Prevent default actions caused by mouse wheel. + event.preventDefault(); }; + /** - * Handle changed groups - * @param {Number[]} ids + * Mouse move handler for checking whether the title moves over a node with a title. + * @param {Event} event * @private */ - ItemSet.prototype._onAddGroups = function(ids) { - var me = this; - - ids.forEach(function (id) { - var groupData = me.groupsData.get(id); - var group = me.groups[id]; + Network.prototype._onMouseMoveTitle = function (event) { + var gesture = hammerUtil.fakeGesture(this, event); + var pointer = this._getPointer(gesture.center); - if (!group) { - // check for reserved ids - if (id == UNGROUPED || id == BACKGROUND) { - throw new Error('Illegal group id. ' + id + ' is a reserved id.'); - } + // check if the previously selected node is still selected + if (this.popupObj) { + this._checkHidePopup(pointer); + } - var groupOptions = Object.create(me.options); - util.extend(groupOptions, { - height: null - }); + // start a timeout that will check if the mouse is positioned above + // an element + var me = this; + var checkShow = function() { + me._checkShowPopup(pointer); + }; + if (this.popupTimer) { + clearInterval(this.popupTimer); // stop any running calculationTimer + } + if (!this.drag.dragging) { + this.popupTimer = setTimeout(checkShow, this.constants.tooltip.delay); + } - group = new Group(id, groupData, me); - me.groups[id] = group; - // add items with this groupId to the new group - for (var itemId in me.items) { - if (me.items.hasOwnProperty(itemId)) { - var item = me.items[itemId]; - if (item.data.group == id) { - group.add(item); - } - } + /** + * Adding hover highlights + */ + if (this.constants.hover == true) { + // removing all hover highlights + for (var edgeId in this.hoverObj.edges) { + if (this.hoverObj.edges.hasOwnProperty(edgeId)) { + this.hoverObj.edges[edgeId].hover = false; + delete this.hoverObj.edges[edgeId]; } + } - group.order(); - group.show(); + // adding hover highlights + var obj = this._getNodeAt(pointer); + if (obj == null) { + obj = this._getEdgeAt(pointer); } - else { - // update group - group.setData(groupData); + if (obj != null) { + this._hoverObject(obj); } - }); - this.body.emitter.emit('change'); + // removing all node hover highlights except for the selected one. + for (var nodeId in this.hoverObj.nodes) { + if (this.hoverObj.nodes.hasOwnProperty(nodeId)) { + if (obj instanceof Node && obj.id != nodeId || obj instanceof Edge || obj == null) { + this._blurObject(this.hoverObj.nodes[nodeId]); + delete this.hoverObj.nodes[nodeId]; + } + } + } + this.redraw(); + } }; /** - * Handle removed groups - * @param {Number[]} ids + * Check if there is an element on the given position in the network + * (a node or edge). If so, and if this element has a title, + * show a popup window with its title. + * + * @param {{x:Number, y:Number}} pointer * @private */ - ItemSet.prototype._onRemoveGroups = function(ids) { - var groups = this.groups; - ids.forEach(function (id) { - var group = groups[id]; + Network.prototype._checkShowPopup = function (pointer) { + var obj = { + left: this._XconvertDOMtoCanvas(pointer.x), + top: this._YconvertDOMtoCanvas(pointer.y), + right: this._XconvertDOMtoCanvas(pointer.x), + bottom: this._YconvertDOMtoCanvas(pointer.y) + }; - if (group) { - group.hide(); - delete groups[id]; + var id; + var lastPopupNode = this.popupObj; + + if (this.popupObj == undefined) { + // search the nodes for overlap, select the top one in case of multiple nodes + var nodes = this.nodes; + for (id in nodes) { + if (nodes.hasOwnProperty(id)) { + var node = nodes[id]; + if (node.getTitle() !== undefined && node.isOverlappingWith(obj)) { + this.popupObj = node; + break; + } + } } - }); + } - this.markDirty(); + if (this.popupObj === undefined) { + // search the edges for overlap + var edges = this.edges; + for (id in edges) { + if (edges.hasOwnProperty(id)) { + var edge = edges[id]; + if (edge.connected && (edge.getTitle() !== undefined) && + edge.isOverlappingWith(obj)) { + this.popupObj = edge; + break; + } + } + } + } - this.body.emitter.emit('change'); + if (this.popupObj) { + // show popup message window + if (this.popupObj != lastPopupNode) { + var me = this; + if (!me.popup) { + me.popup = new Popup(me.frame, me.constants.tooltip); + } + + // adjust a small offset such that the mouse cursor is located in the + // bottom left location of the popup, and you can easily move over the + // popup area + me.popup.setPosition(pointer.x - 3, pointer.y - 3); + me.popup.setText(me.popupObj.getTitle()); + me.popup.show(); + } + } + else { + if (this.popup) { + this.popup.hide(); + } + } }; + /** - * Reorder the groups if needed - * @return {boolean} changed + * Check if the popup must be hided, which is the case when the mouse is no + * longer hovering on the object + * @param {{x:Number, y:Number}} pointer * @private */ - ItemSet.prototype._orderGroups = function () { - if (this.groupsData) { - // reorder the groups - var groupIds = this.groupsData.getIds({ - order: this.options.groupOrder - }); + Network.prototype._checkHidePopup = function (pointer) { + if (!this.popupObj || !this._getNodeAt(pointer) ) { + this.popupObj = undefined; + if (this.popup) { + this.popup.hide(); + } + } + }; - var changed = !util.equalArray(groupIds, this.groupIds); - if (changed) { - // hide all groups, removes them from the DOM - var groups = this.groups; - groupIds.forEach(function (groupId) { - groups[groupId].hide(); - }); - // show the groups again, attach them to the DOM in correct order - groupIds.forEach(function (groupId) { - groups[groupId].show(); - }); + /** + * Set a new size for the network + * @param {string} width Width in pixels or percentage (for example '800px' + * or '50%') + * @param {string} height Height in pixels or percentage (for example '400px' + * or '30%') + */ + Network.prototype.setSize = function(width, height) { + var emitEvent = false; + var oldWidth = this.frame.canvas.width; + var oldHeight = this.frame.canvas.height; + if (width != this.constants.width || height != this.constants.height || this.frame.style.width != width || this.frame.style.height != height) { + this.frame.style.width = width; + this.frame.style.height = height; - this.groupIds = groupIds; - } + this.frame.canvas.style.width = '100%'; + this.frame.canvas.style.height = '100%'; - return changed; + this.frame.canvas.width = this.frame.canvas.clientWidth; + this.frame.canvas.height = this.frame.canvas.clientHeight; + + this.constants.width = width; + this.constants.height = height; + + emitEvent = true; } else { - return false; + // this would adapt the width of the canvas to the width from 100% if and only if + // there is a change. + + if (this.frame.canvas.width != this.frame.canvas.clientWidth) { + this.frame.canvas.width = this.frame.canvas.clientWidth; + emitEvent = true; + } + if (this.frame.canvas.height != this.frame.canvas.clientHeight) { + this.frame.canvas.height = this.frame.canvas.clientHeight; + emitEvent = true; + } + } + + if (emitEvent == true) { + this.emit('resize', {width:this.frame.canvas.width,height:this.frame.canvas.height, oldWidth: oldWidth, oldHeight: oldHeight}); } }; /** - * Add a new item - * @param {Item} item + * Set a data set with nodes for the network + * @param {Array | DataSet | DataView} nodes The data containing the nodes. * @private */ - ItemSet.prototype._addItem = function(item) { - this.items[item.id] = item; + Network.prototype._setNodes = function(nodes) { + var oldNodesData = this.nodesData; - // add to group - var groupId = this._getGroupId(item.data); - var group = this.groups[groupId]; - if (group) group.add(item); - }; + if (nodes instanceof DataSet || nodes instanceof DataView) { + this.nodesData = nodes; + } + else if (Array.isArray(nodes)) { + this.nodesData = new DataSet(); + this.nodesData.add(nodes); + } + else if (!nodes) { + this.nodesData = new DataSet(); + } + else { + throw new TypeError('Array or DataSet expected'); + } - /** - * Update an existing item - * @param {Item} item - * @param {Object} itemData - * @private - */ - ItemSet.prototype._updateItem = function(item, itemData) { - var oldGroupId = item.data.group; + if (oldNodesData) { + // unsubscribe from old dataset + util.forEach(this.nodesListeners, function (callback, event) { + oldNodesData.off(event, callback); + }); + } - // update the items data (will redraw the item when displayed) - item.setData(itemData); + // remove drawn nodes + this.nodes = {}; - // update group - if (oldGroupId != item.data.group) { - var oldGroup = this.groups[oldGroupId]; - if (oldGroup) oldGroup.remove(item); + if (this.nodesData) { + // subscribe to new dataset + var me = this; + util.forEach(this.nodesListeners, function (callback, event) { + me.nodesData.on(event, callback); + }); - var groupId = this._getGroupId(item.data); - var group = this.groups[groupId]; - if (group) group.add(item); + // draw all new nodes + var ids = this.nodesData.getIds(); + this._addNodes(ids); } + this._updateSelection(); }; /** - * Delete an item from the ItemSet: remove it from the DOM, from the map - * with items, and from the map with visible items, and from the selection - * @param {Item} item + * Add nodes + * @param {Number[] | String[]} ids * @private */ - ItemSet.prototype._removeItem = function(item) { - // remove from DOM - item.hide(); - - // remove from items - delete this.items[item.id]; - - // remove from selection - var index = this.selection.indexOf(item.id); - if (index != -1) this.selection.splice(index, 1); + Network.prototype._addNodes = function(ids) { + var id; + for (var i = 0, len = ids.length; i < len; i++) { + id = ids[i]; + var data = this.nodesData.get(id); + var node = new Node(data, this.images, this.groups, this.constants); + this.nodes[id] = node; // note: this may replace an existing node + if ((node.xFixed == false || node.yFixed == false) && (node.x === null || node.y === null)) { + var radius = 10 * 0.1*ids.length + 10; + 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.moving = true; + } - // remove from group - item.parent && item.parent.remove(item); + this._updateNodeIndexList(); + if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { + this._resetLevels(); + this._setupHierarchicalLayout(); + } + this._updateCalculationNodes(); + this._reconnectEdges(); + this._updateValueRange(this.nodes); + this.updateLabels(); }; /** - * Create an array containing all items being a range (having an end date) - * @param array - * @returns {Array} + * Update existing nodes, or create them when not yet existing + * @param {Number[] | String[]} ids * @private */ - ItemSet.prototype._constructByEndArray = function(array) { - var endArray = []; - - for (var i = 0; i < array.length; i++) { - if (array[i] instanceof RangeItem) { - endArray.push(array[i]); + Network.prototype._updateNodes = function(ids,changedData) { + var nodes = this.nodes; + for (var i = 0, len = ids.length; i < len; i++) { + var id = ids[i]; + var node = nodes[id]; + var data = changedData[i]; + if (node) { + // update node + node.setProperties(data, this.constants); + } + else { + // create node + node = new Node(properties, this.images, this.groups, this.constants); + nodes[id] = node; } } - return endArray; + this.moving = true; + if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { + this._resetLevels(); + this._setupHierarchicalLayout(); + } + this._updateNodeIndexList(); + this._updateValueRange(nodes); }; /** - * Register the clicked item on touch, before dragStart is initiated. - * - * dragStart is initiated from a mousemove event, which can have left the item - * already resulting in an item == null - * - * @param {Event} event + * Remove existing nodes. If nodes do not exist, the method will just ignore it. + * @param {Number[] | String[]} ids * @private */ - ItemSet.prototype._onTouch = function (event) { - // store the touched item, used in _onDragStart - this.touchParams.item = ItemSet.itemFromTarget(event); + Network.prototype._removeNodes = function(ids) { + var nodes = this.nodes; + for (var i = 0, len = ids.length; i < len; i++) { + var id = ids[i]; + delete nodes[id]; + } + this._updateNodeIndexList(); + if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { + this._resetLevels(); + this._setupHierarchicalLayout(); + } + this._updateCalculationNodes(); + this._reconnectEdges(); + this._updateSelection(); + this._updateValueRange(nodes); }; /** - * Start dragging the selected events - * @param {Event} event + * Load edges by reading the data table + * @param {Array | DataSet | DataView} edges The data containing the edges. + * @private * @private */ - ItemSet.prototype._onDragStart = function (event) { - if (!this.options.editable.updateTime && !this.options.editable.updateGroup) { - return; - } - - var item = this.touchParams.item || null; - var me = this; - var props = {}; - - props.initialX = event.gesture.center.clientX; - if (item && item.selected) { - var dragLeftItem = event.target.dragLeftItem; - var dragRightItem = event.target.dragRightItem; - - if (dragLeftItem) { - props.item = dragLeftItem; - - if (me.options.editable.updateTime) { - props.start = item.data.start.valueOf(); - } - if (me.options.editable.updateGroup) { - if ('group' in item.data) props.group = item.data.group; - } - - this.touchParams.itemProps = [props]; - } - else if (dragRightItem) { - props.item = dragRightItem; + Network.prototype._setEdges = function(edges) { + var oldEdgesData = this.edgesData; - if (me.options.editable.updateTime) { - props.end = item.data.end.valueOf(); - } - if (me.options.editable.updateGroup) { - if ('group' in item.data) props.group = item.data.group; - } + if (edges instanceof DataSet || edges instanceof DataView) { + this.edgesData = edges; + } + else if (Array.isArray(edges)) { + this.edgesData = new DataSet(); + this.edgesData.add(edges); + } + else if (!edges) { + this.edgesData = new DataSet(); + } + else { + throw new TypeError('Array or DataSet expected'); + } - this.touchParams.itemProps = [props]; - } - else { - this.touchParams.itemProps = this.getSelection().map(function (id) { - var item = me.items[id]; - props.item = item; + if (oldEdgesData) { + // unsubscribe from old dataset + util.forEach(this.edgesListeners, function (callback, event) { + oldEdgesData.off(event, callback); + }); + } - if (me.options.editable.updateTime) { - if ('start' in item.data) props.start = item.data.start.valueOf(); - if ('end' in item.data) props.end = item.data.end.valueOf(); - } - if (me.options.editable.updateGroup) { - if ('group' in item.data) props.group = item.data.group; - } + // remove drawn edges + this.edges = {}; - return props; - }); - } + if (this.edgesData) { + // subscribe to new dataset + var me = this; + util.forEach(this.edgesListeners, function (callback, event) { + me.edgesData.on(event, callback); + }); - event.stopPropagation(); + // draw all new nodes + var ids = this.edgesData.getIds(); + this._addEdges(ids); } + + this._reconnectEdges(); }; /** - * Drag selected items - * @param {Event} event + * Add edges + * @param {Number[] | String[]} ids * @private */ - ItemSet.prototype._onDrag = function (event) { - if (this.touchParams.itemProps) { - var me = this; - var snap = this.body.util.snap || null; - var xOffset = this.body.dom.root.offsetLeft + this.body.domProps.left.width; - - // move - this.touchParams.itemProps.forEach(function (props) { - var newProps = {}; - if ('start' in props && !('end' in props)) { // only start in props - var start = me.body.util.toTime(event.gesture.center.clientX - xOffset); - newProps.start = snap ? snap(start) : start; - } - else if ('start' in props) { // start and end in props - var current = me.body.util.toTime(event.gesture.center.clientX - xOffset); - var initial = me.body.util.toTime(props.initialX - xOffset); - var offset = current - initial; - var start = new Date(props.start + offset); - var end = new Date(props.end + offset); - - newProps.start = snap ? snap(start) : start; - newProps.end = snap ? snap(end) : end; - } - else if ('end' in props) { // only end in props - var end = me.body.util.toTime(event.gesture.center.clientX - xOffset); - newProps.end = snap ? snap(end) : end; - } - - if ('group' in props) { - // drag from one group to another - var group = ItemSet.groupFromTarget(event); - newProps.group = group && group.groupId; - } + Network.prototype._addEdges = function (ids) { + var edges = this.edges, + edgesData = this.edgesData; - // confirm moving the item - var itemData = util.extend({}, props.item.data, newProps); - me.options.onMoving(itemData, function (itemData) { - if (itemData) { - me._updateItemProps(props.item, itemData); - } - }); - }); + for (var i = 0, len = ids.length; i < len; i++) { + var id = ids[i]; - this.stackDirty = true; // force re-stacking of all items next redraw - this.body.emitter.emit('change'); + var oldEdge = edges[id]; + if (oldEdge) { + oldEdge.disconnect(); + } - event.stopPropagation(); + var data = edgesData.get(id, {"showInternalIds" : true}); + edges[id] = new Edge(data, this, this.constants); + } + this.moving = true; + this._updateValueRange(edges); + this._createBezierNodes(); + this._updateCalculationNodes(); + if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { + this._resetLevels(); + this._setupHierarchicalLayout(); } }; /** - * Update an items properties - * @param {Item} item - * @param {Object} props Can contain properties start, end, and group. + * Update existing edges, or create them when not yet existing + * @param {Number[] | String[]} ids * @private */ - ItemSet.prototype._updateItemProps = function(item, props) { - // TODO: copy all properties from props to item? (also new ones) - if ('start' in props) item.data.start = props.start; - if ('end' in props) item.data.end = props.end; - if ('group' in props && item.data.group != props.group) { - this._moveToGroup(item, props.group) + Network.prototype._updateEdges = function (ids) { + var edges = this.edges, + edgesData = this.edgesData; + for (var i = 0, len = ids.length; i < len; i++) { + var id = ids[i]; + + var data = edgesData.get(id); + var edge = edges[id]; + if (edge) { + // update edge + edge.disconnect(); + edge.setProperties(data, this.constants); + edge.connect(); + } + else { + // create edge + edge = new Edge(data, this, this.constants); + this.edges[id] = edge; + } } + + this._createBezierNodes(); + if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { + this._resetLevels(); + this._setupHierarchicalLayout(); + } + this.moving = true; + this._updateValueRange(edges); }; /** - * Move an item to another group - * @param {Item} item - * @param {String | Number} groupId + * Remove existing edges. Non existing ids will be ignored + * @param {Number[] | String[]} ids * @private */ - ItemSet.prototype._moveToGroup = function(item, groupId) { - var group = this.groups[groupId]; - if (group && group.groupId != item.data.group) { - var oldGroup = item.parent; - oldGroup.remove(item); - oldGroup.order(); - group.add(item); - group.order(); + Network.prototype._removeEdges = function (ids) { + var edges = this.edges; + for (var i = 0, len = ids.length; i < len; i++) { + var id = ids[i]; + var edge = edges[id]; + if (edge) { + if (edge.via != null) { + delete this.sectors['support']['nodes'][edge.via.id]; + } + edge.disconnect(); + delete edges[id]; + } + } - item.data.group = group.groupId; + this.moving = true; + this._updateValueRange(edges); + if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { + this._resetLevels(); + this._setupHierarchicalLayout(); } + this._updateCalculationNodes(); }; /** - * End of dragging selected items - * @param {Event} event + * Reconnect all edges * @private */ - ItemSet.prototype._onDragEnd = function (event) { - if (this.touchParams.itemProps) { - // prepare a change set for the changed items - var changes = [], - me = this, - dataset = this.itemsData.getDataSet(); - - var itemProps = this.touchParams.itemProps ; - this.touchParams.itemProps = null; - itemProps.forEach(function (props) { - var id = props.item.id, - itemData = me.itemsData.get(id, me.itemOptions); - - var changed = false; - if ('start' in props.item.data) { - changed = (props.start != props.item.data.start.valueOf()); - itemData.start = util.convert(props.item.data.start, - dataset._options.type && dataset._options.type.start || 'Date'); - } - if ('end' in props.item.data) { - changed = changed || (props.end != props.item.data.end.valueOf()); - itemData.end = util.convert(props.item.data.end, - dataset._options.type && dataset._options.type.end || 'Date'); - } - if ('group' in props.item.data) { - changed = changed || (props.group != props.item.data.group); - itemData.group = props.item.data.group; - } - - // only apply changes when start or end is actually changed - if (changed) { - me.options.onMove(itemData, function (itemData) { - if (itemData) { - // apply changes - itemData[dataset._fieldId] = id; // ensure the item contains its id (can be undefined) - changes.push(itemData); - } - else { - // restore original values - me._updateItemProps(props.item, props); - - me.stackDirty = true; // force re-stacking of all items next redraw - me.body.emitter.emit('change'); - } - }); - } - }); - - // apply the changes to the data (if there are changes) - if (changes.length) { - dataset.update(changes); + Network.prototype._reconnectEdges = function() { + var id, + nodes = this.nodes, + edges = this.edges; + for (id in nodes) { + if (nodes.hasOwnProperty(id)) { + nodes[id].edges = []; + nodes[id].dynamicEdges = []; } + } - event.stopPropagation(); + for (id in edges) { + if (edges.hasOwnProperty(id)) { + var edge = edges[id]; + edge.from = null; + edge.to = null; + edge.connect(); + } } }; /** - * Handle selecting/deselecting an item when tapping it - * @param {Event} event + * Update the values of all object in the given array according to the current + * value range of the objects in the array. + * @param {Object} obj An object containing a set of Edges or Nodes + * The objects must have a method getValue() and + * setValueRange(min, max). * @private */ - ItemSet.prototype._onSelectItem = function (event) { - if (!this.options.selectable) return; + Network.prototype._updateValueRange = function(obj) { + var id; - var ctrlKey = event.gesture.srcEvent && event.gesture.srcEvent.ctrlKey; - var shiftKey = event.gesture.srcEvent && event.gesture.srcEvent.shiftKey; - if (ctrlKey || shiftKey) { - this._onMultiSelectItem(event); - return; + // determine the range of the objects + var valueMin = undefined; + var valueMax = undefined; + for (id in obj) { + if (obj.hasOwnProperty(id)) { + var value = obj[id].getValue(); + if (value !== undefined) { + valueMin = (valueMin === undefined) ? value : Math.min(value, valueMin); + valueMax = (valueMax === undefined) ? value : Math.max(value, valueMax); + } + } } - var oldSelection = this.getSelection(); - - var item = ItemSet.itemFromTarget(event); - var selection = item ? [item.id] : []; - this.setSelection(selection); - - var newSelection = this.getSelection(); - - // emit a select event, - // except when old selection is empty and new selection is still empty - if (newSelection.length > 0 || oldSelection.length > 0) { - this.body.emitter.emit('select', { - items: this.getSelection() - }); + // adjust the range of all objects + if (valueMin !== undefined && valueMax !== undefined) { + for (id in obj) { + if (obj.hasOwnProperty(id)) { + obj[id].setValueRange(valueMin, valueMax); + } + } } }; /** - * Handle creation and updates of an item on double tap - * @param event + * Redraw the network with the current data + * chart will be resized too. + */ + Network.prototype.redraw = function() { + this.setSize(this.constants.width, this.constants.height); + this._redraw(); + }; + + /** + * Redraw the network with the current data * @private */ - ItemSet.prototype._onAddItem = function (event) { - if (!this.options.selectable) return; - if (!this.options.editable.add) return; + Network.prototype._redraw = function() { + var ctx = this.frame.canvas.getContext('2d'); + // clear the canvas + var w = this.frame.canvas.width; + var h = this.frame.canvas.height; + ctx.clearRect(0, 0, w, h); - var me = this, - snap = this.body.util.snap || null, - item = ItemSet.itemFromTarget(event); + // set scaling and translation + ctx.save(); + ctx.translate(this.translation.x, this.translation.y); + ctx.scale(this.scale, this.scale); - if (item) { - // update item + this.canvasTopLeft = { + "x": this._XconvertDOMtoCanvas(0), + "y": this._YconvertDOMtoCanvas(0) + }; + this.canvasBottomRight = { + "x": this._XconvertDOMtoCanvas(this.frame.canvas.clientWidth), + "y": this._YconvertDOMtoCanvas(this.frame.canvas.clientHeight) + }; - // execute async handler to update the item (or cancel it) - var itemData = me.itemsData.get(item.id); // get a clone of the data from the dataset - this.options.onUpdate(itemData, function (itemData) { - if (itemData) { - me.itemsData.update(itemData); - } - }); + + this._doInAllSectors("_drawAllSectorNodes",ctx); + if (this.drag.dragging == false || this.drag.dragging === undefined || this.constants.hideEdgesOnDrag == false) { + this._doInAllSectors("_drawEdges",ctx); } - else { - // add item - var xAbs = util.getAbsoluteLeft(this.dom.frame); - var x = event.gesture.center.pageX - xAbs; - var start = this.body.util.toTime(x); - var newItem = { - start: snap ? snap(start) : start, - content: 'new item' - }; - // when default type is a range, add a default end date to the new item - if (this.options.type === 'range') { - var end = this.body.util.toTime(x + this.props.width / 5); - newItem.end = snap ? snap(end) : end; - } + if (this.drag.dragging == false || this.drag.dragging === undefined || this.constants.hideNodesOnDrag == false) { + this._doInAllSectors("_drawNodes",ctx,false); + } - newItem[this.itemsData._fieldId] = util.randomUUID(); + if (this.controlNodesActive == true) { + this._doInAllSectors("_drawControlNodes",ctx); + } - var group = ItemSet.groupFromTarget(event); - if (group) { - newItem.group = group.groupId; - } + // this._doInSupportSector("_drawNodes",ctx,true); + // this._drawTree(ctx,"#F00F0F"); - // execute async handler to customize (or cancel) adding an item - this.options.onAdd(newItem, function (item) { - if (item) { - me.itemsData.add(item); - // TODO: need to trigger a redraw? - } - }); - } + // restore original scaling and translation + ctx.restore(); }; /** - * Handle selecting/deselecting multiple items when holding an item - * @param {Event} event + * Set the translation of the network + * @param {Number} offsetX Horizontal offset + * @param {Number} offsetY Vertical offset * @private */ - ItemSet.prototype._onMultiSelectItem = function (event) { - if (!this.options.selectable) return; - - var selection, - item = ItemSet.itemFromTarget(event); - - if (item) { - // multi select items - selection = this.getSelection(); // current selection - var index = selection.indexOf(item.id); - if (index == -1) { - // item is not yet selected -> select it - selection.push(item.id); - } - else { - // item is already selected -> deselect it - selection.splice(index, 1); - } - this.setSelection(selection); + Network.prototype._setTranslation = function(offsetX, offsetY) { + if (this.translation === undefined) { + this.translation = { + x: 0, + y: 0 + }; + } - this.body.emitter.emit('select', { - items: this.getSelection() - }); + if (offsetX !== undefined) { + this.translation.x = offsetX; + } + if (offsetY !== undefined) { + this.translation.y = offsetY; } + + this.emit('viewChanged'); }; /** - * Find an item from an event target: - * searches for the attribute 'timeline-item' in the event target's element tree - * @param {Event} event - * @return {Item | null} item + * Get the translation of the network + * @return {Object} translation An object with parameters x and y, both a number + * @private */ - ItemSet.itemFromTarget = function(event) { - var target = event.target; - while (target) { - if (target.hasOwnProperty('timeline-item')) { - return target['timeline-item']; - } - target = target.parentNode; - } - - return null; + Network.prototype._getTranslation = function() { + return { + x: this.translation.x, + y: this.translation.y + }; }; /** - * Find the Group from an event target: - * searches for the attribute 'timeline-group' in the event target's element tree - * @param {Event} event - * @return {Group | null} group + * Scale the network + * @param {Number} scale Scaling factor 1.0 is unscaled + * @private */ - ItemSet.groupFromTarget = function(event) { - var target = event.target; - while (target) { - if (target.hasOwnProperty('timeline-group')) { - return target['timeline-group']; - } - target = target.parentNode; - } - - return null; + Network.prototype._setScale = function(scale) { + this.scale = scale; }; /** - * Find the ItemSet from an event target: - * searches for the attribute 'timeline-itemset' in the event target's element tree - * @param {Event} event - * @return {ItemSet | null} item + * Get the current scale of the network + * @return {Number} scale Scaling factor 1.0 is unscaled + * @private */ - ItemSet.itemSetFromTarget = function(event) { - var target = event.target; - while (target) { - if (target.hasOwnProperty('timeline-itemset')) { - return target['timeline-itemset']; - } - target = target.parentNode; - } - - return null; + Network.prototype._getScale = function() { + return this.scale; }; - module.exports = ItemSet; - - -/***/ }, -/* 31 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(1); - var stack = __webpack_require__(32); - var RangeItem = __webpack_require__(33); - /** - * @constructor Group - * @param {Number | String} groupId - * @param {Object} data - * @param {ItemSet} itemSet + * Convert the X coordinate in DOM-space (coordinate point in browser relative to the container div) to + * the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon) + * @param {number} x + * @returns {number} + * @private */ - function Group (groupId, data, itemSet) { - this.groupId = groupId; - this.subgroups = {}; - this.subgroupIndex = 0; - this.subgroupOrderer = data && data.subgroupOrder; - this.itemSet = itemSet; - - this.dom = {}; - this.props = { - label: { - width: 0, - height: 0 - } - }; - this.className = null; - - this.items = {}; // items filtered by groupId of this group - this.visibleItems = []; // items currently visible in window - this.orderedItems = { // items sorted by start and by end - byStart: [], - byEnd: [] - }; - - this._create(); - - this.setData(data); - } + Network.prototype._XconvertDOMtoCanvas = function(x) { + return (x - this.translation.x) / this.scale; + }; /** - * Create DOM elements for the group + * Convert the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to + * the X coordinate in DOM-space (coordinate point in browser relative to the container div) + * @param {number} x + * @returns {number} * @private */ - Group.prototype._create = function() { - var label = document.createElement('div'); - label.className = 'vlabel'; - this.dom.label = label; + Network.prototype._XconvertCanvasToDOM = function(x) { + return x * this.scale + this.translation.x; + }; - var inner = document.createElement('div'); - inner.className = 'inner'; - label.appendChild(inner); - this.dom.inner = inner; + /** + * Convert the Y coordinate in DOM-space (coordinate point in browser relative to the container div) to + * the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon) + * @param {number} y + * @returns {number} + * @private + */ + Network.prototype._YconvertDOMtoCanvas = function(y) { + return (y - this.translation.y) / this.scale; + }; - var foreground = document.createElement('div'); - foreground.className = 'group'; - foreground['timeline-group'] = this; - this.dom.foreground = foreground; + /** + * Convert the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to + * the Y coordinate in DOM-space (coordinate point in browser relative to the container div) + * @param {number} y + * @returns {number} + * @private + */ + Network.prototype._YconvertCanvasToDOM = function(y) { + return y * this.scale + this.translation.y ; + }; - this.dom.background = document.createElement('div'); - this.dom.background.className = 'group'; - this.dom.axis = document.createElement('div'); - this.dom.axis.className = 'group'; + /** + * + * @param {object} pos = {x: number, y: number} + * @returns {{x: number, y: number}} + * @constructor + */ + Network.prototype.canvasToDOM = function (pos) { + return {x: this._XconvertCanvasToDOM(pos.x), y: this._YconvertCanvasToDOM(pos.y)}; + }; - // create a hidden marker to detect when the Timelines container is attached - // to the DOM, or the style of a parent of the Timeline is changed from - // display:none is changed to visible. - this.dom.marker = document.createElement('div'); - this.dom.marker.style.visibility = 'hidden'; // TODO: ask jos why this is not none? - this.dom.marker.innerHTML = '?'; - this.dom.background.appendChild(this.dom.marker); + /** + * + * @param {object} pos = {x: number, y: number} + * @returns {{x: number, y: number}} + * @constructor + */ + Network.prototype.DOMtoCanvas = function (pos) { + return {x: this._XconvertDOMtoCanvas(pos.x), y: this._YconvertDOMtoCanvas(pos.y)}; }; /** - * Set the group data for this group - * @param {Object} data Group data, can contain properties content and className + * Redraw all nodes + * The 2d context of a HTML canvas can be retrieved by canvas.getContext('2d'); + * @param {CanvasRenderingContext2D} ctx + * @param {Boolean} [alwaysShow] + * @private */ - Group.prototype.setData = function(data) { - // update contents - var content = data && data.content; - if (content instanceof Element) { - this.dom.inner.appendChild(content); - } - else if (content !== undefined && content !== null) { - this.dom.inner.innerHTML = content; - } - else { - this.dom.inner.innerHTML = this.groupId || ''; // groupId can be null + Network.prototype._drawNodes = function(ctx,alwaysShow) { + if (alwaysShow === undefined) { + alwaysShow = false; } - // update title - this.dom.label.title = data && data.title || ''; + // first draw the unselected nodes + var nodes = this.nodes; + var selected = []; - if (!this.dom.inner.firstChild) { - util.addClassName(this.dom.inner, 'hidden'); - } - else { - util.removeClassName(this.dom.inner, 'hidden'); + for (var id in nodes) { + if (nodes.hasOwnProperty(id)) { + nodes[id].setScaleAndPos(this.scale,this.canvasTopLeft,this.canvasBottomRight); + if (nodes[id].isSelected()) { + selected.push(id); + } + else { + if (nodes[id].inArea() || alwaysShow) { + nodes[id].draw(ctx); + } + } + } } - // update className - var className = data && data.className || null; - if (className != this.className) { - if (this.className) { - util.removeClassName(this.dom.label, this.className); - util.removeClassName(this.dom.foreground, this.className); - util.removeClassName(this.dom.background, this.className); - util.removeClassName(this.dom.axis, this.className); + // draw the selected nodes on top + for (var s = 0, sMax = selected.length; s < sMax; s++) { + if (nodes[selected[s]].inArea() || alwaysShow) { + nodes[selected[s]].draw(ctx); } - util.addClassName(this.dom.label, className); - util.addClassName(this.dom.foreground, className); - util.addClassName(this.dom.background, className); - util.addClassName(this.dom.axis, className); - this.className = className; } + }; - // update style - if (this.style) { - util.removeCssText(this.dom.label, this.style); - this.style = null; - } - if (data && data.style) { - util.addCssText(this.dom.label, data.style); - this.style = data.style; + /** + * Redraw all edges + * The 2d context of a HTML canvas can be retrieved by canvas.getContext('2d'); + * @param {CanvasRenderingContext2D} ctx + * @private + */ + Network.prototype._drawEdges = function(ctx) { + var edges = this.edges; + for (var id in edges) { + if (edges.hasOwnProperty(id)) { + var edge = edges[id]; + edge.setScale(this.scale); + if (edge.connected) { + edges[id].draw(ctx); + } + } } }; /** - * Get the width of the group label - * @return {number} width + * Redraw all edges + * The 2d context of a HTML canvas can be retrieved by canvas.getContext('2d'); + * @param {CanvasRenderingContext2D} ctx + * @private */ - Group.prototype.getLabelWidth = function() { - return this.props.label.width; + Network.prototype._drawControlNodes = function(ctx) { + var edges = this.edges; + for (var id in edges) { + if (edges.hasOwnProperty(id)) { + edges[id]._drawControlNodes(ctx); + } + } }; - /** - * Repaint this group - * @param {{start: number, end: number}} range - * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin - * @param {boolean} [restack=false] Force restacking of all items - * @return {boolean} Returns true if the group is resized + * Find a stable position for all nodes + * @private */ - Group.prototype.redraw = function(range, margin, restack) { - var resized = false; - - this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range); - - // force recalculation of the height of the items when the marker height changed - // (due to the Timeline being attached to the DOM or changed from display:none to visible) - var markerHeight = this.dom.marker.clientHeight; - if (markerHeight != this.lastMarkerHeight) { - this.lastMarkerHeight = markerHeight; - - util.forEach(this.items, function (item) { - item.dirty = true; - if (item.displayed) item.redraw(); - }); - - restack = true; + Network.prototype._stabilize = function() { + if (this.constants.freezeForStabilization == true) { + this._freezeDefinedNodes(); } - // reposition visible items vertically - if (this.itemSet.options.stack) { // TODO: ugly way to access options... - stack.stack(this.visibleItems, margin, restack); + // find stable position + var count = 0; + while (this.moving && count < this.constants.stabilizationIterations) { + this._physicsTick(); + count++; } - else { // no stacking - stack.nostack(this.visibleItems, margin, this.subgroups); + this.zoomExtent(undefined,false,true); + if (this.constants.freezeForStabilization == true) { + this._restoreFrozenNodes(); } + }; - // recalculate the height of the group - var height = this._calculateHeight(margin); - - // calculate actual size and position - var foreground = this.dom.foreground; - this.top = foreground.offsetTop; - this.left = foreground.offsetLeft; - this.width = foreground.offsetWidth; - resized = util.updateProperty(this, 'height', height) || resized; + /** + * When initializing and stabilizing, we can freeze nodes with a predefined position. This greatly speeds up stabilization + * because only the supportnodes for the smoothCurves have to settle. + * + * @private + */ + Network.prototype._freezeDefinedNodes = function() { + var nodes = this.nodes; + for (var id in nodes) { + if (nodes.hasOwnProperty(id)) { + if (nodes[id].x != null && nodes[id].y != null) { + nodes[id].fixedData.x = nodes[id].xFixed; + nodes[id].fixedData.y = nodes[id].yFixed; + nodes[id].xFixed = true; + nodes[id].yFixed = true; + } + } + } + }; - // recalculate size of label - resized = util.updateProperty(this.props.label, 'width', this.dom.inner.clientWidth) || resized; - resized = util.updateProperty(this.props.label, 'height', this.dom.inner.clientHeight) || resized; + /** + * Unfreezes the nodes that have been frozen by _freezeDefinedNodes. + * + * @private + */ + Network.prototype._restoreFrozenNodes = function() { + var nodes = this.nodes; + for (var id in nodes) { + if (nodes.hasOwnProperty(id)) { + if (nodes[id].fixedData.x != null) { + nodes[id].xFixed = nodes[id].fixedData.x; + nodes[id].yFixed = nodes[id].fixedData.y; + } + } + } + }; - // apply new height - this.dom.background.style.height = height + 'px'; - this.dom.foreground.style.height = height + 'px'; - this.dom.label.style.height = height + 'px'; - // update vertical position of items after they are re-stacked and the height of the group is calculated - for (var i = 0, ii = this.visibleItems.length; i < ii; i++) { - var item = this.visibleItems[i]; - item.repositionY(margin); + /** + * Check if any of the nodes is still moving + * @param {number} vmin the minimum velocity considered as 'moving' + * @return {boolean} true if moving, false if non of the nodes is moving + * @private + */ + Network.prototype._isMoving = function(vmin) { + var nodes = this.nodes; + for (var id in nodes) { + if (nodes.hasOwnProperty(id) && nodes[id].isMoving(vmin)) { + return true; + } } - - return resized; + return false; }; + /** - * recalculate the height of the group - * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin - * @returns {number} Returns the height + * /** + * Perform one discrete step for all nodes + * * @private */ - Group.prototype._calculateHeight = function (margin) { - // recalculate the height of the group - var height; - var visibleItems = this.visibleItems; - //var visibleSubgroups = []; - //this.visibleSubgroups = 0; - this.resetSubgroups(); - var me = this; - if (visibleItems.length) { - var min = visibleItems[0].top; - var max = visibleItems[0].top + visibleItems[0].height; - util.forEach(visibleItems, function (item) { - min = Math.min(min, item.top); - max = Math.max(max, (item.top + item.height)); - if (item.data.subgroup !== undefined) { - me.subgroups[item.data.subgroup].height = Math.max(me.subgroups[item.data.subgroup].height,item.height); - me.subgroups[item.data.subgroup].visible = true; - //if (visibleSubgroups.indexOf(item.data.subgroup) == -1){ - // visibleSubgroups.push(item.data.subgroup); - // me.visibleSubgroups += 1; - //} + Network.prototype._discreteStepNodes = function() { + var interval = this.physicsDiscreteStepsize; + var nodes = this.nodes; + var nodeId; + var nodesPresent = false; + + if (this.constants.maxVelocity > 0) { + for (nodeId in nodes) { + if (nodes.hasOwnProperty(nodeId)) { + nodes[nodeId].discreteStepLimited(interval, this.constants.maxVelocity); + nodesPresent = true; } - }); - if (min > margin.axis) { - // there is an empty gap between the lowest item and the axis - var offset = min - margin.axis; - max -= offset; - util.forEach(visibleItems, function (item) { - item.top -= offset; - }); } - height = max + margin.item.vertical / 2; } else { - height = margin.axis + margin.item.vertical; + for (nodeId in nodes) { + if (nodes.hasOwnProperty(nodeId)) { + nodes[nodeId].discreteStep(interval); + nodesPresent = true; + } + } } - height = Math.max(height, this.props.label.height); - return height; + if (nodesPresent == true) { + var vminCorrected = this.constants.minVelocity / Math.max(this.scale,0.05); + if (vminCorrected > 0.5*this.constants.maxVelocity) { + return true; + } + else { + return this._isMoving(vminCorrected); + } + } + return false; }; /** - * Show this group: attach to the DOM + * A single simulation step (or "tick") in the physics simulation + * + * @private */ - Group.prototype.show = function() { - if (!this.dom.label.parentNode) { - this.itemSet.dom.labelSet.appendChild(this.dom.label); - } + Network.prototype._physicsTick = function() { + if (!this.freezeSimulation) { + if (this.moving == true) { + var mainMovingStatus = false; + var supportMovingStatus = false; - if (!this.dom.foreground.parentNode) { - this.itemSet.dom.foreground.appendChild(this.dom.foreground); - } + this._doInAllActiveSectors("_initializeForceCalculation"); + var mainMoving = this._doInAllActiveSectors("_discreteStepNodes"); + if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { + supportMovingStatus = this._doInSupportSector("_discreteStepNodes"); + } + // gather movement data from all sectors, if one moves, we are NOT stabilzied + for (var i = 0; i < mainMoving.length; i++) {mainMovingStatus = mainMoving[0] || mainMovingStatus;} - if (!this.dom.background.parentNode) { - this.itemSet.dom.background.appendChild(this.dom.background); - } + // determine if the network has stabilzied + this.moving = mainMovingStatus || supportMovingStatus; - if (!this.dom.axis.parentNode) { - this.itemSet.dom.axis.appendChild(this.dom.axis); + this.stabilizationIterations++; + } } }; + /** - * Hide this group: remove from the DOM + * This function runs one step of the animation. It calls an x amount of physics ticks and one render tick. + * It reschedules itself at the beginning of the function + * + * @private */ - Group.prototype.hide = function() { - var label = this.dom.label; - if (label.parentNode) { - label.parentNode.removeChild(label); - } - - var foreground = this.dom.foreground; - if (foreground.parentNode) { - foreground.parentNode.removeChild(foreground); - } + Network.prototype._animationStep = function() { + // reset the timer so a new scheduled animation step can be set + this.timer = undefined; + // handle the keyboad movement + this._handleNavigation(); - var background = this.dom.background; - if (background.parentNode) { - background.parentNode.removeChild(background); - } + // this schedules a new animation step + this.start(); - var axis = this.dom.axis; - if (axis.parentNode) { - axis.parentNode.removeChild(axis); + // start the physics simulation + var calculationTime = Date.now(); + var maxSteps = 1; + this._physicsTick(); + var timeRequired = Date.now() - calculationTime; + while (timeRequired < 0.9*(this.renderTimestep - this.renderTime) && maxSteps < this.maxPhysicsTicksPerRender) { + this._physicsTick(); + timeRequired = Date.now() - calculationTime; + maxSteps++; } + // start the rendering process + var renderTime = Date.now(); + this._redraw(); + this.renderTime = Date.now() - renderTime; }; + if (typeof window !== 'undefined') { + window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; + } + /** - * Add an item to the group - * @param {Item} item + * Schedule a animation step with the refreshrate interval. */ - Group.prototype.add = function(item) { - this.items[item.id] = item; - item.setParent(this); - - // add to - if (item.data.subgroup !== undefined) { - if (this.subgroups[item.data.subgroup] === undefined) { - this.subgroups[item.data.subgroup] = {height:0, visible: false, index:this.subgroupIndex, items: []}; - this.subgroupIndex++; + Network.prototype.start = function() { + if (this.moving == true || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) { + if (this.startedStabilization == false) { + this.emit("startStabilization"); + this.startedStabilization = true; } - this.subgroups[item.data.subgroup].items.push(item); - } - this.orderSubgroups(); - if (this.visibleItems.indexOf(item) == -1) { - var range = this.itemSet.body.range; // TODO: not nice accessing the range like this - this._checkIfVisible(item, this.visibleItems, range); - } - }; + if (!this.timer) { + var ua = navigator.userAgent.toLowerCase(); - Group.prototype.orderSubgroups = function() { - if (this.subgroupOrderer !== undefined) { - var sortArray = []; - if (typeof this.subgroupOrderer == 'string') { - for (var subgroup in this.subgroups) { - sortArray.push({subgroup: subgroup, sortField: this.subgroups[subgroup].items[0].data[this.subgroupOrderer]}) + var requiresTimeout = false; + if (ua.indexOf('msie 9.0') != -1) { // IE 9 + requiresTimeout = true; } - sortArray.sort(function (a, b) { - return a.sortField - b.sortField; - }) - } - else if (typeof this.subgroupOrderer == 'function') { - for (var subgroup in this.subgroups) { - sortArray.push(this.subgroups[subgroup].items[0].data); + else if (ua.indexOf('safari') != -1) { // safari + if (ua.indexOf('chrome') <= -1) { + requiresTimeout = true; + } } - sortArray.sort(this.subgroupOrderer); - } - if (sortArray.length > 0) { - for (var i = 0; i < sortArray.length; i++) { - this.subgroups[sortArray[i].subgroup].index = i; + if (requiresTimeout == true) { + this.timer = window.setTimeout(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function + } + else{ + this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function } } } - }; - - Group.prototype.resetSubgroups = function() { - for (var subgroup in this.subgroups) { - if (this.subgroups.hasOwnProperty(subgroup)) { - this.subgroups[subgroup].visible = false; + else { + this._redraw(); + if (this.stabilizationIterations > 0) { + // trigger the "stabilized" event. + // The event is triggered on the next tick, to prevent the case that + // it is fired while initializing the Network, in which case you would not + // be able to catch it + var me = this; + var params = { + iterations: me.stabilizationIterations + }; + me.stabilizationIterations = 0; + me.startedStabilization = false; + setTimeout(function () { + me.emit("stabilized", params); + }, 0); } } }; - /** - * Remove an item from the group - * @param {Item} item - */ - Group.prototype.remove = function(item) { - delete this.items[item.id]; - item.setParent(null); - - // remove from visible items - var index = this.visibleItems.indexOf(item); - if (index != -1) this.visibleItems.splice(index, 1); - - // TODO: also remove from ordered items? - }; /** - * Remove an item from the corresponding DataSet - * @param {Item} item + * Move the network according to the keyboard presses. + * + * @private */ - Group.prototype.removeFromDataSet = function(item) { - this.itemSet.removeItem(item.id); + Network.prototype._handleNavigation = function() { + if (this.xIncrement != 0 || this.yIncrement != 0) { + var translation = this._getTranslation(); + this._setTranslation(translation.x+this.xIncrement, translation.y+this.yIncrement); + } + if (this.zoomIncrement != 0) { + var center = { + x: this.frame.canvas.clientWidth / 2, + y: this.frame.canvas.clientHeight / 2 + }; + this._zoom(this.scale*(1 + this.zoomIncrement), center); + } }; - /** - * Reorder the items - */ - Group.prototype.order = function() { - var array = util.toArray(this.items); - this.orderedItems.byStart = array; - this.orderedItems.byEnd = this._constructByEndArray(array); - - stack.orderByStart(this.orderedItems.byStart); - stack.orderByEnd(this.orderedItems.byEnd); - }; /** - * Create an array containing all items being a range (having an end date) - * @param {Item[]} array - * @returns {RangeItem[]} - * @private + * Freeze the _animationStep */ - Group.prototype._constructByEndArray = function(array) { - var endArray = []; - - for (var i = 0; i < array.length; i++) { - if (array[i] instanceof RangeItem) { - endArray.push(array[i]); - } + Network.prototype.toggleFreeze = function() { + if (this.freezeSimulation == false) { + this.freezeSimulation = true; + } + else { + this.freezeSimulation = false; + this.start(); } - return endArray; }; + /** - * Update the visible items - * @param {{byStart: Item[], byEnd: Item[]}} orderedItems All items ordered by start date and by end date - * @param {Item[]} visibleItems The previously visible items. - * @param {{start: number, end: number}} range Visible range - * @return {Item[]} visibleItems The new visible items. + * This function cleans the support nodes if they are not needed and adds them when they are. + * + * @param {boolean} [disableStart] * @private */ - Group.prototype._updateVisibleItems = function(orderedItems, visibleItems, range) { - var initialPosByStart, - newVisibleItems = [], - i; - - // first check if the items that were in view previously are still in view. - // this handles the case for the RangeItem that is both before and after the current one. - if (visibleItems.length > 0) { - for (i = 0; i < visibleItems.length; i++) { - this._checkIfVisible(visibleItems[i], newVisibleItems, range); - } + Network.prototype._configureSmoothCurves = function(disableStart) { + if (disableStart === undefined) { + disableStart = true; } - - // If there were no visible items previously, use binarySearch to find a visible PointItem or RangeItem (based on startTime) - if (newVisibleItems.length == 0) { - initialPosByStart = util.binarySearch(orderedItems.byStart, range, 'data','start'); + if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { + this._createBezierNodes(); + // cleanup unused support nodes + for (var nodeId in this.sectors['support']['nodes']) { + if (this.sectors['support']['nodes'].hasOwnProperty(nodeId)) { + if (this.edges[this.sectors['support']['nodes'][nodeId].parentEdgeId] === undefined) { + delete this.sectors['support']['nodes'][nodeId]; + } + } + } } else { - initialPosByStart = orderedItems.byStart.indexOf(newVisibleItems[0]); - } - - // use visible search to find a visible RangeItem (only based on endTime) - var initialPosByEnd = util.binarySearch(orderedItems.byEnd, range, 'data','end'); - - // if we found a initial ID to use, trace it up and down until we meet an invisible item. - if (initialPosByStart != -1) { - for (i = initialPosByStart; i >= 0; i--) { - if (this._checkIfInvisible(orderedItems.byStart[i], newVisibleItems, range)) {break;} - } - for (i = initialPosByStart + 1; i < orderedItems.byStart.length; i++) { - if (this._checkIfInvisible(orderedItems.byStart[i], newVisibleItems, range)) {break;} + // delete the support nodes + this.sectors['support']['nodes'] = {}; + for (var edgeId in this.edges) { + if (this.edges.hasOwnProperty(edgeId)) { + this.edges[edgeId].via = null; + } } } - // if we found a initial ID to use, trace it up and down until we meet an invisible item. - if (initialPosByEnd != -1) { - for (i = initialPosByEnd; i >= 0; i--) { - if (this._checkIfInvisible(orderedItems.byEnd[i], newVisibleItems, range)) {break;} - } - for (i = initialPosByEnd + 1; i < orderedItems.byEnd.length; i++) { - if (this._checkIfInvisible(orderedItems.byEnd[i], newVisibleItems, range)) {break;} - } - } - return newVisibleItems; + this._updateCalculationNodes(); + if (!disableStart) { + this.moving = true; + this.start(); + } }; - /** - * this function checks if an item is invisible. If it is NOT we make it visible - * and add it to the global visible items. If it is, return true. + * Bezier curves require an anchor point to calculate the smooth flow. These points are nodes. These nodes are invisible but + * are used for the force calculation. * - * @param {Item} item - * @param {Item[]} visibleItems - * @param {{start:number, end:number}} range - * @returns {boolean} * @private */ - Group.prototype._checkIfInvisible = function(item, visibleItems, range) { - if (item.isVisible(range)) { - if (!item.displayed) item.show(); - item.repositionX(); - if (visibleItems.indexOf(item) == -1) { - visibleItems.push(item); + Network.prototype._createBezierNodes = function() { + if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { + for (var edgeId in this.edges) { + if (this.edges.hasOwnProperty(edgeId)) { + var edge = this.edges[edgeId]; + if (edge.via == null) { + var nodeId = "edgeId:".concat(edge.id); + this.sectors['support']['nodes'][nodeId] = new Node( + {id:nodeId, + mass:1, + shape:'circle', + image:"", + internalMultiplier:1 + },{},{},this.constants); + edge.via = this.sectors['support']['nodes'][nodeId]; + edge.via.parentEdgeId = edge.id; + edge.positionBezierNode(); + } } - return false; - } - else { - if (item.displayed) item.hide(); - return true; } + } }; /** - * this function is very similar to the _checkIfInvisible() but it does not - * return booleans, hides the item if it should not be seen and always adds to - * the visibleItems. - * this one is for brute forcing and hiding. + * load the functions that load the mixins into the prototype. * - * @param {Item} item - * @param {Array} visibleItems - * @param {{start:number, end:number}} range * @private */ - Group.prototype._checkIfVisible = function(item, visibleItems, range) { - if (item.isVisible(range)) { - if (!item.displayed) item.show(); - // reposition item horizontally - item.repositionX(); - visibleItems.push(item); - } - else { - if (item.displayed) item.hide(); + Network.prototype._initializeMixinLoaders = function () { + for (var mixin in MixinLoader) { + if (MixinLoader.hasOwnProperty(mixin)) { + Network.prototype[mixin] = MixinLoader[mixin]; } - }; - - module.exports = Group; - - -/***/ }, -/* 32 */ -/***/ function(module, exports, __webpack_require__) { - - // Utility functions for ordering and stacking of items - var EPSILON = 0.001; // used when checking collisions, to prevent round-off errors - - /** - * Order items by their start data - * @param {Item[]} items - */ - exports.orderByStart = function(items) { - items.sort(function (a, b) { - return a.data.start - b.data.start; - }); + } }; /** - * Order items by their end date. If they have no end date, their start date - * is used. - * @param {Item[]} items + * Load the XY positions of the nodes into the dataset. */ - exports.orderByEnd = function(items) { - items.sort(function (a, b) { - var aTime = ('end' in a.data) ? a.data.end : a.data.start, - bTime = ('end' in b.data) ? b.data.end : b.data.start; - - return aTime - bTime; - }); + Network.prototype.storePosition = function() { + console.log("storePosition is depricated: use .storePositions() from now on.") + this.storePositions(); }; /** - * Adjust vertical positions of the items such that they don't overlap each - * other. - * @param {Item[]} items - * All visible items - * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin - * Margins between items and between items and the axis. - * @param {boolean} [force=false] - * If true, all items will be repositioned. If false (default), only - * items having a top===null will be re-stacked + * Load the XY positions of the nodes into the dataset. */ - exports.stack = function(items, margin, force) { - var i, iMax; - - if (force) { - // reset top position of all items - for (i = 0, iMax = items.length; i < iMax; i++) { - items[i].top = null; - } - } - - // calculate new, non-overlapping positions - for (i = 0, iMax = items.length; i < iMax; i++) { - var item = items[i]; - if (item.stack && item.top === null) { - // initialize top position - item.top = margin.axis; - - do { - // TODO: optimize checking for overlap. when there is a gap without items, - // you only need to check for items from the next item on, not from zero - var collidingItem = null; - for (var j = 0, jj = items.length; j < jj; j++) { - var other = items[j]; - if (other.top !== null && other !== item && other.stack && exports.collision(item, other, margin.item)) { - collidingItem = other; - break; - } - } - - if (collidingItem != null) { - // There is a collision. Reposition the items above the colliding element - item.top = collidingItem.top + collidingItem.height + margin.item.vertical; - } - } while (collidingItem); + Network.prototype.storePositions = function() { + var dataArray = []; + for (var nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + var node = this.nodes[nodeId]; + var allowedToMoveX = !this.nodes.xFixed; + var allowedToMoveY = !this.nodes.yFixed; + if (this.nodesData._data[nodeId].x != Math.round(node.x) || this.nodesData._data[nodeId].y != Math.round(node.y)) { + dataArray.push({id:nodeId,x:Math.round(node.x),y:Math.round(node.y),allowedToMoveX:allowedToMoveX,allowedToMoveY:allowedToMoveY}); + } } } + this.nodesData.update(dataArray); }; - /** - * Adjust vertical positions of the items without stacking them - * @param {Item[]} items - * All visible items - * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin - * Margins between items and between items and the axis. + * Return the positions of the nodes. */ - exports.nostack = function(items, margin, subgroups) { - var i, iMax, newTop; - - // reset top position of all items - for (i = 0, iMax = items.length; i < iMax; i++) { - if (items[i].data.subgroup !== undefined) { - newTop = margin.axis; - for (var subgroup in subgroups) { - if (subgroups.hasOwnProperty(subgroup)) { - if (subgroups[subgroup].visible == true && subgroups[subgroup].index < subgroups[items[i].data.subgroup].index) { - newTop += subgroups[subgroup].height + margin.item.vertical; - } + Network.prototype.getPositions = function(ids) { + var dataArray = {}; + if (ids !== undefined) { + if (Array.isArray(ids) == true) { + for (var i = 0; i < ids.length; i++) { + if (this.nodes[ids[i]] !== undefined) { + var node = this.nodes[ids[i]]; + dataArray[ids[i]] = {x: Math.round(node.x), y: Math.round(node.y)}; } } - items[i].top = newTop; } else { - items[i].top = margin.axis; + if (this.nodes[ids] !== undefined) { + var node = this.nodes[ids]; + dataArray[ids] = {x: Math.round(node.x), y: Math.round(node.y)}; + } + } + } + else { + for (var nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + var node = this.nodes[nodeId]; + dataArray[nodeId] = {x: Math.round(node.x), y: Math.round(node.y)}; + } } } + return dataArray; }; + + /** - * Test if the two provided items collide - * The items must have parameters left, width, top, and height. - * @param {Item} a The first item - * @param {Item} b The second item - * @param {{horizontal: number, vertical: number}} margin - * An object containing a horizontal and vertical - * minimum required margin. - * @return {boolean} true if a and b collide, else false + * Center a node in view. + * + * @param {Number} nodeId + * @param {Number} [options] */ - exports.collision = function(a, b, margin) { - return ((a.left - margin.horizontal + EPSILON) < (b.left + b.width) && - (a.left + a.width + margin.horizontal - EPSILON) > b.left && - (a.top - margin.vertical + EPSILON) < (b.top + b.height) && - (a.top + a.height + margin.vertical - EPSILON) > b.top); - }; + Network.prototype.focusOnNode = function (nodeId, options) { + if (this.nodes.hasOwnProperty(nodeId)) { + if (options === undefined) { + options = {}; + } + var nodePosition = {x: this.nodes[nodeId].x, y: this.nodes[nodeId].y}; + options.position = nodePosition; + options.lockedOnNode = nodeId; + this.moveTo(options) + } + else { + console.log("This nodeId cannot be found."); + } + }; -/***/ }, -/* 33 */ -/***/ function(module, exports, __webpack_require__) { + /** + * + * @param {Object} options | options.offset = {x:Number, y:Number} // offset from the center in DOM pixels + * | options.scale = Number // scale to move to + * | options.position = {x:Number, y:Number} // position to move to + * | options.animation = {duration:Number, easingFunction:String} || Boolean // position to move to + */ + Network.prototype.moveTo = function (options) { + if (options === undefined) { + options = {}; + return; + } + if (options.offset === undefined) {options.offset = {x: 0, y: 0}; } + if (options.offset.x === undefined) {options.offset.x = 0; } + if (options.offset.y === undefined) {options.offset.y = 0; } + if (options.scale === undefined) {options.scale = this._getScale(); } + if (options.position === undefined) {options.position = this._getTranslation();} + if (options.animation === undefined) {options.animation = {duration:0}; } + if (options.animation === false ) {options.animation = {duration:0}; } + if (options.animation === true ) {options.animation = {}; } + if (options.animation.duration === undefined) {options.animation.duration = 1000; } // default duration + if (options.animation.easingFunction === undefined) {options.animation.easingFunction = "easeInOutQuad"; } // default easing function - var Hammer = __webpack_require__(18); - var Item = __webpack_require__(34); + this.animateView(options); + }; /** - * @constructor RangeItem - * @extends Item - * @param {Object} data Object containing parameters start, end - * content, className. - * @param {{toScreen: function, toTime: function}} conversion - * Conversion functions from time to screen and vice versa - * @param {Object} [options] Configuration options - * // TODO: describe options + * + * @param {Object} options | options.offset = {x:Number, y:Number} // offset from the center in DOM pixels + * | options.time = Number // animation time in milliseconds + * | options.scale = Number // scale to animate to + * | options.position = {x:Number, y:Number} // position to animate to + * | options.easingFunction = String // linear, easeInQuad, easeOutQuad, easeInOutQuad, + * // easeInCubic, easeOutCubic, easeInOutCubic, + * // easeInQuart, easeOutQuart, easeInOutQuart, + * // easeInQuint, easeOutQuint, easeInOutQuint */ - function RangeItem (data, conversion, options) { - this.props = { - content: { - width: 0 - } + Network.prototype.animateView = function (options) { + if (options === undefined) { + options = {}; + return; + } + + // release if something focussed on the node + this.releaseNode(); + if (options.locked == true) { + this.lockedOnNodeId = options.lockedOnNode; + this.lockedOnNodeOffset = options.offset; + } + + // forcefully complete the old animation if it was still running + if (this.easingTime != 0) { + this._transitionRedraw(1); // by setting easingtime to 1, we finish the animation. + } + + this.sourceScale = this._getScale(); + this.sourceTranslation = this._getTranslation(); + this.targetScale = options.scale; + + // set the scale so the viewCenter is based on the correct zoom level. This is overridden in the transitionRedraw + // but at least then we'll have the target transition + this._setScale(this.targetScale); + var viewCenter = this.DOMtoCanvas({x: 0.5 * this.frame.canvas.clientWidth, y: 0.5 * this.frame.canvas.clientHeight}); + var distanceFromCenter = { // offset from view, distance view has to change by these x and y to center the node + x: viewCenter.x - options.position.x, + y: viewCenter.y - options.position.y + }; + this.targetTranslation = { + x: this.sourceTranslation.x + distanceFromCenter.x * this.targetScale + options.offset.x, + y: this.sourceTranslation.y + distanceFromCenter.y * this.targetScale + options.offset.y }; - this.overflow = false; // if contents can overflow (css styling), this flag is set to true - // validate data - if (data) { - if (data.start == undefined) { - throw new Error('Property "start" missing in item ' + data.id); + // if the time is set to 0, don't do an animation + if (options.animation.duration == 0) { + if (this.lockedOnNodeId != null) { + this._classicRedraw = this._redraw; + this._redraw = this._lockedRedraw; } - if (data.end == undefined) { - throw new Error('Property "end" missing in item ' + data.id); + else { + this._setScale(this.targetScale); + this._setTranslation(this.targetTranslation.x, this.targetTranslation.y); + this._redraw(); } } + else { + this.animationSpeed = 1 / (this.renderRefreshRate * options.animation.duration * 0.001) || 1 / this.renderRefreshRate; + this.animationEasingFunction = options.animation.easingFunction; + this._classicRedraw = this._redraw; + this._redraw = this._transitionRedraw; + this._redraw(); + this.moving = true; + this.start(); + } + }; - Item.call(this, data, conversion, options); - } - RangeItem.prototype = new Item (null, null, null); + Network.prototype._lockedRedraw = function () { + var nodePosition = {x: this.nodes[this.lockedOnNodeId].x, y: this.nodes[this.lockedOnNodeId].y}; + var viewCenter = this.DOMtoCanvas({x: 0.5 * this.frame.canvas.clientWidth, y: 0.5 * this.frame.canvas.clientHeight}); + var distanceFromCenter = { // offset from view, distance view has to change by these x and y to center the node + x: viewCenter.x - nodePosition.x, + y: viewCenter.y - nodePosition.y + }; + var sourceTranslation = this._getTranslation(); + var targetTranslation = { + x: sourceTranslation.x + distanceFromCenter.x * this.scale + this.lockedOnNodeOffset.x, + y: sourceTranslation.y + distanceFromCenter.y * this.scale + this.lockedOnNodeOffset.y + }; - RangeItem.prototype.baseClassName = 'item range'; + this._setTranslation(targetTranslation.x,targetTranslation.y); + this._classicRedraw(); + } - /** - * Check whether this item is visible inside given range - * @returns {{start: Number, end: Number}} range with a timestamp for start and end - * @returns {boolean} True if visible - */ - RangeItem.prototype.isVisible = function(range) { - // determine visibility - return (this.data.start < range.end) && (this.data.end > range.start); - }; + Network.prototype.releaseNode = function () { + if (this.lockedOnNodeId != null) { + this._redraw = this._classicRedraw; + this.lockedOnNodeId = null; + this.lockedOnNodeOffset = null; + } + } /** - * Repaint the item + * + * @param easingTime + * @private */ - RangeItem.prototype.redraw = function() { - var dom = this.dom; - if (!dom) { - // create DOM - this.dom = {}; - dom = this.dom; - - // background box - dom.box = document.createElement('div'); - // className is updated in redraw() + Network.prototype._transitionRedraw = function (easingTime) { + this.easingTime = easingTime || this.easingTime + this.animationSpeed; + this.easingTime += this.animationSpeed; - // contents box - dom.content = document.createElement('div'); - dom.content.className = 'content'; - dom.box.appendChild(dom.content); + var progress = util.easingFunctions[this.animationEasingFunction](this.easingTime); - // attach this item as attribute - dom.box['timeline-item'] = this; + this._setScale(this.sourceScale + (this.targetScale - this.sourceScale) * progress); + this._setTranslation( + this.sourceTranslation.x + (this.targetTranslation.x - this.sourceTranslation.x) * progress, + this.sourceTranslation.y + (this.targetTranslation.y - this.sourceTranslation.y) * progress + ); - this.dirty = true; - } + this._classicRedraw(); + this.moving = true; - // append DOM to parent DOM - if (!this.parent) { - throw new Error('Cannot redraw item: no parent attached'); - } - if (!dom.box.parentNode) { - var foreground = this.parent.dom.foreground; - if (!foreground) { - throw new Error('Cannot redraw item: parent has no foreground container element'); + // cleanup + if (this.easingTime >= 1.0) { + this.easingTime = 0; + if (this.lockedOnNodeId != null) { + this._redraw = this._lockedRedraw; } - foreground.appendChild(dom.box); + else { + this._redraw = this._classicRedraw; + } + this.emit("animationFinished"); } - this.displayed = true; - - // Update DOM when item is marked dirty. An item is marked dirty when: - // - the item is not yet rendered - // - the item's data is changed - // - the item is selected/deselected - if (this.dirty) { - this._updateContents(this.dom.content); - this._updateTitle(this.dom.box); - this._updateDataAttributes(this.dom.box); - this._updateStyle(this.dom.box); - - // update class - var className = (this.data.className ? (' ' + this.data.className) : '') + - (this.selected ? ' selected' : ''); - dom.box.className = this.baseClassName + className; + }; - // determine from css whether this box has overflow - this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden'; + Network.prototype._classicRedraw = function () { + // placeholder function to be overloaded by animations; + }; - // recalculate size - this.props.content.width = this.dom.content.offsetWidth; - this.height = this.dom.box.offsetHeight; + /** + * Returns true when the Network is active. + * @returns {boolean} + */ + Network.prototype.isActive = function () { + return !this.activator || this.activator.active; + }; - this.dirty = false; - } - this._repaintDeleteButton(dom.box); - this._repaintDragLeft(); - this._repaintDragRight(); + /** + * Sets the scale + * @returns {Number} + */ + Network.prototype.setScale = function () { + return this._setScale(); }; + /** - * Show the item in the DOM (when not already visible). The items DOM will - * be created when needed. + * Returns the scale + * @returns {Number} */ - RangeItem.prototype.show = function() { - if (!this.displayed) { - this.redraw(); - } + Network.prototype.getScale = function () { + return this._getScale(); }; + /** - * Hide the item from the DOM (when visible) - * @return {Boolean} changed + * Returns the scale + * @returns {Number} */ - RangeItem.prototype.hide = function() { - if (this.displayed) { - var box = this.dom.box; + Network.prototype.getCenterCoordinates = function () { + return this.DOMtoCanvas({x: 0.5 * this.frame.canvas.clientWidth, y: 0.5 * this.frame.canvas.clientHeight}); + }; - if (box.parentNode) { - box.parentNode.removeChild(box); - } + module.exports = Network; - this.top = null; - this.left = null; - this.displayed = false; - } - }; +/***/ }, +/* 36 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var Node = __webpack_require__(39); /** - * Reposition the item horizontally - * @Override + * @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 */ - RangeItem.prototype.repositionX = function() { - var parentWidth = this.parent.width; - var start = this.conversion.toScreen(this.data.start); - var end = this.conversion.toScreen(this.data.end); - var contentLeft; - var contentWidth; - - // limit the width of the this, as browsers cannot draw very wide divs - if (start < -parentWidth) { - start = -parentWidth; - } - if (end > 2 * parentWidth) { - end = 2 * parentWidth; + function Edge (properties, network, networkConstants) { + if (!network) { + throw "No network provided"; } - var boxWidth = Math.max(end - start, 1); + var fields = ['edges','physics']; + var constants = util.selectiveBridgeObject(fields,networkConstants); + this.options = constants.edges; + this.physics = constants.physics; + this.options['smoothCurves'] = networkConstants['smoothCurves']; - if (this.overflow) { - this.left = start; - this.width = boxWidth + this.props.content.width; - contentWidth = this.props.content.width; - // Note: The calculation of width is an optimistic calculation, giving - // a width which will not change when moving the Timeline - // So no re-stacking needed, which is nicer for the eye; - } - else { - this.left = start; - this.width = boxWidth; - contentWidth = Math.min(end - start, this.props.content.width); - } + this.network = network; - this.dom.box.style.left = this.left + 'px'; - this.dom.box.style.width = boxWidth + 'px'; + // initialize variables + this.id = undefined; + this.fromId = undefined; + this.toId = undefined; + this.title = undefined; + this.widthSelected = this.options.width * this.options.widthSelectionMultiplier; + this.value = undefined; + this.selected = false; + this.hover = false; + this.labelDimensions = {top:0,left:0,width:0,height:0,yLine:0}; // could be cached + this.dirtyLabel = true; - switch (this.options.align) { - case 'left': - this.dom.content.style.left = '0'; - break; + this.from = null; // a node + this.to = null; // a node + this.via = null; // a temp node - case 'right': - this.dom.content.style.left = Math.max((boxWidth - contentWidth - 2 * this.options.padding), 0) + 'px'; - break; + // 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 = []; - case 'center': - this.dom.content.style.left = Math.max((boxWidth - contentWidth - 2 * this.options.padding) / 2, 0) + 'px'; - break; + this.connected = false; - default: // 'auto' - if (this.overflow) { - // when range exceeds left of the window, position the contents at the left of the visible area - contentLeft = Math.max(-start, 0); - } - else { - // when range exceeds left of the window, position the contents at the left of the visible area - if (start < 0) { - contentLeft = Math.min(-start, - (end - start - this.props.content.width - 2 * this.options.padding)); - // TODO: remove the need for options.padding. it's terrible. - } - else { - contentLeft = 0; - } - } - this.dom.content.style.left = contentLeft + 'px'; - } - }; + this.widthFixed = false; + this.lengthFixed = false; + + this.setProperties(properties); + + this.controlNodesEnabled = false; + this.controlNodes = {from:null, to:null, positions:{}}; + this.connectedNode = null; + } /** - * Reposition the item vertically - * @Override + * Set or overwrite properties for the edge + * @param {Object} properties an object with properties + * @param {Object} constants and object with default, global properties */ - RangeItem.prototype.repositionY = function() { - var orientation = this.options.orientation, - box = this.dom.box; + Edge.prototype.setProperties = function(properties) { + if (!properties) { + return; + } - if (orientation == 'top') { - box.style.top = this.top + 'px'; + var fields = ['style','fontSize','fontFace','fontColor','fontFill','width', + 'widthSelectionMultiplier','hoverWidth','arrowScaleFactor','dash','inheritColor' + ]; + util.selectiveDeepExtend(fields, this.options, properties); + + 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.label !== undefined) {this.label = properties.label; this.dirtyLabel = true;} + + if (properties.title !== undefined) {this.title = properties.title;} + if (properties.value !== undefined) {this.value = properties.value;} + if (properties.length !== undefined) {this.physics.springLength = properties.length;} + + if (properties.color !== undefined) { + this.options.inheritColor = false; + if (util.isString(properties.color)) { + this.options.color.color = properties.color; + this.options.color.highlight = properties.color; + } + else { + if (properties.color.color !== undefined) {this.options.color.color = properties.color.color;} + if (properties.color.highlight !== undefined) {this.options.color.highlight = properties.color.highlight;} + if (properties.color.hover !== undefined) {this.options.color.hover = properties.color.hover;} + } } - else { - box.style.top = (this.parent.height - this.top - this.height) + 'px'; + + // 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); + + this.widthSelected = this.options.width* this.options.widthSelectionMultiplier; + + // set draw method based on style + switch (this.options.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; } }; /** - * Repaint a drag area on the left side of the range when the range is selected - * @protected + * Connect an edge to its nodes */ - RangeItem.prototype._repaintDragLeft = function () { - if (this.selected && this.options.editable.updateTime && !this.dom.dragLeft) { - // create and show drag area - var dragLeft = document.createElement('div'); - dragLeft.className = 'drag-left'; - dragLeft.dragLeftItem = this; + Edge.prototype.connect = function () { + this.disconnect(); - // TODO: this should be redundant? - Hammer(dragLeft, { - preventDefault: true - }).on('drag', function () { - //console.log('drag left') - }); + this.from = this.network.nodes[this.fromId] || null; + this.to = this.network.nodes[this.toId] || null; + this.connected = (this.from && this.to); - this.dom.box.appendChild(dragLeft); - this.dom.dragLeft = dragLeft; + if (this.connected) { + this.from.attachEdge(this); + this.to.attachEdge(this); } - else if (!this.selected && this.dom.dragLeft) { - // delete drag area - if (this.dom.dragLeft.parentNode) { - this.dom.dragLeft.parentNode.removeChild(this.dom.dragLeft); + else { + if (this.from) { + this.from.detachEdge(this); + } + if (this.to) { + this.to.detachEdge(this); } - this.dom.dragLeft = null; } }; /** - * Repaint a drag area on the right side of the range when the range is selected - * @protected + * Disconnect an edge from its nodes */ - RangeItem.prototype._repaintDragRight = function () { - if (this.selected && this.options.editable.updateTime && !this.dom.dragRight) { - // create and show drag area - var dragRight = document.createElement('div'); - dragRight.className = 'drag-right'; - dragRight.dragRightItem = this; - - // TODO: this should be redundant? - Hammer(dragRight, { - preventDefault: true - }).on('drag', function () { - //console.log('drag right') - }); - - this.dom.box.appendChild(dragRight); - this.dom.dragRight = dragRight; + Edge.prototype.disconnect = function () { + if (this.from) { + this.from.detachEdge(this); + this.from = null; } - else if (!this.selected && this.dom.dragRight) { - // delete drag area - if (this.dom.dragRight.parentNode) { - this.dom.dragRight.parentNode.removeChild(this.dom.dragRight); - } - this.dom.dragRight = null; + if (this.to) { + this.to.detachEdge(this); + this.to = null; } - }; - - module.exports = RangeItem; - - -/***/ }, -/* 34 */ -/***/ function(module, exports, __webpack_require__) { - var Hammer = __webpack_require__(18); - var util = __webpack_require__(1); + this.connected = false; + }; /** - * @constructor Item - * @param {Object} data Object containing (optional) parameters type, - * start, end, content, group, className. - * @param {{toScreen: function, toTime: function}} conversion - * Conversion functions from time to screen and vice versa - * @param {Object} options Configuration options - * // TODO: describe available options + * get the title of this edge. + * @return {string} title The title of the edge, or undefined when no title + * has been set. */ - function Item (data, conversion, options) { - this.id = null; - this.parent = null; - this.data = data; - this.dom = null; - this.conversion = conversion || {}; - this.options = options || {}; - - this.selected = false; - this.displayed = false; - this.dirty = true; - - this.top = null; - this.left = null; - this.width = null; - this.height = null; - } + Edge.prototype.getTitle = function() { + return typeof this.title === "function" ? this.title() : this.title; + }; - Item.prototype.stack = true; /** - * Select current item + * Retrieve the value of the edge. Can be undefined + * @return {Number} value */ - Item.prototype.select = function() { - this.selected = true; - this.dirty = true; - if (this.displayed) this.redraw(); + Edge.prototype.getValue = function() { + return this.value; }; /** - * Unselect current item + * Adjust the value range of the edge. The edge will adjust it's width + * based on its value. + * @param {Number} min + * @param {Number} max */ - Item.prototype.unselect = function() { - this.selected = false; - this.dirty = true; - if (this.displayed) this.redraw(); + Edge.prototype.setValueRange = function(min, max) { + if (!this.widthFixed && this.value !== undefined) { + var scale = (this.options.widthMax - this.options.widthMin) / (max - min); + this.options.width= (this.value - min) * scale + this.options.widthMin; + this.widthSelected = this.options.width* this.options.widthSelectionMultiplier; + } }; /** - * Set data for the item. Existing data will be updated. The id should not - * be changed. When the item is displayed, it will be redrawn immediately. - * @param {Object} data + * 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 */ - Item.prototype.setData = function(data) { - this.data = data; - this.dirty = true; - if (this.displayed) this.redraw(); + Edge.prototype.draw = function(ctx) { + throw "Method draw not initialized in edge"; }; /** - * Set a parent for the item - * @param {ItemSet | Group} parent + * 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 */ - Item.prototype.setParent = function(parent) { - if (this.displayed) { - this.hide(); - this.parent = parent; - if (this.parent) { - this.show(); - } + 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); + + return (dist < distMax); } else { - this.parent = parent; + return false + } + }; + + Edge.prototype._getColor = function() { + var colorObj = this.options.color; + if (this.options.inheritColor == "to") { + colorObj = { + highlight: this.to.options.color.highlight.border, + hover: this.to.options.color.hover.border, + color: this.to.options.color.border + }; } + else if (this.options.inheritColor == "from" || this.options.inheritColor == true) { + colorObj = { + highlight: this.from.options.color.highlight.border, + hover: this.from.options.color.hover.border, + color: this.from.options.color.border + }; + } + + if (this.selected == true) {return colorObj.highlight;} + else if (this.hover == true) {return colorObj.hover;} + else {return colorObj.color;} }; + /** - * Check whether this item is visible inside given range - * @returns {{start: Number, end: Number}} range with a timestamp for start and end - * @returns {boolean} True if visible + * 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 */ - Item.prototype.isVisible = function(range) { - // Should be implemented by Item implementations - return false; + 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.options.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.physics.springLength / 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); + } }; /** - * Show the Item in the DOM (when not already visible) - * @return {Boolean} changed + * Get the line width of the edge. Depends on width and whether one of the + * connected nodes is selected. + * @return {Number} width + * @private */ - Item.prototype.show = function() { - return false; + Edge.prototype._getLineWidth = function() { + if (this.selected == true) { + return Math.max(Math.min(this.widthSelected, this.options.widthMax), 0.3*this.networkScaleInv); + } + else { + if (this.hover == true) { + return Math.max(Math.min(this.options.hoverWidth, this.options.widthMax), 0.3*this.networkScaleInv); + } + else { + return Math.max(this.options.width, 0.3*this.networkScaleInv); + } + } + }; + + Edge.prototype._getViaCoordinates = function () { + var xVia = null; + var yVia = null; + var factor = this.options.smoothCurves.roundness; + var type = this.options.smoothCurves.type; + + 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)) { // up - down + xVia = this.from.x; + if (this.from.y < this.to.y) { + yVia = this.to.y - (1-factor) * dy; + } + else { + yVia = this.to.y + (1-factor) * dy; + } + } + else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) { // left - right + if (this.from.x < this.to.x) { + xVia = this.to.x - (1-factor) * dx; + } + else { + xVia = this.to.x + (1-factor) * dx; + } + yVia = this.from.y; + } + } + else if (type == 'horizontal') { + if (this.from.x < this.to.x) { + xVia = this.to.x - (1-factor) * dx; + } + else { + xVia = this.to.x + (1-factor) * dx; + } + yVia = this.from.y; + } + else if (type == 'vertical') { + xVia = this.from.x; + if (this.from.y < this.to.y) { + yVia = this.to.y - (1-factor) * dy; + } + else { + yVia = this.to.y + (1-factor) * dy; + } + } + 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; + } + } + 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 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; + } + } + } + } + + + return {x:xVia, y:yVia}; }; /** - * Hide the Item from the DOM (when visible) - * @return {Boolean} changed + * Draw a line between two nodes + * @param {CanvasRenderingContext2D} ctx + * @private */ - Item.prototype.hide = function() { - return false; + Edge.prototype._line = function (ctx) { + // draw a straight line + ctx.beginPath(); + ctx.moveTo(this.from.x, this.from.y); + if (this.options.smoothCurves.enabled == true) { + if (this.options.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; + } + } + 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; + } }; /** - * Repaint the item + * Draw a line from a node to itself, a circle + * @param {CanvasRenderingContext2D} ctx + * @param {Number} x + * @param {Number} y + * @param {Number} radius + * @private */ - Item.prototype.redraw = function() { - // should be implemented by the item + 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(); }; /** - * Reposition the Item horizontally + * 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 */ - Item.prototype.repositionX = function() { - // should be implemented by the item - }; + Edge.prototype._label = function (ctx, text, x, y) { + if (text) { + ctx.font = ((this.from.selected || this.to.selected) ? "bold " : "") + + this.options.fontSize + "px " + this.options.fontFace; + var yLine; + + if (this.dirtyLabel == true) { + var lines = String(text).split('\n'); + var lineCount = lines.length; + var fontSize = (Number(this.options.fontSize) + 4); + yLine = y + (1 - lineCount) / 2 * fontSize; - /** - * Reposition the Item vertically - */ - Item.prototype.repositionY = function() { - // should be implemented by the item - }; + var width = ctx.measureText(lines[0]).width; + for (var i = 1; i < lineCount; i++) { + var lineWidth = ctx.measureText(lines[i]).width; + width = lineWidth > width ? lineWidth : width; + } + var height = this.options.fontSize * lineCount; + var left = x - width / 2; + var top = y - height / 2; - /** - * Repaint a delete button on the top right of the item when the item is selected - * @param {HTMLElement} anchor - * @protected - */ - Item.prototype._repaintDeleteButton = function (anchor) { - if (this.selected && this.options.editable.remove && !this.dom.deleteButton) { - // create and show button - var me = this; + // cache + this.labelDimensions = {top:top,left:left,width:width,height:height,yLine:yLine}; + } - var deleteButton = document.createElement('div'); - deleteButton.className = 'delete'; - deleteButton.title = 'Delete this item'; - Hammer(deleteButton, { - preventDefault: true - }).on('tap', function (event) { - me.parent.removeFromDataSet(me); - event.stopPropagation(); - }); + if (this.options.fontFill !== undefined && this.options.fontFill !== null && this.options.fontFill !== "none") { + ctx.fillStyle = this.options.fontFill; + ctx.fillRect(this.labelDimensions.left, + this.labelDimensions.top, + this.labelDimensions.width, + this.labelDimensions.height); + } - anchor.appendChild(deleteButton); - this.dom.deleteButton = deleteButton; - } - else if (!this.selected && this.dom.deleteButton) { - // remove button - if (this.dom.deleteButton.parentNode) { - this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton); + // draw text + ctx.fillStyle = this.options.fontColor || "black"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + yLine = this.labelDimensions.yLine; + for (var i = 0; i < lineCount; i++) { + ctx.fillText(lines[i], x, yLine); + yLine += fontSize; } - this.dom.deleteButton = null; } }; /** - * Set HTML contents for the item - * @param {Element} element HTML element to fill with the contents + * 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 */ - Item.prototype._updateContents = function (element) { - var content; - if (this.options.template) { - var itemData = this.parent.itemSet.itemsData.get(this.id); // get a clone of the data from the dataset - content = this.options.template(itemData); + Edge.prototype._drawDashLine = function(ctx) { + // set style + ctx.strokeStyle = this._getColor(); + ctx.lineWidth = this._getLineWidth(); + + 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.options.dash.length !== undefined && this.options.dash.gap !== undefined) { + pattern = [this.options.dash.length,this.options.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; + + } else { //Firefox + ctx.mozDash = pattern; + ctx.mozDashOffset = 0; + } + + // draw the line + via = this._line(ctx); + + // restore the dash settings. + if (typeof ctx.setLineDash !== 'undefined') { //Chrome + ctx.setLineDash([0]); + ctx.lineDashOffset = 0; + + } else { //Firefox + ctx.mozDash = [0]; + ctx.mozDashOffset = 0; + } } - else { - content = this.data.content; + else { // unsupporting smooth lines + // draw dashed line + ctx.beginPath(); + ctx.lineCap = 'round'; + if (this.options.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.options.dash.length,this.options.dash.gap,this.options.dash.altLength,this.options.dash.gap]); + } + else if (this.options.dash.length !== undefined && this.options.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.options.dash.length,this.options.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(); } - if(content !== this.content) { - // only replace the content when changed - if (content instanceof Element) { - element.innerHTML = ''; - element.appendChild(content); - } - else if (content != undefined) { - element.innerHTML = content; + // draw label + if (this.label) { + var point; + if (this.options.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 { - if (!(this.data.type == 'background' && this.data.content === undefined)) { - throw new Error('Property "content" missing in item ' + this.id); - } + point = this._pointOnLine(0.5); } - - this.content = content; + this._label(ctx, this.label, point.x, point.y); } }; /** - * Set HTML contents for the item - * @param {Element} element HTML element to fill with the contents + * Get a point on a line + * @param {Number} percentage. Value between 0 (line start) and 1 (line end) + * @return {Object} point * @private */ - Item.prototype._updateTitle = function (element) { - if (this.data.title != null) { - element.title = this.data.title || ''; + 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 } - else { - element.removeAttribute('title'); + }; + + /** + * 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) } }; /** - * Process dataAttributes timeline option and set as data- attributes on dom.content - * @param {Element} element HTML element to which the attributes will be attached + * 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 */ - Item.prototype._updateDataAttributes = function(element) { - if (this.options.dataAttributes && this.options.dataAttributes.length > 0) { - var attributes = []; + Edge.prototype._drawArrowCenter = function(ctx) { + var point; + // set style + ctx.strokeStyle = this._getColor(); + ctx.lineWidth = this._getLineWidth(); - if (Array.isArray(this.options.dataAttributes)) { - attributes = this.options.dataAttributes; - } - else if (this.options.dataAttributes == 'all') { - attributes = Object.keys(this.data); + 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.options.width) * this.options.arrowScaleFactor; + // draw an arrow halfway the line + if (this.options.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 { - return; + point = this._pointOnLine(0.5); } - for (var i = 0; i < attributes.length; i++) { - var name = attributes[i]; - var value = this.data[name]; + ctx.arrow(point.x, point.y, angle, length); + ctx.fill(); + ctx.stroke(); - if (value != null) { - element.setAttribute('data-' + name, value); - } - else { - element.removeAttribute('data-' + name); - } + // 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.physics.springLength); + 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); - /** - * Update custom styles of the element - * @param element - * @private - */ - Item.prototype._updateStyle = function(element) { - // remove old styles - if (this.style) { - util.removeCssText(element, this.style); - this.style = null; - } + // draw all arrows + var angle = 0.2 * Math.PI; + var length = (10 + 5 * this.options.width) * this.options.arrowScaleFactor; + point = this._pointOnCircle(x, y, radius, 0.5); + ctx.arrow(point.x, point.y, angle, length); + ctx.fill(); + ctx.stroke(); - // append new styles - if (this.data.style) { - util.addCssText(element, this.data.style); - this.style = this.data.style; + // draw label + if (this.label) { + point = this._pointOnCircle(x, y, radius, 0.5); + this._label(ctx, this.label, point.x, point.y); + } } }; - module.exports = Item; - - -/***/ }, -/* 35 */ -/***/ function(module, exports, __webpack_require__) { - var util = __webpack_require__(1); - var Group = __webpack_require__(31); /** - * @constructor BackgroundGroup - * @param {Number | String} groupId - * @param {Object} data - * @param {ItemSet} itemSet + * 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 */ - function BackgroundGroup (groupId, data, itemSet) { - Group.call(this, groupId, data, itemSet); + Edge.prototype._drawArrow = function(ctx) { + // set style + ctx.strokeStyle = this._getColor(); + ctx.lineWidth = this._getLineWidth(); - this.width = 0; - this.height = 0; - this.top = 0; - this.left = 0; - } + 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); - BackgroundGroup.prototype = Object.create(Group.prototype); + 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; - /** - * Repaint this group - * @param {{start: number, end: number}} range - * @param {{item: {horizontal: number, vertical: number}, axis: number}} margin - * @param {boolean} [restack=false] Force restacking of all items - * @return {boolean} Returns true if the group is resized - */ - BackgroundGroup.prototype.redraw = function(range, margin, restack) { - var resized = false; + var via; + if (this.options.smoothCurves.dynamic == true && this.options.smoothCurves.enabled == true ) { + via = this.via; + } + else if (this.options.smoothCurves.enabled == true) { + via = this._getViaCoordinates(); + } - this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range); + if (this.options.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; - // calculate actual size - this.width = this.dom.background.offsetWidth; + var xTo,yTo; + if (this.options.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; + } - // apply new height (just always zero for BackgroundGroup - this.dom.background.style.height = '0'; + ctx.beginPath(); + ctx.moveTo(xFrom,yFrom); + if (this.options.smoothCurves.enabled == true && via.x != null) { + ctx.quadraticCurveTo(via.x,via.y,xTo, yTo); + } + else { + ctx.lineTo(xTo, yTo); + } + ctx.stroke(); - // update vertical position of items after they are re-stacked and the height of the group is calculated - for (var i = 0, ii = this.visibleItems.length; i < ii; i++) { - var item = this.visibleItems[i]; - item.repositionY(margin); + // draw arrow at the end of the line + length = (10 + 5 * this.options.width) * this.options.arrowScaleFactor; + ctx.arrow(xTo, yTo, angle, length); + ctx.fill(); + ctx.stroke(); + + // draw label + if (this.label) { + var point; + if (this.options.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.physics.springLength); + 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(); - return resized; - }; + // draw all arrows + var length = (10 + 5 * this.options.width) * this.options.arrowScaleFactor; + ctx.arrow(arrow.x, arrow.y, arrow.angle, length); + ctx.fill(); + ctx.stroke(); - /** - * Show this group: attach to the DOM - */ - BackgroundGroup.prototype.show = function() { - if (!this.dom.background.parentNode) { - this.itemSet.dom.background.appendChild(this.dom.background); + // draw label + if (this.label) { + point = this._pointOnCircle(x, y, radius, 0.5); + this._label(ctx, this.label, point.x, point.y); + } } }; - module.exports = BackgroundGroup; - - -/***/ }, -/* 36 */ -/***/ function(module, exports, __webpack_require__) { - var Item = __webpack_require__(34); - var util = __webpack_require__(1); /** - * @constructor BoxItem - * @extends Item - * @param {Object} data Object containing parameters start - * content, className. - * @param {{toScreen: function, toTime: function}} conversion - * Conversion functions from time to screen and vice versa - * @param {Object} [options] Configuration options - * // TODO: describe available options + * 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 BoxItem (data, conversion, options) { - this.props = { - dot: { - width: 0, - height: 0 - }, - line: { - width: 0, - height: 0 + Edge.prototype._getDistanceToEdge = function (x1,y1, x2,y2, x3,y3) { // x3,y3 is the point + var returnValue = 0; + if (this.from != this.to) { + if (this.options.smoothCurves.enabled == true) { + var xVia, yVia; + if (this.options.smoothCurves.enabled == true && this.options.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 distance; + var i,t,x,y, lastX, lastY; + 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; + if (i > 0) { + distance = this._getDistanceToLine(lastX,lastY,x,y, x3,y3); + minDistance = distance < minDistance ? distance : minDistance; + } + lastX = x; lastY = y; + } + returnValue = minDistance; + } + else { + returnValue = this._getDistanceToLine(x1,y1,x2,y2,x3,y3); + } + } + else { + var x, y, dx, dy; + var radius = 0.25 * this.physics.springLength; + var node = this.from; + if (node.width > node.height) { + x = node.x + 0.5 * node.width; + y = node.y - radius; + } + else { + x = node.x + radius; + y = node.y - 0.5 * node.height; } - }; + dx = x - x3; + dy = y - y3; + returnValue = Math.abs(Math.sqrt(dx*dx + dy*dy) - radius); + } - // validate data - if (data) { - if (data.start == undefined) { - throw new Error('Property "start" missing in item ' + data); - } + if (this.labelDimensions.left < x3 && + this.labelDimensions.left + this.labelDimensions.width > x3 && + this.labelDimensions.top < y3 && + this.labelDimensions.top + this.labelDimensions.height > y3) { + return 0; + } + else { + return returnValue; } + }; - Item.call(this, data, conversion, options); - } + Edge.prototype._getDistanceToLine = function(x1,y1,x2,y2,x3,y3) { + var px = x2-x1, + py = y2-y1, + something = px*px + py*py, + u = ((x3 - x1) * px + (y3 - y1) * py) / something; - BoxItem.prototype = new Item (null, null, null); + if (u > 1) { + u = 1; + } + else if (u < 0) { + u = 0; + } - /** - * Check whether this item is visible inside given range - * @returns {{start: Number, end: Number}} range with a timestamp for start and end - * @returns {boolean} True if visible - */ - BoxItem.prototype.isVisible = function(range) { - // determine visibility - // TODO: account for the real width of the item. Right now we just add 1/4 to the window - var interval = (range.end - range.start) / 4; - return (this.data.start > range.start - interval) && (this.data.start < range.end + interval); + 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); }; /** - * Repaint the item + * This allows the zoom level of the network to influence the rendering + * + * @param scale */ - BoxItem.prototype.redraw = function() { - var dom = this.dom; - if (!dom) { - // create DOM - this.dom = {}; - dom = this.dom; - - // create main box - dom.box = document.createElement('DIV'); - - // contents box (inside the background box). used for making margins - dom.content = document.createElement('DIV'); - dom.content.className = 'content'; - dom.box.appendChild(dom.content); - - // line to axis - dom.line = document.createElement('DIV'); - dom.line.className = 'line'; + Edge.prototype.setScale = function(scale) { + this.networkScaleInv = 1.0/scale; + }; - // dot on axis - dom.dot = document.createElement('DIV'); - dom.dot.className = 'dot'; - // attach this item as attribute - dom.box['timeline-item'] = this; + Edge.prototype.select = function() { + this.selected = true; + }; - this.dirty = true; - } + Edge.prototype.unselect = function() { + this.selected = false; + }; - // append DOM to parent DOM - if (!this.parent) { - throw new Error('Cannot redraw item: no parent attached'); - } - if (!dom.box.parentNode) { - var foreground = this.parent.dom.foreground; - if (!foreground) throw new Error('Cannot redraw item: parent has no foreground container element'); - foreground.appendChild(dom.box); - } - if (!dom.line.parentNode) { - var background = this.parent.dom.background; - if (!background) throw new Error('Cannot redraw item: parent has no background container element'); - background.appendChild(dom.line); - } - if (!dom.dot.parentNode) { - var axis = this.parent.dom.axis; - if (!background) throw new Error('Cannot redraw item: parent has no axis container element'); - axis.appendChild(dom.dot); + Edge.prototype.positionBezierNode = function() { + if (this.via !== null && this.from !== null && this.to !== null) { + this.via.x = 0.5 * (this.from.x + this.to.x); + this.via.y = 0.5 * (this.from.y + this.to.y); } - this.displayed = true; - - // Update DOM when item is marked dirty. An item is marked dirty when: - // - the item is not yet rendered - // - the item's data is changed - // - the item is selected/deselected - if (this.dirty) { - this._updateContents(this.dom.content); - this._updateTitle(this.dom.box); - this._updateDataAttributes(this.dom.box); - this._updateStyle(this.dom.box); + }; - // update class - var className = (this.data.className? ' ' + this.data.className : '') + - (this.selected ? ' selected' : ''); - dom.box.className = 'item box' + className; - dom.line.className = 'item line' + className; - dom.dot.className = 'item dot' + className; + /** + * 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); + } - // recalculate size - this.props.dot.height = dom.dot.offsetHeight; - this.props.dot.width = dom.dot.offsetWidth; - this.props.line.width = dom.line.offsetWidth; - this.width = dom.box.offsetWidth; - this.height = dom.box.offsetHeight; + 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.dirty = false; + this.controlNodes.from.draw(ctx); + this.controlNodes.to.draw(ctx); + } + else { + this.controlNodes = {from:null, to:null, positions:{}}; } - - this._repaintDeleteButton(dom.box); }; /** - * Show the item in the DOM (when not already displayed). The items DOM will - * be created when needed. + * Enable control nodes. + * @private */ - BoxItem.prototype.show = function() { - if (!this.displayed) { - this.redraw(); - } + Edge.prototype._enableControlNodes = function() { + this.controlNodesEnabled = true; }; /** - * Hide the item from the DOM (when visible) + * disable control nodes + * @private */ - BoxItem.prototype.hide = function() { - if (this.displayed) { - var dom = this.dom; - - if (dom.box.parentNode) dom.box.parentNode.removeChild(dom.box); - if (dom.line.parentNode) dom.line.parentNode.removeChild(dom.line); - if (dom.dot.parentNode) dom.dot.parentNode.removeChild(dom.dot); - - this.top = null; - this.left = null; - - this.displayed = false; - } + Edge.prototype._disableControlNodes = function() { + this.controlNodesEnabled = false; }; /** - * Reposition the item horizontally - * @Override + * 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 */ - BoxItem.prototype.repositionX = function() { - var start = this.conversion.toScreen(this.data.start); - var align = this.options.align; - var left; - var box = this.dom.box; - var line = this.dom.line; - var dot = this.dom.dot; + 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)); - // calculate left position of the box - if (align == 'right') { - this.left = start - this.width; + if (fromDistance < 15) { + this.connectedNode = this.from; + this.from = this.controlNodes.from; + return this.controlNodes.from; } - else if (align == 'left') { - this.left = start; + else if (toDistance < 15) { + this.connectedNode = this.to; + this.to = this.controlNodes.to; + return this.controlNodes.to; } else { - // default or 'center' - this.left = start - this.width / 2; + return null; } + }; - // reposition box - box.style.left = this.left + 'px'; - - // reposition line - line.style.left = (start - this.props.line.width / 2) + 'px'; - // reposition dot - dot.style.left = (start - this.props.dot.width / 2) + 'px'; + /** + * 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(); + } }; /** - * Reposition the item vertically - * @Override + * 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: *}}} */ - BoxItem.prototype.repositionY = function() { - var orientation = this.options.orientation; - var box = this.dom.box; - var line = this.dom.line; - var dot = this.dom.dot; + 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; - if (orientation == 'top') { - box.style.top = (this.top || 0) + 'px'; + var via; + if (this.options.smoothCurves.dynamic == true && this.options.smoothCurves.enabled == true) { + via = this.via; + } + else if (this.options.smoothCurves.enabled == true) { + via = this._getViaCoordinates(); + } - line.style.top = '0'; - line.style.height = (this.parent.top + this.top + 1) + 'px'; - line.style.bottom = ''; + if (this.options.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); } - else { // orientation 'bottom' - var itemSetHeight = this.parent.itemSet.props.height; // TODO: this is nasty - var lineHeight = itemSetHeight - this.parent.top - this.parent.height + this.top; + var toBorderDist = this.to.distanceToBorder(ctx, angle); + var toBorderPoint = (edgeSegmentLength - toBorderDist) / edgeSegmentLength; - box.style.top = (this.parent.height - this.top - this.height || 0) + 'px'; - line.style.top = (itemSetHeight - lineHeight) + 'px'; - line.style.bottom = '0'; + var xTo,yTo; + if (this.options.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; } - dot.style.top = (-this.props.dot.height / 2) + 'px'; + return {from:{x:xFrom,y:yFrom},to:{x:xTo,y:yTo}}; }; - module.exports = BoxItem; - + module.exports = Edge; /***/ }, /* 37 */ /***/ function(module, exports, __webpack_require__) { - var Item = __webpack_require__(34); + var util = __webpack_require__(1); /** - * @constructor PointItem - * @extends Item - * @param {Object} data Object containing parameters start - * content, className. - * @param {{toScreen: function, toTime: function}} conversion - * Conversion functions from time to screen and vice versa - * @param {Object} [options] Configuration options - * // TODO: describe available options + * @class Groups + * This class can store groups and properties specific for groups. */ - function PointItem (data, conversion, options) { - this.props = { - dot: { - top: 0, - width: 0, - height: 0 - }, - content: { - height: 0, - marginLeft: 0 - } - }; - - // validate data - if (data) { - if (data.start == undefined) { - throw new Error('Property "start" missing in item ' + data); - } - } - - Item.call(this, data, conversion, options); + function Groups() { + this.clear(); + this.defaultIndex = 0; } - PointItem.prototype = new Item (null, null, null); /** - * Check whether this item is visible inside given range - * @returns {{start: Number, end: Number}} range with a timestamp for start and end - * @returns {boolean} True if visible + * default constants for group colors */ - PointItem.prototype.isVisible = function(range) { - // determine visibility - // TODO: account for the real width of the item. Right now we just add 1/4 to the window - var interval = (range.end - range.start) / 4; - return (this.data.start > range.start - interval) && (this.data.start < range.end + interval); - }; + 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 + ]; + /** - * Repaint the item + * Clear all groups */ - PointItem.prototype.redraw = function() { - var dom = this.dom; - if (!dom) { - // create DOM - this.dom = {}; - dom = this.dom; - - // background box - dom.point = document.createElement('div'); - // className is updated in redraw() - - // contents box, right from the dot - dom.content = document.createElement('div'); - dom.content.className = 'content'; - dom.point.appendChild(dom.content); - - // dot at start - dom.dot = document.createElement('div'); - dom.point.appendChild(dom.dot); - - // attach this item as attribute - dom.point['timeline-item'] = this; - - this.dirty = true; - } - - // append DOM to parent DOM - if (!this.parent) { - throw new Error('Cannot redraw item: no parent attached'); - } - if (!dom.point.parentNode) { - var foreground = this.parent.dom.foreground; - if (!foreground) { - throw new Error('Cannot redraw item: parent has no foreground container element'); + Groups.prototype.clear = function () { + this.groups = {}; + this.groups.length = function() + { + var i = 0; + for ( var p in this ) { + if (this.hasOwnProperty(p)) { + i++; + } } - foreground.appendChild(dom.point); - } - this.displayed = true; - - // Update DOM when item is marked dirty. An item is marked dirty when: - // - the item is not yet rendered - // - the item's data is changed - // - the item is selected/deselected - if (this.dirty) { - this._updateContents(this.dom.content); - this._updateTitle(this.dom.point); - this._updateDataAttributes(this.dom.point); - this._updateStyle(this.dom.point); - - // update class - var className = (this.data.className? ' ' + this.data.className : '') + - (this.selected ? ' selected' : ''); - dom.point.className = 'item point' + className; - dom.dot.className = 'item dot' + className; - - // recalculate size - this.width = dom.point.offsetWidth; - this.height = dom.point.offsetHeight; - this.props.dot.width = dom.dot.offsetWidth; - this.props.dot.height = dom.dot.offsetHeight; - this.props.content.height = dom.content.offsetHeight; - - // resize contents - dom.content.style.marginLeft = 2 * this.props.dot.width + 'px'; - //dom.content.style.marginRight = ... + 'px'; // TODO: margin right - - dom.dot.style.top = ((this.height - this.props.dot.height) / 2) + 'px'; - dom.dot.style.left = (this.props.dot.width / 2) + 'px'; - - this.dirty = false; + return i; } - - this._repaintDeleteButton(dom.point); }; - /** - * Show the item in the DOM (when not already visible). The items DOM will - * be created when needed. - */ - PointItem.prototype.show = function() { - if (!this.displayed) { - this.redraw(); - } - }; /** - * Hide the item from the DOM (when visible) + * 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 */ - PointItem.prototype.hide = function() { - if (this.displayed) { - if (this.dom.point.parentNode) { - this.dom.point.parentNode.removeChild(this.dom.point); - } - - this.top = null; - this.left = null; - - this.displayed = false; + Groups.prototype.get = function (groupname) { + var group = this.groups[groupname]; + 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; } + + return group; }; /** - * Reposition the item horizontally - * @Override - */ - PointItem.prototype.repositionX = function() { - var start = this.conversion.toScreen(this.data.start); - - this.left = start - this.props.dot.width; - - // reposition point - this.dom.point.style.left = this.left + 'px'; - }; - - /** - * Reposition the item vertically - * @Override + * Add a custom group style + * @param {String} groupname + * @param {Object} style An object containing borderColor, + * backgroundColor, etc. + * @return {Object} group The created group object */ - PointItem.prototype.repositionY = function() { - var orientation = this.options.orientation, - point = this.dom.point; - - if (orientation == 'top') { - point.style.top = this.top + 'px'; - } - else { - point.style.top = (this.parent.height - this.top - this.height) + 'px'; + Groups.prototype.add = function (groupname, style) { + this.groups[groupname] = style; + if (style.color) { + style.color = util.parseColor(style.color); } + return style; }; - module.exports = PointItem; + module.exports = Groups; /***/ }, /* 38 */ /***/ function(module, exports, __webpack_require__) { - var Hammer = __webpack_require__(18); - var Item = __webpack_require__(34); - var BackgroundGroup = __webpack_require__(35); - var RangeItem = __webpack_require__(33); + /** + * @class Images + * This class loads images and keeps them stored. + */ + function Images() { + this.images = {}; + + this.callback = undefined; + } /** - * @constructor BackgroundItem - * @extends Item - * @param {Object} data Object containing parameters start, end - * content, className. - * @param {{toScreen: function, toTime: function}} conversion - * Conversion functions from time to screen and vice versa - * @param {Object} [options] Configuration options - * // TODO: describe options + * Set an onload callback function. This will be called each time an image + * is loaded + * @param {function} callback */ - // TODO: implement support for the BackgroundItem just having a start, then being displayed as a sort of an annotation - function BackgroundItem (data, conversion, options) { - this.props = { - content: { - width: 0 - } - }; - this.overflow = false; // if contents can overflow (css styling), this flag is set to true + Images.prototype.setOnloadCallback = function(callback) { + this.callback = callback; + }; - // validate data - if (data) { - if (data.start == undefined) { - throw new Error('Property "start" missing in item ' + data.id); - } - if (data.end == undefined) { - throw new Error('Property "end" missing in item ' + data.id); - } + /** + * + * @param {string} url Url of the image + * @param {string} url Url of an image to use if the url image is not found + * @return {Image} img The image object + */ + Images.prototype.load = function(url, brokenUrl) { + 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.onerror = function () { + this.src = brokenUrl; + if (images.callback) { + images.callback(this); + } + }; + + img.src = url; } - Item.call(this, data, conversion, options); + return img; + }; - this.emptyContent = false; - } + module.exports = Images; - BackgroundItem.prototype = new Item (null, null, null); - BackgroundItem.prototype.baseClassName = 'item background'; - BackgroundItem.prototype.stack = false; +/***/ }, +/* 39 */ +/***/ function(module, exports, __webpack_require__) { - /** - * Check whether this item is visible inside given range - * @returns {{start: Number, end: Number}} range with a timestamp for start and end - * @returns {boolean} True if visible - */ - BackgroundItem.prototype.isVisible = function(range) { - // determine visibility - return (this.data.start < range.end) && (this.data.end > range.start); - }; + var util = __webpack_require__(1); /** - * Repaint the item + * @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 + * */ - BackgroundItem.prototype.redraw = function() { - var dom = this.dom; - if (!dom) { - // create DOM - this.dom = {}; - dom = this.dom; + function Node(properties, imagelist, grouplist, networkConstants) { + var constants = util.selectiveBridgeObject(['nodes'],networkConstants); + this.options = constants.nodes; - // background box - dom.box = document.createElement('div'); - // className is updated in redraw() + this.selected = false; + this.hover = false; - // contents box - dom.content = document.createElement('div'); - dom.content.className = 'content'; - dom.box.appendChild(dom.content); + this.edges = []; // all edges connected to this node + this.dynamicEdges = []; + this.reroutedEdges = {}; - // attach this item as attribute - dom.box['timeline-item'] = this; + this.fontDrawThreshold = 3; - this.dirty = true; - } + // set defaults for the properties + this.id = undefined; + this.x = null; + this.y = null; + this.allowedToMoveX = false; + this.allowedToMoveY = false; + 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.baseRadiusValue = networkConstants.nodes.radius; + this.radiusFixed = false; + this.level = -1; + this.preassignedLevel = false; + this.hierarchyEnumerated = false; + this.labelDimensions = {top:0,left:0,width:0,height:0,yLine:0}; // could be cached - // append DOM to parent DOM - if (!this.parent) { - throw new Error('Cannot redraw item: no parent attached'); - } - if (!dom.box.parentNode) { - var background = this.parent.dom.background; - if (!background) { - throw new Error('Cannot redraw item: parent has no background container element'); - } - background.appendChild(dom.box); - } - this.displayed = true; - // Update DOM when item is marked dirty. An item is marked dirty when: - // - the item is not yet rendered - // - the item's data is changed - // - the item is selected/deselected - if (this.dirty) { - this._updateContents(this.dom.content); - this._updateTitle(this.dom.content); - this._updateDataAttributes(this.dom.content); - this._updateStyle(this.dom.box); + this.imagelist = imagelist; + this.grouplist = grouplist; - // update class - var className = (this.data.className ? (' ' + this.data.className) : '') + - (this.selected ? ' selected' : ''); - dom.box.className = this.baseClassName + className; + // 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.damping = networkConstants.physics.damping; // written every time gravity is calculated + this.fixedData = {x:null,y:null}; - // determine from css whether this box has overflow - this.overflow = window.getComputedStyle(dom.content).overflow !== 'hidden'; + this.setProperties(properties, constants); - // recalculate size - this.props.content.width = this.dom.content.offsetWidth; - this.height = 0; // set height zero, so this item will be ignored when stacking items + // creating the variables for clustering + this.resetCluster(); + this.dynamicEdgesLength = 0; + this.clusterSession = 0; + this.clusterSizeWidthFactor = networkConstants.clustering.nodeScaling.width; + this.clusterSizeHeightFactor = networkConstants.clustering.nodeScaling.height; + this.clusterSizeRadiusFactor = networkConstants.clustering.nodeScaling.radius; + this.maxNodeSizeIncrements = networkConstants.clustering.maxNodeSizeIncrements; + this.growthIndicator = 0; - this.dirty = false; - } - }; + // 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; + } /** - * Show the item in the DOM (when not already visible). The items DOM will - * be created when needed. + * (re)setting the clustering variables and objects */ - BackgroundItem.prototype.show = RangeItem.prototype.show; + 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 = []; + }; /** - * Hide the item from the DOM (when visible) - * @return {Boolean} changed + * Attach a edge to the node + * @param {Edge} edge */ - BackgroundItem.prototype.hide = RangeItem.prototype.hide; + 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); + } + this.dynamicEdgesLength = this.dynamicEdges.length; + }; /** - * Reposition the item horizontally - * @Override + * Detach a edge from the node + * @param {Edge} edge */ - BackgroundItem.prototype.repositionX = RangeItem.prototype.repositionX; + Node.prototype.detachEdge = function(edge) { + var index = this.edges.indexOf(edge); + if (index != -1) { + this.edges.splice(index, 1); + } + index = this.dynamicEdges.indexOf(edge); + if (index != -1) { + this.dynamicEdges.splice(index, 1); + } + this.dynamicEdgesLength = this.dynamicEdges.length; + }; + /** - * Reposition the item vertically - * @Override + * Set or overwrite properties for the node + * @param {Object} properties an object with properties + * @param {Object} constants and object with default, global properties */ - BackgroundItem.prototype.repositionY = function(margin) { - var onTop = this.options.orientation === 'top'; - this.dom.content.style.top = onTop ? '' : '0'; - this.dom.content.style.bottom = onTop ? '0' : ''; - var height; - - // special positioning for subgroups - if (this.data.subgroup !== undefined) { - var itemSubgroup = this.data.subgroup; - var subgroups = this.parent.subgroups; - var subgroupIndex = subgroups[itemSubgroup].index; - // if the orientation is top, we need to take the difference in height into account. - if (onTop == true) { - // the first subgroup will have to account for the distance from the top to the first item. - height = this.parent.subgroups[itemSubgroup].height + margin.item.vertical; - height += subgroupIndex == 0 ? margin.axis - 0.5*margin.item.vertical : 0; - var newTop = this.parent.top; - for (var subgroup in subgroups) { - if (subgroups.hasOwnProperty(subgroup)) { - if (subgroups[subgroup].visible == true && subgroups[subgroup].index < subgroupIndex) { - newTop += subgroups[subgroup].height + margin.item.vertical; - } - } - } - - // the others will have to be offset downwards with this same distance. - newTop += subgroupIndex != 0 ? margin.axis - 0.5 * margin.item.vertical : 0; - this.dom.box.style.top = newTop + 'px'; - this.dom.box.style.bottom = ''; - } - // and when the orientation is bottom: - else { - var newTop = this.parent.top; - for (var subgroup in subgroups) { - if (subgroups.hasOwnProperty(subgroup)) { - if (subgroups[subgroup].visible == true && subgroups[subgroup].index > subgroupIndex) { - newTop += subgroups[subgroup].height + margin.item.vertical; - } - } - } - height = this.parent.subgroups[itemSubgroup].height + margin.item.vertical; - this.dom.box.style.top = newTop + 'px'; - this.dom.box.style.bottom = ''; - } - } - // and in the case of no subgroups: - else { - // we want backgrounds with groups to only show in groups. - if (this.parent instanceof BackgroundGroup) { - // if the item is not in a group: - height = Math.max(this.parent.height, this.parent.itemSet.body.domProps.centerContainer.height); - this.dom.box.style.top = onTop ? '0' : ''; - this.dom.box.style.bottom = onTop ? '' : '0'; - } - else { - height = this.parent.height; - // same alignment for items when orientation is top or bottom - this.dom.box.style.top = this.parent.top + 'px'; - this.dom.box.style.bottom = ''; - } + Node.prototype.setProperties = function(properties, constants) { + if (!properties) { + return; } - this.dom.box.style.height = height + 'px'; - }; - module.exports = BackgroundItem; + var fields = ['borderWidth','borderWidthSelected','shape','image','brokenImage','radius','fontColor', + 'fontSize','fontFace','fontFill','group','mass' + ]; + util.selectiveDeepExtend(fields, this.options, properties); + // 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.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;} -/***/ }, -/* 39 */ -/***/ function(module, exports, __webpack_require__) { + // 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;} - var mousetrap = __webpack_require__(40); - var Emitter = __webpack_require__(10); - var Hammer = __webpack_require__(18); - var util = __webpack_require__(1); + if (this.id === undefined) { + throw "Node must have an id"; + } - /** - * Turn an element into an clickToUse element. - * When not active, the element has a transparent overlay. When the overlay is - * clicked, the mode is changed to active. - * When active, the element is displayed with a blue border around it, and - * the interactive contents of the element can be used. When clicked outside - * the element, the elements mode is changed to inactive. - * @param {Element} container - * @constructor - */ - function Activator(container) { - this.active = false; + // copy group properties + if (typeof this.options.group === 'number' || (typeof this.options.group === 'string' && this.options.group != '')) { + var groupObj = this.grouplist.get(this.options.group); + for (var prop in groupObj) { + if (groupObj.hasOwnProperty(prop)) { + this.options[prop] = groupObj[prop]; + } + } + } - this.dom = { - container: container - }; - this.dom.overlay = document.createElement('div'); - this.dom.overlay.className = 'overlay'; + // individual shape properties + if (properties.radius !== undefined) {this.baseRadiusValue = this.options.radius;} + if (properties.color !== undefined) {this.options.color = util.parseColor(properties.color);} - this.dom.container.appendChild(this.dom.overlay); + if (this.options.image!== undefined && this.options.image!= "") { + if (this.imagelist) { + this.imageObj = this.imagelist.load(this.options.image, this.options.brokenImage); + } + else { + throw "No imagelist provided"; + } + } - this.hammer = Hammer(this.dom.overlay, {prevent_default: false}); - this.hammer.on('tap', this._onTapOverlay.bind(this)); + if (properties.allowedToMoveX !== undefined) { + this.xFixed = !properties.allowedToMoveX; + this.allowedToMoveX = properties.allowedToMoveX; + } + else if (properties.x !== undefined && this.allowedToMoveX == false) { + this.xFixed = true; + } - // block all touch events (except tap) - var me = this; - var events = [ - 'touch', 'pinch', - 'doubletap', 'hold', - 'dragstart', 'drag', 'dragend', - 'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox - ]; - events.forEach(function (event) { - me.hammer.on(event, function (event) { - event.stopPropagation(); - }); - }); - // attach a tap event to the window, in order to deactivate when clicking outside the timeline - this.windowHammer = Hammer(window, {prevent_default: false}); - this.windowHammer.on('tap', function (event) { - // deactivate when clicked outside the container - if (!_hasParent(event.target, container)) { - me.deactivate(); - } - }); + if (properties.allowedToMoveY !== undefined) { + this.yFixed = !properties.allowedToMoveY; + this.allowedToMoveY = properties.allowedToMoveY; + } + else if (properties.y !== undefined && this.allowedToMoveY == false) { + this.yFixed = true; + } - // mousetrap listener only bounded when active) - this.escListener = this.deactivate.bind(this); - } + this.radiusFixed = this.radiusFixed || (properties.radius !== undefined); - // turn into an event emitter - Emitter(Activator.prototype); + if (this.options.shape == 'image') { + this.options.radiusMin = constants.nodes.widthMin; + this.options.radiusMax = constants.nodes.widthMax; + } - // The currently active activator - Activator.current = null; - /** - * Destroy the activator. Cleans up all created DOM and event listeners - */ - Activator.prototype.destroy = function () { - this.deactivate(); - // remove dom - this.dom.overlay.parentNode.removeChild(this.dom.overlay); + // choose draw method depending on the shape + switch (this.options.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; + } + // reset the size of the node, this can be changed + this._reset(); - // cleanup hammer instances - this.hammer = null; - this.windowHammer = null; - // FIXME: cleaning up hammer instances doesn't work (Timeline not removed from memory) }; /** - * Activate the element - * Overlay is hidden, element is decorated with a blue shadow border + * select this node */ - Activator.prototype.activate = function () { - // we allow only one active activator at a time - if (Activator.current) { - Activator.current.deactivate(); - } - Activator.current = this; - - this.active = true; - this.dom.overlay.style.display = 'none'; - util.addClassName(this.dom.container, 'vis-active'); - - this.emit('change'); - this.emit('activate'); - - // ugly hack: bind ESC after emitting the events, as the Network rebinds all - // keyboard events on a 'change' event - mousetrap.bind('esc', this.escListener); + Node.prototype.select = function() { + this.selected = true; + this._reset(); }; /** - * Deactivate the element - * Overlay is displayed on top of the element + * unselect this node */ - Activator.prototype.deactivate = function () { - this.active = false; - this.dom.overlay.style.display = ''; - util.removeClassName(this.dom.container, 'vis-active'); - mousetrap.unbind('esc', this.escListener); - - this.emit('change'); - this.emit('deactivate'); + Node.prototype.unselect = function() { + this.selected = false; + this._reset(); }; + /** - * Handle a tap event: activate the container - * @param event - * @private + * Reset the calculated size of the node, forces it to recalculate its size */ - Activator.prototype._onTapOverlay = function (event) { - // activate the container - this.activate(); - event.stopPropagation(); + Node.prototype.clearSizeCache = function() { + this._reset(); }; /** - * Test whether the element has the requested parent element somewhere in - * its chain of parent nodes. - * @param {HTMLElement} element - * @param {HTMLElement} parent - * @returns {boolean} Returns true when the parent is found somewhere in the - * chain of parent nodes. + * Reset the calculated size of the node, forces it to recalculate its size * @private */ - function _hasParent(element, parent) { - while (element) { - if (element === parent) { - return true - } - element = element.parentNode; - } - return false; - } - - module.exports = Activator; - - -/***/ }, -/* 40 */ -/***/ function(module, exports, __webpack_require__) { + Node.prototype._reset = function() { + this.width = undefined; + this.height = undefined; + }; /** - * 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 - * - * @version 1.1.2 - * @url craig.is/killing/mice + * 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; + }; - /** - * 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', - '_': '-', - '+': '=', - ':': ';', - '\"': '\'', - '<': ',', - '>': '.', - '?': '/', - '|': '\\' - }, + /** + * 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; - /** - * 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' - }, + if (!this.width) { + this.resize(ctx); + } - /** - * 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, + switch (this.options.shape) { + case 'circle': + case 'dot': + return this.options.radius+ borderWidth; - /** - * a list of all the callbacks setup via Mousetrap.bind() - * - * @type {Object} - */ - _callbacks = {}, + 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); - /** - * direct map of string combinations to callbacks used for trigger() - * - * @type {Object} - */ - _direct_map = {}, + // TODO: implement distanceToBorder for database + // TODO: implement distanceToBorder for triangle + // TODO: implement distanceToBorder for triangleDown - /** - * keeps track of what level each sequence is at since multiple - * sequences can start out with the same sequence - * - * @type {Object} - */ - _sequence_levels = {}, + 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; + } - /** - * variable to store the setTimeout call - * - * @type {null|number} - */ - _reset_timer, + } + // TODO: implement calculation of distance to border for all shapes + }; - /** - * temporary state where we will ignore the next keyup - * - * @type {boolean|string} - */ - _ignore_next_keyup = false, + /** + * Set forces acting on the node + * @param {number} fx Force in horizontal direction + * @param {number} fy Force in vertical direction + */ + Node.prototype._setForce = function(fx, fy) { + this.fx = fx; + this.fy = fy; + }; - /** - * are we currently inside of a sequence? - * type of action ("keyup" or "keydown" or "keypress") or false - * - * @type {boolean|string} - */ - _inside_sequence = false; + /** + * Add forces acting on the node + * @param {number} fx Force in horizontal direction + * @param {number} fy Force in vertical direction + * @private + */ + Node.prototype._addForce = function(fx, fy) { + this.fx += fx; + this.fy += fy; + }; - /** - * 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; + /** + * 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.options.mass; // acceleration + this.vx += ax * interval; // velocity + this.x += this.vx * interval; // position } - - /** - * loop through to map numbers on the numeric keypad - */ - for (i = 0; i <= 9; ++i) { - _MAP[i + 96] = i; + else { + this.fx = 0; + this.vx = 0; } - /** - * 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); - } - - object.attachEvent('on' + type, callback); + if (!this.yFixed) { + var dy = this.damping * this.vy; // damping force + var ay = (this.fy - dy) / this.options.mass; // acceleration + this.vy += ay * interval; // velocity + this.y += this.vy * interval; // position } - - /** - * takes the event and returns the key character - * - * @param {Event} e - * @return {string} - */ - function _characterFromEvent(e) { - - // for keypress events we should return the character as is - if (e.type == 'keypress') { - return String.fromCharCode(e.which); - } - - // for non keypress events the special maps are needed - if (_MAP[e.which]) { - return _MAP[e.which]; - } - - if (_KEYCODE_MAP[e.which]) { - return _KEYCODE_MAP[e.which]; - } - - // if it is not in the special map - return String.fromCharCode(e.which).toLowerCase(); + else { + this.fy = 0; + this.vy = 0; } + }; - /** - * 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; - // if the element has the class "mousetrap" then no need to stop - if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) { - return false; - } - // stop for input, select, and textarea - return tag_name == 'INPUT' || tag_name == 'SELECT' || tag_name == 'TEXTAREA' || (element.contentEditable && element.contentEditable == 'true'); + /** + * 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.options.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 } - - /** - * 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(','); + else { + this.fx = 0; + this.vx = 0; } - /** - * 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 || {}; + if (!this.yFixed) { + var dy = this.damping * this.vy; // damping force + var ay = (this.fy - dy) / this.options.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; + this.vy = 0; + } + }; - var active_sequences = false, - key; + /** + * 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); + }; - for (key in _sequence_levels) { - if (do_not_reset[key]) { - active_sequences = true; - continue; - } - _sequence_levels[key] = 0; - } + /** + * 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 + */ + Node.prototype.isMoving = function(vmin) { + var velocity = Math.sqrt(Math.pow(this.vx,2) + Math.pow(this.vy,2)); + // this.velocity = Math.sqrt(Math.pow(this.vx,2) + Math.pow(this.vy,2)) + return (velocity > vmin); + }; - if (!active_sequences) { - _inside_sequence = false; - } - } + /** + * check if this node is selecte + * @return {boolean} selected True if node is selected, else false + */ + Node.prototype.isSelected = function() { + return this.selected; + }; - /** - * 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 = []; + /** + * Retrieve the value of the node. Can be undefined + * @return {Number} value + */ + Node.prototype.getValue = function() { + return this.value; + }; - // if there are no events related to this keycode - if (!_callbacks[character]) { - return []; - } + /** + * 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); + }; - // 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]; + /** + * 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.options.radius= (this.options.radiusMin + this.options.radiusMax) / 2; + } + else { + var scale = (this.options.radiusMax - this.options.radiusMin) / (max - min); + this.options.radius= (this.value - min) * scale + this.options.radiusMin; + } + } + this.baseRadiusValue = this.options.radius; + }; - // 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; - } + /** + * 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"; + }; - // if the action we are looking for doesn't match the action we got - // then we should keep going - if (action != callback.action) { - continue; - } + /** + * 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 + */ + Node.prototype.resize = function(ctx) { + throw "Resize method not initialized for node"; + }; - // 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, right, bottom + * @return {boolean} True if location is located on node + */ + 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); + }; - // 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); - } + Node.prototype._resizeImage = function (ctx) { + // TODO: pre calculate the image size - matches.push(callback); - } + if (!this.width || !this.height) { // undefined or 0 + var width, height; + if (this.value) { + this.options.radius= this.baseRadiusValue; + var scale = this.imageObj.height / this.imageObj.width; + if (scale !== undefined) { + width = this.options.radius|| this.imageObj.width; + height = this.options.radius* scale || this.imageObj.height; + } + else { + width = 0; + height = 0; } + } + else { + width = this.imageObj.width; + height = this.imageObj.height; + } + this.width = width; + this.height = height; - return matches; + 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor; + this.growthIndicator = this.width - width; + } } - /** - * takes a key event and figures out what the modifiers are - * - * @param {Event} e - * @returns {Array} - */ - function _eventModifiers(e) { - var modifiers = []; + }; - if (e.shiftKey) { - modifiers.push('shift'); - } + Node.prototype._drawImage = function (ctx) { + this._resizeImage(ctx); - if (e.altKey) { - modifiers.push('alt'); - } + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; - if (e.ctrlKey) { - modifiers.push('ctrl'); - } + 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); - if (e.metaKey) { - modifiers.push('meta'); - } + ctx.globalAlpha = 0.5; + ctx.drawImage(this.imageObj, this.left - lineWidth, this.top - lineWidth, this.width + 2*lineWidth, this.height + 2*lineWidth); + } - return modifiers; + // 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; } - /** - * 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(); - } + this._label(ctx, this.label, this.x, yLabel, undefined, "top"); + }; - if (e.stopPropagation) { - e.stopPropagation(); - } - e.returnValue = false; - e.cancelBubble = true; - } - } + 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; - /** - * handles a character key event - * - * @param {string} character - * @param {Event} e - * @returns void - */ - function _handleCharacter(character, e) { + 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor; - // 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; + Node.prototype._drawBox = function (ctx) { + this._resizeBox(ctx); - // loop through matching callbacks for this key event - for (i = 0; i < callbacks.length; ++i) { + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; - // 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; + var clusterLineWidth = 2.5; + var borderWidth = this.options.borderWidth; + var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; - // keep a list of which sequences were matches for later - do_not_reset[callbacks[i].seq] = 1; - _fireCallback(callbacks[i].callback, e); - continue; - } + ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; - // 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); - } - } + // draw the outer border + if (this.clusterSize > 1) { + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - // 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); - } + ctx.roundRect(this.left-2*ctx.lineWidth, this.top-2*ctx.lineWidth, this.width+4*ctx.lineWidth, this.height+4*ctx.lineWidth, this.options.radius); + ctx.stroke(); } + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - /** - * handles a keydown event - * - * @param {Event} e - * @returns void - */ - function _handleKey(e) { + ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.options.color.background; - // 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; + ctx.roundRect(this.left, this.top, this.width, this.height, this.options.radius); + ctx.fill(); + ctx.stroke(); - var character = _characterFromEvent(e); + this._label(ctx, this.label, this.x, this.y); + }; - // no character found then stop - if (!character) { - return; - } - if (e.type == 'keyup' && _ignore_next_keyup == character) { - _ignore_next_keyup = false; - return; - } + 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; - _handleCharacter(character, e); + // 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor; + this.growthIndicator = this.width - size; } + }; - /** - * 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'; - } + Node.prototype._drawDatabase = function (ctx) { + this._resizeDatabase(ctx); + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; - /** - * 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); - } + var clusterLineWidth = 2.5; + var borderWidth = this.options.borderWidth; + var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; - /** - * 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) { + ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; - // 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; - } + // draw the outer border + if (this.clusterSize > 1) { + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - if (_MAP.hasOwnProperty(key)) { - _REVERSE_MAP[_MAP[key]] = key; - } - } - } - return _REVERSE_MAP; + 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 : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - /** - * 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) { + ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; + ctx.database(this.x - this.width/2, this.y - this.height*0.5, this.width, this.height); + ctx.fill(); + ctx.stroke(); - // 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'; - } + this._label(ctx, this.label, this.x, this.y); + }; - // modifier keys don't work as expected with keypress, - // switch to keydown - if (action == 'keypress' && modifiers.length) { - action = 'keydown'; - } - return action; + 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.options.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.options.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor; + this.growthIndicator = this.options.radius- 0.5*diameter; } + }; - /** - * 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) { + Node.prototype._drawCircle = function (ctx) { + this._resizeCircle(ctx); + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; - // start off by adding a sequence level record for this combination - // and setting the level to 0 - _sequence_levels[combo] = 0; + var clusterLineWidth = 2.5; + var borderWidth = this.options.borderWidth; + var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; - // if there is no action pick the best one for the first key - // in the sequence - if (!action) { - action = _pickBestAction(keys[0], []); - } + ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; - /** - * 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 outer border + if (this.clusterSize > 1) { + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - /** - * 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); + ctx.circle(this.x, this.y, this.options.radius+2*ctx.lineWidth); + ctx.stroke(); + } + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - // 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); - } + ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; + ctx.circle(this.x, this.y, this.options.radius); + ctx.fill(); + ctx.stroke(); - // weird race condition if a sequence ends with the key - // another sequence begins with - setTimeout(_resetSequences, 10); - }, - i; + this._label(ctx, this.label, this.x, this.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); - } - } + Node.prototype._resizeEllipse = function (ctx) { + if (!this.width) { + var textSize = this.getTextSize(ctx); - /** - * 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.width = textSize.width * 1.5; + this.height = textSize.height * 2; + if (this.width < this.height) { + this.width = this.height; + } + var defaultSize = this.width; - // make sure multiple spaces in a row become a single space - combination = combination.replace(/\s+/g, ' '); + // 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.options.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor; + this.growthIndicator = this.width - defaultSize; + } + }; - var sequence = combination.split(' '), - i, - key, - keys, - modifiers = []; + Node.prototype._drawEllipse = function (ctx) { + this._resizeEllipse(ctx); + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; - // 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 clusterLineWidth = 2.5; + var borderWidth = this.options.borderWidth; + var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; - // take the keys from this pattern and figure out what the actual - // pattern is all about - keys = combination === '+' ? ['+'] : combination.split('+'); + ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; + // draw the outer border + if (this.clusterSize > 1) { + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - // normalize key names - if (_SPECIAL_ALIASES[key]) { - key = _SPECIAL_ALIASES[key]; - } + 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 : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); - // 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'); - } + ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; - // if this key is a modifier then add it to the list of modifiers - if (_isModifier(key)) { - modifiers.push(key); - } - } + ctx.ellipse(this.left, this.top, this.width, this.height); + ctx.fill(); + ctx.stroke(); + this._label(ctx, this.label, this.x, this.y); + }; - // depending on what the key combination is - // we will try to pick the best event for it - action = _pickBestAction(key, modifiers, action); + Node.prototype._drawDot = function (ctx) { + this._drawShape(ctx, 'circle'); + }; - // make sure to initialize array if this is the first time - // a callback is added for this key - if (!_callbacks[key]) { - _callbacks[key] = []; - } + Node.prototype._drawTriangle = function (ctx) { + this._drawShape(ctx, 'triangle'); + }; - // remove an existing match if there is one - _getMatches(key, modifiers, action, !sequence_name, combination); + Node.prototype._drawTriangleDown = function (ctx) { + this._drawShape(ctx, 'triangleDown'); + }; - // 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 - }); - } + Node.prototype._drawSquare = function (ctx) { + this._drawShape(ctx, 'square'); + }; - /** - * 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); - } - } + Node.prototype._drawStar = function (ctx) { + this._drawShape(ctx, 'star'); + }; - // start! - _addEvent(document, 'keypress', _handleKey); - _addEvent(document, 'keydown', _handleKey); - _addEvent(document, 'keyup', _handleKey); + Node.prototype._resizeShape = function (ctx) { + if (!this.width) { + this.options.radius= this.baseRadiusValue; + var size = 2 * this.options.radius; + this.width = size; + this.height = size; - var mousetrap = { + // 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor; + this.growthIndicator = this.width - size; + } + }; - /** - * 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; - }, + Node.prototype._drawShape = function (ctx, shape) { + this._resizeShape(ctx); - /** - * 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; - }, + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; - /** - * 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; - }, + var clusterLineWidth = 2.5; + var borderWidth = this.options.borderWidth; + var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; + var radiusMultiplier = 2; - /** - * 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; - } - }; + // 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; + } - module.exports = mousetrap; + ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; + // draw the outer border + if (this.clusterSize > 1) { + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + ctx[shape](this.x, this.y, this.options.radius+ radiusMultiplier * ctx.lineWidth); + ctx.stroke(); + } + ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); + ctx.lineWidth *= this.networkScaleInv; + ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; + ctx[shape](this.x, this.y, this.options.radius); + ctx.fill(); + ctx.stroke(); -/***/ }, -/* 41 */ -/***/ function(module, exports, __webpack_require__) { + if (this.label) { + this._label(ctx, this.label, this.x, this.y + this.height / 2, undefined, 'top',true); + } + }; - var Emitter = __webpack_require__(10); - var Hammer = __webpack_require__(18); - var util = __webpack_require__(1); - var DataSet = __webpack_require__(7); - var DataView = __webpack_require__(8); - var Range = __webpack_require__(20); - var Core = __webpack_require__(24); - var TimeAxis = __webpack_require__(25); - var CurrentTime = __webpack_require__(27); - var CustomTime = __webpack_require__(29); - var LineGraph = __webpack_require__(42); + 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; - /** - * Create a timeline visualization - * @param {HTMLElement} container - * @param {vis.DataSet | Array | google.visualization.DataTable} [items] - * @param {Object} [options] See Graph2d.setOptions for the available options. - * @constructor - * @extends Core - */ - function Graph2d (container, items, groups, options) { - // if the third element is options, the forth is groups (optionally); - if (!(Array.isArray(groups) || groups instanceof DataSet) && groups instanceof Object) { - var forthArgument = options; - options = groups; - groups = forthArgument; + // 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor; + this.growthIndicator = this.width - (textSize.width + 2 * margin); } + }; - var me = this; - this.defaultOptions = { - start: null, - end: null, + Node.prototype._drawText = function (ctx) { + this._resizeText(ctx); + this.left = this.x - this.width / 2; + this.top = this.y - this.height / 2; - autoResize: true, + this._label(ctx, this.label, this.x, this.y); + }; - orientation: 'bottom', - width: null, - height: null, - maxHeight: null, - minHeight: null - }; - this.options = util.deepExtend({}, this.defaultOptions); - // Create the DOM, props, and emitter - this._create(container); + Node.prototype._label = function (ctx, text, x, y, align, baseline, labelUnderNode) { + if (text && Number(this.options.fontSize) * this.networkScale > this.fontDrawThreshold) { + ctx.font = (this.selected ? "bold " : "") + this.options.fontSize + "px " + this.options.fontFace; - // all components listed here will be repainted automatically - this.components = []; + var lines = text.split('\n'); + var lineCount = lines.length; + var fontSize = (Number(this.options.fontSize) + 4); // TODO: why is this +4 ? + var yLine = y + (1 - lineCount) / 2 * fontSize; + if (labelUnderNode == true) { + yLine = y + (1 - lineCount) / (2 * fontSize); + } - this.body = { - dom: this.dom, - domProps: this.props, - emitter: { - on: this.on.bind(this), - off: this.off.bind(this), - emit: this.emit.bind(this) - }, - hiddenDates: [], - util: { - snap: null, // will be specified after TimeAxis is created - toScreen: me._toScreen.bind(me), - toGlobalScreen: me._toGlobalScreen.bind(me), // this refers to the root.width - toTime: me._toTime.bind(me), - toGlobalTime : me._toGlobalTime.bind(me) + // font fill from edges now for nodes! + var width = ctx.measureText(lines[0]).width; + for (var i = 1; i < lineCount; i++) { + var lineWidth = ctx.measureText(lines[i]).width; + width = lineWidth > width ? lineWidth : width; } - }; + var height = this.options.fontSize * lineCount; + var left = x - width / 2; + var top = y - height / 2; + if (baseline == "top") { + top += 0.5 * fontSize; + } + this.labelDimensions = {top:top,left:left,width:width,height:height,yLine:yLine}; - // range - this.range = new Range(this.body); - this.components.push(this.range); - this.body.range = this.range; + // create the fontfill background + if (this.options.fontFill !== undefined && this.options.fontFill !== null && this.options.fontFill !== "none") { + ctx.fillStyle = this.options.fontFill; + ctx.fillRect(left, top, width, height); + } - // time axis - this.timeAxis = new TimeAxis(this.body); - this.components.push(this.timeAxis); - this.body.util.snap = this.timeAxis.snap.bind(this.timeAxis); + // draw text + ctx.fillStyle = this.options.fontColor || "black"; + ctx.textAlign = align || "center"; + ctx.textBaseline = baseline || "middle"; + for (var i = 0; i < lineCount; i++) { + ctx.fillText(lines[i], x, yLine); + yLine += fontSize; + } + } + }; - // current time bar - this.currentTime = new CurrentTime(this.body); - this.components.push(this.currentTime); - // custom time bar - // Note: time bar will be attached in this.setOptions when selected - this.customTime = new CustomTime(this.body); - this.components.push(this.customTime); + Node.prototype.getTextSize = function(ctx) { + if (this.label !== undefined) { + ctx.font = (this.selected ? "bold " : "") + this.options.fontSize + "px " + this.options.fontFace; - // item set - this.linegraph = new LineGraph(this.body); - this.components.push(this.linegraph); + var lines = this.label.split('\n'), + height = (Number(this.options.fontSize) + 4) * lines.length, + width = 0; - this.itemsData = null; // DataSet - this.groupsData = null; // DataSet + for (var i = 0, iMax = lines.length; i < iMax; i++) { + width = Math.max(width, ctx.measureText(lines[i]).width); + } - // apply options - if (options) { - this.setOptions(options); + return {"width": width, "height": height}; } - - // IMPORTANT: THIS HAPPENS BEFORE SET ITEMS! - if (groups) { - this.setGroups(groups); + else { + return {"width": 0, "height": 0}; } + }; - // create itemset - if (items) { - this.setItems(items); + /** + * 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.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 { - this.redraw(); + return true; } - } + }; - // Extend the functionality from Core - Graph2d.prototype = new Core(); + /** + * 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); + }; /** - * Set items - * @param {vis.DataSet | Array | google.visualization.DataTable | null} items + * 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 */ - Graph2d.prototype.setItems = function(items) { - var initialLoad = (this.itemsData == null); + Node.prototype.setScaleAndPos = function(scale,canvasTopLeft,canvasBottomRight) { + this.networkScaleInv = 1.0/scale; + this.networkScale = scale; + this.canvasTopLeft = canvasTopLeft; + this.canvasBottomRight = canvasBottomRight; + }; - // convert to type DataSet when needed - var newDataSet; - if (!items) { - newDataSet = null; - } - else if (items instanceof DataSet || items instanceof DataView) { - newDataSet = items; + + /** + * 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; + }; + + + + /** + * 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; + }; + + + /** + * Basic preservation of (kinectic) energy + * + * @param massBeforeClustering + */ + Node.prototype.updateVelocity = function(massBeforeClustering) { + var energyBefore = this.vx * this.vx * massBeforeClustering; + //this.vx = (this.vx < 0) ? -Math.sqrt(energyBefore/this.options.mass) : Math.sqrt(energyBefore/this.options.mass); + this.vx = Math.sqrt(energyBefore/this.options.mass); + energyBefore = this.vy * this.vy * massBeforeClustering; + //this.vy = (this.vy < 0) ? -Math.sqrt(energyBefore/this.options.mass) : Math.sqrt(energyBefore/this.options.mass); + this.vy = Math.sqrt(energyBefore/this.options.mass); + }; + + module.exports = Node; + + +/***/ }, +/* 40 */ +/***/ 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 { - // turn an array into a dataset - newDataSet = new DataSet(items, { - type: { - start: 'Date', - end: 'Date' - } - }); + this.container = document.body; } - // set items - this.itemsData = newDataSet; - this.linegraph && this.linegraph.setItems(newDataSet); + // 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' + } + } + } + } - if (initialLoad) { - if (this.options.start != undefined || this.options.end != undefined) { - var start = this.options.start != undefined ? this.options.start : null; - var end = this.options.end != undefined ? this.options.end : null; + this.x = 0; + this.y = 0; + this.padding = 5; - this.setWindow(start, end, {animate: false}); - } - else { - this.fit({animate: false}); - } + 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); + } /** - * Set groups - * @param {vis.DataSet | Array | google.visualization.DataTable} groups + * @param {number} x Horizontal position of the popup window + * @param {number} y Vertical position of the popup window */ - Graph2d.prototype.setGroups = function(groups) { - // convert to type DataSet when needed - var newDataSet; - if (!groups) { - newDataSet = null; - } - else if (groups instanceof DataSet || groups instanceof DataView) { - newDataSet = groups; - } - else { - // turn an array into a dataset - newDataSet = new DataSet(groups); - } - - this.groupsData = newDataSet; - this.linegraph.setGroups(newDataSet); + Popup.prototype.setPosition = function(x, y) { + this.x = parseInt(x); + this.y = parseInt(y); }; /** - * Returns an object containing an SVG element with the icon of the group (size determined by iconWidth and iconHeight), the label of the group (content) and the yAxisOrientation of the group (left or right). - * @param groupId - * @param width - * @param height + * Set the content for the popup window. This can be HTML code or text. + * @param {string | Element} content */ - Graph2d.prototype.getLegend = function(groupId, width, height) { - if (width === undefined) {width = 15;} - if (height === undefined) {height = 15;} - if (this.linegraph.groups[groupId] !== undefined) { - return this.linegraph.groups[groupId].getLegend(width,height); + Popup.prototype.setText = function(content) { + if (content instanceof Element) { + this.frame.innerHTML = ''; + this.frame.appendChild(content); } else { - return "cannot find group:" + groupId; + this.frame.innerHTML = content; // string containing text or HTML } - } + }; /** - * This checks if the visible option of the supplied group (by ID) is true or false. - * @param groupId - * @returns {*} + * Show the popup window + * @param {boolean} show Optional. Show or hide the window */ - Graph2d.prototype.isGroupVisible = function(groupId) { - if (this.linegraph.groups[groupId] !== undefined) { - return (this.linegraph.groups[groupId].visible && (this.linegraph.options.groups.visibility[groupId] === undefined || this.linegraph.options.groups.visibility[groupId] == true)); - } - else { - return false; + Popup.prototype.show = function (show) { + if (show === undefined) { + show = true; } - } + if (show) { + var height = this.frame.clientHeight; + var width = this.frame.clientWidth; + var maxHeight = this.frame.parentNode.clientHeight; + var maxWidth = this.frame.parentNode.clientWidth; - /** - * Get the data range of the item set. - * @returns {{min: Date, max: Date}} range A range with a start and end Date. - * When no minimum is found, min==null - * When no maximum is found, max==null - */ - Graph2d.prototype.getItemRange = function() { - var min = null; - var max = null; + var top = (this.y - height); + if (top + height + this.padding > maxHeight) { + top = maxHeight - height - this.padding; + } + if (top < this.padding) { + top = this.padding; + } - // calculate min from start filed - for (var groupId in this.linegraph.groups) { - if (this.linegraph.groups.hasOwnProperty(groupId)) { - if (this.linegraph.groups[groupId].visible == true) { - for (var i = 0; i < this.linegraph.groups[groupId].itemsData.length; i++) { - var item = this.linegraph.groups[groupId].itemsData[i]; - var value = util.convert(item.x, 'Date').valueOf(); - min = min == null ? value : min > value ? value : min; - max = max == null ? value : max < value ? value : max; - } - } + var left = this.x; + if (left + width + this.padding > maxWidth) { + left = maxWidth - width - this.padding; + } + if (left < this.padding) { + left = this.padding; } - } - return { - min: (min != null) ? new Date(min) : null, - max: (max != null) ? new Date(max) : null - }; + 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"; + }; - - module.exports = Graph2d; + module.exports = Popup; /***/ }, -/* 42 */ +/* 41 */ /***/ function(module, exports, __webpack_require__) { - var util = __webpack_require__(1); - var DOMutil = __webpack_require__(6); - var DataSet = __webpack_require__(7); - var DataView = __webpack_require__(8); - var Component = __webpack_require__(22); - var DataAxis = __webpack_require__(43); - var GraphGroup = __webpack_require__(45); - var Legend = __webpack_require__(46); - - var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items - /** - * This is the constructor of the LineGraph. It requires a Timeline body and options. + * 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. * - * @param body - * @param options - * @constructor + * 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 LineGraph(body, options) { - this.id = util.randomUUID(); - this.body = body; - - this.defaultOptions = { - yAxisOrientation: 'left', - defaultGroup: 'default', - sort: true, - sampling: true, - graphHeight: '400px', - shaded: { - enabled: false, - orientation: 'bottom' // top, bottom - }, - style: 'line', // line, bar - barChart: { - width: 50, - handleOverlap: 'overlap', - align: 'center' // left, center, right - }, - catmullRom: { - enabled: true, - parametrization: 'centripetal', // uniform (alpha = 0.0), chordal (alpha = 1.0), centripetal (alpha = 0.5) - alpha: 0.5 - }, - drawPoints: { - enabled: true, - size: 6, - style: 'square' // square, circle - }, - dataAxis: { - showMinorLabels: true, - showMajorLabels: true, - icons: false, - width: '40px', - visible: true, - customRange: { - left: {min:undefined, max:undefined}, - right: {min:undefined, max:undefined} - } - }, - legend: { - enabled: false, - icons: true, - left: { - visible: true, - position: 'top-left' // top/bottom - left,right - }, - right: { - visible: true, - position: 'top-right' // top/bottom - left,right - } - }, - groups: { - visibility: {} - } - }; - - // options is shared by this ItemSet and all its items - this.options = util.extend({}, this.defaultOptions); - this.dom = {}; - this.props = {}; - this.hammer = null; - this.groups = {}; - this.abortedGraphUpdate = false; - - var me = this; - this.itemsData = null; // DataSet - this.groupsData = null; // DataSet - - // listeners for the DataSet of the items - this.itemListeners = { - 'add': function (event, params, senderId) { - me._onAdd(params.items); - }, - 'update': function (event, params, senderId) { - me._onUpdate(params.items); - }, - 'remove': function (event, params, senderId) { - me._onRemove(params.items); - } - }; - - // listeners for the DataSet of the groups - this.groupListeners = { - 'add': function (event, params, senderId) { - me._onAddGroups(params.items); - }, - 'update': function (event, params, senderId) { - me._onUpdateGroups(params.items); - }, - 'remove': function (event, params, senderId) { - me._onRemoveGroups(params.items); - } - }; - - this.items = {}; // object with an Item for every data item - this.selection = []; // list with the ids of all selected nodes - this.lastStart = this.body.range.start; - this.touchParams = {}; // stores properties while dragging + function parseDOT (data) { + dot = data; + return parseGraph(); + } - this.svgElements = {}; - this.setOptions(options); - this.groupsUsingDefaultStyles = [0]; + // token types enumeration + var TOKENTYPE = { + NULL : 0, + DELIMITER : 1, + IDENTIFIER: 2, + UNKNOWN : 3 + }; - this.body.emitter.on("rangechanged", function() { - me.lastStart = me.body.range.start; - me.svg.style.left = util.option.asSize(-me.width); - me._updateGraph.apply(me); - }); + // map with all delimiters + var DELIMITERS = { + '{': true, + '}': true, + '[': true, + ']': true, + ';': true, + '=': true, + ',': true, - // create the HTML DOM - this._create(); - this.body.emitter.emit("change"); - } + '->': true, + '--': true + }; - LineGraph.prototype = new Component(); + 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 /** - * Create the HTML DOM for the ItemSet + * 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. */ - LineGraph.prototype._create = function(){ - var frame = document.createElement('div'); - frame.className = 'LineGraph'; - this.dom.frame = frame; - - // create svg element for graph drawing. - this.svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); - this.svg.style.position = "relative"; - this.svg.style.height = ('' + this.options.graphHeight).replace("px",'') + 'px'; - this.svg.style.display = "block"; - frame.appendChild(this.svg); - - // data axis - this.options.dataAxis.orientation = 'left'; - this.yAxisLeft = new DataAxis(this.body, this.options.dataAxis, this.svg, this.options.groups); - - this.options.dataAxis.orientation = 'right'; - this.yAxisRight = new DataAxis(this.body, this.options.dataAxis, this.svg, this.options.groups); - delete this.options.dataAxis.orientation; - - // legends - this.legendLeft = new Legend(this.body, this.options.legend, 'left', this.options.groups); - this.legendRight = new Legend(this.body, this.options.legend, 'right', this.options.groups); - - this.show(); - }; + function first() { + index = 0; + c = dot.charAt(0); + } /** - * set the options of the LineGraph. the mergeOptions is used for subObjects that have an enabled element. - * @param options + * 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. */ - LineGraph.prototype.setOptions = function(options) { - if (options) { - var fields = ['sampling','defaultGroup','graphHeight','yAxisOrientation','style','barChart','dataAxis','sort','groups']; - util.selectiveDeepExtend(fields, this.options, options); - util.mergeOptions(this.options, options,'catmullRom'); - util.mergeOptions(this.options, options,'drawPoints'); - util.mergeOptions(this.options, options,'shaded'); - util.mergeOptions(this.options, options,'legend'); - - if (options.catmullRom) { - if (typeof options.catmullRom == 'object') { - if (options.catmullRom.parametrization) { - if (options.catmullRom.parametrization == 'uniform') { - this.options.catmullRom.alpha = 0; - } - else if (options.catmullRom.parametrization == 'chordal') { - this.options.catmullRom.alpha = 1.0; - } - else { - this.options.catmullRom.parametrization = 'centripetal'; - this.options.catmullRom.alpha = 0.5; - } - } - } - } - - if (this.yAxisLeft) { - if (options.dataAxis !== undefined) { - this.yAxisLeft.setOptions(this.options.dataAxis); - this.yAxisRight.setOptions(this.options.dataAxis); - } - } - - if (this.legendLeft) { - if (options.legend !== undefined) { - this.legendLeft.setOptions(this.options.legend); - this.legendRight.setOptions(this.options.legend); - } - } - - if (this.groups.hasOwnProperty(UNGROUPED)) { - this.groups[UNGROUPED].setOptions(options); - } - } - if (this.dom.frame) { - this._updateGraph(); - } - }; + function next() { + index++; + c = dot.charAt(index); + } /** - * Hide the component from the DOM + * Preview the next character from the dot file. + * @return {String} cNext */ - LineGraph.prototype.hide = function() { - // remove the frame containing the items - if (this.dom.frame.parentNode) { - this.dom.frame.parentNode.removeChild(this.dom.frame); - } - }; + function nextPreview() { + return dot.charAt(index + 1); + } /** - * Show the component in the DOM (when not already visible). - * @return {Boolean} changed + * Test whether given character is alphabetic or numeric + * @param {String} c + * @return {Boolean} isAlphaNumeric */ - LineGraph.prototype.show = function() { - // show frame containing the items - if (!this.dom.frame.parentNode) { - this.body.dom.center.appendChild(this.dom.frame); - } - }; - + var regexAlphaNumeric = /[a-zA-Z_0-9.:#]/; + function isAlphaNumeric(c) { + return regexAlphaNumeric.test(c); + } /** - * Set items - * @param {vis.DataSet | null} items + * Merge all properties of object b into object b + * @param {Object} a + * @param {Object} b + * @return {Object} a */ - LineGraph.prototype.setItems = function(items) { - var me = this, - ids, - oldItemsData = this.itemsData; - - // replace the dataset - if (!items) { - this.itemsData = null; - } - else if (items instanceof DataSet || items instanceof DataView) { - this.itemsData = items; - } - else { - throw new TypeError('Data must be an instance of DataSet or DataView'); + function merge (a, b) { + if (!a) { + a = {}; } - if (oldItemsData) { - // unsubscribe from old dataset - util.forEach(this.itemListeners, function (callback, event) { - oldItemsData.off(event, callback); - }); - - // remove all drawn items - ids = oldItemsData.getIds(); - this._onRemove(ids); + if (b) { + for (var name in b) { + if (b.hasOwnProperty(name)) { + a[name] = b[name]; + } + } } + return a; + } - if (this.itemsData) { - // subscribe to new dataset - var id = this.id; - util.forEach(this.itemListeners, function (callback, event) { - me.itemsData.on(event, callback, id); - }); - - // add all new items - ids = this.itemsData.getIds(); - this._onAdd(ids); + /** + * 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; + } } - this._updateUngrouped(); - this._updateGraph(); - this.redraw(); - }; + } /** - * Set groups - * @param {vis.DataSet} groups + * 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 */ - LineGraph.prototype.setGroups = function(groups) { - var me = this, - ids; - - // unsubscribe from current dataset - if (this.groupsData) { - util.forEach(this.groupListeners, function (callback, event) { - me.groupsData.unsubscribe(event, callback); - }); + function addNode(graph, node) { + var i, len; + var current = null; - // remove all drawn groups - ids = this.groupsData.getIds(); - this.groupsData = null; - this._onRemoveGroups(ids); // note: this will cause a redraw + // 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; } - // replace the dataset - if (!groups) { - this.groupsData = null; - } - else if (groups instanceof DataSet || groups instanceof DataView) { - this.groupsData = groups; + // 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; + } + } } - else { - throw new TypeError('Data must be an instance of DataSet or DataView'); + + if (!current) { + // this is a new node + current = { + id: node.id + }; + if (graph.node) { + // clone default attributes + current.attr = merge(current.attr, graph.node); + } } - if (this.groupsData) { - // subscribe to new dataset - var id = this.id; - util.forEach(this.groupListeners, function (callback, event) { - me.groupsData.on(event, callback, id); - }); + // add node to this (sub)graph and all its parent graphs + for (i = graphs.length - 1; i >= 0; i--) { + var g = graphs[i]; - // draw all ms - ids = this.groupsData.getIds(); - this._onAddGroups(ids); + if (!g.nodes) { + g.nodes = []; + } + if (g.nodes.indexOf(current) == -1) { + g.nodes.push(current); + } } - this._onUpdate(); - }; + // merge attributes + if (node.attr) { + current.attr = merge(current.attr, node.attr); + } + } /** - * Update the datapoints - * @param [ids] - * @private + * Add an edge to a graph object + * @param {Object} graph + * @param {Object} edge */ - LineGraph.prototype._onUpdate = function(ids) { - this._updateUngrouped(); - this._updateAllGroupData(); - this._updateGraph(); - this.redraw(); - }; - LineGraph.prototype._onAdd = function (ids) {this._onUpdate(ids);}; - LineGraph.prototype._onRemove = function (ids) {this._onUpdate(ids);}; - LineGraph.prototype._onUpdateGroups = function (groupIds) { - for (var i = 0; i < groupIds.length; i++) { - var group = this.groupsData.get(groupIds[i]); - this._updateGroup(group, groupIds[i]); + 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 } + } - this._updateGraph(); - this.redraw(); - }; - LineGraph.prototype._onAddGroups = function (groupIds) {this._onUpdateGroups(groupIds);}; + /** + * 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 + }; - LineGraph.prototype._onRemoveGroups = function (groupIds) { - for (var i = 0; i < groupIds.length; i++) { - if (!this.groups.hasOwnProperty(groupIds[i])) { - if (this.groups[groupIds[i]].options.yAxisOrientation == 'right') { - this.yAxisRight.removeGroup(groupIds[i]); - this.legendRight.removeGroup(groupIds[i]); - this.legendRight.redraw(); - } - else { - this.yAxisLeft.removeGroup(groupIds[i]); - this.legendLeft.removeGroup(groupIds[i]); - this.legendLeft.redraw(); - } - delete this.groups[groupIds[i]]; - } + if (graph.edge) { + edge.attr = merge({}, graph.edge); // clone default attributes } - this._updateUngrouped(); - this._updateGraph(); - this.redraw(); - }; + edge.attr = merge(edge.attr || {}, attr); // merge attributes + + return edge; + } /** - * update a group object - * - * @param group - * @param groupId - * @private + * Get next token in the current dot file. + * The token and token type are available as token and tokenType */ - LineGraph.prototype._updateGroup = function (group, groupId) { - if (!this.groups.hasOwnProperty(groupId)) { - this.groups[groupId] = new GraphGroup(group, groupId, this.options, this.groupsUsingDefaultStyles); - if (this.groups[groupId].options.yAxisOrientation == 'right') { - this.yAxisRight.addGroup(groupId, this.groups[groupId]); - this.legendRight.addGroup(groupId, this.groups[groupId]); - } - else { - this.yAxisLeft.addGroup(groupId, this.groups[groupId]); - this.legendLeft.addGroup(groupId, this.groups[groupId]); - } - } - else { - this.groups[groupId].update(group); - if (this.groups[groupId].options.yAxisOrientation == 'right') { - this.yAxisRight.updateGroup(groupId, this.groups[groupId]); - this.legendRight.updateGroup(groupId, this.groups[groupId]); - } - else { - this.yAxisLeft.updateGroup(groupId, this.groups[groupId]); - this.legendLeft.updateGroup(groupId, this.groups[groupId]); - } + function getToken() { + tokenType = TOKENTYPE.NULL; + token = ''; + + // skip over whitespaces + while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter + next(); } - this.legendLeft.redraw(); - this.legendRight.redraw(); - }; - LineGraph.prototype._updateAllGroupData = function () { - if (this.itemsData != null) { - var groupsContent = {}; - var groupId; - for (groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - groupsContent[groupId] = []; + 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--; } - } - for (var itemId in this.itemsData._data) { - if (this.itemsData._data.hasOwnProperty(itemId)) { - var item = this.itemsData._data[itemId]; - item.x = util.convert(item.x,"Date"); - groupsContent[item.group].push(item); + 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; } } - for (groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - this.groups[groupId].setItems(groupsContent[groupId]); + if (c == '/' && nextPreview() == '/') { + // skip line comment + while (c != '' && c != '\n') { + next(); } + isComment = true; } - } - }; - - /** - * Create or delete the group holding all ungrouped items. This group is used when - * there are no groups specified. This anonymous group is called 'graph'. - * @protected - */ - LineGraph.prototype._updateUngrouped = function() { - if (this.itemsData && this.itemsData != null) { - var ungroupedCounter = 0; - for (var itemId in this.itemsData._data) { - if (this.itemsData._data.hasOwnProperty(itemId)) { - var item = this.itemsData._data[itemId]; - if (item != undefined) { - if (item.hasOwnProperty('group')) { - if (item.group === undefined) { - item.group = UNGROUPED; - } - } - else { - item.group = UNGROUPED; - } - ungroupedCounter = item.group == UNGROUPED ? ungroupedCounter + 1 : ungroupedCounter; + 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; } - if (ungroupedCounter == 0) { - delete this.groups[UNGROUPED]; - this.legendLeft.removeGroup(UNGROUPED); - this.legendRight.removeGroup(UNGROUPED); - this.yAxisLeft.removeGroup(UNGROUPED); - this.yAxisRight.removeGroup(UNGROUPED); - } - else { - var group = {id: UNGROUPED, content: this.options.defaultGroup}; - this._updateGroup(group, UNGROUPED); + // skip over whitespaces + while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter + next(); } } - else { - delete this.groups[UNGROUPED]; - this.legendLeft.removeGroup(UNGROUPED); - this.legendRight.removeGroup(UNGROUPED); - this.yAxisLeft.removeGroup(UNGROUPED); - this.yAxisRight.removeGroup(UNGROUPED); - } - - this.legendLeft.redraw(); - this.legendRight.redraw(); - }; + while (isComment); + // check for end of dot file + if (c == '') { + // token is still empty + tokenType = TOKENTYPE.DELIMITER; + return; + } - /** - * Redraw the component, mandatory function - * @return {boolean} Returns true if the component is resized - */ - LineGraph.prototype.redraw = function() { - var resized = false; + // check for delimiters consisting of 2 characters + var c2 = c + nextPreview(); + if (DELIMITERS[c2]) { + tokenType = TOKENTYPE.DELIMITER; + token = c2; + next(); + next(); + return; + } - this.svg.style.height = ('' + this.options.graphHeight).replace('px','') + 'px'; - if (this.lastWidth === undefined && this.width || this.lastWidth != this.width) { - resized = true; + // check for delimiters consisting of 1 character + if (DELIMITERS[c]) { + tokenType = TOKENTYPE.DELIMITER; + token = c; + next(); + return; } - // check if this component is resized - resized = this._isResized() || resized; - // check whether zoomed (in that case we need to re-stack everything) - var visibleInterval = this.body.range.end - this.body.range.start; - var zoomed = (visibleInterval != this.lastVisibleInterval) || (this.width != this.lastWidth); - this.lastVisibleInterval = visibleInterval; - this.lastWidth = this.width; - // calculate actual size and position - this.width = this.dom.frame.offsetWidth; + // 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(); - // the svg element is three times as big as the width, this allows for fully dragging left and right - // without reloading the graph. the controls for this are bound to events in the constructor - if (resized == true) { - this.svg.style.width = util.option.asSize(3*this.width); - this.svg.style.left = util.option.asSize(-this.width); + 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; } - if (zoomed == true || this.abortedGraphUpdate == true) { - this._updateGraph(); - } - else { - // move the whole svg while dragging - if (this.lastStart != 0) { - var offset = this.body.range.start - this.lastStart; - var range = this.body.range.end - this.body.range.start; - if (this.width != 0) { - var rangePerPixelInv = this.width/range; - var xOffset = offset * rangePerPixelInv; - this.svg.style.left = (-this.width - xOffset) + "px"; + // 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.legendLeft.redraw(); - this.legendRight.redraw(); - - return resized; - }; + // 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) + '"'); + } /** - * Update and redraw the graph. - * + * Parse a graph. + * @returns {Object} graph */ - LineGraph.prototype._updateGraph = function () { - // reset the svg elements - DOMutil.prepareElements(this.svgElements); - if (this.width != 0 && this.itemsData != null) { - var group, i; - var preprocessedGroupData = {}; - var processedGroupData = {}; - var groupRanges = {}; - var changeCalled = false; - - // getting group Ids - var groupIds = []; - for (var groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - group = this.groups[groupId]; - if (group.visible == true && (this.options.groups.visibility[groupId] === undefined || this.options.groups.visibility[groupId] == true)) { - groupIds.push(groupId); - } - } - } - if (groupIds.length > 0) { - // this is the range of the SVG canvas - var minDate = this.body.util.toGlobalTime(- this.body.domProps.root.width); - var maxDate = this.body.util.toGlobalTime(2 * this.body.domProps.root.width); - var groupsData = {}; - // fill groups data - this._getRelevantData(groupIds, groupsData, minDate, maxDate); - // we transform the X coordinates to detect collisions - for (i = 0; i < groupIds.length; i++) { - preprocessedGroupData[groupIds[i]] = this._convertXcoordinates(groupsData[groupIds[i]]); - } - // now all needed data has been collected we start the processing. - this._getYRanges(groupIds, preprocessedGroupData, groupRanges); + function parseGraph() { + var graph = {}; - // update the Y axis first, we use this data to draw at the correct Y points - // changeCalled is required to clean the SVG on a change emit. - changeCalled = this._updateYAxis(groupIds, groupRanges); - if (changeCalled == true) { - DOMutil.cleanupElements(this.svgElements); - this.abortedGraphUpdate = true; - this.body.emitter.emit("change"); - return; - } - this.abortedGraphUpdate = false; + first(); + getToken(); - // With the yAxis scaled correctly, use this to get the Y values of the points. - for (i = 0; i < groupIds.length; i++) { - group = this.groups[groupIds[i]]; - processedGroupData[groupIds[i]] = this._convertYcoordinates(groupsData[groupIds[i]], group); - } + // optional strict keyword + if (token == 'strict') { + graph.strict = true; + getToken(); + } + // graph or digraph keyword + if (token == 'graph' || token == 'digraph') { + graph.type = token; + getToken(); + } - // draw the groups - for (i = 0; i < groupIds.length; i++) { - group = this.groups[groupIds[i]]; - if (group.options.style == 'line') { - this._drawLineGraph(processedGroupData[groupIds[i]], group); - } - } - this._drawBarGraphs(groupIds, processedGroupData); - } + // optional graph id + if (tokenType == TOKENTYPE.IDENTIFIER) { + graph.id = token; + getToken(); } - // cleanup unused svg elements - DOMutil.cleanupElements(this.svgElements); - }; + // open angle bracket + if (token != '{') { + throw newSyntaxError('Angle bracket { expected'); + } + getToken(); + // statements + parseStatements(graph); - LineGraph.prototype._getRelevantData = function (groupIds, groupsData, minDate, maxDate) { - // first select and preprocess the data from the datasets. - // the groups have their preselection of data, we now loop over this data to see - // what data we need to draw. Sorted data is much faster. - // more optimization is possible by doing the sampling before and using the binary search - // to find the end date to determine the increment. - var group, i, j, item; - if (groupIds.length > 0) { - for (i = 0; i < groupIds.length; i++) { - group = this.groups[groupIds[i]]; - groupsData[groupIds[i]] = []; - var dataContainer = groupsData[groupIds[i]]; - // optimization for sorted data - if (group.options.sort == true) { - var guess = Math.max(0, util.binarySearchGeneric(group.itemsData, minDate, 'x', 'before')); - for (j = guess; j < group.itemsData.length; j++) { - item = group.itemsData[j]; - if (item !== undefined) { - if (item.x > maxDate) { - dataContainer.push(item); - break; - } - else { - dataContainer.push(item); - } - } - } - } - else { - for (j = 0; j < group.itemsData.length; j++) { - item = group.itemsData[j]; - if (item !== undefined) { - if (item.x > minDate && item.x < maxDate) { - dataContainer.push(item); - } - } - } - } - } + // close angle bracket + if (token != '}') { + throw newSyntaxError('Angle bracket } expected'); } + getToken(); - this._applySampling(groupIds, groupsData); - }; - - LineGraph.prototype._applySampling = function (groupIds, groupsData) { - var group; - if (groupIds.length > 0) { - for (var i = 0; i < groupIds.length; i++) { - group = this.groups[groupIds[i]]; - if (group.options.sampling == true) { - var dataContainer = groupsData[groupIds[i]]; - if (dataContainer.length > 0) { - var increment = 1; - var amountOfPoints = dataContainer.length; + // end of file + if (token !== '') { + throw newSyntaxError('End of file expected'); + } + getToken(); - // the global screen is used because changing the width of the yAxis may affect the increment, resulting in an endless loop - // of width changing of the yAxis. - var xDistance = this.body.util.toGlobalScreen(dataContainer[dataContainer.length - 1].x) - this.body.util.toGlobalScreen(dataContainer[0].x); - var pointsPerPixel = amountOfPoints / xDistance; - increment = Math.min(Math.ceil(0.2 * amountOfPoints), Math.max(1, Math.round(pointsPerPixel))); + // remove temporary default properties + delete graph.node; + delete graph.edge; + delete graph.graph; - var sampledData = []; - for (var j = 0; j < amountOfPoints; j += increment) { - sampledData.push(dataContainer[j]); + return graph; + } - } - groupsData[groupIds[i]] = sampledData; - } - } + /** + * Parse a list with statements. + * @param {Object} graph + */ + function parseStatements (graph) { + while (token !== '' && token != '}') { + parseStatement(graph); + if (token == ';') { + getToken(); } } - }; + } - LineGraph.prototype._getYRanges = function (groupIds, groupsData, groupRanges) { - var groupData, group, i,j; - var barCombinedDataLeft = []; - var barCombinedDataRight = []; - var barCombinedData; - if (groupIds.length > 0) { - for (i = 0; i < groupIds.length; i++) { - groupData = groupsData[groupIds[i]]; - if (groupData.length > 0) { - group = this.groups[groupIds[i]]; - if (group.options.style == 'line' || group.options.barChart.handleOverlap != "stack") { - var yMin = groupData[0].y; - var yMax = groupData[0].y; - for (j = 0; j < groupData.length; j++) { - yMin = yMin > groupData[j].y ? groupData[j].y : yMin; - yMax = yMax < groupData[j].y ? groupData[j].y : yMax; - } - groupRanges[groupIds[i]] = {min: yMin, max: yMax, yAxisOrientation: group.options.yAxisOrientation}; - } - else if (group.options.style == 'bar') { - if (group.options.yAxisOrientation == 'left') { - barCombinedData = barCombinedDataLeft; - } - else { - barCombinedData = barCombinedDataRight; - } + /** + * 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); - groupRanges[groupIds[i]] = {min: 0, max: 0, yAxisOrientation: group.options.yAxisOrientation, ignore: true}; + return; + } - // combine data - for (j = 0; j < groupData.length; j++) { - barCombinedData.push({ - x: groupData[j].x, - y: groupData[j].y, - groupId: groupIds[i] - }); - } - } - } - } + // parse an attribute statement + var attr = parseAttributeStatement(graph); + if (attr) { + return; + } - var intersections; - if (barCombinedDataLeft.length > 0) { - // sort by time and by group - barCombinedDataLeft.sort(function (a, b) { - if (a.x == b.x) { - return a.groupId - b.groupId; - } else { - return a.x - b.x; - } - }); - intersections = {}; - this._getDataIntersections(intersections, barCombinedDataLeft); - groupRanges["__barchartLeft"] = this._getStackedBarYRange(intersections, barCombinedDataLeft); - groupRanges["__barchartLeft"].yAxisOrientation = "left"; - groupIds.push("__barchartLeft"); - } - if (barCombinedDataRight.length > 0) { - // sort by time and by group - barCombinedDataRight.sort(function (a, b) { - if (a.x == b.x) { - return a.groupId - b.groupId; - } else { - return a.x - b.x; - } - }); - intersections = {}; - this._getDataIntersections(intersections, barCombinedDataRight); - groupRanges["__barchartRight"] = this._getStackedBarYRange(intersections, barCombinedDataRight); - groupRanges["__barchartRight"].yAxisOrientation = "right"; - groupIds.push("__barchartRight"); - } + // parse node + if (tokenType != TOKENTYPE.IDENTIFIER) { + throw newSyntaxError('Identifier expected'); } - }; + var id = token; // id can be a string or a number + getToken(); - LineGraph.prototype._getStackedBarYRange = function (intersections, combinedData) { - var key; - var yMin = combinedData[0].y; - var yMax = combinedData[0].y; - for (var i = 0; i < combinedData.length; i++) { - key = combinedData[i].x; - if (intersections[key] === undefined) { - yMin = yMin > combinedData[i].y ? combinedData[i].y : yMin; - yMax = yMax < combinedData[i].y ? combinedData[i].y : yMax; - } - else { - intersections[key].accumulated += combinedData[i].y; + 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] " } - for (var xpos in intersections) { - if (intersections.hasOwnProperty(xpos)) { - yMin = yMin > intersections[xpos].accumulated ? intersections[xpos].accumulated : yMin; - yMax = yMax < intersections[xpos].accumulated ? intersections[xpos].accumulated : yMax; - } + else { + parseNodeStatement(graph, id); } - - return {min: yMin, max: yMax}; - }; - + } /** - * this sets the Y ranges for the Y axis. It also determines which of the axis should be shown or hidden. - * @param {Array} groupIds - * @param {Object} groupRanges - * @private + * Parse a subgraph + * @param {Object} graph parent graph object + * @return {Object | null} subgraph */ - LineGraph.prototype._updateYAxis = function (groupIds, groupRanges) { - var changeCalled = false; - var yAxisLeftUsed = false; - var yAxisRightUsed = false; - var minLeft = 1e9, minRight = 1e9, maxLeft = -1e9, maxRight = -1e9, minVal, maxVal; - // if groups are present - if (groupIds.length > 0) { - for (var i = 0; i < groupIds.length; i++) { - if (groupRanges.hasOwnProperty(groupIds[i])) { - if (groupRanges[groupIds[i]].ignore !== true) { - minVal = groupRanges[groupIds[i]].min; - maxVal = groupRanges[groupIds[i]].max; + function parseSubgraph (graph) { + var subgraph = null; - if (groupRanges[groupIds[i]].yAxisOrientation == 'left') { - yAxisLeftUsed = true; - minLeft = minLeft > minVal ? minVal : minLeft; - maxLeft = maxLeft < maxVal ? maxVal : maxLeft; - } - else { - yAxisRightUsed = true; - minRight = minRight > minVal ? minVal : minRight; - maxRight = maxRight < maxVal ? maxVal : maxRight; - } - } - } + // optional subgraph keyword + if (token == 'subgraph') { + subgraph = {}; + subgraph.type = 'subgraph'; + getToken(); + + // optional graph id + if (tokenType == TOKENTYPE.IDENTIFIER) { + subgraph.id = token; + getToken(); } + } - if (yAxisLeftUsed == true) { - this.yAxisLeft.setRange(minLeft, maxLeft); + // open angle bracket + if (token == '{') { + getToken(); + + if (!subgraph) { + subgraph = {}; } - if (yAxisRightUsed == true) { - this.yAxisRight.setRange(minRight, maxRight); + 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(); - changeCalled = this._toggleAxisVisiblity(yAxisLeftUsed , this.yAxisLeft) || changeCalled; - changeCalled = this._toggleAxisVisiblity(yAxisRightUsed, this.yAxisRight) || changeCalled; + // remove temporary default properties + delete subgraph.node; + delete subgraph.edge; + delete subgraph.graph; + delete subgraph.parent; - if (yAxisRightUsed == true && yAxisLeftUsed == true) { - this.yAxisLeft.drawIcons = true; - this.yAxisRight.drawIcons = true; - } - else { - this.yAxisLeft.drawIcons = false; - this.yAxisRight.drawIcons = false; + // register at the parent graph + if (!graph.subgraphs) { + graph.subgraphs = []; + } + graph.subgraphs.push(subgraph); } - this.yAxisRight.master = !yAxisLeftUsed; + return subgraph; + } - if (this.yAxisRight.master == false) { - if (yAxisRightUsed == true) {this.yAxisLeft.lineOffset = this.yAxisRight.width;} - else {this.yAxisLeft.lineOffset = 0;} + /** + * 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. + */ + function parseAttributeStatement (graph) { + // attribute statements + if (token == 'node') { + getToken(); - changeCalled = this.yAxisLeft.redraw() || changeCalled; - this.yAxisRight.stepPixelsForced = this.yAxisLeft.stepPixels; - changeCalled = this.yAxisRight.redraw() || changeCalled; - } - else { - changeCalled = this.yAxisRight.redraw() || changeCalled; + // node attributes + graph.node = parseAttributeList(); + return 'node'; } + else if (token == 'edge') { + getToken(); - // clean the accumulated lists - if (groupIds.indexOf("__barchartLeft") != -1) { - groupIds.splice(groupIds.indexOf("__barchartLeft"),1); + // edge attributes + graph.edge = parseAttributeList(); + return 'edge'; } - if (groupIds.indexOf("__barchartRight") != -1) { - groupIds.splice(groupIds.indexOf("__barchartRight"),1); + else if (token == 'graph') { + getToken(); + + // graph attributes + graph.graph = parseAttributeList(); + return 'graph'; } - return changeCalled; - }; + return null; + } /** - * This shows or hides the Y axis if needed. If there is a change, the changed event is emitted by the updateYAxis function - * - * @param {boolean} axisUsed - * @returns {boolean} - * @private - * @param axis + * parse a node statement + * @param {Object} graph + * @param {String | Number} id */ - LineGraph.prototype._toggleAxisVisiblity = function (axisUsed, axis) { - var changed = false; - if (axisUsed == false) { - if (axis.dom.frame.parentNode) { - axis.hide(); - changed = true; - } - } - else { - if (!axis.dom.frame.parentNode) { - axis.show(); - changed = true; - } + function parseNodeStatement(graph, id) { + // node statement + var node = { + id: id + }; + var attr = parseAttributeList(); + if (attr) { + node.attr = attr; } - return changed; - }; + addNode(graph, node); + // edge statements + parseEdge(graph, id); + } /** - * draw a bar graph - * - * @param groupIds - * @param processedGroupData + * Parse an edge or a series of edges + * @param {Object} graph + * @param {String | Number} from Id of the from node */ - LineGraph.prototype._drawBarGraphs = function (groupIds, processedGroupData) { - var combinedData = []; - var intersections = {}; - var coreDistance; - var key, drawData; - var group; - var i,j; - var barPoints = 0; + function parseEdge(graph, from) { + while (token == '->' || token == '--') { + var to; + var type = token; + getToken(); - // combine all barchart data - for (i = 0; i < groupIds.length; i++) { - group = this.groups[groupIds[i]]; - if (group.options.style == 'bar') { - if (group.visible == true && (this.options.groups.visibility[groupIds[i]] === undefined || this.options.groups.visibility[groupIds[i]] == true)) { - for (j = 0; j < processedGroupData[groupIds[i]].length; j++) { - combinedData.push({ - x: processedGroupData[groupIds[i]][j].x, - y: processedGroupData[groupIds[i]][j].y, - groupId: groupIds[i] - }); - barPoints += 1; - } + var subgraph = parseSubgraph(graph); + if (subgraph) { + to = subgraph; + } + else { + if (tokenType != TOKENTYPE.IDENTIFIER) { + throw newSyntaxError('Identifier or subgraph expected'); } + to = token; + addNode(graph, { + id: to + }); + getToken(); } - } - if (barPoints == 0) {return;} + // parse edge attributes + var attr = parseAttributeList(); - // sort by time and by group - combinedData.sort(function (a, b) { - if (a.x == b.x) { - return a.groupId - b.groupId; - } else { - return a.x - b.x; - } - }); + // create edge + var edge = createEdge(graph, from, to, type, attr); + addEdge(graph, edge); - // get intersections - this._getDataIntersections(intersections, combinedData); + from = to; + } + } - // plot barchart - for (i = 0; i < combinedData.length; i++) { - group = this.groups[combinedData[i].groupId]; - var minWidth = 0.1 * group.options.barChart.width; + /** + * Parse a set with attributes, + * for example [label="1.000", shape=solid] + * @return {Object | null} attr + */ + function parseAttributeList() { + var attr = null; - key = combinedData[i].x; - var heightOffset = 0; - if (intersections[key] === undefined) { - if (i+1 < combinedData.length) {coreDistance = Math.abs(combinedData[i+1].x - key);} - if (i > 0) {coreDistance = Math.min(coreDistance,Math.abs(combinedData[i-1].x - key));} - drawData = this._getSafeDrawData(coreDistance, group, minWidth); - } - else { - var nextKey = i + (intersections[key].amount - intersections[key].resolved); - var prevKey = i - (intersections[key].resolved + 1); - if (nextKey < combinedData.length) {coreDistance = Math.abs(combinedData[nextKey].x - key);} - if (prevKey > 0) {coreDistance = Math.min(coreDistance,Math.abs(combinedData[prevKey].x - key));} - drawData = this._getSafeDrawData(coreDistance, group, minWidth); - intersections[key].resolved += 1; + while (token == '[') { + getToken(); + attr = {}; + while (token !== '' && token != ']') { + if (tokenType != TOKENTYPE.IDENTIFIER) { + throw newSyntaxError('Attribute name expected'); + } + var name = token; - if (group.options.barChart.handleOverlap == 'stack') { - heightOffset = intersections[key].accumulated; - intersections[key].accumulated += group.zeroPosition - combinedData[i].y; + getToken(); + if (token != '=') { + throw newSyntaxError('Equal sign = expected'); } - else if (group.options.barChart.handleOverlap == 'sideBySide') { - drawData.width = drawData.width / intersections[key].amount; - drawData.offset += (intersections[key].resolved) * drawData.width - (0.5*drawData.width * (intersections[key].amount+1)); - if (group.options.barChart.align == 'left') {drawData.offset -= 0.5*drawData.width;} - else if (group.options.barChart.align == 'right') {drawData.offset += 0.5*drawData.width;} + 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(); } } - DOMutil.drawBar(combinedData[i].x + drawData.offset, combinedData[i].y - heightOffset, drawData.width, group.zeroPosition - combinedData[i].y, group.className + ' bar', this.svgElements, this.svg); - // draw points - if (group.options.drawPoints.enabled == true) { - DOMutil.drawPoint(combinedData[i].x + drawData.offset, combinedData[i].y - heightOffset, group, this.svgElements, this.svg); + + if (token != ']') { + throw newSyntaxError('Bracket ] expected'); } + getToken(); } - }; + + return attr; + } /** - * Fill the intersections object with counters of how many datapoints share the same x coordinates - * @param intersections - * @param combinedData - * @private + * Create a syntax error with extra information on current token and index. + * @param {String} message + * @returns {SyntaxError} err */ - LineGraph.prototype._getDataIntersections = function (intersections, combinedData) { - // get intersections - var coreDistance; - for (var i = 0; i < combinedData.length; i++) { - if (i + 1 < combinedData.length) { - coreDistance = Math.abs(combinedData[i + 1].x - combinedData[i].x); - } - if (i > 0) { - coreDistance = Math.min(coreDistance, Math.abs(combinedData[i - 1].x - combinedData[i].x)); - } - if (coreDistance == 0) { - if (intersections[combinedData[i].x] === undefined) { - intersections[combinedData[i].x] = {amount: 0, resolved: 0, accumulated: 0}; - } - intersections[combinedData[i].x].amount += 1; - } - } - }; + function newSyntaxError(message) { + return new SyntaxError(message + ', got "' + chop(token, 30) + '" (char ' + index + ')'); + } /** - * Get the width and offset for bargraphs based on the coredistance between datapoints - * - * @param coreDistance - * @param group - * @param minWidth - * @returns {{width: Number, offset: Number}} - * @private + * Chop off text after a maximum length + * @param {String} text + * @param {Number} maxLength + * @returns {String} */ - LineGraph.prototype._getSafeDrawData = function (coreDistance, group, minWidth) { - var width, offset; - if (coreDistance < group.options.barChart.width && coreDistance > 0) { - width = coreDistance < minWidth ? minWidth : coreDistance; - - offset = 0; // recalculate offset with the new width; - if (group.options.barChart.align == 'left') { - offset -= 0.5 * coreDistance; - } - else if (group.options.barChart.align == 'right') { - offset += 0.5 * coreDistance; - } + function chop (text, maxLength) { + return (text.length <= maxLength) ? text : (text.substr(0, 27) + '...'); + } + + /** + * 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 (Array.isArray(array1)) { + array1.forEach(function (elem1) { + if (Array.isArray(array2)) { + array2.forEach(function (elem2) { + fn(elem1, elem2); + }); + } + else { + fn(elem1, array2); + } + }); } else { - // default settings - width = group.options.barChart.width; - offset = 0; - if (group.options.barChart.align == 'left') { - offset -= 0.5 * group.options.barChart.width; + if (Array.isArray(array2)) { + array2.forEach(function (elem2) { + fn(array1, elem2); + }); } - else if (group.options.barChart.align == 'right') { - offset += 0.5 * group.options.barChart.width; + else { + fn(array1, array2); } } - - return {width: width, offset: offset}; - }; - + } /** - * draw a line graph - * - * @param dataset - * @param group + * 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 */ - LineGraph.prototype._drawLineGraph = function (dataset, group) { - if (dataset != null) { - if (dataset.length > 0) { - var path, d; - var svgHeight = Number(this.svg.style.height.replace("px","")); - path = DOMutil.getSVGElement('path', this.svgElements, this.svg); - path.setAttributeNS(null, "class", group.className); + function DOTToGraph (data) { + // parse the DOT file + var dotData = parseDOT(data); + var graphData = { + nodes: [], + edges: [], + options: {} + }; - // construct path from dataset - if (group.options.catmullRom.enabled == true) { - d = this._catmullRom(dataset, group); + // 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); + }); + } + + // 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; + } + + dotData.edges.forEach(function (dotEdge) { + var from, to; + if (dotEdge.from instanceof Object) { + from = dotEdge.from.nodes; } else { - d = this._linear(dataset); + from = { + id: dotEdge.from + } } - // append with points for fill and finalize the path - if (group.options.shaded.enabled == true) { - var fillPath = DOMutil.getSVGElement('path',this.svgElements, this.svg); - var dFill; - if (group.options.shaded.orientation == 'top') { - dFill = "M" + dataset[0].x + "," + 0 + " " + d + "L" + dataset[dataset.length - 1].x + "," + 0; - } - else { - dFill = "M" + dataset[0].x + "," + svgHeight + " " + d + "L" + dataset[dataset.length - 1].x + "," + svgHeight; + if (dotEdge.to instanceof Object) { + to = dotEdge.to.nodes; + } + else { + to = { + id: dotEdge.to } - fillPath.setAttributeNS(null, "class", group.className + " fill"); - fillPath.setAttributeNS(null, "d", dFill); } - // copy properties to path for drawing. - path.setAttributeNS(null, "d", "M" + d); - // draw points - if (group.options.drawPoints.enabled == true) { - this._drawPoints(dataset, group, this.svgElements, this.svg); + if (dotEdge.from instanceof Object && dotEdge.from.edges) { + dotEdge.from.edges.forEach(function (subEdge) { + var graphEdge = convertEdge(subEdge); + graphData.edges.push(graphEdge); + }); } - } - } - }; - /** - * draw the data points - * - * @param {Array} dataset - * @param {Object} JSONcontainer - * @param {Object} svg | SVG DOM element - * @param {GraphGroup} group - * @param {Number} [offset] - */ - LineGraph.prototype._drawPoints = function (dataset, group, JSONcontainer, svg, offset) { - if (offset === undefined) {offset = 0;} - for (var i = 0; i < dataset.length; i++) { - DOMutil.drawPoint(dataset[i].x + offset, dataset[i].y, group, JSONcontainer, svg); - } - }; + 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); + }); + if (dotEdge.to instanceof Object && dotEdge.to.edges) { + dotEdge.to.edges.forEach(function (subEdge) { + var graphEdge = convertEdge(subEdge); + graphData.edges.push(graphEdge); + }); + } + }); + } + // copy the options + if (dotData.attr) { + graphData.options = dotData.attr; + } - /** - * This uses the DataAxis object to generate the correct X coordinate on the SVG window. It uses the - * util function toScreen to get the x coordinate from the timestamp. It also pre-filters the data and get the minMax ranges for - * the yAxis. - * - * @param datapoints - * @returns {Array} - * @private - */ - LineGraph.prototype._convertXcoordinates = function (datapoints) { - var extractedData = []; - var xValue, yValue; - var toScreen = this.body.util.toScreen; + return graphData; + } - for (var i = 0; i < datapoints.length; i++) { - xValue = toScreen(datapoints[i].x) + this.width; - yValue = datapoints[i].y; - extractedData.push({x: xValue, y: yValue}); - } + // exports + exports.parseDOT = parseDOT; + exports.DOTToGraph = DOTToGraph; - return extractedData; - }; +/***/ }, +/* 42 */ +/***/ function(module, exports, __webpack_require__) { + + function parseGephi(gephiJSON, options) { + var edges = []; + var nodes = []; + this.options = { + edges: { + inheritColor: true + }, + nodes: { + allowedToMove: false, + parseColor: false + } + }; - /** - * This uses the DataAxis object to generate the correct X coordinate on the SVG window. It uses the - * util function toScreen to get the x coordinate from the timestamp. It also pre-filters the data and get the minMax ranges for - * the yAxis. - * - * @param datapoints - * @returns {Array} - * @private - */ - LineGraph.prototype._convertYcoordinates = function (datapoints, group) { - var extractedData = []; - var xValue, yValue; - var toScreen = this.body.util.toScreen; - var axis = this.yAxisLeft; - var svgHeight = Number(this.svg.style.height.replace("px","")); - if (group.options.yAxisOrientation == 'right') { - axis = this.yAxisRight; + if (options !== undefined) { + this.options.nodes['allowedToMove'] = options.allowedToMove | false; + this.options.nodes['parseColor'] = options.parseColor | false; + this.options.edges['inheritColor'] = options.inheritColor | true; } - for (var i = 0; i < datapoints.length; i++) { - xValue = toScreen(datapoints[i].x) + this.width; - yValue = Math.round(axis.convertValue(datapoints[i].y)); - extractedData.push({x: xValue, y: yValue}); + var gEdges = gephiJSON.edges; + var gNodes = gephiJSON.nodes; + for (var i = 0; i < gEdges.length; i++) { + var edge = {}; + var gEdge = gEdges[i]; + edge['id'] = gEdge.id; + edge['from'] = gEdge.source; + edge['to'] = gEdge.target; + edge['attributes'] = gEdge.attributes; + // edge['value'] = gEdge.attributes !== undefined ? gEdge.attributes.Weight : undefined; + // edge['width'] = edge['value'] !== undefined ? undefined : edgegEdge.size; + edge['color'] = gEdge.color; + edge['inheritColor'] = edge['color'] !== undefined ? false : this.options.inheritColor; + edges.push(edge); } - group.setZeroPosition(Math.min(svgHeight, axis.convertValue(0))); + for (var i = 0; i < gNodes.length; i++) { + var node = {}; + var gNode = gNodes[i]; + node['id'] = gNode.id; + node['attributes'] = gNode.attributes; + node['x'] = gNode.x; + node['y'] = gNode.y; + node['label'] = gNode.label; + if (this.options.nodes.parseColor == true) { + node['color'] = gNode.color; + } + else { + node['color'] = gNode.color !== undefined ? {background:gNode.color, border:gNode.color} : undefined; + } + node['radius'] = gNode.size; + node['allowedToMoveX'] = this.options.nodes.allowedToMove; + node['allowedToMoveY'] = this.options.nodes.allowedToMove; + nodes.push(node); + } - return extractedData; - }; + return {nodes:nodes, edges:edges}; + } - /** - * This uses an uniform parametrization of the CatmullRom algorithm: - * "On the Parameterization of Catmull-Rom Curves" by Cem Yuksel et al. - * @param data - * @returns {string} - * @private - */ - LineGraph.prototype._catmullRomUniform = function(data) { - // catmull rom - var p0, p1, p2, p3, bp1, bp2; - var d = Math.round(data[0].x) + "," + Math.round(data[0].y) + " "; - var normalization = 1/6; - var length = data.length; - for (var i = 0; i < length - 1; i++) { + exports.parseGephi = parseGephi; - p0 = (i == 0) ? data[0] : data[i-1]; - p1 = data[i]; - p2 = data[i+1]; - p3 = (i + 2 < length) ? data[i+2] : p2; +/***/ }, +/* 43 */ +/***/ function(module, exports, __webpack_require__) { + // first check if moment.js is already loaded in the browser window, if so, + // use this instance. Else, load via commonjs. + module.exports = (typeof window !== 'undefined') && window['moment'] || __webpack_require__(53); - // Catmull-Rom to Cubic Bezier conversion matrix - // 0 1 0 0 - // -1/6 1 1/6 0 - // 0 1/6 1 -1/6 - // 0 0 1 0 - // bp0 = { x: p1.x, y: p1.y }; - bp1 = { x: ((-p0.x + 6*p1.x + p2.x) *normalization), y: ((-p0.y + 6*p1.y + p2.y) *normalization)}; - bp2 = { x: (( p1.x + 6*p2.x - p3.x) *normalization), y: (( p1.y + 6*p2.y - p3.y) *normalization)}; - // bp0 = { x: p2.x, y: p2.y }; +/***/ }, +/* 44 */ +/***/ function(module, exports, __webpack_require__) { - d += "C" + - bp1.x + "," + - bp1.y + " " + - bp2.x + "," + - bp2.y + " " + - p2.x + "," + - p2.y + " "; + // Only load hammer.js when in a browser environment + // (loading hammer.js in a node.js environment gives errors) + if (typeof window !== 'undefined') { + module.exports = window['Hammer'] || __webpack_require__(54); + } + else { + module.exports = function () { + throw Error('hammer.js is only available in a browser, not in node.js.'); } + } - return d; - }; + +/***/ }, +/* 45 */ +/***/ function(module, exports, __webpack_require__) { + + var Emitter = __webpack_require__(52); + var Hammer = __webpack_require__(44); + var util = __webpack_require__(1); + var DataSet = __webpack_require__(3); + var DataView = __webpack_require__(4); + var Range = __webpack_require__(16); + var TimeAxis = __webpack_require__(29); + var CurrentTime = __webpack_require__(20); + var CustomTime = __webpack_require__(21); + var ItemSet = __webpack_require__(26); + var Activator = __webpack_require__(51); + var DateUtil = __webpack_require__(14); /** - * This uses either the chordal or centripetal parameterization of the catmull-rom algorithm. - * By default, the centripetal parameterization is used because this gives the nicest results. - * These parameterizations are relatively heavy because the distance between 4 points have to be calculated. - * - * One optimization can be used to reuse distances since this is a sliding window approach. - * @param data - * @returns {string} - * @private + * Create a timeline visualization + * @param {HTMLElement} container + * @param {vis.DataSet | Array | google.visualization.DataTable} [items] + * @param {Object} [options] See Core.setOptions for the available options. + * @constructor */ - LineGraph.prototype._catmullRom = function(data, group) { - var alpha = group.options.catmullRom.alpha; - if (alpha == 0 || alpha === undefined) { - return this._catmullRomUniform(data); - } - else { - var p0, p1, p2, p3, bp1, bp2, d1,d2,d3, A, B, N, M; - var d3powA, d2powA, d3pow2A, d2pow2A, d1pow2A, d1powA; - var d = Math.round(data[0].x) + "," + Math.round(data[0].y) + " "; - var length = data.length; - for (var i = 0; i < length - 1; i++) { + function Core () {} - p0 = (i == 0) ? data[0] : data[i-1]; - p1 = data[i]; - p2 = data[i+1]; - p3 = (i + 2 < length) ? data[i+2] : p2; + // turn Core into an event emitter + Emitter(Core.prototype); - d1 = Math.sqrt(Math.pow(p0.x - p1.x,2) + Math.pow(p0.y - p1.y,2)); - d2 = Math.sqrt(Math.pow(p1.x - p2.x,2) + Math.pow(p1.y - p2.y,2)); - d3 = Math.sqrt(Math.pow(p2.x - p3.x,2) + Math.pow(p2.y - p3.y,2)); + /** + * Create the main DOM for the Core: a root panel containing left, right, + * top, bottom, content, and background panel. + * @param {Element} container The container element where the Core will + * be attached. + * @private + */ + Core.prototype._create = function (container) { + this.dom = {}; - // Catmull-Rom to Cubic Bezier conversion matrix - // - // A = 2d1^2a + 3d1^a * d2^a + d3^2a - // B = 2d3^2a + 3d3^a * d2^a + d2^2a - // - // [ 0 1 0 0 ] - // [ -d2^2a/N A/N d1^2a/N 0 ] - // [ 0 d3^2a/M B/M -d2^2a/M ] - // [ 0 0 1 0 ] + this.dom.root = document.createElement('div'); + this.dom.background = document.createElement('div'); + this.dom.backgroundVertical = document.createElement('div'); + this.dom.backgroundHorizontal = document.createElement('div'); + this.dom.centerContainer = document.createElement('div'); + this.dom.leftContainer = document.createElement('div'); + this.dom.rightContainer = document.createElement('div'); + this.dom.center = document.createElement('div'); + this.dom.left = document.createElement('div'); + this.dom.right = document.createElement('div'); + this.dom.top = document.createElement('div'); + this.dom.bottom = document.createElement('div'); + this.dom.shadowTop = document.createElement('div'); + this.dom.shadowBottom = document.createElement('div'); + this.dom.shadowTopLeft = document.createElement('div'); + this.dom.shadowBottomLeft = document.createElement('div'); + this.dom.shadowTopRight = document.createElement('div'); + this.dom.shadowBottomRight = document.createElement('div'); - // [ 0 1 0 0 ] - // [ -d2pow2a/N A/N d1pow2a/N 0 ] - // [ 0 d3pow2a/M B/M -d2pow2a/M ] - // [ 0 0 1 0 ] + this.dom.root.className = 'vis timeline root'; + this.dom.background.className = 'vispanel background'; + this.dom.backgroundVertical.className = 'vispanel background vertical'; + this.dom.backgroundHorizontal.className = 'vispanel background horizontal'; + this.dom.centerContainer.className = 'vispanel center'; + this.dom.leftContainer.className = 'vispanel left'; + this.dom.rightContainer.className = 'vispanel right'; + this.dom.top.className = 'vispanel top'; + this.dom.bottom.className = 'vispanel bottom'; + this.dom.left.className = 'content'; + this.dom.center.className = 'content'; + this.dom.right.className = 'content'; + this.dom.shadowTop.className = 'shadow top'; + this.dom.shadowBottom.className = 'shadow bottom'; + this.dom.shadowTopLeft.className = 'shadow top'; + this.dom.shadowBottomLeft.className = 'shadow bottom'; + this.dom.shadowTopRight.className = 'shadow top'; + this.dom.shadowBottomRight.className = 'shadow bottom'; - d3powA = Math.pow(d3, alpha); - d3pow2A = Math.pow(d3,2*alpha); - d2powA = Math.pow(d2, alpha); - d2pow2A = Math.pow(d2,2*alpha); - d1powA = Math.pow(d1, alpha); - d1pow2A = Math.pow(d1,2*alpha); + this.dom.root.appendChild(this.dom.background); + this.dom.root.appendChild(this.dom.backgroundVertical); + this.dom.root.appendChild(this.dom.backgroundHorizontal); + this.dom.root.appendChild(this.dom.centerContainer); + this.dom.root.appendChild(this.dom.leftContainer); + this.dom.root.appendChild(this.dom.rightContainer); + this.dom.root.appendChild(this.dom.top); + this.dom.root.appendChild(this.dom.bottom); - A = 2*d1pow2A + 3*d1powA * d2powA + d2pow2A; - B = 2*d3pow2A + 3*d3powA * d2powA + d2pow2A; - N = 3*d1powA * (d1powA + d2powA); - if (N > 0) {N = 1 / N;} - M = 3*d3powA * (d3powA + d2powA); - if (M > 0) {M = 1 / M;} + this.dom.centerContainer.appendChild(this.dom.center); + this.dom.leftContainer.appendChild(this.dom.left); + this.dom.rightContainer.appendChild(this.dom.right); - bp1 = { x: ((-d2pow2A * p0.x + A*p1.x + d1pow2A * p2.x) * N), - y: ((-d2pow2A * p0.y + A*p1.y + d1pow2A * p2.y) * N)}; + this.dom.centerContainer.appendChild(this.dom.shadowTop); + this.dom.centerContainer.appendChild(this.dom.shadowBottom); + this.dom.leftContainer.appendChild(this.dom.shadowTopLeft); + this.dom.leftContainer.appendChild(this.dom.shadowBottomLeft); + this.dom.rightContainer.appendChild(this.dom.shadowTopRight); + this.dom.rightContainer.appendChild(this.dom.shadowBottomRight); - bp2 = { x: (( d3pow2A * p1.x + B*p2.x - d2pow2A * p3.x) * M), - y: (( d3pow2A * p1.y + B*p2.y - d2pow2A * p3.y) * M)}; + this.on('rangechange', this.redraw.bind(this)); + this.on('change', this.redraw.bind(this)); + this.on('touch', this._onTouch.bind(this)); + this.on('pinch', this._onPinch.bind(this)); + this.on('dragstart', this._onDragStart.bind(this)); + this.on('drag', this._onDrag.bind(this)); - if (bp1.x == 0 && bp1.y == 0) {bp1 = p1;} - if (bp2.x == 0 && bp2.y == 0) {bp2 = p2;} - d += "C" + - bp1.x + "," + - bp1.y + " " + - bp2.x + "," + - bp2.y + " " + - p2.x + "," + - p2.y + " "; - } + // create event listeners for all interesting events, these events will be + // emitted via emitter + this.hammer = Hammer(this.dom.root, { + preventDefault: true + }); + this.listeners = {}; - return d; - } + var me = this; + var events = [ + 'touch', 'pinch', + 'tap', 'doubletap', 'hold', + 'dragstart', 'drag', 'dragend', + 'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox + ]; + events.forEach(function (event) { + var listener = function () { + var args = [event].concat(Array.prototype.slice.call(arguments, 0)); + if (me.isActive()) { + me.emit.apply(me, args); + } + }; + me.hammer.on(event, listener); + me.listeners[event] = listener; + }); + + // size properties of each of the panels + this.props = { + root: {}, + background: {}, + centerContainer: {}, + leftContainer: {}, + rightContainer: {}, + center: {}, + left: {}, + right: {}, + top: {}, + bottom: {}, + border: {}, + scrollTop: 0, + scrollTopMin: 0 + }; + this.touch = {}; // store state information needed for touch events + + // attach the root panel to the provided container + if (!container) throw new Error('No container provided'); + container.appendChild(this.dom.root); }; /** - * this generates the SVG path for a linear drawing between datapoints. - * @param data - * @returns {string} - * @private + * Set options. Options will be passed to all components loaded in the Timeline. + * @param {Object} [options] + * {String} orientation + * Vertical orientation for the Timeline, + * can be 'bottom' (default) or 'top'. + * {String | Number} width + * Width for the timeline, a number in pixels or + * a css string like '1000px' or '75%'. '100%' by default. + * {String | Number} height + * Fixed height for the Timeline, a number in pixels or + * a css string like '400px' or '75%'. If undefined, + * The Timeline will automatically size such that + * its contents fit. + * {String | Number} minHeight + * Minimum height for the Timeline, a number in pixels or + * a css string like '400px' or '75%'. + * {String | Number} maxHeight + * Maximum height for the Timeline, a number in pixels or + * a css string like '400px' or '75%'. + * {Number | Date | String} start + * Start date for the visible window + * {Number | Date | String} end + * End date for the visible window */ - LineGraph.prototype._linear = function(data) { - // linear - var d = ""; - for (var i = 0; i < data.length; i++) { - if (i == 0) { - d += data[i].x + "," + data[i].y; + Core.prototype.setOptions = function (options) { + if (options) { + // copy the known options + var fields = ['width', 'height', 'minHeight', 'maxHeight', 'autoResize', 'start', 'end', 'orientation', 'clickToUse', 'dataAttributes', 'hiddenDates']; + util.selectiveExtend(fields, this.options, options); + + if ('hiddenDates' in this.options) { + DateUtil.convertHiddenOptions(this.body, this.options.hiddenDates); } - else { - d += " " + data[i].x + "," + data[i].y; + + if ('clickToUse' in options) { + if (options.clickToUse) { + this.activator = new Activator(this.dom.root); + } + else { + if (this.activator) { + this.activator.destroy(); + delete this.activator; + } + } } - } - return d; - }; - module.exports = LineGraph; + // enable/disable autoResize + this._initAutoResize(); + } + // propagate options to all components + this.components.forEach(function (component) { + component.setOptions(options); + }); -/***/ }, -/* 43 */ -/***/ function(module, exports, __webpack_require__) { + // TODO: remove deprecation error one day (deprecated since version 0.8.0) + if (options && options.order) { + throw new Error('Option order is deprecated. There is no replacement for this feature.'); + } - var util = __webpack_require__(1); - var DOMutil = __webpack_require__(6); - var Component = __webpack_require__(22); - var DataStep = __webpack_require__(44); + // redraw everything + this.redraw(); + }; /** - * A horizontal time axis - * @param {Object} [options] See DataAxis.setOptions for the available - * options. - * @constructor DataAxis - * @extends Component - * @param body + * Returns true when the Timeline is active. + * @returns {boolean} */ - function DataAxis (body, options, svg, linegraphOptions) { - this.id = util.randomUUID(); - this.body = body; - - this.defaultOptions = { - orientation: 'left', // supported: 'left', 'right' - showMinorLabels: true, - showMajorLabels: true, - icons: true, - majorLinesOffset: 7, - minorLinesOffset: 4, - labelOffsetX: 10, - labelOffsetY: 2, - iconWidth: 20, - width: '40px', - visible: true, - customRange: { - left: {min:undefined, max:undefined}, - right: {min:undefined, max:undefined} - } - }; - - this.linegraphOptions = linegraphOptions; - this.linegraphSVG = svg; - this.props = {}; - this.DOMelements = { // dynamic elements - lines: {}, - labels: {} - }; - - this.dom = {}; - - this.range = {start:0, end:0}; + Core.prototype.isActive = function () { + return !this.activator || this.activator.active; + }; - this.options = util.extend({}, this.defaultOptions); - this.conversionFactor = 1; + /** + * Destroy the Core, clean up all DOM elements and event listeners. + */ + Core.prototype.destroy = function () { + // unbind datasets + this.clear(); - this.setOptions(options); - this.width = Number(('' + this.options.width).replace("px","")); - this.minWidth = this.width; - this.height = this.linegraphSVG.offsetHeight; + // remove all event listeners + this.off(); - this.stepPixels = 25; - this.stepPixelsForced = 25; - this.lineOffset = 0; - this.master = true; - this.svgElements = {}; + // stop checking for changed size + this._stopAutoResize(); + // remove from DOM + if (this.dom.root.parentNode) { + this.dom.root.parentNode.removeChild(this.dom.root); + } + this.dom = null; - this.groups = {}; - this.amountOfGroups = 0; + // remove Activator + if (this.activator) { + this.activator.destroy(); + delete this.activator; + } - // create the HTML DOM - this._create(); - } + // cleanup hammer touch events + for (var event in this.listeners) { + if (this.listeners.hasOwnProperty(event)) { + delete this.listeners[event]; + } + } + this.listeners = null; + this.hammer = null; - DataAxis.prototype = new Component(); + // give all components the opportunity to cleanup + this.components.forEach(function (component) { + component.destroy(); + }); + this.body = null; + }; - DataAxis.prototype.addGroup = function(label, graphOptions) { - if (!this.groups.hasOwnProperty(label)) { - this.groups[label] = graphOptions; + /** + * Set a custom time bar + * @param {Date} time + */ + Core.prototype.setCustomTime = function (time) { + if (!this.customTime) { + throw new Error('Cannot get custom time: Custom time bar is not enabled'); } - this.amountOfGroups += 1; - }; - DataAxis.prototype.updateGroup = function(label, graphOptions) { - this.groups[label] = graphOptions; + this.customTime.setCustomTime(time); }; - DataAxis.prototype.removeGroup = function(label) { - if (this.groups.hasOwnProperty(label)) { - delete this.groups[label]; - this.amountOfGroups -= 1; + /** + * Retrieve the current custom time. + * @return {Date} customTime + */ + Core.prototype.getCustomTime = function() { + if (!this.customTime) { + throw new Error('Cannot get custom time: Custom time bar is not enabled'); } - }; - - - DataAxis.prototype.setOptions = function (options) { - if (options) { - var redraw = false; - if (this.options.orientation != options.orientation && options.orientation !== undefined) { - redraw = true; - } - var fields = [ - 'orientation', - 'showMinorLabels', - 'showMajorLabels', - 'icons', - 'majorLinesOffset', - 'minorLinesOffset', - 'labelOffsetX', - 'labelOffsetY', - 'iconWidth', - 'width', - 'visible', - 'customRange' - ]; - util.selectiveExtend(fields, this.options, options); - - this.minWidth = Number(('' + this.options.width).replace("px","")); - if (redraw == true && this.dom.frame) { - this.hide(); - this.show(); - } - } + return this.customTime.getCustomTime(); }; /** - * Create the HTML DOM for the DataAxis + * Get the id's of the currently visible items. + * @returns {Array} The ids of the visible items */ - DataAxis.prototype._create = function() { - this.dom.frame = document.createElement('div'); - this.dom.frame.style.width = this.options.width; - this.dom.frame.style.height = this.height; - - this.dom.lineContainer = document.createElement('div'); - this.dom.lineContainer.style.width = '100%'; - this.dom.lineContainer.style.height = this.height; - - // create svg element for graph drawing. - this.svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); - this.svg.style.position = "absolute"; - this.svg.style.top = '0px'; - this.svg.style.height = '100%'; - this.svg.style.width = '100%'; - this.svg.style.display = "block"; - this.dom.frame.appendChild(this.svg); + Core.prototype.getVisibleItems = function() { + return this.itemSet && this.itemSet.getVisibleItems() || []; }; - DataAxis.prototype._redrawGroupIcons = function () { - DOMutil.prepareElements(this.svgElements); - var x; - var iconWidth = this.options.iconWidth; - var iconHeight = 15; - var iconOffset = 4; - var y = iconOffset + 0.5 * iconHeight; - if (this.options.orientation == 'left') { - x = iconOffset; - } - else { - x = this.width - iconWidth - iconOffset; + /** + * Clear the Core. By Default, items, groups and options are cleared. + * Example usage: + * + * timeline.clear(); // clear items, groups, and options + * timeline.clear({options: true}); // clear options only + * + * @param {Object} [what] Optionally specify what to clear. By default: + * {items: true, groups: true, options: true} + */ + Core.prototype.clear = function(what) { + // clear items + if (!what || what.items) { + this.setItems(null); } - for (var groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { - this.groups[groupId].drawIcon(x, y, this.svgElements, this.svg, iconWidth, iconHeight); - y += iconHeight + iconOffset; - } - } + // clear groups + if (!what || what.groups) { + this.setGroups(null); } - DOMutil.cleanupElements(this.svgElements); + // clear options of timeline and of each of the components + if (!what || what.options) { + this.components.forEach(function (component) { + component.setOptions(component.defaultOptions); + }); + + this.setOptions(this.defaultOptions); // this will also do a redraw + } }; /** - * Create the HTML DOM for the DataAxis + * Set Core window such that it fits all items + * @param {Object} [options] Available options: + * `animate: boolean | number` + * If true (default), the range is animated + * smoothly to the new window. + * If a number, the number is taken as duration + * for the animation. Default duration is 500 ms. */ - DataAxis.prototype.show = function() { - if (!this.dom.frame.parentNode) { - if (this.options.orientation == 'left') { - this.body.dom.left.appendChild(this.dom.frame); - } - else { - this.body.dom.right.appendChild(this.dom.frame); + Core.prototype.fit = function(options) { + // apply the data range as range + var dataRange = this.getItemRange(); + + // add 5% space on both sides + var start = dataRange.min; + var end = dataRange.max; + if (start != null && end != null) { + var interval = (end.valueOf() - start.valueOf()); + if (interval <= 0) { + // prevent an empty interval + interval = 24 * 60 * 60 * 1000; // 1 day } + start = new Date(start.valueOf() - interval * 0.05); + end = new Date(end.valueOf() + interval * 0.05); } - if (!this.dom.lineContainer.parentNode) { - this.body.dom.backgroundHorizontal.appendChild(this.dom.lineContainer); + // skip range set if there is no start and end date + if (start === null && end === null) { + return; } + + var animate = (options && options.animate !== undefined) ? options.animate : true; + this.range.setRange(start, end, animate); }; /** - * Create the HTML DOM for the DataAxis + * Set the visible window. Both parameters are optional, you can change only + * start or only end. Syntax: + * + * TimeLine.setWindow(start, end) + * TimeLine.setWindow(range) + * + * Where start and end can be a Date, number, or string, and range is an + * object with properties start and end. + * + * @param {Date | Number | String | Object} [start] Start date of visible window + * @param {Date | Number | String} [end] End date of visible window + * @param {Object} [options] Available options: + * `animate: boolean | number` + * If true (default), the range is animated + * smoothly to the new window. + * If a number, the number is taken as duration + * for the animation. Default duration is 500 ms. */ - DataAxis.prototype.hide = function() { - if (this.dom.frame.parentNode) { - this.dom.frame.parentNode.removeChild(this.dom.frame); + Core.prototype.setWindow = function(start, end, options) { + var animate = (options && options.animate !== undefined) ? options.animate : true; + if (arguments.length == 1) { + var range = arguments[0]; + this.range.setRange(range.start, range.end, animate); } - - if (this.dom.lineContainer.parentNode) { - this.dom.lineContainer.parentNode.removeChild(this.dom.lineContainer); + else { + this.range.setRange(start, end, animate); } }; /** - * Set a range (start and end) - * @param end - * @param start - * @param end + * Move the window such that given time is centered on screen. + * @param {Date | Number | String} time + * @param {Object} [options] Available options: + * `animate: boolean | number` + * If true (default), the range is animated + * smoothly to the new window. + * If a number, the number is taken as duration + * for the animation. Default duration is 500 ms. */ - DataAxis.prototype.setRange = function (start, end) { - this.range.start = start; - this.range.end = end; + Core.prototype.moveTo = function(time, options) { + var interval = this.range.end - this.range.start; + var t = util.convert(time, 'Date').valueOf(); + + var start = t - interval / 2; + var end = t + interval / 2; + var animate = (options && options.animate !== undefined) ? options.animate : true; + + this.range.setRange(start, end, animate); }; /** - * Repaint the component - * @return {boolean} Returns true if the component is resized + * Get the visible window + * @return {{start: Date, end: Date}} Visible range */ - DataAxis.prototype.redraw = function () { - var changeCalled = false; - var activeGroups = 0; - for (var groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { - activeGroups++; - } - } - } - if (this.amountOfGroups == 0 || activeGroups == 0) { - this.hide(); - } - else { - this.show(); - this.height = Number(this.linegraphSVG.style.height.replace("px","")); - // svg offsetheight did not work in firefox and explorer... - - this.dom.lineContainer.style.height = this.height + 'px'; - this.width = this.options.visible == true ? Number(('' + this.options.width).replace("px","")) : 0; - - var props = this.props; - var frame = this.dom.frame; - - // update classname - frame.className = 'dataaxis'; - - // calculate character width and height - this._calculateCharSize(); - - var orientation = this.options.orientation; - var showMinorLabels = this.options.showMinorLabels; - var showMajorLabels = this.options.showMajorLabels; - - // determine the width and height of the elemens for the axis - props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0; - props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0; - - props.minorLineWidth = this.body.dom.backgroundHorizontal.offsetWidth - this.lineOffset - this.width + 2 * this.options.minorLinesOffset; - props.minorLineHeight = 1; - props.majorLineWidth = this.body.dom.backgroundHorizontal.offsetWidth - this.lineOffset - this.width + 2 * this.options.majorLinesOffset; - props.majorLineHeight = 1; - - // take frame offline while updating (is almost twice as fast) - if (orientation == 'left') { - frame.style.top = '0'; - frame.style.left = '0'; - frame.style.bottom = ''; - frame.style.width = this.width + 'px'; - frame.style.height = this.height + "px"; - } - else { // right - frame.style.top = ''; - frame.style.bottom = '0'; - frame.style.left = '0'; - frame.style.width = this.width + 'px'; - frame.style.height = this.height + "px"; - } - changeCalled = this._redrawLabels(); - if (this.options.icons == true) { - this._redrawGroupIcons(); - } - } - return changeCalled; + Core.prototype.getWindow = function() { + var range = this.range.getRange(); + return { + start: new Date(range.start), + end: new Date(range.end) + }; }; /** - * Repaint major and minor text labels and vertical grid lines - * @private + * Force a redraw of the Core. Can be useful to manually redraw when + * option autoResize=false */ - DataAxis.prototype._redrawLabels = function () { - DOMutil.prepareElements(this.DOMelements.lines); - DOMutil.prepareElements(this.DOMelements.labels); + Core.prototype.redraw = function() { + var resized = false; + var options = this.options; + var props = this.props; + var dom = this.dom; - var orientation = this.options['orientation']; + if (!dom) return; // when destroyed - // calculate range and step (step such that we have space for 7 characters per label) - var minimumStep = this.master ? this.props.majorCharHeight || 10 : this.stepPixelsForced; + DateUtil.updateHiddenDates(this.body, this.options.hiddenDates); - var step = new DataStep(this.range.start, this.range.end, minimumStep, this.dom.frame.offsetHeight, this.options.customRange[this.options.orientation]); - this.step = step; - // get the distance in pixels for a step - // dead space is space that is "left over" after a step - var stepPixels = (this.dom.frame.offsetHeight - (step.deadSpace * (this.dom.frame.offsetHeight / step.marginRange))) / (((step.marginRange - step.deadSpace) / step.step)); - this.stepPixels = stepPixels; + // update class names + if (options.orientation == 'top') { + util.addClassName(dom.root, 'top'); + util.removeClassName(dom.root, 'bottom'); + } + else { + util.removeClassName(dom.root, 'top'); + util.addClassName(dom.root, 'bottom'); + } - var amountOfSteps = this.height / stepPixels; - var stepDifference = 0; + // update root width and height options + dom.root.style.maxHeight = util.option.asSize(options.maxHeight, ''); + dom.root.style.minHeight = util.option.asSize(options.minHeight, ''); + dom.root.style.width = util.option.asSize(options.width, ''); + + // calculate border widths + props.border.left = (dom.centerContainer.offsetWidth - dom.centerContainer.clientWidth) / 2; + props.border.right = props.border.left; + props.border.top = (dom.centerContainer.offsetHeight - dom.centerContainer.clientHeight) / 2; + props.border.bottom = props.border.top; + var borderRootHeight= dom.root.offsetHeight - dom.root.clientHeight; + var borderRootWidth = dom.root.offsetWidth - dom.root.clientWidth; - if (this.master == false) { - stepPixels = this.stepPixelsForced; - stepDifference = Math.round((this.dom.frame.offsetHeight / stepPixels) - amountOfSteps); - for (var i = 0; i < 0.5 * stepDifference; i++) { - step.previous(); - } - amountOfSteps = this.height / stepPixels; + // workaround for a bug in IE: the clientWidth of an element with + // a height:0px and overflow:hidden is not calculated and always has value 0 + if (dom.centerContainer.clientHeight === 0) { + props.border.left = props.border.top; + props.border.right = props.border.left; } - else { - amountOfSteps += 0.25; + if (dom.root.clientHeight === 0) { + borderRootWidth = borderRootHeight; } + // calculate the heights. If any of the side panels is empty, we set the height to + // minus the border width, such that the border will be invisible + props.center.height = dom.center.offsetHeight; + props.left.height = dom.left.offsetHeight; + props.right.height = dom.right.offsetHeight; + props.top.height = dom.top.clientHeight || -props.border.top; + props.bottom.height = dom.bottom.clientHeight || -props.border.bottom; - this.valueAtZero = step.marginEnd; - var marginStartPos = 0; + // TODO: compensate borders when any of the panels is empty. - // do not draw the first label - var max = 1; + // apply auto height + // TODO: only calculate autoHeight when needed (else we cause an extra reflow/repaint of the DOM) + var contentHeight = Math.max(props.left.height, props.center.height, props.right.height); + var autoHeight = props.top.height + contentHeight + props.bottom.height + + borderRootHeight + props.border.top + props.border.bottom; + dom.root.style.height = util.option.asSize(options.height, autoHeight + 'px'); - this.maxLabelSize = 0; - var y = 0; - while (max < Math.round(amountOfSteps)) { - step.next(); - y = Math.round(max * stepPixels); - marginStartPos = max * stepPixels; - var isMajor = step.isMajor(); + // calculate heights of the content panels + props.root.height = dom.root.offsetHeight; + props.background.height = props.root.height - borderRootHeight; + var containerHeight = props.root.height - props.top.height - props.bottom.height - + borderRootHeight; + props.centerContainer.height = containerHeight; + props.leftContainer.height = containerHeight; + props.rightContainer.height = props.leftContainer.height; - if (this.options['showMinorLabels'] && isMajor == false || this.master == false && this.options['showMinorLabels'] == true) { - this._redrawLabel(y - 2, step.getCurrent(), orientation, 'yAxis minor', this.props.minorCharHeight); - } + // calculate the widths of the panels + props.root.width = dom.root.offsetWidth; + props.background.width = props.root.width - borderRootWidth; + props.left.width = dom.leftContainer.clientWidth || -props.border.left; + props.leftContainer.width = props.left.width; + props.right.width = dom.rightContainer.clientWidth || -props.border.right; + props.rightContainer.width = props.right.width; + var centerWidth = props.root.width - props.left.width - props.right.width - borderRootWidth; + props.center.width = centerWidth; + props.centerContainer.width = centerWidth; + props.top.width = centerWidth; + props.bottom.width = centerWidth; - if (isMajor && this.options['showMajorLabels'] && this.master == true || - this.options['showMinorLabels'] == false && this.master == false && isMajor == true) { - if (y >= 0) { - this._redrawLabel(y - 2, step.getCurrent(), orientation, 'yAxis major', this.props.majorCharHeight); - } - this._redrawLine(y, orientation, 'grid horizontal major', this.options.majorLinesOffset, this.props.majorLineWidth); - } - else { - this._redrawLine(y, orientation, 'grid horizontal minor', this.options.minorLinesOffset, this.props.minorLineWidth); - } + // resize the panels + dom.background.style.height = props.background.height + 'px'; + dom.backgroundVertical.style.height = props.background.height + 'px'; + dom.backgroundHorizontal.style.height = props.centerContainer.height + 'px'; + dom.centerContainer.style.height = props.centerContainer.height + 'px'; + dom.leftContainer.style.height = props.leftContainer.height + 'px'; + dom.rightContainer.style.height = props.rightContainer.height + 'px'; - max++; - } + dom.background.style.width = props.background.width + 'px'; + dom.backgroundVertical.style.width = props.centerContainer.width + 'px'; + dom.backgroundHorizontal.style.width = props.background.width + 'px'; + dom.centerContainer.style.width = props.center.width + 'px'; + dom.top.style.width = props.top.width + 'px'; + dom.bottom.style.width = props.bottom.width + 'px'; - if (this.master == false) { - this.conversionFactor = y / (this.valueAtZero - step.current); - } - else { - this.conversionFactor = this.dom.frame.offsetHeight / step.marginRange; - } + // reposition the panels + dom.background.style.left = '0'; + dom.background.style.top = '0'; + dom.backgroundVertical.style.left = (props.left.width + props.border.left) + 'px'; + dom.backgroundVertical.style.top = '0'; + dom.backgroundHorizontal.style.left = '0'; + dom.backgroundHorizontal.style.top = props.top.height + 'px'; + dom.centerContainer.style.left = props.left.width + 'px'; + dom.centerContainer.style.top = props.top.height + 'px'; + dom.leftContainer.style.left = '0'; + dom.leftContainer.style.top = props.top.height + 'px'; + dom.rightContainer.style.left = (props.left.width + props.center.width) + 'px'; + dom.rightContainer.style.top = props.top.height + 'px'; + dom.top.style.left = props.left.width + 'px'; + dom.top.style.top = '0'; + dom.bottom.style.left = props.left.width + 'px'; + dom.bottom.style.top = (props.top.height + props.centerContainer.height) + 'px'; - var offset = this.options.icons == true ? this.options.iconWidth + this.options.labelOffsetX + 15 : this.options.labelOffsetX + 15; - // this will resize the yAxis to accomodate the labels. - if (this.maxLabelSize > (this.width - offset) && this.options.visible == true) { - this.width = this.maxLabelSize + offset; - this.options.width = this.width + "px"; - DOMutil.cleanupElements(this.DOMelements.lines); - DOMutil.cleanupElements(this.DOMelements.labels); - this.redraw(); - return true; + // update the scrollTop, feasible range for the offset can be changed + // when the height of the Core or of the contents of the center changed + this._updateScrollTop(); + + // reposition the scrollable contents + var offset = this.props.scrollTop; + if (options.orientation == 'bottom') { + offset += Math.max(this.props.centerContainer.height - this.props.center.height - + this.props.border.top - this.props.border.bottom, 0); } - // this will resize the yAxis if it is too big for the labels. - else if (this.maxLabelSize < (this.width - offset) && this.options.visible == true && this.width > this.minWidth) { - this.width = Math.max(this.minWidth,this.maxLabelSize + offset); - this.options.width = this.width + "px"; - DOMutil.cleanupElements(this.DOMelements.lines); - DOMutil.cleanupElements(this.DOMelements.labels); + dom.center.style.left = '0'; + dom.center.style.top = offset + 'px'; + dom.left.style.left = '0'; + dom.left.style.top = offset + 'px'; + dom.right.style.left = '0'; + dom.right.style.top = offset + 'px'; + + // show shadows when vertical scrolling is available + var visibilityTop = this.props.scrollTop == 0 ? 'hidden' : ''; + var visibilityBottom = this.props.scrollTop == this.props.scrollTopMin ? 'hidden' : ''; + dom.shadowTop.style.visibility = visibilityTop; + dom.shadowBottom.style.visibility = visibilityBottom; + dom.shadowTopLeft.style.visibility = visibilityTop; + dom.shadowBottomLeft.style.visibility = visibilityBottom; + dom.shadowTopRight.style.visibility = visibilityTop; + dom.shadowBottomRight.style.visibility = visibilityBottom; + + // redraw all components + this.components.forEach(function (component) { + resized = component.redraw() || resized; + }); + if (resized) { + // keep repainting until all sizes are settled this.redraw(); - return true; - } - else { - DOMutil.cleanupElements(this.DOMelements.lines); - DOMutil.cleanupElements(this.DOMelements.labels); - return false; } }; - DataAxis.prototype.convertValue = function (value) { - var invertedValue = this.valueAtZero - value; - var convertedValue = invertedValue * this.conversionFactor; - return convertedValue; + // TODO: deprecated since version 1.1.0, remove some day + Core.prototype.repaint = function () { + throw new Error('Function repaint is deprecated. Use redraw instead.'); }; /** - * Create a label for the axis at position x - * @private - * @param y - * @param text - * @param orientation - * @param className - * @param characterHeight + * Set a current time. This can be used for example to ensure that a client's + * time is synchronized with a shared server time. + * Only applicable when option `showCurrentTime` is true. + * @param {Date | String | Number} time A Date, unix timestamp, or + * ISO date string. */ - DataAxis.prototype._redrawLabel = function (y, text, orientation, className, characterHeight) { - // reuse redundant label - var label = DOMutil.getDOMElement('div',this.DOMelements.labels, this.dom.frame); //this.dom.redundant.labels.shift(); - label.className = className; - label.innerHTML = text; - if (orientation == 'left') { - label.style.left = '-' + this.options.labelOffsetX + 'px'; - label.style.textAlign = "right"; - } - else { - label.style.right = '-' + this.options.labelOffsetX + 'px'; - label.style.textAlign = "left"; + Core.prototype.setCurrentTime = function(time) { + if (!this.currentTime) { + throw new Error('Option showCurrentTime must be true'); } - label.style.top = y - 0.5 * characterHeight + this.options.labelOffsetY + 'px'; - - text += ''; - - var largestWidth = Math.max(this.props.majorCharWidth,this.props.minorCharWidth); - if (this.maxLabelSize < text.length * largestWidth) { - this.maxLabelSize = text.length * largestWidth; - } + this.currentTime.setCurrentTime(time); }; /** - * Create a minor line for the axis at position y - * @param y - * @param orientation - * @param className - * @param offset - * @param width + * Get the current time. + * Only applicable when option `showCurrentTime` is true. + * @return {Date} Returns the current time. */ - DataAxis.prototype._redrawLine = function (y, orientation, className, offset, width) { - if (this.master == true) { - var line = DOMutil.getDOMElement('div',this.DOMelements.lines, this.dom.lineContainer);//this.dom.redundant.lines.shift(); - line.className = className; - line.innerHTML = ''; - - if (orientation == 'left') { - line.style.left = (this.width - offset) + 'px'; - } - else { - line.style.right = (this.width - offset) + 'px'; - } - - line.style.width = width + 'px'; - line.style.top = y + 'px'; + Core.prototype.getCurrentTime = function() { + if (!this.currentTime) { + throw new Error('Option showCurrentTime must be true'); } - }; - - - + return this.currentTime.getCurrentTime(); + }; /** - * Determine the size of text on the axis (both major and minor axis). - * The size is calculated only once and then cached in this.props. + * Convert a position on screen (pixels) to a datetime + * @param {int} x Position on the screen in pixels + * @return {Date} time The datetime the corresponds with given position x * @private */ - DataAxis.prototype._calculateCharSize = function () { - // determine the char width and height on the minor axis - if (!('minorCharHeight' in this.props)) { - var textMinor = document.createTextNode('0'); - var measureCharMinor = document.createElement('DIV'); - measureCharMinor.className = 'yAxis minor measure'; - measureCharMinor.appendChild(textMinor); - this.dom.frame.appendChild(measureCharMinor); - - this.props.minorCharHeight = measureCharMinor.clientHeight; - this.props.minorCharWidth = measureCharMinor.clientWidth; - - this.dom.frame.removeChild(measureCharMinor); - } - - if (!('majorCharHeight' in this.props)) { - var textMajor = document.createTextNode('0'); - var measureCharMajor = document.createElement('DIV'); - measureCharMajor.className = 'yAxis major measure'; - measureCharMajor.appendChild(textMajor); - this.dom.frame.appendChild(measureCharMajor); - - this.props.majorCharHeight = measureCharMajor.clientHeight; - this.props.majorCharWidth = measureCharMajor.clientWidth; - - this.dom.frame.removeChild(measureCharMajor); - } + // TODO: move this function to Range + Core.prototype._toTime = function(x) { + return DateUtil.toTime(this.body, this.range, x, this.props.center.width); }; /** - * Snap a date to a rounded value. - * The snap intervals are dependent on the current scale and step. - * @param {Date} date the date to be snapped. - * @return {Date} snappedDate + * Convert a position on the global screen (pixels) to a datetime + * @param {int} x Position on the screen in pixels + * @return {Date} time The datetime the corresponds with given position x + * @private */ - DataAxis.prototype.snap = function(date) { - return this.step.snap(date); + // TODO: move this function to Range + Core.prototype._toGlobalTime = function(x) { + return DateUtil.toTime(this.body, this.range, x, this.props.root.width); + //var conversion = this.range.conversion(this.props.root.width); + //return new Date(x / conversion.scale + conversion.offset); }; - module.exports = DataAxis; - - -/***/ }, -/* 44 */ -/***/ function(module, exports, __webpack_require__) { - /** - * @constructor DataStep - * The class DataStep is an iterator for data for the lineGraph. You provide a start data point and an - * end data point. The class itself determines the best scale (step size) based on the - * provided start Date, end Date, and minimumStep. - * - * If minimumStep is provided, the step size is chosen as close as possible - * to the minimumStep but larger than minimumStep. If minimumStep is not - * provided, the scale is set to 1 DAY. - * The minimumStep should correspond with the onscreen size of about 6 characters - * - * Alternatively, you can set a scale by hand. - * After creation, you can initialize the class by executing first(). Then you - * can iterate from the start date to the end date via next(). You can check if - * the end date is reached with the function hasNext(). After each step, you can - * retrieve the current date via getCurrent(). - * The DataStep has scales ranging from milliseconds, seconds, minutes, hours, - * days, to years. - * - * Version: 1.2 - * - * @param {Date} [start] The start date, for example new Date(2010, 9, 21) - * or new Date(2010, 9, 21, 23, 45, 00) - * @param {Date} [end] The end date - * @param {Number} [minimumStep] Optional. Minimum step size in milliseconds + * Convert a datetime (Date object) into a position on the screen + * @param {Date} time A date + * @return {int} x The position on the screen in pixels which corresponds + * with the given date. + * @private */ - function DataStep(start, end, minimumStep, containerHeight, customRange) { - // variables - this.current = 0; - - this.autoScale = true; - this.stepIndex = 0; - this.step = 1; - this.scale = 1; - - this.marginStart; - this.marginEnd; - this.deadSpace = 0; + // TODO: move this function to Range + Core.prototype._toScreen = function(time) { + return DateUtil.toScreen(this, time, this.props.center.width); + }; - this.majorSteps = [1, 2, 5, 10]; - this.minorSteps = [0.25, 0.5, 1, 2]; - this.setRange(start, end, minimumStep, containerHeight, customRange); - } + /** + * Convert a datetime (Date object) into a position on the root + * This is used to get the pixel density estimate for the screen, not the center panel + * @param {Date} time A date + * @return {int} x The position on root in pixels which corresponds + * with the given date. + * @private + */ + // TODO: move this function to Range + Core.prototype._toGlobalScreen = function(time) { + return DateUtil.toScreen(this, time, this.props.root.width); + //var conversion = this.range.conversion(this.props.root.width); + //return (time.valueOf() - conversion.offset) * conversion.scale; + }; /** - * Set a new range - * If minimumStep is provided, the step size is chosen as close as possible - * to the minimumStep but larger than minimumStep. If minimumStep is not - * provided, the scale is set to 1 DAY. - * The minimumStep should correspond with the onscreen size of about 6 characters - * @param {Number} [start] The start date and time. - * @param {Number} [end] The end date and time. - * @param {Number} [minimumStep] Optional. Minimum step size in milliseconds + * Initialize watching when option autoResize is true + * @private */ - DataStep.prototype.setRange = function(start, end, minimumStep, containerHeight, customRange) { - this._start = customRange.min === undefined ? start : customRange.min; - this._end = customRange.max === undefined ? end : customRange.max; - - if (this._start == this._end) { - this._start -= 0.75; - this._end += 1; + Core.prototype._initAutoResize = function () { + if (this.options.autoResize == true) { + this._startAutoResize(); } - - if (this.autoScale) { - this.setMinimumStep(minimumStep, containerHeight); + else { + this._stopAutoResize(); } - this.setFirst(customRange); }; /** - * Automatically determine the scale that bests fits the provided minimum step - * @param {Number} [minimumStep] The minimum step size in milliseconds + * Watch for changes in the size of the container. On resize, the Panel will + * automatically redraw itself. + * @private */ - DataStep.prototype.setMinimumStep = function(minimumStep, containerHeight) { - // round to floor - var size = this._end - this._start; - var safeSize = size * 1.2; - var minimumStepValue = minimumStep * (safeSize / containerHeight); - var orderOfMagnitude = Math.round(Math.log(safeSize)/Math.LN10); + Core.prototype._startAutoResize = function () { + var me = this; - var minorStepIdx = -1; - var magnitudefactor = Math.pow(10,orderOfMagnitude); + this._stopAutoResize(); - var start = 0; - if (orderOfMagnitude < 0) { - start = orderOfMagnitude; - } + this._onResize = function() { + if (me.options.autoResize != true) { + // stop watching when the option autoResize is changed to false + me._stopAutoResize(); + return; + } - var solutionFound = false; - for (var i = start; Math.abs(i) <= Math.abs(orderOfMagnitude); i++) { - magnitudefactor = Math.pow(10,i); - for (var j = 0; j < this.minorSteps.length; j++) { - var stepSize = magnitudefactor * this.minorSteps[j]; - if (stepSize >= minimumStepValue) { - solutionFound = true; - minorStepIdx = j; - break; + if (me.dom.root) { + // check whether the frame is resized + // Note: we compare offsetWidth here, not clientWidth. For some reason, + // IE does not restore the clientWidth from 0 to the actual width after + // changing the timeline's container display style from none to visible + if ((me.dom.root.offsetWidth != me.props.lastWidth) || + (me.dom.root.offsetHeight != me.props.lastHeight)) { + me.props.lastWidth = me.dom.root.offsetWidth; + me.props.lastHeight = me.dom.root.offsetHeight; + + me.emit('change'); } } - if (solutionFound == true) { - break; - } - } - this.stepIndex = minorStepIdx; - this.scale = magnitudefactor; - this.step = magnitudefactor * this.minorSteps[minorStepIdx]; - }; + }; + // add event listener to window resize + util.addEventListener(window, 'resize', this._onResize); + this.watchTimer = setInterval(this._onResize, 1000); + }; /** - * Round the current date to the first minor date value - * This must be executed once when the current date is set to start Date + * Stop watching for a resize of the frame. + * @private */ - DataStep.prototype.setFirst = function(customRange) { - if (customRange === undefined) { - customRange = {}; + Core.prototype._stopAutoResize = function () { + if (this.watchTimer) { + clearInterval(this.watchTimer); + this.watchTimer = undefined; } - var niceStart = customRange.min === undefined ? this._start - (this.scale * 2 * this.minorSteps[this.stepIndex]) : customRange.min; - var niceEnd = customRange.max === undefined ? this._end + (this.scale * this.minorSteps[this.stepIndex]) : customRange.max; - - this.marginEnd = customRange.max === undefined ? this.roundToMinor(niceEnd) : customRange.max; - this.marginStart = customRange.min === undefined ? this.roundToMinor(niceStart) : customRange.min; - this.deadSpace = this.roundToMinor(niceEnd) - niceEnd + this.roundToMinor(niceStart) - niceStart; - this.marginRange = this.marginEnd - this.marginStart; - - this.current = this.marginEnd; + // remove event listener on window.resize + util.removeEventListener(window, 'resize', this._onResize); + this._onResize = null; }; - DataStep.prototype.roundToMinor = function(value) { - var rounded = value - (value % (this.scale * this.minorSteps[this.stepIndex])); - if (value % (this.scale * this.minorSteps[this.stepIndex]) > 0.5 * (this.scale * this.minorSteps[this.stepIndex])) { - return rounded + (this.scale * this.minorSteps[this.stepIndex]); - } - else { - return rounded; - } - } + /** + * Start moving the timeline vertically + * @param {Event} event + * @private + */ + Core.prototype._onTouch = function (event) { + this.touch.allowDragging = true; + }; + /** + * Start moving the timeline vertically + * @param {Event} event + * @private + */ + Core.prototype._onPinch = function (event) { + this.touch.allowDragging = false; + }; /** - * Check if the there is a next step - * @return {boolean} true if the current date has not passed the end date + * Start moving the timeline vertically + * @param {Event} event + * @private */ - DataStep.prototype.hasNext = function () { - return (this.current >= this.marginStart); + Core.prototype._onDragStart = function (event) { + this.touch.initialScrollTop = this.props.scrollTop; }; /** - * Do the next step + * Move the timeline vertically + * @param {Event} event + * @private */ - DataStep.prototype.next = function() { - var prev = this.current; - this.current -= this.step; + Core.prototype._onDrag = function (event) { + // refuse to drag when we where pinching to prevent the timeline make a jump + // when releasing the fingers in opposite order from the touch screen + if (!this.touch.allowDragging) return; - // safety mechanism: if current time is still unchanged, move to the end - if (this.current == prev) { - this.current = this._end; + var delta = event.gesture.deltaY; + + var oldScrollTop = this._getScrollTop(); + var newScrollTop = this._setScrollTop(this.touch.initialScrollTop + delta); + + if (newScrollTop != oldScrollTop) { + this.redraw(); // TODO: this causes two redraws when dragging, the other is triggered by rangechange already } }; /** - * Do the next step + * Apply a scrollTop + * @param {Number} scrollTop + * @returns {Number} scrollTop Returns the applied scrollTop + * @private */ - DataStep.prototype.previous = function() { - this.current += this.step; - this.marginEnd += this.step; - this.marginRange = this.marginEnd - this.marginStart; + Core.prototype._setScrollTop = function (scrollTop) { + this.props.scrollTop = scrollTop; + this._updateScrollTop(); + return this.props.scrollTop; }; - - /** - * Get the current datetime - * @return {String} current The current date + * Update the current scrollTop when the height of the containers has been changed + * @returns {Number} scrollTop Returns the applied scrollTop + * @private */ - DataStep.prototype.getCurrent = function() { - var toPrecision = '' + Number(this.current).toPrecision(5); - if (toPrecision.indexOf(",") != -1 || toPrecision.indexOf(".") != -1) { - for (var i = toPrecision.length-1; i > 0; i--) { - if (toPrecision[i] == "0") { - toPrecision = toPrecision.slice(0,i); - } - else if (toPrecision[i] == "." || toPrecision[i] == ",") { - toPrecision = toPrecision.slice(0,i); - break; - } - else{ - break; - } + Core.prototype._updateScrollTop = function () { + // recalculate the scrollTopMin + var scrollTopMin = Math.min(this.props.centerContainer.height - this.props.center.height, 0); // is negative or zero + if (scrollTopMin != this.props.scrollTopMin) { + // in case of bottom orientation, change the scrollTop such that the contents + // do not move relative to the time axis at the bottom + if (this.options.orientation == 'bottom') { + this.props.scrollTop += (scrollTopMin - this.props.scrollTopMin); } + this.props.scrollTopMin = scrollTopMin; } - return toPrecision; - }; - - - - /** - * Snap a date to a rounded value. - * The snap intervals are dependent on the current scale and step. - * @param {Date} date the date to be snapped. - * @return {Date} snappedDate - */ - DataStep.prototype.snap = function(date) { + // limit the scrollTop to the feasible scroll range + if (this.props.scrollTop > 0) this.props.scrollTop = 0; + if (this.props.scrollTop < scrollTopMin) this.props.scrollTop = scrollTopMin; + return this.props.scrollTop; }; /** - * Check if the current value is a major value (for example when the step - * is DAY, a major value is each first day of the MONTH) - * @return {boolean} true if current date is major, else false. + * Get the current scrollTop + * @returns {number} scrollTop + * @private */ - DataStep.prototype.isMajor = function() { - return (this.current % (this.scale * this.majorSteps[this.stepIndex]) == 0); + Core.prototype._getScrollTop = function () { + return this.props.scrollTop; }; - module.exports = DataStep; + module.exports = Core; /***/ }, -/* 45 */ +/* 46 */ /***/ function(module, exports, __webpack_require__) { - var util = __webpack_require__(1); - var DOMutil = __webpack_require__(6); + var Hammer = __webpack_require__(44); /** - * @constructor Group - * @param {Number | String} groupId - * @param {Object} data - * @param {ItemSet} itemSet + * Fake a hammer.js gesture. Event can be a ScrollEvent or MouseMoveEvent + * @param {Element} element + * @param {Event} event */ - function GraphGroup (group, groupId, options, groupsUsingDefaultStyles) { - this.id = groupId; - var fields = ['sampling','style','sort','yAxisOrientation','barChart','drawPoints','shaded','catmullRom'] - this.options = util.selectiveBridgeObject(fields,options); - this.usingDefaultStyle = group.className === undefined; - this.groupsUsingDefaultStyles = groupsUsingDefaultStyles; - this.zeroPosition = 0; - this.update(group); - if (this.usingDefaultStyle == true) { - this.groupsUsingDefaultStyles[0] += 1; - } - this.itemsData = []; - this.visible = group.visible === undefined ? true : group.visible; - } + exports.fakeGesture = function(element, event) { + var eventType = null; - GraphGroup.prototype.setItems = function(items) { - if (items != null) { - this.itemsData = items; - if (this.options.sort == true) { - this.itemsData.sort(function (a,b) {return a.x - b.x;}) - } + // for hammer.js 1.0.5 + // var gesture = Hammer.event.collectEventData(this, eventType, event); + + // for hammer.js 1.0.6+ + var touches = Hammer.event.getTouchList(event, eventType); + var gesture = Hammer.event.collectEventData(this, eventType, touches, event); + + // on IE in standards mode, no touches are recognized by hammer.js, + // resulting in NaN values for center.pageX and center.pageY + if (isNaN(gesture.center.pageX)) { + gesture.center.pageX = event.pageX; } - else { - this.itemsData = []; + if (isNaN(gesture.center.pageY)) { + gesture.center.pageY = event.pageY; } - }; - GraphGroup.prototype.setZeroPosition = function(pos) { - this.zeroPosition = pos; + return gesture; }; - GraphGroup.prototype.setOptions = function(options) { - if (options !== undefined) { - var fields = ['sampling','style','sort','yAxisOrientation','barChart']; - util.selectiveDeepExtend(fields, this.options, options); - util.mergeOptions(this.options, options,'catmullRom'); - util.mergeOptions(this.options, options,'drawPoints'); - util.mergeOptions(this.options, options,'shaded'); +/***/ }, +/* 47 */ +/***/ function(module, exports, __webpack_require__) { - if (options.catmullRom) { - if (typeof options.catmullRom == 'object') { - if (options.catmullRom.parametrization) { - if (options.catmullRom.parametrization == 'uniform') { - this.options.catmullRom.alpha = 0; - } - else if (options.catmullRom.parametrization == 'chordal') { - this.options.catmullRom.alpha = 1.0; - } - else { - this.options.catmullRom.parametrization = 'centripetal'; - this.options.catmullRom.alpha = 0.5; - } - } - } - } - } + // English + exports['en'] = { + current: 'current', + time: 'time' }; + exports['en_EN'] = exports['en']; + exports['en_US'] = exports['en']; - GraphGroup.prototype.update = function(group) { - this.group = group; - this.content = group.content || 'graph'; - this.className = group.className || this.className || "graphGroup" + this.groupsUsingDefaultStyles[0] % 10; - this.visible = group.visible === undefined ? true : group.visible; - this.setOptions(group.options); + // Dutch + exports['nl'] = { + custom: 'aangepaste', + time: 'tijd' }; + exports['nl_NL'] = exports['nl']; + exports['nl_BE'] = exports['nl']; - GraphGroup.prototype.drawIcon = function(x, y, JSONcontainer, SVGcontainer, iconWidth, iconHeight) { - var fillHeight = iconHeight * 0.5; - var path, fillPath; - var outline = DOMutil.getSVGElement("rect", JSONcontainer, SVGcontainer); - outline.setAttributeNS(null, "x", x); - outline.setAttributeNS(null, "y", y - fillHeight); - outline.setAttributeNS(null, "width", iconWidth); - outline.setAttributeNS(null, "height", 2*fillHeight); - outline.setAttributeNS(null, "class", "outline"); +/***/ }, +/* 48 */ +/***/ function(module, exports, __webpack_require__) { - if (this.options.style == 'line') { - path = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer); - path.setAttributeNS(null, "class", this.className); - path.setAttributeNS(null, "d", "M" + x + ","+y+" L" + (x + iconWidth) + ","+y+""); - if (this.options.shaded.enabled == true) { - fillPath = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer); - if (this.options.shaded.orientation == 'top') { - fillPath.setAttributeNS(null, "d", "M"+x+", " + (y - fillHeight) + - "L"+x+","+y+" L"+ (x + iconWidth) + ","+y+" L"+ (x + iconWidth) + "," + (y - fillHeight)); - } - else { - fillPath.setAttributeNS(null, "d", "M"+x+","+y+" " + - "L"+x+"," + (y + fillHeight) + " " + - "L"+ (x + iconWidth) + "," + (y + fillHeight) + - "L"+ (x + iconWidth) + ","+y); - } - fillPath.setAttributeNS(null, "class", this.className + " iconFill"); - } + // English + exports['en'] = { + edit: 'Edit', + del: 'Delete selected', + back: 'Back', + addNode: 'Add Node', + addEdge: 'Add Edge', + editNode: 'Edit Node', + editEdge: 'Edit Edge', + addDescription: 'Click in an empty space to place a new node.', + edgeDescription: 'Click on a node and drag the edge to another node to connect them.', + editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.', + createEdgeError: 'Cannot link edges to a cluster.', + deleteClusterError: 'Clusters cannot be deleted.' + }; + exports['en_EN'] = exports['en']; + exports['en_US'] = exports['en']; - if (this.options.drawPoints.enabled == true) { - DOMutil.drawPoint(x + 0.5 * iconWidth,y, this, JSONcontainer, SVGcontainer); - } - } - else { - var barWidth = Math.round(0.3 * iconWidth); - var bar1Height = Math.round(0.4 * iconHeight); - var bar2Height = Math.round(0.75 * iconHeight); + // Dutch + exports['nl'] = { + edit: 'Wijzigen', + del: 'Selectie verwijderen', + back: 'Terug', + addNode: 'Node toevoegen', + addEdge: 'Link toevoegen', + editNode: 'Node wijzigen', + editEdge: 'Link wijzigen', + addDescription: 'Klik op een leeg gebied om een nieuwe node te maken.', + edgeDescription: 'Klik op een node en sleep de link naar een andere node om ze te verbinden.', + editEdgeDescription: 'Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.', + createEdgeError: 'Kan geen link maken naar een cluster.', + deleteClusterError: 'Clusters kunnen niet worden verwijderd.' + }; + exports['nl_NL'] = exports['nl']; + exports['nl_BE'] = exports['nl']; - var offset = Math.round((iconWidth - (2 * barWidth))/3); - DOMutil.drawBar(x + 0.5*barWidth + offset , y + fillHeight - bar1Height - 1, barWidth, bar1Height, this.className + ' bar', JSONcontainer, SVGcontainer); - DOMutil.drawBar(x + 1.5*barWidth + offset + 2, y + fillHeight - bar2Height - 1, barWidth, bar2Height, this.className + ' bar', JSONcontainer, SVGcontainer); - } - }; +/***/ }, +/* 49 */ +/***/ function(module, exports, __webpack_require__) { /** - * - * @param iconWidth - * @param iconHeight - * @returns {{icon: HTMLElement, label: (group.content|*|string), orientation: (.options.yAxisOrientation|*)}} + * Canvas shapes used by Network */ - GraphGroup.prototype.getLegend = function(iconWidth, iconHeight) { - var svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); - this.drawIcon(0,0.5*iconHeight,[],svg,iconWidth,iconHeight); - return {icon: svg, label: this.content, orientation:this.options.yAxisOrientation}; - } + if (typeof CanvasRenderingContext2D !== 'undefined') { - module.exports = GraphGroup; + /** + * 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); + }; -/***/ }, -/* 46 */ -/***/ function(module, exports, __webpack_require__) { + /** + * 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 util = __webpack_require__(1); - var DOMutil = __webpack_require__(6); - var Component = __webpack_require__(22); + 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 - /** - * Legend for Graph2d - */ - function Legend(body, options, side, linegraphOptions) { - this.body = body; - this.defaultOptions = { - enabled: true, - icons: true, - iconSize: 20, - iconSpacing: 6, - left: { - visible: true, - position: 'top-left' // top/bottom - left,center,right - }, - right: { - visible: true, - position: 'top-left' // top/bottom - left,center,right + 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.side = side; - this.options = util.extend({},this.defaultOptions); - this.linegraphOptions = linegraphOptions; - this.svgElements = {}; - this.dom = {}; - this.groups = {}; - this.amountOfGroups = 0; - this._create(); + 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); + }; + + + + /** + * 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; + } + }; - this.setOptions(options); + // TODO: add diamond shape } - Legend.prototype = new Component(); +/***/ }, +/* 50 */ +/***/ function(module, exports, __webpack_require__) { - Legend.prototype.addGroup = function(label, graphOptions) { - if (!this.groups.hasOwnProperty(label)) { - this.groups[label] = graphOptions; + var PhysicsMixin = __webpack_require__(62); + var ClusterMixin = __webpack_require__(56); + var SectorsMixin = __webpack_require__(57); + var SelectionMixin = __webpack_require__(58); + var ManipulationMixin = __webpack_require__(59); + var NavigationMixin = __webpack_require__(60); + var HierarchicalLayoutMixin = __webpack_require__(61); + + /** + * 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]; + } } - this.amountOfGroups += 1; }; - Legend.prototype.updateGroup = function(label, graphOptions) { - this.groups[label] = graphOptions; - }; - Legend.prototype.removeGroup = function(label) { - if (this.groups.hasOwnProperty(label)) { - delete this.groups[label]; - this.amountOfGroups -= 1; + /** + * 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; + } } }; - Legend.prototype._create = function() { - this.dom.frame = document.createElement('div'); - this.dom.frame.className = 'legend'; - this.dom.frame.style.position = "absolute"; - this.dom.frame.style.top = "10px"; - this.dom.frame.style.display = "block"; - this.dom.textArea = document.createElement('div'); - this.dom.textArea.className = 'legendText'; - this.dom.textArea.style.position = "relative"; - this.dom.textArea.style.top = "0px"; + /** + * 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(); + } + }; - this.svg = document.createElementNS('http://www.w3.org/2000/svg',"svg"); - this.svg.style.position = 'absolute'; - this.svg.style.top = 0 +'px'; - this.svg.style.width = this.options.iconSize + 5 + 'px'; - this.svg.style.height = '100%'; - this.dom.frame.appendChild(this.svg); - this.dom.frame.appendChild(this.dom.textArea); + /** + * Mixin the cluster system and initialize the parameters required. + * + * @private + */ + exports._loadClusterSystem = function () { + this.clusterSession = 0; + this.hubThreshold = 5; + this._loadMixin(ClusterMixin); }; + /** - * Hide the component from the DOM + * Mixin the sector system and initialize the parameters required + * + * @private */ - Legend.prototype.hide = function() { - // remove the frame containing the items - if (this.dom.frame.parentNode) { - this.dom.frame.parentNode.removeChild(this.dom.frame); - } + 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); }; + /** - * Show the component in the DOM (when not already visible). - * @return {Boolean} changed + * Mixin the selection system and initialize the parameters required + * + * @private */ - Legend.prototype.show = function() { - // show frame containing the items - if (!this.dom.frame.parentNode) { - this.body.dom.center.appendChild(this.dom.frame); - } - }; + exports._loadSelectionSystem = function () { + this.selectionObj = {nodes: {}, edges: {}}; - Legend.prototype.setOptions = function(options) { - var fields = ['enabled','orientation','icons','left','right']; - util.selectiveDeepExtend(fields, this.options, options); + this._loadMixin(SelectionMixin); }; - Legend.prototype.redraw = function() { - var activeGroups = 0; - for (var groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { - activeGroups++; + + /** + * 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; + + 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.frame.appendChild(this.manipulationDiv); } - } - if (this.options[this.side].visible == false || this.amountOfGroups == 0 || this.options.enabled == false || activeGroups == 0) { - this.hide(); - } - else { - this.show(); - if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'bottom-left') { - this.dom.frame.style.left = '4px'; - this.dom.frame.style.textAlign = "left"; - this.dom.textArea.style.textAlign = "left"; - this.dom.textArea.style.left = (this.options.iconSize + 15) + 'px'; - this.dom.textArea.style.right = ''; - this.svg.style.left = 0 +'px'; - this.svg.style.right = ''; - } - else { - this.dom.frame.style.right = '4px'; - this.dom.frame.style.textAlign = "right"; - this.dom.textArea.style.textAlign = "right"; - this.dom.textArea.style.right = (this.options.iconSize + 15) + 'px'; - this.dom.textArea.style.left = ''; - this.svg.style.right = 0 +'px'; - this.svg.style.left = ''; + 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.frame.appendChild(this.editModeDiv); } - if (this.options[this.side].position == 'top-left' || this.options[this.side].position == 'top-right') { - this.dom.frame.style.top = 4 - Number(this.body.dom.center.style.top.replace("px","")) + 'px'; - this.dom.frame.style.bottom = ''; - } - else { - this.dom.frame.style.bottom = 4 - Number(this.body.dom.center.style.top.replace("px","")) + 'px'; - this.dom.frame.style.top = ''; + 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.frame.appendChild(this.closeDiv); } - if (this.options.icons == false) { - this.dom.frame.style.width = this.dom.textArea.offsetWidth + 10 + 'px'; - this.dom.textArea.style.right = ''; - this.dom.textArea.style.left = ''; - this.svg.style.width = '0px'; - } - else { - this.dom.frame.style.width = this.options.iconSize + 15 + this.dom.textArea.offsetWidth + 10 + 'px' - this.drawLegendIcons(); - } + // load the manipulation functions + this._loadMixin(ManipulationMixin); - var content = ''; - for (var groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { - content += this.groups[groupId].content + '
'; - } - } - } - this.dom.textArea.innerHTML = content; - this.dom.textArea.style.lineHeight = ((0.75 * this.options.iconSize) + this.options.iconSpacing) + 'px'; + // create the manipulator toolbar + this._createManipulatorBar(); } - }; - - Legend.prototype.drawLegendIcons = function() { - if (this.dom.frame.parentNode) { - DOMutil.prepareElements(this.svgElements); - var padding = window.getComputedStyle(this.dom.frame).paddingTop; - var iconOffset = Number(padding.replace('px','')); - var x = iconOffset; - var iconWidth = this.options.iconSize; - var iconHeight = 0.75 * this.options.iconSize; - var y = iconOffset + 0.5 * iconHeight + 3; + else { + if (this.manipulationDiv !== undefined) { + // removes all the bindings and overloads + this._createManipulatorBar(); - this.svg.style.width = iconWidth + 5 + iconOffset + 'px'; + // remove the manipulation divs + this.frame.removeChild(this.manipulationDiv); + this.frame.removeChild(this.editModeDiv); + this.frame.removeChild(this.closeDiv); - for (var groupId in this.groups) { - if (this.groups.hasOwnProperty(groupId)) { - if (this.groups[groupId].visible == true && (this.linegraphOptions.visibility[groupId] === undefined || this.linegraphOptions.visibility[groupId] == true)) { - this.groups[groupId].drawIcon(x, y, this.svgElements, this.svg, iconWidth, iconHeight); - y += iconHeight + this.options.iconSpacing; - } - } + this.manipulationDiv = undefined; + this.editModeDiv = undefined; + this.closeDiv = undefined; + // remove the mixin functions + this._clearMixin(ManipulationMixin); } - - DOMutil.cleanupElements(this.svgElements); } }; - module.exports = Legend; - - -/***/ }, -/* 47 */ -/***/ function(module, exports, __webpack_require__) { - - var Emitter = __webpack_require__(10); - var Hammer = __webpack_require__(18); - var mousetrap = __webpack_require__(40); - var util = __webpack_require__(1); - var hammerUtil = __webpack_require__(21); - var DataSet = __webpack_require__(7); - var DataView = __webpack_require__(8); - var dotparser = __webpack_require__(48); - var gephiParser = __webpack_require__(49); - var Groups = __webpack_require__(50); - var Images = __webpack_require__(51); - var Node = __webpack_require__(52); - var Edge = __webpack_require__(53); - var Popup = __webpack_require__(54); - var MixinLoader = __webpack_require__(55); - var Activator = __webpack_require__(39); - var locales = __webpack_require__(66); - - // Load custom shapes into CanvasRenderingContext2D - __webpack_require__(67); /** - * @constructor Network - * Create a network visualization, displaying nodes and edges. + * Mixin the navigation (User Interface) system and initialize the parameters required * - * @param {Element} container The DOM element in which the Network will - * be created. Normally a div element. - * @param {Object} data An object containing parameters - * {Array} nodes - * {Array} edges - * @param {Object} options Options + * @private */ - function Network (container, data, options) { - if (!(this instanceof Network)) { - throw new SyntaxError('Constructor must be called with the new operator'); - } - - this._initializeMixinLoaders(); - - // create variables and set default values - this.containerElement = container; - - // render and calculation settings - this.renderRefreshRate = 60; // hz (fps) - this.renderTimestep = 1000 / this.renderRefreshRate; // ms -- saves calculation later on - this.renderTime = 0.5 * this.renderTimestep; // measured time it takes to render a frame - this.maxPhysicsTicksPerRender = 3; // max amount of physics ticks per render step. - this.physicsDiscreteStepsize = 0.50; // discrete stepsize of the simulation - - this.initializing = true; - - this.triggerFunctions = {add:null,edit:null,editEdge:null,connect:null,del:null}; - - // set constant values - this.defaultOptions = { - nodes: { - mass: 1, - radiusMin: 10, - radiusMax: 30, - radius: 10, - shape: 'ellipse', - image: undefined, - widthMin: 16, // px - widthMax: 64, // px - fontColor: 'black', - fontSize: 14, // px - fontFace: 'verdana', - fontFill: undefined, - level: -1, - color: { - border: '#2B7CE9', - background: '#97C2FC', - highlight: { - border: '#2B7CE9', - background: '#D2E5FF' - }, - hover: { - border: '#2B7CE9', - background: '#D2E5FF' - } - }, - borderColor: '#2B7CE9', - backgroundColor: '#97C2FC', - highlightColor: '#D2E5FF', - group: undefined, - borderWidth: 1, - borderWidthSelected: undefined - }, - edges: { - widthMin: 1, // - widthMax: 15,// - width: 1, - widthSelectionMultiplier: 2, - hoverWidth: 1.5, - style: 'line', - color: { - color:'#848484', - highlight:'#848484', - hover: '#848484' - }, - fontColor: '#343434', - fontSize: 14, // px - fontFace: 'arial', - fontFill: 'white', - arrowScaleFactor: 1, - dash: { - length: 10, - gap: 5, - altLength: undefined - }, - inheritColor: "from" // to, from, false, true (== from) - }, - configurePhysics:false, - physics: { - barnesHut: { - enabled: true, - theta: 1 / 0.6, // inverted to save time during calculation - gravitationalConstant: -2000, - centralGravity: 0.3, - springLength: 95, - springConstant: 0.04, - damping: 0.09 - }, - repulsion: { - centralGravity: 0.0, - springLength: 200, - springConstant: 0.05, - nodeDistance: 100, - damping: 0.09 - }, - hierarchicalRepulsion: { - enabled: false, - centralGravity: 0.0, - springLength: 100, - springConstant: 0.01, - nodeDistance: 150, - damping: 0.09 - }, - damping: null, - centralGravity: null, - springLength: null, - springConstant: null - }, - clustering: { // Per Node in Cluster = PNiC - enabled: false, // (Boolean) | global on/off switch for clustering. - initialMaxNodes: 100, // (# nodes) | if the initial amount of nodes is larger than this, we cluster until the total number is less than this threshold. - clusterThreshold:500, // (# nodes) | during calculate forces, we check if the total number of nodes is larger than this. If it is, cluster until reduced to reduceToNodes - reduceToNodes:300, // (# nodes) | during calculate forces, we check if the total number of nodes is larger than clusterThreshold. If it is, cluster until reduced to this - chainThreshold: 0.4, // (% of all drawn nodes)| maximum percentage of allowed chainnodes (long strings of connected nodes) within all nodes. (lower means less chains). - clusterEdgeThreshold: 20, // (px) | edge length threshold. if smaller, this node is clustered. - sectorThreshold: 100, // (# nodes in cluster) | cluster size threshold. If larger, expanding in own sector. - screenSizeThreshold: 0.2, // (% of canvas) | relative size threshold. If the width or height of a clusternode takes up this much of the screen, decluster node. - fontSizeMultiplier: 4.0, // (px PNiC) | how much the cluster font size grows per node in cluster (in px). - maxFontSize: 1000, - forceAmplification: 0.1, // (multiplier PNiC) | factor of increase fo the repulsion force of a cluster (per node in cluster). - distanceAmplification: 0.1, // (multiplier PNiC) | factor how much the repulsion distance of a cluster increases (per node in cluster). - edgeGrowth: 20, // (px PNiC) | amount of clusterSize connected to the edge is multiplied with this and added to edgeLength. - nodeScaling: {width: 1, // (px PNiC) | growth of the width per node in cluster. - height: 1, // (px PNiC) | growth of the height per node in cluster. - radius: 1}, // (px PNiC) | growth of the radius per node in cluster. - maxNodeSizeIncrements: 600, // (# increments) | max growth of the width per node in cluster. - activeAreaBoxSize: 80, // (px) | box area around the curser where clusters are popped open. - clusterLevelDifference: 2 - }, - navigation: { - enabled: false - }, - keyboard: { - enabled: false, - speed: {x: 10, y: 10, zoom: 0.02} - }, - dataManipulation: { - enabled: false, - initiallyVisible: false - }, - hierarchicalLayout: { - enabled:false, - levelSeparation: 150, - nodeSpacing: 100, - direction: "UD", // UD, DU, LR, RL - layout: "hubsize" // hubsize, directed - }, - freezeForStabilization: false, - smoothCurves: { - enabled: true, - dynamic: true, - type: "continuous", - roundness: 0.5 - }, - dynamicSmoothCurves: true, - maxVelocity: 30, - minVelocity: 0.1, // px/s - stabilize: true, // stabilize before displaying the network - stabilizationIterations: 1000, // maximum number of iteration to stabilize - locale: 'en', - locales: locales, - tooltip: { - delay: 300, - fontColor: 'black', - fontSize: 14, // px - fontFace: 'verdana', - color: { - border: '#666', - background: '#FFFFC6' - } - }, - dragNetwork: true, - dragNodes: true, - zoomable: true, - hover: false, - hideEdgesOnDrag: false, - hideNodesOnDrag: false, - width : '100%', - height : '100%', - selectable: true - }; - this.constants = util.extend({}, this.defaultOptions); - - this.hoverObj = {nodes:{},edges:{}}; - this.controlNodesActive = false; - this.navigationHammers = {existing:[], new: []}; - - // animation properties - this.animationSpeed = 1/this.renderRefreshRate; - this.animationEasingFunction = "easeInOutQuint"; - this.easingTime = 0; - this.sourceScale = 0; - this.targetScale = 0; - this.sourceTranslation = 0; - this.targetTranslation = 0; - this.lockedOnNodeId = null; - this.lockedOnNodeOffset = null; - - // Node variables - var network = this; - this.groups = new Groups(); // object with groups - this.images = new Images(); // object with images - this.images.setOnloadCallback(function () { - network._redraw(); - }); - - // keyboard navigation variables - this.xIncrement = 0; - this.yIncrement = 0; - this.zoomIncrement = 0; - - // loading all the mixins: - // load the force calculation functions, grouped under the physics system. - this._loadPhysicsSystem(); - // create a frame and canvas - this._create(); - // load the sector system. (mandatory, fully integrated with Network) - this._loadSectorSystem(); - // load the cluster system. (mandatory, even when not using the cluster system, there are function calls to it) - this._loadClusterSystem(); - // load the selection system. (mandatory, required by Network) - this._loadSelectionSystem(); - // load the selection system. (mandatory, required by Network) - this._loadHierarchySystem(); + 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(); + } + }; - // apply options - this._setTranslation(this.frame.clientWidth / 2, this.frame.clientHeight / 2); - this._setScale(1); - this.setOptions(options); + /** + * Mixin the hierarchical layout system. + * + * @private + */ + exports._loadHierarchySystem = function () { + this._loadMixin(HierarchicalLayoutMixin); + }; - // other vars - this.freezeSimulation = false;// freeze the simulation - this.cachedFunctions = {}; - this.startedStabilization = false; - this.stabilized = false; - this.stabilizationIterations = null; - // containers for nodes and edges - this.calculationNodes = {}; - this.calculationNodeIndices = []; - this.nodeIndices = []; // array with all the indices of the nodes. Used to speed up forces calculation - this.nodes = {}; // object with Node objects - this.edges = {}; // object with Edge objects +/***/ }, +/* 51 */ +/***/ function(module, exports, __webpack_require__) { - // position and scale variables and objects - this.canvasTopLeft = {"x": 0,"y": 0}; // coordinates of the top left of the canvas. they will be set during _redraw. - this.canvasBottomRight = {"x": 0,"y": 0}; // coordinates of the bottom right of the canvas. they will be set during _redraw - this.pointerPosition = {"x": 0,"y": 0}; // coordinates of the bottom right of the canvas. they will be set during _redraw - this.areaCenter = {}; // object with x and y elements used for determining the center of the zoom action - this.scale = 1; // defining the global scale variable in the constructor - this.previousScale = this.scale; // this is used to check if the zoom operation is zooming in or out + var mousetrap = __webpack_require__(55); + var Emitter = __webpack_require__(52); + var Hammer = __webpack_require__(44); + var util = __webpack_require__(1); - // datasets or dataviews - this.nodesData = null; // A DataSet or DataView - this.edgesData = null; // A DataSet or DataView + /** + * Turn an element into an clickToUse element. + * When not active, the element has a transparent overlay. When the overlay is + * clicked, the mode is changed to active. + * When active, the element is displayed with a blue border around it, and + * the interactive contents of the element can be used. When clicked outside + * the element, the elements mode is changed to inactive. + * @param {Element} container + * @constructor + */ + function Activator(container) { + this.active = false; - // create event listeners used to subscribe on the DataSets of the nodes and edges - this.nodesListeners = { - 'add': function (event, params) { - network._addNodes(params.items); - network.start(); - }, - 'update': function (event, params) { - network._updateNodes(params.items, params.data); - network.start(); - }, - 'remove': function (event, params) { - network._removeNodes(params.items); - network.start(); - } - }; - this.edgesListeners = { - 'add': function (event, params) { - network._addEdges(params.items); - network.start(); - }, - 'update': function (event, params) { - network._updateEdges(params.items); - network.start(); - }, - 'remove': function (event, params) { - network._removeEdges(params.items); - network.start(); - } + this.dom = { + container: container }; - // properties for the animation - this.moving = true; - this.timer = undefined; // Scheduling function. Is definded in this.start(); + this.dom.overlay = document.createElement('div'); + this.dom.overlay.className = 'overlay'; - // load data (the disable start variable will be the same as the enabled clustering) - this.setData(data,this.constants.clustering.enabled || this.constants.hierarchicalLayout.enabled); + this.dom.container.appendChild(this.dom.overlay); - // hierarchical layout - this.initializing = false; - if (this.constants.hierarchicalLayout.enabled == true) { - this._setupHierarchicalLayout(); - } - else { - // zoom so all data will fit on the screen, if clustering is enabled, we do not want start to be called here. - if (this.constants.stabilize == false) { - this.zoomExtent(undefined, true,this.constants.clustering.enabled); + this.hammer = Hammer(this.dom.overlay, {prevent_default: false}); + this.hammer.on('tap', this._onTapOverlay.bind(this)); + + // block all touch events (except tap) + var me = this; + var events = [ + 'touch', 'pinch', + 'doubletap', 'hold', + 'dragstart', 'drag', 'dragend', + 'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox + ]; + events.forEach(function (event) { + me.hammer.on(event, function (event) { + event.stopPropagation(); + }); + }); + + // attach a tap event to the window, in order to deactivate when clicking outside the timeline + this.windowHammer = Hammer(window, {prevent_default: false}); + this.windowHammer.on('tap', function (event) { + // deactivate when clicked outside the container + if (!_hasParent(event.target, container)) { + me.deactivate(); } - } + }); - // if clustering is disabled, the simulation will have started in the setData function - if (this.constants.clustering.enabled) { - this.startWithClustering(); - } + // mousetrap listener only bounded when active) + this.escListener = this.deactivate.bind(this); } - // Extend Network with an Emitter mixin - Emitter(Network.prototype); + // turn into an event emitter + Emitter(Activator.prototype); + + // The currently active activator + Activator.current = null; /** - * Get the script path where the vis.js library is located - * - * @returns {string | null} path Path or null when not found. Path does not - * end with a slash. - * @private + * Destroy the activator. Cleans up all created DOM and event listeners */ - Network.prototype._getScriptPath = function() { - var scripts = document.getElementsByTagName( 'script' ); + Activator.prototype.destroy = function () { + this.deactivate(); - // find script named vis.js or vis.min.js - for (var i = 0; i < scripts.length; i++) { - var src = scripts[i].src; - var match = src && /\/?vis(.min)?\.js$/.exec(src); - if (match) { - // return path without the script name - return src.substring(0, src.length - match[0].length); - } + // remove dom + this.dom.overlay.parentNode.removeChild(this.dom.overlay); + + // cleanup hammer instances + this.hammer = null; + this.windowHammer = null; + // FIXME: cleaning up hammer instances doesn't work (Timeline not removed from memory) + }; + + /** + * Activate the element + * Overlay is hidden, element is decorated with a blue shadow border + */ + Activator.prototype.activate = function () { + // we allow only one active activator at a time + if (Activator.current) { + Activator.current.deactivate(); } + Activator.current = this; - return null; + this.active = true; + this.dom.overlay.style.display = 'none'; + util.addClassName(this.dom.container, 'vis-active'); + + this.emit('change'); + this.emit('activate'); + + // ugly hack: bind ESC after emitting the events, as the Network rebinds all + // keyboard events on a 'change' event + mousetrap.bind('esc', this.escListener); + }; + + /** + * Deactivate the element + * Overlay is displayed on top of the element + */ + Activator.prototype.deactivate = function () { + this.active = false; + this.dom.overlay.style.display = ''; + util.removeClassName(this.dom.container, 'vis-active'); + mousetrap.unbind('esc', this.escListener); + + this.emit('change'); + this.emit('deactivate'); }; + /** + * Handle a tap event: activate the container + * @param event + * @private + */ + Activator.prototype._onTapOverlay = function (event) { + // activate the container + this.activate(); + event.stopPropagation(); + }; /** - * Find the center position of the network + * Test whether the element has the requested parent element somewhere in + * its chain of parent nodes. + * @param {HTMLElement} element + * @param {HTMLElement} parent + * @returns {boolean} Returns true when the parent is found somewhere in the + * chain of parent nodes. * @private */ - Network.prototype._getRange = function() { - var minY = 1e9, maxY = -1e9, minX = 1e9, maxX = -1e9, node; - for (var nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - node = this.nodes[nodeId]; - if (minX > (node.x)) {minX = node.x;} - if (maxX < (node.x)) {maxX = node.x;} - if (minY > (node.y)) {minY = node.y;} - if (maxY < (node.y)) {maxY = node.y;} + function _hasParent(element, parent) { + while (element) { + if (element === parent) { + return true } + element = element.parentNode; } - if (minX == 1e9 && maxX == -1e9 && minY == 1e9 && maxY == -1e9) { - minY = 0, maxY = 0, minX = 0, maxX = 0; - } - return {minX: minX, maxX: maxX, minY: minY, maxY: maxY}; - }; + return false; + } + module.exports = Activator; + + +/***/ }, +/* 52 */ +/***/ function(module, exports, __webpack_require__) { + /** - * @param {object} range = {minX: minX, maxX: maxX, minY: minY, maxY: maxY}; - * @returns {{x: number, y: number}} - * @private + * Expose `Emitter`. */ - Network.prototype._findCenter = function(range) { - return {x: (0.5 * (range.maxX + range.minX)), - y: (0.5 * (range.maxY + range.minY))}; - }; + module.exports = Emitter; /** - * This function zooms out to fit all data on screen based on amount of nodes + * Initialize a new `Emitter`. * - * @param {Boolean} [initialZoom] | zoom based on fitted formula or range, true = fitted, default = false; - * @param {Boolean} [disableStart] | If true, start is not called. + * @api public */ - Network.prototype.zoomExtent = function(animationOptions, initialZoom, disableStart) { - if (initialZoom === undefined) { - initialZoom = false; - } - if (disableStart === undefined) { - disableStart = false; - } - if (animationOptions === undefined) { - animationOptions = false; - } - var range = this._getRange(); - var zoomLevel; + function Emitter(obj) { + if (obj) return mixin(obj); + }; - if (initialZoom == true) { - var numberOfNodes = this.nodeIndices.length; - if (this.constants.smoothCurves == true) { - if (this.constants.clustering.enabled == true && - numberOfNodes >= this.constants.clustering.initialMaxNodes) { - zoomLevel = 49.07548 / (numberOfNodes + 142.05338) + 9.1444e-04; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. - } - else { - zoomLevel = 12.662 / (numberOfNodes + 7.4147) + 0.0964822; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. - } - } - else { - if (this.constants.clustering.enabled == true && - numberOfNodes >= this.constants.clustering.initialMaxNodes) { - zoomLevel = 77.5271985 / (numberOfNodes + 187.266146) + 4.76710517e-05; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. - } - else { - zoomLevel = 30.5062972 / (numberOfNodes + 19.93597763) + 0.08413486; // this is obtained from fitting a dataset from 5 points with scale levels that looked good. - } - } + /** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ - // correct for larger canvasses. - var factor = Math.min(this.frame.canvas.clientWidth / 600, this.frame.canvas.clientHeight / 600); - zoomLevel *= factor; + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; } - else { - var xDistance = Math.abs(range.maxX - range.minX) * 1.1; - var yDistance = Math.abs(range.maxY - range.minY) * 1.1; + return obj; + } - var xZoomLevel = this.frame.canvas.clientWidth / xDistance; - var yZoomLevel = this.frame.canvas.clientHeight / yDistance; + /** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ - zoomLevel = (xZoomLevel <= yZoomLevel) ? xZoomLevel : yZoomLevel; + Emitter.prototype.on = + Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; + }; + + /** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); } - if (zoomLevel > 1.0) { - zoomLevel = 1.0; + on.fn = fn; + this.on(event, on); + return this; + }; + + /** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.off = + Emitter.prototype.removeListener = + Emitter.prototype.removeAllListeners = + Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; } + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; - var center = this._findCenter(range); - if (disableStart == false) { - var options = {position: center, scale: zoomLevel, animation: animationOptions}; - this.moveTo(options); - this.moving = true; - this.start(); + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; } - else { - center.x *= zoomLevel; - center.y *= zoomLevel; - center.x -= 0.5 * this.frame.canvas.clientWidth; - center.y -= 0.5 * this.frame.canvas.clientHeight; - this._setScale(zoomLevel); - this._setTranslation(-center.x,-center.y); + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } } + return this; }; - /** - * Update the this.nodeIndices with the most recent node index list - * @private + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} */ - Network.prototype._updateNodeIndexList = function() { - this._clearNodeIndexList(); - for (var idx in this.nodes) { - if (this.nodes.hasOwnProperty(idx)) { - this.nodeIndices.push(idx); + + Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); } } - }; + return this; + }; /** - * Set nodes and edges, and optionally options as well. + * Return array of callbacks for `event`. * - * @param {Object} data Object containing parameters: - * {Array | DataSet | DataView} [nodes] Array with nodes - * {Array | DataSet | DataView} [edges] Array with edges - * {String} [dot] String containing data in DOT format - * {String} [gephi] String containing data in gephi JSON format - * {Options} [options] Object with options - * @param {Boolean} [disableStart] | optional: disable the calling of the start function. + * @param {String} event + * @return {Array} + * @api public */ - Network.prototype.setData = function(data, disableStart) { - if (disableStart === undefined) { - disableStart = false; - } - // we set initializing to true to ensure that the hierarchical layout is not performed until both nodes and edges are added. - this.initializing = true; - if (data && data.dot && (data.nodes || data.edges)) { - throw new SyntaxError('Data must contain either parameter "dot" or ' + - ' parameter pair "nodes" and "edges", but not both.'); - } + Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; + }; - // set options - this.setOptions(data && data.options); - // set all data - if (data && data.dot) { - // parse DOT file - if(data && data.dot) { - var dotData = dotparser.DOTToGraph(data.dot); - this.setData(dotData); - return; - } - } - else if (data && data.gephi) { - // parse DOT file - if(data && data.gephi) { - var gephiData = gephiParser.parseGephi(data.gephi); - this.setData(gephiData); - return; - } - } - else { - this._setNodes(data && data.nodes); - this._setEdges(data && data.edges); - } - this._putDataInSector(); - if (disableStart == false) { - if (this.constants.hierarchicalLayout.enabled == true) { - this._resetLevels(); - this._setupHierarchicalLayout(); - } - else { - // find a stable position or start animating to a stable position - if (this.constants.stabilize) { - this._stabilize(); - } - } - this.start(); - } - this.initializing = false; + /** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + + Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; }; - /** - * Set options - * @param {Object} options - */ - Network.prototype.setOptions = function (options) { - if (options) { - var prop; - var fields = ['nodes','edges','smoothCurves','hierarchicalLayout','clustering','navigation','keyboard','dataManipulation', - 'onAdd','onEdit','onEditEdge','onConnect','onDelete','clickToUse' - ]; - util.selectiveNotDeepExtend(fields,this.constants, options); - util.selectiveNotDeepExtend(['color'],this.constants.nodes, options.nodes); - util.selectiveNotDeepExtend(['color','length'],this.constants.edges, options.edges); +/***/ }, +/* 53 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global, module) {//! moment.js + //! version : 2.8.3 + //! authors : Tim Wood, Iskren Chernev, Moment.js contributors + //! license : MIT + //! momentjs.com + + (function (undefined) { + /************************************ + Constants + ************************************/ + + var moment, + VERSION = '2.8.3', + // the global-scope this is NOT the global object in Node.js + globalScope = typeof global !== 'undefined' ? global : this, + oldGlobalMoment, + round = Math.round, + hasOwnProperty = Object.prototype.hasOwnProperty, + i, - if (options.physics) { - util.mergeOptions(this.constants.physics, options.physics,'barnesHut'); - util.mergeOptions(this.constants.physics, options.physics,'repulsion'); + YEAR = 0, + MONTH = 1, + DATE = 2, + HOUR = 3, + MINUTE = 4, + SECOND = 5, + MILLISECOND = 6, - if (options.physics.hierarchicalRepulsion) { - this.constants.hierarchicalLayout.enabled = true; - this.constants.physics.hierarchicalRepulsion.enabled = true; - this.constants.physics.barnesHut.enabled = false; - for (prop in options.physics.hierarchicalRepulsion) { - if (options.physics.hierarchicalRepulsion.hasOwnProperty(prop)) { - this.constants.physics.hierarchicalRepulsion[prop] = options.physics.hierarchicalRepulsion[prop]; - } - } - } - } + // internal storage for locale config files + locales = {}, - if (options.onAdd) {this.triggerFunctions.add = options.onAdd;} - if (options.onEdit) {this.triggerFunctions.edit = options.onEdit;} - if (options.onEditEdge) {this.triggerFunctions.editEdge = options.onEditEdge;} - if (options.onConnect) {this.triggerFunctions.connect = options.onConnect;} - if (options.onDelete) {this.triggerFunctions.del = options.onDelete;} + // extra moment internal properties (plugins register props here) + momentProperties = [], - util.mergeOptions(this.constants, options,'smoothCurves'); - util.mergeOptions(this.constants, options,'hierarchicalLayout'); - util.mergeOptions(this.constants, options,'clustering'); - util.mergeOptions(this.constants, options,'navigation'); - util.mergeOptions(this.constants, options,'keyboard'); - util.mergeOptions(this.constants, options,'dataManipulation'); + // check for nodeJS + hasModule = (typeof module !== 'undefined' && module.exports), + // ASP.NET json date format regex + aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, + aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, - if (options.dataManipulation) { - this.editMode = this.constants.dataManipulation.initiallyVisible; - } + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, + // format tokens + formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, + localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, - // TODO: work out these options and document them - if (options.edges) { - if (options.edges.color !== undefined) { - if (util.isString(options.edges.color)) { - this.constants.edges.color = {}; - this.constants.edges.color.color = options.edges.color; - this.constants.edges.color.highlight = options.edges.color; - this.constants.edges.color.hover = options.edges.color; - } - else { - if (options.edges.color.color !== undefined) {this.constants.edges.color.color = options.edges.color.color;} - if (options.edges.color.highlight !== undefined) {this.constants.edges.color.highlight = options.edges.color.highlight;} - if (options.edges.color.hover !== undefined) {this.constants.edges.color.hover = options.edges.color.hover;} - } - } + // parsing token regexes + parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 + parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 + parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999 + parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 + parseTokenDigits = /\d+/, // nonzero number of digits + parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. + parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z + parseTokenT = /T/i, // T (ISO separator) + parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 + parseTokenOrdinal = /\d{1,2}/, - if (!options.edges.fontColor) { - if (options.edges.color !== undefined) { - if (util.isString(options.edges.color)) {this.constants.edges.fontColor = options.edges.color;} - else if (options.edges.color.color !== undefined) {this.constants.edges.fontColor = options.edges.color.color;} - } - } - } + //strict parsing regexes + parseTokenOneDigit = /\d/, // 0 - 9 + parseTokenTwoDigits = /\d\d/, // 00 - 99 + parseTokenThreeDigits = /\d{3}/, // 000 - 999 + parseTokenFourDigits = /\d{4}/, // 0000 - 9999 + parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999 + parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf - if (options.nodes) { - if (options.nodes.color) { - var newColorObj = util.parseColor(options.nodes.color); - this.constants.nodes.color.background = newColorObj.background; - this.constants.nodes.color.border = newColorObj.border; - this.constants.nodes.color.highlight.background = newColorObj.highlight.background; - this.constants.nodes.color.highlight.border = newColorObj.highlight.border; - this.constants.nodes.color.hover.background = newColorObj.hover.background; - this.constants.nodes.color.hover.border = newColorObj.hover.border; - } - } - if (options.groups) { - for (var groupname in options.groups) { - if (options.groups.hasOwnProperty(groupname)) { - var group = options.groups[groupname]; - this.groups.add(groupname, group); - } - } - } + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, - if (options.tooltip) { - for (prop in options.tooltip) { - if (options.tooltip.hasOwnProperty(prop)) { - this.constants.tooltip[prop] = options.tooltip[prop]; - } - } - if (options.tooltip.color) { - this.constants.tooltip.color = util.parseColor(options.tooltip.color); - } - } + isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', - if ('clickToUse' in options) { - if (options.clickToUse) { - this.activator = new Activator(this.frame); - this.activator.on('change', this._createKeyBinds.bind(this)); - } - else { - if (this.activator) { - this.activator.destroy(); - delete this.activator; - } - } - } + isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], + ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], + ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], + ['GGGG-[W]WW', /\d{4}-W\d{2}/], + ['YYYY-DDD', /\d{4}-\d{3}/] + ], - if (options.labels) { - throw new Error('Option "labels" is deprecated. Use options "locale" and "locales" instead.'); - } - } + // iso time formats and regexes + isoTimes = [ + ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], + ['HH:mm', /(T| )\d\d:\d\d/], + ['HH', /(T| )\d\d/] + ], - // (Re)loading the mixins that can be enabled or disabled in the options. - // load the force calculation functions, grouped under the physics system. - this._loadPhysicsSystem(); - // load the navigation system. - this._loadNavigationControls(); - // load the data manipulation system - this._loadManipulationSystem(); - // configure the smooth curves - this._configureSmoothCurves(); + // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-15', '30'] + parseTimezoneChunker = /([\+\-]|\d\d)/gi, + // getter and setter names + proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), + unitMillisecondFactors = { + 'Milliseconds' : 1, + 'Seconds' : 1e3, + 'Minutes' : 6e4, + 'Hours' : 36e5, + 'Days' : 864e5, + 'Months' : 2592e6, + 'Years' : 31536e6 + }, - // bind keys. If disabled, this will not do anything; - this._createKeyBinds(); - this.setSize(this.constants.width, this.constants.height); - this.moving = true; - this.start(); - }; + unitAliases = { + ms : 'millisecond', + s : 'second', + m : 'minute', + h : 'hour', + d : 'day', + D : 'date', + w : 'week', + W : 'isoWeek', + M : 'month', + Q : 'quarter', + y : 'year', + DDD : 'dayOfYear', + e : 'weekday', + E : 'isoWeekday', + gg: 'weekYear', + GG: 'isoWeekYear' + }, - /** - * Create the main frame for the Network. - * This function is executed once when a Network object is created. The frame - * contains a canvas, and this canvas contains all objects like the axis and - * nodes. - * @private - */ - Network.prototype._create = function () { - // remove all elements from the container element. - while (this.containerElement.hasChildNodes()) { - this.containerElement.removeChild(this.containerElement.firstChild); - } + camelFunctions = { + dayofyear : 'dayOfYear', + isoweekday : 'isoWeekday', + isoweek : 'isoWeek', + weekyear : 'weekYear', + isoweekyear : 'isoWeekYear' + }, - this.frame = document.createElement('div'); - this.frame.className = 'vis network-frame'; - this.frame.style.position = 'relative'; - this.frame.style.overflow = 'hidden'; + // format function strings + formatFunctions = {}, - // create the network canvas (HTML canvas element) - this.frame.canvas = document.createElement( 'canvas' ); - this.frame.canvas.style.position = 'relative'; - this.frame.appendChild(this.frame.canvas); - if (!this.frame.canvas.getContext) { - var noCanvas = document.createElement( 'DIV' ); - noCanvas.style.color = 'red'; - noCanvas.style.fontWeight = 'bold' ; - noCanvas.style.padding = '10px'; - noCanvas.innerHTML = 'Error: your browser does not support HTML canvas'; - this.frame.canvas.appendChild(noCanvas); - } + // default relative time thresholds + relativeTimeThresholds = { + s: 45, // seconds to minute + m: 45, // minutes to hour + h: 22, // hours to day + d: 26, // days to month + M: 11 // months to year + }, - var me = this; - this.drag = {}; - this.pinch = {}; - this.hammer = Hammer(this.frame.canvas, { - prevent_default: true - }); - this.hammer.on('tap', me._onTap.bind(me) ); - this.hammer.on('doubletap', me._onDoubleTap.bind(me) ); - this.hammer.on('hold', me._onHold.bind(me) ); - this.hammer.on('pinch', me._onPinch.bind(me) ); - this.hammer.on('touch', me._onTouch.bind(me) ); - this.hammer.on('dragstart', me._onDragStart.bind(me) ); - this.hammer.on('drag', me._onDrag.bind(me) ); - this.hammer.on('dragend', me._onDragEnd.bind(me) ); - this.hammer.on('release', me._onRelease.bind(me) ); - this.hammer.on('mousewheel',me._onMouseWheel.bind(me) ); - this.hammer.on('DOMMouseScroll',me._onMouseWheel.bind(me) ); // for FF - this.hammer.on('mousemove', me._onMouseMoveTitle.bind(me) ); + // tokens to ordinalize and pad + ordinalizeTokens = 'DDD w W M D d'.split(' '), + paddedTokens = 'M D H h m s w W'.split(' '), - // add the frame to the container element - this.containerElement.appendChild(this.frame); + formatTokenFunctions = { + M : function () { + return this.month() + 1; + }, + MMM : function (format) { + return this.localeData().monthsShort(this, format); + }, + MMMM : function (format) { + return this.localeData().months(this, format); + }, + D : function () { + return this.date(); + }, + DDD : function () { + return this.dayOfYear(); + }, + d : function () { + return this.day(); + }, + dd : function (format) { + return this.localeData().weekdaysMin(this, format); + }, + ddd : function (format) { + return this.localeData().weekdaysShort(this, format); + }, + dddd : function (format) { + return this.localeData().weekdays(this, format); + }, + w : function () { + return this.week(); + }, + W : function () { + return this.isoWeek(); + }, + YY : function () { + return leftZeroFill(this.year() % 100, 2); + }, + YYYY : function () { + return leftZeroFill(this.year(), 4); + }, + YYYYY : function () { + return leftZeroFill(this.year(), 5); + }, + YYYYYY : function () { + var y = this.year(), sign = y >= 0 ? '+' : '-'; + return sign + leftZeroFill(Math.abs(y), 6); + }, + gg : function () { + return leftZeroFill(this.weekYear() % 100, 2); + }, + gggg : function () { + return leftZeroFill(this.weekYear(), 4); + }, + ggggg : function () { + return leftZeroFill(this.weekYear(), 5); + }, + GG : function () { + return leftZeroFill(this.isoWeekYear() % 100, 2); + }, + GGGG : function () { + return leftZeroFill(this.isoWeekYear(), 4); + }, + GGGGG : function () { + return leftZeroFill(this.isoWeekYear(), 5); + }, + e : function () { + return this.weekday(); + }, + E : function () { + return this.isoWeekday(); + }, + a : function () { + return this.localeData().meridiem(this.hours(), this.minutes(), true); + }, + A : function () { + return this.localeData().meridiem(this.hours(), this.minutes(), false); + }, + H : function () { + return this.hours(); + }, + h : function () { + return this.hours() % 12 || 12; + }, + m : function () { + return this.minutes(); + }, + s : function () { + return this.seconds(); + }, + S : function () { + return toInt(this.milliseconds() / 100); + }, + SS : function () { + return leftZeroFill(toInt(this.milliseconds() / 10), 2); + }, + SSS : function () { + return leftZeroFill(this.milliseconds(), 3); + }, + SSSS : function () { + return leftZeroFill(this.milliseconds(), 3); + }, + Z : function () { + var a = -this.zone(), + b = '+'; + if (a < 0) { + a = -a; + b = '-'; + } + return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2); + }, + ZZ : function () { + var a = -this.zone(), + b = '+'; + if (a < 0) { + a = -a; + b = '-'; + } + return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); + }, + z : function () { + return this.zoneAbbr(); + }, + zz : function () { + return this.zoneName(); + }, + X : function () { + return this.unix(); + }, + Q : function () { + return this.quarter(); + } + }, - }; + deprecations = {}, + lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; - /** - * Binding the keys for keyboard navigation. These functions are defined in the NavigationMixin - * @private - */ - Network.prototype._createKeyBinds = function() { - var me = this; - this.mousetrap = mousetrap; + // Pick the first defined of two or three arguments. dfl comes from + // default. + function dfl(a, b, c) { + switch (arguments.length) { + case 2: return a != null ? a : b; + case 3: return a != null ? a : b != null ? b : c; + default: throw new Error('Implement me'); + } + } - this.mousetrap.reset(); + function hasOwnProp(a, b) { + return hasOwnProperty.call(a, b); + } - if (this.constants.keyboard.enabled && this.isActive()) { - this.mousetrap.bind("up", this._moveUp.bind(me) , "keydown"); - this.mousetrap.bind("up", this._yStopMoving.bind(me), "keyup"); - this.mousetrap.bind("down", this._moveDown.bind(me) , "keydown"); - this.mousetrap.bind("down", this._yStopMoving.bind(me), "keyup"); - this.mousetrap.bind("left", this._moveLeft.bind(me) , "keydown"); - this.mousetrap.bind("left", this._xStopMoving.bind(me), "keyup"); - this.mousetrap.bind("right",this._moveRight.bind(me), "keydown"); - this.mousetrap.bind("right",this._xStopMoving.bind(me), "keyup"); - this.mousetrap.bind("=", this._zoomIn.bind(me), "keydown"); - this.mousetrap.bind("=", this._stopZoom.bind(me), "keyup"); - this.mousetrap.bind("-", this._zoomOut.bind(me), "keydown"); - this.mousetrap.bind("-", this._stopZoom.bind(me), "keyup"); - this.mousetrap.bind("[", this._zoomIn.bind(me), "keydown"); - this.mousetrap.bind("[", this._stopZoom.bind(me), "keyup"); - this.mousetrap.bind("]", this._zoomOut.bind(me), "keydown"); - this.mousetrap.bind("]", this._stopZoom.bind(me), "keyup"); - this.mousetrap.bind("pageup",this._zoomIn.bind(me), "keydown"); - this.mousetrap.bind("pageup",this._stopZoom.bind(me), "keyup"); - this.mousetrap.bind("pagedown",this._zoomOut.bind(me),"keydown"); - this.mousetrap.bind("pagedown",this._stopZoom.bind(me), "keyup"); - } + function defaultParsingFlags() { + // We need to deep clone this object, and es5 standard is not very + // helpful. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso: false + }; + } - if (this.constants.dataManipulation.enabled == true) { - this.mousetrap.bind("escape",this._createManipulatorBar.bind(me)); - this.mousetrap.bind("del",this._deleteSelected.bind(me)); - } - }; + function printMsg(msg) { + if (moment.suppressDeprecationWarnings === false && + typeof console !== 'undefined' && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } - /** - * Get the pointer location from a touch location - * @param {{pageX: Number, pageY: Number}} touch - * @return {{x: Number, y: Number}} pointer - * @private - */ - Network.prototype._getPointer = function (touch) { - return { - x: touch.pageX - util.getAbsoluteLeft(this.frame.canvas), - y: touch.pageY - util.getAbsoluteTop(this.frame.canvas) - }; - }; + function deprecate(msg, fn) { + var firstTime = true; + return extend(function () { + if (firstTime) { + printMsg(msg); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } - /** - * On start of a touch gesture, store the pointer - * @param event - * @private - */ - Network.prototype._onTouch = function (event) { - this.drag.pointer = this._getPointer(event.gesture.center); - this.drag.pinched = false; - this.pinch.scale = this._getScale(); + function deprecateSimple(name, msg) { + if (!deprecations[name]) { + printMsg(msg); + deprecations[name] = true; + } + } - this._handleTouch(this.drag.pointer); - }; + function padToken(func, count) { + return function (a) { + return leftZeroFill(func.call(this, a), count); + }; + } + function ordinalizeToken(func, period) { + return function (a) { + return this.localeData().ordinal(func.call(this, a), period); + }; + } - /** - * handle drag start event - * @private - */ - Network.prototype._onDragStart = function () { - this._handleDragStart(); - }; + while (ordinalizeTokens.length) { + i = ordinalizeTokens.pop(); + formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i); + } + while (paddedTokens.length) { + i = paddedTokens.pop(); + formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); + } + formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); - /** - * This function is called by _onDragStart. - * It is separated out because we can then overload it for the datamanipulation system. - * - * @private - */ - Network.prototype._handleDragStart = function() { - var drag = this.drag; - var node = this._getNodeAt(drag.pointer); - // note: drag.pointer is set in _onTouch to get the initial touch location + /************************************ + Constructors + ************************************/ - drag.dragging = true; - drag.selection = []; - drag.translation = this._getTranslation(); - drag.nodeId = null; + function Locale() { + } - if (node != null && this.constants.dragNodes == true) { - drag.nodeId = node.id; - // select the clicked node if not yet selected - if (!node.isSelected()) { - this._selectObject(node,false); + // Moment prototype object + function Moment(config, skipOverflow) { + if (skipOverflow !== false) { + checkOverflow(config); + } + copyConfig(this, config); + this._d = new Date(+config._d); } - this.emit("dragStart",{nodeIds:this.getSelection().nodes}); + // Duration Constructor + function Duration(duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; - // create an array with the selected nodes and their original location and status - for (var objectId in this.selectionObj.nodes) { - if (this.selectionObj.nodes.hasOwnProperty(objectId)) { - var object = this.selectionObj.nodes[objectId]; - var s = { - id: object.id, - node: object, + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 36e5; // 1000 * 60 * 60 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; - // store original x, y, xFixed and yFixed, make the node temporarily Fixed - x: object.x, - y: object.y, - xFixed: object.xFixed, - yFixed: object.yFixed - }; + this._data = {}; - object.xFixed = true; - object.yFixed = true; + this._locale = moment.localeData(); - drag.selection.push(s); - } + this._bubble(); } - } - }; - - /** - * handle drag event - * @private - */ - Network.prototype._onDrag = function (event) { - this._handleOnDrag(event) - }; + /************************************ + Helpers + ************************************/ - /** - * This function is called by _onDrag. - * It is separated out because we can then overload it for the datamanipulation system. - * - * @private - */ - Network.prototype._handleOnDrag = function(event) { - if (this.drag.pinched) { - return; - } + function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } - // remove the focus on node if it is focussed on by the focusOnNode - this.releaseNode(); + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } - var pointer = this._getPointer(event.gesture.center); - var me = this; - var drag = this.drag; - var selection = drag.selection; - if (selection && selection.length && this.constants.dragNodes == true) { - // calculate delta's and new location - var deltaX = pointer.x - drag.pointer.x; - var deltaY = pointer.y - drag.pointer.y; + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } - // update position of all selected nodes - selection.forEach(function (s) { - var node = s.node; + return a; + } - if (!s.xFixed) { - node.x = me._XconvertDOMtoCanvas(me._XconvertCanvasToDOM(s.x) + deltaX); - } + function copyConfig(to, from) { + var i, prop, val; - if (!s.yFixed) { - node.y = me._YconvertDOMtoCanvas(me._YconvertCanvasToDOM(s.y) + deltaY); - } - }); + if (typeof from._isAMomentObject !== 'undefined') { + to._isAMomentObject = from._isAMomentObject; + } + if (typeof from._i !== 'undefined') { + to._i = from._i; + } + if (typeof from._f !== 'undefined') { + to._f = from._f; + } + if (typeof from._l !== 'undefined') { + to._l = from._l; + } + if (typeof from._strict !== 'undefined') { + to._strict = from._strict; + } + if (typeof from._tzm !== 'undefined') { + to._tzm = from._tzm; + } + if (typeof from._isUTC !== 'undefined') { + to._isUTC = from._isUTC; + } + if (typeof from._offset !== 'undefined') { + to._offset = from._offset; + } + if (typeof from._pf !== 'undefined') { + to._pf = from._pf; + } + if (typeof from._locale !== 'undefined') { + to._locale = from._locale; + } + if (momentProperties.length > 0) { + for (i in momentProperties) { + prop = momentProperties[i]; + val = from[prop]; + if (typeof val !== 'undefined') { + to[prop] = val; + } + } + } - // start _animationStep if not yet running - if (!this.moving) { - this.moving = true; - this.start(); + return to; } - } - else { - if (this.constants.dragNetwork == true) { - // move the network - var diffX = pointer.x - this.drag.pointer.x; - var diffY = pointer.y - this.drag.pointer.y; - this._setTranslation( - this.drag.translation.x + diffX, - this.drag.translation.y + diffY - ); - this._redraw(); - // this.moving = true; - // this.start(); + function absRound(number) { + if (number < 0) { + return Math.ceil(number); + } else { + return Math.floor(number); + } } - } - }; - /** - * handle drag start event - * @private - */ - Network.prototype._onDragEnd = function (event) { - this._handleDragEnd(event); - }; + // left zero fill a number + // see http://jsperf.com/left-zero-filling for performance comparison + function leftZeroFill(number, targetLength, forceSign) { + var output = '' + Math.abs(number), + sign = number >= 0; + while (output.length < targetLength) { + output = '0' + output; + } + return (sign ? (forceSign ? '+' : '') : '-') + output; + } - Network.prototype._handleDragEnd = function(event) { - this.drag.dragging = false; - var selection = this.drag.selection; - if (selection && selection.length) { - selection.forEach(function (s) { - // restore original xFixed and yFixed - s.node.xFixed = s.xFixed; - s.node.yFixed = s.yFixed; - }); - this.moving = true; - this.start(); - } - else { - this._redraw(); - } - this.emit("dragEnd",{nodeIds:this.getSelection().nodes}); - } - /** - * handle tap/click event: select/unselect a node - * @private - */ - Network.prototype._onTap = function (event) { - var pointer = this._getPointer(event.gesture.center); - this.pointerPosition = pointer; - this._handleTap(pointer); + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; - }; + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - /** - * handle doubletap event - * @private - */ - Network.prototype._onDoubleTap = function (event) { - var pointer = this._getPointer(event.gesture.center); - this._handleDoubleTap(pointer); - }; + return res; + } + function momentsDifference(base, other) { + var res; + other = makeAs(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } - /** - * handle long tap event: multi select nodes - * @private - */ - Network.prototype._onHold = function (event) { - var pointer = this._getPointer(event.gesture.center); - this.pointerPosition = pointer; - this._handleOnHold(pointer); - }; + return res; + } - /** - * handle the release of the screen - * - * @private - */ - Network.prototype._onRelease = function (event) { - var pointer = this._getPointer(event.gesture.center); - this._handleOnRelease(pointer); - }; + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).'); + tmp = val; val = period; period = tmp; + } - /** - * Handle pinch event - * @param event - * @private - */ - Network.prototype._onPinch = function (event) { - var pointer = this._getPointer(event.gesture.center); + val = typeof val === 'string' ? +val : val; + dur = moment.duration(val, period); + addOrSubtractDurationFromMoment(this, dur, direction); + return this; + }; + } - this.drag.pinched = true; - if (!('scale' in this.pinch)) { - this.pinch.scale = 1; - } + function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = duration._days, + months = duration._months; + updateOffset = updateOffset == null ? true : updateOffset; - // TODO: enabled moving while pinching? - var scale = this.pinch.scale * event.gesture.scale; - this._zoom(scale, pointer) - }; + if (milliseconds) { + mom._d.setTime(+mom._d + milliseconds * isAdding); + } + if (days) { + rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); + } + if (months) { + rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); + } + if (updateOffset) { + moment.updateOffset(mom, days || months); + } + } - /** - * Zoom the network in or out - * @param {Number} scale a number around 1, and between 0.01 and 10 - * @param {{x: Number, y: Number}} pointer Position on screen - * @return {Number} appliedScale scale is limited within the boundaries - * @private - */ - Network.prototype._zoom = function(scale, pointer) { - if (this.constants.zoomable == true) { - var scaleOld = this._getScale(); - if (scale < 0.00001) { - scale = 0.00001; + // check if is an array + function isArray(input) { + return Object.prototype.toString.call(input) === '[object Array]'; } - if (scale > 10) { - scale = 10; + + function isDate(input) { + return Object.prototype.toString.call(input) === '[object Date]' || + input instanceof Date; } - var preScaleDragPointer = null; - if (this.drag !== undefined) { - if (this.drag.dragging == true) { - preScaleDragPointer = this.DOMtoCanvas(this.drag.pointer); - } + // compare two arrays, return the number of differences + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; } - // + this.frame.canvas.clientHeight / 2 - var translation = this._getTranslation(); - var scaleFrac = scale / scaleOld; - var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac; - var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac; + function normalizeUnits(units) { + if (units) { + var lowered = units.toLowerCase().replace(/(.)s$/, '$1'); + units = unitAliases[units] || camelFunctions[lowered] || lowered; + } + return units; + } - this.areaCenter = {"x" : this._XconvertDOMtoCanvas(pointer.x), - "y" : this._YconvertDOMtoCanvas(pointer.y)}; + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; - this._setScale(scale); - this._setTranslation(tx, ty); - this.updateClustersDefault(); + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } - if (preScaleDragPointer != null) { - var postScaleDragPointer = this.canvasToDOM(preScaleDragPointer); - this.drag.pointer.x = postScaleDragPointer.x; - this.drag.pointer.y = postScaleDragPointer.y; + return normalizedInput; } - this._redraw(); - - if (scaleOld < scale) { - this.emit("zoom", {direction:"+"}); - } - else { - this.emit("zoom", {direction:"-"}); - } + function makeList(field) { + var count, setter; - return scale; - } - }; + if (field.indexOf('week') === 0) { + count = 7; + setter = 'day'; + } + else if (field.indexOf('month') === 0) { + count = 12; + setter = 'month'; + } + else { + return; + } + moment[field] = function (format, index) { + var i, getter, + method = moment._locale[field], + results = []; - /** - * Event handler for mouse wheel event, used to zoom the timeline - * See http://adomas.org/javascript-mouse-wheel/ - * https://github.com/EightMedia/hammer.js/issues/256 - * @param {MouseEvent} event - * @private - */ - Network.prototype._onMouseWheel = function(event) { - // retrieve delta - var delta = 0; - if (event.wheelDelta) { /* IE/Opera. */ - delta = event.wheelDelta/120; - } else if (event.detail) { /* Mozilla case. */ - // In Mozilla, sign of delta is different than in IE. - // Also, delta is multiple of 3. - delta = -event.detail/3; - } + if (typeof format === 'number') { + index = format; + format = undefined; + } - // If delta is nonzero, handle it. - // Basically, delta is now positive if wheel was scrolled up, - // and negative, if wheel was scrolled down. - if (delta) { + getter = function (i) { + var m = moment().utc().set(setter, i); + return method.call(moment._locale, m, format || ''); + }; - // calculate the new scale - var scale = this._getScale(); - var zoom = delta / 10; - if (delta < 0) { - zoom = zoom / (1 - zoom); + if (index != null) { + return getter(index); + } + else { + for (i = 0; i < count; i++) { + results.push(getter(i)); + } + return results; + } + }; } - scale *= (1 + zoom); - // calculate the pointer location - var gesture = hammerUtil.fakeGesture(this, event); - var pointer = this._getPointer(gesture.center); + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; - // apply the new scale - this._zoom(scale, pointer); - } + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + if (coercedNumber >= 0) { + value = Math.floor(coercedNumber); + } else { + value = Math.ceil(coercedNumber); + } + } - // Prevent default actions caused by mouse wheel. - event.preventDefault(); - }; + return value; + } + function daysInMonth(year, month) { + return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); + } - /** - * Mouse move handler for checking whether the title moves over a node with a title. - * @param {Event} event - * @private - */ - Network.prototype._onMouseMoveTitle = function (event) { - var gesture = hammerUtil.fakeGesture(this, event); - var pointer = this._getPointer(gesture.center); + function weeksInYear(year, dow, doy) { + return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; + } - // check if the previously selected node is still selected - if (this.popupObj) { - this._checkHidePopup(pointer); - } + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } - // start a timeout that will check if the mouse is positioned above - // an element - var me = this; - var checkShow = function() { - me._checkShowPopup(pointer); - }; - if (this.popupTimer) { - clearInterval(this.popupTimer); // stop any running calculationTimer - } - if (!this.drag.dragging) { - this.popupTimer = setTimeout(checkShow, this.constants.tooltip.delay); - } + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + function checkOverflow(m) { + var overflow; + if (m._a && m._pf.overflow === -2) { + overflow = + m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : + m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : + m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : + m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : + m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : + m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : + -1; - /** - * Adding hover highlights - */ - if (this.constants.hover == true) { - // removing all hover highlights - for (var edgeId in this.hoverObj.edges) { - if (this.hoverObj.edges.hasOwnProperty(edgeId)) { - this.hoverObj.edges[edgeId].hover = false; - delete this.hoverObj.edges[edgeId]; - } - } + if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } - // adding hover highlights - var obj = this._getNodeAt(pointer); - if (obj == null) { - obj = this._getEdgeAt(pointer); - } - if (obj != null) { - this._hoverObject(obj); + m._pf.overflow = overflow; + } } - // removing all node hover highlights except for the selected one. - for (var nodeId in this.hoverObj.nodes) { - if (this.hoverObj.nodes.hasOwnProperty(nodeId)) { - if (obj instanceof Node && obj.id != nodeId || obj instanceof Edge || obj == null) { - this._blurObject(this.hoverObj.nodes[nodeId]); - delete this.hoverObj.nodes[nodeId]; + function isValid(m) { + if (m._isValid == null) { + m._isValid = !isNaN(m._d.getTime()) && + m._pf.overflow < 0 && + !m._pf.empty && + !m._pf.invalidMonth && + !m._pf.nullInput && + !m._pf.invalidFormat && + !m._pf.userInvalidated; + + if (m._strict) { + m._isValid = m._isValid && + m._pf.charsLeftOver === 0 && + m._pf.unusedTokens.length === 0; + } } - } + return m._isValid; } - this.redraw(); - } - }; - /** - * Check if there is an element on the given position in the network - * (a node or edge). If so, and if this element has a title, - * show a popup window with its title. - * - * @param {{x:Number, y:Number}} pointer - * @private - */ - Network.prototype._checkShowPopup = function (pointer) { - var obj = { - left: this._XconvertDOMtoCanvas(pointer.x), - top: this._YconvertDOMtoCanvas(pointer.y), - right: this._XconvertDOMtoCanvas(pointer.x), - bottom: this._YconvertDOMtoCanvas(pointer.y) - }; + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; + } - var id; - var lastPopupNode = this.popupObj; + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; - if (this.popupObj == undefined) { - // search the nodes for overlap, select the top one in case of multiple nodes - var nodes = this.nodes; - for (id in nodes) { - if (nodes.hasOwnProperty(id)) { - var node = nodes[id]; - if (node.getTitle() !== undefined && node.isOverlappingWith(obj)) { - this.popupObj = node; - break; + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; } - } + return null; } - } - if (this.popupObj === undefined) { - // search the edges for overlap - var edges = this.edges; - for (id in edges) { - if (edges.hasOwnProperty(id)) { - var edge = edges[id]; - if (edge.connected && (edge.getTitle() !== undefined) && - edge.isOverlappingWith(obj)) { - this.popupObj = edge; - break; + function loadLocale(name) { + var oldLocale = null; + if (!locales[name] && hasModule) { + try { + oldLocale = moment.locale(); + !(function webpackMissingModule() { var e = new Error("Cannot find module \"./locale\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()); + // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales + moment.locale(oldLocale); + } catch (e) { } } - } + return locales[name]; } - } - - if (this.popupObj) { - // show popup message window - if (this.popupObj != lastPopupNode) { - var me = this; - if (!me.popup) { - me.popup = new Popup(me.frame, me.constants.tooltip); - } - // adjust a small offset such that the mouse cursor is located in the - // bottom left location of the popup, and you can easily move over the - // popup area - me.popup.setPosition(pointer.x - 3, pointer.y - 3); - me.popup.setText(me.popupObj.getTitle()); - me.popup.show(); - } - } - else { - if (this.popup) { - this.popup.hide(); + // Return a moment from input, that is local/utc/zone equivalent to model. + function makeAs(input, model) { + return model._isUTC ? moment(input).zone(model._offset || 0) : + moment(input).local(); } - } - }; + /************************************ + Locale + ************************************/ - /** - * Check if the popup must be hided, which is the case when the mouse is no - * longer hovering on the object - * @param {{x:Number, y:Number}} pointer - * @private - */ - Network.prototype._checkHidePopup = function (pointer) { - if (!this.popupObj || !this._getNodeAt(pointer) ) { - this.popupObj = undefined; - if (this.popup) { - this.popup.hide(); - } - } - }; + extend(Locale.prototype, { - /** - * Set a new size for the network - * @param {string} width Width in pixels or percentage (for example '800px' - * or '50%') - * @param {string} height Height in pixels or percentage (for example '400px' - * or '30%') - */ - Network.prototype.setSize = function(width, height) { - var emitEvent = false; - var oldWidth = this.frame.canvas.width; - var oldHeight = this.frame.canvas.height; - if (width != this.constants.width || height != this.constants.height || this.frame.style.width != width || this.frame.style.height != height) { - this.frame.style.width = width; - this.frame.style.height = height; + set : function (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (typeof prop === 'function') { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + }, - this.frame.canvas.style.width = '100%'; - this.frame.canvas.style.height = '100%'; + _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + months : function (m) { + return this._months[m.month()]; + }, - this.frame.canvas.width = this.frame.canvas.clientWidth; - this.frame.canvas.height = this.frame.canvas.clientHeight; + _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + monthsShort : function (m) { + return this._monthsShort[m.month()]; + }, - this.constants.width = width; - this.constants.height = height; + monthsParse : function (monthName) { + var i, mom, regex; - emitEvent = true; - } - else { - // this would adapt the width of the canvas to the width from 100% if and only if - // there is a change. + if (!this._monthsParse) { + this._monthsParse = []; + } - if (this.frame.canvas.width != this.frame.canvas.clientWidth) { - this.frame.canvas.width = this.frame.canvas.clientWidth; - emitEvent = true; - } - if (this.frame.canvas.height != this.frame.canvas.clientHeight) { - this.frame.canvas.height = this.frame.canvas.clientHeight; - emitEvent = true; - } - } + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + if (!this._monthsParse[i]) { + mom = moment.utc([2000, i]); + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (this._monthsParse[i].test(monthName)) { + return i; + } + } + }, - if (emitEvent == true) { - this.emit('resize', {width:this.frame.canvas.width,height:this.frame.canvas.height, oldWidth: oldWidth, oldHeight: oldHeight}); - } - }; + _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdays : function (m) { + return this._weekdays[m.day()]; + }, - /** - * Set a data set with nodes for the network - * @param {Array | DataSet | DataView} nodes The data containing the nodes. - * @private - */ - Network.prototype._setNodes = function(nodes) { - var oldNodesData = this.nodesData; + _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysShort : function (m) { + return this._weekdaysShort[m.day()]; + }, - if (nodes instanceof DataSet || nodes instanceof DataView) { - this.nodesData = nodes; - } - else if (Array.isArray(nodes)) { - this.nodesData = new DataSet(); - this.nodesData.add(nodes); - } - else if (!nodes) { - this.nodesData = new DataSet(); - } - else { - throw new TypeError('Array or DataSet expected'); - } + _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + weekdaysMin : function (m) { + return this._weekdaysMin[m.day()]; + }, - if (oldNodesData) { - // unsubscribe from old dataset - util.forEach(this.nodesListeners, function (callback, event) { - oldNodesData.off(event, callback); - }); - } + weekdaysParse : function (weekdayName) { + var i, mom, regex; - // remove drawn nodes - this.nodes = {}; + if (!this._weekdaysParse) { + this._weekdaysParse = []; + } - if (this.nodesData) { - // subscribe to new dataset - var me = this; - util.forEach(this.nodesListeners, function (callback, event) { - me.nodesData.on(event, callback); - }); + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + if (!this._weekdaysParse[i]) { + mom = moment([2000, 1]).day(i); + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + }, - // draw all new nodes - var ids = this.nodesData.getIds(); - this._addNodes(ids); - } - this._updateSelection(); - }; + _longDateFormat : { + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY LT', + LLLL : 'dddd, MMMM D, YYYY LT' + }, + longDateFormat : function (key) { + var output = this._longDateFormat[key]; + if (!output && this._longDateFormat[key.toUpperCase()]) { + output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + this._longDateFormat[key] = output; + } + return output; + }, - /** - * Add nodes - * @param {Number[] | String[]} ids - * @private - */ - Network.prototype._addNodes = function(ids) { - var id; - for (var i = 0, len = ids.length; i < len; i++) { - id = ids[i]; - var data = this.nodesData.get(id); - var node = new Node(data, this.images, this.groups, this.constants); - this.nodes[id] = node; // note: this may replace an existing node - if ((node.xFixed == false || node.yFixed == false) && (node.x === null || node.y === null)) { - var radius = 10 * 0.1*ids.length + 10; - 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.moving = true; - } + isPM : function (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); + }, - this._updateNodeIndexList(); - if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { - this._resetLevels(); - this._setupHierarchicalLayout(); - } - this._updateCalculationNodes(); - this._reconnectEdges(); - this._updateValueRange(this.nodes); - this.updateLabels(); - }; + _meridiemParse : /[ap]\.?m?\.?/i, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + }, - /** - * Update existing nodes, or create them when not yet existing - * @param {Number[] | String[]} ids - * @private - */ - Network.prototype._updateNodes = function(ids,changedData) { - var nodes = this.nodes; - for (var i = 0, len = ids.length; i < len; i++) { - var id = ids[i]; - var node = nodes[id]; - var data = changedData[i]; - if (node) { - // update node - node.setProperties(data, this.constants); - } - else { - // create node - node = new Node(properties, this.images, this.groups, this.constants); - nodes[id] = node; - } - } - this.moving = true; - if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { - this._resetLevels(); - this._setupHierarchicalLayout(); - } - this._updateNodeIndexList(); - this._updateValueRange(nodes); - }; + _calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + calendar : function (key, mom) { + var output = this._calendar[key]; + return typeof output === 'function' ? output.apply(mom) : output; + }, + + _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' + }, - /** - * Remove existing nodes. If nodes do not exist, the method will just ignore it. - * @param {Number[] | String[]} ids - * @private - */ - Network.prototype._removeNodes = function(ids) { - var nodes = this.nodes; - for (var i = 0, len = ids.length; i < len; i++) { - var id = ids[i]; - delete nodes[id]; - } - this._updateNodeIndexList(); - if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { - this._resetLevels(); - this._setupHierarchicalLayout(); - } - this._updateCalculationNodes(); - this._reconnectEdges(); - this._updateSelection(); - this._updateValueRange(nodes); - }; + relativeTime : function (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (typeof output === 'function') ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); + }, - /** - * Load edges by reading the data table - * @param {Array | DataSet | DataView} edges The data containing the edges. - * @private - * @private - */ - Network.prototype._setEdges = function(edges) { - var oldEdgesData = this.edgesData; + pastFuture : function (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); + }, - if (edges instanceof DataSet || edges instanceof DataView) { - this.edgesData = edges; - } - else if (Array.isArray(edges)) { - this.edgesData = new DataSet(); - this.edgesData.add(edges); - } - else if (!edges) { - this.edgesData = new DataSet(); - } - else { - throw new TypeError('Array or DataSet expected'); - } + ordinal : function (number) { + return this._ordinal.replace('%d', number); + }, + _ordinal : '%d', - if (oldEdgesData) { - // unsubscribe from old dataset - util.forEach(this.edgesListeners, function (callback, event) { - oldEdgesData.off(event, callback); - }); - } + preparse : function (string) { + return string; + }, - // remove drawn edges - this.edges = {}; + postformat : function (string) { + return string; + }, - if (this.edgesData) { - // subscribe to new dataset - var me = this; - util.forEach(this.edgesListeners, function (callback, event) { - me.edgesData.on(event, callback); - }); + week : function (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + }, - // draw all new nodes - var ids = this.edgesData.getIds(); - this._addEdges(ids); - } + _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._reconnectEdges(); - }; + _invalidDate: 'Invalid date', + invalidDate: function () { + return this._invalidDate; + } + }); - /** - * Add edges - * @param {Number[] | String[]} ids - * @private - */ - Network.prototype._addEdges = function (ids) { - var edges = this.edges, - edgesData = this.edgesData; + /************************************ + Formatting + ************************************/ - for (var i = 0, len = ids.length; i < len; i++) { - var id = ids[i]; - var oldEdge = edges[id]; - if (oldEdge) { - oldEdge.disconnect(); + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); } - var data = edgesData.get(id, {"showInternalIds" : true}); - edges[id] = new Edge(data, this, this.constants); - } - this.moving = true; - this._updateValueRange(edges); - this._createBezierNodes(); - this._updateCalculationNodes(); - if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { - this._resetLevels(); - this._setupHierarchicalLayout(); - } - }; + function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; - /** - * Update existing edges, or create them when not yet existing - * @param {Number[] | String[]} ids - * @private - */ - Network.prototype._updateEdges = function (ids) { - var edges = this.edges, - edgesData = this.edgesData; - for (var i = 0, len = ids.length; i < len; i++) { - var id = ids[i]; + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } - var data = edgesData.get(id); - var edge = edges[id]; - if (edge) { - // update edge - edge.disconnect(); - edge.setProperties(data, this.constants); - edge.connect(); - } - else { - // create edge - edge = new Edge(data, this, this.constants); - this.edges[id] = edge; + return function (mom) { + var output = ''; + for (i = 0; i < length; i++) { + output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; + } + return output; + }; } - } - this._createBezierNodes(); - if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { - this._resetLevels(); - this._setupHierarchicalLayout(); - } - this.moving = true; - this._updateValueRange(edges); - }; + // format date using native date object + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } - /** - * Remove existing edges. Non existing ids will be ignored - * @param {Number[] | String[]} ids - * @private - */ - Network.prototype._removeEdges = function (ids) { - var edges = this.edges; - for (var i = 0, len = ids.length; i < len; i++) { - var id = ids[i]; - var edge = edges[id]; - if (edge) { - if (edge.via != null) { - delete this.sectors['support']['nodes'][edge.via.id]; - } - edge.disconnect(); - delete edges[id]; + format = expandFormat(format, m.localeData()); + + if (!formatFunctions[format]) { + formatFunctions[format] = makeFormatFunction(format); + } + + return formatFunctions[format](m); } - } - this.moving = true; - this._updateValueRange(edges); - if (this.constants.hierarchicalLayout.enabled == true && this.initializing == false) { - this._resetLevels(); - this._setupHierarchicalLayout(); - } - this._updateCalculationNodes(); - }; + function expandFormat(format, locale) { + var i = 5; - /** - * Reconnect all edges - * @private - */ - Network.prototype._reconnectEdges = function() { - var id, - nodes = this.nodes, - edges = this.edges; - for (id in nodes) { - if (nodes.hasOwnProperty(id)) { - nodes[id].edges = []; - nodes[id].dynamicEdges = []; + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; } - } - for (id in edges) { - if (edges.hasOwnProperty(id)) { - var edge = edges[id]; - edge.from = null; - edge.to = null; - edge.connect(); + + /************************************ + Parsing + ************************************/ + + + // get the regex to find the next token + function getParseRegexForToken(token, config) { + var a, strict = config._strict; + switch (token) { + case 'Q': + return parseTokenOneDigit; + case 'DDDD': + return parseTokenThreeDigits; + case 'YYYY': + case 'GGGG': + case 'gggg': + return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; + case 'Y': + case 'G': + case 'g': + return parseTokenSignedNumber; + case 'YYYYYY': + case 'YYYYY': + case 'GGGGG': + case 'ggggg': + return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; + case 'S': + if (strict) { + return parseTokenOneDigit; + } + /* falls through */ + case 'SS': + if (strict) { + return parseTokenTwoDigits; + } + /* falls through */ + case 'SSS': + if (strict) { + return parseTokenThreeDigits; + } + /* falls through */ + case 'DDD': + return parseTokenOneToThreeDigits; + case 'MMM': + case 'MMMM': + case 'dd': + case 'ddd': + case 'dddd': + return parseTokenWord; + case 'a': + case 'A': + return config._locale._meridiemParse; + case 'X': + return parseTokenTimestampMs; + case 'Z': + case 'ZZ': + return parseTokenTimezone; + case 'T': + return parseTokenT; + case 'SSSS': + return parseTokenDigits; + case 'MM': + case 'DD': + case 'YY': + case 'GG': + case 'gg': + case 'HH': + case 'hh': + case 'mm': + case 'ss': + case 'ww': + case 'WW': + return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; + case 'M': + case 'D': + case 'd': + case 'H': + case 'h': + case 'm': + case 's': + case 'w': + case 'W': + case 'e': + case 'E': + return parseTokenOneOrTwoDigits; + case 'Do': + return parseTokenOrdinal; + default : + a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); + return a; + } } - } - }; - /** - * Update the values of all object in the given array according to the current - * value range of the objects in the array. - * @param {Object} obj An object containing a set of Edges or Nodes - * The objects must have a method getValue() and - * setValueRange(min, max). - * @private - */ - Network.prototype._updateValueRange = function(obj) { - var id; + function timezoneMinutesFromString(string) { + string = string || ''; + var possibleTzMatches = (string.match(parseTokenTimezone) || []), + tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], + parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], + minutes = +(parts[1] * 60) + toInt(parts[2]); - // determine the range of the objects - var valueMin = undefined; - var valueMax = undefined; - for (id in obj) { - if (obj.hasOwnProperty(id)) { - var value = obj[id].getValue(); - if (value !== undefined) { - valueMin = (valueMin === undefined) ? value : Math.min(value, valueMin); - valueMax = (valueMax === undefined) ? value : Math.max(value, valueMax); - } + return parts[0] === '+' ? -minutes : minutes; } - } - // adjust the range of all objects - if (valueMin !== undefined && valueMax !== undefined) { - for (id in obj) { - if (obj.hasOwnProperty(id)) { - obj[id].setValueRange(valueMin, valueMax); - } + // function to convert string input to date + function addTimeToArrayFromToken(token, input, config) { + var a, datePartArray = config._a; + + switch (token) { + // QUARTER + case 'Q': + if (input != null) { + datePartArray[MONTH] = (toInt(input) - 1) * 3; + } + break; + // MONTH + case 'M' : // fall through to MM + case 'MM' : + if (input != null) { + datePartArray[MONTH] = toInt(input) - 1; + } + break; + case 'MMM' : // fall through to MMMM + case 'MMMM' : + a = config._locale.monthsParse(input); + // if we didn't find a month name, mark the date as invalid. + if (a != null) { + datePartArray[MONTH] = a; + } else { + config._pf.invalidMonth = input; + } + break; + // DAY OF MONTH + case 'D' : // fall through to DD + case 'DD' : + if (input != null) { + datePartArray[DATE] = toInt(input); + } + break; + case 'Do' : + if (input != null) { + datePartArray[DATE] = toInt(parseInt(input, 10)); + } + break; + // DAY OF YEAR + case 'DDD' : // fall through to DDDD + case 'DDDD' : + if (input != null) { + config._dayOfYear = toInt(input); + } + + break; + // YEAR + case 'YY' : + datePartArray[YEAR] = moment.parseTwoDigitYear(input); + break; + case 'YYYY' : + case 'YYYYY' : + case 'YYYYYY' : + datePartArray[YEAR] = toInt(input); + break; + // AM / PM + case 'a' : // fall through to A + case 'A' : + config._isPm = config._locale.isPM(input); + break; + // 24 HOUR + case 'H' : // fall through to hh + case 'HH' : // fall through to hh + case 'h' : // fall through to hh + case 'hh' : + datePartArray[HOUR] = toInt(input); + break; + // MINUTE + case 'm' : // fall through to mm + case 'mm' : + datePartArray[MINUTE] = toInt(input); + break; + // SECOND + case 's' : // fall through to ss + case 'ss' : + datePartArray[SECOND] = toInt(input); + break; + // MILLISECOND + case 'S' : + case 'SS' : + case 'SSS' : + case 'SSSS' : + datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); + break; + // UNIX TIMESTAMP WITH MS + case 'X': + config._d = new Date(parseFloat(input) * 1000); + break; + // TIMEZONE + case 'Z' : // fall through to ZZ + case 'ZZ' : + config._useUTC = true; + config._tzm = timezoneMinutesFromString(input); + break; + // WEEKDAY - human + case 'dd': + case 'ddd': + case 'dddd': + a = config._locale.weekdaysParse(input); + // if we didn't get a weekday name, mark the date as invalid + if (a != null) { + config._w = config._w || {}; + config._w['d'] = a; + } else { + config._pf.invalidWeekday = input; + } + break; + // WEEK, WEEK DAY - numeric + case 'w': + case 'ww': + case 'W': + case 'WW': + case 'd': + case 'e': + case 'E': + token = token.substr(0, 1); + /* falls through */ + case 'gggg': + case 'GGGG': + case 'GGGGG': + token = token.substr(0, 2); + if (input) { + config._w = config._w || {}; + config._w[token] = toInt(input); + } + break; + case 'gg': + case 'GG': + config._w = config._w || {}; + config._w[token] = moment.parseTwoDigitYear(input); + } } - } - }; - - /** - * Redraw the network with the current data - * chart will be resized too. - */ - Network.prototype.redraw = function() { - this.setSize(this.constants.width, this.constants.height); - this._redraw(); - }; - - /** - * Redraw the network with the current data - * @private - */ - Network.prototype._redraw = function() { - var ctx = this.frame.canvas.getContext('2d'); - // clear the canvas - var w = this.frame.canvas.width; - var h = this.frame.canvas.height; - ctx.clearRect(0, 0, w, h); - - // set scaling and translation - ctx.save(); - ctx.translate(this.translation.x, this.translation.y); - ctx.scale(this.scale, this.scale); - - this.canvasTopLeft = { - "x": this._XconvertDOMtoCanvas(0), - "y": this._YconvertDOMtoCanvas(0) - }; - this.canvasBottomRight = { - "x": this._XconvertDOMtoCanvas(this.frame.canvas.clientWidth), - "y": this._YconvertDOMtoCanvas(this.frame.canvas.clientHeight) - }; - - - this._doInAllSectors("_drawAllSectorNodes",ctx); - if (this.drag.dragging == false || this.drag.dragging === undefined || this.constants.hideEdgesOnDrag == false) { - this._doInAllSectors("_drawEdges",ctx); - } - - if (this.drag.dragging == false || this.drag.dragging === undefined || this.constants.hideNodesOnDrag == false) { - this._doInAllSectors("_drawNodes",ctx,false); - } - - if (this.controlNodesActive == true) { - this._doInAllSectors("_drawControlNodes",ctx); - } - - // this._doInSupportSector("_drawNodes",ctx,true); - // this._drawTree(ctx,"#F00F0F"); - - // restore original scaling and translation - ctx.restore(); - }; - - /** - * Set the translation of the network - * @param {Number} offsetX Horizontal offset - * @param {Number} offsetY Vertical offset - * @private - */ - Network.prototype._setTranslation = function(offsetX, offsetY) { - if (this.translation === undefined) { - this.translation = { - x: 0, - y: 0 - }; - } - - if (offsetX !== undefined) { - this.translation.x = offsetX; - } - if (offsetY !== undefined) { - this.translation.y = offsetY; - } - this.emit('viewChanged'); - }; + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp; - /** - * Get the translation of the network - * @return {Object} translation An object with parameters x and y, both a number - * @private - */ - Network.prototype._getTranslation = function() { - return { - x: this.translation.x, - y: this.translation.y - }; - }; + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; - /** - * Scale the network - * @param {Number} scale Scaling factor 1.0 is unscaled - * @private - */ - Network.prototype._setScale = function(scale) { - this.scale = scale; - }; + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); + week = dfl(w.W, 1); + weekday = dfl(w.E, 1); + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; - /** - * Get the current scale of the network - * @return {Number} scale Scaling factor 1.0 is unscaled - * @private - */ - Network.prototype._getScale = function() { - return this.scale; - }; + weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); + week = dfl(w.w, 1); - /** - * Convert the X coordinate in DOM-space (coordinate point in browser relative to the container div) to - * the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon) - * @param {number} x - * @returns {number} - * @private - */ - Network.prototype._XconvertDOMtoCanvas = function(x) { - return (x - this.translation.x) / this.scale; - }; + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < dow) { + ++week; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + } else { + // default to begining of week + weekday = dow; + } + } + temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); - /** - * Convert the X coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to - * the X coordinate in DOM-space (coordinate point in browser relative to the container div) - * @param {number} x - * @returns {number} - * @private - */ - Network.prototype._XconvertCanvasToDOM = function(x) { - return x * this.scale + this.translation.x; - }; + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } - /** - * Convert the Y coordinate in DOM-space (coordinate point in browser relative to the container div) to - * the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon) - * @param {number} y - * @returns {number} - * @private - */ - Network.prototype._YconvertDOMtoCanvas = function(y) { - return (y - this.translation.y) / this.scale; - }; + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function dateFromConfig(config) { + var i, date, input = [], currentDate, yearToUse; - /** - * Convert the Y coordinate in canvas-space (the simulation sandbox, which the camera looks upon) to - * the Y coordinate in DOM-space (coordinate point in browser relative to the container div) - * @param {number} y - * @returns {number} - * @private - */ - Network.prototype._YconvertCanvasToDOM = function(y) { - return y * this.scale + this.translation.y ; - }; + if (config._d) { + return; + } + currentDate = currentDateArray(config); - /** - * - * @param {object} pos = {x: number, y: number} - * @returns {{x: number, y: number}} - * @constructor - */ - Network.prototype.canvasToDOM = function (pos) { - return {x: this._XconvertCanvasToDOM(pos.x), y: this._YconvertCanvasToDOM(pos.y)}; - }; + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } - /** - * - * @param {object} pos = {x: number, y: number} - * @returns {{x: number, y: number}} - * @constructor - */ - Network.prototype.DOMtoCanvas = function (pos) { - return {x: this._XconvertDOMtoCanvas(pos.x), y: this._YconvertDOMtoCanvas(pos.y)}; - }; + //if the day of the year is set, figure out what it is + if (config._dayOfYear) { + yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); - /** - * Redraw all nodes - * The 2d context of a HTML canvas can be retrieved by canvas.getContext('2d'); - * @param {CanvasRenderingContext2D} ctx - * @param {Boolean} [alwaysShow] - * @private - */ - Network.prototype._drawNodes = function(ctx,alwaysShow) { - if (alwaysShow === undefined) { - alwaysShow = false; - } + if (config._dayOfYear > daysInYear(yearToUse)) { + config._pf._overflowDayOfYear = true; + } - // first draw the unselected nodes - var nodes = this.nodes; - var selected = []; + date = makeUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } - for (var id in nodes) { - if (nodes.hasOwnProperty(id)) { - nodes[id].setScaleAndPos(this.scale,this.canvasTopLeft,this.canvasBottomRight); - if (nodes[id].isSelected()) { - selected.push(id); - } - else { - if (nodes[id].inArea() || alwaysShow) { - nodes[id].draw(ctx); + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; } - } - } - } - // draw the selected nodes on top - for (var s = 0, sMax = selected.length; s < sMax; s++) { - if (nodes[selected[s]].inArea() || alwaysShow) { - nodes[selected[s]].draw(ctx); - } - } - }; + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } - /** - * Redraw all edges - * The 2d context of a HTML canvas can be retrieved by canvas.getContext('2d'); - * @param {CanvasRenderingContext2D} ctx - * @private - */ - Network.prototype._drawEdges = function(ctx) { - var edges = this.edges; - for (var id in edges) { - if (edges.hasOwnProperty(id)) { - var edge = edges[id]; - edge.setScale(this.scale); - if (edge.connected) { - edges[id].draw(ctx); - } + config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); + // Apply timezone offset from input. The actual zone can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); + } } - } - }; - /** - * Redraw all edges - * The 2d context of a HTML canvas can be retrieved by canvas.getContext('2d'); - * @param {CanvasRenderingContext2D} ctx - * @private - */ - Network.prototype._drawControlNodes = function(ctx) { - var edges = this.edges; - for (var id in edges) { - if (edges.hasOwnProperty(id)) { - edges[id]._drawControlNodes(ctx); - } - } - }; + function dateFromObject(config) { + var normalizedInput; - /** - * Find a stable position for all nodes - * @private - */ - Network.prototype._stabilize = function() { - if (this.constants.freezeForStabilization == true) { - this._freezeDefinedNodes(); - } + if (config._d) { + return; + } - // find stable position - var count = 0; - while (this.moving && count < this.constants.stabilizationIterations) { - this._physicsTick(); - count++; - } - this.zoomExtent(undefined,false,true); - if (this.constants.freezeForStabilization == true) { - this._restoreFrozenNodes(); - } - }; + normalizedInput = normalizeObjectUnits(config._i); + config._a = [ + normalizedInput.year, + normalizedInput.month, + normalizedInput.day, + normalizedInput.hour, + normalizedInput.minute, + normalizedInput.second, + normalizedInput.millisecond + ]; - /** - * When initializing and stabilizing, we can freeze nodes with a predefined position. This greatly speeds up stabilization - * because only the supportnodes for the smoothCurves have to settle. - * - * @private - */ - Network.prototype._freezeDefinedNodes = function() { - var nodes = this.nodes; - for (var id in nodes) { - if (nodes.hasOwnProperty(id)) { - if (nodes[id].x != null && nodes[id].y != null) { - nodes[id].fixedData.x = nodes[id].xFixed; - nodes[id].fixedData.y = nodes[id].yFixed; - nodes[id].xFixed = true; - nodes[id].yFixed = true; - } + dateFromConfig(config); } - } - }; - /** - * Unfreezes the nodes that have been frozen by _freezeDefinedNodes. - * - * @private - */ - Network.prototype._restoreFrozenNodes = function() { - var nodes = this.nodes; - for (var id in nodes) { - if (nodes.hasOwnProperty(id)) { - if (nodes[id].fixedData.x != null) { - nodes[id].xFixed = nodes[id].fixedData.x; - nodes[id].yFixed = nodes[id].fixedData.y; - } + function currentDateArray(config) { + var now = new Date(); + if (config._useUTC) { + return [ + now.getUTCFullYear(), + now.getUTCMonth(), + now.getUTCDate() + ]; + } else { + return [now.getFullYear(), now.getMonth(), now.getDate()]; + } } - } - }; - - /** - * Check if any of the nodes is still moving - * @param {number} vmin the minimum velocity considered as 'moving' - * @return {boolean} true if moving, false if non of the nodes is moving - * @private - */ - Network.prototype._isMoving = function(vmin) { - var nodes = this.nodes; - for (var id in nodes) { - if (nodes.hasOwnProperty(id) && nodes[id].isMoving(vmin)) { - return true; - } - } - return false; - }; + // date from string and format string + function makeDateFromStringAndFormat(config) { + if (config._f === moment.ISO_8601) { + parseISO(config); + return; + } + config._a = []; + config._pf.empty = true; - /** - * /** - * Perform one discrete step for all nodes - * - * @private - */ - Network.prototype._discreteStepNodes = function() { - var interval = this.physicsDiscreteStepsize; - var nodes = this.nodes; - var nodeId; - var nodesPresent = false; + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; - if (this.constants.maxVelocity > 0) { - for (nodeId in nodes) { - if (nodes.hasOwnProperty(nodeId)) { - nodes[nodeId].discreteStepLimited(interval, this.constants.maxVelocity); - nodesPresent = true; - } - } - } - else { - for (nodeId in nodes) { - if (nodes.hasOwnProperty(nodeId)) { - nodes[nodeId].discreteStep(interval); - nodesPresent = true; - } - } - } + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - if (nodesPresent == true) { - var vminCorrected = this.constants.minVelocity / Math.max(this.scale,0.05); - if (vminCorrected > 0.5*this.constants.maxVelocity) { - return true; - } - else { - return this._isMoving(vminCorrected); - } - } - return false; - }; + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + config._pf.unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + config._pf.empty = false; + } + else { + config._pf.unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + config._pf.unusedTokens.push(token); + } + } - /** - * A single simulation step (or "tick") in the physics simulation - * - * @private - */ - Network.prototype._physicsTick = function() { - if (!this.freezeSimulation) { - if (this.moving == true) { - var mainMovingStatus = false; - var supportMovingStatus = false; + // add remaining unparsed input length to the string + config._pf.charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + config._pf.unusedInput.push(string); + } - this._doInAllActiveSectors("_initializeForceCalculation"); - var mainMoving = this._doInAllActiveSectors("_discreteStepNodes"); - if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { - supportMovingStatus = this._doInSupportSector("_discreteStepNodes"); - } - // gather movement data from all sectors, if one moves, we are NOT stabilzied - for (var i = 0; i < mainMoving.length; i++) {mainMovingStatus = mainMoving[0] || mainMovingStatus;} + // handle am pm + if (config._isPm && config._a[HOUR] < 12) { + config._a[HOUR] += 12; + } + // if is 12 am, change hours to 0 + if (config._isPm === false && config._a[HOUR] === 12) { + config._a[HOUR] = 0; + } - // determine if the network has stabilzied - this.moving = mainMovingStatus || supportMovingStatus; + dateFromConfig(config); + checkOverflow(config); + } - this.stabilizationIterations++; + function unescapeFormat(s) { + return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + }); } - } - }; + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function regexpEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } - /** - * This function runs one step of the animation. It calls an x amount of physics ticks and one render tick. - * It reschedules itself at the beginning of the function - * - * @private - */ - Network.prototype._animationStep = function() { - // reset the timer so a new scheduled animation step can be set - this.timer = undefined; - // handle the keyboad movement - this._handleNavigation(); + // date from string and array of format strings + function makeDateFromStringAndArray(config) { + var tempConfig, + bestMoment, - // this schedules a new animation step - this.start(); + scoreToBeat, + i, + currentScore; - // start the physics simulation - var calculationTime = Date.now(); - var maxSteps = 1; - this._physicsTick(); - var timeRequired = Date.now() - calculationTime; - while (timeRequired < 0.9*(this.renderTimestep - this.renderTime) && maxSteps < this.maxPhysicsTicksPerRender) { - this._physicsTick(); - timeRequired = Date.now() - calculationTime; - maxSteps++; - } - // start the rendering process - var renderTime = Date.now(); - this._redraw(); - this.renderTime = Date.now() - renderTime; - }; + if (config._f.length === 0) { + config._pf.invalidFormat = true; + config._d = new Date(NaN); + return; + } - if (typeof window !== 'undefined') { - window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; - } + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._pf = defaultParsingFlags(); + tempConfig._f = config._f[i]; + makeDateFromStringAndFormat(tempConfig); - /** - * Schedule a animation step with the refreshrate interval. - */ - Network.prototype.start = function() { - if (this.moving == true || this.xIncrement != 0 || this.yIncrement != 0 || this.zoomIncrement != 0) { - if (this.startedStabilization == false) { - this.emit("startStabilization"); - this.startedStabilization = true; - } + if (!isValid(tempConfig)) { + continue; + } - if (!this.timer) { - var ua = navigator.userAgent.toLowerCase(); + // if there is any input that was not parsed add a penalty for that format + currentScore += tempConfig._pf.charsLeftOver; - var requiresTimeout = false; - if (ua.indexOf('msie 9.0') != -1) { // IE 9 - requiresTimeout = true; - } - else if (ua.indexOf('safari') != -1) { // safari - if (ua.indexOf('chrome') <= -1) { - requiresTimeout = true; - } - } + //or tokens + currentScore += tempConfig._pf.unusedTokens.length * 10; - if (requiresTimeout == true) { - this.timer = window.setTimeout(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function - } - else{ - this.timer = window.requestAnimationFrame(this._animationStep.bind(this), this.renderTimestep); // wait this.renderTimeStep milliseconds and perform the animation step function - } - } - } - else { - this._redraw(); - if (this.stabilizationIterations > 0) { - // trigger the "stabilized" event. - // The event is triggered on the next tick, to prevent the case that - // it is fired while initializing the Network, in which case you would not - // be able to catch it - var me = this; - var params = { - iterations: me.stabilizationIterations - }; - me.stabilizationIterations = 0; - me.startedStabilization = false; - setTimeout(function () { - me.emit("stabilized", params); - }, 0); - } - } - }; + tempConfig._pf.score = currentScore; + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } - /** - * Move the network according to the keyboard presses. - * - * @private - */ - Network.prototype._handleNavigation = function() { - if (this.xIncrement != 0 || this.yIncrement != 0) { - var translation = this._getTranslation(); - this._setTranslation(translation.x+this.xIncrement, translation.y+this.yIncrement); - } - if (this.zoomIncrement != 0) { - var center = { - x: this.frame.canvas.clientWidth / 2, - y: this.frame.canvas.clientHeight / 2 - }; - this._zoom(this.scale*(1 + this.zoomIncrement), center); - } - }; + extend(config, bestMoment || tempConfig); + } + // date from iso format + function parseISO(config) { + var i, l, + string = config._i, + match = isoRegex.exec(string); - /** - * Freeze the _animationStep - */ - Network.prototype.toggleFreeze = function() { - if (this.freezeSimulation == false) { - this.freezeSimulation = true; - } - else { - this.freezeSimulation = false; - this.start(); - } - }; + if (match) { + config._pf.iso = true; + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(string)) { + // match[5] should be 'T' or undefined + config._f = isoDates[i][0] + (match[6] || ' '); + break; + } + } + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(string)) { + config._f += isoTimes[i][0]; + break; + } + } + if (string.match(parseTokenTimezone)) { + config._f += 'Z'; + } + makeDateFromStringAndFormat(config); + } else { + config._isValid = false; + } + } + // date from iso format or fallback + function makeDateFromString(config) { + parseISO(config); + if (config._isValid === false) { + delete config._isValid; + moment.createFromInputFallback(config); + } + } - /** - * This function cleans the support nodes if they are not needed and adds them when they are. - * - * @param {boolean} [disableStart] - * @private - */ - Network.prototype._configureSmoothCurves = function(disableStart) { - if (disableStart === undefined) { - disableStart = true; - } - if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { - this._createBezierNodes(); - // cleanup unused support nodes - for (var nodeId in this.sectors['support']['nodes']) { - if (this.sectors['support']['nodes'].hasOwnProperty(nodeId)) { - if (this.edges[this.sectors['support']['nodes'][nodeId].parentEdgeId] === undefined) { - delete this.sectors['support']['nodes'][nodeId]; + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); } - } + return res; } - } - else { - // delete the support nodes - this.sectors['support']['nodes'] = {}; - for (var edgeId in this.edges) { - if (this.edges.hasOwnProperty(edgeId)) { - this.edges[edgeId].via = null; - } + + function makeDateFromInput(config) { + var input = config._i, matched; + if (input === undefined) { + config._d = new Date(); + } else if (isDate(input)) { + config._d = new Date(+input); + } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { + config._d = new Date(+matched[1]); + } else if (typeof input === 'string') { + makeDateFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + dateFromConfig(config); + } else if (typeof(input) === 'object') { + dateFromObject(config); + } else if (typeof(input) === 'number') { + // from milliseconds + config._d = new Date(input); + } else { + moment.createFromInputFallback(config); + } } - } + function makeDate(y, m, d, h, M, s, ms) { + //can't just apply() to create a date: + //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply + var date = new Date(y, m, d, h, M, s, ms); - this._updateCalculationNodes(); - if (!disableStart) { - this.moving = true; - this.start(); - } - }; + //the date constructor doesn't accept years < 1970 + if (y < 1970) { + date.setFullYear(y); + } + return date; + } + function makeUTCDate(y) { + var date = new Date(Date.UTC.apply(null, arguments)); + if (y < 1970) { + date.setUTCFullYear(y); + } + return date; + } - /** - * Bezier curves require an anchor point to calculate the smooth flow. These points are nodes. These nodes are invisible but - * are used for the force calculation. - * - * @private - */ - Network.prototype._createBezierNodes = function() { - if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { - for (var edgeId in this.edges) { - if (this.edges.hasOwnProperty(edgeId)) { - var edge = this.edges[edgeId]; - if (edge.via == null) { - var nodeId = "edgeId:".concat(edge.id); - this.sectors['support']['nodes'][nodeId] = new Node( - {id:nodeId, - mass:1, - shape:'circle', - image:"", - internalMultiplier:1 - },{},{},this.constants); - edge.via = this.sectors['support']['nodes'][nodeId]; - edge.via.parentEdgeId = edge.id; - edge.positionBezierNode(); + function parseWeekday(input, locale) { + if (typeof input === 'string') { + if (!isNaN(input)) { + input = parseInt(input, 10); + } + else { + input = locale.weekdaysParse(input); + if (typeof input !== 'number') { + return null; + } + } } - } + return input; } - } - }; - /** - * load the functions that load the mixins into the prototype. - * - * @private - */ - Network.prototype._initializeMixinLoaders = function () { - for (var mixin in MixinLoader) { - if (MixinLoader.hasOwnProperty(mixin)) { - Network.prototype[mixin] = MixinLoader[mixin]; + /************************************ + Relative Time + ************************************/ + + + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } - } - }; - /** - * Load the XY positions of the nodes into the dataset. - */ - Network.prototype.storePosition = function() { - console.log("storePosition is depricated: use .storePositions() from now on.") - this.storePositions(); - }; + function relativeTime(posNegDuration, withoutSuffix, locale) { + var duration = moment.duration(posNegDuration).abs(), + seconds = round(duration.as('s')), + minutes = round(duration.as('m')), + hours = round(duration.as('h')), + days = round(duration.as('d')), + months = round(duration.as('M')), + years = round(duration.as('y')), - /** - * Load the XY positions of the nodes into the dataset. - */ - Network.prototype.storePositions = function() { - var dataArray = []; - for (var nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - var node = this.nodes[nodeId]; - var allowedToMoveX = !this.nodes.xFixed; - var allowedToMoveY = !this.nodes.yFixed; - if (this.nodesData._data[nodeId].x != Math.round(node.x) || this.nodesData._data[nodeId].y != Math.round(node.y)) { - dataArray.push({id:nodeId,x:Math.round(node.x),y:Math.round(node.y),allowedToMoveX:allowedToMoveX,allowedToMoveY:allowedToMoveY}); - } + args = seconds < relativeTimeThresholds.s && ['s', seconds] || + minutes === 1 && ['m'] || + minutes < relativeTimeThresholds.m && ['mm', minutes] || + hours === 1 && ['h'] || + hours < relativeTimeThresholds.h && ['hh', hours] || + days === 1 && ['d'] || + days < relativeTimeThresholds.d && ['dd', days] || + months === 1 && ['M'] || + months < relativeTimeThresholds.M && ['MM', months] || + years === 1 && ['y'] || ['yy', years]; + + args[2] = withoutSuffix; + args[3] = +posNegDuration > 0; + args[4] = locale; + return substituteTimeAgo.apply({}, args); } - } - this.nodesData.update(dataArray); - }; - /** - * Return the positions of the nodes. - */ - Network.prototype.getPositions = function(ids) { - var dataArray = {}; - if (ids !== undefined) { - if (Array.isArray(ids) == true) { - for (var i = 0; i < ids.length; i++) { - if (this.nodes[ids[i]] !== undefined) { - var node = this.nodes[ids[i]]; - dataArray[ids[i]] = {x: Math.round(node.x), y: Math.round(node.y)}; + + /************************************ + Week of Year + ************************************/ + + + // firstDayOfWeek 0 = sun, 6 = sat + // the day of the week that starts the week + // (usually sunday or monday) + // firstDayOfWeekOfYear 0 = sun, 6 = sat + // the first week is the week that contains the first + // of this day of the week + // (eg. ISO weeks use thursday (4)) + function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { + var end = firstDayOfWeekOfYear - firstDayOfWeek, + daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), + adjustedMoment; + + + if (daysToDayOfWeek > end) { + daysToDayOfWeek -= 7; } - } - } - else { - if (this.nodes[ids] !== undefined) { - var node = this.nodes[ids]; - dataArray[ids] = {x: Math.round(node.x), y: Math.round(node.y)}; - } - } - } - else { - for (var nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - var node = this.nodes[nodeId]; - dataArray[nodeId] = {x: Math.round(node.x), y: Math.round(node.y)}; - } + + if (daysToDayOfWeek < end - 7) { + daysToDayOfWeek += 7; + } + + adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); + return { + week: Math.ceil(adjustedMoment.dayOfYear() / 7), + year: adjustedMoment.year() + }; } - } - return dataArray; - }; + //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { + var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; + d = d === 0 ? 7 : d; + weekday = weekday != null ? weekday : firstDayOfWeek; + daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); + dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; - /** - * Center a node in view. - * - * @param {Number} nodeId - * @param {Number} [options] - */ - Network.prototype.focusOnNode = function (nodeId, options) { - if (this.nodes.hasOwnProperty(nodeId)) { - if (options === undefined) { - options = {}; + return { + year: dayOfYear > 0 ? year : year - 1, + dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear + }; } - var nodePosition = {x: this.nodes[nodeId].x, y: this.nodes[nodeId].y}; - options.position = nodePosition; - options.lockedOnNode = nodeId; - this.moveTo(options) - } - else { - console.log("This nodeId cannot be found."); - } - }; + /************************************ + Top Level Functions + ************************************/ - /** - * - * @param {Object} options | options.offset = {x:Number, y:Number} // offset from the center in DOM pixels - * | options.scale = Number // scale to move to - * | options.position = {x:Number, y:Number} // position to move to - * | options.animation = {duration:Number, easingFunction:String} || Boolean // position to move to - */ - Network.prototype.moveTo = function (options) { - if (options === undefined) { - options = {}; - return; - } - if (options.offset === undefined) {options.offset = {x: 0, y: 0}; } - if (options.offset.x === undefined) {options.offset.x = 0; } - if (options.offset.y === undefined) {options.offset.y = 0; } - if (options.scale === undefined) {options.scale = this._getScale(); } - if (options.position === undefined) {options.position = this._getTranslation();} - if (options.animation === undefined) {options.animation = {duration:0}; } - if (options.animation === false ) {options.animation = {duration:0}; } - if (options.animation === true ) {options.animation = {}; } - if (options.animation.duration === undefined) {options.animation.duration = 1000; } // default duration - if (options.animation.easingFunction === undefined) {options.animation.easingFunction = "easeInOutQuad"; } // default easing function + function makeMoment(config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || moment.localeData(config._l); + + if (input === null || (format === undefined && input === '')) { + return moment.invalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (moment.isMoment(input)) { + return new Moment(input, true); + } else if (format) { + if (isArray(format)) { + makeDateFromStringAndArray(config); + } else { + makeDateFromStringAndFormat(config); + } + } else { + makeDateFromInput(config); + } - this.animateView(options); - }; + return new Moment(config); + } - /** - * - * @param {Object} options | options.offset = {x:Number, y:Number} // offset from the center in DOM pixels - * | options.time = Number // animation time in milliseconds - * | options.scale = Number // scale to animate to - * | options.position = {x:Number, y:Number} // position to animate to - * | options.easingFunction = String // linear, easeInQuad, easeOutQuad, easeInOutQuad, - * // easeInCubic, easeOutCubic, easeInOutCubic, - * // easeInQuart, easeOutQuart, easeInOutQuart, - * // easeInQuint, easeOutQuint, easeInOutQuint - */ - Network.prototype.animateView = function (options) { - if (options === undefined) { - options = {}; - return; - } + moment = function (input, format, locale, strict) { + var c; - // release if something focussed on the node - this.releaseNode(); - if (options.locked == true) { - this.lockedOnNodeId = options.lockedOnNode; - this.lockedOnNodeOffset = options.offset; - } + if (typeof(locale) === 'boolean') { + strict = locale; + locale = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c = {}; + c._isAMomentObject = true; + c._i = input; + c._f = format; + c._l = locale; + c._strict = strict; + c._isUTC = false; + c._pf = defaultParsingFlags(); - // forcefully complete the old animation if it was still running - if (this.easingTime != 0) { - this._transitionRedraw(1); // by setting easingtime to 1, we finish the animation. - } + return makeMoment(c); + }; - this.sourceScale = this._getScale(); - this.sourceTranslation = this._getTranslation(); - this.targetScale = options.scale; + moment.suppressDeprecationWarnings = false; - // set the scale so the viewCenter is based on the correct zoom level. This is overridden in the transitionRedraw - // but at least then we'll have the target transition - this._setScale(this.targetScale); - var viewCenter = this.DOMtoCanvas({x: 0.5 * this.frame.canvas.clientWidth, y: 0.5 * this.frame.canvas.clientHeight}); - var distanceFromCenter = { // offset from view, distance view has to change by these x and y to center the node - x: viewCenter.x - options.position.x, - y: viewCenter.y - options.position.y - }; - this.targetTranslation = { - x: this.sourceTranslation.x + distanceFromCenter.x * this.targetScale + options.offset.x, - y: this.sourceTranslation.y + distanceFromCenter.y * this.targetScale + options.offset.y - }; + moment.createFromInputFallback = deprecate( + 'moment construction falls back to js Date. This is ' + + 'discouraged and will be removed in upcoming major ' + + 'release. Please refer to ' + + 'https://github.com/moment/moment/issues/1407 for more info.', + function (config) { + config._d = new Date(config._i); + } + ); - // if the time is set to 0, don't do an animation - if (options.animation.duration == 0) { - if (this.lockedOnNodeId != null) { - this._classicRedraw = this._redraw; - this._redraw = this._lockedRedraw; - } - else { - this._setScale(this.targetScale); - this._setTranslation(this.targetTranslation.x, this.targetTranslation.y); - this._redraw(); + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return moment(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (moments[i][fn](res)) { + res = moments[i]; + } + } + return res; } - } - else { - this.animationSpeed = 1 / (this.renderRefreshRate * options.animation.duration * 0.001) || 1 / this.renderRefreshRate; - this.animationEasingFunction = options.animation.easingFunction; - this._classicRedraw = this._redraw; - this._redraw = this._transitionRedraw; - this._redraw(); - this.moving = true; - this.start(); - } - }; + moment.min = function () { + var args = [].slice.call(arguments, 0); - Network.prototype._lockedRedraw = function () { - var nodePosition = {x: this.nodes[this.lockedOnNodeId].x, y: this.nodes[this.lockedOnNodeId].y}; - var viewCenter = this.DOMtoCanvas({x: 0.5 * this.frame.canvas.clientWidth, y: 0.5 * this.frame.canvas.clientHeight}); - var distanceFromCenter = { // offset from view, distance view has to change by these x and y to center the node - x: viewCenter.x - nodePosition.x, - y: viewCenter.y - nodePosition.y - }; - var sourceTranslation = this._getTranslation(); - var targetTranslation = { - x: sourceTranslation.x + distanceFromCenter.x * this.scale + this.lockedOnNodeOffset.x, - y: sourceTranslation.y + distanceFromCenter.y * this.scale + this.lockedOnNodeOffset.y - }; + return pickBy('isBefore', args); + }; - this._setTranslation(targetTranslation.x,targetTranslation.y); - this._classicRedraw(); - } + moment.max = function () { + var args = [].slice.call(arguments, 0); - Network.prototype.releaseNode = function () { - if (this.lockedOnNodeId != null) { - this._redraw = this._classicRedraw; - this.lockedOnNodeId = null; - this.lockedOnNodeOffset = null; - } - } + return pickBy('isAfter', args); + }; - /** - * - * @param easingTime - * @private - */ - Network.prototype._transitionRedraw = function (easingTime) { - this.easingTime = easingTime || this.easingTime + this.animationSpeed; - this.easingTime += this.animationSpeed; + // creating with utc + moment.utc = function (input, format, locale, strict) { + var c; - var progress = util.easingFunctions[this.animationEasingFunction](this.easingTime); + if (typeof(locale) === 'boolean') { + strict = locale; + locale = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c = {}; + c._isAMomentObject = true; + c._useUTC = true; + c._isUTC = true; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + c._pf = defaultParsingFlags(); - this._setScale(this.sourceScale + (this.targetScale - this.sourceScale) * progress); - this._setTranslation( - this.sourceTranslation.x + (this.targetTranslation.x - this.sourceTranslation.x) * progress, - this.sourceTranslation.y + (this.targetTranslation.y - this.sourceTranslation.y) * progress - ); + return makeMoment(c).utc(); + }; - this._classicRedraw(); - this.moving = true; + // creating with unix timestamp (in seconds) + moment.unix = function (input) { + return moment(input * 1000); + }; - // cleanup - if (this.easingTime >= 1.0) { - this.easingTime = 0; - if (this.lockedOnNodeId != null) { - this._redraw = this._lockedRedraw; - } - else { - this._redraw = this._classicRedraw; - } - this.emit("animationFinished"); - } - }; + // duration + moment.duration = function (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + parseIso, + diffRes; - Network.prototype._classicRedraw = function () { - // placeholder function to be overloaded by animations; - }; + if (moment.isDuration(input)) { + duration = { + ms: input._milliseconds, + d: input._days, + M: input._months + }; + } else if (typeof input === 'number') { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y: 0, + d: toInt(match[DATE]) * sign, + h: toInt(match[HOUR]) * sign, + m: toInt(match[MINUTE]) * sign, + s: toInt(match[SECOND]) * sign, + ms: toInt(match[MILLISECOND]) * sign + }; + } else if (!!(match = isoDurationRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + parseIso = function (inp) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + }; + duration = { + y: parseIso(match[2]), + M: parseIso(match[3]), + d: parseIso(match[4]), + h: parseIso(match[5]), + m: parseIso(match[6]), + s: parseIso(match[7]), + w: parseIso(match[8]) + }; + } else if (typeof duration === 'object' && + ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(moment(duration.from), moment(duration.to)); - /** - * Returns true when the Network is active. - * @returns {boolean} - */ - Network.prototype.isActive = function () { - return !this.activator || this.activator.active; - }; + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + ret = new Duration(duration); - /** - * Sets the scale - * @returns {Number} - */ - Network.prototype.setScale = function () { - return this._setScale(); - }; + if (moment.isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + return ret; + }; - /** - * Returns the scale - * @returns {Number} - */ - Network.prototype.getScale = function () { - return this._getScale(); - }; + // version number + moment.version = VERSION; + // default format + moment.defaultFormat = isoFormat; - /** - * Returns the scale - * @returns {Number} - */ - Network.prototype.getCenterCoordinates = function () { - return this.DOMtoCanvas({x: 0.5 * this.frame.canvas.clientWidth, y: 0.5 * this.frame.canvas.clientHeight}); - }; + // constant that refers to the ISO standard + moment.ISO_8601 = function () {}; - module.exports = Network; + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + moment.momentProperties = momentProperties; + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + moment.updateOffset = function () {}; -/***/ }, -/* 48 */ -/***/ function(module, exports, __webpack_require__) { + // This function allows you to set a threshold for relative time strings + moment.relativeTimeThreshold = function (threshold, limit) { + if (relativeTimeThresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return relativeTimeThresholds[threshold]; + } + relativeTimeThresholds[threshold] = limit; + return true; + }; - /** - * 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(); - } + moment.lang = deprecate( + 'moment.lang is deprecated. Use moment.locale instead.', + function (key, value) { + return moment.locale(key, value); + } + ); - // token types enumeration - var TOKENTYPE = { - NULL : 0, - DELIMITER : 1, - IDENTIFIER: 2, - UNKNOWN : 3 - }; + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + moment.locale = function (key, values) { + var data; + if (key) { + if (typeof(values) !== 'undefined') { + data = moment.defineLocale(key, values); + } + else { + data = moment.localeData(key); + } - // map with all delimiters - var DELIMITERS = { - '{': true, - '}': true, - '[': true, - ']': true, - ';': true, - '=': true, - ',': true, + if (data) { + moment.duration._locale = moment._locale = data; + } + } - '->': true, - '--': true - }; + return moment._locale._abbr; + }; - 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 + moment.defineLocale = function (name, values) { + if (values !== null) { + values.abbr = name; + if (!locales[name]) { + locales[name] = new Locale(); + } + locales[name].set(values); - /** - * 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); - } + // backwards compat for now: also set the locale + moment.locale(name); - /** - * 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); - } + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + }; - /** - * Preview the next character from the dot file. - * @return {String} cNext - */ - function nextPreview() { - return dot.charAt(index + 1); - } + moment.langData = deprecate( + 'moment.langData is deprecated. Use moment.localeData instead.', + function (key) { + return moment.localeData(key); + } + ); - /** - * 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); - } + // returns locale data + moment.localeData = function (key) { + var locale; - /** - * 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 = {}; - } + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } - if (b) { - for (var name in b) { - if (b.hasOwnProperty(name)) { - a[name] = b[name]; - } - } - } - return a; - } + if (!key) { + return moment._locale; + } - /** - * 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; - } - } - } + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } - /** - * 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; + return chooseLocale(key); + }; - // 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; - } + // compare moment object + moment.isMoment = function (obj) { + return obj instanceof Moment || + (obj != null && hasOwnProp(obj, '_isAMomentObject')); + }; - // 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; - } + // for typechecking Duration objects + moment.isDuration = function (obj) { + return obj instanceof Duration; + }; + + for (i = lists.length - 1; i >= 0; --i) { + makeList(lists[i]); } - } - if (!current) { - // this is a new node - current = { - id: node.id + moment.normalizeUnits = function (units) { + return normalizeUnits(units); }; - if (graph.node) { - // clone default attributes - current.attr = merge(current.attr, graph.node); - } - } - // add node to this (sub)graph and all its parent graphs - for (i = graphs.length - 1; i >= 0; i--) { - var g = graphs[i]; + moment.invalid = function (flags) { + var m = moment.utc(NaN); + if (flags != null) { + extend(m._pf, flags); + } + else { + m._pf.userInvalidated = true; + } - if (!g.nodes) { - g.nodes = []; - } - if (g.nodes.indexOf(current) == -1) { - g.nodes.push(current); - } - } + return m; + }; - // merge attributes - if (node.attr) { - current.attr = merge(current.attr, node.attr); - } - } + moment.parseZone = function () { + return moment.apply(null, arguments).parseZone(); + }; - /** - * 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 - } - } + moment.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; - /** - * 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 - }; + /************************************ + Moment Prototype + ************************************/ - if (graph.edge) { - edge.attr = merge({}, graph.edge); // clone default attributes - } - edge.attr = merge(edge.attr || {}, attr); // merge attributes - return edge; - } + extend(moment.fn = Moment.prototype, { - /** - * 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 = ''; + clone : function () { + return moment(this); + }, - // skip over whitespaces - while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter - next(); - } + valueOf : function () { + return +this._d + ((this._offset || 0) * 60000); + }, - do { - var isComment = false; + unix : function () { + return Math.floor(+this / 1000); + }, - // 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; - } + toString : function () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + }, - // skip over whitespaces - while (c == ' ' || c == '\t' || c == '\n' || c == '\r') { // space, tab, enter - next(); - } - } - while (isComment); + toDate : function () { + return this._offset ? new Date(+this) : this._d; + }, - // check for end of dot file - if (c == '') { - // token is still empty - tokenType = TOKENTYPE.DELIMITER; - return; - } + toISOString : function () { + var m = moment(this).utc(); + if (0 < m.year() && m.year() <= 9999) { + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } else { + return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } + }, - // check for delimiters consisting of 2 characters - var c2 = c + nextPreview(); - if (DELIMITERS[c2]) { - tokenType = TOKENTYPE.DELIMITER; - token = c2; - next(); - next(); - return; - } + toArray : function () { + var m = this; + return [ + m.year(), + m.month(), + m.date(), + m.hours(), + m.minutes(), + m.seconds(), + m.milliseconds() + ]; + }, - // check for delimiters consisting of 1 character - if (DELIMITERS[c]) { - tokenType = TOKENTYPE.DELIMITER; - token = c; - next(); - return; - } + isValid : function () { + return isValid(this); + }, - // 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(); + isDSTShifted : function () { + if (this._a) { + return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; + } - 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; - } + return false; + }, - // 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; - } + parsingFlags : function () { + return extend({}, this._pf); + }, - // 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) + '"'); - } + invalidAt: function () { + return this._pf.overflow; + }, - /** - * Parse a graph. - * @returns {Object} graph - */ - function parseGraph() { - var graph = {}; + utc : function (keepLocalTime) { + return this.zone(0, keepLocalTime); + }, - first(); - getToken(); + local : function (keepLocalTime) { + if (this._isUTC) { + this.zone(0, keepLocalTime); + this._isUTC = false; - // optional strict keyword - if (token == 'strict') { - graph.strict = true; - getToken(); - } + if (keepLocalTime) { + this.add(this._dateTzOffset(), 'm'); + } + } + return this; + }, - // graph or digraph keyword - if (token == 'graph' || token == 'digraph') { - graph.type = token; - getToken(); - } + format : function (inputString) { + var output = formatMoment(this, inputString || moment.defaultFormat); + return this.localeData().postformat(output); + }, - // optional graph id - if (tokenType == TOKENTYPE.IDENTIFIER) { - graph.id = token; - getToken(); - } + add : createAdder(1, 'add'), - // open angle bracket - if (token != '{') { - throw newSyntaxError('Angle bracket { expected'); - } - getToken(); + subtract : createAdder(-1, 'subtract'), - // statements - parseStatements(graph); + diff : function (input, units, asFloat) { + var that = makeAs(input, this), + zoneDiff = (this.zone() - that.zone()) * 6e4, + diff, output, daysAdjust; - // close angle bracket - if (token != '}') { - throw newSyntaxError('Angle bracket } expected'); - } - getToken(); + units = normalizeUnits(units); - // end of file - if (token !== '') { - throw newSyntaxError('End of file expected'); - } - getToken(); + if (units === 'year' || units === 'month') { + // average number of days in the months in the given dates + diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 + // difference in months + output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); + // adjust by taking difference in days, average number of days + // and dst in the given months. + daysAdjust = (this - moment(this).startOf('month')) - + (that - moment(that).startOf('month')); + // same as above but with zones, to negate all dst + daysAdjust -= ((this.zone() - moment(this).startOf('month').zone()) - + (that.zone() - moment(that).startOf('month').zone())) * 6e4; + output += daysAdjust / diff; + if (units === 'year') { + output = output / 12; + } + } else { + diff = (this - that); + output = units === 'second' ? diff / 1e3 : // 1000 + units === 'minute' ? diff / 6e4 : // 1000 * 60 + units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 + units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst + units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst + diff; + } + return asFloat ? output : absRound(output); + }, - // remove temporary default properties - delete graph.node; - delete graph.edge; - delete graph.graph; + from : function (time, withoutSuffix) { + return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + }, - return graph; - } + fromNow : function (withoutSuffix) { + return this.from(moment(), withoutSuffix); + }, - /** - * Parse a list with statements. - * @param {Object} graph - */ - function parseStatements (graph) { - while (token !== '' && token != '}') { - parseStatement(graph); - if (token == ';') { - getToken(); - } - } - } + calendar : function (time) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're zone'd or not. + var now = time || moment(), + sod = makeAs(now, this).startOf('day'), + diff = this.diff(sod, 'days', true), + format = diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + return this.format(this.localeData().calendar(format, this)); + }, - /** - * 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); + isLeapYear : function () { + return isLeapYear(this.year()); + }, + + isDST : function () { + return (this.zone() < this.clone().month(0).zone() || + this.zone() < this.clone().month(5).zone()); + }, + + day : function (input) { + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + }, + + month : makeAccessor('Month', true), + + startOf : function (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + /* falls through */ + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } else if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; + }, + + endOf: function (units) { + units = normalizeUnits(units); + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + }, + + isAfter: function (input, units) { + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this > +input; + } else { + return +this.clone().startOf(units) > +moment(input).startOf(units); + } + }, - return; - } + isBefore: function (input, units) { + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this < +input; + } else { + return +this.clone().startOf(units) < +moment(input).startOf(units); + } + }, - // parse an attribute statement - var attr = parseAttributeStatement(graph); - if (attr) { - return; - } + isSame: function (input, units) { + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this === +input; + } else { + return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); + } + }, - // parse node - if (tokenType != TOKENTYPE.IDENTIFIER) { - throw newSyntaxError('Identifier expected'); - } - var id = token; // id can be a string or a number - getToken(); + min: deprecate( + 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other < this ? this : other; + } + ), - 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 { - parseNodeStatement(graph, id); - } - } + max: deprecate( + 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other > this ? this : other; + } + ), - /** - * Parse a subgraph - * @param {Object} graph parent graph object - * @return {Object | null} subgraph - */ - function parseSubgraph (graph) { - var subgraph = null; + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + zone : function (input, keepLocalTime) { + var offset = this._offset || 0, + localAdjust; + if (input != null) { + if (typeof input === 'string') { + input = timezoneMinutesFromString(input); + } + if (Math.abs(input) < 16) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = this._dateTzOffset(); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.subtract(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addOrSubtractDurationFromMoment(this, + moment.duration(offset - input, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + moment.updateOffset(this, true); + this._changeInProgress = null; + } + } + } else { + return this._isUTC ? offset : this._dateTzOffset(); + } + return this; + }, - // optional subgraph keyword - if (token == 'subgraph') { - subgraph = {}; - subgraph.type = 'subgraph'; - getToken(); + zoneAbbr : function () { + return this._isUTC ? 'UTC' : ''; + }, - // optional graph id - if (tokenType == TOKENTYPE.IDENTIFIER) { - subgraph.id = token; - getToken(); - } - } + zoneName : function () { + return this._isUTC ? 'Coordinated Universal Time' : ''; + }, - // open angle bracket - if (token == '{') { - getToken(); + parseZone : function () { + if (this._tzm) { + this.zone(this._tzm); + } else if (typeof this._i === 'string') { + this.zone(this._i); + } + return this; + }, - if (!subgraph) { - subgraph = {}; - } - subgraph.parent = graph; - subgraph.node = graph.node; - subgraph.edge = graph.edge; - subgraph.graph = graph.graph; + hasAlignedHourOffset : function (input) { + if (!input) { + input = 0; + } + else { + input = moment(input).zone(); + } - // statements - parseStatements(subgraph); + return (this.zone() - input) % 60 === 0; + }, - // close angle bracket - if (token != '}') { - throw newSyntaxError('Angle bracket } expected'); - } - getToken(); + daysInMonth : function () { + return daysInMonth(this.year(), this.month()); + }, - // remove temporary default properties - delete subgraph.node; - delete subgraph.edge; - delete subgraph.graph; - delete subgraph.parent; + dayOfYear : function (input) { + var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + }, - // register at the parent graph - if (!graph.subgraphs) { - graph.subgraphs = []; - } - graph.subgraphs.push(subgraph); - } + quarter : function (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + }, - return subgraph; - } + weekYear : function (input) { + var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; + return input == null ? year : this.add((input - year), 'y'); + }, - /** - * 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. - */ - function parseAttributeStatement (graph) { - // attribute statements - if (token == 'node') { - getToken(); + isoWeekYear : function (input) { + var year = weekOfYear(this, 1, 4).year; + return input == null ? year : this.add((input - year), 'y'); + }, - // node attributes - graph.node = parseAttributeList(); - return 'node'; - } - else if (token == 'edge') { - getToken(); + week : function (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + }, - // edge attributes - graph.edge = parseAttributeList(); - return 'edge'; - } - else if (token == 'graph') { - getToken(); + isoWeek : function (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + }, - // graph attributes - graph.graph = parseAttributeList(); - return 'graph'; - } + weekday : function (input) { + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + }, - return null; - } + isoWeekday : function (input) { + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); + }, - /** - * parse a node statement - * @param {Object} graph - * @param {String | Number} id - */ - function parseNodeStatement(graph, id) { - // node statement - var node = { - id: id - }; - var attr = parseAttributeList(); - if (attr) { - node.attr = attr; - } - addNode(graph, node); + isoWeeksInYear : function () { + return weeksInYear(this.year(), 1, 4); + }, - // edge statements - parseEdge(graph, id); - } + weeksInYear : function () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + }, - /** - * 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(); + get : function (units) { + units = normalizeUnits(units); + return this[units](); + }, - var subgraph = parseSubgraph(graph); - if (subgraph) { - to = subgraph; - } - else { - if (tokenType != TOKENTYPE.IDENTIFIER) { - throw newSyntaxError('Identifier or subgraph expected'); - } - to = token; - addNode(graph, { - id: to - }); - getToken(); - } + set : function (units, value) { + units = normalizeUnits(units); + if (typeof this[units] === 'function') { + this[units](value); + } + return this; + }, - // parse edge attributes - var attr = parseAttributeList(); + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + locale : function (key) { + var newLocaleData; - // create edge - var edge = createEdge(graph, from, to, type, attr); - addEdge(graph, edge); + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = moment.localeData(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } + }, - from = to; - } - } + lang : deprecate( + 'moment().lang() is deprecated. Use moment().localeData() instead.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ), - /** - * Parse a set with attributes, - * for example [label="1.000", shape=solid] - * @return {Object | null} attr - */ - function parseAttributeList() { - var attr = null; + localeData : function () { + return this._locale; + }, - while (token == '[') { - getToken(); - attr = {}; - while (token !== '' && token != ']') { - if (tokenType != TOKENTYPE.IDENTIFIER) { - throw newSyntaxError('Attribute name expected'); - } - var name = token; + _dateTzOffset : function () { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return Math.round(this._d.getTimezoneOffset() / 15) * 15; + } + }); - getToken(); - if (token != '=') { - throw newSyntaxError('Equal sign = expected'); - } - getToken(); + function rawMonthSetter(mom, value) { + var dayOfMonth; - if (tokenType != TOKENTYPE.IDENTIFIER) { - throw newSyntaxError('Attribute value expected'); - } - var value = token; - setValue(attr, name, value); // name can be a path + // TODO: Move this out of here! + if (typeof value === 'string') { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (typeof value !== 'number') { + return mom; + } + } - getToken(); - if (token ==',') { - getToken(); - } + dayOfMonth = Math.min(mom.date(), + daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; } - if (token != ']') { - throw newSyntaxError('Bracket ] expected'); + function rawGetter(mom, unit) { + return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); } - getToken(); - } - return attr; - } + function rawSetter(mom, unit, value) { + if (unit === 'Month') { + return rawMonthSetter(mom, value); + } else { + return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } - /** - * 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 + ')'); - } + function makeAccessor(unit, keepTime) { + return function (value) { + if (value != null) { + rawSetter(this, unit, value); + moment.updateOffset(this, keepTime); + return this; + } else { + return rawGetter(this, unit); + } + }; + } - /** - * 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) + '...'); - } + moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); + moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); + moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); + // Setting the hour should keep the time, because the user explicitly + // specified which hour he wants. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); + // moment.fn.month is defined separately + moment.fn.date = makeAccessor('Date', true); + moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); + moment.fn.year = makeAccessor('FullYear', true); + moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); - /** - * 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 (Array.isArray(array1)) { - array1.forEach(function (elem1) { - if (Array.isArray(array2)) { - array2.forEach(function (elem2) { - fn(elem1, elem2); - }); - } - else { - fn(elem1, array2); - } - }); - } - else { - if (Array.isArray(array2)) { - array2.forEach(function (elem2) { - fn(array1, elem2); - }); - } - else { - fn(array1, array2); - } - } - } + // add plural methods + moment.fn.days = moment.fn.day; + moment.fn.months = moment.fn.month; + moment.fn.weeks = moment.fn.week; + moment.fn.isoWeeks = moment.fn.isoWeek; + moment.fn.quarters = moment.fn.quarter; - /** - * 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: {} - }; + // add aliased format methods + moment.fn.toJSON = moment.fn.toISOString; + + /************************************ + Duration Prototype + ************************************/ - // 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); - }); - } - // 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; + function daysToYears (days) { + // 400 years have 146097 days (taking into account leap year rules) + return days * 400 / 146097; } - dotData.edges.forEach(function (dotEdge) { - var from, to; - if (dotEdge.from instanceof Object) { - from = dotEdge.from.nodes; - } - else { - from = { - id: dotEdge.from - } - } + function yearsToDays (years) { + // years * 365 + absRound(years / 4) - + // absRound(years / 100) + absRound(years / 400); + return years * 146097 / 400; + } - if (dotEdge.to instanceof Object) { - to = dotEdge.to.nodes; - } - else { - to = { - id: dotEdge.to - } - } + extend(moment.duration.fn = Duration.prototype, { - if (dotEdge.from instanceof Object && dotEdge.from.edges) { - dotEdge.from.edges.forEach(function (subEdge) { - var graphEdge = convertEdge(subEdge); - graphData.edges.push(graphEdge); - }); - } + _bubble : function () { + var milliseconds = this._milliseconds, + days = this._days, + months = this._months, + data = this._data, + seconds, minutes, hours, years = 0; - 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); - }); + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; - if (dotEdge.to instanceof Object && dotEdge.to.edges) { - dotEdge.to.edges.forEach(function (subEdge) { - var graphEdge = convertEdge(subEdge); - graphData.edges.push(graphEdge); - }); - } - }); - } + seconds = absRound(milliseconds / 1000); + data.seconds = seconds % 60; - // copy the options - if (dotData.attr) { - graphData.options = dotData.attr; - } + minutes = absRound(seconds / 60); + data.minutes = minutes % 60; - return graphData; - } + hours = absRound(minutes / 60); + data.hours = hours % 24; - // exports - exports.parseDOT = parseDOT; - exports.DOTToGraph = DOTToGraph; + days += absRound(hours / 24); + // Accurately convert days to years, assume start from year 0. + years = absRound(daysToYears(days)); + days -= absRound(yearsToDays(years)); -/***/ }, -/* 49 */ -/***/ function(module, exports, __webpack_require__) { + // 30 days to a month + // TODO (iskren): Use anchor date (like 1st Jan) to compute this. + months += absRound(days / 30); + days %= 30; - - function parseGephi(gephiJSON, options) { - var edges = []; - var nodes = []; - this.options = { - edges: { - inheritColor: true - }, - nodes: { - allowedToMove: false, - parseColor: false - } - }; + // 12 months -> 1 year + years += absRound(months / 12); + months %= 12; - if (options !== undefined) { - this.options.nodes['allowedToMove'] = options.allowedToMove | false; - this.options.nodes['parseColor'] = options.parseColor | false; - this.options.edges['inheritColor'] = options.inheritColor | true; - } + data.days = days; + data.months = months; + data.years = years; + }, - var gEdges = gephiJSON.edges; - var gNodes = gephiJSON.nodes; - for (var i = 0; i < gEdges.length; i++) { - var edge = {}; - var gEdge = gEdges[i]; - edge['id'] = gEdge.id; - edge['from'] = gEdge.source; - edge['to'] = gEdge.target; - edge['attributes'] = gEdge.attributes; - // edge['value'] = gEdge.attributes !== undefined ? gEdge.attributes.Weight : undefined; - // edge['width'] = edge['value'] !== undefined ? undefined : edgegEdge.size; - edge['color'] = gEdge.color; - edge['inheritColor'] = edge['color'] !== undefined ? false : this.options.inheritColor; - edges.push(edge); - } + abs : function () { + this._milliseconds = Math.abs(this._milliseconds); + this._days = Math.abs(this._days); + this._months = Math.abs(this._months); - for (var i = 0; i < gNodes.length; i++) { - var node = {}; - var gNode = gNodes[i]; - node['id'] = gNode.id; - node['attributes'] = gNode.attributes; - node['x'] = gNode.x; - node['y'] = gNode.y; - node['label'] = gNode.label; - if (this.options.nodes.parseColor == true) { - node['color'] = gNode.color; - } - else { - node['color'] = gNode.color !== undefined ? {background:gNode.color, border:gNode.color} : undefined; - } - node['radius'] = gNode.size; - node['allowedToMoveX'] = this.options.nodes.allowedToMove; - node['allowedToMoveY'] = this.options.nodes.allowedToMove; - nodes.push(node); - } + this._data.milliseconds = Math.abs(this._data.milliseconds); + this._data.seconds = Math.abs(this._data.seconds); + this._data.minutes = Math.abs(this._data.minutes); + this._data.hours = Math.abs(this._data.hours); + this._data.months = Math.abs(this._data.months); + this._data.years = Math.abs(this._data.years); - return {nodes:nodes, edges:edges}; - } + return this; + }, - exports.parseGephi = parseGephi; + weeks : function () { + return absRound(this.days() / 7); + }, -/***/ }, -/* 50 */ -/***/ function(module, exports, __webpack_require__) { + valueOf : function () { + return this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6; + }, - var util = __webpack_require__(1); + humanize : function (withSuffix) { + var output = relativeTime(this, !withSuffix, this.localeData()); - /** - * @class Groups - * This class can store groups and properties specific for groups. - */ - function Groups() { - this.clear(); - this.defaultIndex = 0; - } + if (withSuffix) { + output = this.localeData().pastFuture(+this, output); + } + return this.localeData().postformat(output); + }, - /** - * 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 - ]; + add : function (input, val) { + // supports only 2.0-style add(1, 's') or add(moment) + var dur = moment.duration(input, val); + this._milliseconds += dur._milliseconds; + this._days += dur._days; + this._months += dur._months; - /** - * 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; - } - }; + this._bubble(); + return this; + }, - /** - * 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]; - 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; - } + subtract : function (input, val) { + var dur = moment.duration(input, val); - return group; - }; + this._milliseconds -= dur._milliseconds; + this._days -= dur._days; + this._months -= dur._months; - /** - * 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); - } - return style; - }; + this._bubble(); - module.exports = Groups; + return this; + }, + get : function (units) { + units = normalizeUnits(units); + return this[units.toLowerCase() + 's'](); + }, -/***/ }, -/* 51 */ -/***/ function(module, exports, __webpack_require__) { + as : function (units) { + var days, months; + units = normalizeUnits(units); - /** - * @class Images - * This class loads images and keeps them stored. - */ - function Images() { - this.images = {}; + if (units === 'month' || units === 'year') { + days = this._days + this._milliseconds / 864e5; + months = this._months + daysToYears(days) * 12; + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + yearsToDays(this._months / 12); + switch (units) { + case 'week': return days / 7 + this._milliseconds / 6048e5; + case 'day': return days + this._milliseconds / 864e5; + case 'hour': return days * 24 + this._milliseconds / 36e5; + case 'minute': return days * 24 * 60 + this._milliseconds / 6e4; + case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } + }, - this.callback = undefined; - } + lang : moment.fn.lang, + locale : moment.fn.locale, - /** - * 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; - }; + toIsoString : deprecate( + 'toIsoString() is deprecated. Please use toISOString() instead ' + + '(notice the capitals)', + function () { + return this.toISOString(); + } + ), - /** - * - * @param {string} url Url of the image - * @param {string} url Url of an image to use if the url image is not found - * @return {Image} img The image object - */ - Images.prototype.load = function(url, brokenUrl) { - 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.onerror = function () { - this.src = brokenUrl; - if (images.callback) { - images.callback(this); - } - }; - - img.src = url; - } + toISOString : function () { + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var years = Math.abs(this.years()), + months = Math.abs(this.months()), + days = Math.abs(this.days()), + hours = Math.abs(this.hours()), + minutes = Math.abs(this.minutes()), + seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); - return img; - }; + if (!this.asSeconds()) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } - module.exports = Images; + return (this.asSeconds() < 0 ? '-' : '') + + 'P' + + (years ? years + 'Y' : '') + + (months ? months + 'M' : '') + + (days ? days + 'D' : '') + + ((hours || minutes || seconds) ? 'T' : '') + + (hours ? hours + 'H' : '') + + (minutes ? minutes + 'M' : '') + + (seconds ? seconds + 'S' : ''); + }, + localeData : function () { + return this._locale; + } + }); -/***/ }, -/* 52 */ -/***/ function(module, exports, __webpack_require__) { + moment.duration.fn.toString = moment.duration.fn.toISOString; - var util = __webpack_require__(1); + function makeDurationGetter(name) { + moment.duration.fn[name] = function () { + return this._data[name]; + }; + } - /** - * @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, networkConstants) { - var constants = util.selectiveBridgeObject(['nodes'],networkConstants); - this.options = constants.nodes; + for (i in unitMillisecondFactors) { + if (hasOwnProp(unitMillisecondFactors, i)) { + makeDurationGetter(i.toLowerCase()); + } + } - this.selected = false; - this.hover = false; + moment.duration.fn.asMilliseconds = function () { + return this.as('ms'); + }; + moment.duration.fn.asSeconds = function () { + return this.as('s'); + }; + moment.duration.fn.asMinutes = function () { + return this.as('m'); + }; + moment.duration.fn.asHours = function () { + return this.as('h'); + }; + moment.duration.fn.asDays = function () { + return this.as('d'); + }; + moment.duration.fn.asWeeks = function () { + return this.as('weeks'); + }; + moment.duration.fn.asMonths = function () { + return this.as('M'); + }; + moment.duration.fn.asYears = function () { + return this.as('y'); + }; - this.edges = []; // all edges connected to this node - this.dynamicEdges = []; - this.reroutedEdges = {}; + /************************************ + Default Locale + ************************************/ - this.fontDrawThreshold = 3; - // set defaults for the properties - this.id = undefined; - this.x = null; - this.y = null; - this.allowedToMoveX = false; - this.allowedToMoveY = false; - 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.baseRadiusValue = networkConstants.nodes.radius; - this.radiusFixed = false; - this.level = -1; - this.preassignedLevel = false; - this.hierarchyEnumerated = false; - this.labelDimensions = {top:0,left:0,width:0,height:0,yLine:0}; // could be cached + // Set default locale, other locale will inherit from English. + moment.locale('en', { + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + /* EMBED_LOCALES */ + /************************************ + Exposing Moment + ************************************/ + + function makeGlobal(shouldDeprecate) { + /*global ender:false */ + if (typeof ender !== 'undefined') { + return; + } + oldGlobalMoment = globalScope.moment; + if (shouldDeprecate) { + globalScope.moment = deprecate( + 'Accessing Moment through the global scope is ' + + 'deprecated, and will be removed in an upcoming ' + + 'release.', + moment); + } else { + globalScope.moment = moment; + } + } - this.imagelist = imagelist; - this.grouplist = grouplist; + // CommonJS module is defined + if (hasModule) { + module.exports = moment; + } else if (true) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + if (module.config && module.config() && module.config().noGlobal === true) { + // release the global variable + globalScope.moment = oldGlobalMoment; + } - // 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.damping = networkConstants.physics.damping; // written every time gravity is calculated - this.fixedData = {x:null,y:null}; + return moment; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + makeGlobal(true); + } else { + makeGlobal(); + } + }).call(this); + + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(67)(module))) - this.setProperties(properties, constants); +/***/ }, +/* 54 */ +/***/ function(module, exports, __webpack_require__) { - // creating the variables for clustering - this.resetCluster(); - this.dynamicEdgesLength = 0; - this.clusterSession = 0; - this.clusterSizeWidthFactor = networkConstants.clustering.nodeScaling.width; - this.clusterSizeHeightFactor = networkConstants.clustering.nodeScaling.height; - this.clusterSizeRadiusFactor = networkConstants.clustering.nodeScaling.radius; - this.maxNodeSizeIncrements = networkConstants.clustering.maxNodeSizeIncrements; - this.growthIndicator = 0; + var __WEBPACK_AMD_DEFINE_RESULT__;/*! Hammer.JS - v1.1.3 - 2014-05-20 + * http://eightmedia.github.io/hammer.js + * + * Copyright (c) 2014 Jorik Tangelder ; + * Licensed under the MIT license */ - // 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; - } + (function(window, undefined) { + 'use strict'; /** - * (re)setting the clustering variables and objects + * @main + * @module hammer + * + * @class Hammer + * @static */ - 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 = []; - }; /** - * Attach a edge to the node - * @param {Edge} edge + * Hammer, use this to create instances + * ```` + * var hammertime = new Hammer(myElement); + * ```` + * + * @method Hammer + * @param {HTMLElement} element + * @param {Object} [options={}] + * @return {Hammer.Instance} */ - 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); - } - this.dynamicEdgesLength = this.dynamicEdges.length; + var Hammer = function Hammer(element, options) { + return new Hammer.Instance(element, options || {}); }; /** - * Detach a edge from the node - * @param {Edge} edge + * version, as defined in package.json + * the value will be set at each build + * @property VERSION + * @final + * @type {String} */ - Node.prototype.detachEdge = function(edge) { - var index = this.edges.indexOf(edge); - if (index != -1) { - this.edges.splice(index, 1); - } - index = this.dynamicEdges.indexOf(edge); - if (index != -1) { - this.dynamicEdges.splice(index, 1); - } - this.dynamicEdgesLength = this.dynamicEdges.length; - }; - + Hammer.VERSION = '1.1.3'; /** - * Set or overwrite properties for the node - * @param {Object} properties an object with properties - * @param {Object} constants and object with default, global properties + * default settings. + * more settings are defined per gesture at `/gestures`. Each gesture can be disabled/enabled + * by setting it's name (like `swipe`) to false. + * You can set the defaults for all instances by changing this object before creating an instance. + * @example + * ```` + * Hammer.defaults.drag = false; + * Hammer.defaults.behavior.touchAction = 'pan-y'; + * delete Hammer.defaults.behavior.userSelect; + * ```` + * @property defaults + * @type {Object} */ - Node.prototype.setProperties = function(properties, constants) { - if (!properties) { - return; - } + Hammer.defaults = { + /** + * this setting object adds styles and attributes to the element to prevent the browser from doing + * its native behavior. The css properties are auto prefixed for the browsers when needed. + * @property defaults.behavior + * @type {Object} + */ + behavior: { + /** + * Disables text selection to improve the dragging gesture. When the value is `none` it also sets + * `onselectstart=false` for IE on the element. Mainly for desktop browsers. + * @property defaults.behavior.userSelect + * @type {String} + * @default 'none' + */ + userSelect: 'none', - var fields = ['borderWidth','borderWidthSelected','shape','image','brokenImage','radius','fontColor', - 'fontSize','fontFace','fontFill','group','mass' - ]; - util.selectiveDeepExtend(fields, this.options, properties); + /** + * Specifies whether and how a given region can be manipulated by the user (for instance, by panning or zooming). + * Used by Chrome 35> and IE10>. By default this makes the element blocking any touch event. + * @property defaults.behavior.touchAction + * @type {String} + * @default: 'pan-y' + */ + touchAction: 'pan-y', - // 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.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;} + /** + * Disables the default callout shown when you touch and hold a touch target. + * On iOS, when you touch and hold a touch target such as a link, Safari displays + * a callout containing information about the link. This property allows you to disable that callout. + * @property defaults.behavior.touchCallout + * @type {String} + * @default 'none' + */ + touchCallout: 'none', - // 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;} + /** + * Specifies whether zooming is enabled. Used by IE10> + * @property defaults.behavior.contentZooming + * @type {String} + * @default 'none' + */ + contentZooming: 'none', - if (this.id === undefined) { - throw "Node must have an id"; - } + /** + * Specifies that an entire element should be draggable instead of its contents. + * Mainly for desktop browsers. + * @property defaults.behavior.userDrag + * @type {String} + * @default 'none' + */ + userDrag: 'none', - // copy group properties - if (typeof this.options.group === 'number' || (typeof this.options.group === 'string' && this.options.group != '')) { - var groupObj = this.grouplist.get(this.options.group); - for (var prop in groupObj) { - if (groupObj.hasOwnProperty(prop)) { - this.options[prop] = groupObj[prop]; - } + /** + * Overrides the highlight color shown when the user taps a link or a JavaScript + * clickable element in Safari on iPhone. This property obeys the alpha value, if specified. + * + * If you don't specify an alpha value, Safari on iPhone applies a default alpha value + * to the color. To disable tap highlighting, set the alpha value to 0 (invisible). + * If you set the alpha value to 1.0 (opaque), the element is not visible when tapped. + * @property defaults.behavior.tapHighlightColor + * @type {String} + * @default 'rgba(0,0,0,0)' + */ + tapHighlightColor: 'rgba(0,0,0,0)' } - } + }; + /** + * hammer document where the base events are added at + * @property DOCUMENT + * @type {HTMLElement} + * @default window.document + */ + Hammer.DOCUMENT = document; - // individual shape properties - if (properties.radius !== undefined) {this.baseRadiusValue = this.options.radius;} - if (properties.color !== undefined) {this.options.color = util.parseColor(properties.color);} + /** + * detect support for pointer events + * @property HAS_POINTEREVENTS + * @type {Boolean} + */ + Hammer.HAS_POINTEREVENTS = navigator.pointerEnabled || navigator.msPointerEnabled; - if (this.options.image!== undefined && this.options.image!= "") { - if (this.imagelist) { - this.imageObj = this.imagelist.load(this.options.image, this.options.brokenImage); - } - else { - throw "No imagelist provided"; - } - } + /** + * detect support for touch events + * @property HAS_TOUCHEVENTS + * @type {Boolean} + */ + Hammer.HAS_TOUCHEVENTS = ('ontouchstart' in window); - if (properties.allowedToMoveX !== undefined) { - this.xFixed = !properties.allowedToMoveX; - this.allowedToMoveX = properties.allowedToMoveX; - } - else if (properties.x !== undefined && this.allowedToMoveX == false) { - this.xFixed = true; - } + /** + * detect mobile browsers + * @property IS_MOBILE + * @type {Boolean} + */ + Hammer.IS_MOBILE = /mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent); + /** + * detect if we want to support mouseevents at all + * @property NO_MOUSEEVENTS + * @type {Boolean} + */ + Hammer.NO_MOUSEEVENTS = (Hammer.HAS_TOUCHEVENTS && Hammer.IS_MOBILE) || Hammer.HAS_POINTEREVENTS; - if (properties.allowedToMoveY !== undefined) { - this.yFixed = !properties.allowedToMoveY; - this.allowedToMoveY = properties.allowedToMoveY; - } - else if (properties.y !== undefined && this.allowedToMoveY == false) { - this.yFixed = true; - } + /** + * interval in which Hammer recalculates current velocity/direction/angle in ms + * @property CALCULATE_INTERVAL + * @type {Number} + * @default 25 + */ + Hammer.CALCULATE_INTERVAL = 25; - this.radiusFixed = this.radiusFixed || (properties.radius !== undefined); + /** + * eventtypes per touchevent (start, move, end) are filled by `Event.determineEventTypes` on `setup` + * the object contains the DOM event names per type (`EVENT_START`, `EVENT_MOVE`, `EVENT_END`) + * @property EVENT_TYPES + * @private + * @writeOnce + * @type {Object} + */ + var EVENT_TYPES = {}; - if (this.options.shape == 'image') { - this.options.radiusMin = constants.nodes.widthMin; - this.options.radiusMax = constants.nodes.widthMax; - } + /** + * direction strings, for safe comparisons + * @property DIRECTION_DOWN|LEFT|UP|RIGHT + * @final + * @type {String} + * @default 'down' 'left' 'up' 'right' + */ + var DIRECTION_DOWN = Hammer.DIRECTION_DOWN = 'down'; + var DIRECTION_LEFT = Hammer.DIRECTION_LEFT = 'left'; + var DIRECTION_UP = Hammer.DIRECTION_UP = 'up'; + var DIRECTION_RIGHT = Hammer.DIRECTION_RIGHT = 'right'; + /** + * pointertype strings, for safe comparisons + * @property POINTER_MOUSE|TOUCH|PEN + * @final + * @type {String} + * @default 'mouse' 'touch' 'pen' + */ + var POINTER_MOUSE = Hammer.POINTER_MOUSE = 'mouse'; + var POINTER_TOUCH = Hammer.POINTER_TOUCH = 'touch'; + var POINTER_PEN = Hammer.POINTER_PEN = 'pen'; + /** + * eventtypes + * @property EVENT_START|MOVE|END|RELEASE|TOUCH + * @final + * @type {String} + * @default 'start' 'change' 'move' 'end' 'release' 'touch' + */ + var EVENT_START = Hammer.EVENT_START = 'start'; + var EVENT_MOVE = Hammer.EVENT_MOVE = 'move'; + var EVENT_END = Hammer.EVENT_END = 'end'; + var EVENT_RELEASE = Hammer.EVENT_RELEASE = 'release'; + var EVENT_TOUCH = Hammer.EVENT_TOUCH = 'touch'; - // choose draw method depending on the shape - switch (this.options.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; - } - // reset the size of the node, this can be changed - this._reset(); + /** + * if the window events are set... + * @property READY + * @writeOnce + * @type {Boolean} + * @default false + */ + Hammer.READY = false; - }; + /** + * plugins namespace + * @property plugins + * @type {Object} + */ + Hammer.plugins = Hammer.plugins || {}; /** - * select this node + * gestures namespace + * see `/gestures` for the definitions + * @property gestures + * @type {Object} */ - Node.prototype.select = function() { - this.selected = true; - this._reset(); - }; + Hammer.gestures = Hammer.gestures || {}; /** - * unselect this node + * setup events to detect gestures on the document + * this function is called when creating an new instance + * @private */ - Node.prototype.unselect = function() { - this.selected = false; - this._reset(); - }; + function setup() { + if(Hammer.READY) { + return; + } + // find what eventtypes we add listeners to + Event.determineEventTypes(); + + // Register all gestures inside Hammer.gestures + Utils.each(Hammer.gestures, function(gesture) { + Detection.register(gesture); + }); + + // Add touch events on the document + Event.onTouch(Hammer.DOCUMENT, EVENT_MOVE, Detection.detect); + Event.onTouch(Hammer.DOCUMENT, EVENT_END, Detection.detect); + + // Hammer is ready...! + Hammer.READY = true; + } /** - * Reset the calculated size of the node, forces it to recalculate its size + * @module hammer + * + * @class Utils + * @static */ - Node.prototype.clearSizeCache = function() { - this._reset(); - }; + var Utils = Hammer.utils = { + /** + * extend method, could also be used for cloning when `dest` is an empty object. + * changes the dest object + * @method extend + * @param {Object} dest + * @param {Object} src + * @param {Boolean} [merge=false] do a merge + * @return {Object} dest + */ + extend: function extend(dest, src, merge) { + for(var key in src) { + if(!src.hasOwnProperty(key) || (dest[key] !== undefined && merge)) { + continue; + } + dest[key] = src[key]; + } + return dest; + }, + + /** + * simple addEventListener wrapper + * @method on + * @param {HTMLElement} element + * @param {String} type + * @param {Function} handler + */ + on: function on(element, type, handler) { + element.addEventListener(type, handler, false); + }, + + /** + * simple removeEventListener wrapper + * @method off + * @param {HTMLElement} element + * @param {String} type + * @param {Function} handler + */ + off: function off(element, type, handler) { + element.removeEventListener(type, handler, false); + }, + + /** + * forEach over arrays and objects + * @method each + * @param {Object|Array} obj + * @param {Function} iterator + * @param {any} iterator.item + * @param {Number} iterator.index + * @param {Object|Array} iterator.obj the source object + * @param {Object} context value to use as `this` in the iterator + */ + each: function each(obj, iterator, context) { + var i, len; + + // native forEach on arrays + if('forEach' in obj) { + obj.forEach(iterator, context); + // arrays + } else if(obj.length !== undefined) { + for(i = 0, len = obj.length; i < len; i++) { + if(iterator.call(context, obj[i], i, obj) === false) { + return; + } + } + // objects + } else { + for(i in obj) { + if(obj.hasOwnProperty(i) && + iterator.call(context, obj[i], i, obj) === false) { + return; + } + } + } + }, + + /** + * find if a string contains the string using indexOf + * @method inStr + * @param {String} src + * @param {String} find + * @return {Boolean} found + */ + inStr: function inStr(src, find) { + return src.indexOf(find) > -1; + }, + + /** + * find if a array contains the object using indexOf or a simple polyfill + * @method inArray + * @param {String} src + * @param {String} find + * @return {Boolean|Number} false when not found, or the index + */ + inArray: function inArray(src, find) { + if(src.indexOf) { + var index = src.indexOf(find); + return (index === -1) ? false : index; + } else { + for(var i = 0, len = src.length; i < len; i++) { + if(src[i] === find) { + return i; + } + } + return false; + } + }, - /** - * Reset the calculated size of the node, forces it to recalculate its size - * @private - */ - Node.prototype._reset = function() { - this.width = undefined; - this.height = undefined; - }; + /** + * convert an array-like object (`arguments`, `touchlist`) to an array + * @method toArray + * @param {Object} obj + * @return {Array} + */ + toArray: function toArray(obj) { + return Array.prototype.slice.call(obj, 0); + }, - /** - * 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; - }; + /** + * find if a node is in the given parent + * @method hasParent + * @param {HTMLElement} node + * @param {HTMLElement} parent + * @return {Boolean} found + */ + hasParent: function hasParent(node, parent) { + while(node) { + if(node == parent) { + return true; + } + node = node.parentNode; + } + return false; + }, - /** - * 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; + /** + * get the center of all the touches + * @method getCenter + * @param {Array} touches + * @return {Object} center contains `pageX`, `pageY`, `clientX` and `clientY` properties + */ + getCenter: function getCenter(touches) { + var pageX = [], + pageY = [], + clientX = [], + clientY = [], + min = Math.min, + max = Math.max; - if (!this.width) { - this.resize(ctx); - } + // no need to loop when only one touch + if(touches.length === 1) { + return { + pageX: touches[0].pageX, + pageY: touches[0].pageY, + clientX: touches[0].clientX, + clientY: touches[0].clientY + }; + } - switch (this.options.shape) { - case 'circle': - case 'dot': - return this.options.radius+ borderWidth; + Utils.each(touches, function(touch) { + pageX.push(touch.pageX); + pageY.push(touch.pageY); + clientX.push(touch.clientX); + clientY.push(touch.clientY); + }); - 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 { + pageX: (min.apply(Math, pageX) + max.apply(Math, pageX)) / 2, + pageY: (min.apply(Math, pageY) + max.apply(Math, pageY)) / 2, + clientX: (min.apply(Math, clientX) + max.apply(Math, clientX)) / 2, + clientY: (min.apply(Math, clientY) + max.apply(Math, clientY)) / 2 + }; + }, - // TODO: implement distanceToBorder for database - // TODO: implement distanceToBorder for triangle - // TODO: implement distanceToBorder for triangleDown + /** + * calculate the velocity between two points. unit is in px per ms. + * @method getVelocity + * @param {Number} deltaTime + * @param {Number} deltaX + * @param {Number} deltaY + * @return {Object} velocity `x` and `y` + */ + getVelocity: function getVelocity(deltaTime, deltaX, deltaY) { + return { + x: Math.abs(deltaX / deltaTime) || 0, + y: Math.abs(deltaY / deltaTime) || 0 + }; + }, - 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; - } + /** + * calculate the angle between two coordinates + * @method getAngle + * @param {Touch} touch1 + * @param {Touch} touch2 + * @return {Number} angle + */ + getAngle: function getAngle(touch1, touch2) { + var x = touch2.clientX - touch1.clientX, + y = touch2.clientY - touch1.clientY; - } - // TODO: implement calculation of distance to border for all shapes - }; + return Math.atan2(y, x) * 180 / Math.PI; + }, - /** - * Set forces acting on the node - * @param {number} fx Force in horizontal direction - * @param {number} fy Force in vertical direction - */ - Node.prototype._setForce = function(fx, fy) { - this.fx = fx; - this.fy = fy; - }; + /** + * do a small comparision to get the direction between two touches. + * @method getDirection + * @param {Touch} touch1 + * @param {Touch} touch2 + * @return {String} direction matches `DIRECTION_LEFT|RIGHT|UP|DOWN` + */ + getDirection: function getDirection(touch1, touch2) { + var x = Math.abs(touch1.clientX - touch2.clientX), + y = Math.abs(touch1.clientY - touch2.clientY); - /** - * Add forces acting on the node - * @param {number} fx Force in horizontal direction - * @param {number} fy Force in vertical direction - * @private - */ - Node.prototype._addForce = function(fx, fy) { - this.fx += fx; - this.fy += fy; - }; + if(x >= y) { + return touch1.clientX - touch2.clientX > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; + } + return touch1.clientY - touch2.clientY > 0 ? DIRECTION_UP : DIRECTION_DOWN; + }, - /** - * 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.options.mass; // acceleration - this.vx += ax * interval; // velocity - this.x += this.vx * interval; // position - } - else { - this.fx = 0; - this.vx = 0; - } + /** + * calculate the distance between two touches + * @method getDistance + * @param {Touch}touch1 + * @param {Touch} touch2 + * @return {Number} distance + */ + getDistance: function getDistance(touch1, touch2) { + var x = touch2.clientX - touch1.clientX, + y = touch2.clientY - touch1.clientY; - if (!this.yFixed) { - var dy = this.damping * this.vy; // damping force - var ay = (this.fy - dy) / this.options.mass; // acceleration - this.vy += ay * interval; // velocity - this.y += this.vy * interval; // position - } - else { - this.fy = 0; - this.vy = 0; - } - }; + return Math.sqrt((x * x) + (y * y)); + }, + /** + * calculate the scale factor between two touchLists + * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out + * @method getScale + * @param {Array} start array of touches + * @param {Array} end array of touches + * @return {Number} scale + */ + getScale: function getScale(start, end) { + // need two fingers... + if(start.length >= 2 && end.length >= 2) { + return this.getDistance(end[0], end[1]) / this.getDistance(start[0], start[1]); + } + return 1; + }, + /** + * calculate the rotation degrees between two touchLists + * @method getRotation + * @param {Array} start array of touches + * @param {Array} end array of touches + * @return {Number} rotation + */ + getRotation: function getRotation(start, end) { + // need two fingers + if(start.length >= 2 && end.length >= 2) { + return this.getAngle(end[1], end[0]) - this.getAngle(start[1], start[0]); + } + return 0; + }, - /** - * 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.options.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; - this.vx = 0; - } + /** + * find out if the direction is vertical * + * @method isVertical + * @param {String} direction matches `DIRECTION_UP|DOWN` + * @return {Boolean} is_vertical + */ + isVertical: function isVertical(direction) { + return direction == DIRECTION_UP || direction == DIRECTION_DOWN; + }, - if (!this.yFixed) { - var dy = this.damping * this.vy; // damping force - var ay = (this.fy - dy) / this.options.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; - this.vy = 0; - } - }; + /** + * set css properties with their prefixes + * @param {HTMLElement} element + * @param {String} prop + * @param {String} value + * @param {Boolean} [toggle=true] + * @return {Boolean} + */ + setPrefixedCss: function setPrefixedCss(element, prop, value, toggle) { + var prefixes = ['', 'Webkit', 'Moz', 'O', 'ms']; + prop = Utils.toCamelCase(prop); - /** - * 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); - }; + for(var i = 0; i < prefixes.length; i++) { + var p = prop; + // prefixes + if(prefixes[i]) { + p = prefixes[i] + p.slice(0, 1).toUpperCase() + p.slice(1); + } - /** - * 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 - */ - Node.prototype.isMoving = function(vmin) { - var velocity = Math.sqrt(Math.pow(this.vx,2) + Math.pow(this.vy,2)); - // this.velocity = Math.sqrt(Math.pow(this.vx,2) + Math.pow(this.vy,2)) - return (velocity > vmin); - }; + // test the style + if(p in element.style) { + element.style[p] = (toggle == null || toggle) && value || ''; + break; + } + } + }, - /** - * check if this node is selecte - * @return {boolean} selected True if node is selected, else false - */ - Node.prototype.isSelected = function() { - return this.selected; - }; + /** + * toggle browser default behavior by setting css properties. + * `userSelect='none'` also sets `element.onselectstart` to false + * `userDrag='none'` also sets `element.ondragstart` to false + * + * @method toggleBehavior + * @param {HtmlElement} element + * @param {Object} props + * @param {Boolean} [toggle=true] + */ + toggleBehavior: function toggleBehavior(element, props, toggle) { + if(!props || !element || !element.style) { + return; + } - /** - * Retrieve the value of the node. Can be undefined - * @return {Number} value - */ - Node.prototype.getValue = function() { - return this.value; - }; + // set the css properties + Utils.each(props, function(value, prop) { + Utils.setPrefixedCss(element, prop, value, toggle); + }); - /** - * 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); - }; + var falseFn = toggle && function() { + return false; + }; + // also the disable onselectstart + if(props.userSelect == 'none') { + element.onselectstart = falseFn; + } + // and disable ondragstart + if(props.userDrag == 'none') { + element.ondragstart = falseFn; + } + }, - /** - * 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.options.radius= (this.options.radiusMin + this.options.radiusMax) / 2; - } - else { - var scale = (this.options.radiusMax - this.options.radiusMin) / (max - min); - this.options.radius= (this.value - min) * scale + this.options.radiusMin; + /** + * convert a string with underscores to camelCase + * so prevent_default becomes preventDefault + * @param {String} str + * @return {String} camelCaseStr + */ + toCamelCase: function toCamelCase(str) { + return str.replace(/[_-]([a-z])/g, function(s) { + return s[1].toUpperCase(); + }); } - } - this.baseRadiusValue = this.options.radius; }; - /** - * 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"; - }; /** - * 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 + * @module hammer */ - Node.prototype.resize = function(ctx) { - throw "Resize method not initialized for node"; - }; - /** - * 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 + * @class Event + * @static */ - 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); - }; - - Node.prototype._resizeImage = function (ctx) { - // TODO: pre calculate the image size - - if (!this.width || !this.height) { // undefined or 0 - var width, height; - if (this.value) { - this.options.radius= this.baseRadiusValue; - var scale = this.imageObj.height / this.imageObj.width; - if (scale !== undefined) { - width = this.options.radius|| this.imageObj.width; - height = this.options.radius* scale || this.imageObj.height; - } - else { - width = 0; - height = 0; - } - } - else { - width = this.imageObj.width; - height = this.imageObj.height; - } - 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor; - this.growthIndicator = this.width - width; - } - } - - }; - - 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); + var Event = Hammer.event = { + /** + * when touch events have been fired, this is true + * this is used to stop mouse events + * @property prevent_mouseevents + * @private + * @type {Boolean} + */ + preventMouseEvents: false, - ctx.globalAlpha = 0.5; - ctx.drawImage(this.imageObj, this.left - lineWidth, this.top - lineWidth, this.width + 2*lineWidth, this.height + 2*lineWidth); - } + /** + * if EVENT_START has been fired + * @property started + * @private + * @type {Boolean} + */ + started: false, - // 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; - } + /** + * when the mouse is hold down, this is true + * @property should_detect + * @private + * @type {Boolean} + */ + shouldDetect: false, - this._label(ctx, this.label, this.x, yLabel, undefined, "top"); - }; + /** + * simple event binder with a hook and support for multiple types + * @method on + * @param {HTMLElement} element + * @param {String} type + * @param {Function} handler + * @param {Function} [hook] + * @param {Object} hook.type + */ + on: function on(element, type, handler, hook) { + var types = type.split(' '); + Utils.each(types, function(type) { + Utils.on(element, type, handler); + hook && hook(type); + }); + }, + /** + * simple event unbinder with a hook and support for multiple types + * @method off + * @param {HTMLElement} element + * @param {String} type + * @param {Function} handler + * @param {Function} [hook] + * @param {Object} hook.type + */ + off: function off(element, type, handler, hook) { + var types = type.split(' '); + Utils.each(types, function(type) { + Utils.off(element, type, handler); + hook && hook(type); + }); + }, - 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; + /** + * the core touch event handler. + * this finds out if we should to detect gestures + * @method onTouch + * @param {HTMLElement} element + * @param {String} eventType matches `EVENT_START|MOVE|END` + * @param {Function} handler + * @return onTouchHandler {Function} the core event handler + */ + onTouch: function onTouch(element, eventType, handler) { + var self = this; - 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor; + var onTouchHandler = function onTouchHandler(ev) { + var srcType = ev.type.toLowerCase(), + isPointer = Hammer.HAS_POINTEREVENTS, + isMouse = Utils.inStr(srcType, 'mouse'), + triggerType; - } - }; + // if we are in a mouseevent, but there has been a touchevent triggered in this session + // we want to do nothing. simply break out of the event. + if(isMouse && self.preventMouseEvents) { + return; - Node.prototype._drawBox = function (ctx) { - this._resizeBox(ctx); + // mousebutton must be down + } else if(isMouse && eventType == EVENT_START && ev.button === 0) { + self.preventMouseEvents = false; + self.shouldDetect = true; + } else if(isPointer && eventType == EVENT_START) { + self.shouldDetect = (ev.buttons === 1 || PointerEvent.matchType(POINTER_TOUCH, ev)); + // just a valid start event, but no mouse + } else if(!isMouse && eventType == EVENT_START) { + self.preventMouseEvents = true; + self.shouldDetect = true; + } - this.left = this.x - this.width / 2; - this.top = this.y - this.height / 2; + // update the pointer event before entering the detection + if(isPointer && eventType != EVENT_END) { + PointerEvent.updatePointer(eventType, ev); + } - var clusterLineWidth = 2.5; - var borderWidth = this.options.borderWidth; - var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; + // we are in a touch/down state, so allowed detection of gestures + if(self.shouldDetect) { + triggerType = self.doDetect.call(self, ev, eventType, element, handler); + } - ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; + // ...and we are done with the detection + // so reset everything to start each detection totally fresh + if(triggerType == EVENT_END) { + self.preventMouseEvents = false; + self.shouldDetect = false; + PointerEvent.reset(); + // update the pointerevent object after the detection + } - // draw the outer border - if (this.clusterSize > 1) { - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + if(isPointer && eventType == EVENT_END) { + PointerEvent.updatePointer(eventType, ev); + } + }; - ctx.roundRect(this.left-2*ctx.lineWidth, this.top-2*ctx.lineWidth, this.width+4*ctx.lineWidth, this.height+4*ctx.lineWidth, this.options.radius); - ctx.stroke(); - } - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + this.on(element, EVENT_TYPES[eventType], onTouchHandler); + return onTouchHandler; + }, - ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.options.color.background; + /** + * the core detection method + * this finds out what hammer-touch-events to trigger + * @method doDetect + * @param {Object} ev + * @param {String} eventType matches `EVENT_START|MOVE|END` + * @param {HTMLElement} element + * @param {Function} handler + * @return {String} triggerType matches `EVENT_START|MOVE|END` + */ + doDetect: function doDetect(ev, eventType, element, handler) { + var touchList = this.getTouchList(ev, eventType); + var touchListLength = touchList.length; + var triggerType = eventType; + var triggerChange = touchList.trigger; // used by fakeMultitouch plugin + var changedLength = touchListLength; - ctx.roundRect(this.left, this.top, this.width, this.height, this.options.radius); - ctx.fill(); - ctx.stroke(); + // at each touchstart-like event we want also want to trigger a TOUCH event... + if(eventType == EVENT_START) { + triggerChange = EVENT_TOUCH; + // ...the same for a touchend-like event + } else if(eventType == EVENT_END) { + triggerChange = EVENT_RELEASE; - this._label(ctx, this.label, this.x, this.y); - }; + // keep track of how many touches have been removed + changedLength = touchList.length - ((ev.changedTouches) ? ev.changedTouches.length : 1); + } + // after there are still touches on the screen, + // we just want to trigger a MOVE event. so change the START or END to a MOVE + // but only after detection has been started, the first time we actualy want a START + if(changedLength > 0 && this.started) { + triggerType = EVENT_MOVE; + } - 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; + // detection has been started, we keep track of this, see above + this.started = true; - // 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor; - this.growthIndicator = this.width - size; - } - }; + // generate some event data, some basic information + var evData = this.collectEventData(element, triggerType, touchList, ev); - Node.prototype._drawDatabase = function (ctx) { - this._resizeDatabase(ctx); - this.left = this.x - this.width / 2; - this.top = this.y - this.height / 2; + // trigger the triggerType event before the change (TOUCH, RELEASE) events + // but the END event should be at last + if(eventType != EVENT_END) { + handler.call(Detection, evData); + } - var clusterLineWidth = 2.5; - var borderWidth = this.options.borderWidth; - var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; + // trigger a change (TOUCH, RELEASE) event, this means the length of the touches changed + if(triggerChange) { + evData.changedLength = changedLength; + evData.eventType = triggerChange; - ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; + handler.call(Detection, evData); - // draw the outer border - if (this.clusterSize > 1) { - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + evData.eventType = triggerType; + delete evData.changedLength; + } - 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 : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + // trigger the END event + if(triggerType == EVENT_END) { + handler.call(Detection, evData); - ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; - ctx.database(this.x - this.width/2, this.y - this.height*0.5, this.width, this.height); - ctx.fill(); - ctx.stroke(); + // ...and we are done with the detection + // so reset everything to start each detection totally fresh + this.started = false; + } - this._label(ctx, this.label, this.x, this.y); - }; + return triggerType; + }, + /** + * we have different events for each device/browser + * determine what we need and set them in the EVENT_TYPES constant + * the `onTouch` method is bind to these properties. + * @method determineEventTypes + * @return {Object} events + */ + determineEventTypes: function determineEventTypes() { + var types; + if(Hammer.HAS_POINTEREVENTS) { + if(window.PointerEvent) { + types = [ + 'pointerdown', + 'pointermove', + 'pointerup pointercancel lostpointercapture' + ]; + } else { + types = [ + 'MSPointerDown', + 'MSPointerMove', + 'MSPointerUp MSPointerCancel MSLostPointerCapture' + ]; + } + } else if(Hammer.NO_MOUSEEVENTS) { + types = [ + 'touchstart', + 'touchmove', + 'touchend touchcancel' + ]; + } else { + types = [ + 'touchstart mousedown', + 'touchmove mousemove', + 'touchend touchcancel mouseup' + ]; + } - 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.options.radius = diameter / 2; + EVENT_TYPES[EVENT_START] = types[0]; + EVENT_TYPES[EVENT_MOVE] = types[1]; + EVENT_TYPES[EVENT_END] = types[2]; + return EVENT_TYPES; + }, - this.width = diameter; - this.height = diameter; + /** + * create touchList depending on the event + * @method getTouchList + * @param {Object} ev + * @param {String} eventType + * @return {Array} touches + */ + getTouchList: function getTouchList(ev, eventType) { + // get the fake pointerEvent touchlist + if(Hammer.HAS_POINTEREVENTS) { + return PointerEvent.getTouchList(); + } - // 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.options.radius += Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor; - this.growthIndicator = this.options.radius- 0.5*diameter; - } - }; + // get the touchlist + if(ev.touches) { + if(eventType == EVENT_MOVE) { + return ev.touches; + } - Node.prototype._drawCircle = function (ctx) { - this._resizeCircle(ctx); - this.left = this.x - this.width / 2; - this.top = this.y - this.height / 2; + var identifiers = []; + var concat = [].concat(Utils.toArray(ev.touches), Utils.toArray(ev.changedTouches)); + var touchList = []; - var clusterLineWidth = 2.5; - var borderWidth = this.options.borderWidth; - var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; + Utils.each(concat, function(touch) { + if(Utils.inArray(identifiers, touch.identifier) === false) { + touchList.push(touch); + } + identifiers.push(touch.identifier); + }); - ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; + return touchList; + } - // draw the outer border - if (this.clusterSize > 1) { - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + // make fake touchList from mouse position + ev.identifier = 1; + return [ev]; + }, - ctx.circle(this.x, this.y, this.options.radius+2*ctx.lineWidth); - ctx.stroke(); - } - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + /** + * collect basic event data + * @method collectEventData + * @param {HTMLElement} element + * @param {String} eventType matches `EVENT_START|MOVE|END` + * @param {Array} touches + * @param {Object} ev + * @return {Object} ev + */ + collectEventData: function collectEventData(element, eventType, touches, ev) { + // find out pointerType + var pointerType = POINTER_TOUCH; + if(Utils.inStr(ev.type, 'mouse') || PointerEvent.matchType(POINTER_MOUSE, ev)) { + pointerType = POINTER_MOUSE; + } else if(PointerEvent.matchType(POINTER_PEN, ev)) { + pointerType = POINTER_PEN; + } - ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; - ctx.circle(this.x, this.y, this.options.radius); - ctx.fill(); - ctx.stroke(); + return { + center: Utils.getCenter(touches), + timeStamp: Date.now(), + target: ev.target, + touches: touches, + eventType: eventType, + pointerType: pointerType, + srcEvent: ev, - this._label(ctx, this.label, this.x, this.y); - }; + /** + * prevent the browser default actions + * mostly used to disable scrolling of the browser + */ + preventDefault: function() { + var srcEvent = this.srcEvent; + srcEvent.preventManipulation && srcEvent.preventManipulation(); + srcEvent.preventDefault && srcEvent.preventDefault(); + }, - Node.prototype._resizeEllipse = function (ctx) { - if (!this.width) { - var textSize = this.getTextSize(ctx); + /** + * stop bubbling the event up to its parents + */ + stopPropagation: function() { + this.srcEvent.stopPropagation(); + }, - this.width = textSize.width * 1.5; - this.height = textSize.height * 2; - if (this.width < this.height) { - this.width = this.height; + /** + * immediately stop gesture detection + * might be useful after a swipe was detected + * @return {*} + */ + stopDetect: function() { + return Detection.stopDetect(); + } + }; } - 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.options.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 borderWidth = this.options.borderWidth; - var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; + /** + * @module hammer + * + * @class PointerEvent + * @static + */ + var PointerEvent = Hammer.PointerEvent = { + /** + * holds all pointers, by `identifier` + * @property pointers + * @type {Object} + */ + pointers: {}, - ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; + /** + * get the pointers as an array + * @method getTouchList + * @return {Array} touchlist + */ + getTouchList: function getTouchList() { + var touchlist = []; + // we can use forEach since pointerEvents only is in IE10 + Utils.each(this.pointers, function(pointer) { + touchlist.push(pointer); + }); + return touchlist; + }, - // draw the outer border - if (this.clusterSize > 1) { - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + /** + * update the position of a pointer + * @method updatePointer + * @param {String} eventType matches `EVENT_START|MOVE|END` + * @param {Object} pointerEvent + */ + updatePointer: function updatePointer(eventType, pointerEvent) { + if(eventType == EVENT_END || (eventType != EVENT_END && pointerEvent.buttons !== 1)) { + delete this.pointers[pointerEvent.pointerId]; + } else { + pointerEvent.identifier = pointerEvent.pointerId; + this.pointers[pointerEvent.pointerId] = pointerEvent; + } + }, - 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 : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + /** + * check if ev matches pointertype + * @method matchType + * @param {String} pointerType matches `POINTER_MOUSE|TOUCH|PEN` + * @param {PointerEvent} ev + */ + matchType: function matchType(pointerType, ev) { + if(!ev.pointerType) { + return false; + } - ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; + var pt = ev.pointerType, + types = {}; - ctx.ellipse(this.left, this.top, this.width, this.height); - ctx.fill(); - ctx.stroke(); - this._label(ctx, this.label, this.x, this.y); - }; + types[POINTER_MOUSE] = (pt === (ev.MSPOINTER_TYPE_MOUSE || POINTER_MOUSE)); + types[POINTER_TOUCH] = (pt === (ev.MSPOINTER_TYPE_TOUCH || POINTER_TOUCH)); + types[POINTER_PEN] = (pt === (ev.MSPOINTER_TYPE_PEN || POINTER_PEN)); + return types[pointerType]; + }, - Node.prototype._drawDot = function (ctx) { - this._drawShape(ctx, 'circle'); + /** + * reset the stored pointers + * @method reset + */ + reset: function resetList() { + this.pointers = {}; + } }; - Node.prototype._drawTriangle = function (ctx) { - this._drawShape(ctx, 'triangle'); - }; - Node.prototype._drawTriangleDown = function (ctx) { - this._drawShape(ctx, 'triangleDown'); - }; + /** + * @module hammer + * + * @class Detection + * @static + */ + var Detection = Hammer.detection = { + // contains all registred Hammer.gestures in the correct order + gestures: [], - Node.prototype._drawSquare = function (ctx) { - this._drawShape(ctx, 'square'); - }; + // data of the current Hammer.gesture detection session + current: null, - Node.prototype._drawStar = function (ctx) { - this._drawShape(ctx, 'star'); - }; + // the previous Hammer.gesture session data + // is a full clone of the previous gesture.current object + previous: null, - Node.prototype._resizeShape = function (ctx) { - if (!this.width) { - this.options.radius= this.baseRadiusValue; - var size = 2 * this.options.radius; - this.width = size; - this.height = size; + // when this becomes true, no gestures are fired + stopped: false, - // 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * 0.5 * this.clusterSizeRadiusFactor; - this.growthIndicator = this.width - size; - } - }; + /** + * start Hammer.gesture detection + * @method startDetect + * @param {Hammer.Instance} inst + * @param {Object} eventData + */ + startDetect: function startDetect(inst, eventData) { + // already busy with a Hammer.gesture detection on an element + if(this.current) { + return; + } - Node.prototype._drawShape = function (ctx, shape) { - this._resizeShape(ctx); + this.stopped = false; - this.left = this.x - this.width / 2; - this.top = this.y - this.height / 2; + // holds current session + this.current = { + inst: inst, // reference to HammerInstance we're working for + startEvent: Utils.extend({}, eventData), // start eventData for distances, timing etc + lastEvent: false, // last eventData + lastCalcEvent: false, // last eventData for calculations. + futureCalcEvent: false, // last eventData for calculations. + lastCalcData: {}, // last lastCalcData + name: '' // current gesture we're in/detected, can be 'tap', 'hold' etc + }; - var clusterLineWidth = 2.5; - var borderWidth = this.options.borderWidth; - var selectionLineWidth = this.options.borderWidthSelected || 2 * this.options.borderWidth; - var radiusMultiplier = 2; + this.detect(eventData); + }, - // 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; - } + /** + * Hammer.gesture detection + * @method detect + * @param {Object} eventData + * @return {any} + */ + detect: function detect(eventData) { + if(!this.current || this.stopped) { + return; + } - ctx.strokeStyle = this.selected ? this.options.color.highlight.border : this.hover ? this.options.color.hover.border : this.options.color.border; - // draw the outer border - if (this.clusterSize > 1) { - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + // extend event data with calculations about scale, distance etc + eventData = this.extendEventData(eventData); - ctx[shape](this.x, this.y, this.options.radius+ radiusMultiplier * ctx.lineWidth); - ctx.stroke(); - } - ctx.lineWidth = (this.selected ? selectionLineWidth : borderWidth) + ((this.clusterSize > 1) ? clusterLineWidth : 0.0); - ctx.lineWidth *= this.networkScaleInv; - ctx.lineWidth = Math.min(this.width,ctx.lineWidth); + // hammer instance and instance options + var inst = this.current.inst, + instOptions = inst.options; - ctx.fillStyle = this.selected ? this.options.color.highlight.background : this.hover ? this.options.color.hover.background : this.options.color.background; - ctx[shape](this.x, this.y, this.options.radius); - ctx.fill(); - ctx.stroke(); + // call Hammer.gesture handlers + Utils.each(this.gestures, function triggerGesture(gesture) { + // only when the instance options have enabled this gesture + if(!this.stopped && inst.enabled && instOptions[gesture.name]) { + gesture.handler.call(gesture, eventData, inst); + } + }, this); - if (this.label) { - this._label(ctx, this.label, this.x, this.y + this.height / 2, undefined, 'top',true); - } - }; + // store as previous event event + if(this.current) { + this.current.lastEvent = eventData; + } - 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; + if(eventData.eventType == EVENT_END) { + this.stopDetect(); + } - // 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.options.radius+= Math.min(this.clusterSize - 1, this.maxNodeSizeIncrements) * this.clusterSizeRadiusFactor; - this.growthIndicator = this.width - (textSize.width + 2 * margin); - } - }; + return eventData; + }, - Node.prototype._drawText = function (ctx) { - this._resizeText(ctx); - this.left = this.x - this.width / 2; - this.top = this.y - this.height / 2; + /** + * clear the Hammer.gesture vars + * this is called on endDetect, but can also be used when a final Hammer.gesture has been detected + * to stop other Hammer.gestures from being fired + * @method stopDetect + */ + stopDetect: function stopDetect() { + // clone current data to the store as the previous gesture + // used for the double tap gesture, since this is an other gesture detect session + this.previous = Utils.extend({}, this.current); - this._label(ctx, this.label, this.x, this.y); - }; + // reset the current + this.current = null; + this.stopped = true; + }, + /** + * calculate velocity, angle and direction + * @method getVelocityData + * @param {Object} ev + * @param {Object} center + * @param {Number} deltaTime + * @param {Number} deltaX + * @param {Number} deltaY + */ + getCalculatedData: function getCalculatedData(ev, center, deltaTime, deltaX, deltaY) { + var cur = this.current, + recalc = false, + calcEv = cur.lastCalcEvent, + calcData = cur.lastCalcData; - Node.prototype._label = function (ctx, text, x, y, align, baseline, labelUnderNode) { - if (text && Number(this.options.fontSize) * this.networkScale > this.fontDrawThreshold) { - ctx.font = (this.selected ? "bold " : "") + this.options.fontSize + "px " + this.options.fontFace; + if(calcEv && ev.timeStamp - calcEv.timeStamp > Hammer.CALCULATE_INTERVAL) { + center = calcEv.center; + deltaTime = ev.timeStamp - calcEv.timeStamp; + deltaX = ev.center.clientX - calcEv.center.clientX; + deltaY = ev.center.clientY - calcEv.center.clientY; + recalc = true; + } - var lines = text.split('\n'); - var lineCount = lines.length; - var fontSize = (Number(this.options.fontSize) + 4); // TODO: why is this +4 ? - var yLine = y + (1 - lineCount) / 2 * fontSize; - if (labelUnderNode == true) { - yLine = y + (1 - lineCount) / (2 * fontSize); - } + if(ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) { + cur.futureCalcEvent = ev; + } - // font fill from edges now for nodes! - var width = ctx.measureText(lines[0]).width; - for (var i = 1; i < lineCount; i++) { - var lineWidth = ctx.measureText(lines[i]).width; - width = lineWidth > width ? lineWidth : width; - } - var height = this.options.fontSize * lineCount; - var left = x - width / 2; - var top = y - height / 2; - if (baseline == "top") { - top += 0.5 * fontSize; - } - this.labelDimensions = {top:top,left:left,width:width,height:height,yLine:yLine}; + if(!cur.lastCalcEvent || recalc) { + calcData.velocity = Utils.getVelocity(deltaTime, deltaX, deltaY); + calcData.angle = Utils.getAngle(center, ev.center); + calcData.direction = Utils.getDirection(center, ev.center); - // create the fontfill background - if (this.options.fontFill !== undefined && this.options.fontFill !== null && this.options.fontFill !== "none") { - ctx.fillStyle = this.options.fontFill; - ctx.fillRect(left, top, width, height); - } + cur.lastCalcEvent = cur.futureCalcEvent || ev; + cur.futureCalcEvent = ev; + } - // draw text - ctx.fillStyle = this.options.fontColor || "black"; - ctx.textAlign = align || "center"; - ctx.textBaseline = baseline || "middle"; - for (var i = 0; i < lineCount; i++) { - ctx.fillText(lines[i], x, yLine); - yLine += fontSize; - } - } - }; + ev.velocityX = calcData.velocity.x; + ev.velocityY = calcData.velocity.y; + ev.interimAngle = calcData.angle; + ev.interimDirection = calcData.direction; + }, + /** + * extend eventData for Hammer.gestures + * @method extendEventData + * @param {Object} ev + * @return {Object} ev + */ + extendEventData: function extendEventData(ev) { + var cur = this.current, + startEv = cur.startEvent, + lastEv = cur.lastEvent || startEv; - Node.prototype.getTextSize = function(ctx) { - if (this.label !== undefined) { - ctx.font = (this.selected ? "bold " : "") + this.options.fontSize + "px " + this.options.fontFace; + // update the start touchlist to calculate the scale/rotation + if(ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) { + startEv.touches = []; + Utils.each(ev.touches, function(touch) { + startEv.touches.push({ + clientX: touch.clientX, + clientY: touch.clientY + }); + }); + } - var lines = this.label.split('\n'), - height = (Number(this.options.fontSize) + 4) * lines.length, - width = 0; + var deltaTime = ev.timeStamp - startEv.timeStamp, + deltaX = ev.center.clientX - startEv.center.clientX, + deltaY = ev.center.clientY - startEv.center.clientY; - for (var i = 0, iMax = lines.length; i < iMax; i++) { - width = Math.max(width, ctx.measureText(lines[i]).width); - } + this.getCalculatedData(ev, lastEv.center, deltaTime, deltaX, deltaY); - return {"width": width, "height": height}; - } - else { - return {"width": 0, "height": 0}; - } - }; + Utils.extend(ev, { + startEvent: startEv, - /** - * 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.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; - } - }; + deltaTime: deltaTime, + deltaX: deltaX, + deltaY: deltaY, - /** - * 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); - }; + distance: Utils.getDistance(startEv.center, ev.center), + angle: Utils.getAngle(startEv.center, ev.center), + direction: Utils.getDirection(startEv.center, ev.center), + scale: Utils.getScale(startEv.touches, ev.touches), + rotation: Utils.getRotation(startEv.touches, ev.touches) + }); - /** - * 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; - }; + return ev; + }, + + /** + * register new gesture + * @method register + * @param {Object} gesture object, see `gestures/` for documentation + * @return {Array} gestures + */ + register: function register(gesture) { + // add an enable gesture options if there is no given + var options = gesture.defaults || {}; + if(options[gesture.name] === undefined) { + options[gesture.name] = true; + } + // extend Hammer default options with the Hammer.gesture options + Utils.extend(Hammer.defaults, options, true); - /** - * 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; - }; + // set its index + gesture.index = gesture.index || 1000; + // add Hammer.gesture to the list + this.gestures.push(gesture); + // sort the list by index + this.gestures.sort(function(a, b) { + if(a.index < b.index) { + return -1; + } + if(a.index > b.index) { + return 1; + } + return 0; + }); - /** - * 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; + return this.gestures; + } }; /** - * Basic preservation of (kinectic) energy - * - * @param massBeforeClustering + * @module hammer */ - Node.prototype.updateVelocity = function(massBeforeClustering) { - var energyBefore = this.vx * this.vx * massBeforeClustering; - //this.vx = (this.vx < 0) ? -Math.sqrt(energyBefore/this.options.mass) : Math.sqrt(energyBefore/this.options.mass); - this.vx = Math.sqrt(energyBefore/this.options.mass); - energyBefore = this.vy * this.vy * massBeforeClustering; - //this.vy = (this.vy < 0) ? -Math.sqrt(energyBefore/this.options.mass) : Math.sqrt(energyBefore/this.options.mass); - this.vy = Math.sqrt(energyBefore/this.options.mass); - }; - - module.exports = Node; - - -/***/ }, -/* 53 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(1); - var Node = __webpack_require__(52); /** - * @class Edge + * create new hammer instance + * all methods should return the instance itself, so it is chainable. * - * 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 + * @class Instance + * @constructor + * @param {HTMLElement} element + * @param {Object} [options={}] options are merged with `Hammer.defaults` + * @return {Hammer.Instance} */ - function Edge (properties, network, networkConstants) { - if (!network) { - throw "No network provided"; - } - var fields = ['edges','physics']; - var constants = util.selectiveBridgeObject(fields,networkConstants); - this.options = constants.edges; - this.physics = constants.physics; - this.options['smoothCurves'] = networkConstants['smoothCurves']; + Hammer.Instance = function(element, options) { + var self = this; + // setup HammerJS window events and register all gestures + // this also sets up the default options + setup(); - this.network = network; + /** + * @property element + * @type {HTMLElement} + */ + this.element = element; - // initialize variables - this.id = undefined; - this.fromId = undefined; - this.toId = undefined; - this.title = undefined; - this.widthSelected = this.options.width * this.options.widthSelectionMultiplier; - this.value = undefined; - this.selected = false; - this.hover = false; - this.labelDimensions = {top:0,left:0,width:0,height:0,yLine:0}; // could be cached - this.dirtyLabel = true; + /** + * @property enabled + * @type {Boolean} + * @protected + */ + this.enabled = true; - this.from = null; // a node - this.to = null; // a node - this.via = null; // a temp node + /** + * options, merged with the defaults + * options with an _ are converted to camelCase + * @property options + * @type {Object} + */ + Utils.each(options, function(value, name) { + delete options[name]; + options[Utils.toCamelCase(name)] = value; + }); - // 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.options = Utils.extend(Utils.extend({}, Hammer.defaults), options || {}); - this.connected = false; + // add some css to the element to prevent the browser from doing its native behavoir + if(this.options.behavior) { + Utils.toggleBehavior(this.element, this.options.behavior, true); + } - this.widthFixed = false; - this.lengthFixed = false; + /** + * event start handler on the element to start the detection + * @property eventStartHandler + * @type {Object} + */ + this.eventStartHandler = Event.onTouch(element, EVENT_START, function(ev) { + if(self.enabled && ev.eventType == EVENT_START) { + Detection.startDetect(self, ev); + } else if(ev.eventType == EVENT_TOUCH) { + Detection.detect(ev); + } + }); - this.setProperties(properties); + /** + * keep a list of user event handlers which needs to be removed when calling 'dispose' + * @property eventHandlers + * @type {Array} + */ + this.eventHandlers = []; + }; - this.controlNodesEnabled = false; - this.controlNodes = {from:null, to:null, positions:{}}; - this.connectedNode = null; - } + Hammer.Instance.prototype = { + /** + * bind events to the instance + * @method on + * @chainable + * @param {String} gestures multiple gestures by splitting with a space + * @param {Function} handler + * @param {Object} handler.ev event object + */ + on: function onEvent(gestures, handler) { + var self = this; + Event.on(self.element, gestures, handler, function(type) { + self.eventHandlers.push({ gesture: type, handler: handler }); + }); + return self; + }, - /** - * 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) { - if (!properties) { - return; - } + /** + * unbind events to the instance + * @method off + * @chainable + * @param {String} gestures + * @param {Function} handler + */ + off: function offEvent(gestures, handler) { + var self = this; - var fields = ['style','fontSize','fontFace','fontColor','fontFill','width', - 'widthSelectionMultiplier','hoverWidth','arrowScaleFactor','dash','inheritColor' - ]; - util.selectiveDeepExtend(fields, this.options, properties); + Event.off(self.element, gestures, handler, function(type) { + var index = Utils.inArray({ gesture: type, handler: handler }); + if(index !== false) { + self.eventHandlers.splice(index, 1); + } + }); + return self; + }, - if (properties.from !== undefined) {this.fromId = properties.from;} - if (properties.to !== undefined) {this.toId = properties.to;} + /** + * trigger gesture event + * @method trigger + * @chainable + * @param {String} gesture + * @param {Object} [eventData] + */ + trigger: function triggerEvent(gesture, eventData) { + // optional + if(!eventData) { + eventData = {}; + } - if (properties.id !== undefined) {this.id = properties.id;} - if (properties.label !== undefined) {this.label = properties.label; this.dirtyLabel = true;} + // create DOM event + var event = Hammer.DOCUMENT.createEvent('Event'); + event.initEvent(gesture, true, true); + event.gesture = eventData; - if (properties.title !== undefined) {this.title = properties.title;} - if (properties.value !== undefined) {this.value = properties.value;} - if (properties.length !== undefined) {this.physics.springLength = properties.length;} + // trigger on the target if it is in the instance element, + // this is for event delegation tricks + var element = this.element; + if(Utils.hasParent(eventData.target, element)) { + element = eventData.target; + } - if (properties.color !== undefined) { - this.options.inheritColor = false; - if (util.isString(properties.color)) { - this.options.color.color = properties.color; - this.options.color.highlight = properties.color; - } - else { - if (properties.color.color !== undefined) {this.options.color.color = properties.color.color;} - if (properties.color.highlight !== undefined) {this.options.color.highlight = properties.color.highlight;} - if (properties.color.hover !== undefined) {this.options.color.hover = properties.color.hover;} - } - } + element.dispatchEvent(event); + return this; + }, - // A node is connected when it has a from and to node. - this.connect(); + /** + * enable of disable hammer.js detection + * @method enable + * @chainable + * @param {Boolean} state + */ + enable: function enable(state) { + this.enabled = state; + return this; + }, - this.widthFixed = this.widthFixed || (properties.width !== undefined); - this.lengthFixed = this.lengthFixed || (properties.length !== undefined); + /** + * dispose this hammer instance + * @method dispose + * @return {Null} + */ + dispose: function dispose() { + var i, eh; - this.widthSelected = this.options.width* this.options.widthSelectionMultiplier; + // undo all changes made by stop_browser_behavior + Utils.toggleBehavior(this.element, this.options.behavior, false); - // set draw method based on style - switch (this.options.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; - } - }; + // unbind all custom event handlers + for(i = -1; (eh = this.eventHandlers[++i]);) { + Utils.off(this.element, eh.gesture, eh.handler); + } - /** - * Connect an edge to its nodes - */ - Edge.prototype.connect = function () { - this.disconnect(); + this.eventHandlers = []; - this.from = this.network.nodes[this.fromId] || null; - this.to = this.network.nodes[this.toId] || null; - this.connected = (this.from && this.to); + // unbind the start event listener + Event.off(this.element, EVENT_TYPES[EVENT_START], this.eventStartHandler); - 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); + return null; } - } }; + /** - * Disconnect an edge from its nodes + * @module gestures */ - Edge.prototype.disconnect = function () { - if (this.from) { - this.from.detachEdge(this); - this.from = null; - } - if (this.to) { - this.to.detachEdge(this); - this.to = null; - } - - this.connected = false; - }; - /** - * get the title of this edge. - * @return {string} title The title of the edge, or undefined when no title - * has been set. + * Move with x fingers (default 1) around on the page. + * Preventing the default browser behavior is a good way to improve feel and working. + * ```` + * hammertime.on("drag", function(ev) { + * console.log(ev); + * ev.gesture.preventDefault(); + * }); + * ```` + * + * @class Drag + * @static */ - Edge.prototype.getTitle = function() { - return typeof this.title === "function" ? this.title() : this.title; - }; - - /** - * Retrieve the value of the edge. Can be undefined - * @return {Number} value + * @event drag + * @param {Object} ev */ - Edge.prototype.getValue = function() { - return this.value; - }; - /** - * Adjust the value range of the edge. The edge will adjust it's width - * based on its value. - * @param {Number} min - * @param {Number} max + * @event dragstart + * @param {Object} ev */ - Edge.prototype.setValueRange = function(min, max) { - if (!this.widthFixed && this.value !== undefined) { - var scale = (this.options.widthMax - this.options.widthMin) / (max - min); - this.options.width= (this.value - min) * scale + this.options.widthMin; - this.widthSelected = this.options.width* this.options.widthSelectionMultiplier; - } - }; - /** - * 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 + * @event dragend + * @param {Object} ev */ - Edge.prototype.draw = function(ctx) { - throw "Method draw not initialized in edge"; - }; - /** - * 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 + * @event drapleft + * @param {Object} ev + */ + /** + * @event dragright + * @param {Object} ev + */ + /** + * @event dragup + * @param {Object} ev + */ + /** + * @event dragdown + * @param {Object} ev */ - 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); - - return (dist < distMax); - } - else { - return false - } - }; - Edge.prototype._getColor = function() { - var colorObj = this.options.color; - if (this.options.inheritColor == "to") { - colorObj = { - highlight: this.to.options.color.highlight.border, - hover: this.to.options.color.hover.border, - color: this.to.options.color.border - }; - } - else if (this.options.inheritColor == "from" || this.options.inheritColor == true) { - colorObj = { - highlight: this.from.options.color.highlight.border, - hover: this.from.options.color.hover.border, - color: this.from.options.color.border - }; - } + /** + * @param {String} name + */ + (function(name) { + var triggered = false; - if (this.selected == true) {return colorObj.highlight;} - else if (this.hover == true) {return colorObj.hover;} - else {return colorObj.color;} - }; + function dragGesture(ev, inst) { + var cur = Detection.current; + // max touches + if(inst.options.dragMaxTouches > 0 && + ev.touches.length > inst.options.dragMaxTouches) { + return; + } - /** - * 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(); + switch(ev.eventType) { + case EVENT_START: + triggered = false; + break; - if (this.from != this.to) { - // draw line - var via = this._line(ctx); + case EVENT_MOVE: + // when the distance we moved is too small we skip this gesture + // or we can be already in dragging + if(ev.distance < inst.options.dragMinDistance && + cur.name != name) { + return; + } - // draw label - var point; - if (this.label) { - if (this.options.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.physics.springLength / 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); - } - }; + var startCenter = cur.startEvent.center; - /** - * 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.max(Math.min(this.widthSelected, this.options.widthMax), 0.3*this.networkScaleInv); - } - else { - if (this.hover == true) { - return Math.max(Math.min(this.options.hoverWidth, this.options.widthMax), 0.3*this.networkScaleInv); - } - else { - return Math.max(this.options.width, 0.3*this.networkScaleInv); - } - } - }; + // we are dragging! + if(cur.name != name) { + cur.name = name; + if(inst.options.dragDistanceCorrection && ev.distance > 0) { + // When a drag is triggered, set the event center to dragMinDistance pixels from the original event center. + // Without this correction, the dragged distance would jumpstart at dragMinDistance pixels instead of at 0. + // It might be useful to save the original start point somewhere + var factor = Math.abs(inst.options.dragMinDistance / ev.distance); + startCenter.pageX += ev.deltaX * factor; + startCenter.pageY += ev.deltaY * factor; + startCenter.clientX += ev.deltaX * factor; + startCenter.clientY += ev.deltaY * factor; - Edge.prototype._getViaCoordinates = function () { - var xVia = null; - var yVia = null; - var factor = this.options.smoothCurves.roundness; - var type = this.options.smoothCurves.type; + // recalculate event data using new start point + ev = Detection.extendEventData(ev); + } + } - 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)) { // up - down - xVia = this.from.x; - if (this.from.y < this.to.y) { - yVia = this.to.y - (1-factor) * dy; - } - else { - yVia = this.to.y + (1-factor) * dy; - } - } - else if (Math.abs(this.from.x - this.to.x) > Math.abs(this.from.y - this.to.y)) { // left - right - if (this.from.x < this.to.x) { - xVia = this.to.x - (1-factor) * dx; - } - else { - xVia = this.to.x + (1-factor) * dx; - } - yVia = this.from.y; - } - } - else if (type == 'horizontal') { - if (this.from.x < this.to.x) { - xVia = this.to.x - (1-factor) * dx; - } - else { - xVia = this.to.x + (1-factor) * dx; - } - yVia = this.from.y; - } - else if (type == 'vertical') { - xVia = this.from.x; - if (this.from.y < this.to.y) { - yVia = this.to.y - (1-factor) * dy; - } - else { - yVia = this.to.y + (1-factor) * dy; - } - } - 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; - } - } - 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 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; - } - } - } - } + // lock drag to axis? + if(cur.lastEvent.dragLockToAxis || + ( inst.options.dragLockToAxis && + inst.options.dragLockMinDistance <= ev.distance + )) { + ev.dragLockToAxis = true; + } + // keep direction on the axis that the drag gesture started on + var lastDirection = cur.lastEvent.direction; + if(ev.dragLockToAxis && lastDirection !== ev.direction) { + if(Utils.isVertical(lastDirection)) { + ev.direction = (ev.deltaY < 0) ? DIRECTION_UP : DIRECTION_DOWN; + } else { + ev.direction = (ev.deltaX < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT; + } + } - return {x:xVia, y:yVia}; - }; + // first time, trigger dragstart event + if(!triggered) { + inst.trigger(name + 'start', ev); + triggered = true; + } - /** - * 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.options.smoothCurves.enabled == true) { - if (this.options.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; - } - } - else { - ctx.quadraticCurveTo(this.via.x,this.via.y,this.to.x, this.to.y); - ctx.stroke(); - return this.via; + // trigger events + inst.trigger(name, ev); + inst.trigger(name + ev.direction, ev); + + var isVertical = Utils.isVertical(ev.direction); + + // block the browser events + if((inst.options.dragBlockVertical && isVertical) || + (inst.options.dragBlockHorizontal && !isVertical)) { + ev.preventDefault(); + } + break; + + case EVENT_RELEASE: + if(triggered && ev.changedLength <= inst.options.dragMaxTouches) { + inst.trigger(name + 'end', ev); + triggered = false; + } + break; + + case EVENT_END: + triggered = false; + break; + } } - } - 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(); - }; + Hammer.gestures.Drag = { + name: name, + index: 50, + handler: dragGesture, + defaults: { + /** + * minimal movement that have to be made before the drag event gets triggered + * @property dragMinDistance + * @type {Number} + * @default 10 + */ + dragMinDistance: 10, - /** - * 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) { - ctx.font = ((this.from.selected || this.to.selected) ? "bold " : "") + - this.options.fontSize + "px " + this.options.fontFace; - var yLine; + /** + * Set dragDistanceCorrection to true to make the starting point of the drag + * be calculated from where the drag was triggered, not from where the touch started. + * Useful to avoid a jerk-starting drag, which can make fine-adjustments + * through dragging difficult, and be visually unappealing. + * @property dragDistanceCorrection + * @type {Boolean} + * @default true + */ + dragDistanceCorrection: true, - if (this.dirtyLabel == true) { - var lines = String(text).split('\n'); - var lineCount = lines.length; - var fontSize = (Number(this.options.fontSize) + 4); - yLine = y + (1 - lineCount) / 2 * fontSize; + /** + * set 0 for unlimited, but this can conflict with transform + * @property dragMaxTouches + * @type {Number} + * @default 1 + */ + dragMaxTouches: 1, - var width = ctx.measureText(lines[0]).width; - for (var i = 1; i < lineCount; i++) { - var lineWidth = ctx.measureText(lines[i]).width; - width = lineWidth > width ? lineWidth : width; - } - var height = this.options.fontSize * lineCount; - var left = x - width / 2; - var top = y - height / 2; + /** + * prevent default browser behavior when dragging occurs + * be careful with it, it makes the element a blocking element + * when you are using the drag gesture, it is a good practice to set this true + * @property dragBlockHorizontal + * @type {Boolean} + * @default false + */ + dragBlockHorizontal: false, - // cache - this.labelDimensions = {top:top,left:left,width:width,height:height,yLine:yLine}; - } + /** + * same as `dragBlockHorizontal`, but for vertical movement + * @property dragBlockVertical + * @type {Boolean} + * @default false + */ + dragBlockVertical: false, + /** + * dragLockToAxis keeps the drag gesture on the axis that it started on, + * It disallows vertical directions if the initial direction was horizontal, and vice versa. + * @property dragLockToAxis + * @type {Boolean} + * @default false + */ + dragLockToAxis: false, - if (this.options.fontFill !== undefined && this.options.fontFill !== null && this.options.fontFill !== "none") { - ctx.fillStyle = this.options.fontFill; - ctx.fillRect(this.labelDimensions.left, - this.labelDimensions.top, - this.labelDimensions.width, - this.labelDimensions.height); - } + /** + * drag lock only kicks in when distance > dragLockMinDistance + * This way, locking occurs only when the distance has become large enough to reliably determine the direction + * @property dragLockMinDistance + * @type {Number} + * @default 25 + */ + dragLockMinDistance: 25 + } + }; + })('drag'); - // draw text - ctx.fillStyle = this.options.fontColor || "black"; - ctx.textAlign = "center"; - ctx.textBaseline = "middle"; - yLine = this.labelDimensions.yLine; - for (var i = 0; i < lineCount; i++) { - ctx.fillText(lines[i], x, yLine); - yLine += fontSize; + /** + * @module gestures + */ + /** + * trigger a simple gesture event, so you can do anything in your handler. + * only usable if you know what your doing... + * + * @class Gesture + * @static + */ + /** + * @event gesture + * @param {Object} ev + */ + Hammer.gestures.Gesture = { + name: 'gesture', + index: 1337, + handler: function releaseGesture(ev, inst) { + inst.trigger(this.name, ev); } - } }; /** - * 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 + * @module gestures + */ + /** + * Touch stays at the same place for x time + * + * @class Hold + * @static + */ + /** + * @event hold + * @param {Object} ev */ - Edge.prototype._drawDashLine = function(ctx) { - // set style - ctx.strokeStyle = this._getColor(); - ctx.lineWidth = this._getLineWidth(); - 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.options.dash.length !== undefined && this.options.dash.gap !== undefined) { - pattern = [this.options.dash.length,this.options.dash.gap]; - } - else { - pattern = [5,5]; - } + /** + * @param {String} name + */ + (function(name) { + var timer; - // set dash settings for chrome or firefox - if (typeof ctx.setLineDash !== 'undefined') { //Chrome - ctx.setLineDash(pattern); - ctx.lineDashOffset = 0; + function holdGesture(ev, inst) { + var options = inst.options, + current = Detection.current; - } else { //Firefox - ctx.mozDash = pattern; - ctx.mozDashOffset = 0; - } + switch(ev.eventType) { + case EVENT_START: + clearTimeout(timer); - // draw the line - via = this._line(ctx); + // set the gesture so we can check in the timeout if it still is + current.name = name; - // restore the dash settings. - if (typeof ctx.setLineDash !== 'undefined') { //Chrome - ctx.setLineDash([0]); - ctx.lineDashOffset = 0; + // set timer and if after the timeout it still is hold, + // we trigger the hold event + timer = setTimeout(function() { + if(current && current.name == name) { + inst.trigger(name, ev); + } + }, options.holdTimeout); + break; - } else { //Firefox - ctx.mozDash = [0]; - ctx.mozDashOffset = 0; - } - } - else { // unsupporting smooth lines - // draw dashed line - ctx.beginPath(); - ctx.lineCap = 'round'; - if (this.options.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.options.dash.length,this.options.dash.gap,this.options.dash.altLength,this.options.dash.gap]); - } - else if (this.options.dash.length !== undefined && this.options.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.options.dash.length,this.options.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(); - } + case EVENT_MOVE: + if(ev.distance > options.holdThreshold) { + clearTimeout(timer); + } + break; - // draw label - if (this.label) { - var point; - if (this.options.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); + case EVENT_RELEASE: + clearTimeout(timer); + break; + } } - this._label(ctx, this.label, point.x, point.y); - } - }; + + Hammer.gestures.Hold = { + name: name, + index: 10, + defaults: { + /** + * @property holdTimeout + * @type {Number} + * @default 500 + */ + holdTimeout: 500, + + /** + * movement allowed while holding + * @property holdThreshold + * @type {Number} + * @default 2 + */ + holdThreshold: 2 + }, + handler: holdGesture + }; + })('hold'); /** - * Get a point on a line - * @param {Number} percentage. Value between 0 (line start) and 1 (line end) - * @return {Object} point - * @private + * @module gestures */ - 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 + * when a touch is being released from the page + * + * @class Release + * @static */ - 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) - } + /** + * @event release + * @param {Object} ev + */ + Hammer.gestures.Release = { + name: 'release', + index: Infinity, + handler: function releaseGesture(ev, inst) { + if(ev.eventType == EVENT_RELEASE) { + inst.trigger(this.name, ev); + } + } }; /** - * 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 + * @module gestures */ - Edge.prototype._drawArrowCenter = function(ctx) { - var point; - // set style - ctx.strokeStyle = this._getColor(); - ctx.lineWidth = this._getLineWidth(); - - 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.options.width) * this.options.arrowScaleFactor; - // draw an arrow halfway the line - if (this.options.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); - } + /** + * triggers swipe events when the end velocity is above the threshold + * for best usage, set `preventDefault` (on the drag gesture) to `true` + * ```` + * hammertime.on("dragleft swipeleft", function(ev) { + * console.log(ev); + * ev.gesture.preventDefault(); + * }); + * ```` + * + * @class Swipe + * @static + */ + /** + * @event swipe + * @param {Object} ev + */ + /** + * @event swipeleft + * @param {Object} ev + */ + /** + * @event swiperight + * @param {Object} ev + */ + /** + * @event swipeup + * @param {Object} ev + */ + /** + * @event swipedown + * @param {Object} ev + */ + Hammer.gestures.Swipe = { + name: 'swipe', + index: 40, + defaults: { + /** + * @property swipeMinTouches + * @type {Number} + * @default 1 + */ + swipeMinTouches: 1, - ctx.arrow(point.x, point.y, angle, length); - ctx.fill(); - ctx.stroke(); + /** + * @property swipeMaxTouches + * @type {Number} + * @default 1 + */ + swipeMaxTouches: 1, - // 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.physics.springLength); - 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); + /** + * horizontal swipe velocity + * @property swipeVelocityX + * @type {Number} + * @default 0.6 + */ + swipeVelocityX: 0.6, - // draw all arrows - var angle = 0.2 * Math.PI; - var length = (10 + 5 * this.options.width) * this.options.arrowScaleFactor; - point = this._pointOnCircle(x, y, radius, 0.5); - ctx.arrow(point.x, point.y, angle, length); - ctx.fill(); - ctx.stroke(); + /** + * vertical swipe velocity + * @property swipeVelocityY + * @type {Number} + * @default 0.6 + */ + swipeVelocityY: 0.6 + }, - // draw label - if (this.label) { - point = this._pointOnCircle(x, y, radius, 0.5); - this._label(ctx, this.label, point.x, point.y); + handler: function swipeGesture(ev, inst) { + if(ev.eventType == EVENT_RELEASE) { + var touches = ev.touches.length, + options = inst.options; + + // max touches + if(touches < options.swipeMinTouches || + touches > options.swipeMaxTouches) { + return; + } + + // when the distance we moved is too small we skip this gesture + // or we can be already in dragging + if(ev.velocityX > options.swipeVelocityX || + ev.velocityY > options.swipeVelocityY) { + // trigger swipe events + inst.trigger(this.name, ev); + inst.trigger(this.name + ev.direction, ev); + } + } } - } }; - + /** + * @module gestures + */ + /** + * Single tap and a double tap on a place + * + * @class Tap + * @static + */ + /** + * @event tap + * @param {Object} ev + */ + /** + * @event doubletap + * @param {Object} ev + */ /** - * 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 + * @param {String} name */ - Edge.prototype._drawArrow = function(ctx) { - // set style - ctx.strokeStyle = this._getColor(); - ctx.lineWidth = this._getLineWidth(); + (function(name) { + var hasMoved = false; - 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); + function tapGesture(ev, inst) { + var options = inst.options, + current = Detection.current, + prev = Detection.previous, + sincePrev, + didDoubleTap; - 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; + switch(ev.eventType) { + case EVENT_START: + hasMoved = false; + break; - var via; - if (this.options.smoothCurves.dynamic == true && this.options.smoothCurves.enabled == true ) { - via = this.via; - } - else if (this.options.smoothCurves.enabled == true) { - via = this._getViaCoordinates(); - } + case EVENT_MOVE: + hasMoved = hasMoved || (ev.distance > options.tapMaxDistance); + break; - if (this.options.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; + case EVENT_END: + if(!Utils.inStr(ev.srcEvent.type, 'cancel') && ev.deltaTime < options.tapMaxTime && !hasMoved) { + // previous gesture, for the double tap since these are two different gesture detections + sincePrev = prev && prev.lastEvent && ev.timeStamp - prev.lastEvent.timeStamp; + didDoubleTap = false; - var xTo,yTo; - if (this.options.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; - } + // check if double tap + if(prev && prev.name == name && + (sincePrev && sincePrev < options.doubleTapInterval) && + ev.distance < options.doubleTapDistance) { + inst.trigger('doubletap', ev); + didDoubleTap = true; + } - ctx.beginPath(); - ctx.moveTo(xFrom,yFrom); - if (this.options.smoothCurves.enabled == true && via.x != null) { - ctx.quadraticCurveTo(via.x,via.y,xTo, yTo); - } - else { - ctx.lineTo(xTo, yTo); + // do a single tap + if(!didDoubleTap || options.tapAlways) { + current.name = name; + inst.trigger(current.name, ev); + } + } + break; + } } - ctx.stroke(); - - // draw arrow at the end of the line - length = (10 + 5 * this.options.width) * this.options.arrowScaleFactor; - ctx.arrow(xTo, yTo, angle, length); - ctx.fill(); - ctx.stroke(); - // draw label - if (this.label) { - var point; - if (this.options.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.physics.springLength); - 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(); + Hammer.gestures.Tap = { + name: name, + index: 100, + handler: tapGesture, + defaults: { + /** + * max time of a tap, this is for the slow tappers + * @property tapMaxTime + * @type {Number} + * @default 250 + */ + tapMaxTime: 250, - // draw all arrows - var length = (10 + 5 * this.options.width) * this.options.arrowScaleFactor; - ctx.arrow(arrow.x, arrow.y, arrow.angle, length); - ctx.fill(); - ctx.stroke(); + /** + * max distance of movement of a tap, this is for the slow tappers + * @property tapMaxDistance + * @type {Number} + * @default 10 + */ + tapMaxDistance: 10, - // draw label - if (this.label) { - point = this._pointOnCircle(x, y, radius, 0.5); - this._label(ctx, this.label, point.x, point.y); - } - } - }; + /** + * always trigger the `tap` event, even while double-tapping + * @property tapAlways + * @type {Boolean} + * @default true + */ + tapAlways: true, + /** + * max distance between two taps + * @property doubleTapDistance + * @type {Number} + * @default 20 + */ + doubleTapDistance: 20, + /** + * max time between two taps + * @property doubleTapInterval + * @type {Number} + * @default 300 + */ + doubleTapInterval: 300 + } + }; + })('tap'); /** - * 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 + * @module gestures */ - Edge.prototype._getDistanceToEdge = function (x1,y1, x2,y2, x3,y3) { // x3,y3 is the point - var returnValue = 0; - if (this.from != this.to) { - if (this.options.smoothCurves.enabled == true) { - var xVia, yVia; - if (this.options.smoothCurves.enabled == true && this.options.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 distance; - var i,t,x,y, lastX, lastY; - 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; - if (i > 0) { - distance = this._getDistanceToLine(lastX,lastY,x,y, x3,y3); - minDistance = distance < minDistance ? distance : minDistance; + /** + * when a touch is being touched at the page + * + * @class Touch + * @static + */ + /** + * @event touch + * @param {Object} ev + */ + Hammer.gestures.Touch = { + name: 'touch', + index: -Infinity, + defaults: { + /** + * call preventDefault at touchstart, and makes the element blocking by disabling the scrolling of the page, + * but it improves gestures like transforming and dragging. + * be careful with using this, it can be very annoying for users to be stuck on the page + * @property preventDefault + * @type {Boolean} + * @default false + */ + preventDefault: false, + + /** + * disable mouse events, so only touch (or pen!) input triggers events + * @property preventMouse + * @type {Boolean} + * @default false + */ + preventMouse: false + }, + handler: function touchGesture(ev, inst) { + if(inst.options.preventMouse && ev.pointerType == POINTER_MOUSE) { + ev.stopDetect(); + return; } - lastX = x; lastY = y; - } - returnValue = minDistance; - } - else { - returnValue = this._getDistanceToLine(x1,y1,x2,y2,x3,y3); - } - } - else { - var x, y, dx, dy; - var radius = 0.25 * this.physics.springLength; - var node = this.from; - if (node.width > node.height) { - x = node.x + 0.5 * node.width; - y = node.y - radius; - } - else { - x = node.x + radius; - y = node.y - 0.5 * node.height; - } - dx = x - x3; - dy = y - y3; - returnValue = Math.abs(Math.sqrt(dx*dx + dy*dy) - radius); - } - if (this.labelDimensions.left < x3 && - this.labelDimensions.left + this.labelDimensions.width > x3 && - this.labelDimensions.top < y3 && - this.labelDimensions.top + this.labelDimensions.height > y3) { - return 0; - } - else { - return returnValue; - } + if(inst.options.preventDefault) { + ev.preventDefault(); + } + + if(ev.eventType == EVENT_TOUCH) { + inst.trigger('touch', ev); + } + } }; - Edge.prototype._getDistanceToLine = function(x1,y1,x2,y2,x3,y3) { - var px = x2-x1, - py = y2-y1, - something = px*px + py*py, - u = ((x3 - x1) * px + (y3 - y1) * py) / something; + /** + * @module gestures + */ + /** + * User want to scale or rotate with 2 fingers + * Preventing the default browser behavior is a good way to improve feel and working. This can be done with the + * `preventDefault` option. + * + * @class Transform + * @static + */ + /** + * @event transform + * @param {Object} ev + */ + /** + * @event transformstart + * @param {Object} ev + */ + /** + * @event transformend + * @param {Object} ev + */ + /** + * @event pinchin + * @param {Object} ev + */ + /** + * @event pinchout + * @param {Object} ev + */ + /** + * @event rotate + * @param {Object} ev + */ - if (u > 1) { - u = 1; - } - else if (u < 0) { - u = 0; - } + /** + * @param {String} name + */ + (function(name) { + var triggered = false; - var x = x1 + u * px, - y = y1 + u * py, - dx = x - x3, - dy = y - y3; + function transformGesture(ev, inst) { + switch(ev.eventType) { + case EVENT_START: + triggered = false; + break; - //# 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 + case EVENT_MOVE: + // at least multitouch + if(ev.touches.length < 2) { + return; + } - return Math.sqrt(dx*dx + dy*dy); - }; + var scaleThreshold = Math.abs(1 - ev.scale); + var rotationThreshold = Math.abs(ev.rotation); - /** - * This allows the zoom level of the network to influence the rendering - * - * @param scale - */ - Edge.prototype.setScale = function(scale) { - this.networkScaleInv = 1.0/scale; - }; + // when the distance we moved is too small we skip this gesture + // or we can be already in dragging + if(scaleThreshold < inst.options.transformMinScale && + rotationThreshold < inst.options.transformMinRotation) { + return; + } + // we are transforming! + Detection.current.name = name; - Edge.prototype.select = function() { - this.selected = true; - }; + // first time, trigger dragstart event + if(!triggered) { + inst.trigger(name + 'start', ev); + triggered = true; + } - Edge.prototype.unselect = function() { - this.selected = false; - }; + inst.trigger(name, ev); // basic transform event - Edge.prototype.positionBezierNode = function() { - if (this.via !== null && this.from !== null && this.to !== null) { - this.via.x = 0.5 * (this.from.x + this.to.x); - this.via.y = 0.5 * (this.from.y + this.to.y); - } - }; + // trigger rotate event + if(rotationThreshold > inst.options.transformMinRotation) { + inst.trigger('rotate', ev); + } - /** - * 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); - } + // trigger pinch event + if(scaleThreshold > inst.options.transformMinScale) { + inst.trigger('pinch', ev); + inst.trigger('pinch' + (ev.scale < 1 ? 'in' : 'out'), ev); + } + break; - 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; + case EVENT_RELEASE: + if(triggered && ev.changedLength < 2) { + inst.trigger(name + 'end', ev); + triggered = false; + } + break; + } } - this.controlNodes.from.draw(ctx); - this.controlNodes.to.draw(ctx); - } - else { - this.controlNodes = {from:null, to:null, positions:{}}; - } - }; + Hammer.gestures.Transform = { + name: name, + index: 45, + defaults: { + /** + * minimal scale factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1 + * @property transformMinScale + * @type {Number} + * @default 0.01 + */ + transformMinScale: 0.01, - /** - * Enable control nodes. - * @private - */ - Edge.prototype._enableControlNodes = function() { - this.controlNodesEnabled = true; - }; + /** + * rotation in degrees + * @property transformMinRotation + * @type {Number} + * @default 1 + */ + transformMinRotation: 1 + }, - /** - * disable control nodes - * @private - */ - Edge.prototype._disableControlNodes = function() { - this.controlNodesEnabled = false; - }; + handler: transformGesture + }; + })('transform'); /** - * 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 + * @module hammer */ - 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 (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; - } - }; + // AMD export + if(true) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { + return Hammer; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + // commonjs export + } else if(typeof module !== 'undefined' && module.exports) { + module.exports = Hammer; + // browser export + } else { + window.Hammer = Hammer; + } + })(window); - /** - * 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(); - } - }; +/***/ }, +/* 55 */ +/***/ function(module, exports, __webpack_require__) { /** - * this calculates the position of the control nodes on the edges of the parent nodes. + * Copyright 2012 Craig Campbell * - * @param ctx - * @returns {{from: {x: number, y: number}, to: {x: *, y: *}}} + * 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 */ - 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.options.smoothCurves.dynamic == true && this.options.smoothCurves.enabled == true) { - via = this.via; - } - else if (this.options.smoothCurves.enabled == true) { - via = this._getViaCoordinates(); - } - if (this.options.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; + /** + * 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' + }, - var xTo,yTo; - if (this.options.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; - } + /** + * 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: '\'' + }, - return {from:{x:xFrom,y:yFrom},to:{x:xTo,y:yTo}}; - }; + /** + * 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', + '_': '-', + '+': '=', + ':': ';', + '\"': '\'', + '<': ',', + '>': '.', + '?': '/', + '|': '\\' + }, - module.exports = Edge; + /** + * 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' + }, -/***/ }, -/* 54 */ -/***/ function(module, exports, __webpack_require__) { + /** + * 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, - /** - * 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; - } + /** + * a list of all the callbacks setup via Mousetrap.bind() + * + * @type {Object} + */ + _callbacks = {}, - // 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' - } - } - } - } + /** + * direct map of string combinations to callbacks used for trigger() + * + * @type {Object} + */ + _direct_map = {}, - this.x = 0; - this.y = 0; - this.padding = 5; + /** + * keeps track of what level each sequence is at since multiple + * sequences can start out with the same sequence + * + * @type {Object} + */ + _sequence_levels = {}, - if (x !== undefined && y !== undefined ) { - this.setPosition(x, y); - } - if (text !== undefined) { - this.setText(text); - } + /** + * variable to store the setTimeout call + * + * @type {null|number} + */ + _reset_timer, - // 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); - } + /** + * temporary state where we will ignore the next keyup + * + * @type {boolean|string} + */ + _ignore_next_keyup = false, - /** - * @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); - }; + /** + * are we currently inside of a sequence? + * type of action ("keyup" or "keydown" or "keypress") or false + * + * @type {boolean|string} + */ + _inside_sequence = false; - /** - * Set the content for the popup window. This can be HTML code or text. - * @param {string | Element} content - */ - Popup.prototype.setText = function(content) { - if (content instanceof Element) { - this.frame.innerHTML = ''; - this.frame.appendChild(content); - } - else { - this.frame.innerHTML = content; // string containing text or HTML + /** + * 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; } - }; - /** - * Show the popup window - * @param {boolean} show Optional. Show or hide the window - */ - Popup.prototype.show = function (show) { - if (show === undefined) { - show = true; + /** + * loop through to map numbers on the numeric keypad + */ + for (i = 0; i <= 9; ++i) { + _MAP[i + 96] = i; } - 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 top = (this.y - height); - if (top + height + this.padding > maxHeight) { - top = maxHeight - height - this.padding; - } - if (top < this.padding) { - top = this.padding; - } - - var left = this.x; - if (left + width + this.padding > maxWidth) { - left = maxWidth - width - this.padding; - } - if (left < this.padding) { - left = this.padding; - } + /** + * 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); + } - this.frame.style.left = left + "px"; - this.frame.style.top = top + "px"; - this.frame.style.visibility = "visible"; - } - else { - this.hide(); + object.attachEvent('on' + type, callback); } - }; - - /** - * Hide the popup window - */ - Popup.prototype.hide = function () { - this.frame.style.visibility = "hidden"; - }; - module.exports = Popup; + /** + * takes the event and returns the key character + * + * @param {Event} e + * @return {string} + */ + function _characterFromEvent(e) { + // for keypress events we should return the character as is + if (e.type == 'keypress') { + return String.fromCharCode(e.which); + } -/***/ }, -/* 55 */ -/***/ function(module, exports, __webpack_require__) { + // for non keypress events the special maps are needed + if (_MAP[e.which]) { + return _MAP[e.which]; + } - var PhysicsMixin = __webpack_require__(56); - var ClusterMixin = __webpack_require__(60); - var SectorsMixin = __webpack_require__(61); - var SelectionMixin = __webpack_require__(62); - var ManipulationMixin = __webpack_require__(63); - var NavigationMixin = __webpack_require__(64); - var HierarchicalLayoutMixin = __webpack_require__(65); + if (_KEYCODE_MAP[e.which]) { + return _KEYCODE_MAP[e.which]; + } - /** - * 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]; - } + // 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; + + // if the element has the class "mousetrap" then no need to stop + if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) { + return false; + } + + // stop for input, select, and textarea + return tag_name == 'INPUT' || tag_name == 'SELECT' || tag_name == 'TEXTAREA' || (element.contentEditable && element.contentEditable == 'true'); + } - /** - * 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; - } + /** + * 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; - /** - * 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(); + for (key in _sequence_levels) { + if (do_not_reset[key]) { + active_sequences = true; + continue; + } + _sequence_levels[key] = 0; + } + + 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 = []; - /** - * Mixin the cluster system and initialize the parameters required. - * - * @private - */ - exports._loadClusterSystem = function () { - this.clusterSession = 0; - this.hubThreshold = 5; - this._loadMixin(ClusterMixin); - }; + // if there are no events related to this keycode + if (!_callbacks[character]) { + return []; + } + // if a modifier key is coming up on its own we should allow it + if (action == 'keyup' && _isModifier(character)) { + modifiers = [character]; + } - /** - * 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 }; + // 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]; - this.nodeIndices = this.sectors["active"]["default"]["nodeIndices"]; // the node indices list is used to speed up the computation of the repulsion fields + // 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; + } - this._loadMixin(SectorsMixin); - }; + // if the action we are looking for doesn't match the action we got + // then we should keep going + if (action != callback.action) { + continue; + } + // 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)) { - /** - * Mixin the selection system and initialize the parameters required - * - * @private - */ - exports._loadSelectionSystem = function () { - this.selectionObj = {nodes: {}, edges: {}}; + // 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._loadMixin(SelectionMixin); - }; + matches.push(callback); + } + } + return matches; + } - /** - * 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; + /** + * takes a key event and figures out what the modifiers are + * + * @param {Event} e + * @returns {Array} + */ + function _eventModifiers(e) { + var modifiers = []; - 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"; + if (e.shiftKey) { + modifiers.push('shift'); } - this.frame.appendChild(this.manipulationDiv); - } - 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"; + if (e.altKey) { + modifiers.push('alt'); } - this.frame.appendChild(this.editModeDiv); - } - 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.frame.appendChild(this.closeDiv); - } + if (e.ctrlKey) { + modifiers.push('ctrl'); + } - // load the manipulation functions - this._loadMixin(ManipulationMixin); + if (e.metaKey) { + modifiers.push('meta'); + } - // create the manipulator toolbar - this._createManipulatorBar(); + return modifiers; } - else { - if (this.manipulationDiv !== undefined) { - // removes all the bindings and overloads - this._createManipulatorBar(); - - // remove the manipulation divs - this.frame.removeChild(this.manipulationDiv); - this.frame.removeChild(this.editModeDiv); - this.frame.removeChild(this.closeDiv); - this.manipulationDiv = undefined; - this.editModeDiv = undefined; - this.closeDiv = undefined; - // remove the mixin functions - this._clearMixin(ManipulationMixin); - } - } - }; + /** + * 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(); + } - /** - * 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(); + e.returnValue = false; + e.cancelBubble = true; + } } - }; + /** + * handles a character key event + * + * @param {string} character + * @param {Event} e + * @returns void + */ + function _handleCharacter(character, e) { - /** - * Mixin the hierarchical layout system. - * - * @private - */ - exports._loadHierarchySystem = function () { - this._loadMixin(HierarchicalLayoutMixin); - }; + // 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; -/***/ }, -/* 56 */ -/***/ function(module, exports, __webpack_require__) { + // loop through matching callbacks for this key event + for (i = 0; i < callbacks.length; ++i) { - var util = __webpack_require__(1); - var RepulsionMixin = __webpack_require__(57); - var HierarchialRepulsionMixin = __webpack_require__(58); - var BarnesHutMixin = __webpack_require__(59); + // 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; - /** - * 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(); - }; + // 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); + } + } - /** - * 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); + // 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); + } + } - 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; + /** + * handles a keydown event + * + * @param {Event} e + * @returns void + */ + function _handleKey(e) { - this._loadMixin(BarnesHutMixin); - } - else if (this.constants.physics.hierarchicalRepulsion.enabled == true) { - this._clearMixin(BarnesHutMixin); - this._clearMixin(RepulsionMixin); + // 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; - 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 character = _characterFromEvent(e); - this._loadMixin(HierarchialRepulsionMixin); - } - else { - this._clearMixin(BarnesHutMixin); - this._clearMixin(HierarchialRepulsionMixin); - this.barnesHutTree = undefined; + // no character found then stop + if (!character) { + return; + } - 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; + if (e.type == 'keyup' && _ignore_next_keyup == character) { + _ignore_next_keyup = false; + return; + } - this._loadMixin(RepulsionMixin); + _handleCharacter(character, e); } - }; - /** - * 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); + /** + * 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 { - // 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); - } - // we now start the force calculation - this._calculateForces(); + /** + * 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); } - }; - - /** - * 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 + /** + * 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) { - this._calculateGravitationalForces(); - this._calculateNodeForces(); + // 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; + } - 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(); + if (_MAP.hasOwnProperty(key)) { + _REVERSE_MAP[_MAP[key]] = key; + } + } } - } + return _REVERSE_MAP; } - }; - - /** - * 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 = []; + /** + * 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) { - for (var nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - this.calculationNodes[nodeId] = this.nodes[nodeId]; + // 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'; } - } - 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); - } + + // modifier keys don't work as expected with keypress, + // switch to keydown + if (action == 'keypress' && modifiers.length) { + action = 'keydown'; } - } - for (var idx in this.calculationNodes) { - if (this.calculationNodes.hasOwnProperty(idx)) { - this.calculationNodeIndices.push(idx); - } - } - } - else { - this.calculationNodes = this.nodes; - this.calculationNodeIndices = this.nodeIndices; + return action; } - }; + /** + * 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) { - /** - * 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; + // start off by adding a sequence level record for this combination + // and setting the level to 0 + _sequence_levels[combo] = 0; - 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); + // if there is no action pick the best one for the first key + // in the sequence + if (!action) { + action = _pickBestAction(keys[0], []); + } - gravityForce = (distance == 0) ? 0 : (gravity / distance); - node.fx = dx * gravityForce; - node.fy = dy * gravityForce; - } - else { - node.fx = 0; - node.fy = 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(); + }, + /** + * 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; - /** - * 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; + // 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); + } + } - // 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.physics.springLength; - // this implies that the edges between big clusters are longer - edgeLength += (edge.to.clusterSize + edge.from.clusterSize - 2) * this.constants.clustering.edgeGrowth; + /** + * 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) { - dx = (edge.from.x - edge.to.x); - dy = (edge.from.y - edge.to.y); - distance = Math.sqrt(dx * dx + dy * dy); + // make sure multiple spaces in a row become a single space + combination = combination.replace(/\s+/g, ' '); - if (distance == 0) { - distance = 0.01; - } + var sequence = combination.split(' '), + i, + key, + keys, + modifiers = []; - // the 1/distance is so the fx and fy can be calculated without sine or cosine. - springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance; + // 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); + } - fx = dx * springForce; - fy = dy * springForce; + // take the keys from this pattern and figure out what the actual + // pattern is all about + keys = combination === '+' ? ['+'] : combination.split('+'); - edge.from.fx += fx; - edge.from.fy += fy; - edge.to.fx -= fx; - edge.to.fy -= fy; - } - } - } - } - }; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + // normalize key names + if (_SPECIAL_ALIASES[key]) { + key = _SPECIAL_ALIASES[key]; + } + // 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'); + } + // if this key is a modifier then add it to the list of modifiers + if (_isModifier(key)) { + modifiers.push(key); + } + } - /** - * 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; + // depending on what the key combination is + // we will try to pick the best event for it + action = _pickBestAction(key, modifiers, action); - // 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; + // make sure to initialize array if this is the first time + // a callback is added for this key + if (!_callbacks[key]) { + _callbacks[key] = []; + } - edgeLength = edge.physics.springLength; + // remove an existing match if there is one + _getMatches(key, modifiers, action, !sequence_name, combination); - combinedClusterSize = node1.clusterSize + node3.clusterSize - 2; + // 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 + }); + } - // 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); - } - } + /** + * 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); } - } } - }; + // start! + _addEvent(document, 'keypress', _handleKey); + _addEvent(document, 'keydown', _handleKey); + _addEvent(document, 'keyup', _handleKey); - /** - * 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; + var mousetrap = { - dx = (node1.x - node2.x); - dy = (node1.y - node2.y); - distance = Math.sqrt(dx * dx + dy * dy); + /** + * 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; + }, - if (distance == 0) { - distance = 0.01; - } + /** + * 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; + }, - // the 1/distance is so the fx and fy can be calculated without sine or cosine. - springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance; + /** + * 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; + }, - fx = dx * springForce; - fy = dy * springForce; + /** + * 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; - node1.fx += fx; - node1.fy += fy; - node2.fx -= fx; - node2.fy -= fy; - }; +/***/ }, +/* 56 */ +/***/ function(module, exports, __webpack_require__) { + /** - * Load the HTML for the physics config and bind it - * @private + * Creation of the ClusterMixin var. + * + * This contains all the functions the Network object can use to employ clustering */ - 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 = '' + - '' + - '' + - '' + - '' + - '' + - '' + - '
Simulation Mode:
Barnes HutRepulsionHierarchical
' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '
Options:
' - 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"); + /** + * 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); - 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"); + // updates the lables after clustering + this.updateLabels(); - 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"); + // 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(); + }; - 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; - } + /** + * 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 graph_toggleSmooth = document.getElementById("graph_toggleSmooth"); - var graph_repositionNodes = document.getElementById("graph_repositionNodes"); - var graph_generateOptions = document.getElementById("graph_generateOptions"); + var maxLevels = 50; + var level = 0; - 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"; + // 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 { - graph_toggleSmooth.style.background = "#FF8532"; + this.increaseClusterLevel(); // this also includes a cluster normalization } + numberOfNodes = this.nodeIndices.length; + level += 1; + } - switchConfigurations.apply(this); - - radioButton1.onchange = switchConfigurations.bind(this); - radioButton2.onchange = switchConfigurations.bind(this); - radioButton3.onchange = switchConfigurations.bind(this); + // after the clustering we reposition the nodes to reduce the initial chaos + if (level > 0 && reposition == true) { + this.repositionNodes(); } + this._updateCalculationNodes(); }; /** - * This overwrites the this.constants. + * 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 constantsVariableName - * @param value - * @private + * @param node | Node object: cluster to open. */ - exports._overWriteGraphConstants = function (constantsVariableName, value) { - var nameArray = constantsVariableName.split("_"); - if (nameArray.length == 1) { - this.constants[nameArray[0]] = value; + 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; + + // we decluster until we reach a decent number of nodes + while ((this.nodeIndices.length < this.constants.clustering.initialMaxNodes) && (level < 10)) { + this.decreaseClusterLevel(); + level += 1; + } + } - else if (nameArray.length == 2) { - this.constants[nameArray[0]][nameArray[1]] = value; + else { + this._expandClusterNode(node,false,true); + + // update the index list, dynamic edges and labels + this._updateNodeIndexList(); + this._updateDynamicEdges(); + this._updateCalculationNodes(); + this.updateLabels(); } - else if (nameArray.length == 3) { - this.constants[nameArray[0]][nameArray[1]][nameArray[2]] = value; + + // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded + if (this.moving != isMovingBeforeClustering) { + this.start(); } }; /** - * this function is bound to the toggle smooth curves button. That is also why it is not in the prototype. + * This calls the updateClustes with default arguments */ - 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";} + exports.updateClustersDefault = function() { + if (this.constants.clustering.enabled == true) { + this.updateClusters(0,false,false); + } + }; - this._configureSmoothCurves(false); - } /** - * this function is used to scramble the nodes + * 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 * */ - 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; + 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(); } } - if (this.constants.hierarchicalLayout.enabled == true) { - this._setupHierarchicalLayout(); - showValueOfRange.call(this, 'graph_H_nd', 1, "physics_hierarchicalRepulsion_nodeDistance"); - showValueOfRange.call(this, 'graph_H_cg', 1, "physics_centralGravity"); - showValueOfRange.call(this, 'graph_H_sc', 1, "physics_springConstant"); - showValueOfRange.call(this, 'graph_H_sl', 1, "physics_springLength"); - showValueOfRange.call(this, 'graph_H_damp', 1, "physics_damping"); + 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(); } - else { - this.repositionNodes(); + + // we now reduce chains. + if (this.previousScale > this.scale || zoomDirection == -1) { // zoom out + this.handleChains(); + this._updateNodeIndexList(); } - this.moving = true; - this.start(); - } + + 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(); + } + } + + this._updateCalculationNodes(); + }; /** - * this is used to generate an options file from the playing with physics system. + * This function handles the chains. It is called on every updateClusters(). */ - 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 += '};' + 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) + + } + }; + + /** + * this functions starts clustering by hubs + * The minimum hub threshold is set globally + * + * @private + */ + exports._aggregateHubs = function(force) { + this._getHubSize(); + this._formClustersByHub(force,false); + }; + + + /** + * This function is fired by keypress. It forces hubs to form. + * + */ + exports.forceAggregateHubs = function(doNotStart) { + var isMovingBeforeClustering = this.moving; + var amountOfNodes = this.nodeIndices.length; + + 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(); } } - 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 += ", " + }; + + /** + * 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); } } - 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 += ", "; + }; + + + /** + * 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(); + } + }; + + /** + * 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; + } + 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); + } + } } } - 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 += ", " + } + }; + + /** + * 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]; + + // 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(); + + // 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); + + // reconnect rerouted edges to the childNode + this._connectEdgeBackToChild(parentNode,childNode); + + // validate all edges in dynamicEdges + this._validateEdges(parentNode); + + // undo the changes from the clustering operation on the parent node + parentNode.options.mass -= childNode.options.mass; + parentNode.clusterSize -= childNode.clusterSize; + parentNode.options.fontSize = Math.min(this.constants.clustering.maxFontSize, this.constants.nodes.fontSize + this.constants.clustering.fontSizeMultiplier*(parentNode.clusterSize-1)); + 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()); + + // 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; } } - options += '}' } - else { - options += "enabled:true}"; + // if there are no others, remove the cluster session from the list + if (othersPresent == false) { + parentNode.clusterSessions.pop(); } - options += '};' + + 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); + } + }; - this.optionsDiv.innerHTML = options; - } /** - * this is used to switch between barnesHut, repulsion and hierarchical. + * position the bezier nodes at the center of the edges * + * @param node + * @private */ - 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(); - } + exports._repositionBezierNodes = function(node) { + for (var i = 0; i < node.dynamicEdges.length; i++) { + node.dynamicEdges[i].positionBezierNode(); + } + }; /** - * this generates the ranges depending on the iniital values. + * 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 * - * @param id - * @param map - * @param constantsVariableName + * @private + * @param {Boolean} force */ - function showValueOfRange (id,map,constantsVariableName) { - var valueId = id + "_value"; - var rangeValue = document.getElementById(id).value; - - if (Array.isArray(map)) { - document.getElementById(valueId).value = map[parseInt(rangeValue)]; - this._overWriteGraphConstants(constantsVariableName,map[parseInt(rangeValue)]); + exports._formClusters = function(force) { + if (force == false) { + this._formClustersByZoom(); } else { - document.getElementById(valueId).value = parseInt(map) * parseFloat(rangeValue); - this._overWriteGraphConstants(constantsVariableName, parseInt(map) * parseFloat(rangeValue)); - } - - if (constantsVariableName == "hierarchicalLayout_direction" || - constantsVariableName == "hierarchicalLayout_levelSeparation" || - constantsVariableName == "hierarchicalLayout_nodeSpacing") { - this._setupHierarchicalLayout(); + this._forceClustersByZoom(); } - this.moving = true; - this.start(); - } - + }; -/***/ }, -/* 57 */ -/***/ function(module, exports, __webpack_require__) { /** - * Calculate the forces the nodes apply on each other based on a repulsion field. - * This field is linearly approximated. + * This function handles the clustering by zooming out, this is based on a minimum edge distance * * @private */ - exports._calculateNodeForces = function () { - var dx, dy, angle, distance, fx, fy, combinedClusterSize, - repulsingForce, node1, node2, i, j; - - var nodes = this.calculationNodes; - var nodeIndices = this.calculationNodeIndices; - - // approximation constants - var a_base = -2 / 3; - var b = 4 / 3; + exports._formClustersByZoom = function() { + var dx,dy,length, + minLength = this.constants.clustering.clusterEdgeThreshold/this.scale; - // repulsing forces between nodes - var nodeDistance = this.constants.physics.repulsion.nodeDistance; - var minimumDistance = nodeDistance; + // 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); - // 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); + if (length < minLength) { + // first check which node is larger + var parentNode = edge.from; + var childNode = edge.to; + if (edge.to.options.mass > edge.from.options.mass) { + parentNode = edge.to; + childNode = edge.from; + } - 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)) + if (childNode.dynamicEdgesLength == 1) { + this._addToCluster(parentNode,childNode,false); + } + else if (parentNode.dynamicEdgesLength == 1) { + this._addToCluster(childNode,parentNode,false); + } + } } + } + } + } + }; - // amplify the repulsion for clusters. - repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification; - repulsingForce = repulsingForce / distance; + /** + * 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]; - fx = dx * repulsingForce; - fy = dy * repulsingForce; + // 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]; - node1.fx -= fx; - node1.fy -= fy; - node2.fx += fx; - node2.fy += fy; + // group to the largest node + if (childNode.id != parentNode.id) { + if (parentNode.options.mass > childNode.options.mass) { + this._addToCluster(parentNode,childNode,true); + } + else { + this._addToCluster(childNode,parentNode,true); + } + } } } } }; -/***/ }, -/* 58 */ -/***/ function(module, exports, __webpack_require__) { - /** - * Calculate the forces the nodes apply on eachother based on a repulsion field. - * This field is linearly approximated. + * 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._calculateNodeForces = function () { - var dx, dy, distance, fx, fy, - repulsingForce, node1, node2, i, j; + 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 nodes = this.calculationNodes; - var nodeIndices = this.calculationNodeIndices; - // repulsing forces between nodes - var nodeDistance = this.constants.physics.hierarchicalRepulsion.nodeDistance; + if (neighbour != null && smallestNeighbour > neighbour.clusterSessions.length) { + smallestNeighbour = neighbour.clusterSessions.length; + smallestNeighbourNode = neighbour; + } + } + } - // 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 (neighbour != null && this.nodes[neighbour.id] !== undefined) { + this._addToCluster(neighbour, node, true); + } + }; - // nodes only affect nodes on their level - if (node1.level == node2.level) { - dx = node2.x - node1.x; - dy = node2.y - node1.y; - distance = Math.sqrt(dx * dx + dy * dy); + /** + * 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); + } + } + }; + + /** + * 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); + } - var steepness = 0.05; - if (distance < nodeDistance) { - repulsingForce = -Math.pow(steepness*distance,2) + Math.pow(steepness*nodeDistance,2); - } - else { - repulsingForce = 0; - } - // normalize force with - if (distance == 0) { - distance = 0.01; - } - else { - repulsingForce = repulsingForce / distance; + // 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; + } + } } - fx = dx * repulsingForce; - fy = dy * repulsingForce; + } + } + } - node1.fx -= fx; - node1.fy -= fy; - node2.fx += fx; - node2.fy += fy; + // 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); + } + } } } } }; + /** - * this function calculates the effects of the springs in the case of unsmooth curves. + * 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._calculateHierarchicalSpringForces = function () { - var edgeLength, edge, edgeId; - var dx, dy, fx, fy, springForce, distance; - var edges = this.edges; + exports._addToCluster = function(parentNode, childNode, force) { + // join child node in the parent node + parentNode.containedNodes[childNode.id] = childNode; - var nodes = this.calculationNodes; - var nodeIndices = this.calculationNodeIndices; + // 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 = []; + // remove circular edges from clusters + this._containCircularEdgesFromNode(parentNode,childNode); - for (var i = 0; i < nodeIndices.length; i++) { - var node1 = nodes[nodeIndices[i]]; - node1.springFx = 0; - node1.springFy = 0; + + // remove the childNode from the global nodes object + delete this.nodes[childNode.id]; + + // update the properties of the child and parent + var massBefore = parentNode.options.mass; + childNode.clusterSession = this.clusterSession; + parentNode.options.mass += childNode.options.mass; + parentNode.clusterSize += childNode.clusterSize; + parentNode.options.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 + } - // 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.physics.springLength; - // this implies that the edges between big clusters are longer - edgeLength += (edge.to.clusterSize + edge.from.clusterSize - 2) * this.constants.clustering.edgeGrowth; + // recalculate the size of the node on the next time the node is rendered + parentNode.clearSizeCache(); - dx = (edge.from.x - edge.to.x); - dy = (edge.from.y - edge.to.y); - distance = Math.sqrt(dx * dx + dy * dy); + // set the pop-out scale for the childnode + parentNode.containedNodes[childNode.id].formationScale = parentNode.formationScale; - if (distance == 0) { - distance = 0.01; - } + // nullify the movement velocity of the child, this is to avoid hectic behaviour + childNode.clearVelocity(); - // the 1/distance is so the fx and fy can be calculated without sine or cosine. - springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance; + // the mass has altered, preservation of energy dictates the velocity to be updated + parentNode.updateVelocity(massBefore); - fx = dx * springForce; - fy = dy * springForce; + // restart the simulation to reorganise all nodes + this.moving = true; + }; + /** + * 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; - if (edge.to.level != edge.from.level) { - edge.to.springFx -= fx; - edge.to.springFy -= fy; - edge.from.springFx += fx; - edge.from.springFy += fy; - } - else { - var factor = 0.5; - edge.to.fx -= factor*fx; - edge.to.fy -= factor*fy; - edge.from.fx += factor*fx; - edge.from.fy += factor*fy; + // 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; } + }; - // normalize spring forces - var springForce = 1; - var springFx, springFy; - for (i = 0; i < nodeIndices.length; i++) { - var node = nodes[nodeIndices[i]]; - springFx = Math.min(springForce,Math.max(-springForce,node.springFx)); - springFy = Math.min(springForce,Math.max(-springForce,node.springFy)); - node.fx += springFx; - node.fy += springFy; + /** + * 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); - // retain energy balance - var totalFx = 0; - var totalFy = 0; - for (i = 0; i < nodeIndices.length; i++) { - var node = nodes[nodeIndices[i]]; - totalFx += node.fx; - totalFy += node.fy; + // 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; + } } - var correctionFx = totalFx / nodeIndices.length; - var correctionFy = totalFy / nodeIndices.length; + }; - for (i = 0; i < nodeIndices.length; i++) { - var node = nodes[nodeIndices[i]]; - node.fx -= correctionFx; - node.fy -= correctionFy; + /** + * 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 + + edge.originalFromId.push(childNode.id); + edge.from = parentNode; + edge.fromId = parentNode.id; + } + + 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); + }; - }; -/***/ }, -/* 59 */ -/***/ 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. + * 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._calculateNodeForces = function() { - if (this.constants.physics.barnesHut.gravitationalConstant != 0) { - var node; - var nodes = this.calculationNodes; - var nodeIndices = this.calculationNodeIndices; - var nodeCount = nodeIndices.length; - - this._formBarnesHutTree(nodes,nodeIndices); + 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; + } - var barnesHutTree = this.barnesHutTree; + // append this edge to the list of edges connecting to the childnode + childNode.dynamicEdges.push(edge); - // place the nodes one by one recursively - for (var i = 0; i < nodeCount; i++) { - node = nodes[nodeIndices[i]]; - if (node.options.mass > 0) { - // 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); + // 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]; } }; /** - * 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. + * 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 parentBranch - * @param node + * @param parentNode | Node object * @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); - - // 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.options.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); - } - 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.options.mass / (distance * distance * distance); - var fx = dx * gravityForce; - var fy = dy * gravityForce; - node.fx += fx; - node.fy += fy; - } - } + 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); } } }; + /** - * This function constructs the barnesHut tree recursively. It creates the root, splits it and starts placing the nodes. + * 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 nodes - * @param nodeIndices + * @param {Node} parentNode | + * @param {Node} childNode | * @private */ - exports._formBarnesHutTree = function(nodes,nodeIndices) { - var node; - var nodeCount = nodeIndices.length; + exports._releaseContainedEdges = function(parentNode, childNode) { + for (var i = 0; i < parentNode.containedEdges[childNode.id].length; i++) { + var edge = parentNode.containedEdges[childNode.id][i]; - var minX = Number.MAX_VALUE, - minY = Number.MAX_VALUE, - maxX =-Number.MAX_VALUE, - maxY =-Number.MAX_VALUE; + // put the edge back in the global edges object + this.edges[edge.id] = edge; - // 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 (nodes[nodeIndices[i]].options.mass > 0) { - if (x < minX) { minX = x; } - if (x > maxX) { maxX = x; } - if (y < minY) { minY = y; } - if (y > maxY) { maxY = y; } - } + // put the edge back in the dynamic edges of the child and parent + childNode.dynamicEdges.push(edge); + parentNode.dynamicEdges.push(edge); } - // 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 + // remove the entry from the contained edges + delete parentNode.containedEdges[childNode.id]; + }; - 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._splitBranch(barnesHutTree.root); - // place the nodes one by one recursively - for (i = 0; i < nodeCount; i++) { - node = nodes[nodeIndices[i]]; - if (node.options.mass > 0) { - this._placeInTree(barnesHutTree.root,node); - } - } - // make global - this.barnesHutTree = barnesHutTree - }; + // ------------------- UTILITY FUNCTIONS ---------------------------- // /** - * this updates the mass of a branch. this is increased by adding a node. - * - * @param parentBranch - * @param node - * @private + * This updates the node labels for all nodes (for debugging purposes) */ - exports._updateBranchMass = function(parentBranch, node) { - var totalMass = parentBranch.mass + node.options.mass; - var totalMassInv = 1/totalMass; - - parentBranch.centerOfMass.x = parentBranch.centerOfMass.x * parentBranch.mass + node.x * node.options.mass; - parentBranch.centerOfMass.x *= totalMassInv; + 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),"]"); + } + } + } - parentBranch.centerOfMass.y = parentBranch.centerOfMass.y * parentBranch.mass + node.y * node.options.mass; - parentBranch.centerOfMass.y *= totalMassInv; + // 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); + } + } + } + } - parentBranch.mass = totalMass; - var biggestSize = Math.max(Math.max(node.height,node.radius),node.width); - parentBranch.maxWidth = (parentBranch.maxWidth < biggestSize) ? biggestSize : parentBranch.maxWidth; + // /* Debug Override */ + // for (nodeId in this.nodes) { + // if (this.nodes.hasOwnProperty(nodeId)) { + // node = this.nodes[nodeId]; + // node.label = String(node.level); + // } + // } }; /** - * determine in which branch the node will be placed. - * - * @param parentBranch - * @param node - * @param skipMassUpdate - * @private + * 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._placeInTree = function(parentBranch,node,skipMassUpdate) { - if (skipMassUpdate != true || skipMassUpdate === undefined) { - // update the mass of the branch. - this._updateBranchMass(parentBranch,node); - } + exports.normalizeClusterLevels = function() { + var maxLevel = 0; + var minLevel = 1e9; + var clusterLevel = 0; + var nodeId; - 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"); - } - else { // in SW - this._placeInRegion(parentBranch,node,"SW"); + // 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;} } } - else { // in NE or SE - if (parentBranch.children.NW.range.maxY > node.y) { // in NE - this._placeInRegion(parentBranch,node,"NE"); + + 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]); + } + } } - else { // in SE - this._placeInRegion(parentBranch,node,"SE"); + this._updateNodeIndexList(); + this._updateDynamicEdges(); + // if a cluster was formed, we increase the clusterSession + if (this.nodeIndices.length != amountOfNodes) { + this.clusterSession += 1; } } }; + /** - * actually place the node in a region (or branch) + * This function determines if the cluster we want to decluster is in the active area + * this means around the zoom center * - * @param parentBranch - * @param node - * @param region + * @param {Node} node + * @returns {boolean} * @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; - } + 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 + ) }; /** - * 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. + * 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. * - * @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.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.options.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); + } } }; /** - * This function subdivides the region into four new segments. - * Specifically, this inserts a single new segment. - * It fills the children section of the parentBranch + * 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%) * - * @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; - } + exports._getHubSize = function() { + var average = 0; + var averageSquared = 0; + var hubCounter = 0; + var largestHub = 0; + for (var i = 0; i < this.nodeIndices.length; i++) { - 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 - }; - }; + 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 variance = averageSquared - Math.pow(average,2); - /** - * 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 standardDeviation = Math.sqrt(variance); - ctx.lineWidth = 1; + this.hubThreshold = Math.floor(average + 2*standardDeviation); - this._drawBranch(this.barnesHutTree.root,ctx,color); + // always have at least one to cluster + if (this.hubThreshold > largestHub) { + this.hubThreshold = largestHub; } + + // console.log("average",average,"averageSQ",averageSquared,"var",variance,"std",standardDeviation); + // console.log("hubThreshold:",this.hubThreshold); }; /** - * This function is for debugging purposes. It draws the branches recursively. + * 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 branch - * @param ctx - * @param color + * @param {Number} fraction | between 0 and 1, the percentage of chains to reduce * @private */ - exports._drawBranch = function(branch,ctx,color) { - if (color === undefined) { - color = "#FF0000"; - } - - 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); + 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; + } + } + } } - ctx.strokeStyle = color; - ctx.beginPath(); - ctx.moveTo(branch.range.minX,branch.range.minY); - ctx.lineTo(branch.range.maxX,branch.range.minY); - ctx.stroke(); - - 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(); - } - */ + /** + * 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 chains/total; }; /***/ }, -/* 60 */ +/* 57 */ /***/ function(module, exports, __webpack_require__) { + var util = __webpack_require__(1); + var Node = __webpack_require__(39); + /** - * Creation of the ClusterMixin var. + * Creation of the SectorMixin var. * - * This contains all the functions the Network object can use to employ clustering + * 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 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(); - - // 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(); + * 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; }; + /** - * This function clusters until the initialMaxNodes has been reached + * /** + * 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 {Number} maxNumberOfNodes - * @param {Boolean} reposition + * @param {String} sectorId + * @param {String} [sectorType] | "active" or "frozen" + * @private */ - exports.clusterToFit = function(maxNumberOfNodes, reposition) { - var numberOfNodes = this.nodeIndices.length; - - var maxLevels = 50; - var level = 0; - - // 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 - } - - numberOfNodes = this.nodeIndices.length; - level += 1; + exports._switchToSector = function(sectorId, sectorType) { + if (sectorType === undefined || sectorType == "active") { + this._switchToActiveSector(sectorId); } - - // after the clustering we reposition the nodes to reduce the initial chaos - if (level > 0 && reposition == true) { - this.repositionNodes(); + else { + this._switchToFrozenSector(sectorId); } - this._updateCalculationNodes(); }; + /** - * This function can be called to open up a specific cluster. It is only called by - * It will unpack the cluster back one level. + * This function sets the global references to nodes, edges and nodeIndices back to + * those of the supplied active sector. * - * @param node | Node object: cluster to open. + * @param sectorId + * @private */ - 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; - - // we decluster until we reach a decent number of nodes - while ((this.nodeIndices.length < this.constants.clustering.initialMaxNodes) && (level < 10)) { - this.decreaseClusterLevel(); - level += 1; - } - - } - else { - this._expandClusterNode(node,false,true); - - // 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(); - } + 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"]; }; /** - * This calls the updateClustes with default arguments + * This function sets the global references to nodes, edges and nodeIndices back to + * those of the supplied active sector. + * + * @private */ - exports.updateClustersDefault = function() { - if (this.constants.clustering.enabled == true) { - this.updateClusters(0,false,false); - } + exports._switchToSupportSector = function() { + this.nodeIndices = this.sectors["support"]["nodeIndices"]; + this.nodes = this.sectors["support"]["nodes"]; + this.edges = this.sectors["support"]["edges"]; }; /** - * 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. + * This function sets the global references to nodes, edges and nodeIndices back to + * those of the supplied frozen sector. + * + * @param sectorId + * @private */ - exports.increaseClusterLevel = function() { - this.updateClusters(-1,false,true); + 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 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. + * This function sets the global references to nodes, edges and nodeIndices back to + * those of the currently active sector. + * + * @private */ - exports.decreaseClusterLevel = function() { - this.updateClusters(1,false,true); + exports._loadLatestSector = function() { + this._switchToSector(this._sector()); }; /** - * 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 + * This function returns the currently active sector Id * + * @returns {String} + * @private */ - exports.updateClusters = function(zoomDirection,recursive,force,doNotStart) { - var isMovingBeforeClustering = this.moving; - var amountOfNodes = this.nodeIndices.length; + exports._sector = function() { + return this.activeSector[this.activeSector.length-1]; + }; - // 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); + /** + * 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 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(); - } + else { + throw new TypeError('there are not enough sectors in the this.activeSector array.'); } - 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(); - } + /** + * 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); + }; - this.previousScale = this.scale; - // rest of the update the index list, dynamic edges and labels - this._updateDynamicEdges(); - this.updateLabels(); + /** + * 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(); + }; - // 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(); - } - } + /** + * 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}; - this._updateCalculationNodes(); + // 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; }; + /** - * This function handles the chains. It is called on every updateClusters(). + * 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.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) - - } + exports._deleteActiveSector = function(sectorId) { + delete this.sectors["active"][sectorId]; }; + /** - * this functions starts clustering by hubs - * The minimum hub threshold is set globally + * 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._aggregateHubs = function(force) { - this._getHubSize(); - this._formClustersByHub(force,false); + exports._deleteFrozenSector = function(sectorId) { + delete this.sectors["frozen"][sectorId]; }; /** - * This function is fired by keypress. It forces hubs to form. + * 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.forceAggregateHubs = function(doNotStart) { - var isMovingBeforeClustering = this.moving; - var amountOfNodes = this.nodeIndices.length; + exports._freezeSector = function(sectorId) { + // we move the set references from the active to the frozen stack. + this.sectors["frozen"][sectorId] = this.sectors["active"][sectorId]; - this._aggregateHubs(true); + // we have moved the sector data into the frozen set, we now remove it from the active set + this._deleteActiveSector(sectorId); + }; - // 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; - } + /** + * 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]; - 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(); - } - } + // we have moved the sector data into the active set, we now remove it from the frozen stack + this._deleteFrozenSector(sectorId); }; + /** - * If a cluster takes up more than a set percentage of the screen, open the cluster + * 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._openClustersBySize = function() { + exports._mergeThisWithFrozen = function(sectorId) { + // copy all nodes 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); - } - } + this.sectors["frozen"][sectorId]["nodes"][nodeId] = this.nodes[nodeId]; } } - }; + // 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]; + } + } - /** - * 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) { + // merge the nodeIndices for (var i = 0; i < this.nodeIndices.length; i++) { - var node = this.nodes[this.nodeIndices[i]]; - this._expandClusterNode(node,recursive,force); - this._updateCalculationNodes(); + this.sectors["frozen"][sectorId]["nodeIndices"].push(this.nodeIndices[i]); } }; + /** - * 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. + * 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. * - * @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; - } - 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); - } - } - } - } - } - } + exports._collapseThisToSingleCluster = function() { + this.clusterToFit(1,false); }; + /** - * 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. + * We create a new active sector from the node that we want to open. * - * @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 + * @param node * @private */ - exports._expelChildFromParent = function(parentNode, containedNodeId, recursive, force, openAll) { - var childNode = parentNode.containedNodes[containedNodeId]; + exports._addSector = function(node) { + // this is the currently active sector + var sector = this._sector(); - // 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(); + // // 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!!"); + // } - // put the child node back in the global nodes object - this.nodes[containedNodeId] = childNode; + // 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]; - // release the contained edges from this childNode back into the global edges - this._releaseContainedEdges(parentNode,childNode); + var unqiueIdentifier = util.randomUUID(); - // reconnect rerouted edges to the childNode - this._connectEdgeBackToChild(parentNode,childNode); + // we fully freeze the currently active sector + this._freezeSector(sector); - // validate all edges in dynamicEdges - this._validateEdges(parentNode); + // we create a new active sector. This sector has the Id of the node to ensure uniqueness + this._createNewSector(unqiueIdentifier); - // undo the changes from the clustering operation on the parent node - parentNode.options.mass -= childNode.options.mass; - parentNode.clusterSize -= childNode.clusterSize; - parentNode.options.fontSize = Math.min(this.constants.clustering.maxFontSize, this.constants.nodes.fontSize + this.constants.clustering.fontSizeMultiplier*(parentNode.clusterSize-1)); - parentNode.dynamicEdgesLength = parentNode.dynamicEdges.length; + // we add the active sector to the sectors array to be able to revert these steps later on + this._setActiveSector(unqiueIdentifier); + + // 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; + }; + + + /** + * 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(); - // 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()); + // we collapse the sector back to a single cluster + this._collapseThisToSingleCluster(); - // remove node from the list - delete parentNode.containedNodes[containedNodeId]; + // we move the remaining nodes, edges and nodeIndices to the previous sector. + // This previous sector is the one we will reactivate + this._mergeThisWithFrozen(previousSector); - // 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(); - } + // 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); - this._repositionBezierNodes(childNode); - // this._repositionBezierNodes(parentNode); + // we activate the previously active (and currently frozen) sector. + this._activateSector(previousSector); - // remove the clusterSession from the child node - childNode.clusterSession = 0; + // we load the references from the newly active sector into the global references + this._switchToSector(previousSector); - // recalculate the size of the node on the next time the node is rendered - parentNode.clearSizeCache(); + // we forget the previously active sector because we reverted to the one before + this._forgetLastSector(); - // restart the simulation to reorganise all nodes - this.moving = true; - } + // finally, we update the node index list. + this._updateNodeIndexList(); - // check if a further expansion step is possible if recursivity is enabled - if (recursive == true) { - this._expandClusterNode(childNode,recursive,force,openAll); + // we refresh the list with calulation nodes and calculation node indices. + this._updateCalculationNodes(); + } } }; /** - * position the bezier nodes at the center of the edges + * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation(). * - * @param node + * @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._repositionBezierNodes = function(node) { - for (var i = 0; i < node.dynamicEdges.length; i++) { - node.dynamicEdges[i].positionBezierNode(); + exports._doInAllActiveSectors = function(runFunction,argument) { + var returnValues = []; + 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); + returnValues.push( 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) { + returnValues.push( this[runFunction](args[0],args[1]) ); + } + else { + returnValues.push( this[runFunction](argument) ); + } + } + } } + // we revert the global references back to our active sector + this._loadLatestSector(); + return returnValues; }; /** - * 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 + * 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 - * @param {Boolean} force */ - exports._formClusters = function(force) { - if (force == false) { - this._formClustersByZoom(); + exports._doInSupportSector = function(runFunction,argument) { + var returnValues = false; + if (argument === undefined) { + this._switchToSupportSector(); + returnValues = this[runFunction](); } else { - this._forceClustersByZoom(); + this._switchToSupportSector(); + var args = Array.prototype.splice.call(arguments, 1); + if (args.length > 1) { + returnValues = this[runFunction](args[0],args[1]); + } + else { + returnValues = this[runFunction](argument); + } } + // we revert the global references back to our active sector + this._loadLatestSector(); + return returnValues; }; /** - * This function handles the clustering by zooming out, this is based on a minimum edge distance + * 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._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.options.mass > edge.from.options.mass) { - parentNode = edge.to; - childNode = edge.from; - } - - if (childNode.dynamicEdgesLength == 1) { - this._addToCluster(parentNode,childNode,false); - } - else if (parentNode.dynamicEdgesLength == 1) { - this._addToCluster(childNode,parentNode,false); - } - } + 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(); }; + /** - * This function forces the network to cluster all nodes with only one connecting edge to their - * connected node. + * 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._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.options.mass > childNode.options.mass) { - this._addToCluster(parentNode,childNode,true); - } - else { - this._addToCluster(childNode,parentNode,true); - } - } - } + 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); } } }; /** - * To keep the nodes of roughly equal size we normalize the cluster levels. - * This function clusters a node to its smallest connected neighbour. + * 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. * - * @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; - } + exports._clearNodeIndexList = function() { + var sector = this._sector(); + this.sectors["active"][sector]["nodeIndices"] = []; + this.nodeIndices = this.sectors["active"][sector]["nodeIndices"]; + }; - if (neighbour != null && smallestNeighbour > neighbour.clusterSessions.length) { - smallestNeighbour = neighbour.clusterSessions.length; - smallestNeighbourNode = neighbour; + /** + * 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;} + } + } + 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.options.radius = Math.sqrt(Math.pow(0.5*node.width,2) + Math.pow(0.5*node.height,2)); + node.setScale(this.scale); + node._drawCircle(ctx); } } } + }; - if (neighbour != null && this.nodes[neighbour.id] !== undefined) { - this._addToCluster(neighbour, node, true); - } + exports._drawAllSectorNodes = function(ctx) { + this._drawSectorNodes(ctx,"frozen"); + this._drawSectorNodes(ctx,"active"); + this._loadLatestSector(); }; +/***/ }, +/* 58 */ +/***/ function(module, exports, __webpack_require__) { + + var Node = __webpack_require__(39); + /** - * This function forms clusters from hubs, it loops over all nodes + * This function can be called from the _doInAllSectors function * - * @param {Boolean} force | Disregard zoom level - * @param {Boolean} onlyEqual | This only clusters a hub with a specific number of edges + * @param object + * @param overlappingNodes * @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); + 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); + } } } }; /** - * This function forms a cluster from a specific preselected hub node + * 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; + }; + + + /** + * Return a position object in canvasspace from a single point in screenspace * - * @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] | + * @param pointer + * @returns {{left: number, top: number, right: number, bottom: number}} * @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; + exports._pointerToPositionObject = function(pointer) { + var x = this._XconvertDOMtoCanvas(pointer.x); + var y = this._YconvertDOMtoCanvas(pointer.y); - // 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); - } + return { + left: x, + top: y, + right: x, + bottom: y + }; + }; - // 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; - } - } - } - } - } - } + /** + * 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); - // 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); - } - } + // 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; + } + }; + + + /** + * 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); } } } }; + /** + * 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; + }; /** - * This function adds the child node to the parent node, creating a cluster if it is not already. + * 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 {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 + * @param pointer + * @returns {null} * @private */ - exports._addToCluster = function(parentNode, childNode, force) { - // join child node in the parent node - parentNode.containedNodes[childNode.id] = childNode; + exports._getEdgeAt = function(pointer) { + var positionObject = this._pointerToPositionObject(pointer); + var overlappingEdges = this._getAllEdgesOverlappingWith(positionObject); - // 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); - } + if (overlappingEdges.length > 0) { + return this.edges[overlappingEdges[overlappingEdges.length - 1]]; } - // 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]; + else { + return null; + } + }; - // update the properties of the child and parent - var massBefore = parentNode.options.mass; - childNode.clusterSession = this.clusterSession; - parentNode.options.mass += childNode.options.mass; - parentNode.clusterSize += childNode.clusterSize; - parentNode.options.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); + /** + * 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; } + }; - // 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; + /** + * Add object to the selection array. + * + * @param obj + * @private + */ + exports._addToHover = function(obj) { + if (obj instanceof Node) { + this.hoverObj.nodes[obj.id] = obj; } else { - parentNode.formationScale = this.scale; // The latest child has been added on this scale + this.hoverObj.edges[obj.id] = obj; } - - // recalculate the size of the node on the next time the node is rendered - parentNode.clearSizeCache(); - - // 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(); - - // the mass has altered, preservation of energy dictates the velocity to be updated - parentNode.updateVelocity(massBefore); - - // restart the simulation to reorganise all nodes - this.moving = true; }; /** - * 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(). + * Remove a single option from selection. + * + * @param {Object} obj * @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; + exports._removeFromSelection = function(obj) { + if (obj instanceof Node) { + delete this.selectionObj.nodes[obj.id]; + } + else { + delete this.selectionObj.edges[obj.id]; } }; - /** - * This adds an edge from the childNode to the contained edges of the parent node + * Unselect all. The selectionObj is useful for this. * - * @param parentNode | Node object - * @param childNode | Node object - * @param edge | Edge object + * @param {Boolean} [doNotTrigger] | ignore trigger * @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] = [] + 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(); + } + } + for(var edgeId in this.selectionObj.edges) { + if(this.selectionObj.edges.hasOwnProperty(edgeId)) { + this.selectionObj.edges[edgeId].unselect(); + } } - // add this edge to the list - parentNode.containedEdges[childNode.id].push(edge); - // remove the edge from the global edges object - delete this.edges[edge.id]; + this.selectionObj = {nodes:{},edges:{}}; - // 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; - } + if (doNotTrigger == false) { + this.emit('select', this.getSelection()); } }; /** - * 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. + * Unselect all clusters. The selectionObj is useful for this. * - * @param {Node} parentNode | Node object - * @param {Node} childNode | Node object - * @param {Edge} edge | Edge object + * @param {Boolean} [doNotTrigger] | ignore trigger * @private */ - exports._connectEdgeToCluster = function(parentNode, childNode, edge) { - // handle circular edges - if (edge.toId == edge.fromId) { - this._addToContainedEdges(parentNode, childNode, edge); + exports._unselectClusters = function(doNotTrigger) { + if (doNotTrigger === undefined) { + doNotTrigger = false; } - 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 - edge.originalFromId.push(childNode.id); - edge.from = parentNode; - edge.fromId = parentNode.id; + 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]); + } } + } - this._addToReroutedEdges(parentNode,childNode,edge); + if (doNotTrigger == false) { + this.emit('select', this.getSelection()); } }; /** - * If a node is connected to itself, a circular edge is drawn. When clustering we want to contain - * these edges inside of the cluster. + * return the number of selected nodes * - * @param parentNode - * @param childNode + * @returns {number} * @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); + exports._getSelectedNodeCount = function() { + var count = 0; + for (var nodeId in this.selectionObj.nodes) { + if (this.selectionObj.nodes.hasOwnProperty(nodeId)) { + count += 1; } } + return count; }; - /** - * This adds an edge from the childNode to the rerouted edges of the parent node + * return the selected node * - * @param parentNode | Node object - * @param childNode | Node object - * @param edge | Edge object + * @returns {number} * @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] = []; + exports._getSelectedNode = function() { + for (var nodeId in this.selectionObj.nodes) { + if (this.selectionObj.nodes.hasOwnProperty(nodeId)) { + return this.selectionObj.nodes[nodeId]; + } } - parentNode.reroutedEdges[childNode.id].push(edge); - - // this edge becomes part of the dynamicEdges of the cluster node - parentNode.dynamicEdges.push(edge); - }; - - + return null; + }; /** - * This function connects an edge that was connected to a cluster node back to the child node. + * return the selected edge * - * @param parentNode | Node object - * @param childNode | Node object + * @returns {number} * @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); - - // 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; - } - } + exports._getSelectedEdge = function() { + for (var edgeId in this.selectionObj.edges) { + if (this.selectionObj.edges.hasOwnProperty(edgeId)) { + return this.selectionObj.edges[edgeId]; } - // remove the entry from the rerouted edges - delete parentNode.reroutedEdges[childNode.id]; } + return null; }; /** - * 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 + * return the number of selected edges * - * @param parentNode | Node object + * @returns {number} * @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); + exports._getSelectedEdgeCount = function() { + var count = 0; + for (var edgeId in this.selectionObj.edges) { + if (this.selectionObj.edges.hasOwnProperty(edgeId)) { + count += 1; } } + return count; }; /** - * This function released the contained edges back into the global domain and puts them back into the - * dynamic edges of both parent and child. + * return the number of selected objects. * - * @param {Node} parentNode | - * @param {Node} childNode | + * @returns {number} * @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); + exports._getSelectedObjectCount = function() { + var count = 0; + for(var nodeId in this.selectionObj.nodes) { + if(this.selectionObj.nodes.hasOwnProperty(nodeId)) { + count += 1; + } } - // remove the entry from the contained edges - delete parentNode.containedEdges[childNode.id]; - + for(var edgeId in this.selectionObj.edges) { + if(this.selectionObj.edges.hasOwnProperty(edgeId)) { + count += 1; + } + } + return count; }; - - - - // ------------------- UTILITY FUNCTIONS ---------------------------- // - - /** - * This updates the node labels for all nodes (for debugging purposes) + * Check if anything is selected + * + * @returns {boolean} + * @private */ - 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),"]"); - } + exports._selectionIsEmpty = function() { + for(var nodeId in this.selectionObj.nodes) { + if(this.selectionObj.nodes.hasOwnProperty(nodeId)) { + 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; - } - else { - node.label = String(node.id); - } - } + for(var edgeId in this.selectionObj.edges) { + if(this.selectionObj.edges.hasOwnProperty(edgeId)) { + return false; } } - - // /* Debug Override */ - // for (nodeId in this.nodes) { - // if (this.nodes.hasOwnProperty(nodeId)) { - // node = this.nodes[nodeId]; - // node.label = String(node.level); - // } - // } - + return true; }; /** - * 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. + * check if one of the selected nodes is a cluster. + * + * @returns {boolean} + * @private */ - exports.normalizeClusterLevels = function() { - var maxLevel = 0; - var minLevel = 1e9; - var clusterLevel = 0; - var nodeId; - - // 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;} - } - } - - 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]); - } + 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; } } - this._updateNodeIndexList(); - this._updateDynamicEdges(); - // if a cluster was formed, we increase the clusterSession - if (this.nodeIndices.length != amountOfNodes) { - this.clusterSession += 1; - } } + return false; }; - - /** - * This function determines if the cluster we want to decluster is in the active area - * this means around the zoom center + * select the edges connected to the node that is being selected * * @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 - ) + exports._selectConnectedEdges = function(node) { + for (var i = 0; i < node.dynamicEdges.length; i++) { + var edge = node.dynamicEdges[i]; + edge.select(); + this._addToSelection(edge); + } }; - /** - * 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. + * select the edges connected to the node that is being selected * + * @param {Node} node + * @private */ - 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.options.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); - } + exports._hoverConnectedEdges = function(node) { + for (var i = 0; i < node.dynamicEdges.length; i++) { + var edge = node.dynamicEdges[i]; + edge.hover = true; + this._addToHover(edge); } }; /** - * 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%) + * unselect the edges connected to the node that is being selected * + * @param {Node} node * @private */ - exports._getHubSize = function() { - var average = 0; - var averageSquared = 0; - var hubCounter = 0; - var largestHub = 0; + exports._unselectConnectedEdges = function(node) { + for (var i = 0; i < node.dynamicEdges.length; i++) { + var edge = node.dynamicEdges[i]; + edge.unselect(); + this._removeFromSelection(edge); + } + }; - for (var i = 0; i < this.nodeIndices.length; i++) { - 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 variance = averageSquared - Math.pow(average,2); - var standardDeviation = Math.sqrt(variance); + /** + * 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, overrideSelectable) { + if (doNotTrigger === undefined) { + doNotTrigger = false; + } + if (highlightEdges === undefined) { + highlightEdges = true; + } - this.hubThreshold = Math.floor(average + 2*standardDeviation); + if (this._selectionIsEmpty() == false && append == false && this.forceAppendSelection == false) { + this._unselectAll(true); + } - // always have at least one to cluster - if (this.hubThreshold > largestHub) { - this.hubThreshold = largestHub; + // selectable allows the object to be selected. Override can be used if needed to bypass this. + if (object.selected == false && (this.constants.selectable == true || overrideSelectable)) { + object.select(); + this._addToSelection(object); + if (object instanceof Node && this.blockConnectingEdgeSelection == false && highlightEdges == true) { + this._selectConnectedEdges(object); + } + } + // do not select the object if selectable is false, only add it to selection to allow drag to work + else if (object.selected == false) { + this._addToSelection(object); + doNotTrigger = true; + } + else { + object.unselect(); + this._removeFromSelection(object); } - // console.log("average",average,"averageSQ",averageSquared,"var",variance,"std",standardDeviation); - // console.log("hubThreshold:",this.hubThreshold); + if (doNotTrigger == false) { + this.emit('select', this.getSelection()); + } }; /** - * 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. + * 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 {Number} fraction | between 0 and 1, the percentage of chains to reduce + * @param {Node || Edge} object * @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; - } - } - } + exports._blurObject = function(object) { + if (object.hover == true) { + object.hover = false; + this.emit("blurNode",{node:object.id}); } }; /** - * 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. + * 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._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; + exports._hoverObject = function(object) { + if (object.hover == false) { + object.hover = true; + this._addToHover(object); + if (object instanceof Node) { + this.emit("hoverNode",{node:object.id}); } } - return chains/total; - }; - - -/***/ }, -/* 61 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(1); - var Node = __webpack_require__(52); + if (object instanceof Node) { + this._hoverConnectedEdges(object); + } + }; - /** - * 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. + * 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._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; + exports._handleTouch = function(pointer) { }; /** - * /** - * 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 + * handles the selection part of the tap; * - * @param {String} sectorId - * @param {String} [sectorType] | "active" or "frozen" + * @param {Object} pointer * @private */ - exports._switchToSector = function(sectorId, sectorType) { - if (sectorType === undefined || sectorType == "active") { - this._switchToActiveSector(sectorId); + exports._handleTap = function(pointer) { + var node = this._getNodeAt(pointer); + if (node != null) { + this._selectObject(node, false); } else { - this._switchToFrozenSector(sectorId); + var edge = this._getEdgeAt(pointer); + if (edge != null) { + this._selectObject(edge, false); + } + else { + this._unselectAll(); + } } + this.emit("click", this.getSelection()); + this._redraw(); }; /** - * This function sets the global references to nodes, edges and nodeIndices back to - * those of the supplied active sector. + * handles the selection part of the double tap and opens a cluster if needed * - * @param sectorId + * @param {Object} pointer * @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"]; + 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()); }; /** - * This function sets the global references to nodes, edges and nodeIndices back to - * those of the supplied active sector. + * Handle the onHold selection part * + * @param pointer * @private */ - exports._switchToSupportSector = function() { - this.nodeIndices = this.sectors["support"]["nodeIndices"]; - this.nodes = this.sectors["support"]["nodes"]; - this.edges = this.sectors["support"]["edges"]; + 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(); }; /** - * This function sets the global references to nodes, edges and nodeIndices back to - * those of the supplied frozen sector. + * handle the onRelease event. These functions are here for the navigation controls module + * and data manipulation module. * - * @param sectorId - * @private + * @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"]; + exports._handleOnRelease = function(pointer) { + this._manipulationReleaseOverload(pointer); + this._navigationReleaseOverload(pointer); }; + exports._manipulationReleaseOverload = function (pointer) {}; + exports._navigationReleaseOverload = function (pointer) {}; /** - * This function sets the global references to nodes, edges and nodeIndices back to - * those of the currently active sector. * - * @private + * retrieve the currently selected objects + * @return {{nodes: Array., edges: Array.}} selection */ - exports._loadLatestSector = function() { - this._switchToSector(this._sector()); + exports.getSelection = function() { + var nodeIds = this.getSelectedNodes(); + var edgeIds = this.getSelectedEdges(); + return {nodes:nodeIds, edges:edgeIds}; }; - /** - * This function returns the currently active sector Id * - * @returns {String} - * @private + * retrieve the currently selected nodes + * @return {String[]} selection An array with the ids of the + * selected nodes. */ - exports._sector = function() { - return this.activeSector[this.activeSector.length-1]; + exports.getSelectedNodes = function() { + var idArray = []; + if (this.constants.selectable == true) { + for (var nodeId in this.selectionObj.nodes) { + if (this.selectionObj.nodes.hasOwnProperty(nodeId)) { + idArray.push(nodeId); + } + } + } + return idArray }; - /** - * This function returns the previously active sector Id * - * @returns {String} - * @private + * retrieve the currently selected edges + * @return {Array} selection An array with the ids of the + * selected nodes. */ - 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.'); + exports.getSelectedEdges = function() { + var idArray = []; + if (this.constants.selectable == true) { + for (var edgeId in this.selectionObj.edges) { + if (this.selectionObj.edges.hasOwnProperty(edgeId)) { + idArray.push(edgeId); + } + } } + return idArray; }; /** - * 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 + * select zero or more nodes DEPRICATED + * @param {Number[] | String[]} selection An array with the ids of the + * selected nodes. */ - exports._setActiveSector = function(newId) { - this.activeSector.push(newId); + exports.setSelection = function() { + console.log("setSelection is deprecated. Please use selectNodes instead.") }; /** - * We remove the currently active sector id from the active sector stack. This happens when - * we reactivate the previously active sector - * - * @private + * 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._forgetLastSector = function() { - this.activeSector.pop(); + exports.selectNodes = function(selection, highlightEdges) { + var i, iMax, id; + + if (!selection || (selection.length == undefined)) + throw 'Selection must be an array with ids'; + + // 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'); + } + this._selectObject(node,true,true,highlightEdges,true); + } + this.redraw(); }; /** - * 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 + * select zero or more edges + * @param {Number[] | String[]} selection An array with the ids of the + * selected nodes. */ - exports._createNewSector = function(newId) { - // create the new sector - this.sectors["active"][newId] = {"nodes":{}, - "edges":{}, - "nodeIndices":[], - "formationScale": this.scale, - "drawingNode": undefined}; + exports.selectEdges = function(selection) { + var i, iMax, id; - // 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; - }; + if (!selection || (selection.length == undefined)) + throw 'Selection must be an array with ids'; + + // 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,false,true); + } + this.redraw(); + }; /** - * 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 + * Validate the selection: remove ids of nodes which no longer exist * @private */ - exports._deleteActiveSector = function(sectorId) { - delete this.sectors["active"][sectorId]; + 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]; + } + } + } }; +/***/ }, +/* 59 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var Node = __webpack_require__(39); + var Edge = __webpack_require__(36); + /** - * This function removes the currently active sector. This is called when we reactivate - * the previously active sector. + * clears the toolbar div element of children * - * @param {String} sectorId | Id of the active sector that will be removed * @private */ - exports._deleteFrozenSector = function(sectorId) { - delete this.sectors["frozen"][sectorId]; - }; + exports._clearManipulatorBar = function() { + while (this.manipulationDiv.hasChildNodes()) { + this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); + } + this._manipulationReleaseOverload = function () {}; + delete this.sectors['support']['nodes']['targetNode']; + delete this.sectors['support']['nodes']['targetViaNode']; + this.controlNodesActive = false; + }; /** - * Freezing an active sector means moving it from the "active" object to the "frozen" object. - * We copy the references, then delete the active entree. + * 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. * - * @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); + exports._restoreOverloadedFunctions = function() { + for (var functionName in this.cachedFunctions) { + if (this.cachedFunctions.hasOwnProperty(functionName)) { + this[functionName] = this.cachedFunctions[functionName]; + } + } }; - /** - * This is the reverse operation of _freezeSector. Activating means moving the sector from the "frozen" - * object to the "active" object. + * Enable or disable edit-mode. * - * @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); + 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() }; - /** - * 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. + * main function, creates the main toolbar. Removes functions bound to the select event. Binds all the buttons of the toolbar. * - * @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]; - } + exports._createManipulatorBar = function() { + // remove bound functions + if (this.boundFunction) { + this.off('select', this.boundFunction); } - // 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]; - } + var locale = this.constants.locales[this.constants.locale]; + + if (this.edgeBeingEdited !== undefined) { + this.edgeBeingEdited._disableControlNodes(); + this.edgeBeingEdited = undefined; + this.selectedControlNode = null; + this.controlNodesActive = false; } - // merge the nodeIndices - for (var i = 0; i < this.nodeIndices.length; i++) { - this.sectors["frozen"][sectorId]["nodeIndices"].push(this.nodeIndices[i]); + // restore overloaded functions + this._restoreOverloadedFunctions(); + + // resume calculation + this.freezeSimulation = false; + + // 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 = "" + + "" + + ""+locale['addNode'] +"" + + "
" + + "" + + ""+locale['addEdge'] +""; + if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) { + this.manipulationDiv.innerHTML += "" + + "
" + + "" + + ""+locale['editNode'] +""; + } + else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) { + this.manipulationDiv.innerHTML += "" + + "
" + + "" + + ""+locale['editEdge'] +""; + } + if (this._selectionIsEmpty() == false) { + this.manipulationDiv.innerHTML += "" + + "
" + + "" + + ""+locale['del'] +""; + } + + + // 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); + } + 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 = "" + + "" + + "" + locale['edit'] + ""; + var editModeButton = document.getElementById("network-manipulate-editModeButton"); + editModeButton.onclick = this._toggleEditMode.bind(this); } }; + /** - * 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. + * Create the toolbar for adding Nodes * * @private */ - exports._collapseThisToSingleCluster = function() { - this.clusterToFit(1,false); + exports._createAddNodeToolbar = function() { + // clear the toolbar + this._clearManipulatorBar(); + if (this.boundFunction) { + this.off('select', this.boundFunction); + } + + var locale = this.constants.locales[this.constants.locale]; + + // create the toolbar contents + this.manipulationDiv.innerHTML = "" + + "" + + "" + locale['back'] + " " + + "
" + + "" + + "" + locale['addDescription'] + ""; + + // bind the icon + var backButton = document.getElementById("network-manipulate-back"); + backButton.onclick = this._createManipulatorBar.bind(this); + + // 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); }; /** - * We create a new active sector from the node that we want to open. + * create the toolbar to connect nodes * - * @param node * @private */ - exports._addSector = function(node) { - // this is the currently active sector - var sector = this._sector(); + exports._createAddEdgeToolbar = function() { + // clear the toolbar + this._clearManipulatorBar(); + this._unselectAll(true); + this.freezeSimulation = true; - // // 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!!"); - // } + var locale = this.constants.locales[this.constants.locale]; - // 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]; + if (this.boundFunction) { + this.off('select', this.boundFunction); + } - var unqiueIdentifier = util.randomUUID(); + this._unselectAll(); + this.forceAppendSelection = false; + this.blockConnectingEdgeSelection = true; - // we fully freeze the currently active sector - this._freezeSector(sector); + this.manipulationDiv.innerHTML = "" + + "" + + "" + locale['back'] + " " + + "
" + + "" + + "" + locale['edgeDescription'] + ""; - // we create a new active sector. This sector has the Id of the node to ensure uniqueness - this._createNewSector(unqiueIdentifier); + // bind the icon + var backButton = document.getElementById("network-manipulate-back"); + backButton.onclick = this._createManipulatorBar.bind(this); - // we add the active sector to the sectors array to be able to revert these steps later on - this._setActiveSector(unqiueIdentifier); + // 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); - // we redirect the global references to the new sector's references. this._sector() now returns unqiueIdentifier - this._switchToSector(this._sector()); + // temporarily overload functions + this.cachedFunctions["_handleTouch"] = this._handleTouch; + this.cachedFunctions["_manipulationReleaseOverload"] = this._manipulationReleaseOverload; + this.cachedFunctions["_handleDragStart"] = this._handleDragStart; + this.cachedFunctions["_handleDragEnd"] = this._handleDragEnd; + this._handleTouch = this._handleConnect; + this._manipulationReleaseOverload = function () {}; + this._handleDragStart = function () {}; + this._handleDragEnd = this._finishConnect; - // finally we add the node we removed from our previous active sector to the new active sector - this.nodes[node.id] = node; + // redraw to show the unselect + this._redraw(); }; - /** - * 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. + * create the toolbar to edit edges * * @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(); - - // we collapse the sector back to a single cluster - this._collapseThisToSingleCluster(); + exports._createEditEdgeToolbar = function() { + // clear the toolbar + this._clearManipulatorBar(); + this.controlNodesActive = true; - // we move the remaining nodes, edges and nodeIndices to the previous sector. - // This previous sector is the one we will reactivate - this._mergeThisWithFrozen(previousSector); + if (this.boundFunction) { + this.off('select', this.boundFunction); + } - // 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); + this.edgeBeingEdited = this._getSelectedEdge(); + this.edgeBeingEdited._enableControlNodes(); - // we activate the previously active (and currently frozen) sector. - this._activateSector(previousSector); + var locale = this.constants.locales[this.constants.locale]; - // we load the references from the newly active sector into the global references - this._switchToSector(previousSector); + this.manipulationDiv.innerHTML = "" + + "" + + "" + locale['back'] + " " + + "
" + + "" + + "" + locale['editEdgeDescription'] + ""; - // we forget the previously active sector because we reverted to the one before - this._forgetLastSector(); + // bind the icon + var backButton = document.getElementById("network-manipulate-back"); + backButton.onclick = this._createManipulatorBar.bind(this); - // finally, we update the node index list. - this._updateNodeIndexList(); + // temporarily overload functions + this.cachedFunctions["_handleTouch"] = this._handleTouch; + this.cachedFunctions["_manipulationReleaseOverload"] = this._manipulationReleaseOverload; + 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._manipulationReleaseOverload = this._releaseControlNode; - // we refresh the list with calulation nodes and calculation node indices. - this._updateCalculationNodes(); - } - } + // redraw to show the unselect + this._redraw(); }; /** - * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation(). + * 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. * - * @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) { - var returnValues = []; - 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); - returnValues.push( 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) { - returnValues.push( this[runFunction](args[0],args[1]) ); - } - else { - returnValues.push( this[runFunction](argument) ); - } - } - } + 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; } - // we revert the global references back to our active sector - this._loadLatestSector(); - return returnValues; + this._redraw(); }; /** - * This runs a function in all active sectors. This is used in _redraw() and the _initializeForceCalculation(). + * 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. * - * @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) { - var returnValues = false; - if (argument === undefined) { - this._switchToSupportSector(); - returnValues = this[runFunction](); + 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); } - else { - this._switchToSupportSector(); - var args = Array.prototype.splice.call(arguments, 1); - if (args.length > 1) { - returnValues = this[runFunction](args[0],args[1]); + 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(); } - else { - returnValues = this[runFunction](argument); + if (this.edgeBeingEdited.controlNodes.to.selected == true) { + this._editEdge(this.edgeBeingEdited.from.id, newNode.id); + this.edgeBeingEdited.controlNodes.to.unselect(); } } - // we revert the global references back to our active sector - this._loadLatestSector(); - return returnValues; + else { + this.edgeBeingEdited._restoreControlNodes(); + } + this.freezeSimulation = false; + this._redraw(); }; - /** - * This runs a function in all frozen sectors. This is used in the _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. * - * @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](); + exports._handleConnect = function(pointer) { + if (this._getSelectedNodeCount() == 0) { + var node = this._getNodeAt(pointer); + + if (node != null) { + if (node.clusterSize > 1) { + alert(this.constants.locales[this.constants.locale]['createEdgeError']) + } + else { + this._selectObject(node,false); + var supportNodes = this.sectors['support']['nodes']; + + // create a node the temporary line can look at + supportNodes['targetNode'] = new Node({id:'targetNode'},{},{},this.constants); + var targetNode = supportNodes['targetNode']; + targetNode.x = node.x; + targetNode.y = node.y; + + // create a temporary edge + this.edges['connectionEdge'] = new Edge({id:"connectionEdge",from:node.id,to:targetNode.id}, this, this.constants); + var connectionEdge = this.edges['connectionEdge']; + connectionEdge.from = node; + connectionEdge.connected = true; + connectionEdge.options.smoothCurves = {enabled: true, + dynamic: false, + type: "continuous", + roundness: 0.5 + }; + connectionEdge.selected = true; + connectionEdge.to = targetNode; + + this.cachedFunctions["_handleOnDrag"] = this._handleOnDrag; + this._handleOnDrag = function(event) { + var pointer = this._getPointer(event.gesture.center); + var connectionEdge = this.edges['connectionEdge']; + connectionEdge.to.x = this._XconvertDOMtoCanvas(pointer.x); + connectionEdge.to.y = this._YconvertDOMtoCanvas(pointer.y); + }; + + this.moving = true; + this.start(); } } } - 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); - } + }; + + exports._finishConnect = function(event) { + if (this._getSelectedNodeCount() == 1) { + var pointer = this._getPointer(event.gesture.center); + // 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']; + + var node = this._getNodeAt(pointer); + if (node != null) { + if (node.clusterSize > 1) { + alert(this.constants.locales[this.constants.locale]["createEdgeError"]) + } + else { + this._createEdge(connectFromId,node.id); + this._createManipulatorBar(); } } + this._unselectAll(); } - 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 + * Adds a node on the specified location */ - 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]); + 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 { + throw new Error('The function for add does not support two arguments (data,callback)'); + this._createManipulatorBar(); + this.moving = true; + this.start(); + } } else { - this._doInAllActiveSectors(runFunction,argument); - this._doInAllFrozenSectors(runFunction,argument); + this.nodesData.add(defaultData); + this._createManipulatorBar(); + this.moving = true; + this.start(); } } }; /** - * 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 + * connect two nodes with a new edge. * - * @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;} - } - } - 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.options.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._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 { + throw new Error('The function for connect does not support two arguments (data,callback)'); + this.moving = true; + this.start(); } } + else { + this.edgesData.add(defaultData); + this.moving = true; + this.start(); + } } }; - exports._drawAllSectorNodes = function(ctx) { - this._drawSectorNodes(ctx,"frozen"); - this._drawSectorNodes(ctx,"active"); - this._loadLatestSector(); - }; - - -/***/ }, -/* 62 */ -/***/ function(module, exports, __webpack_require__) { - - var Node = __webpack_require__(52); - /** - * This function can be called from the _doInAllSectors function + * connect two nodes with a new edge. * - * @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); + 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 { + throw new Error('The function for edit does not support two arguments (data, callback)'); + this.moving = true; + this.start(); } } + else { + this.edgesData.update(defaultData); + this.moving = true; + this.start(); + } } }; /** - * 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 + * 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._getAllNodesOverlappingWith = function (object) { - var overlappingNodes = []; - this._doInAllActiveSectors("_getNodesOverlappingWith",object,overlappingNodes); - return overlappingNodes; + exports._editNode = function() { + if (this.triggerFunctions.edit && this.editMode == true) { + var node = this._getSelectedNode(); + var data = {id:node.id, + label: node.label, + group: node.options.group, + shape: node.options.shape, + color: { + background:node.options.color.background, + border:node.options.color.border, + highlight: { + background:node.options.color.highlight.background, + border:node.options.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 { + throw new Error('The function for edit does not support two arguments (data, callback)'); + } + } + else { + throw new Error('No edit function has been bound to this button'); + } }; - /** - * 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); - - return { - left: x, - top: y, - right: x, - bottom: y - }; - }; /** - * Get the top node at the a specific point (like a click) + * delete everything in the selection * - * @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); - - // 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; + 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 { + throw new Error('The function for delete does not support two arguments (data, callback)') + } + } + else { + this.edgesData.remove(selectedEdges); + this.nodesData.remove(selectedNodes); + this._unselectAll(); + this.moving = true; + this.start(); + } + } + else { + alert(this.constants.locales[this.constants.locale]["deleteClusterError"]); + } } }; - /** - * 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); - } +/***/ }, +/* 60 */ +/***/ function(module, exports, __webpack_require__) { + + var util = __webpack_require__(1); + var Hammer = __webpack_require__(44); + + exports._cleanNavigation = function() { + // clean hammer bindings + if (this.navigationHammers.existing.length != 0) { + for (var i = 0; i < this.navigationHammers.existing.length; i++) { + this.navigationHammers.existing[i].dispose(); } + this.navigationHammers.existing = []; } - }; + this._navigationReleaseOverload = function () {}; - /** - * 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; + // clean up previous navigation items + var wrapper = document.getElementById('network-navigation_wrapper'); + if (wrapper && wrapper.parentNode) { + wrapper.parentNode.removeChild(wrapper); + } }; /** - * Place holder. To implement change the _getNodeAt to a _getObjectAt. Have the _getObjectAt call - * _getNodeAt and _getEdgesAt, then priortize the selection to user preferences. + * 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. * - * @param pointer - * @returns {null} * @private */ - exports._getEdgeAt = function(pointer) { - var positionObject = this._pointerToPositionObject(pointer); - var overlappingEdges = this._getAllEdgesOverlappingWith(positionObject); + exports._loadNavigationElements = function() { + this._cleanNavigation(); - if (overlappingEdges.length > 0) { - return this.edges[overlappingEdges[overlappingEdges.length - 1]]; - } - else { - return null; + this.navigationDivs = {}; + var navigationDivs = ['up','down','left','right','zoomIn','zoomOut','zoomExtends']; + var navigationDivActions = ['_moveUp','_moveDown','_moveLeft','_moveRight','_zoomIn','_zoomOut','_zoomExtent']; + + this.navigationDivs['wrapper'] = document.createElement('div'); + this.navigationDivs['wrapper'].id = 'network-navigation_wrapper'; + this.frame.appendChild(this.navigationDivs['wrapper']); + + 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]]); + + var hammer = Hammer(this.navigationDivs[navigationDivs[i]], {prevent_default: true}); + hammer.on('touch', this[navigationDivActions[i]].bind(this)); + this.navigationHammers.new.push(hammer); } + + this._navigationReleaseOverload = this._stopMovement; + + this.navigationHammers.existing = this.navigationHammers.new; }; /** - * Add object to the selection array. + * this stops all movement induced by the navigation buttons * - * @param obj * @private */ - exports._addToSelection = function(obj) { - if (obj instanceof Node) { - this.selectionObj.nodes[obj.id] = obj; - } - else { - this.selectionObj.edges[obj.id] = obj; - } + exports._zoomExtent = function(event) { + this.zoomExtent({duration:800}); + event.stopPropagation(); }; /** - * Add object to the selection array. + * this stops all movement induced by the navigation buttons * - * @param obj * @private */ - exports._addToHover = function(obj) { - if (obj instanceof Node) { - this.hoverObj.nodes[obj.id] = obj; - } - else { - this.hoverObj.edges[obj.id] = obj; - } + exports._stopMovement = function() { + this._xStopMoving(); + this._yStopMoving(); + this._stopZoom(); }; /** - * Remove a single option from selection. + * 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. * - * @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]; - } + exports._moveUp = function(event) { + this.yIncrement = this.constants.keyboard.speed.y; + this.start(); // if there is no node movement, the calculation wont be done + event.preventDefault(); }; + /** - * Unselect all. The selectionObj is useful for this. - * - * @param {Boolean} [doNotTrigger] | ignore trigger + * move the screen down * @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(); - } - } - for(var edgeId in this.selectionObj.edges) { - if(this.selectionObj.edges.hasOwnProperty(edgeId)) { - this.selectionObj.edges[edgeId].unselect(); - } - } - - this.selectionObj = {nodes:{},edges:{}}; - - if (doNotTrigger == false) { - this.emit('select', this.getSelection()); - } + exports._moveDown = function(event) { + this.yIncrement = -this.constants.keyboard.speed.y; + this.start(); // if there is no node movement, the calculation wont be done + event.preventDefault(); }; + /** - * Unselect all clusters. The selectionObj is useful for this. - * - * @param {Boolean} [doNotTrigger] | ignore trigger + * move the screen left * @private */ - exports._unselectClusters = function(doNotTrigger) { - if (doNotTrigger === undefined) { - doNotTrigger = false; - } - - 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()); - } + exports._moveLeft = function(event) { + this.xIncrement = this.constants.keyboard.speed.x; + this.start(); // if there is no node movement, the calculation wont be done + event.preventDefault(); }; /** - * return the number of selected nodes - * - * @returns {number} + * move the screen right * @private */ - exports._getSelectedNodeCount = function() { - var count = 0; - for (var nodeId in this.selectionObj.nodes) { - if (this.selectionObj.nodes.hasOwnProperty(nodeId)) { - count += 1; - } - } - return count; + exports._moveRight = function(event) { + this.xIncrement = -this.constants.keyboard.speed.y; + this.start(); // if there is no node movement, the calculation wont be done + event.preventDefault(); }; + /** - * return the selected node - * - * @returns {number} + * Zoom in, using the same method as the movement. * @private */ - exports._getSelectedNode = function() { - for (var nodeId in this.selectionObj.nodes) { - if (this.selectionObj.nodes.hasOwnProperty(nodeId)) { - return this.selectionObj.nodes[nodeId]; - } - } - return null; + exports._zoomIn = function(event) { + this.zoomIncrement = this.constants.keyboard.speed.zoom; + this.start(); // if there is no node movement, the calculation wont be done + event.preventDefault(); }; + /** - * return the selected edge - * - * @returns {number} + * Zoom out * @private */ - exports._getSelectedEdge = function() { - for (var edgeId in this.selectionObj.edges) { - if (this.selectionObj.edges.hasOwnProperty(edgeId)) { - return this.selectionObj.edges[edgeId]; - } - } - return null; + exports._zoomOut = function(event) { + this.zoomIncrement = -this.constants.keyboard.speed.zoom; + this.start(); // if there is no node movement, the calculation wont be done + event.preventDefault(); }; /** - * return the number of selected edges - * - * @returns {number} + * Stop zooming and unhighlight the zoom controls * @private */ - exports._getSelectedEdgeCount = function() { - var count = 0; - for (var edgeId in this.selectionObj.edges) { - if (this.selectionObj.edges.hasOwnProperty(edgeId)) { - count += 1; - } - } - return count; + exports._stopZoom = function(event) { + this.zoomIncrement = 0; + event && event.preventDefault(); }; /** - * return the number of selected objects. - * - * @returns {number} + * Stop moving in the Y direction and unHighlight the up and down * @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; + exports._yStopMoving = function(event) { + this.yIncrement = 0; + event && event.preventDefault(); }; + /** - * Check if anything is selected - * - * @returns {boolean} + * Stop moving in the X direction and unHighlight left and right. * @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; + exports._xStopMoving = function(event) { + this.xIncrement = 0; + event && event.preventDefault(); }; - /** - * 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; +/***/ }, +/* 61 */ +/***/ function(module, exports, __webpack_require__) { + + 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; + node.hierarchyEnumerated = false; } } } - return false; }; /** - * select the edges connected to the node that is being selected + * This is the main function to layout the nodes in a hierarchical way. + * It checks if the node details are supplied correctly * - * @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); - } - }; + 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); + } - /** - * 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); + 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"; + } + } + // 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) { + throw new Error("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes."); + this.zoomExtent(undefined,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) { + if (this.constants.hierarchicalLayout.layout == "hubsize") { + this._determineLevels(hubsize); + } + else { + this._determineLevelsDirected(); + } + + } + // 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(); + } } }; /** - * unselect the edges connected to the node that is being selected + * This function places the nodes on the canvas based on the hierarchial distribution. * - * @param {Node} node + * @param {Object} distribution | obtained by the function this._getDistribution() * @private */ - exports._unselectConnectedEdges = function(node) { - for (var i = 0; i < node.dynamicEdges.length; i++) { - var edge = node.dynamicEdges[i]; - edge.unselect(); - this._removeFromSelection(edge); - } - }; + exports._placeNodesByHierarchy = function(distribution) { + var nodeId, node; + + // start placing all the level 0 nodes first. Then recursively position their branches. + for (var level in distribution) { + if (distribution.hasOwnProperty(level)) { + + for (nodeId in distribution[level].nodes) { + if (distribution[level].nodes.hasOwnProperty(nodeId)) { + node = distribution[level].nodes[nodeId]; + if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") { + if (node.xFixed) { + node.x = distribution[level].minPos; + node.xFixed = false; + + distribution[level].minPos += distribution[level].nodeSpacing; + } + } + else { + if (node.yFixed) { + node.y = distribution[level].minPos; + node.yFixed = false; + distribution[level].minPos += distribution[level].nodeSpacing; + } + } + this._placeBranchNodes(node.edges,node.id,distribution,node.level); + } + } + } + } + // stabilize the system after positioning. This function calls zoomExtent. + this._stabilize(); + }; /** - * 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 + * This function get the distribution of levels based on hubsize * - * @param {Node || Edge} object - * @param {Boolean} append - * @param {Boolean} [doNotTrigger] | ignore trigger + * @returns {Object} * @private */ - exports._selectObject = function(object, append, doNotTrigger, highlightEdges, overrideSelectable) { - if (doNotTrigger === undefined) { - doNotTrigger = false; - } - if (highlightEdges === undefined) { - highlightEdges = true; - } + exports._getDistribution = function() { + var distribution = {}; + var nodeId, node, level; - if (this._selectionIsEmpty() == false && append == false && this.forceAppendSelection == false) { - this._unselectAll(true); + // 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[node.level] === undefined) { + distribution[node.level] = {amount: 0, nodes: {}, minPos:0, nodeSpacing:0}; + } + distribution[node.level].amount += 1; + distribution[node.level].nodes[nodeId] = node; + } } - // selectable allows the object to be selected. Override can be used if needed to bypass this. - if (object.selected == false && (this.constants.selectable == true || overrideSelectable)) { - object.select(); - this._addToSelection(object); - if (object instanceof Node && this.blockConnectingEdgeSelection == false && highlightEdges == true) { - this._selectConnectedEdges(object); + // 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; + } } } - // do not select the object if selectable is false, only add it to selection to allow drag to work - else if (object.selected == false) { - this._addToSelection(object); - doNotTrigger = true; - } - else { - object.unselect(); - this._removeFromSelection(object); - } - if (doNotTrigger == false) { - this.emit('select', this.getSelection()); + // 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); + } } + + return distribution; }; /** - * 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 + * this function allocates nodes in levels based on the recursive branching from the largest hubs. * - * @param {Node || Edge} object + * @param hubsize * @private */ - exports._blurObject = function(object) { - if (object.hover == true) { - object.hover = false; - this.emit("blurNode",{node:object.id}); - } - }; + exports._determineLevels = function(hubsize) { + var nodeId, node; - /** - * 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}); + // determine hubs + for (nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + node = this.nodes[nodeId]; + if (node.edges.length == hubsize) { + node.level = 0; + } } } - if (object instanceof Node) { - this._hoverConnectedEdges(object); + + // 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); + } + } } }; - /** - * 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 + * this function allocates nodes in levels based on the recursive branching from the largest hubs. * - * @param {Object} pointer + * @param hubsize * @private */ - exports._handleTouch = function(pointer) { - }; + exports._determineLevelsDirected = function() { + var nodeId, node; + // set first node to source + for (nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + this.nodes[nodeId].level = 10000; + break; + } + } - /** - * 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); + // branch from hubs + for (nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + node = this.nodes[nodeId]; + if (node.level == 10000) { + this._setLevelDirected(10000,node.edges,node.id); + } + } } - else { - var edge = this._getEdgeAt(pointer); - if (edge != null) { - this._selectObject(edge, false); + + + // branch from hubs + var minLevel = 10000; + for (nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + node = this.nodes[nodeId]; + minLevel = node.level < minLevel ? node.level : minLevel; } - else { - this._unselectAll(); + } + + // branch from hubs + for (nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + node = this.nodes[nodeId]; + node.level -= minLevel; } } - this.emit("click", this.getSelection()); - this._redraw(); }; /** - * handles the selection part of the double tap and opens a cluster if needed + * 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 {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); + 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.emit("doubleClick", this.getSelection()); + this._configureSmoothCurves(); }; /** - * Handle the onHold selection part + * 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 pointer + * @param edges + * @param parentId + * @param distribution + * @param parentLevel * @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); + 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; } - } - this._redraw(); - }; - - - /** - * handle the onRelease event. These functions are here for the navigation controls module - * and data manipulation module. - * - * @private - */ - exports._handleOnRelease = function(pointer) { - this._manipulationReleaseOverload(pointer); - this._navigationReleaseOverload(pointer); - }; - - exports._manipulationReleaseOverload = function (pointer) {}; - exports._navigationReleaseOverload = function (pointer) {}; - /** - * - * 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}; - }; + // 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; + } + } - /** - * - * retrieve the currently selected nodes - * @return {String[]} selection An array with the ids of the - * selected nodes. - */ - exports.getSelectedNodes = function() { - var idArray = []; - if (this.constants.selectable == true) { - for (var nodeId in this.selectionObj.nodes) { - if (this.selectionObj.nodes.hasOwnProperty(nodeId)) { - idArray.push(nodeId); + 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); } } } - return idArray }; + /** + * this function is called recursively to enumerate the barnches of the largest hubs and give each node a level. * - * retrieve the currently selected edges - * @return {Array} selection An array with the ids of the - * selected nodes. + * @param level + * @param edges + * @param parentId + * @private */ - exports.getSelectedEdges = function() { - var idArray = []; - if (this.constants.selectable == true) { - for (var edgeId in this.selectionObj.edges) { - if (this.selectionObj.edges.hasOwnProperty(edgeId)) { - idArray.push(edgeId); + 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 (childNode.edges.length > 1) { + this._setLevel(level+1, childNode.edges, childNode.id); } } } - return idArray; - }; - - - /** - * select zero or more nodes DEPRICATED - * @param {Number[] | String[]} selection An array with the ids of the - * selected nodes. - */ - exports.setSelection = function() { - console.log("setSelection is deprecated. Please use selectNodes instead.") }; /** - * 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] + * this function is called recursively to enumerate the barnches of the largest hubs and give each node a level. + * + * @param level + * @param edges + * @param parentId + * @private */ - exports.selectNodes = function(selection, highlightEdges) { - var i, iMax, id; - - if (!selection || (selection.length == undefined)) - throw 'Selection must be an array with ids'; - - // 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'); + exports._setLevelDirected = function(level, edges, parentId) { + this.nodes[parentId].hierarchyEnumerated = true; + for (var i = 0; i < edges.length; i++) { + var childNode = null; + var direction = 1; + if (edges[i].toId == parentId) { + childNode = edges[i].from; + direction = -1; + } + else { + childNode = edges[i].to; + } + if (childNode.level == -1) { + childNode.level = level + direction; } - this._selectObject(node,true,true,highlightEdges,true); } - this.redraw(); - }; - - - /** - * 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; - - if (!selection || (selection.length == undefined)) - throw 'Selection must be an array with ids'; - - // 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'); + 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.edges.length > 1 && childNode.hierarchyEnumerated === false) { + this._setLevelDirected(childNode.level, childNode.edges, childNode.id); } - this._selectObject(edge,true,true,false,true); } - this.redraw(); }; + /** - * Validate the selection: remove ids of nodes which no longer exist + * Unfix nodes + * * @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]; - } + exports._restoreNodes = function() { + for (var nodeId in this.nodes) { + if (this.nodes.hasOwnProperty(nodeId)) { + this.nodes[nodeId].xFixed = false; + this.nodes[nodeId].yFixed = false; } } }; /***/ }, -/* 63 */ +/* 62 */ /***/ function(module, exports, __webpack_require__) { var util = __webpack_require__(1); - var Node = __webpack_require__(52); - var Edge = __webpack_require__(53); + var RepulsionMixin = __webpack_require__(64); + var HierarchialRepulsionMixin = __webpack_require__(65); + var BarnesHutMixin = __webpack_require__(66); /** - * clears the toolbar div element of children + * Toggling barnes Hut calculation on and off. * * @private */ - exports._clearManipulatorBar = function() { - while (this.manipulationDiv.hasChildNodes()) { - this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); - } - - this._manipulationReleaseOverload = function () {}; - delete this.sectors['support']['nodes']['targetNode']; - delete this.sectors['support']['nodes']['targetViaNode']; - this.controlNodesActive = false; + exports._toggleBarnesHut = function () { + this.constants.physics.barnesHut.enabled = !this.constants.physics.barnesHut.enabled; + this._loadSelectedForceSolver(); + this.moving = true; + this.start(); }; + /** - * 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. + * This loads the node force solver based on the barnes hut or repulsion algorithm * * @private */ - exports._restoreOverloadedFunctions = function() { - for (var functionName in this.cachedFunctions) { - if (this.cachedFunctions.hasOwnProperty(functionName)) { - this[functionName] = this.cachedFunctions[functionName]; - } + exports._loadSelectedForceSolver = function () { + // this overloads the this._calculateNodeForces + if (this.constants.physics.barnesHut.enabled == true) { + this._clearMixin(RepulsionMixin); + this._clearMixin(HierarchialRepulsionMixin); + + 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); - /** - * 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); + 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 { - toolbar.style.display="none"; - closeDiv.style.display="none"; - editModeDiv.style.display="block"; - closeDiv.onclick = null; + 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); } - this._createManipulatorBar() }; /** - * main function, creates the main toolbar. Removes functions bound to the select event. Binds all the buttons of the toolbar. + * 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._createManipulatorBar = function() { - // remove bound functions - if (this.boundFunction) { - this.off('select', this.boundFunction); - } - - var locale = this.constants.locales[this.constants.locale]; - - if (this.edgeBeingEdited !== undefined) { - this.edgeBeingEdited._disableControlNodes(); - this.edgeBeingEdited = undefined; - this.selectedControlNode = null; - this.controlNodesActive = false; + exports._initializeForceCalculation = function () { + // stop calculation if there is only one node + if (this.nodeIndices.length == 1) { + this.nodes[this.nodeIndices[0]]._setForce(0, 0); } - - // restore overloaded functions - this._restoreOverloadedFunctions(); - - // resume calculation - this.freezeSimulation = false; - - // 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 = "" + - "" + - ""+locale['addNode'] +"" + - "
" + - "" + - ""+locale['addEdge'] +""; - if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) { - this.manipulationDiv.innerHTML += "" + - "
" + - "" + - ""+locale['editNode'] +""; - } - else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) { - this.manipulationDiv.innerHTML += "" + - "
" + - "" + - ""+locale['editEdge'] +""; - } - if (this._selectionIsEmpty() == false) { - this.manipulationDiv.innerHTML += "" + - "
" + - "" + - ""+locale['del'] +""; - } - - - // 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); + 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); } - 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 = "" + - "" + - "" + locale['edit'] + ""; - var editModeButton = document.getElementById("network-manipulate-editModeButton"); - editModeButton.onclick = this._toggleEditMode.bind(this); + // we now start the force calculation + this._calculateForces(); } }; - /** - * Create the toolbar for adding Nodes - * + * Calculate the external forces acting on the nodes + * Forces are caused by: edges, repulsing forces between nodes, gravity * @private */ - exports._createAddNodeToolbar = function() { - // clear the toolbar - this._clearManipulatorBar(); - if (this.boundFunction) { - this.off('select', this.boundFunction); - } - - var locale = this.constants.locales[this.constants.locale]; - - // create the toolbar contents - this.manipulationDiv.innerHTML = "" + - "" + - "" + locale['back'] + " " + - "
" + - "" + - "" + locale['addDescription'] + ""; + 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 - // bind the icon - var backButton = document.getElementById("network-manipulate-back"); - backButton.onclick = this._createManipulatorBar.bind(this); + this._calculateGravitationalForces(); + this._calculateNodeForces(); - // 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); + 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(); + } + } + } }; /** - * create the toolbar to connect nodes + * 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._createAddEdgeToolbar = function() { - // clear the toolbar - this._clearManipulatorBar(); - this._unselectAll(true); - this.freezeSimulation = true; + exports._updateCalculationNodes = function () { + if (this.constants.smoothCurves.enabled == true && this.constants.smoothCurves.dynamic == true) { + this.calculationNodes = {}; + this.calculationNodeIndices = []; - var locale = this.constants.locales[this.constants.locale]; + 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); + } + } + } - if (this.boundFunction) { - this.off('select', this.boundFunction); + 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._unselectAll(); - this.forceAppendSelection = false; - this.blockConnectingEdgeSelection = true; - this.manipulationDiv.innerHTML = "" + - "" + - "" + locale['back'] + " " + - "
" + - "" + - "" + locale['edgeDescription'] + ""; + /** + * 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; - // bind the icon - var backButton = document.getElementById("network-manipulate-back"); - backButton.onclick = this._createManipulatorBar.bind(this); + 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; + } + else { + node.fx = 0; + node.fy = 0; + } + } + }; - // 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); - // temporarily overload functions - this.cachedFunctions["_handleTouch"] = this._handleTouch; - this.cachedFunctions["_manipulationReleaseOverload"] = this._manipulationReleaseOverload; - this.cachedFunctions["_handleDragStart"] = this._handleDragStart; - this.cachedFunctions["_handleDragEnd"] = this._handleDragEnd; - this._handleTouch = this._handleConnect; - this._manipulationReleaseOverload = function () {}; - this._handleDragStart = function () {}; - this._handleDragEnd = this._finishConnect; - // redraw to show the unselect - this._redraw(); - }; /** - * create the toolbar to edit edges + * this function calculates the effects of the springs in the case of unsmooth curves. * * @private */ - exports._createEditEdgeToolbar = function() { - // clear the toolbar - this._clearManipulatorBar(); - this.controlNodesActive = true; - - if (this.boundFunction) { - this.off('select', this.boundFunction); - } + exports._calculateSpringForces = function () { + var edgeLength, edge, edgeId; + var dx, dy, fx, fy, springForce, distance; + var edges = this.edges; - this.edgeBeingEdited = this._getSelectedEdge(); - this.edgeBeingEdited._enableControlNodes(); + // 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.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 locale = this.constants.locales[this.constants.locale]; + dx = (edge.from.x - edge.to.x); + dy = (edge.from.y - edge.to.y); + distance = Math.sqrt(dx * dx + dy * dy); - this.manipulationDiv.innerHTML = "" + - "" + - "" + locale['back'] + " " + - "
" + - "" + - "" + locale['editEdgeDescription'] + ""; + if (distance == 0) { + distance = 0.01; + } - // bind the icon - var backButton = document.getElementById("network-manipulate-back"); - backButton.onclick = this._createManipulatorBar.bind(this); + // the 1/distance is so the fx and fy can be calculated without sine or cosine. + springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance; - // temporarily overload functions - this.cachedFunctions["_handleTouch"] = this._handleTouch; - this.cachedFunctions["_manipulationReleaseOverload"] = this._manipulationReleaseOverload; - 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._manipulationReleaseOverload = this._releaseControlNode; + fx = dx * springForce; + fy = dy * springForce; - // redraw to show the unselect - this._redraw(); + edge.from.fx += fx; + edge.from.fy += fy; + edge.to.fx -= fx; + edge.to.fy -= fy; + } + } + } + } }; - /** - * 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(); - }; /** - * 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. + * This function calculates the springforces on the nodes, accounting for the support nodes. * * @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(); - }; + exports._calculateSpringForcesWithSupport = function () { + var edgeLength, edge, edgeId, combinedClusterSize; + var edges = this.edges; - 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(); + // 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; + + edgeLength = edge.physics.springLength; + + combinedClusterSize = node1.clusterSize + node3.clusterSize - 2; + + // 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); + } + } + } } } - else { - this.edgeBeingEdited._restoreControlNodes(); - } - 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. + * 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._handleConnect = function(pointer) { - if (this._getSelectedNodeCount() == 0) { - var node = this._getNodeAt(pointer); + exports._calculateSpringForce = function (node1, node2, edgeLength) { + var dx, dy, fx, fy, springForce, distance; - if (node != null) { - if (node.clusterSize > 1) { - alert(this.constants.locales[this.constants.locale]['createEdgeError']) - } - else { - this._selectObject(node,false); - var supportNodes = this.sectors['support']['nodes']; + dx = (node1.x - node2.x); + dy = (node1.y - node2.y); + distance = Math.sqrt(dx * dx + dy * dy); - // create a node the temporary line can look at - supportNodes['targetNode'] = new Node({id:'targetNode'},{},{},this.constants); - var targetNode = supportNodes['targetNode']; - targetNode.x = node.x; - targetNode.y = node.y; + if (distance == 0) { + distance = 0.01; + } - // create a temporary edge - this.edges['connectionEdge'] = new Edge({id:"connectionEdge",from:node.id,to:targetNode.id}, this, this.constants); - var connectionEdge = this.edges['connectionEdge']; - connectionEdge.from = node; - connectionEdge.connected = true; - connectionEdge.options.smoothCurves = {enabled: true, - dynamic: false, - type: "continuous", - roundness: 0.5 - }; - connectionEdge.selected = true; - connectionEdge.to = targetNode; + // the 1/distance is so the fx and fy can be calculated without sine or cosine. + springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance; - this.cachedFunctions["_handleOnDrag"] = this._handleOnDrag; - this._handleOnDrag = function(event) { - var pointer = this._getPointer(event.gesture.center); - var connectionEdge = this.edges['connectionEdge']; - connectionEdge.to.x = this._XconvertDOMtoCanvas(pointer.x); - connectionEdge.to.y = this._YconvertDOMtoCanvas(pointer.y); - }; + fx = dx * springForce; + fy = dy * springForce; - this.moving = true; - this.start(); - } - } - } + node1.fx += fx; + node1.fy += fy; + node2.fx -= fx; + node2.fy -= fy; }; - exports._finishConnect = function(event) { - if (this._getSelectedNodeCount() == 1) { - var pointer = this._getPointer(event.gesture.center); - // restore the drag function - this._handleOnDrag = this.cachedFunctions["_handleOnDrag"]; - delete this.cachedFunctions["_handleOnDrag"]; - // remember the edge id - var connectFromId = this.edges['connectionEdge'].fromId; + /** + * 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); - // remove the temporary nodes and edge - delete this.edges['connectionEdge']; - delete this.sectors['support']['nodes']['targetNode']; - delete this.sectors['support']['nodes']['targetViaNode']; + var hierarchicalLayoutDirections = ["LR", "RL", "UD", "DU"]; + this.physicsConfiguration = document.createElement('div'); + this.physicsConfiguration.className = "PhysicsConfiguration"; + this.physicsConfiguration.innerHTML = '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
Simulation Mode:
Barnes HutRepulsionHierarchical
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
Options:
' + 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 node = this._getNodeAt(pointer); - if (node != null) { - if (node.clusterSize > 1) { - alert(this.constants.locales[this.constants.locale]["createEdgeError"]) - } - else { - this._createEdge(connectFromId,node.id); - this._createManipulatorBar(); - } + 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"); + + 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 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; } - this._unselectAll(); - } - }; + var graph_toggleSmooth = document.getElementById("graph_toggleSmooth"); + var graph_repositionNodes = document.getElementById("graph_repositionNodes"); + var graph_generateOptions = document.getElementById("graph_generateOptions"); - /** - * 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 { - throw new Error('The function for add does not support two arguments (data,callback)'); - this._createManipulatorBar(); - this.moving = true; - this.start(); - } + 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 { - this.nodesData.add(defaultData); - this._createManipulatorBar(); - this.moving = true; - this.start(); + graph_toggleSmooth.style.background = "#FF8532"; } + + + switchConfigurations.apply(this); + + radioButton1.onchange = switchConfigurations.bind(this); + radioButton2.onchange = switchConfigurations.bind(this); + radioButton3.onchange = switchConfigurations.bind(this); } }; - /** - * connect two nodes with a new edge. + * This overwrites the this.constants. * + * @param constantsVariableName + * @param value * @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 { - throw new Error('The function for connect does not support two arguments (data,callback)'); - this.moving = true; - this.start(); - } - } - else { - this.edgesData.add(defaultData); - this.moving = true; - this.start(); - } + 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; } }; + /** - * connect two nodes with a new edge. - * - * @private + * this function is bound to the toggle smooth curves button. That is also why it is not in the prototype. */ - 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 { - throw new Error('The function for edit does not support two arguments (data, callback)'); - this.moving = true; - this.start(); - } - } - else { - this.edgesData.update(defaultData); - this.moving = true; - this.start(); - } - } - }; + 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); + } /** - * Create the toolbar to edit the selected node. The label and the color can be changed. Other colors are derived from the chosen color. + * this function is used to scramble the nodes * - * @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.options.group, - shape: node.options.shape, - color: { - background:node.options.color.background, - border:node.options.color.border, - highlight: { - background:node.options.color.highlight.background, - border:node.options.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 { - throw new Error('The function for edit does not support two arguments (data, callback)'); + 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(); + showValueOfRange.call(this, 'graph_H_nd', 1, "physics_hierarchicalRepulsion_nodeDistance"); + showValueOfRange.call(this, 'graph_H_cg', 1, "physics_centralGravity"); + showValueOfRange.call(this, 'graph_H_sc', 1, "physics_springConstant"); + showValueOfRange.call(this, 'graph_H_sl', 1, "physics_springLength"); + showValueOfRange.call(this, 'graph_H_damp', 1, "physics_damping"); + } else { - throw new Error('No edit function has been bound to this button'); + this.repositionNodes(); } - }; - - - + this.moving = true; + this.start(); + } /** - * delete everything in the selection - * - * @private + * this is used to generate an options file from the playing with physics system. */ - 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 { - throw new Error('The function for delete does not support two arguments (data, callback)') + 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 += ", " } } - else { - this.edgesData.remove(selectedEdges); - this.nodesData.remove(selectedNodes); - this._unselectAll(); - this.moving = true; - this.start(); + 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 += '}}' } - else { - alert(this.constants.locales[this.constants.locale]["deleteClusterError"]); + if (optionsSpecific.length == 0) {options += "}"} + if (this.constants.smoothCurves != this.backupConstants.smoothCurves) { + options += ", smoothCurves: " + this.constants.smoothCurves; } + options += '};' } - }; - - -/***/ }, -/* 64 */ -/***/ function(module, exports, __webpack_require__) { - - var util = __webpack_require__(1); - var Hammer = __webpack_require__(18); - - exports._cleanNavigation = function() { - // clean hammer bindings - if (this.navigationHammers.existing.length != 0) { - for (var i = 0; i < this.navigationHammers.existing.length; i++) { - this.navigationHammers.existing[i].dispose(); + 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 += '}},'; } - this.navigationHammers.existing = []; + 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 += '};' } - this._navigationReleaseOverload = function () {}; - // clean up previous navigation items - var wrapper = document.getElementById('network-navigation_wrapper'); - if (wrapper && wrapper.parentNode) { - wrapper.parentNode.removeChild(wrapper); - } - }; + this.optionsDiv.innerHTML = options; + } /** - * 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. + * this is used to switch between barnesHut, repulsion and hierarchical. * - * @private */ - exports._loadNavigationElements = function() { - this._cleanNavigation(); - - this.navigationDivs = {}; - var navigationDivs = ['up','down','left','right','zoomIn','zoomOut','zoomExtends']; - var navigationDivActions = ['_moveUp','_moveDown','_moveLeft','_moveRight','_zoomIn','_zoomOut','_zoomExtent']; - - this.navigationDivs['wrapper'] = document.createElement('div'); - this.navigationDivs['wrapper'].id = 'network-navigation_wrapper'; - this.frame.appendChild(this.navigationDivs['wrapper']); - - 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]]); - - var hammer = Hammer(this.navigationDivs[navigationDivs[i]], {prevent_default: true}); - hammer.on('touch', this[navigationDivActions[i]].bind(this)); - this.navigationHammers.new.push(hammer); + 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(); + } - this._navigationReleaseOverload = this._stopMovement; - - this.navigationHammers.existing = this.navigationHammers.new; - }; - - - /** - * this stops all movement induced by the navigation buttons - * - * @private - */ - exports._zoomExtent = function(event) { - this.zoomExtent({duration:800}); - event.stopPropagation(); - }; /** - * this stops all movement induced by the navigation buttons + * this generates the ranges depending on the iniital values. * - * @private + * @param id + * @param map + * @param constantsVariableName */ - exports._stopMovement = function() { - this._xStopMoving(); - this._yStopMoving(); - this._stopZoom(); - }; + function showValueOfRange (id,map,constantsVariableName) { + var valueId = id + "_value"; + var rangeValue = document.getElementById(id).value; + if (Array.isArray(map)) { + 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)); + } - /** - * 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 - event.preventDefault(); - }; + if (constantsVariableName == "hierarchicalLayout_direction" || + constantsVariableName == "hierarchicalLayout_levelSeparation" || + constantsVariableName == "hierarchicalLayout_nodeSpacing") { + this._setupHierarchicalLayout(); + } + this.moving = true; + this.start(); + } - /** - * 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 - event.preventDefault(); - }; +/***/ }, +/* 63 */ +/***/ function(module, exports, __webpack_require__) { + function webpackContext(req) { + throw new Error("Cannot find module '" + req + "'."); + } + webpackContext.keys = function() { return []; }; + webpackContext.resolve = webpackContext; + module.exports = webpackContext; + webpackContext.id = 63; - /** - * 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 - event.preventDefault(); - }; +/***/ }, +/* 64 */ +/***/ function(module, exports, __webpack_require__) { /** - * move the screen right + * Calculate the forces the nodes apply on each other based on a repulsion field. + * This field is linearly approximated. + * * @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 - event.preventDefault(); - }; - + exports._calculateNodeForces = function () { + var dx, dy, angle, distance, fx, fy, combinedClusterSize, + repulsingForce, node1, node2, i, j; - /** - * 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 - event.preventDefault(); - }; + var nodes = this.calculationNodes; + var nodeIndices = this.calculationNodeIndices; + // approximation constants + var a_base = -2 / 3; + var b = 4 / 3; - /** - * Zoom out - * @private - */ - exports._zoomOut = function(event) { - this.zoomIncrement = -this.constants.keyboard.speed.zoom; - this.start(); // if there is no node movement, the calculation wont be done - event.preventDefault(); - }; + // repulsing forces between nodes + var nodeDistance = this.constants.physics.repulsion.nodeDistance; + var minimumDistance = nodeDistance; + // 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; - /** - * Stop zooming and unhighlight the zoom controls - * @private - */ - exports._stopZoom = function(event) { - this.zoomIncrement = 0; - event && event.preventDefault(); - }; + dx = node2.x - node1.x; + dy = node2.y - node1.y; + distance = Math.sqrt(dx * dx + dy * dy); + 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)) + } - /** - * Stop moving in the Y direction and unHighlight the up and down - * @private - */ - exports._yStopMoving = function(event) { - this.yIncrement = 0; - event && event.preventDefault(); - }; + // amplify the repulsion for clusters. + repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification; + repulsingForce = repulsingForce / distance; + fx = dx * repulsingForce; + fy = dy * repulsingForce; - /** - * Stop moving in the X direction and unHighlight left and right. - * @private - */ - exports._xStopMoving = function(event) { - this.xIncrement = 0; - event && event.preventDefault(); + node1.fx -= fx; + node1.fy -= fy; + node2.fx += fx; + node2.fy += fy; + } + } + } }; @@ -32828,688 +32936,579 @@ return /******/ (function(modules) { // webpackBootstrap /* 65 */ /***/ function(module, exports, __webpack_require__) { - 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; - node.hierarchyEnumerated = false; - } - } - } - }; - /** - * This is the main function to layout the nodes in a hierarchical way. - * It checks if the node details are supplied correctly + * Calculate the forces the nodes apply on eachother based on a repulsion field. + * This field is linearly approximated. * * @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); - } + exports._calculateNodeForces = function () { + var dx, dy, distance, fx, fy, + repulsingForce, node1, node2, i, j; - 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"; - } - } - // 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; + var nodes = this.calculationNodes; + var nodeIndices = this.calculationNodeIndices; - 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; - } - } - } + // repulsing forces between nodes + var nodeDistance = this.constants.physics.hierarchicalRepulsion.nodeDistance; - // if the user defined some levels but not all, alert and run without hierarchical layout - if (undefinedLevel == true && definedLevel == true) { - throw new Error("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes."); - this.zoomExtent(undefined,true,this.constants.clustering.enabled); - if (!this.constants.clustering.enabled) { - this.start(); - } - } - else { - // setup the system to use hierarchical method. - this._changeConstants(); + // 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]]; - // define levels if undefined by the users. Based on hubsize - if (undefinedLevel == true) { - if (this.constants.hierarchicalLayout.layout == "hubsize") { - this._determineLevels(hubsize); + // nodes only affect nodes on their level + if (node1.level == node2.level) { + + dx = node2.x - node1.x; + dy = node2.y - node1.y; + distance = Math.sqrt(dx * dx + dy * dy); + + + var steepness = 0.05; + if (distance < nodeDistance) { + repulsingForce = -Math.pow(steepness*distance,2) + Math.pow(steepness*nodeDistance,2); } else { - this._determineLevelsDirected(); + repulsingForce = 0; } + // 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; } - // 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 places the nodes on the canvas based on the hierarchial distribution. + * this function calculates the effects of the springs in the case of unsmooth curves. * - * @param {Object} distribution | obtained by the function this._getDistribution() * @private */ - exports._placeNodesByHierarchy = function(distribution) { - var nodeId, node; + exports._calculateHierarchicalSpringForces = function () { + var edgeLength, edge, edgeId; + var dx, dy, fx, fy, springForce, distance; + var edges = this.edges; - // start placing all the level 0 nodes first. Then recursively position their branches. - for (var level in distribution) { - if (distribution.hasOwnProperty(level)) { + var nodes = this.calculationNodes; + var nodeIndices = this.calculationNodeIndices; - for (nodeId in distribution[level].nodes) { - if (distribution[level].nodes.hasOwnProperty(nodeId)) { - node = distribution[level].nodes[nodeId]; - if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") { - if (node.xFixed) { - node.x = distribution[level].minPos; - node.xFixed = false; - distribution[level].minPos += distribution[level].nodeSpacing; - } + for (var i = 0; i < nodeIndices.length; i++) { + var node1 = nodes[nodeIndices[i]]; + node1.springFx = 0; + node1.springFy = 0; + } + + + // 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.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); + + if (distance == 0) { + distance = 0.01; } - else { - if (node.yFixed) { - node.y = distribution[level].minPos; - node.yFixed = false; - distribution[level].minPos += distribution[level].nodeSpacing; - } + // 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; + + + + if (edge.to.level != edge.from.level) { + edge.to.springFx -= fx; + edge.to.springFy -= fy; + edge.from.springFx += fx; + edge.from.springFy += fy; + } + else { + var factor = 0.5; + edge.to.fx -= factor*fx; + edge.to.fy -= factor*fy; + edge.from.fx += factor*fx; + edge.from.fy += factor*fy; } - this._placeBranchNodes(node.edges,node.id,distribution,node.level); } } } } - // stabilize the system after positioning. This function calls zoomExtent. - this._stabilize(); + // normalize spring forces + var springForce = 1; + var springFx, springFy; + for (i = 0; i < nodeIndices.length; i++) { + var node = nodes[nodeIndices[i]]; + springFx = Math.min(springForce,Math.max(-springForce,node.springFx)); + springFy = Math.min(springForce,Math.max(-springForce,node.springFy)); + + node.fx += springFx; + node.fy += springFy; + } + + // retain energy balance + var totalFx = 0; + var totalFy = 0; + for (i = 0; i < nodeIndices.length; i++) { + var node = nodes[nodeIndices[i]]; + totalFx += node.fx; + totalFy += node.fy; + } + var correctionFx = totalFx / nodeIndices.length; + var correctionFy = totalFy / nodeIndices.length; + + for (i = 0; i < nodeIndices.length; i++) { + var node = nodes[nodeIndices[i]]; + node.fx -= correctionFx; + node.fy -= correctionFy; + } + }; +/***/ }, +/* 66 */ +/***/ function(module, exports, __webpack_require__) { /** - * This function get the distribution of levels based on hubsize + * 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. * - * @returns {Object} * @private */ - exports._getDistribution = function() { - var distribution = {}; - var nodeId, node, level; + exports._calculateNodeForces = function() { + if (this.constants.physics.barnesHut.gravitationalConstant != 0) { + var node; + var nodes = this.calculationNodes; + var nodeIndices = this.calculationNodeIndices; + var nodeCount = nodeIndices.length; - // 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[node.level] === undefined) { - distribution[node.level] = {amount: 0, nodes: {}, minPos:0, nodeSpacing:0}; - } - distribution[node.level].amount += 1; - distribution[node.level].nodes[nodeId] = node; - } - } + this._formBarnesHutTree(nodes,nodeIndices); - // 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; - } - } - } + var barnesHutTree = this.barnesHutTree; - // 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); + // place the nodes one by one recursively + for (var i = 0; i < nodeCount; i++) { + node = nodes[nodeIndices[i]]; + if (node.options.mass > 0) { + // 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); + } } } - - return distribution; }; /** - * this function allocates nodes in levels based on the recursive branching from the largest hubs. + * 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 hubsize + * @param parentBranch + * @param node * @private */ - exports._determineLevels = function(hubsize) { - var nodeId, node; + exports._getForceContribution = function(parentBranch,node) { + // we get no force contribution from an empty region + if (parentBranch.childrenCount > 0) { + var dx,dy,distance; - // determine hubs - for (nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - node = this.nodes[nodeId]; - if (node.edges.length == hubsize) { - node.level = 0; + // 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.options.mass / (distance * distance * distance); + var fx = dx * gravityForce; + var fy = dy * gravityForce; + node.fx += fx; + node.fy += fy; } - } - - // 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); + 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.options.mass / (distance * distance * distance); + var fx = dx * gravityForce; + var fy = dy * gravityForce; + node.fx += fx; + node.fy += fy; + } } } } }; /** - * this function allocates nodes in levels based on the recursive branching from the largest hubs. + * This function constructs the barnesHut tree recursively. It creates the root, splits it and starts placing the nodes. * - * @param hubsize + * @param nodes + * @param nodeIndices * @private */ - exports._determineLevelsDirected = function() { - var nodeId, node; + exports._formBarnesHutTree = function(nodes,nodeIndices) { + var node; + var nodeCount = nodeIndices.length; - // set first node to source - for (nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - this.nodes[nodeId].level = 10000; - break; - } - } + var minX = Number.MAX_VALUE, + minY = Number.MAX_VALUE, + maxX =-Number.MAX_VALUE, + maxY =-Number.MAX_VALUE; - // branch from hubs - for (nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - node = this.nodes[nodeId]; - if (node.level == 10000) { - this._setLevelDirected(10000,node.edges,node.id); - } + // 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 (nodes[nodeIndices[i]].options.mass > 0) { + 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 - // branch from hubs - var minLevel = 10000; - for (nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - node = this.nodes[nodeId]; - minLevel = node.level < minLevel ? node.level : minLevel; + 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._splitBranch(barnesHutTree.root); - // branch from hubs - for (nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - node = this.nodes[nodeId]; - node.level -= minLevel; + // place the nodes one by one recursively + for (i = 0; i < nodeCount; i++) { + node = nodes[nodeIndices[i]]; + if (node.options.mass > 0) { + this._placeInTree(barnesHutTree.root,node); } } + + // make global + this.barnesHutTree = barnesHutTree }; /** - * 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. + * this updates the mass of a branch. this is increased by adding a node. * + * @param parentBranch + * @param node * @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; - } - this._configureSmoothCurves(); + exports._updateBranchMass = function(parentBranch, node) { + var totalMass = parentBranch.mass + node.options.mass; + var totalMassInv = 1/totalMass; + + parentBranch.centerOfMass.x = parentBranch.centerOfMass.x * parentBranch.mass + node.x * node.options.mass; + parentBranch.centerOfMass.x *= totalMassInv; + + parentBranch.centerOfMass.y = parentBranch.centerOfMass.y * parentBranch.mass + node.y * node.options.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; + }; /** - * 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. + * determine in which branch the node will be placed. * - * @param edges - * @param parentId - * @param distribution - * @param parentLevel + * @param parentBranch + * @param node + * @param skipMassUpdate * @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; - } + exports._placeInTree = function(parentBranch,node,skipMassUpdate) { + if (skipMassUpdate != true || skipMassUpdate === undefined) { + // update the mass of the branch. + this._updateBranchMass(parentBranch,node); + } - // 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; - } + 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"); } - else { - if (childNode.yFixed && childNode.level > parentLevel) { - childNode.yFixed = false; - childNode.y = distribution[childNode.level].minPos; - nodeMoved = true; - } + else { // in SW + this._placeInRegion(parentBranch,node,"SW"); } - - 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); - } + } + 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"); } } }; /** - * this function is called recursively to enumerate the barnches of the largest hubs and give each node a level. + * actually place the node in a region (or branch) * - * @param level - * @param edges - * @param parentId + * @param parentBranch + * @param node + * @param region * @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 (childNode.edges.length > 1) { - this._setLevel(level+1, childNode.edges, childNode.id); + 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; } }; /** - * this function is called recursively to enumerate the barnches of the largest hubs and give each node a level. + * 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 level - * @param edges - * @param parentId + * @param parentBranch * @private */ - exports._setLevelDirected = function(level, edges, parentId) { - this.nodes[parentId].hierarchyEnumerated = true; - for (var i = 0; i < edges.length; i++) { - var childNode = null; - var direction = 1; - if (edges[i].toId == parentId) { - childNode = edges[i].from; - direction = -1; - } - else { - childNode = edges[i].to; - } - if (childNode.level == -1) { - childNode.level = level + direction; - } + 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"); - 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.edges.length > 1 && childNode.hierarchyEnumerated === false) { - this._setLevelDirected(childNode.level, childNode.edges, childNode.id); - } + if (containedNode != null) { + this._placeInTree(parentBranch,containedNode); } }; /** - * Unfix nodes + * 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._restoreNodes = function() { - for (var nodeId in this.nodes) { - if (this.nodes.hasOwnProperty(nodeId)) { - this.nodes[nodeId].xFixed = false; - this.nodes[nodeId].yFixed = false; - } + 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; } - }; - - -/***/ }, -/* 66 */ -/***/ function(module, exports, __webpack_require__) { - // English - exports['en'] = { - edit: 'Edit', - del: 'Delete selected', - back: 'Back', - addNode: 'Add Node', - addEdge: 'Add Edge', - editNode: 'Edit Node', - editEdge: 'Edit Edge', - addDescription: 'Click in an empty space to place a new node.', - edgeDescription: 'Click on a node and drag the edge to another node to connect them.', - editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.', - createEdgeError: 'Cannot link edges to a cluster.', - deleteClusterError: 'Clusters cannot be deleted.' - }; - exports['en_EN'] = exports['en']; - exports['en_US'] = exports['en']; - // Dutch - exports['nl'] = { - edit: 'Wijzigen', - del: 'Selectie verwijderen', - back: 'Terug', - addNode: 'Node toevoegen', - addEdge: 'Link toevoegen', - editNode: 'Node wijzigen', - editEdge: 'Link wijzigen', - addDescription: 'Klik op een leeg gebied om een nieuwe node te maken.', - edgeDescription: 'Klik op een node en sleep de link naar een andere node om ze te verbinden.', - editEdgeDescription: 'Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.', - createEdgeError: 'Kan geen link maken naar een cluster.', - deleteClusterError: 'Clusters kunnen niet worden verwijderd.' + 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 + }; }; - exports['nl_NL'] = exports['nl']; - exports['nl_BE'] = exports['nl']; - -/***/ }, -/* 67 */ -/***/ function(module, exports, __webpack_require__) { /** - * Canvas shapes used by Network + * This function is for debugging purposed, it draws the tree. + * + * @param ctx + * @param color + * @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); - }; - - - - /** - * 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; + exports._drawTree = function(ctx,color) { + if (this.barnesHutTree !== undefined) { - 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 + ctx.lineWidth = 1; - this.beginPath(); - this.moveTo(xe, ym); + this._drawBranch(this.barnesHutTree.root,ctx,color); + } + }; - 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 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.lineTo(xe, ymb); + 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(); - this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb); - this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb); + ctx.beginPath(); + ctx.moveTo(branch.range.maxX,branch.range.minY); + ctx.lineTo(branch.range.maxX,branch.range.maxY); + ctx.stroke(); - this.lineTo(x, ym); - }; + 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(); - /** - * Draw an arrow point (no line) + /* + if (branch.mass > 0) { + ctx.circle(branch.centerOfMass.x, branch.centerOfMass.y, 3*branch.mass); + ctx.stroke(); + } */ - 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; - } - }; +/***/ }, +/* 67 */ +/***/ function(module, exports, __webpack_require__) { - // TODO: add diamond shape + module.exports = function(module) { + if(!module.webpackPolyfill) { + module.deprecate = function() {}; + module.paths = []; + // module.parent = undefined by default + module.children = []; + module.webpackPolyfill = 1; + } + return module; } diff --git a/dist/vis.map b/dist/vis.map index e5e6ee85..2be1ff4e 100644 --- a/dist/vis.map +++ b/dist/vis.map @@ -1 +1 @@ -{"version":3,"file":"vis.map","sources":["./dist/vis.js"],"names":["root","factory","exports","module","define","amd","this","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","util","DOMutil","DataSet","DataView","Graph3d","graph3d","Camera","Filter","Point2d","Point3d","Slider","StepNumber","Timeline","Graph2d","timeline","DateUtil","DataStep","Range","stack","TimeStep","components","items","Item","BackgroundItem","BoxItem","PointItem","RangeItem","Component","CurrentTime","CustomTime","DataAxis","GraphGroup","Group","BackgroundGroup","ItemSet","Legend","LineGraph","TimeAxis","Network","network","Edge","Groups","Images","Node","Popup","dotparser","gephiParser","Graph","Error","moment","hammer","isNumber","object","Number","isString","String","isDate","Date","match","ASPDateRegex","exec","isNaN","parse","isDataTable","google","visualization","DataTable","randomUUID","S4","Math","floor","random","toString","extend","a","i","len","arguments","length","other","prop","hasOwnProperty","selectiveExtend","props","Array","isArray","selectiveDeepExtend","b","TypeError","constructor","Object","undefined","deepExtend","selectiveNotDeepExtend","indexOf","equalArray","convert","type","Boolean","valueOf","isMoment","toDate","getType","toISOString","value","getAbsoluteLeft","elem","getBoundingClientRect","left","window","pageXOffset","getAbsoluteTop","top","pageYOffset","addClassName","className","classes","split","push","join","removeClassName","index","splice","forEach","callback","toArray","array","updateProperty","key","addEventListener","element","action","listener","useCapture","navigator","userAgent","attachEvent","removeEventListener","detachEvent","preventDefault","event","returnValue","getTarget","target","srcElement","nodeType","parentNode","option","asBoolean","defaultValue","asNumber","asString","asSize","asElement","GiveDec","Hex","Value","eval","GiveHex","Dec","parseColor","color","isValidRGB","rgb","substr","RGBToHex","isValidHex","hsv","hexToHSV","lighterColorHSV","h","s","v","min","darkerColorHSV","darkerColorHex","HSVToHex","lighterColorHex","background","border","highlight","hover","hexToRGB","hex","replace","toUpperCase","substring","d","e","f","r","g","red","green","blue","RGBToHSV","minRGB","maxRGB","max","hue","saturation","cssUtil","cssText","styles","style","trim","parts","keys","map","addCssText","currentStyles","newStyles","removeCssText","removeStyles","HSVToRGB","q","t","isOk","test","selectiveBridgeObject","fields","referenceObject","objectTo","create","bridgeObject","mergeOptions","mergeTarget","options","enabled","binarySearch","orderedItems","range","field","field2","maxIterations","iteration","found","low","high","newLow","newHigh","guess","isVisible","start","console","log","binarySearchGeneric","sidePreference","newGuess","prevValue","nextValue","easeInOutQuad","end","duration","change","easingFunctions","linear","easeInQuad","easeOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","prepareElements","JSONcontainer","elementType","redundant","used","cleanupElements","removeChild","getSVGElement","svgContainer","shift","document","createElementNS","appendChild","getDOMElement","DOMContainer","insertBefore","createElement","drawPoint","x","y","group","point","drawPoints","setAttributeNS","size","drawBar","width","height","rect","data","_options","_data","_fieldId","fieldId","_type","_subscribers","add","prototype","on","subscribers","subscribe","off","filter","unsubscribe","_trigger","params","senderId","concat","subscriber","addedIds","me","_addItem","columns","_getColumnNames","row","rows","getNumberOfRows","item","col","cols","getValue","update","updatedIds","updatedData","addOrUpdate","_updateItem","get","ids","firstType","returnType","allowedValues","itemId","_getItem","order","_sort","_filterFields","_appendRow","result","getIds","getDataSet","mappedItems","filteredItem","name","sort","av","bv","remove","removedId","removedIds","_remove","clear","maxField","itemField","minField","distinct","values","fieldType","count","exists","types","raw","converted","JSON","stringify","dataTable","getNumberOfColumns","getColumnId","getColumnLabel","addRow","setValue","_ids","_onEvent","apply","setData","viewOptions","getArguments","defaultFilter","dataSet","added","updated","removed","container","SyntaxError","containerElement","margin","defaultXCenter","defaultYCenter","xLabel","yLabel","zLabel","passValueFn","xValueLabel","yValueLabel","zValueLabel","filterLabel","legendLabel","STYLE","DOT","showPerspective","showGrid","keepAspectRatio","showShadow","showGrayBottom","showTooltip","verticalRatio","animationInterval","animationPreload","camera","eye","dataPoints","colX","colY","colZ","colValue","colFilter","xMin","xStep","xMax","yMin","yStep","yMax","zMin","zStep","zMax","valueMin","valueMax","xBarWidth","yBarWidth","colorAxis","colorGrid","colorDot","colorDotBorder","setOptions","Emitter","_setScale","scale","z","xCenter","yCenter","zCenter","setArmLocation","_convert3Dto2D","point3d","translation","_convertPointToTranslation","_convertTranslationToScreen","ax","ay","az","cx","getCameraLocation","cy","cz","sinTx","sin","getCameraRotation","cosTx","cos","sinTy","cosTy","sinTz","cosTz","dx","dy","dz","bx","by","ex","ey","ez","getArmLength","xcenter","frame","canvas","clientWidth","ycenter","_setBackgroundColor","backgroundColor","fill","stroke","strokeWidth","borderColor","borderWidth","borderStyle","BAR","BARCOLOR","BARSIZE","DOTLINE","DOTCOLOR","DOTSIZE","GRID","LINE","SURFACE","_getStyleNumber","styleName","_determineColumnIndexes","counter","column","getDistinctValues","distinctValues","getColumnRange","minMax","_dataInitialize","rawData","_onChange","dataFilter","setOnLoadCallback","redraw","withBars","defaultXBarWidth","dataX","defaultYBarWidth","dataY","xRange","defaultXMin","defaultXMax","defaultXStep","yRange","defaultYMin","defaultYMax","defaultYStep","zRange","defaultZMin","defaultZMax","defaultZStep","valueRange","defaultValueMin","defaultValueMax","_getDataPoints","sortNumber","obj","dataMatrix","xIndex","yIndex","trans","screen","bottom","pointRight","pointTop","pointCross","hasChildNodes","firstChild","position","overflow","noCanvas","fontWeight","padding","innerHTML","onmousedown","_onMouseDown","ontouchstart","_onTouchStart","onmousewheel","_onWheel","ontooltip","_onTooltip","onkeydown","setSize","_resizeCanvas","clientHeight","animationStart","slider","play","animationStop","stop","_resizeCenter","charAt","parseFloat","setCameraPosition","pos","horizontal","vertical","setArmRotation","distance","setArmLength","getCameraPosition","getArmRotation","_readData","_redrawFilter","animationAutoStart","cameraPosition","styleNumber","tooltip","showAnimationControls","_redrawSlider","_redrawClear","_redrawAxis","_redrawDataGrid","_redrawDataLine","_redrawDataBar","_redrawDataDot","_redrawInfo","_redrawLegend","ctx","getContext","clearRect","widthMin","widthMax","dotSize","right","lineWidth","font","ymin","ymax","_hsv2rgb","strokeStyle","beginPath","moveTo","lineTo","strokeRect","fillStyle","closePath","gridLineLen","step","getCurrent","next","textAlign","textBaseline","fillText","label","visible","setValues","setPlayInterval","onchange","getIndex","selectValue","setOnChangeCallback","lineStyle","getLabel","getSelectedValue","from","to","prettyStep","text","xText","yText","zText","offset","xOffset","yOffset","xMin2d","xMax2d","gridLenX","gridLenY","textMargin","armAngle","H","S","V","R","G","B","C","Hi","X","abs","parseInt","cross","topSideVisible","zAvg","transBottom","dist","sortDepth","aDiff","subtract","bDiff","crossproduct","crossProduct","radius","arc","PI","j","surface","corners","xWidth","yWidth","surfaces","center","avg","transCenter","diff","leftButtonDown","_onMouseUp","which","button","touchDown","startMouseX","getMouseX","startMouseY","getMouseY","startStart","startEnd","startArmRotation","cursor","onmousemove","_onMouseMove","onmouseup","diffX","diffY","horizontalNew","verticalNew","snapAngle","snapValue","round","parameters","emit","delay","mouseX","mouseY","tooltipTimeout","clearTimeout","_hideTooltip","dataPoint","_dataPointFromXY","_showTooltip","setTimeout","ontouchmove","_onTouchMove","ontouchend","_onTouchEnd","delta","wheelDelta","detail","oldLength","newLength","_insideTriangle","triangle","sign","as","bs","cs","distMax","closestDataPoint","closestDist","triangle1","triangle2","distX","distY","sqrt","content","line","dot","dom","borderRadius","boxShadow","borderLeft","contentWidth","offsetWidth","contentHeight","offsetHeight","lineHeight","dotWidth","dotHeight","clientX","targetTouches","clientY","armLocation","armRotation","armLength","cameraLocation","cameraRotation","calculateCameraOrientation","rot","graph","onLoadCallback","loadInBackground","isLoaded","getLoadedProgress","getColumn","getValues","dataView","progress","sub","sum","prev","bar","MozBorderRadius","slide","onclick","togglePlay","onChangeCallback","playTimeout","playInterval","playLoop","setIndex","playNext","interval","clearInterval","getPlayInterval","setPlayLoop","doLoop","onChange","indexToLeft","startClientX","startSlideX","leftToIndex","_start","_end","_step","precision","_current","setRange","setStep","calculatePrettyStep","log10","LN10","step1","pow","step2","step5","toPrecision","getStep","groups","forthArgument","defaultOptions","autoResize","orientation","maxHeight","minHeight","_create","body","domProps","emitter","bind","hiddenDates","snap","toScreen","_toScreen","toGlobalScreen","_toGlobalScreen","toTime","_toTime","toGlobalTime","_toGlobalTime","timeAxis","currentTime","customTime","itemSet","itemsData","groupsData","setGroups","setItems","Core","newDataSet","initialLoad","setWindow","animate","fit","setSelection","focus","getSelection","itemData","middle","getItemRange","dataset","minItem","maxStartItem","maxEndItem","linegraph","getLegend","groupId","isGroupVisible","visibility","convertHiddenOptions","repeat","dateItem","updateHiddenDates","centerContainer","totalRange","pixelTime","startDate","endDate","_d","runUntil","clone","day","dayOfYear","year","dayOffset","date","month","removeDuplicates","startHidden","isHidden","endHidden","rangeStart","rangeEnd","hidden","startToFront","endToFront","_applyRange","safeDates","printDates","dates","stepOverHiddenDates","timeStep","previousTime","stepInHidden","currentValue","current","newValue","switchedYear","switchedMonth","switchedDay","checkFirstStep","time","getHiddenDurationBetween","correctTimeForHidden","conversion","hiddenDuration","totalDuration","partialDuration","accumulatedHiddenDuration","getAccumulatedHiddenDuration","newTime","getHiddenDurationBefore","timeOffset","requiredDuration","previousPoint","snapAwayFromHidden","direction","correctionEnabled","minimumStep","containerHeight","customRange","autoScale","stepIndex","marginStart","marginEnd","deadSpace","majorSteps","minorSteps","setMinimumStep","setFirst","safeSize","minimumStepValue","orderOfMagnitude","minorStepIdx","magnitudefactor","solutionFound","stepSize","niceStart","niceEnd","roundToMinor","marginRange","rounded","hasNext","previous","slice","isMajor","now","hours","minutes","seconds","milliseconds","deltaDifference","scaleOffset","moveable","zoomable","zoomMin","zoomMax","touch","animateTimer","_onDragStart","_onDrag","_onDragEnd","_onHold","_onMouseWheel","_onTouch","_onPinch","validateDirection","getPointer","pageX","pageY","hammerUtil","dragging","initTime","done","initStart","initEnd","changed","anyChanged","_cancelAnimation","newStart","newEnd","getRange","totalHidden","previousDelta","allowDragging","gesture","deltaX","deltaY","diffRange","safeStart","safeEnd","fakeGesture","pointer","pointerDate","_pointerToDate","zoom","touches","hiddenDurationBefore","hiddenDurationAfter","move","EPSILON","orderByStart","orderByEnd","aTime","bTime","force","iMax","axis","collidingItem","jj","collision","nostack","subgroups","newTop","subgroup","SCALE","DAY","MILLISECOND","SECOND","MINUTE","HOUR","WEEKDAY","MONTH","YEAR","first","setFullYear","getFullYear","setMonth","setDate","setHours","setMinutes","setSeconds","setMilliseconds","getMilliseconds","getSeconds","getMinutes","getHours","getDate","getMonth","setScale","newScale","newStep","setAutoScale","enable","stepYear","stepMonth","stepDay","stepHour","stepMinute","stepSecond","stepMillisecond","getLabelMinor","format","getLabelMajor","destroy","_isResized","resized","_previousWidth","_previousHeight","showCurrentTime","locales","locale","parent","backgroundVertical","title","currentTimeTimer","setCurrentTime","getCurrentTime","showCustomTime","eventParams","Hammer","drag","prevent_default","setCustomTime","getCustomTime","stopPropagation","svg","linegraphOptions","showMinorLabels","showMajorLabels","icons","majorLinesOffset","minorLinesOffset","labelOffsetX","labelOffsetY","iconWidth","linegraphSVG","DOMelements","lines","labels","conversionFactor","minWidth","stepPixels","stepPixelsForced","lineOffset","master","svgElements","amountOfGroups","addGroup","graphOptions","updateGroup","removeGroup","hide","show","lineContainer","display","_redrawGroupIcons","iconHeight","iconOffset","drawIcon","backgroundHorizontal","changeCalled","activeGroups","_calculateCharSize","minorLabelHeight","minorCharHeight","majorLabelHeight","majorCharHeight","minorLineWidth","minorLineHeight","majorLineWidth","majorLineHeight","_redrawLabels","amountOfSteps","stepDifference","valueAtZero","marginStartPos","maxLabelSize","_redrawLabel","_redrawLine","convertValue","invertedValue","convertedValue","characterHeight","largestWidth","majorCharWidth","minorCharWidth","textMinor","createTextNode","measureCharMinor","textMajor","measureCharMajor","groupsUsingDefaultStyles","usingDefaultStyle","zeroPosition","setZeroPosition","catmullRom","parametrization","alpha","SVGcontainer","path","fillPath","fillHeight","outline","shaded","barWidth","bar1Height","bar2Height","icon","yAxisOrientation","subgroupIndex","subgroupOrderer","subgroupOrder","visibleItems","byStart","byEnd","inner","foreground","marker","Element","getLabelWidth","restack","_updateVisibleItems","markerHeight","lastMarkerHeight","dirty","displayed","_calculateHeight","offsetTop","offsetLeft","ii","repositionY","resetSubgroups","labelSet","setParent","orderSubgroups","_checkIfVisible","sortArray","sortField","removeFromDataSet","removeItem","_constructByEndArray","endArray","initialPosByStart","newVisibleItems","initialPosByEnd","_checkIfInvisible","repositionX","align","groupOrder","selectable","editable","updateTime","onAdd","onUpdate","onMove","onRemove","onMoving","itemOptions","itemListeners","_onAdd","_onUpdate","_onRemove","groupListeners","_onAddGroups","_onUpdateGroups","_onRemoveGroups","groupIds","selection","stackDirty","touchParams","UNGROUPED","BACKGROUND","box","_updateUngrouped","backgroundGroup","_onSelectItem","_onMultiSelectItem","_onAddItem","addCallback","fn","Function","markDirty","unselect","select","getVisibleItems","rawVisibleItems","_deselect","_orderGroups","visibleInterval","zoomed","lastVisibleInterval","lastWidth","nonFirstMargin","firstGroup","_firstGroup","firstMargin","groupMargin","groupResized","firstGroupIndex","firstGroupId","ungrouped","_getGroupId","getLabelSet","oldItemsData","getItems","_order","getGroups","_getType","_removeItem","groupData","groupOptions","oldGroupId","oldGroup","itemFromTarget","initialX","selected","dragLeftItem","dragRightItem","itemProps","newProps","initial","groupFromTarget","_updateItemProps","_moveToGroup","changes","ctrlKey","srcEvent","shiftKey","oldSelection","newSelection","xAbs","newItem","itemSetFromTarget","side","iconSize","iconSpacing","textArea","drawLegendIcons","getComputedStyle","paddingTop","defaultGroup","sampling","graphHeight","barChart","handleOverlap","dataAxis","legend","abortedGraphUpdate","lastStart","_updateGraph","yAxisLeft","yAxisRight","legendLeft","legendRight","_updateAllGroupData","_updateGroup","groupsContent","ungroupedCounter","rangePerPixelInv","preprocessedGroupData","processedGroupData","groupRanges","minDate","maxDate","_getRelevantData","_convertXcoordinates","_getYRanges","_updateYAxis","_convertYcoordinates","_drawLineGraph","_drawBarGraphs","dataContainer","_applySampling","increment","amountOfPoints","xDistance","pointsPerPixel","ceil","sampledData","barCombinedData","barCombinedDataLeft","barCombinedDataRight","ignore","intersections","_getDataIntersections","_getStackedBarYRange","combinedData","accumulated","xpos","minVal","maxVal","yAxisLeftUsed","yAxisRightUsed","minLeft","minRight","maxLeft","maxRight","_toggleAxisVisiblity","drawIcons","axisUsed","coreDistance","drawData","barPoints","heightOffset","_getSafeDrawData","nextKey","amount","resolved","prevKey","svgHeight","_catmullRom","_linear","dFill","_drawPoints","datapoints","xValue","yValue","extractedData","_catmullRomUniform","p0","p1","p2","p3","bp1","bp2","normalization","d1","d2","d3","A","N","M","d3powA","d2powA","d3pow2A","d2pow2A","d1pow2A","d1powA","majorLines","majorTexts","minorLines","minorTexts","lineTop","lang","parentChanged","foregroundNextSibling","nextSibling","backgroundNextSibling","_repaintLabels","timeLabelsize","xFirstMajorLabel","cur","_repaintMinorText","_repaintMajorText","_repaintMajorLine","_repaintMinorLine","leftTime","leftText","widthText","arr","pop","childNodes","nodeValue","_repaintDeleteButton","anchor","deleteButton","_updateContents","template","_updateTitle","removeAttribute","_updateDataAttributes","dataAttributes","attributes","setAttribute","_updateStyle","emptyContent","baseClassName","onTop","itemSubgroup","itemSetHeight","marginLeft","_repaintDragLeft","_repaintDragRight","contentLeft","parentWidth","boxWidth","dragLeft","dragRight","_initializeMixinLoaders","renderRefreshRate","renderTimestep","renderTime","maxPhysicsTicksPerRender","physicsDiscreteStepsize","initializing","triggerFunctions","edit","editEdge","connect","del","nodes","mass","radiusMin","radiusMax","shape","image","fontColor","fontSize","fontFace","fontFill","level","highlightColor","borderWidthSelected","edges","widthSelectionMultiplier","hoverWidth","arrowScaleFactor","dash","gap","altLength","inheritColor","configurePhysics","physics","barnesHut","theta","gravitationalConstant","centralGravity","springLength","springConstant","damping","repulsion","nodeDistance","hierarchicalRepulsion","clustering","initialMaxNodes","clusterThreshold","reduceToNodes","chainThreshold","clusterEdgeThreshold","sectorThreshold","screenSizeThreshold","fontSizeMultiplier","maxFontSize","forceAmplification","distanceAmplification","edgeGrowth","nodeScaling","maxNodeSizeIncrements","activeAreaBoxSize","clusterLevelDifference","navigation","keyboard","speed","dataManipulation","initiallyVisible","hierarchicalLayout","levelSeparation","nodeSpacing","layout","freezeForStabilization","smoothCurves","dynamic","roundness","dynamicSmoothCurves","maxVelocity","minVelocity","stabilize","stabilizationIterations","dragNetwork","dragNodes","hideEdgesOnDrag","hideNodesOnDrag","constants","hoverObj","controlNodesActive","navigationHammers","existing","new","animationSpeed","animationEasingFunction","easingTime","sourceScale","targetScale","sourceTranslation","targetTranslation","lockedOnNodeId","lockedOnNodeOffset","images","setOnloadCallback","_redraw","xIncrement","yIncrement","zoomIncrement","_loadPhysicsSystem","_loadSectorSystem","_loadClusterSystem","_loadSelectionSystem","_loadHierarchySystem","_setTranslation","freezeSimulation","cachedFunctions","startedStabilization","stabilized","calculationNodes","calculationNodeIndices","nodeIndices","canvasTopLeft","canvasBottomRight","pointerPosition","areaCenter","previousScale","nodesData","edgesData","nodesListeners","_addNodes","_updateNodes","_removeNodes","edgesListeners","_addEdges","_updateEdges","_removeEdges","moving","timer","_setupHierarchicalLayout","zoomExtent","startWithClustering","mousetrap","MixinLoader","Activator","_getScriptPath","scripts","getElementsByTagName","src","_getRange","node","minY","maxY","minX","maxX","nodeId","_findCenter","animationOptions","initialZoom","disableStart","zoomLevel","numberOfNodes","factor","yDistance","xZoomLevel","yZoomLevel","animation","_updateNodeIndexList","_clearNodeIndexList","idx","dotData","DOTToGraph","gephi","gephiData","parseGephi","_setNodes","_setEdges","_putDataInSector","_resetLevels","_stabilize","onEdit","onEditEdge","onConnect","onDelete","editMode","newColorObj","groupname","clickToUse","activator","_createKeyBinds","_loadNavigationControls","_loadManipulationSystem","_configureSmoothCurves","pinch","_onTap","_onDoubleTap","_onRelease","_onMouseMoveTitle","reset","isActive","_moveUp","_yStopMoving","_moveDown","_moveLeft","_xStopMoving","_moveRight","_zoomIn","_stopZoom","_zoomOut","_createManipulatorBar","_deleteSelected","_getPointer","pinched","_getScale","_handleTouch","_handleDragStart","_getNodeAt","_getTranslation","isSelected","_selectObject","nodeIds","objectId","selectionObj","xFixed","yFixed","_handleOnDrag","releaseNode","_XconvertDOMtoCanvas","_XconvertCanvasToDOM","_YconvertDOMtoCanvas","_YconvertCanvasToDOM","_handleDragEnd","_handleTap","_handleDoubleTap","_handleOnHold","_handleOnRelease","_zoom","scaleOld","preScaleDragPointer","DOMtoCanvas","scaleFrac","tx","ty","updateClustersDefault","postScaleDragPointer","canvasToDOM","popupObj","_checkHidePopup","checkShow","_checkShowPopup","popupTimer","edgeId","_getEdgeAt","_hoverObject","_blurObject","lastPopupNode","getTitle","isOverlappingWith","edge","connected","popup","setPosition","setText","emitEvent","oldWidth","oldHeight","oldNodesData","_updateSelection","angle","_updateCalculationNodes","_reconnectEdges","_updateValueRange","updateLabels","changedData","setProperties","properties","oldEdgesData","oldEdge","disconnect","showInternalIds","_createBezierNodes","via","sectors","dynamicEdges","setValueRange","w","save","translate","_doInAllSectors","restore","offsetX","offsetY","_drawNodes","alwaysShow","setScaleAndPos","inArea","draw","sMax","_drawEdges","_drawControlNodes","_freezeDefinedNodes","_physicsTick","_restoreFrozenNodes","fixedData","_isMoving","vmin","isMoving","_discreteStepNodes","nodesPresent","discreteStepLimited","discreteStep","vminCorrected","mainMovingStatus","supportMovingStatus","_doInAllActiveSectors","mainMoving","_doInSupportSector","_animationStep","_handleNavigation","calculationTime","maxSteps","timeRequired","requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","msRequestAnimationFrame","ua","toLowerCase","requiresTimeout","iterations","toggleFreeze","parentEdgeId","internalMultiplier","positionBezierNode","mixin","storePosition","storePositions","dataArray","allowedToMoveX","allowedToMoveY","getPositions","focusOnNode","nodePosition","lockedOnNode","easingFunction","animateView","locked","_transitionRedraw","viewCenter","distanceFromCenter","_classicRedraw","_lockedRedraw","active","getScale","getCenterCoordinates","networkConstants","fromId","toId","widthSelected","labelDimensions","yLine","dirtyLabel","originalFromId","originalToId","widthFixed","lengthFixed","controlNodesEnabled","controlNodes","positions","connectedNode","_drawLine","_drawArrow","_drawArrowCenter","_drawDashLine","attachEdge","detachEdge","xFrom","yFrom","xTo","yTo","xObj","yObj","_getDistanceToEdge","_getColor","colorObj","_getLineWidth","_line","midpointX","midpointY","_pointOnLine","_label","resize","_circle","_pointOnCircle","networkScaleInv","_getViaCoordinates","xVia","yVia","quadraticCurveTo","lineCount","measureText","fillRect","mozDash","setLineDash","pattern","lineDashOffset","mozDashOffset","lineCap","dashedLine","percentage","atan2","arrow","edgeSegmentLength","fromBorderDist","distanceToBorder","fromBorderPoint","toBorderDist","toBorderPoint","x1","y1","x2","y2","x3","y3","lastX","lastY","minDistance","_getDistanceToLine","px","py","something","u","nodeIdFrom","nodeIdTo","getControlNodePositions","_enableControlNodes","_disableControlNodes","_getSelectedControlNode","fromDistance","toDistance","_restoreControlNodes","defaultIndex","DEFAULT","load","url","brokenUrl","img","Image","onload","onerror","imagelist","grouplist","reroutedEdges","fontDrawThreshold","horizontalAlignLeft","verticalAlignTop","baseRadiusValue","radiusFixed","preassignedLevel","hierarchyEnumerated","fx","fy","vx","vy","resetCluster","dynamicEdgesLength","clusterSession","clusterSizeWidthFactor","clusterSizeHeightFactor","clusterSizeRadiusFactor","growthIndicator","networkScale","formationScale","clusterSize","containedNodes","containedEdges","clusterSessions","originalLabel","triggerFunction","groupObj","imageObj","brokenImage","_drawDatabase","_resizeDatabase","_drawBox","_resizeBox","_drawCircle","_resizeCircle","_drawEllipse","_resizeEllipse","_drawImage","_resizeImage","_drawText","_resizeText","_drawDot","_resizeShape","_drawSquare","_drawTriangle","_drawTriangleDown","_drawStar","_reset","clearSizeCache","_setForce","_addForce","isFixed","velocity","getDistance","globalAlpha","drawImage","textSize","getTextSize","clusterLineWidth","selectionLineWidth","roundRect","database","diameter","circle","defaultSize","ellipse","_drawShape","radiusMultiplier","baseline","labelUnderNode","inView","clearVelocity","updateVelocity","massBeforeClustering","energyBefore","styleAttr","fontFamily","WebkitBorderRadius","whiteSpace","maxWidth","parseDOT","parseGraph","nextPreview","isAlphaNumeric","regexAlphaNumeric","merge","o","addNode","graphs","attr","addEdge","createEdge","getToken","tokenType","TOKENTYPE","NULL","token","isComment","DELIMITER","c2","DELIMITERS","IDENTIFIER","newSyntaxError","UNKNOWN","chop","strict","parseStatements","parseStatement","subgraph","parseSubgraph","parseEdge","parseAttributeStatement","parseNodeStatement","subgraphs","parseAttributeList","message","maxLength","forEach2","array1","array2","elem1","elem2","convertEdge","dotEdge","graphEdge","graphData","dotNode","graphNode","subEdge","{","}","[","]",";","=",",","->","--","gephiJSON","allowedToMove","gEdges","gNodes","gEdge","source","gNode","leftContainer","rightContainer","shadowTop","shadowBottom","shadowTopLeft","shadowBottomLeft","shadowTopRight","shadowBottomRight","listeners","events","args","scrollTop","scrollTopMin","_initAutoResize","component","_stopAutoResize","what","dataRange","getWindow","borderRootHeight","borderRootWidth","autoHeight","centerWidth","_updateScrollTop","visibilityTop","visibilityBottom","repaint","_startAutoResize","_onResize","lastHeight","watchTimer","setInterval","initialScrollTop","oldScrollTop","_getScrollTop","newScrollTop","_setScrollTop","eventType","getTouchList","collectEventData","custom","back","editNode","addDescription","edgeDescription","editEdgeDescription","createEdgeError","deleteClusterError","CanvasRenderingContext2D","square","s2","ir","triangleDown","star","n","r2d","kappa","ox","oy","xe","ye","xm","ym","bezierCurveTo","wEllipse","hEllipse","ymb","yeb","xt","yt","xi","yi","xl","yl","xr","yr","dashArray","dashLength","dashCount","slope","distRemaining","dashIndex","PhysicsMixin","ClusterMixin","SectorsMixin","SelectionMixin","ManipulationMixin","NavigationMixin","HierarchicalLayoutMixin","_loadMixin","sourceVariable","mixinFunction","_clearMixin","_loadSelectedForceSolver","_loadPhysicsConfiguration","hubThreshold","activeSector","drawingNode","blockConnectingEdgeSelection","forceAppendSelection","manipulationDiv","editModeDiv","closeDiv","_cleanNavigation","_loadNavigationElements","overlay","_onTapOverlay","windowHammer","_hasParent","deactivate","escListener","activate","unbind","_callbacks","once","self","removeListener","removeAllListeners","callbacks","cb","hasListeners","__WEBPACK_AMD_DEFINE_RESULT__","setup","READY","Event","determineEventTypes","Utils","each","gestures","Detection","register","onTouch","DOCUMENT","EVENT_MOVE","detect","EVENT_END","Instance","VERSION","defaults","behavior","userSelect","touchAction","touchCallout","contentZooming","userDrag","tapHighlightColor","HAS_POINTEREVENTS","pointerEnabled","msPointerEnabled","HAS_TOUCHEVENTS","IS_MOBILE","NO_MOUSEEVENTS","CALCULATE_INTERVAL","EVENT_TYPES","DIRECTION_DOWN","DIRECTION_LEFT","DIRECTION_UP","DIRECTION_RIGHT","POINTER_MOUSE","POINTER_TOUCH","POINTER_PEN","EVENT_START","EVENT_RELEASE","EVENT_TOUCH","plugins","utils","dest","handler","iterator","context","inStr","find","inArray","hasParent","getCenter","getVelocity","deltaTime","getAngle","touch1","touch2","getDirection","getRotation","isVertical","setPrefixedCss","toggle","prefixes","toCamelCase","toggleBehavior","falseFn","onselectstart","ondragstart","str","preventMouseEvents","started","shouldDetect","hook","onTouchHandler","ev","triggerType","srcType","isPointer","isMouse","buttons","PointerEvent","matchType","updatePointer","doDetect","touchList","touchListLength","triggerChange","trigger","changedLength","changedTouches","evData","identifiers","identifier","pointerType","timeStamp","preventManipulation","stopDetect","pointers","touchlist","pointerEvent","pointerId","pt","MSPOINTER_TYPE_MOUSE","MSPOINTER_TYPE_TOUCH","MSPOINTER_TYPE_PEN","detection","stopped","startDetect","inst","eventData","startEvent","lastEvent","lastCalcEvent","futureCalcEvent","lastCalcData","extendEventData","instOptions","getCalculatedData","recalc","calcEv","calcData","velocityX","velocityY","interimAngle","interimDirection","startEv","lastEv","rotation","eventStartHandler","eventHandlers","createEvent","initEvent","dispatchEvent","state","dispose","eh","dragGesture","dragMaxTouches","triggered","dragMinDistance","startCenter","dragDistanceCorrection","dragLockToAxis","dragLockMinDistance","lastDirection","dragBlockVertical","dragBlockHorizontal","Drag","Gesture","holdGesture","holdTimeout","holdThreshold","Hold","Release","Infinity","Swipe","swipeMinTouches","swipeMaxTouches","swipeVelocityX","swipeVelocityY","tapGesture","sincePrev","didDoubleTap","hasMoved","tapMaxDistance","tapMaxTime","doubleTapInterval","doubleTapDistance","tapAlways","Tap","Touch","preventMouse","transformGesture","scaleThreshold","rotationThreshold","transformMinScale","transformMinRotation","Transform","_addEvent","_characterFromEvent","fromCharCode","_MAP","_KEYCODE_MAP","_stop","tag_name","tagName","contentEditable","_modifiersMatch","modifiers1","modifiers2","_resetSequences","do_not_reset","active_sequences","_sequence_levels","_inside_sequence","_getMatches","character","modifiers","combination","matches","_isModifier","seq","combo","_eventModifiers","altKey","metaKey","_fireCallback","cancelBubble","_handleCharacter","processed_sequence_callback","_handleKey","keyCode","_ignore_next_keyup","_resetSequenceTimer","_reset_timer","_getReverseMap","_REVERSE_MAP","_pickBestAction","_bindSequence","_increaseSequence","_callbackAndReset","_bindSingle","sequence_name","sequence","_SPECIAL_ALIASES","_SHIFT_MAP","_bindMultiple","combinations",8,9,13,16,17,18,20,27,32,33,34,35,36,37,38,39,40,45,46,91,93,224,106,107,109,110,111,186,187,188,189,190,191,192,219,220,221,222,"~","!","@","#","$","%","^","&","*","(",")","_","+",":","\"","<",">","?","|","command","return","escape","_direct_map","global","dfl","hasOwnProp","defaultParsingFlags","empty","unusedTokens","unusedInput","charsLeftOver","nullInput","invalidMonth","invalidFormat","userInvalidated","iso","printMsg","msg","suppressDeprecationWarnings","warn","deprecate","firstTime","deprecateSimple","deprecations","padToken","func","leftZeroFill","ordinalizeToken","period","localeData","ordinal","Locale","Moment","config","skipOverflow","checkOverflow","copyConfig","Duration","normalizedInput","normalizeObjectUnits","years","quarters","quarter","months","weeks","week","days","hour","minute","second","millisecond","_milliseconds","_days","_months","_locale","_bubble","val","_isAMomentObject","_i","_f","_l","_strict","_tzm","_isUTC","_offset","_pf","momentProperties","absRound","number","targetLength","forceSign","output","positiveMomentsDifference","base","res","isAfter","momentsDifference","makeAs","isBefore","createAdder","dur","tmp","addOrSubtractDurationFromMoment","mom","isAdding","updateOffset","setTime","rawSetter","rawGetter","rawMonthSetter","input","compareArrays","dontConvert","lengthDiff","diffs","toInt","normalizeUnits","units","lowered","unitAliases","camelFunctions","inputObject","normalizedProp","makeList","setter","getter","method","results","utc","set","argumentForCoercion","coercedNumber","isFinite","daysInMonth","UTC","getUTCDate","weeksInYear","dow","doy","weekOfYear","daysInYear","isLeapYear","_a","DATE","_overflowDayOfYear","isValid","_isValid","getTime","normalizeLocale","chooseLocale","names","loadLocale","oldLocale","hasModule","code","model","zone","local","removeFormattingTokens","makeFormatFunction","formattingTokens","formatTokenFunctions","formatMoment","expandFormat","formatFunctions","invalidDate","replaceLongDateFormatTokens","longDateFormat","localFormattingTokens","lastIndex","getParseRegexForToken","parseTokenOneDigit","parseTokenThreeDigits","parseTokenFourDigits","parseTokenOneToFourDigits","parseTokenSignedNumber","parseTokenSixDigits","parseTokenOneToSixDigits","parseTokenTwoDigits","parseTokenOneToThreeDigits","parseTokenWord","_meridiemParse","parseTokenTimestampMs","parseTokenTimezone","parseTokenT","parseTokenDigits","parseTokenOneOrTwoDigits","parseTokenOrdinal","RegExp","regexpEscape","unescapeFormat","timezoneMinutesFromString","string","possibleTzMatches","tzChunk","parseTimezoneChunker","addTimeToArrayFromToken","datePartArray","monthsParse","_dayOfYear","parseTwoDigitYear","_isPm","isPM","_useUTC","weekdaysParse","_w","invalidWeekday","dayOfYearFromWeekInfo","weekYear","weekday","temp","GG","W","E","_week","gg","dayOfYearFromWeeks","dateFromConfig","currentDate","yearToUse","currentDateArray","makeUTCDate","getUTCMonth","makeDate","setUTCMinutes","getUTCMinutes","dateFromObject","getUTCFullYear","makeDateFromStringAndFormat","ISO_8601","parseISO","parsedInput","tokens","skipped","stringLength","totalParsedInputLength","matched","p4","makeDateFromStringAndArray","tempConfig","bestMoment","scoreToBeat","currentScore","NaN","score","l","isoRegex","isoDates","isoTimes","makeDateFromString","createFromInputFallback","makeDateFromInput","aspNetJsonRegex","ms","setUTCFullYear","parseWeekday","substituteTimeAgo","withoutSuffix","isFuture","relativeTime","posNegDuration","relativeTimeThresholds","firstDayOfWeek","firstDayOfWeekOfYear","adjustedMoment","daysToDayOfWeek","daysToAdd","getUTCDay","makeMoment","invalid","preparse","pickBy","moments","dayOfMonth","unit","makeAccessor","keepTime","daysToYears","yearsToDays","makeDurationGetter","makeGlobal","shouldDeprecate","ender","oldGlobalMoment","globalScope","aspNetTimeSpanJsonRegex","isoDurationRegex","isoFormat","unitMillisecondFactors","Milliseconds","Seconds","Minutes","Hours","Days","Months","Years","D","Q","DDD","dayofyear","isoweekday","isoweek","weekyear","isoweekyear","ordinalizeTokens","paddedTokens","MMM","monthsShort","MMMM","dd","weekdaysMin","ddd","weekdaysShort","dddd","weekdays","isoWeek","YY","YYYY","YYYYY","YYYYYY","gggg","ggggg","isoWeekYear","GGGG","GGGGG","isoWeekday","meridiem","SS","SSS","SSSS","Z","ZZ","zoneAbbr","zz","zoneName","unix","lists","DDDD","_monthsShort","monthName","regex","_monthsParse","_weekdays","_weekdaysShort","_weekdaysMin","weekdayName","_weekdaysParse","_longDateFormat","LT","L","LL","LLL","LLLL","isLower","_calendar","sameDay","nextDay","nextWeek","lastDay","lastWeek","sameElse","calendar","_relativeTime","future","past","mm","hh","MM","yy","pastFuture","_ordinal","postformat","_invalidDate","ret","parseIso","diffRes","isDuration","inp","version","defaultFormat","relativeTimeThreshold","threshold","limit","defineLocale","_abbr","abbr","langData","flags","parseZone","isDSTShifted","parsingFlags","invalidAt","keepLocalTime","_dateTzOffset","inputString","asFloat","daysAdjust","that","zoneDiff","startOf","humanize","fromNow","sod","isDST","getDay","endOf","isSame","localAdjust","_changeInProgress","hasAlignedHourOffset","isoWeeksInYear","weekInfo","newLocaleData","getTimezoneOffset","isoWeeks","toJSON","withSuffix","toIsoString","asSeconds","asMilliseconds","asMinutes","asHours","asDays","asWeeks","asMonths","asYears","require","noGlobal","clusterToFit","maxNumberOfNodes","reposition","maxLevels","forceAggregateHubs","normalizeClusterLevels","increaseClusterLevel","repositionNodes","openCluster","isMovingBeforeClustering","_nodeInActiveArea","_sector","_addSector","decreaseClusterLevel","_expandClusterNode","_updateDynamicEdges","updateClusters","zoomDirection","recursive","doNotStart","amountOfNodes","_collapseSector","_formClusters","_openClusters","_openClustersBySize","_aggregateHubs","handleChains","chainPercentage","_getChainFraction","_reduceAmountOfChains","_getHubSize","_formClustersByHub","openAll","containedNodeId","childNode","_expelChildFromParent","_unselectAll","_releaseContainedEdges","_connectEdgeBackToChild","_validateEdges","othersPresent","childNodeId","_repositionBezierNodes","_formClustersByZoom","_forceClustersByZoom","minLength","_addToCluster","_clusterToSmallestNeighbour","smallestNeighbour","smallestNeighbourNode","neighbour","onlyEqual","_formClusterFromHub","hubNode","absorptionSizeOffset","allowCluster","edgesIdarray","amountOfInitialEdges","_addToContainedEdges","_connectEdgeToCluster","_containCircularEdgesFromNode","massBefore","correction","edgeToId","edgeFromId","k","_addToReroutedEdges","maxLevel","minLevel","clusterLevel","targetLevel","average","averageSquared","hubCounter","largestHub","variance","standardDeviation","fraction","reduceAmount","chains","total","_switchToSector","sectorId","sectorType","_switchToActiveSector","_switchToFrozenSector","_switchToSupportSector","_loadLatestSector","_previousSector","_setActiveSector","newId","_forgetLastSector","_createNewSector","_deleteActiveSector","_deleteFrozenSector","_freezeSector","_activateSector","_mergeThisWithFrozen","_collapseThisToSingleCluster","sector","unqiueIdentifier","previousSector","runFunction","argument","returnValues","_doInAllFrozenSectors","_drawSectorNodes","_drawAllSectorNodes","_getNodesOverlappingWith","overlappingNodes","_getAllNodesOverlappingWith","_pointerToPositionObject","positionObject","_getEdgesOverlappingWith","overlappingEdges","_getAllEdgesOverlappingWith","_addToSelection","_addToHover","_removeFromSelection","doNotTrigger","_unselectClusters","_getSelectedNodeCount","_getSelectedNode","_getSelectedEdge","_getSelectedEdgeCount","_getSelectedObjectCount","_selectionIsEmpty","_clusterInSelection","_selectConnectedEdges","_hoverConnectedEdges","_unselectConnectedEdges","append","highlightEdges","overrideSelectable","_manipulationReleaseOverload","_navigationReleaseOverload","getSelectedNodes","edgeIds","getSelectedEdges","idArray","selectNodes","RangeError","selectEdges","_clearManipulatorBar","_restoreOverloadedFunctions","functionName","_toggleEditMode","toolbar","getElementById","boundFunction","edgeBeingEdited","selectedControlNode","addNodeButton","_createAddNodeToolbar","addEdgeButton","_createAddEdgeToolbar","editButton","_editNode","_createEditEdgeToolbar","editModeButton","backButton","_addNode","_handleConnect","_finishConnect","_selectControlNode","_controlNodeDrag","_releaseControlNode","newNode","_editEdge","alert","supportNodes","targetNode","connectionEdge","connectFromId","_createEdge","defaultData","finalizedData","sourceNodeId","targetNodeId","selectedNodes","selectedEdges","wrapper","navigationDivs","navigationDivActions","_stopMovement","_zoomExtent","hubsize","definedLevel","undefinedLevel","_changeConstants","_determineLevels","_determineLevelsDirected","distribution","_getDistribution","_placeNodesByHierarchy","minPos","_placeBranchNodes","maxCount","_setLevel","_setLevelDirected","parentId","parentLevel","nodeMoved","_restoreNodes","graphToggleSmoothCurves","graph_toggleSmooth","graphRepositionNodes","showValueOfRange","graphGenerateOptions","optionsSpecific","radioButton1","radioButton2","checked","backupConstants","optionsDiv","switchConfigurations","radioButton","querySelector","tableId","table","constantsVariableName","valueId","rangeValue","_overWriteGraphConstants","RepulsionMixin","HierarchialRepulsionMixin","BarnesHutMixin","_toggleBarnesHut","barnesHutTree","_initializeForceCalculation","_calculateForces","_calculateGravitationalForces","_calculateNodeForces","_calculateSpringForcesWithSupport","_calculateHierarchicalSpringForces","_calculateSpringForces","supportNodeId","gravity","gravityForce","edgeLength","springForce","combinedClusterSize","node1","node2","node3","_calculateSpringForce","physicsConfiguration","hierarchicalLayoutDirections","parentElement","rangeElement","radioButton3","graph_repositionNodes","graph_generateOptions","nameArray","webpackContext","req","resolve","repulsingForce","a_base","minimumDistance","steepness","springFx","springFy","totalFx","totalFy","correctionFx","correctionFy","nodeCount","_formBarnesHutTree","_getForceContribution","children","NW","NE","SW","SE","parentBranch","childrenCount","centerOfMass","calcSize","MAX_VALUE","sizeDiff","minimumTreeSize","rootSize","halfRootSize","centerX","centerY","_splitBranch","_placeInTree","_updateBranchMass","totalMass","totalMassInv","biggestSize","skipMassUpdate","_placeInRegion","region","containedNode","_insertRegion","childSize","_drawTree","_drawBranch","branch","webpackPolyfill","paths"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"vis.map","sources":["./dist/vis.js"],"names":["root","factory","exports","module","define","amd","this","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","util","DOMutil","DataSet","DataView","Graph3d","graph3d","Camera","Filter","Point2d","Point3d","Slider","StepNumber","Timeline","Graph2d","timeline","DateUtil","DataStep","Range","stack","TimeStep","components","items","Item","BackgroundItem","BoxItem","PointItem","RangeItem","Component","CurrentTime","CustomTime","DataAxis","GraphGroup","Group","BackgroundGroup","ItemSet","Legend","LineGraph","TimeAxis","Network","network","Edge","Groups","Images","Node","Popup","dotparser","gephiParser","Graph","Error","moment","hammer","isNumber","object","Number","isString","String","isDate","Date","match","ASPDateRegex","exec","isNaN","parse","isDataTable","google","visualization","DataTable","randomUUID","S4","Math","floor","random","toString","extend","a","i","len","arguments","length","other","prop","hasOwnProperty","selectiveExtend","props","Array","isArray","selectiveDeepExtend","b","TypeError","constructor","Object","undefined","deepExtend","selectiveNotDeepExtend","indexOf","equalArray","convert","type","Boolean","valueOf","isMoment","toDate","getType","toISOString","value","getAbsoluteLeft","elem","getBoundingClientRect","left","window","pageXOffset","getAbsoluteTop","top","pageYOffset","addClassName","className","classes","split","push","join","removeClassName","index","splice","forEach","callback","toArray","array","updateProperty","key","addEventListener","element","action","listener","useCapture","navigator","userAgent","attachEvent","removeEventListener","detachEvent","preventDefault","event","returnValue","getTarget","target","srcElement","nodeType","parentNode","option","asBoolean","defaultValue","asNumber","asString","asSize","asElement","GiveDec","Hex","Value","eval","GiveHex","Dec","parseColor","color","isValidRGB","rgb","substr","RGBToHex","isValidHex","hsv","hexToHSV","lighterColorHSV","h","s","v","min","darkerColorHSV","darkerColorHex","HSVToHex","lighterColorHex","background","border","highlight","hover","hexToRGB","hex","replace","toUpperCase","substring","d","e","f","r","g","red","green","blue","RGBToHSV","minRGB","maxRGB","max","hue","saturation","cssUtil","cssText","styles","style","trim","parts","keys","map","addCssText","currentStyles","newStyles","removeCssText","removeStyles","HSVToRGB","q","t","isOk","test","selectiveBridgeObject","fields","referenceObject","objectTo","create","bridgeObject","mergeOptions","mergeTarget","options","enabled","binarySearch","orderedItems","range","field","field2","maxIterations","iteration","low","high","middle","item","isVisible","start","binarySearchGeneric","sidePreference","newGuess","prevValue","nextValue","found","newLow","newHigh","guess","console","log","easeInOutQuad","end","duration","change","easingFunctions","linear","easeInQuad","easeOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","prepareElements","JSONcontainer","elementType","redundant","used","cleanupElements","removeChild","getSVGElement","svgContainer","shift","document","createElementNS","appendChild","getDOMElement","DOMContainer","insertBefore","createElement","drawPoint","x","y","group","point","drawPoints","setAttributeNS","size","drawBar","width","height","rect","data","_options","_data","_fieldId","fieldId","_type","_subscribers","add","prototype","on","subscribers","subscribe","off","filter","unsubscribe","_trigger","params","senderId","concat","subscriber","addedIds","me","_addItem","columns","_getColumnNames","row","rows","getNumberOfRows","col","cols","getValue","update","updatedIds","updatedData","addOrUpdate","_updateItem","get","ids","firstType","returnType","allowedValues","itemId","_getItem","order","_sort","_filterFields","_appendRow","result","getIds","getDataSet","mappedItems","filteredItem","name","sort","av","bv","remove","removedId","removedIds","_remove","clear","maxField","itemField","minField","distinct","values","fieldType","count","exists","types","raw","converted","JSON","stringify","dataTable","getNumberOfColumns","getColumnId","getColumnLabel","addRow","setValue","_ids","_onEvent","apply","setData","viewOptions","getArguments","defaultFilter","dataSet","added","updated","removed","container","SyntaxError","containerElement","margin","defaultXCenter","defaultYCenter","xLabel","yLabel","zLabel","passValueFn","xValueLabel","yValueLabel","zValueLabel","filterLabel","legendLabel","STYLE","DOT","showPerspective","showGrid","keepAspectRatio","showShadow","showGrayBottom","showTooltip","verticalRatio","animationInterval","animationPreload","camera","eye","dataPoints","colX","colY","colZ","colValue","colFilter","xMin","xStep","xMax","yMin","yStep","yMax","zMin","zStep","zMax","valueMin","valueMax","xBarWidth","yBarWidth","colorAxis","colorGrid","colorDot","colorDotBorder","setOptions","Emitter","_setScale","scale","z","xCenter","yCenter","zCenter","setArmLocation","_convert3Dto2D","point3d","translation","_convertPointToTranslation","_convertTranslationToScreen","ax","ay","az","cx","getCameraLocation","cy","cz","sinTx","sin","getCameraRotation","cosTx","cos","sinTy","cosTy","sinTz","cosTz","dx","dy","dz","bx","by","ex","ey","ez","getArmLength","xcenter","frame","canvas","clientWidth","ycenter","_setBackgroundColor","backgroundColor","fill","stroke","strokeWidth","borderColor","borderWidth","borderStyle","BAR","BARCOLOR","BARSIZE","DOTLINE","DOTCOLOR","DOTSIZE","GRID","LINE","SURFACE","_getStyleNumber","styleName","_determineColumnIndexes","counter","column","getDistinctValues","distinctValues","getColumnRange","minMax","_dataInitialize","rawData","_onChange","dataFilter","setOnLoadCallback","redraw","withBars","defaultXBarWidth","dataX","defaultYBarWidth","dataY","xRange","defaultXMin","defaultXMax","defaultXStep","yRange","defaultYMin","defaultYMax","defaultYStep","zRange","defaultZMin","defaultZMax","defaultZStep","valueRange","defaultValueMin","defaultValueMax","_getDataPoints","sortNumber","obj","dataMatrix","xIndex","yIndex","trans","screen","bottom","pointRight","pointTop","pointCross","hasChildNodes","firstChild","position","overflow","noCanvas","fontWeight","padding","innerHTML","onmousedown","_onMouseDown","ontouchstart","_onTouchStart","onmousewheel","_onWheel","ontooltip","_onTooltip","onkeydown","setSize","_resizeCanvas","clientHeight","animationStart","slider","play","animationStop","stop","_resizeCenter","charAt","parseFloat","setCameraPosition","pos","horizontal","vertical","setArmRotation","distance","setArmLength","getCameraPosition","getArmRotation","_readData","_redrawFilter","animationAutoStart","cameraPosition","styleNumber","tooltip","showAnimationControls","_redrawSlider","_redrawClear","_redrawAxis","_redrawDataGrid","_redrawDataLine","_redrawDataBar","_redrawDataDot","_redrawInfo","_redrawLegend","ctx","getContext","clearRect","widthMin","widthMax","dotSize","right","lineWidth","font","ymin","ymax","_hsv2rgb","strokeStyle","beginPath","moveTo","lineTo","strokeRect","fillStyle","closePath","gridLineLen","step","getCurrent","next","textAlign","textBaseline","fillText","label","visible","setValues","setPlayInterval","onchange","getIndex","selectValue","setOnChangeCallback","lineStyle","getLabel","getSelectedValue","from","to","prettyStep","text","xText","yText","zText","offset","xOffset","yOffset","xMin2d","xMax2d","gridLenX","gridLenY","textMargin","armAngle","H","S","V","R","G","B","C","Hi","X","abs","parseInt","cross","topSideVisible","zAvg","transBottom","dist","sortDepth","aDiff","subtract","bDiff","crossproduct","crossProduct","radius","arc","PI","j","surface","corners","xWidth","yWidth","surfaces","center","avg","transCenter","diff","leftButtonDown","_onMouseUp","which","button","touchDown","startMouseX","getMouseX","startMouseY","getMouseY","startStart","startEnd","startArmRotation","cursor","onmousemove","_onMouseMove","onmouseup","diffX","diffY","horizontalNew","verticalNew","snapAngle","snapValue","round","parameters","emit","delay","mouseX","mouseY","tooltipTimeout","clearTimeout","_hideTooltip","dataPoint","_dataPointFromXY","_showTooltip","setTimeout","ontouchmove","_onTouchMove","ontouchend","_onTouchEnd","delta","wheelDelta","detail","oldLength","newLength","_insideTriangle","triangle","sign","as","bs","cs","distMax","closestDataPoint","closestDist","triangle1","triangle2","distX","distY","sqrt","content","line","dot","dom","borderRadius","boxShadow","borderLeft","contentWidth","offsetWidth","contentHeight","offsetHeight","lineHeight","dotWidth","dotHeight","clientX","targetTouches","clientY","armLocation","armRotation","armLength","cameraLocation","cameraRotation","calculateCameraOrientation","rot","graph","onLoadCallback","loadInBackground","isLoaded","getLoadedProgress","getColumn","getValues","dataView","progress","sub","sum","prev","bar","MozBorderRadius","slide","onclick","togglePlay","onChangeCallback","playTimeout","playInterval","playLoop","setIndex","playNext","interval","clearInterval","getPlayInterval","setPlayLoop","doLoop","onChange","indexToLeft","startClientX","startSlideX","leftToIndex","_start","_end","_step","precision","_current","setRange","setStep","calculatePrettyStep","log10","LN10","step1","pow","step2","step5","toPrecision","getStep","groups","forthArgument","defaultOptions","autoResize","orientation","maxHeight","minHeight","_create","body","domProps","emitter","bind","hiddenDates","snap","toScreen","_toScreen","toGlobalScreen","_toGlobalScreen","toTime","_toTime","toGlobalTime","_toGlobalTime","timeAxis","currentTime","customTime","itemSet","itemsData","groupsData","setGroups","setItems","Core","newDataSet","initialLoad","setWindow","animate","fit","setSelection","focus","getSelection","itemData","getItemRange","dataset","minItem","maxStartItem","maxEndItem","linegraph","getLegend","groupId","isGroupVisible","visibility","convertHiddenOptions","repeat","dateItem","updateHiddenDates","centerContainer","totalRange","pixelTime","startDate","endDate","_d","runUntil","clone","day","dayOfYear","year","dayOffset","date","month","removeDuplicates","startHidden","isHidden","endHidden","rangeStart","rangeEnd","hidden","startToFront","endToFront","_applyRange","safeDates","printDates","dates","stepOverHiddenDates","timeStep","previousTime","stepInHidden","currentValue","current","newValue","switchedYear","switchedMonth","switchedDay","checkFirstStep","time","getHiddenDurationBetween","correctTimeForHidden","conversion","hiddenDuration","totalDuration","partialDuration","accumulatedHiddenDuration","getAccumulatedHiddenDuration","newTime","getHiddenDurationBefore","timeOffset","requiredDuration","previousPoint","snapAwayFromHidden","direction","correctionEnabled","minimumStep","containerHeight","customRange","autoScale","stepIndex","marginStart","marginEnd","deadSpace","majorSteps","minorSteps","setMinimumStep","setFirst","safeSize","minimumStepValue","orderOfMagnitude","minorStepIdx","magnitudefactor","solutionFound","stepSize","niceStart","niceEnd","roundToMinor","marginRange","rounded","hasNext","previous","slice","isMajor","now","hours","minutes","seconds","milliseconds","deltaDifference","scaleOffset","moveable","zoomable","zoomMin","zoomMax","touch","animateTimer","_onDragStart","_onDrag","_onDragEnd","_onHold","_onMouseWheel","_onTouch","_onPinch","validateDirection","getPointer","pageX","pageY","hammerUtil","dragging","initTime","done","initStart","initEnd","changed","anyChanged","_cancelAnimation","newStart","newEnd","getRange","totalHidden","previousDelta","allowDragging","gesture","deltaX","deltaY","diffRange","safeStart","safeEnd","fakeGesture","pointer","pointerDate","_pointerToDate","zoom","touches","hiddenDurationBefore","hiddenDurationAfter","move","EPSILON","orderByStart","orderByEnd","aTime","bTime","force","iMax","axis","collidingItem","jj","collision","nostack","subgroups","newTop","subgroup","SCALE","DAY","MILLISECOND","SECOND","MINUTE","HOUR","WEEKDAY","MONTH","YEAR","first","setFullYear","getFullYear","setMonth","setDate","setHours","setMinutes","setSeconds","setMilliseconds","getMilliseconds","getSeconds","getMinutes","getHours","getDate","getMonth","setScale","newScale","newStep","setAutoScale","enable","stepYear","stepMonth","stepDay","stepHour","stepMinute","stepSecond","stepMillisecond","getLabelMinor","format","getLabelMajor","destroy","_isResized","resized","_previousWidth","_previousHeight","showCurrentTime","locales","locale","parent","backgroundVertical","title","currentTimeTimer","setCurrentTime","getCurrentTime","showCustomTime","eventParams","Hammer","drag","prevent_default","setCustomTime","getCustomTime","stopPropagation","svg","linegraphOptions","showMinorLabels","showMajorLabels","icons","majorLinesOffset","minorLinesOffset","labelOffsetX","labelOffsetY","iconWidth","linegraphSVG","DOMelements","lines","labels","conversionFactor","minWidth","stepPixels","stepPixelsForced","lineOffset","master","svgElements","amountOfGroups","addGroup","graphOptions","updateGroup","removeGroup","hide","show","lineContainer","display","_redrawGroupIcons","iconHeight","iconOffset","drawIcon","backgroundHorizontal","changeCalled","activeGroups","_calculateCharSize","minorLabelHeight","minorCharHeight","majorLabelHeight","majorCharHeight","minorLineWidth","minorLineHeight","majorLineWidth","majorLineHeight","_redrawLabels","amountOfSteps","stepDifference","valueAtZero","marginStartPos","maxLabelSize","_redrawLabel","_redrawLine","convertValue","invertedValue","convertedValue","characterHeight","largestWidth","majorCharWidth","minorCharWidth","textMinor","createTextNode","measureCharMinor","textMajor","measureCharMajor","groupsUsingDefaultStyles","usingDefaultStyle","zeroPosition","setZeroPosition","catmullRom","parametrization","alpha","SVGcontainer","path","fillPath","fillHeight","outline","shaded","barWidth","bar1Height","bar2Height","icon","yAxisOrientation","subgroupIndex","subgroupOrderer","subgroupOrder","visibleItems","byStart","byEnd","inner","foreground","marker","Element","getLabelWidth","restack","_updateVisibleItems","markerHeight","lastMarkerHeight","dirty","displayed","_calculateHeight","offsetTop","offsetLeft","ii","repositionY","resetSubgroups","labelSet","setParent","orderSubgroups","_checkIfVisible","sortArray","sortField","removeFromDataSet","removeItem","_constructByEndArray","endArray","initialPosByStart","newVisibleItems","initialPosByEnd","_checkIfInvisible","repositionX","align","groupOrder","selectable","editable","updateTime","onAdd","onUpdate","onMove","onRemove","onMoving","itemOptions","itemListeners","_onAdd","_onUpdate","_onRemove","groupListeners","_onAddGroups","_onUpdateGroups","_onRemoveGroups","groupIds","selection","stackDirty","touchParams","UNGROUPED","BACKGROUND","box","_updateUngrouped","backgroundGroup","_onSelectItem","_onMultiSelectItem","_onAddItem","addCallback","fn","Function","markDirty","unselect","select","getVisibleItems","rawVisibleItems","_deselect","_orderGroups","visibleInterval","zoomed","lastVisibleInterval","lastWidth","firstGroup","_firstGroup","firstMargin","nonFirstMargin","groupMargin","groupResized","firstGroupIndex","firstGroupId","ungrouped","_getGroupId","getLabelSet","oldItemsData","getItems","_order","getGroups","_getType","_removeItem","groupData","groupOptions","oldGroupId","oldGroup","itemFromTarget","initialX","selected","dragLeftItem","dragRightItem","itemProps","newProps","initial","groupFromTarget","_updateItemProps","_moveToGroup","changes","ctrlKey","srcEvent","shiftKey","oldSelection","newSelection","xAbs","newItem","itemSetFromTarget","side","iconSize","iconSpacing","textArea","drawLegendIcons","getComputedStyle","paddingTop","defaultGroup","sampling","graphHeight","barChart","handleOverlap","dataAxis","legend","abortedGraphUpdate","lastStart","_updateGraph","yAxisLeft","yAxisRight","legendLeft","legendRight","_updateAllGroupData","_updateGroup","groupsContent","ungroupedCounter","rangePerPixelInv","preprocessedGroupData","processedGroupData","groupRanges","minDate","maxDate","_getRelevantData","_convertXcoordinates","_getYRanges","_updateYAxis","_convertYcoordinates","_drawLineGraph","_drawBarGraphs","dataContainer","_applySampling","increment","amountOfPoints","xDistance","pointsPerPixel","ceil","sampledData","barCombinedData","barCombinedDataLeft","barCombinedDataRight","ignore","intersections","_getDataIntersections","_getStackedBarYRange","combinedData","accumulated","xpos","minVal","maxVal","yAxisLeftUsed","yAxisRightUsed","minLeft","minRight","maxLeft","maxRight","_toggleAxisVisiblity","drawIcons","axisUsed","coreDistance","drawData","barPoints","heightOffset","_getSafeDrawData","nextKey","amount","resolved","prevKey","svgHeight","_catmullRom","_linear","dFill","_drawPoints","datapoints","xValue","yValue","extractedData","_catmullRomUniform","p0","p1","p2","p3","bp1","bp2","normalization","d1","d2","d3","A","N","M","d3powA","d2powA","d3pow2A","d2pow2A","d1pow2A","d1powA","majorLines","majorTexts","minorLines","minorTexts","lineTop","lang","parentChanged","foregroundNextSibling","nextSibling","backgroundNextSibling","_repaintLabels","timeLabelsize","xFirstMajorLabel","cur","_repaintMinorText","_repaintMajorText","_repaintMajorLine","_repaintMinorLine","leftTime","leftText","widthText","arr","pop","childNodes","nodeValue","_repaintDeleteButton","anchor","deleteButton","_updateContents","template","_updateTitle","removeAttribute","_updateDataAttributes","dataAttributes","attributes","setAttribute","_updateStyle","emptyContent","baseClassName","onTop","itemSubgroup","itemSetHeight","marginLeft","_repaintDragLeft","_repaintDragRight","contentLeft","parentWidth","boxWidth","dragLeft","dragRight","_initializeMixinLoaders","renderRefreshRate","renderTimestep","renderTime","maxPhysicsTicksPerRender","physicsDiscreteStepsize","initializing","triggerFunctions","edit","editEdge","connect","del","nodes","mass","radiusMin","radiusMax","shape","image","fontColor","fontSize","fontFace","fontFill","level","highlightColor","borderWidthSelected","edges","widthSelectionMultiplier","hoverWidth","arrowScaleFactor","dash","gap","altLength","inheritColor","configurePhysics","physics","barnesHut","theta","gravitationalConstant","centralGravity","springLength","springConstant","damping","repulsion","nodeDistance","hierarchicalRepulsion","clustering","initialMaxNodes","clusterThreshold","reduceToNodes","chainThreshold","clusterEdgeThreshold","sectorThreshold","screenSizeThreshold","fontSizeMultiplier","maxFontSize","forceAmplification","distanceAmplification","edgeGrowth","nodeScaling","maxNodeSizeIncrements","activeAreaBoxSize","clusterLevelDifference","navigation","keyboard","speed","dataManipulation","initiallyVisible","hierarchicalLayout","levelSeparation","nodeSpacing","layout","freezeForStabilization","smoothCurves","dynamic","roundness","dynamicSmoothCurves","maxVelocity","minVelocity","stabilize","stabilizationIterations","dragNetwork","dragNodes","hideEdgesOnDrag","hideNodesOnDrag","constants","hoverObj","controlNodesActive","navigationHammers","existing","new","animationSpeed","animationEasingFunction","easingTime","sourceScale","targetScale","sourceTranslation","targetTranslation","lockedOnNodeId","lockedOnNodeOffset","images","setOnloadCallback","_redraw","xIncrement","yIncrement","zoomIncrement","_loadPhysicsSystem","_loadSectorSystem","_loadClusterSystem","_loadSelectionSystem","_loadHierarchySystem","_setTranslation","freezeSimulation","cachedFunctions","startedStabilization","stabilized","calculationNodes","calculationNodeIndices","nodeIndices","canvasTopLeft","canvasBottomRight","pointerPosition","areaCenter","previousScale","nodesData","edgesData","nodesListeners","_addNodes","_updateNodes","_removeNodes","edgesListeners","_addEdges","_updateEdges","_removeEdges","moving","timer","_setupHierarchicalLayout","zoomExtent","startWithClustering","mousetrap","MixinLoader","Activator","_getScriptPath","scripts","getElementsByTagName","src","_getRange","node","minY","maxY","minX","maxX","nodeId","_findCenter","animationOptions","initialZoom","disableStart","zoomLevel","numberOfNodes","factor","yDistance","xZoomLevel","yZoomLevel","animation","_updateNodeIndexList","_clearNodeIndexList","idx","dotData","DOTToGraph","gephi","gephiData","parseGephi","_setNodes","_setEdges","_putDataInSector","_resetLevels","_stabilize","onEdit","onEditEdge","onConnect","onDelete","editMode","newColorObj","groupname","clickToUse","activator","_createKeyBinds","_loadNavigationControls","_loadManipulationSystem","_configureSmoothCurves","pinch","_onTap","_onDoubleTap","_onRelease","_onMouseMoveTitle","reset","isActive","_moveUp","_yStopMoving","_moveDown","_moveLeft","_xStopMoving","_moveRight","_zoomIn","_stopZoom","_zoomOut","_createManipulatorBar","_deleteSelected","_getPointer","pinched","_getScale","_handleTouch","_handleDragStart","_getNodeAt","_getTranslation","isSelected","_selectObject","nodeIds","objectId","selectionObj","xFixed","yFixed","_handleOnDrag","releaseNode","_XconvertDOMtoCanvas","_XconvertCanvasToDOM","_YconvertDOMtoCanvas","_YconvertCanvasToDOM","_handleDragEnd","_handleTap","_handleDoubleTap","_handleOnHold","_handleOnRelease","_zoom","scaleOld","preScaleDragPointer","DOMtoCanvas","scaleFrac","tx","ty","updateClustersDefault","postScaleDragPointer","canvasToDOM","popupObj","_checkHidePopup","checkShow","_checkShowPopup","popupTimer","edgeId","_getEdgeAt","_hoverObject","_blurObject","lastPopupNode","getTitle","isOverlappingWith","edge","connected","popup","setPosition","setText","emitEvent","oldWidth","oldHeight","oldNodesData","_updateSelection","angle","_updateCalculationNodes","_reconnectEdges","_updateValueRange","updateLabels","changedData","setProperties","properties","oldEdgesData","oldEdge","disconnect","showInternalIds","_createBezierNodes","via","sectors","dynamicEdges","setValueRange","w","save","translate","_doInAllSectors","restore","offsetX","offsetY","_drawNodes","alwaysShow","setScaleAndPos","inArea","draw","sMax","_drawEdges","_drawControlNodes","_freezeDefinedNodes","_physicsTick","_restoreFrozenNodes","fixedData","_isMoving","vmin","isMoving","_discreteStepNodes","nodesPresent","discreteStepLimited","discreteStep","vminCorrected","mainMovingStatus","supportMovingStatus","_doInAllActiveSectors","mainMoving","_doInSupportSector","_animationStep","_handleNavigation","calculationTime","maxSteps","timeRequired","requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","msRequestAnimationFrame","ua","toLowerCase","requiresTimeout","iterations","toggleFreeze","parentEdgeId","internalMultiplier","positionBezierNode","mixin","storePosition","storePositions","dataArray","allowedToMoveX","allowedToMoveY","getPositions","focusOnNode","nodePosition","lockedOnNode","easingFunction","animateView","locked","_transitionRedraw","viewCenter","distanceFromCenter","_classicRedraw","_lockedRedraw","active","getScale","getCenterCoordinates","networkConstants","fromId","toId","widthSelected","labelDimensions","yLine","dirtyLabel","originalFromId","originalToId","widthFixed","lengthFixed","controlNodesEnabled","controlNodes","positions","connectedNode","_drawLine","_drawArrow","_drawArrowCenter","_drawDashLine","attachEdge","detachEdge","xFrom","yFrom","xTo","yTo","xObj","yObj","_getDistanceToEdge","_getColor","colorObj","_getLineWidth","_line","midpointX","midpointY","_pointOnLine","_label","resize","_circle","_pointOnCircle","networkScaleInv","_getViaCoordinates","xVia","yVia","quadraticCurveTo","lineCount","measureText","fillRect","mozDash","setLineDash","pattern","lineDashOffset","mozDashOffset","lineCap","dashedLine","percentage","atan2","arrow","edgeSegmentLength","fromBorderDist","distanceToBorder","fromBorderPoint","toBorderDist","toBorderPoint","x1","y1","x2","y2","x3","y3","lastX","lastY","minDistance","_getDistanceToLine","px","py","something","u","nodeIdFrom","nodeIdTo","getControlNodePositions","_enableControlNodes","_disableControlNodes","_getSelectedControlNode","fromDistance","toDistance","_restoreControlNodes","defaultIndex","DEFAULT","load","url","brokenUrl","img","Image","onload","onerror","imagelist","grouplist","reroutedEdges","fontDrawThreshold","horizontalAlignLeft","verticalAlignTop","baseRadiusValue","radiusFixed","preassignedLevel","hierarchyEnumerated","fx","fy","vx","vy","resetCluster","dynamicEdgesLength","clusterSession","clusterSizeWidthFactor","clusterSizeHeightFactor","clusterSizeRadiusFactor","growthIndicator","networkScale","formationScale","clusterSize","containedNodes","containedEdges","clusterSessions","originalLabel","triggerFunction","groupObj","imageObj","brokenImage","_drawDatabase","_resizeDatabase","_drawBox","_resizeBox","_drawCircle","_resizeCircle","_drawEllipse","_resizeEllipse","_drawImage","_resizeImage","_drawText","_resizeText","_drawDot","_resizeShape","_drawSquare","_drawTriangle","_drawTriangleDown","_drawStar","_reset","clearSizeCache","_setForce","_addForce","isFixed","velocity","getDistance","globalAlpha","drawImage","textSize","getTextSize","clusterLineWidth","selectionLineWidth","roundRect","database","diameter","circle","defaultSize","ellipse","_drawShape","radiusMultiplier","baseline","labelUnderNode","inView","clearVelocity","updateVelocity","massBeforeClustering","energyBefore","styleAttr","fontFamily","WebkitBorderRadius","whiteSpace","maxWidth","parseDOT","parseGraph","nextPreview","isAlphaNumeric","regexAlphaNumeric","merge","o","addNode","graphs","attr","addEdge","createEdge","getToken","tokenType","TOKENTYPE","NULL","token","isComment","DELIMITER","c2","DELIMITERS","IDENTIFIER","newSyntaxError","UNKNOWN","chop","strict","parseStatements","parseStatement","subgraph","parseSubgraph","parseEdge","parseAttributeStatement","parseNodeStatement","subgraphs","parseAttributeList","message","maxLength","forEach2","array1","array2","elem1","elem2","convertEdge","dotEdge","graphEdge","graphData","dotNode","graphNode","subEdge","{","}","[","]",";","=",",","->","--","gephiJSON","allowedToMove","gEdges","gNodes","gEdge","source","gNode","leftContainer","rightContainer","shadowTop","shadowBottom","shadowTopLeft","shadowBottomLeft","shadowTopRight","shadowBottomRight","listeners","events","args","scrollTop","scrollTopMin","_initAutoResize","component","_stopAutoResize","what","dataRange","getWindow","borderRootHeight","borderRootWidth","autoHeight","centerWidth","_updateScrollTop","visibilityTop","visibilityBottom","repaint","_startAutoResize","_onResize","lastHeight","watchTimer","setInterval","initialScrollTop","oldScrollTop","_getScrollTop","newScrollTop","_setScrollTop","eventType","getTouchList","collectEventData","custom","back","editNode","addDescription","edgeDescription","editEdgeDescription","createEdgeError","deleteClusterError","CanvasRenderingContext2D","square","s2","ir","triangleDown","star","n","r2d","kappa","ox","oy","xe","ye","xm","ym","bezierCurveTo","wEllipse","hEllipse","ymb","yeb","xt","yt","xi","yi","xl","yl","xr","yr","dashArray","dashLength","dashCount","slope","distRemaining","dashIndex","PhysicsMixin","ClusterMixin","SectorsMixin","SelectionMixin","ManipulationMixin","NavigationMixin","HierarchicalLayoutMixin","_loadMixin","sourceVariable","mixinFunction","_clearMixin","_loadSelectedForceSolver","_loadPhysicsConfiguration","hubThreshold","activeSector","drawingNode","blockConnectingEdgeSelection","forceAppendSelection","manipulationDiv","editModeDiv","closeDiv","_cleanNavigation","_loadNavigationElements","overlay","_onTapOverlay","windowHammer","_hasParent","deactivate","escListener","activate","unbind","_callbacks","once","self","removeListener","removeAllListeners","callbacks","cb","hasListeners","__WEBPACK_AMD_DEFINE_RESULT__","global","dfl","hasOwnProp","defaultParsingFlags","empty","unusedTokens","unusedInput","charsLeftOver","nullInput","invalidMonth","invalidFormat","userInvalidated","iso","printMsg","msg","suppressDeprecationWarnings","warn","deprecate","firstTime","deprecateSimple","deprecations","padToken","func","leftZeroFill","ordinalizeToken","period","localeData","ordinal","Locale","Moment","config","skipOverflow","checkOverflow","copyConfig","Duration","normalizedInput","normalizeObjectUnits","years","quarters","quarter","months","weeks","week","days","hour","minute","second","millisecond","_milliseconds","_days","_months","_locale","_bubble","val","_isAMomentObject","_i","_f","_l","_strict","_tzm","_isUTC","_offset","_pf","momentProperties","absRound","number","targetLength","forceSign","output","positiveMomentsDifference","base","res","isAfter","momentsDifference","makeAs","isBefore","createAdder","dur","tmp","addOrSubtractDurationFromMoment","mom","isAdding","updateOffset","setTime","rawSetter","rawGetter","rawMonthSetter","input","compareArrays","dontConvert","lengthDiff","diffs","toInt","normalizeUnits","units","lowered","unitAliases","camelFunctions","inputObject","normalizedProp","makeList","setter","getter","method","results","utc","set","argumentForCoercion","coercedNumber","isFinite","daysInMonth","UTC","getUTCDate","weeksInYear","dow","doy","weekOfYear","daysInYear","isLeapYear","_a","DATE","_overflowDayOfYear","isValid","_isValid","getTime","normalizeLocale","chooseLocale","names","loadLocale","oldLocale","hasModule","code","model","zone","local","removeFormattingTokens","makeFormatFunction","formattingTokens","formatTokenFunctions","formatMoment","expandFormat","formatFunctions","invalidDate","replaceLongDateFormatTokens","longDateFormat","localFormattingTokens","lastIndex","getParseRegexForToken","parseTokenOneDigit","parseTokenThreeDigits","parseTokenFourDigits","parseTokenOneToFourDigits","parseTokenSignedNumber","parseTokenSixDigits","parseTokenOneToSixDigits","parseTokenTwoDigits","parseTokenOneToThreeDigits","parseTokenWord","_meridiemParse","parseTokenTimestampMs","parseTokenTimezone","parseTokenT","parseTokenDigits","parseTokenOneOrTwoDigits","parseTokenOrdinal","RegExp","regexpEscape","unescapeFormat","timezoneMinutesFromString","string","possibleTzMatches","tzChunk","parseTimezoneChunker","addTimeToArrayFromToken","datePartArray","monthsParse","_dayOfYear","parseTwoDigitYear","_isPm","isPM","_useUTC","weekdaysParse","_w","invalidWeekday","dayOfYearFromWeekInfo","weekYear","weekday","temp","GG","W","E","_week","gg","dayOfYearFromWeeks","dateFromConfig","currentDate","yearToUse","currentDateArray","makeUTCDate","getUTCMonth","makeDate","setUTCMinutes","getUTCMinutes","dateFromObject","getUTCFullYear","makeDateFromStringAndFormat","ISO_8601","parseISO","parsedInput","tokens","skipped","stringLength","totalParsedInputLength","matched","p4","makeDateFromStringAndArray","tempConfig","bestMoment","scoreToBeat","currentScore","NaN","score","l","isoRegex","isoDates","isoTimes","makeDateFromString","createFromInputFallback","makeDateFromInput","aspNetJsonRegex","ms","setUTCFullYear","parseWeekday","substituteTimeAgo","withoutSuffix","isFuture","relativeTime","posNegDuration","relativeTimeThresholds","firstDayOfWeek","firstDayOfWeekOfYear","adjustedMoment","daysToDayOfWeek","daysToAdd","getUTCDay","makeMoment","invalid","preparse","pickBy","moments","dayOfMonth","unit","makeAccessor","keepTime","daysToYears","yearsToDays","makeDurationGetter","makeGlobal","shouldDeprecate","ender","oldGlobalMoment","globalScope","VERSION","aspNetTimeSpanJsonRegex","isoDurationRegex","isoFormat","unitMillisecondFactors","Milliseconds","Seconds","Minutes","Hours","Days","Months","Years","D","Q","DDD","dayofyear","isoweekday","isoweek","weekyear","isoweekyear","ordinalizeTokens","paddedTokens","MMM","monthsShort","MMMM","dd","weekdaysMin","ddd","weekdaysShort","dddd","weekdays","isoWeek","YY","YYYY","YYYYY","YYYYYY","gggg","ggggg","isoWeekYear","GGGG","GGGGG","isoWeekday","meridiem","SS","SSS","SSSS","Z","ZZ","zoneAbbr","zz","zoneName","unix","lists","DDDD","_monthsShort","monthName","regex","_monthsParse","_weekdays","_weekdaysShort","_weekdaysMin","weekdayName","_weekdaysParse","_longDateFormat","LT","L","LL","LLL","LLLL","isLower","_calendar","sameDay","nextDay","nextWeek","lastDay","lastWeek","sameElse","calendar","_relativeTime","future","past","mm","hh","MM","yy","pastFuture","_ordinal","postformat","_invalidDate","ret","parseIso","diffRes","isDuration","inp","version","defaultFormat","relativeTimeThreshold","threshold","limit","defineLocale","_abbr","abbr","langData","flags","parseZone","isDSTShifted","parsingFlags","invalidAt","keepLocalTime","_dateTzOffset","inputString","asFloat","daysAdjust","that","zoneDiff","startOf","humanize","fromNow","sod","isDST","getDay","endOf","isSame","localAdjust","_changeInProgress","hasAlignedHourOffset","isoWeeksInYear","weekInfo","newLocaleData","getTimezoneOffset","isoWeeks","toJSON","withSuffix","toIsoString","asSeconds","asMilliseconds","asMinutes","asHours","asDays","asWeeks","asMonths","asYears","require","noGlobal","setup","READY","Event","determineEventTypes","Utils","each","gestures","Detection","register","onTouch","DOCUMENT","EVENT_MOVE","detect","EVENT_END","Instance","defaults","behavior","userSelect","touchAction","touchCallout","contentZooming","userDrag","tapHighlightColor","HAS_POINTEREVENTS","pointerEnabled","msPointerEnabled","HAS_TOUCHEVENTS","IS_MOBILE","NO_MOUSEEVENTS","CALCULATE_INTERVAL","EVENT_TYPES","DIRECTION_DOWN","DIRECTION_LEFT","DIRECTION_UP","DIRECTION_RIGHT","POINTER_MOUSE","POINTER_TOUCH","POINTER_PEN","EVENT_START","EVENT_RELEASE","EVENT_TOUCH","plugins","utils","dest","handler","iterator","context","inStr","find","inArray","hasParent","getCenter","getVelocity","deltaTime","getAngle","touch1","touch2","getDirection","getRotation","isVertical","setPrefixedCss","toggle","prefixes","toCamelCase","toggleBehavior","falseFn","onselectstart","ondragstart","str","preventMouseEvents","started","shouldDetect","hook","onTouchHandler","ev","triggerType","srcType","isPointer","isMouse","buttons","PointerEvent","matchType","updatePointer","doDetect","touchList","touchListLength","triggerChange","trigger","changedLength","changedTouches","evData","identifiers","identifier","pointerType","timeStamp","preventManipulation","stopDetect","pointers","touchlist","pointerEvent","pointerId","pt","MSPOINTER_TYPE_MOUSE","MSPOINTER_TYPE_TOUCH","MSPOINTER_TYPE_PEN","detection","stopped","startDetect","inst","eventData","startEvent","lastEvent","lastCalcEvent","futureCalcEvent","lastCalcData","extendEventData","instOptions","getCalculatedData","recalc","calcEv","calcData","velocityX","velocityY","interimAngle","interimDirection","startEv","lastEv","rotation","eventStartHandler","eventHandlers","createEvent","initEvent","dispatchEvent","state","dispose","eh","dragGesture","dragMaxTouches","triggered","dragMinDistance","startCenter","dragDistanceCorrection","dragLockToAxis","dragLockMinDistance","lastDirection","dragBlockVertical","dragBlockHorizontal","Drag","Gesture","holdGesture","holdTimeout","holdThreshold","Hold","Release","Infinity","Swipe","swipeMinTouches","swipeMaxTouches","swipeVelocityX","swipeVelocityY","tapGesture","sincePrev","didDoubleTap","hasMoved","tapMaxDistance","tapMaxTime","doubleTapInterval","doubleTapDistance","tapAlways","Tap","Touch","preventMouse","transformGesture","scaleThreshold","rotationThreshold","transformMinScale","transformMinRotation","Transform","_addEvent","_characterFromEvent","fromCharCode","_MAP","_KEYCODE_MAP","_stop","tag_name","tagName","contentEditable","_modifiersMatch","modifiers1","modifiers2","_resetSequences","do_not_reset","active_sequences","_sequence_levels","_inside_sequence","_getMatches","character","modifiers","combination","matches","_isModifier","seq","combo","_eventModifiers","altKey","metaKey","_fireCallback","cancelBubble","_handleCharacter","processed_sequence_callback","_handleKey","keyCode","_ignore_next_keyup","_resetSequenceTimer","_reset_timer","_getReverseMap","_REVERSE_MAP","_pickBestAction","_bindSequence","_increaseSequence","_callbackAndReset","_bindSingle","sequence_name","sequence","_SPECIAL_ALIASES","_SHIFT_MAP","_bindMultiple","combinations",8,9,13,16,17,18,20,27,32,33,34,35,36,37,38,39,40,45,46,91,93,224,106,107,109,110,111,186,187,188,189,190,191,192,219,220,221,222,"~","!","@","#","$","%","^","&","*","(",")","_","+",":","\"","<",">","?","|","command","return","escape","_direct_map","clusterToFit","maxNumberOfNodes","reposition","maxLevels","forceAggregateHubs","normalizeClusterLevels","increaseClusterLevel","repositionNodes","openCluster","isMovingBeforeClustering","_nodeInActiveArea","_sector","_addSector","decreaseClusterLevel","_expandClusterNode","_updateDynamicEdges","updateClusters","zoomDirection","recursive","doNotStart","amountOfNodes","_collapseSector","_formClusters","_openClusters","_openClustersBySize","_aggregateHubs","handleChains","chainPercentage","_getChainFraction","_reduceAmountOfChains","_getHubSize","_formClustersByHub","openAll","containedNodeId","childNode","_expelChildFromParent","_unselectAll","_releaseContainedEdges","_connectEdgeBackToChild","_validateEdges","othersPresent","childNodeId","_repositionBezierNodes","_formClustersByZoom","_forceClustersByZoom","minLength","_addToCluster","_clusterToSmallestNeighbour","smallestNeighbour","smallestNeighbourNode","neighbour","onlyEqual","_formClusterFromHub","hubNode","absorptionSizeOffset","allowCluster","edgesIdarray","amountOfInitialEdges","_addToContainedEdges","_connectEdgeToCluster","_containCircularEdgesFromNode","massBefore","correction","edgeToId","edgeFromId","k","_addToReroutedEdges","maxLevel","minLevel","clusterLevel","targetLevel","average","averageSquared","hubCounter","largestHub","variance","standardDeviation","fraction","reduceAmount","chains","total","_switchToSector","sectorId","sectorType","_switchToActiveSector","_switchToFrozenSector","_switchToSupportSector","_loadLatestSector","_previousSector","_setActiveSector","newId","_forgetLastSector","_createNewSector","_deleteActiveSector","_deleteFrozenSector","_freezeSector","_activateSector","_mergeThisWithFrozen","_collapseThisToSingleCluster","sector","unqiueIdentifier","previousSector","runFunction","argument","returnValues","_doInAllFrozenSectors","_drawSectorNodes","_drawAllSectorNodes","_getNodesOverlappingWith","overlappingNodes","_getAllNodesOverlappingWith","_pointerToPositionObject","positionObject","_getEdgesOverlappingWith","overlappingEdges","_getAllEdgesOverlappingWith","_addToSelection","_addToHover","_removeFromSelection","doNotTrigger","_unselectClusters","_getSelectedNodeCount","_getSelectedNode","_getSelectedEdge","_getSelectedEdgeCount","_getSelectedObjectCount","_selectionIsEmpty","_clusterInSelection","_selectConnectedEdges","_hoverConnectedEdges","_unselectConnectedEdges","append","highlightEdges","overrideSelectable","_manipulationReleaseOverload","_navigationReleaseOverload","getSelectedNodes","edgeIds","getSelectedEdges","idArray","selectNodes","RangeError","selectEdges","_clearManipulatorBar","_restoreOverloadedFunctions","functionName","_toggleEditMode","toolbar","getElementById","boundFunction","edgeBeingEdited","selectedControlNode","addNodeButton","_createAddNodeToolbar","addEdgeButton","_createAddEdgeToolbar","editButton","_editNode","_createEditEdgeToolbar","editModeButton","backButton","_addNode","_handleConnect","_finishConnect","_selectControlNode","_controlNodeDrag","_releaseControlNode","newNode","_editEdge","alert","supportNodes","targetNode","connectionEdge","connectFromId","_createEdge","defaultData","finalizedData","sourceNodeId","targetNodeId","selectedNodes","selectedEdges","wrapper","navigationDivs","navigationDivActions","_stopMovement","_zoomExtent","hubsize","definedLevel","undefinedLevel","_changeConstants","_determineLevels","_determineLevelsDirected","distribution","_getDistribution","_placeNodesByHierarchy","minPos","_placeBranchNodes","maxCount","_setLevel","_setLevelDirected","parentId","parentLevel","nodeMoved","_restoreNodes","graphToggleSmoothCurves","graph_toggleSmooth","graphRepositionNodes","showValueOfRange","graphGenerateOptions","optionsSpecific","radioButton1","radioButton2","checked","backupConstants","optionsDiv","switchConfigurations","radioButton","querySelector","tableId","table","constantsVariableName","valueId","rangeValue","_overWriteGraphConstants","RepulsionMixin","HierarchialRepulsionMixin","BarnesHutMixin","_toggleBarnesHut","barnesHutTree","_initializeForceCalculation","_calculateForces","_calculateGravitationalForces","_calculateNodeForces","_calculateSpringForcesWithSupport","_calculateHierarchicalSpringForces","_calculateSpringForces","supportNodeId","gravity","gravityForce","edgeLength","springForce","combinedClusterSize","node1","node2","node3","_calculateSpringForce","physicsConfiguration","hierarchicalLayoutDirections","parentElement","rangeElement","radioButton3","graph_repositionNodes","graph_generateOptions","nameArray","webpackContext","req","resolve","repulsingForce","a_base","minimumDistance","steepness","springFx","springFy","totalFx","totalFy","correctionFx","correctionFy","nodeCount","_formBarnesHutTree","_getForceContribution","children","NW","NE","SW","SE","parentBranch","childrenCount","centerOfMass","calcSize","MAX_VALUE","sizeDiff","minimumTreeSize","rootSize","halfRootSize","centerX","centerY","_splitBranch","_placeInTree","_updateBranchMass","totalMass","totalMassInv","biggestSize","skipMassUpdate","_placeInRegion","region","containedNode","_insertRegion","childSize","_drawTree","_drawBranch","branch","webpackPolyfill","paths"],"mappings":"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"} \ No newline at end of file diff --git a/dist/vis.min.js b/dist/vis.min.js index 87e37a3b..904ab645 100644 --- a/dist/vis.min.js +++ b/dist/vis.min.js @@ -22,17 +22,17 @@ * * Vis.js may be distributed under either license. */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.vis=e():t.vis=e()}(this,function(){return function(t){function e(s){if(i[s])return i[s].exports;var o=i[s]={exports:{},id:s,loaded:!1};return t[s].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){e.util=i(1),e.DOMutil=i(2),e.DataSet=i(3),e.DataView=i(4),e.Graph3d=i(5),e.graph3d={Camera:i(6),Filter:i(7),Point2d:i(8),Point3d:i(9),Slider:i(10),StepNumber:i(11)},e.Timeline=i(12),e.Graph2d=i(13),e.timeline={DateUtil:i(14),DataStep:i(15),Range:i(16),stack:i(17),TimeStep:i(18),components:{items:{Item:i(30),BackgroundItem:i(31),BoxItem:i(32),PointItem:i(33),RangeItem:i(34)},Component:i(19),CurrentTime:i(20),CustomTime:i(21),DataAxis:i(22),GraphGroup:i(23),Group:i(24),BackgroundGroup:i(25),ItemSet:i(26),Legend:i(27),LineGraph:i(28),TimeAxis:i(29)}},e.Network=i(35),e.network={Edge:i(36),Groups:i(37),Images:i(38),Node:i(39),Popup:i(40),dotparser:i(41),gephiParser:i(42)},e.Graph=function(){throw new Error("Graph is renamed to Network. Please create a graph as new vis.Network(...)")},e.moment=i(43),e.hammer=i(44)},function(module,exports,__webpack_require__){var moment=__webpack_require__(43);exports.isNumber=function(t){return t instanceof Number||"number"==typeof t},exports.isString=function(t){return t instanceof String||"string"==typeof t},exports.isDate=function(t){if(t instanceof Date)return!0;if(exports.isString(t)){var e=ASPDateRegex.exec(t);if(e)return!0;if(!isNaN(Date.parse(t)))return!0}return!1},exports.isDataTable=function(t){return"undefined"!=typeof google&&google.visualization&&google.visualization.DataTable&&t instanceof google.visualization.DataTable},exports.randomUUID=function(){var t=function(){return Math.floor(65536*Math.random()).toString(16)};return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()},exports.extend=function(t){for(var e=1,i=arguments.length;i>e;e++){var s=arguments[e];for(var o in s)s.hasOwnProperty(o)&&(t[o]=s[o])}return t},exports.selectiveExtend=function(t,e){if(!Array.isArray(t))throw new Error("Array with property names expected as first argument");for(var i=2;ii;i++)if(t[i]!=e[i])return!1;return!0},exports.convert=function(t,e){var i;if(void 0===t)return void 0;if(null===t)return null;if(!e)return t;if("string"!=typeof e&&!(e instanceof String))throw new Error("Type must be a string");switch(e){case"boolean":case"Boolean":return Boolean(t);case"number":case"Number":return Number(t.valueOf());case"string":case"String":return String(t);case"Date":if(exports.isNumber(t))return new Date(t);if(t instanceof Date)return new Date(t.valueOf());if(moment.isMoment(t))return new Date(t.valueOf());if(exports.isString(t))return i=ASPDateRegex.exec(t),i?new Date(Number(i[1])):moment(t).toDate();throw new Error("Cannot convert object of type "+exports.getType(t)+" to type Date");case"Moment":if(exports.isNumber(t))return moment(t);if(t instanceof Date)return moment(t.valueOf());if(moment.isMoment(t))return moment(t);if(exports.isString(t))return i=ASPDateRegex.exec(t),moment(i?Number(i[1]):t);throw new Error("Cannot convert object of type "+exports.getType(t)+" to type Date");case"ISODate":if(exports.isNumber(t))return new Date(t);if(t instanceof Date)return t.toISOString();if(moment.isMoment(t))return t.toDate().toISOString();if(exports.isString(t))return i=ASPDateRegex.exec(t),i?new Date(Number(i[1])).toISOString():new Date(t).toISOString();throw new Error("Cannot convert object of type "+exports.getType(t)+" to type ISODate");case"ASPDate":if(exports.isNumber(t))return"/Date("+t+")/";if(t instanceof Date)return"/Date("+t.valueOf()+")/";if(exports.isString(t)){i=ASPDateRegex.exec(t);var s;return s=i?new Date(Number(i[1])).valueOf():new Date(t).valueOf(),"/Date("+s+")/"}throw new Error("Cannot convert object of type "+exports.getType(t)+" to type ASPDate");default:throw new Error('Unknown type "'+e+'"')}};var ASPDateRegex=/^\/?Date\((\-?\d+)/i;exports.getType=function(t){var e=typeof t;return"object"==e?null==t?"null":t instanceof Boolean?"Boolean":t instanceof Number?"Number":t instanceof String?"String":Array.isArray(t)?"Array":t instanceof Date?"Date":"Object":"number"==e?"Number":"boolean"==e?"Boolean":"string"==e?"String":e},exports.getAbsoluteLeft=function(t){return t.getBoundingClientRect().left+window.pageXOffset},exports.getAbsoluteTop=function(t){return t.getBoundingClientRect().top+window.pageYOffset},exports.addClassName=function(t,e){var i=t.className.split(" ");-1==i.indexOf(e)&&(i.push(e),t.className=i.join(" "))},exports.removeClassName=function(t,e){var i=t.className.split(" "),s=i.indexOf(e);-1!=s&&(i.splice(s,1),t.className=i.join(" "))},exports.forEach=function(t,e){var i,s;if(Array.isArray(t))for(i=0,s=t.length;s>i;i++)e(t[i],i,t);else for(i in t)t.hasOwnProperty(i)&&e(t[i],i,t)},exports.toArray=function(t){var e=[];for(var i in t)t.hasOwnProperty(i)&&e.push(t[i]);return e},exports.updateProperty=function(t,e,i){return t[e]!==i?(t[e]=i,!0):!1},exports.addEventListener=function(t,e,i,s){t.addEventListener?(void 0===s&&(s=!1),"mousewheel"===e&&navigator.userAgent.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.addEventListener(e,i,s)):t.attachEvent("on"+e,i)},exports.removeEventListener=function(t,e,i,s){t.removeEventListener?(void 0===s&&(s=!1),"mousewheel"===e&&navigator.userAgent.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.removeEventListener(e,i,s)):t.detachEvent("on"+e,i)},exports.preventDefault=function(t){t||(t=window.event),t.preventDefault?t.preventDefault():t.returnValue=!1},exports.getTarget=function(t){t||(t=window.event);var e;return t.target?e=t.target:t.srcElement&&(e=t.srcElement),void 0!=e.nodeType&&3==e.nodeType&&(e=e.parentNode),e},exports.option={},exports.option.asBoolean=function(t,e){return"function"==typeof t&&(t=t()),null!=t?0!=t:e||null},exports.option.asNumber=function(t,e){return"function"==typeof t&&(t=t()),null!=t?Number(t)||e||null:e||null},exports.option.asString=function(t,e){return"function"==typeof t&&(t=t()),null!=t?String(t):e||null},exports.option.asSize=function(t,e){return"function"==typeof t&&(t=t()),exports.isString(t)?t:exports.isNumber(t)?t+"px":e||null},exports.option.asElement=function(t,e){return"function"==typeof t&&(t=t()),t||e||null},exports.GiveDec=function(Hex){var Value;return Value="A"==Hex?10:"B"==Hex?11:"C"==Hex?12:"D"==Hex?13:"E"==Hex?14:"F"==Hex?15:eval(Hex)},exports.GiveHex=function(t){var e;return e=10==t?"A":11==t?"B":12==t?"C":13==t?"D":14==t?"E":15==t?"F":""+t},exports.parseColor=function(t){var e;if(exports.isString(t)){if(exports.isValidRGB(t)){var i=t.substr(4).substr(0,t.length-5).split(",");t=exports.RGBToHex(i[0],i[1],i[2])}if(exports.isValidHex(t)){var s=exports.hexToHSV(t),o={h:s.h,s:.45*s.s,v:Math.min(1,1.05*s.v)},n={h:s.h,s:Math.min(1,1.25*s.v),v:.6*s.v},r=exports.HSVToHex(n.h,n.h,n.v),a=exports.HSVToHex(o.h,o.s,o.v);e={background:t,border:r,highlight:{background:a,border:r},hover:{background:a,border:r}}}else e={background:t,border:t,highlight:{background:t,border:t},hover:{background:t,border:t}}}else e={},e.background=t.background||"white",e.border=t.border||e.background,exports.isString(t.highlight)?e.highlight={border:t.highlight,background:t.highlight}:(e.highlight={},e.highlight.background=t.highlight&&t.highlight.background||e.background,e.highlight.border=t.highlight&&t.highlight.border||e.border),exports.isString(t.hover)?e.hover={border:t.hover,background:t.hover}:(e.hover={},e.hover.background=t.hover&&t.hover.background||e.background,e.hover.border=t.hover&&t.hover.border||e.border);return e},exports.hexToRGB=function(t){t=t.replace("#","").toUpperCase();var e=exports.GiveDec(t.substring(0,1)),i=exports.GiveDec(t.substring(1,2)),s=exports.GiveDec(t.substring(2,3)),o=exports.GiveDec(t.substring(3,4)),n=exports.GiveDec(t.substring(4,5)),r=exports.GiveDec(t.substring(5,6)),a=16*e+i,h=16*s+o,i=16*n+r;return{r:a,g:h,b:i}},exports.RGBToHex=function(t,e,i){var s=exports.GiveHex(Math.floor(t/16)),o=exports.GiveHex(t%16),n=exports.GiveHex(Math.floor(e/16)),r=exports.GiveHex(e%16),a=exports.GiveHex(Math.floor(i/16)),h=exports.GiveHex(i%16),d=s+o+n+r+a+h;return"#"+d},exports.RGBToHSV=function(t,e,i){t/=255,e/=255,i/=255;var s=Math.min(t,Math.min(e,i)),o=Math.max(t,Math.max(e,i));if(s==o)return{h:0,s:0,v:s};var n=t==s?e-i:i==s?t-e:i-t,r=t==s?3:i==s?1:5,a=60*(r-n/(o-s))/360,h=(o-s)/o,d=o;return{h:a,s:h,v:d}};var cssUtil={split:function(t){var e={};return t.split(";").forEach(function(t){if(""!=t.trim()){var i=t.split(":"),s=i[0].trim(),o=i[1].trim();e[s]=o}}),e},join:function(t){return Object.keys(t).map(function(e){return e+": "+t[e]}).join("; ")}};exports.addCssText=function(t,e){var i=cssUtil.split(t.style.cssText),s=cssUtil.split(e),o=exports.extend(i,s);t.style.cssText=cssUtil.join(o)},exports.removeCssText=function(t,e){var i=cssUtil.split(t.style.cssText),s=cssUtil.split(e);for(var o in s)s.hasOwnProperty(o)&&delete i[o];t.style.cssText=cssUtil.join(i)},exports.HSVToRGB=function(t,e,i){var s,o,n,r=Math.floor(6*t),a=6*t-r,h=i*(1-e),d=i*(1-a*e),l=i*(1-(1-a)*e);switch(r%6){case 0:s=i,o=l,n=h;break;case 1:s=d,o=i,n=h;break;case 2:s=h,o=i,n=l;break;case 3:s=h,o=d,n=i;break;case 4:s=l,o=h,n=i;break;case 5:s=i,o=h,n=d}return{r:Math.floor(255*s),g:Math.floor(255*o),b:Math.floor(255*n)}},exports.HSVToHex=function(t,e,i){var s=exports.HSVToRGB(t,e,i);return exports.RGBToHex(s.r,s.g,s.b)},exports.hexToHSV=function(t){var e=exports.hexToRGB(t);return exports.RGBToHSV(e.r,e.g,e.b)},exports.isValidHex=function(t){var e=/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(t);return e},exports.isValidRGB=function(t){t=t.replace(" ","");var e=/rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/i.test(t);return e},exports.selectiveBridgeObject=function(t,e){if("object"==typeof e){for(var i=Object.create(e),s=0;sa;)o=void 0===s?n[u][i]:n[u][i][s],n[u].isVisible(e)?h=!0:(o=r&&console.log("BinarySearch too many iterations. Aborting.")}return u},exports.binarySearchGeneric=function(t,e,i,s){var o,n,r,a,h=1e4,d=0,l=t,c=!1,p=0,u=l.length,f=p,m=u,g=Math.floor(.5*(u+p));if(0==u)g=-1;else if(1==u)r=l[g][i],g=r==e?0:-1;else{for(u-=1;0==c&&h>d;)n=l[Math.max(0,g-1)][i],r=l[g][i],a=l[Math.min(l.length-1,g+1)][i],r==e||e>n&&r>e||e>r&&a>e?(c=!0,r!=e&&("before"==s?e>n&&r>e&&(g=Math.max(0,g-1)):e>r&&a>e&&(g=Math.min(l.length-1,g+1)))):(e>r?f=Math.floor(.5*(u+p)):m=Math.floor(.5*(u+p)),o=Math.floor(.5*(u+p)),p==f&&u==m?(g=-1,c=!0):(u=m,p=f,g=Math.floor(.5*(u+p)))),d++;d>=h&&console.log("BinarySearch too many iterations. Aborting.")}return g},exports.easeInOutQuad=function(t,e,i,s){var o=i-e;return t/=s/2,1>t?o/2*t*t+e:(t--,-o/2*(t*(t-2)-1)+e)},exports.easingFunctions={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return t*(2-t)},easeInOutQuad:function(t){return.5>t?2*t*t:-1+(4-2*t)*t},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return--t*t*t+1},easeInOutCubic:function(t){return.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return 1- --t*t*t*t},easeInOutQuart:function(t){return.5>t?8*t*t*t*t:1-8*--t*t*t*t},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return 1+--t*t*t*t*t},easeInOutQuint:function(t){return.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t}}},function(t,e){e.prepareElements=function(t){for(var e in t)t.hasOwnProperty(e)&&(t[e].redundant=t[e].used,t[e].used=[])},e.cleanupElements=function(t){for(var e in t)if(t.hasOwnProperty(e)&&t[e].redundant){for(var i=0;i0?(s=e[t].redundant[0],e[t].redundant.shift()):(s=document.createElementNS("http://www.w3.org/2000/svg",t),i.appendChild(s)):(s=document.createElementNS("http://www.w3.org/2000/svg",t),e[t]={used:[],redundant:[]},i.appendChild(s)),e[t].used.push(s),s},e.getDOMElement=function(t,e,i,s){var o;return e.hasOwnProperty(t)?e[t].redundant.length>0?(o=e[t].redundant[0],e[t].redundant.shift()):(o=document.createElement(t),void 0!==s?i.insertBefore(o,s):i.appendChild(o)):(o=document.createElement(t),e[t]={used:[],redundant:[]},void 0!==s?i.insertBefore(o,s):i.appendChild(o)),e[t].used.push(o),o},e.drawPoint=function(t,i,s,o,n){var r;return"circle"==s.options.drawPoints.style?(r=e.getSVGElement("circle",o,n),r.setAttributeNS(null,"cx",t),r.setAttributeNS(null,"cy",i),r.setAttributeNS(null,"r",.5*s.options.drawPoints.size),r.setAttributeNS(null,"class",s.className+" point")):(r=e.getSVGElement("rect",o,n),r.setAttributeNS(null,"x",t-.5*s.options.drawPoints.size),r.setAttributeNS(null,"y",i-.5*s.options.drawPoints.size),r.setAttributeNS(null,"width",s.options.drawPoints.size),r.setAttributeNS(null,"height",s.options.drawPoints.size),r.setAttributeNS(null,"class",s.className+" point")),r},e.drawBar=function(t,i,s,o,n,r,a){if(0!=o){0>o&&(o*=-1,i-=o);var h=e.getSVGElement("rect",r,a);h.setAttributeNS(null,"x",t-.5*s),h.setAttributeNS(null,"y",i),h.setAttributeNS(null,"width",s),h.setAttributeNS(null,"height",o),h.setAttributeNS(null,"class",n)}}},function(t,e,i){function s(t,e){if(!t||Array.isArray(t)||o.isDataTable(t)||(e=t,t=null),this._options=e||{},this._data={},this._fieldId=this._options.fieldId||"id",this._type={},this._options.type)for(var i in this._options.type)if(this._options.type.hasOwnProperty(i)){var s=this._options.type[i];this._type[i]="Date"==s||"ISODate"==s||"ASPDate"==s?"Date":s}if(this._options.convert)throw new Error('Option "convert" is deprecated. Use "type" instead.');this._subscribers={},t&&this.add(t)}var o=i(1);s.prototype.on=function(t,e){var i=this._subscribers[t];i||(i=[],this._subscribers[t]=i),i.push({callback:e})},s.prototype.subscribe=s.prototype.on,s.prototype.off=function(t,e){var i=this._subscribers[t];i&&(this._subscribers[t]=i.filter(function(t){return t.callback!=e}))},s.prototype.unsubscribe=s.prototype.off,s.prototype._trigger=function(t,e,i){if("*"==t)throw new Error("Cannot trigger event *");var s=[];t in this._subscribers&&(s=s.concat(this._subscribers[t])),"*"in this._subscribers&&(s=s.concat(this._subscribers["*"]));for(var o=0;or;r++)i=n._addItem(t[r]),s.push(i);else if(o.isDataTable(t))for(var h=this._getColumnNames(t),d=0,l=t.getNumberOfRows();l>d;d++){for(var c={},p=0,u=h.length;u>p;p++){var f=h[p];c[f]=t.getValue(d,p)}i=n._addItem(c),s.push(i)}else{if(!(t instanceof Object))throw new Error("Unknown dataType");i=n._addItem(t),s.push(i)}return s.length&&this._trigger("add",{items:s},e),s},s.prototype.update=function(t,e){var i=[],s=[],n=[],r=this,a=r._fieldId,h=function(t){var e=t[a];r._data[e]?(e=r._updateItem(t),s.push(e),n.push(t)):(e=r._addItem(t),i.push(e))};if(Array.isArray(t))for(var d=0,l=t.length;l>d;d++)h(t[d]);else if(o.isDataTable(t))for(var c=this._getColumnNames(t),p=0,u=t.getNumberOfRows();u>p;p++){for(var f={},m=0,g=c.length;g>m;m++){var v=c[m];f[v]=t.getValue(p,m)}h(f)}else{if(!(t instanceof Object))throw new Error("Unknown dataType");h(t)}return i.length&&this._trigger("add",{items:i},e),s.length&&this._trigger("update",{items:s,data:n},e),i.concat(s)},s.prototype.get=function(){var t,e,i,s,n=this,r=o.getType(arguments[0]);"String"==r||"Number"==r?(t=arguments[0],i=arguments[1],s=arguments[2]):"Array"==r?(e=arguments[0],i=arguments[1],s=arguments[2]):(i=arguments[0],s=arguments[1]);var a;if(i&&i.returnType){var h=["DataTable","Array","Object"];if(a=-1==h.indexOf(i.returnType)?"Array":i.returnType,s&&a!=o.getType(s))throw new Error('Type of parameter "data" ('+o.getType(s)+") does not correspond with specified options.type ("+i.type+")");if("DataTable"==a&&!o.isDataTable(s))throw new Error('Parameter "data" must be a DataTable when options.type is "DataTable"')}else a=s&&"DataTable"==o.getType(s)?"DataTable":"Array";var d,l,c,p,u=i&&i.type||this._options.type,f=i&&i.filter,m=[];if(void 0!=t)d=n._getItem(t,u),f&&!f(d)&&(d=null);else if(void 0!=e)for(c=0,p=e.length;p>c;c++)d=n._getItem(e[c],u),(!f||f(d))&&m.push(d);else for(l in this._data)this._data.hasOwnProperty(l)&&(d=n._getItem(l,u),(!f||f(d))&&m.push(d));if(i&&i.order&&void 0==t&&this._sort(m,i.order),i&&i.fields){var g=i.fields;if(void 0!=t)d=this._filterFields(d,g);else for(c=0,p=m.length;p>c;c++)m[c]=this._filterFields(m[c],g)}if("DataTable"==a){var v=this._getColumnNames(s);if(void 0!=t)n._appendRow(s,v,d);else for(c=0;cc;c++)s.push(m[c]);return s}return m},s.prototype.getIds=function(t){var e,i,s,o,n,r=this._data,a=t&&t.filter,h=t&&t.order,d=t&&t.type||this._options.type,l=[];if(a)if(h){n=[];for(s in r)r.hasOwnProperty(s)&&(o=this._getItem(s,d),a(o)&&n.push(o));for(this._sort(n,h),e=0,i=n.length;i>e;e++)l[e]=n[e][this._fieldId]}else for(s in r)r.hasOwnProperty(s)&&(o=this._getItem(s,d),a(o)&&l.push(o[this._fieldId]));else if(h){n=[];for(s in r)r.hasOwnProperty(s)&&n.push(r[s]);for(this._sort(n,h),e=0,i=n.length;i>e;e++)l[e]=n[e][this._fieldId]}else for(s in r)r.hasOwnProperty(s)&&(o=r[s],l.push(o[this._fieldId]));return l},s.prototype.getDataSet=function(){return this},s.prototype.forEach=function(t,e){var i,s,o=e&&e.filter,n=e&&e.type||this._options.type,r=this._data;if(e&&e.order)for(var a=this.get(e),h=0,d=a.length;d>h;h++)i=a[h],s=i[this._fieldId],t(i,s);else for(s in r)r.hasOwnProperty(s)&&(i=this._getItem(s,n),(!o||o(i))&&t(i,s))},s.prototype.map=function(t,e){var i,s=e&&e.filter,o=e&&e.type||this._options.type,n=[],r=this._data;for(var a in r)r.hasOwnProperty(a)&&(i=this._getItem(a,o),(!s||s(i))&&n.push(t(i,a)));return e&&e.order&&this._sort(n,e.order),n},s.prototype._filterFields=function(t,e){var i={};for(var s in t)t.hasOwnProperty(s)&&-1!=e.indexOf(s)&&(i[s]=t[s]);return i},s.prototype._sort=function(t,e){if(o.isString(e)){var i=e;t.sort(function(t,e){var s=t[i],o=e[i];return s>o?1:o>s?-1:0})}else{if("function"!=typeof e)throw new TypeError("Order must be a function or a string");t.sort(e)}},s.prototype.remove=function(t,e){var i,s,o,n=[];if(Array.isArray(t))for(i=0,s=t.length;s>i;i++)o=this._remove(t[i]),null!=o&&n.push(o);else o=this._remove(t),null!=o&&n.push(o);return n.length&&this._trigger("remove",{items:n},e),n},s.prototype._remove=function(t){if(o.isNumber(t)||o.isString(t)){if(this._data[t])return delete this._data[t],t}else if(t instanceof Object){var e=t[this._fieldId];if(e&&this._data[e])return delete this._data[e],e}return null},s.prototype.clear=function(t){var e=Object.keys(this._data);return this._data={},this._trigger("remove",{items:e},t),e},s.prototype.max=function(t){var e=this._data,i=null,s=null;for(var o in e)if(e.hasOwnProperty(o)){var n=e[o],r=n[t];null!=r&&(!i||r>s)&&(i=n,s=r)}return i},s.prototype.min=function(t){var e=this._data,i=null,s=null;for(var o in e)if(e.hasOwnProperty(o)){var n=e[o],r=n[t];null!=r&&(!i||s>r)&&(i=n,s=r)}return i},s.prototype.distinct=function(t){var e,i=this._data,s=[],n=this._options.type&&this._options.type[t]||null,r=0;for(var a in i)if(i.hasOwnProperty(a)){var h=i[a],d=h[t],l=!1;for(e=0;r>e;e++)if(s[e]==d){l=!0;break}l||void 0===d||(s[r]=d,r++)}if(n)for(e=0;ei;i++)e[i]=t.getColumnId(i)||t.getColumnLabel(i);return e},s.prototype._appendRow=function(t,e,i){for(var s=t.addRow(),o=0,n=e.length;n>o;o++){var r=e[o];t.setValue(s,o,i[r])}},t.exports=s},function(t,e,i){function s(t,e){this._data=null,this._ids={},this._options=e||{},this._fieldId="id",this._subscribers={};var i=this;this.listener=function(){i._onEvent.apply(i,arguments)},this.setData(t)}var o=i(1),n=i(3);s.prototype.setData=function(t){var e,i,s;if(this._data){this._data.unsubscribe&&this._data.unsubscribe("*",this.listener),e=[];for(var o in this._ids)this._ids.hasOwnProperty(o)&&e.push(o);this._ids={},this._trigger("remove",{items:e})}if(this._data=t,this._data){for(this._fieldId=this._options.fieldId||this._data&&this._data.options&&this._data.options.fieldId||"id",e=this._data.getIds({filter:this._options&&this._options.filter}),i=0,s=e.length;s>i;i++)o=e[i],this._ids[o]=!0;this._trigger("add",{items:e}),this._data.on&&this._data.on("*",this.listener)}},s.prototype.get=function(){var t,e,i,s=this,n=o.getType(arguments[0]);"String"==n||"Number"==n||"Array"==n?(t=arguments[0],e=arguments[1],i=arguments[2]):(e=arguments[0],i=arguments[1]);var r=o.extend({},this._options,e);this._options.filter&&e&&e.filter&&(r.filter=function(t){return s._options.filter(t)&&e.filter(t)});var a=[];return void 0!=t&&a.push(t),a.push(r),a.push(i),this._data&&this._data.get.apply(this._data,a)},s.prototype.getIds=function(t){var e;if(this._data){var i,s=this._options.filter;i=t&&t.filter?s?function(e){return s(e)&&t.filter(e)}:t.filter:s,e=this._data.getIds({filter:i,order:t&&t.order})}else e=[];return e},s.prototype.getDataSet=function(){for(var t=this;t instanceof s;)t=t._data;return t||null},s.prototype._onEvent=function(t,e,i){var s,o,n,r,a=e&&e.items,h=this._data,d=[],l=[],c=[];if(a&&h){switch(t){case"add":for(s=0,o=a.length;o>s;s++)n=a[s],r=this.get(n),r&&(this._ids[n]=!0,d.push(n));break;case"update":for(s=0,o=a.length;o>s;s++)n=a[s],r=this.get(n),r?this._ids[n]?l.push(n):(this._ids[n]=!0,d.push(n)):this._ids[n]&&(delete this._ids[n],c.push(n));break;case"remove":for(s=0,o=a.length;o>s;s++)n=a[s],this._ids[n]&&(delete this._ids[n],c.push(n))}d.length&&this._trigger("add",{items:d},i),l.length&&this._trigger("update",{items:l},i),c.length&&this._trigger("remove",{items:c},i)}},s.prototype.on=n.prototype.on,s.prototype.off=n.prototype.off,s.prototype._trigger=n.prototype._trigger,s.prototype.subscribe=s.prototype.on,s.prototype.unsubscribe=s.prototype.off,t.exports=s},function(t,e,i){function s(t,e,i){if(!(this instanceof s))throw new SyntaxError("Constructor must be called with the new operator");this.containerElement=t,this.width="400px",this.height="400px",this.margin=10,this.defaultXCenter="55%",this.defaultYCenter="50%",this.xLabel="x",this.yLabel="y",this.zLabel="z";var o=function(t){return t};this.xValueLabel=o,this.yValueLabel=o,this.zValueLabel=o,this.filterLabel="time",this.legendLabel="value",this.style=s.STYLE.DOT,this.showPerspective=!0,this.showGrid=!0,this.keepAspectRatio=!0,this.showShadow=!1,this.showGrayBottom=!1,this.showTooltip=!1,this.verticalRatio=.5,this.animationInterval=1e3,this.animationPreload=!1,this.camera=new l,this.eye=new h(0,0,-1),this.dataTable=null,this.dataPoints=null,this.colX=void 0,this.colY=void 0,this.colZ=void 0,this.colValue=void 0,this.colFilter=void 0,this.xMin=0,this.xStep=void 0,this.xMax=1,this.yMin=0,this.yStep=void 0,this.yMax=1,this.zMin=0,this.zStep=void 0,this.zMax=1,this.valueMin=0,this.valueMax=1,this.xBarWidth=1,this.yBarWidth=1,this.colorAxis="#4D4D4D",this.colorGrid="#D3D3D3",this.colorDot="#7DC1FF",this.colorDotBorder="#3267D2",this.create(),this.setOptions(i),e&&this.setData(e)}var o=i(52),n=i(3),r=i(4),a=i(1),h=i(9),d=i(8),l=i(6),c=i(7),p=i(10),u=i(11);o(s.prototype),s.prototype._setScale=function(){this.scale=new h(1/(this.xMax-this.xMin),1/(this.yMax-this.yMin),1/(this.zMax-this.zMin)),this.keepAspectRatio&&(this.scale.x3&&(this.colFilter=3);else{if(this.style!==s.STYLE.DOTCOLOR&&this.style!==s.STYLE.DOTSIZE&&this.style!==s.STYLE.BARCOLOR&&this.style!==s.STYLE.BARSIZE)throw'Unknown style "'+this.style+'"';this.colX=0,this.colY=1,this.colZ=2,this.colValue=3,t.getNumberOfColumns()>4&&(this.colFilter=4)}},s.prototype.getNumberOfRows=function(t){return t.length},s.prototype.getNumberOfColumns=function(t){var e=0;for(var i in t[0])t[0].hasOwnProperty(i)&&e++;return e},s.prototype.getDistinctValues=function(t,e){for(var i=[],s=0;st[s][e]&&(i.min=t[s][e]),i.maxt;t++){var m=(t-p)/(f-p),g=240*m,v=this._hsv2rgb(g,1,1);c.strokeStyle=v,c.beginPath(),c.moveTo(h,r+t),c.lineTo(a,r+t),c.stroke()}c.strokeStyle=this.colorAxis,c.strokeRect(h,r,i,n)}if(this.style===s.STYLE.DOTSIZE&&(c.strokeStyle=this.colorAxis,c.fillStyle=this.colorDot,c.beginPath(),c.moveTo(h,r),c.lineTo(a,r),c.lineTo(a-i+e,d),c.lineTo(h,d),c.closePath(),c.fill(),c.stroke()),this.style===s.STYLE.DOTCOLOR||this.style===s.STYLE.DOTSIZE){var y=5,b=new u(this.valueMin,this.valueMax,(this.valueMax-this.valueMin)/5,!0);for(b.start(),b.getCurrent()0?this.yMin:this.yMax,o=this._convert3Dto2D(new h(x,r,this.zMin)),Math.cos(2*_)>0?(g.textAlign="center",g.textBaseline="top",o.y+=b):Math.sin(2*_)<0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(" "+this.xValueLabel(i.getCurrent())+" ",o.x,o.y),i.next()}for(g.lineWidth=1,s=void 0===this.defaultYStep,i=new u(this.yMin,this.yMax,this.yStep,s),i.start(),i.getCurrent()0?this.xMin:this.xMax,o=this._convert3Dto2D(new h(n,i.getCurrent(),this.zMin)),Math.cos(2*_)<0?(g.textAlign="center",g.textBaseline="top",o.y+=b):Math.sin(2*_)>0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(" "+this.yValueLabel(i.getCurrent())+" ",o.x,o.y),i.next();for(g.lineWidth=1,s=void 0===this.defaultZStep,i=new u(this.zMin,this.zMax,this.zStep,s),i.start(),i.getCurrent()0?this.xMin:this.xMax,r=Math.sin(_)<0?this.yMin:this.yMax;!i.end();)t=this._convert3Dto2D(new h(n,r,i.getCurrent())),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(t.x-b,t.y),g.stroke(),g.textAlign="right",g.textBaseline="middle",g.fillStyle=this.colorAxis,g.fillText(this.zValueLabel(i.getCurrent())+" ",t.x-5,t.y),i.next();g.lineWidth=1,t=this._convert3Dto2D(new h(n,r,this.zMin)),e=this._convert3Dto2D(new h(n,r,this.zMax)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(e.x,e.y),g.stroke(),g.lineWidth=1,p=this._convert3Dto2D(new h(this.xMin,this.yMin,this.zMin)),f=this._convert3Dto2D(new h(this.xMax,this.yMin,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(p.x,p.y),g.lineTo(f.x,f.y),g.stroke(),p=this._convert3Dto2D(new h(this.xMin,this.yMax,this.zMin)),f=this._convert3Dto2D(new h(this.xMax,this.yMax,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(p.x,p.y),g.lineTo(f.x,f.y),g.stroke(),g.lineWidth=1,t=this._convert3Dto2D(new h(this.xMin,this.yMin,this.zMin)),e=this._convert3Dto2D(new h(this.xMin,this.yMax,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(e.x,e.y),g.stroke(),t=this._convert3Dto2D(new h(this.xMax,this.yMin,this.zMin)),e=this._convert3Dto2D(new h(this.xMax,this.yMax,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(e.x,e.y),g.stroke();var w=this.xLabel;w.length>0&&(c=.1/this.scale.y,n=(this.xMin+this.xMax)/2,r=Math.cos(_)>0?this.yMin-c:this.yMax+c,o=this._convert3Dto2D(new h(n,r,this.zMin)),Math.cos(2*_)>0?(g.textAlign="center",g.textBaseline="top"):Math.sin(2*_)<0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(w,o.x,o.y));var S=this.yLabel;S.length>0&&(l=.1/this.scale.x,n=Math.sin(_)>0?this.xMin-l:this.xMax+l,r=(this.yMin+this.yMax)/2,o=this._convert3Dto2D(new h(n,r,this.zMin)),Math.cos(2*_)<0?(g.textAlign="center",g.textBaseline="top"):Math.sin(2*_)>0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(S,o.x,o.y));var D=this.zLabel;D.length>0&&(d=30,n=Math.cos(_)>0?this.xMin:this.xMax,r=Math.sin(_)<0?this.yMin:this.yMax,a=(this.zMin+this.zMax)/2,o=this._convert3Dto2D(new h(n,r,a)),g.textAlign="right",g.textBaseline="middle",g.fillStyle=this.colorAxis,g.fillText(D,o.x-d,o.y))},s.prototype._hsv2rgb=function(t,e,i){var s,o,n,r,a,h;switch(r=i*e,a=Math.floor(t/60),h=r*(1-Math.abs(t/60%2-1)),a){case 0:s=r,o=h,n=0;break;case 1:s=h,o=r,n=0;break;case 2:s=0,o=r,n=h;break;case 3:s=0,o=h,n=r;break;case 4:s=h,o=0,n=r;break;case 5:s=r,o=0,n=h;break;default:s=0,o=0,n=0}return"RGB("+parseInt(255*s)+","+parseInt(255*o)+","+parseInt(255*n)+")"},s.prototype._redrawDataGrid=function(){var t,e,i,o,n,r,a,d,l,c,p,u,f,m=this.frame.canvas,g=m.getContext("2d");if(!(void 0===this.dataPoints||this.dataPoints.length<=0)){for(n=0;n0}else r=!0;r?(f=(t.point.z+e.point.z+i.point.z+o.point.z)/4,c=240*(1-(f-this.zMin)*this.scale.z/this.verticalRatio),p=1,this.showShadow?(u=Math.min(1+S.x/D/2,1),a=this._hsv2rgb(c,p,u),d=a):(u=1,a=this._hsv2rgb(c,p,u),d=this.colorAxis)):(a="gray",d=this.colorAxis),l=.5,g.lineWidth=l,g.fillStyle=a,g.strokeStyle=d,g.beginPath(),g.moveTo(t.screen.x,t.screen.y),g.lineTo(e.screen.x,e.screen.y),g.lineTo(o.screen.x,o.screen.y),g.lineTo(i.screen.x,i.screen.y),g.closePath(),g.fill(),g.stroke()}}else for(n=0;np&&(p=0);var u,f,m;this.style===s.STYLE.DOTCOLOR?(u=240*(1-(d.point.value-this.valueMin)*this.scale.value),f=this._hsv2rgb(u,1,1),m=this._hsv2rgb(u,1,.8)):this.style===s.STYLE.DOTSIZE?(f=this.colorDot,m=this.colorDotBorder):(u=240*(1-(d.point.z-this.zMin)*this.scale.z/this.verticalRatio),f=this._hsv2rgb(u,1,1),m=this._hsv2rgb(u,1,.8)),i.lineWidth=1,i.strokeStyle=m,i.fillStyle=f,i.beginPath(),i.arc(d.screen.x,d.screen.y,p,0,2*Math.PI,!0),i.fill(),i.stroke()}}},s.prototype._redrawDataBar=function(){var t,e,i,o,n=this.frame.canvas,r=n.getContext("2d");if(!(void 0===this.dataPoints||this.dataPoints.length<=0)){for(t=0;t0&&(t=this.dataPoints[0],s.lineWidth=1,s.strokeStyle="blue",s.beginPath(),s.moveTo(t.screen.x,t.screen.y)),e=1;e0&&s.stroke()}},s.prototype._onMouseDown=function(t){if(t=t||window.event,this.leftButtonDown&&this._onMouseUp(t),this.leftButtonDown=t.which?1===t.which:1===t.button,this.leftButtonDown||this.touchDown){this.startMouseX=getMouseX(t),this.startMouseY=getMouseY(t),this.startStart=new Date(this.start),this.startEnd=new Date(this.end),this.startArmRotation=this.camera.getArmRotation(),this.frame.style.cursor="move";var e=this;this.onmousemove=function(t){e._onMouseMove(t)},this.onmouseup=function(t){e._onMouseUp(t)},a.addEventListener(document,"mousemove",e.onmousemove),a.addEventListener(document,"mouseup",e.onmouseup),a.preventDefault(t)}},s.prototype._onMouseMove=function(t){t=t||window.event;var e=parseFloat(getMouseX(t))-this.startMouseX,i=parseFloat(getMouseY(t))-this.startMouseY,s=this.startArmRotation.horizontal+e/200,o=this.startArmRotation.vertical+i/200,n=4,r=Math.sin(n/360*2*Math.PI);Math.abs(Math.sin(s))0?1:0>t?-1:0}var s=e[0],o=e[1],n=e[2],r=i((o.x-s.x)*(t.y-s.y)-(o.y-s.y)*(t.x-s.x)),a=i((n.x-o.x)*(t.y-o.y)-(n.y-o.y)*(t.x-o.x)),h=i((s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x));return!(0!=r&&0!=a&&r!=a||0!=a&&0!=h&&a!=h||0!=r&&0!=h&&r!=h)},s.prototype._dataPointFromXY=function(t,e){var i,o=100,n=null,r=null,a=null,h=new d(t,e);if(this.style===s.STYLE.BAR||this.style===s.STYLE.BARCOLOR||this.style===s.STYLE.BARSIZE)for(i=this.dataPoints.length-1;i>=0;i--){n=this.dataPoints[i];var l=n.surfaces;if(l)for(var c=l.length-1;c>=0;c--){var p=l[c],u=p.corners,f=[u[0].screen,u[1].screen,u[2].screen],m=[u[2].screen,u[3].screen,u[0].screen];if(this._insideTriangle(h,f)||this._insideTriangle(h,m))return n}}else for(i=0;ib)&&o>b&&(a=b,r=n)}}return r},s.prototype._showTooltip=function(t){var e,i,s;this.tooltip?(e=this.tooltip.dom.content,i=this.tooltip.dom.line,s=this.tooltip.dom.dot):(e=document.createElement("div"),e.style.position="absolute",e.style.padding="10px",e.style.border="1px solid #4d4d4d",e.style.color="#1a1a1a",e.style.background="rgba(255,255,255,0.7)",e.style.borderRadius="2px",e.style.boxShadow="5px 5px 10px rgba(128,128,128,0.5)",i=document.createElement("div"),i.style.position="absolute",i.style.height="40px",i.style.width="0",i.style.borderLeft="1px solid #4d4d4d",s=document.createElement("div"),s.style.position="absolute",s.style.height="0",s.style.width="0",s.style.border="5px solid #4d4d4d",s.style.borderRadius="5px",this.tooltip={dataPoint:null,dom:{content:e,line:i,dot:s}}),this._hideTooltip(),this.tooltip.dataPoint=t,e.innerHTML="function"==typeof this.showTooltip?this.showTooltip(t.point):"
x:"+t.point.x+"
y:"+t.point.y+"
z:"+t.point.z+"
",e.style.left="0",e.style.top="0",this.frame.appendChild(e),this.frame.appendChild(i),this.frame.appendChild(s);var o=e.offsetWidth,n=e.offsetHeight,r=i.offsetHeight,a=s.offsetWidth,h=s.offsetHeight,d=t.screen.x-o/2;d=Math.min(Math.max(d,10),this.frame.clientWidth-10-o),i.style.left=t.screen.x+"px",i.style.top=t.screen.y-r+"px",e.style.left=d+"px",e.style.top=t.screen.y-r-n+"px",s.style.left=t.screen.x-a/2+"px",s.style.top=t.screen.y-h/2+"px"},s.prototype._hideTooltip=function(){if(this.tooltip){this.tooltip.dataPoint=null;for(var t in this.tooltip.dom)if(this.tooltip.dom.hasOwnProperty(t)){var e=this.tooltip.dom[t];e&&e.parentNode&&e.parentNode.removeChild(e)}}},getMouseX=function(t){return"clientX"in t?t.clientX:t.targetTouches[0]&&t.targetTouches[0].clientX||0},getMouseY=function(t){return"clientY"in t?t.clientY:t.targetTouches[0]&&t.targetTouches[0].clientY||0},t.exports=s},function(t,e,i){var s=i(9);Camera=function(){this.armLocation=new s,this.armRotation={},this.armRotation.horizontal=0,this.armRotation.vertical=0,this.armLength=1.7,this.cameraLocation=new s,this.cameraRotation=new s(.5*Math.PI,0,0),this.calculateCameraOrientation()},Camera.prototype.setArmLocation=function(t,e,i){this.armLocation.x=t,this.armLocation.y=e,this.armLocation.z=i,this.calculateCameraOrientation()},Camera.prototype.setArmRotation=function(t,e){void 0!==t&&(this.armRotation.horizontal=t),void 0!==e&&(this.armRotation.vertical=e,this.armRotation.vertical<0&&(this.armRotation.vertical=0),this.armRotation.vertical>.5*Math.PI&&(this.armRotation.vertical=.5*Math.PI)),(void 0!==t||void 0!==e)&&this.calculateCameraOrientation()},Camera.prototype.getArmRotation=function(){var t={};return t.horizontal=this.armRotation.horizontal,t.vertical=this.armRotation.vertical,t},Camera.prototype.setArmLength=function(t){void 0!==t&&(this.armLength=t,this.armLength<.71&&(this.armLength=.71),this.armLength>5&&(this.armLength=5),this.calculateCameraOrientation())},Camera.prototype.getArmLength=function(){return this.armLength},Camera.prototype.getCameraLocation=function(){return this.cameraLocation},Camera.prototype.getCameraRotation=function(){return this.cameraRotation},Camera.prototype.calculateCameraOrientation=function(){this.cameraLocation.x=this.armLocation.x-this.armLength*Math.sin(this.armRotation.horizontal)*Math.cos(this.armRotation.vertical),this.cameraLocation.y=this.armLocation.y-this.armLength*Math.cos(this.armRotation.horizontal)*Math.cos(this.armRotation.vertical),this.cameraLocation.z=this.armLocation.z+this.armLength*Math.sin(this.armRotation.vertical),this.cameraRotation.x=Math.PI/2-this.armRotation.vertical,this.cameraRotation.y=0,this.cameraRotation.z=-this.armRotation.horizontal},t.exports=Camera},function(t,e,i){function s(t,e,i){this.data=t,this.column=e,this.graph=i,this.index=void 0,this.value=void 0,this.values=i.getDistinctValues(t.get(),this.column),this.values.sort(function(t,e){return t>e?1:e>t?-1:0}),this.values.length>0&&this.selectValue(0),this.dataPoints=[],this.loaded=!1,this.onLoadCallback=void 0,i.animationPreload?(this.loaded=!1,this.loadInBackground()):this.loaded=!0}var o=i(4);s.prototype.isLoaded=function(){return this.loaded},s.prototype.getLoadedProgress=function(){for(var t=this.values.length,e=0;this.dataPoints[e];)e++;return Math.round(e/t*100)},s.prototype.getLabel=function(){return this.graph.filterLabel},s.prototype.getColumn=function(){return this.column},s.prototype.getSelectedValue=function(){return void 0===this.index?void 0:this.values[this.index]},s.prototype.getValues=function(){return this.values},s.prototype.getValue=function(t){if(t>=this.values.length)throw"Error: index out of range";return this.values[t]},s.prototype._getDataPoints=function(t){if(void 0===t&&(t=this.index),void 0===t)return[];var e;if(this.dataPoints[t])e=this.dataPoints[t];else{var i={};i.column=this.column,i.value=this.values[t];var s=new o(this.data,{filter:function(t){return t[i.column]==i.value}}).get();e=this.graph._getDataPoints(s),this.dataPoints[t]=e}return e},s.prototype.setOnLoadCallback=function(t){this.onLoadCallback=t},s.prototype.selectValue=function(t){if(t>=this.values.length)throw"Error: index out of range";this.index=t,this.value=this.values[t]},s.prototype.loadInBackground=function(t){void 0===t&&(t=0);var e=this.graph.frame;if(t0&&(t--,this.setIndex(t))},s.prototype.next=function(){var t=this.getIndex();t0?this.setIndex(0):this.index=void 0},s.prototype.setIndex=function(t){if(!(ts&&(s=0),s>this.values.length-1&&(s=this.values.length-1),s},s.prototype.indexToLeft=function(t){var e=parseFloat(this.frame.bar.style.width)-this.frame.slide.clientWidth-10,i=t/(this.values.length-1)*e,s=i+3;return s},s.prototype._onMouseMove=function(t){var e=t.clientX-this.startClientX,i=this.startSlideX+e,s=this.leftToIndex(i);this.setIndex(s),o.preventDefault()},s.prototype._onMouseUp=function(){this.frame.style.cursor="auto",o.removeEventListener(document,"mousemove",this.onmousemove),o.removeEventListener(document,"mouseup",this.onmouseup),o.preventDefault()},t.exports=s},function(t){function e(t,e,i,s){this._start=0,this._end=0,this._step=1,this.prettyStep=!0,this.precision=5,this._current=0,this.setRange(t,e,i,s)}e.prototype.setRange=function(t,e,i,s){this._start=t?t:0,this._end=e?e:0,this.setStep(i,s)},e.prototype.setStep=function(t,i){void 0===t||0>=t||(void 0!==i&&(this.prettyStep=i),this._step=this.prettyStep===!0?e.calculatePrettyStep(t):t)},e.calculatePrettyStep=function(t){var e=function(t){return Math.log(t)/Math.LN10},i=Math.pow(10,Math.round(e(t))),s=2*Math.pow(10,Math.round(e(t/2))),o=5*Math.pow(10,Math.round(e(t/5))),n=i;return Math.abs(s-t)<=Math.abs(n-t)&&(n=s),Math.abs(o-t)<=Math.abs(n-t)&&(n=o),0>=n&&(n=1),n},e.prototype.getCurrent=function(){return parseFloat(this._current.toPrecision(this.precision))},e.prototype.getStep=function(){return this._step},e.prototype.start=function(){this._current=this._start-this._start%this._step},e.prototype.next=function(){this._current+=this._step},e.prototype.end=function(){return this._current>this._end},t.exports=e},function(t,e,i){function s(t,e,i,r){if(!(this instanceof s))throw new SyntaxError("Constructor must be called with the new operator");if(!(Array.isArray(i)||i instanceof n)&&i instanceof Object){var h=r;r=i,i=h}var u=this;this.defaultOptions={start:null,end:null,autoResize:!0,orientation:"bottom",width:null,height:null,maxHeight:null,minHeight:null},this.options=o.deepExtend({},this.defaultOptions),this._create(t),this.components=[],this.body={dom:this.dom,domProps:this.props,emitter:{on:this.on.bind(this),off:this.off.bind(this),emit:this.emit.bind(this)},hiddenDates:[],util:{snap:null,toScreen:u._toScreen.bind(u),toGlobalScreen:u._toGlobalScreen.bind(u),toTime:u._toTime.bind(u),toGlobalTime:u._toGlobalTime.bind(u)}},this.range=new a(this.body),this.components.push(this.range),this.body.range=this.range,this.timeAxis=new d(this.body),this.components.push(this.timeAxis),this.body.util.snap=this.timeAxis.snap.bind(this.timeAxis),this.currentTime=new l(this.body),this.components.push(this.currentTime),this.customTime=new c(this.body),this.components.push(this.customTime),this.itemSet=new p(this.body),this.components.push(this.itemSet),this.itemsData=null,this.groupsData=null,r&&this.setOptions(r),i&&this.setGroups(i),e?this.setItems(e):this.redraw()}var o=(i(52),i(44),i(1)),n=i(3),r=i(4),a=i(16),h=i(45),d=i(29),l=i(20),c=i(21),p=i(26);s.prototype=new h,s.prototype.setItems=function(t){var e,i=null==this.itemsData;if(e=t?t instanceof n||t instanceof r?t:new n(t,{type:{start:"Date",end:"Date"}}):null,this.itemsData=e,this.itemSet&&this.itemSet.setItems(e),i)if(void 0!=this.options.start||void 0!=this.options.end){var s=void 0!=this.options.start?this.options.start:null,o=void 0!=this.options.end?this.options.end:null;this.setWindow(s,o,{animate:!1})}else this.fit({animate:!1})},s.prototype.setGroups=function(t){var e;e=t?t instanceof n||t instanceof r?t:new n(t):null,this.groupsData=e,this.itemSet.setGroups(e)},s.prototype.setSelection=function(t,e){this.itemSet&&this.itemSet.setSelection(t),e&&e.focus&&this.focus(t,e)},s.prototype.getSelection=function(){return this.itemSet&&this.itemSet.getSelection()||[]},s.prototype.focus=function(t,e){if(this.itemsData&&void 0!=t){var i=Array.isArray(t)?t:[t],s=this.itemsData.getDataSet().get(i,{type:{start:"Date",end:"Date"}}),o=null,n=null;if(s.forEach(function(t){var e=t.start.valueOf(),i="end"in t?t.end.valueOf():t.start.valueOf();(null===o||o>e)&&(o=e),(null===n||i>n)&&(n=i)}),null!==o&&null!==n){var r=(o+n)/2,a=Math.max(this.range.end-this.range.start,1.1*(n-o)),h=e&&void 0!==e.animate?e.animate:!0;this.range.setRange(r-a/2,r+a/2,h)}}},s.prototype.getItemRange=function(){var t=this.itemsData.getDataSet(),e=null,i=null;if(t){var s=t.min("start");e=s?o.convert(s.start,"Date").valueOf():null;var n=t.max("start");n&&(i=o.convert(n.start,"Date").valueOf());var r=t.max("end");r&&(i=null==i?o.convert(r.end,"Date").valueOf():Math.max(i,o.convert(r.end,"Date").valueOf()))}return{min:null!=e?new Date(e):null,max:null!=i?new Date(i):null}},t.exports=s},function(t,e,i){function s(t,e,i,s){if(!(Array.isArray(i)||i instanceof n)&&i instanceof Object){var r=s;s=i,i=r}var h=this;this.defaultOptions={start:null,end:null,autoResize:!0,orientation:"bottom",width:null,height:null,maxHeight:null,minHeight:null},this.options=o.deepExtend({},this.defaultOptions),this._create(t),this.components=[],this.body={dom:this.dom,domProps:this.props,emitter:{on:this.on.bind(this),off:this.off.bind(this),emit:this.emit.bind(this)},hiddenDates:[],util:{snap:null,toScreen:h._toScreen.bind(h),toGlobalScreen:h._toGlobalScreen.bind(h),toTime:h._toTime.bind(h),toGlobalTime:h._toGlobalTime.bind(h)}},this.range=new a(this.body),this.components.push(this.range),this.body.range=this.range,this.timeAxis=new d(this.body),this.components.push(this.timeAxis),this.body.util.snap=this.timeAxis.snap.bind(this.timeAxis),this.currentTime=new l(this.body),this.components.push(this.currentTime),this.customTime=new c(this.body),this.components.push(this.customTime),this.linegraph=new p(this.body),this.components.push(this.linegraph),this.itemsData=null,this.groupsData=null,s&&this.setOptions(s),i&&this.setGroups(i),e?this.setItems(e):this.redraw()}var o=(i(52),i(44),i(1)),n=i(3),r=i(4),a=i(16),h=i(45),d=i(29),l=i(20),c=i(21),p=i(28);s.prototype=new h,s.prototype.setItems=function(t){var e,i=null==this.itemsData;if(e=t?t instanceof n||t instanceof r?t:new n(t,{type:{start:"Date",end:"Date"}}):null,this.itemsData=e,this.linegraph&&this.linegraph.setItems(e),i)if(void 0!=this.options.start||void 0!=this.options.end){var s=void 0!=this.options.start?this.options.start:null,o=void 0!=this.options.end?this.options.end:null;this.setWindow(s,o,{animate:!1})}else this.fit({animate:!1})},s.prototype.setGroups=function(t){var e;e=t?t instanceof n||t instanceof r?t:new n(t):null,this.groupsData=e,this.linegraph.setGroups(e)},s.prototype.getLegend=function(t,e,i){return void 0===e&&(e=15),void 0===i&&(i=15),void 0!==this.linegraph.groups[t]?this.linegraph.groups[t].getLegend(e,i):"cannot find group:"+t},s.prototype.isGroupVisible=function(t){return void 0!==this.linegraph.groups[t]?this.linegraph.groups[t].visible&&(void 0===this.linegraph.options.groups.visibility[t]||1==this.linegraph.options.groups.visibility[t]):!1},s.prototype.getItemRange=function(){var t=null,e=null;for(var i in this.linegraph.groups)if(this.linegraph.groups.hasOwnProperty(i)&&1==this.linegraph.groups[i].visible)for(var s=0;sr?r:t,e=null==e?r:r>e?r:e}return{min:null!=t?new Date(t):null,max:null!=e?new Date(e):null}},t.exports=s},function(t,e,i){var s=i(43);e.convertHiddenOptions=function(t,e){if(t.hiddenDates=[],e&&1==Array.isArray(e)){for(var i=0;i=4*a){var p=0,u=n.clone();switch(i[h].repeat){case"daily":d.day()!=l.day()&&(p=1),d.dayOfYear(o.dayOfYear()),d.year(o.year()),d.subtract(7,"days"),l.dayOfYear(o.dayOfYear()),l.year(o.year()),l.subtract(7-p,"days"),u.add(1,"weeks");break;case"weekly":var f=l.diff(d,"days"),m=d.day();d.date(o.date()),d.month(o.month()),d.year(o.year()),l=d.clone(),d.day(m),l.day(m),l.add(f,"days"),d.subtract(1,"weeks"),l.subtract(1,"weeks"),u.add(1,"weeks");break;case"monthly":d.month()!=l.month()&&(p=1),d.month(o.month()),d.year(o.year()),d.subtract(1,"months"),l.month(o.month()),l.year(o.year()),l.subtract(1,"months"),l.add(p,"months"),u.add(1,"months");break;case"yearly":d.year()!=l.year()&&(p=1),d.year(o.year()),d.subtract(1,"years"),l.year(o.year()),l.subtract(1,"years"),l.add(p,"years"),u.add(1,"years");break;default:return void console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:",i[h].repeat)}for(;u>d;)switch(t.hiddenDates.push({start:d.valueOf(),end:l.valueOf()}),i[h].repeat){case"daily":d.add(1,"days"),l.add(1,"days");break;case"weekly":d.add(1,"weeks"),l.add(1,"weeks");break;case"monthly":d.add(1,"months"),l.add(1,"months");break;case"yearly":d.add(1,"y"),l.add(1,"y");break;default:return void console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:",i[h].repeat)}t.hiddenDates.push({start:d.valueOf(),end:l.valueOf()})}}e.removeDuplicates(t);var g=e.isHidden(t.range.start,t.hiddenDates),v=e.isHidden(t.range.end,t.hiddenDates),y=t.range.start,b=t.range.end;1==g.hidden&&(y=1==t.range.startToFront?g.startDate-1:g.endDate+1),1==v.hidden&&(b=1==t.range.endToFront?v.startDate-1:v.endDate+1),(1==g.hidden||1==v.hidden)&&t.range._applyRange(y,b)}},e.removeDuplicates=function(t){for(var e=t.hiddenDates,i=[],s=0;s=e[s].start&&e[o].end<=e[s].end?e[o].remove=!0:e[o].start>=e[s].start&&e[o].start<=e[s].end?(e[s].end=e[o].end,e[o].remove=!0):e[o].end>=e[s].start&&e[o].end<=e[s].end&&(e[s].start=e[o].start,e[o].remove=!0));for(var s=0;s=r&&a>o){i=!0;break}}if(1==i&&o=n&&r>i){e=!0;break}}if(1==e&&i<=t._end.valueOf()){var a=s(r);t.current=a.toDate()}},e.toScreen=function(t,i,s){var o=e.isHidden(i,t.body.hiddenDates);1==o.hidden&&(i=o.startDate);var n=e.getHiddenDurationBetween(t.body.hiddenDates,t.range.start,t.range.end);i=e.correctTimeForHidden(t.body.hiddenDates,t.range,i);var r=t.range.conversion(s,n);return(i.valueOf()-r.offset)*r.scale},e.toTime=function(t,i,s,o){var n=e.getHiddenDurationBetween(t.hiddenDates,i.start,i.end),r=i.end-i.start-n,a=r*s/o,h=e.getAccumulatedHiddenDuration(t.hiddenDates,i,a),d=new Date(h+a+i.start);return d},e.getHiddenDurationBetween=function(t,e,i){for(var s=0,o=0;o=e&&i>r&&(s+=r-n)}return s},e.correctTimeForHidden=function(t,i,o){return o=s(o).toDate().valueOf(),o-=e.getHiddenDurationBefore(t,i,o)},e.getHiddenDurationBefore=function(t,e,i){var o=0;i=s(i).toDate().valueOf();for(var n=0;n=e.start&&a=a&&(o+=a-r)}return o},e.getAccumulatedHiddenDuration=function(t,e,i){for(var s=0,o=0,n=e.start,r=0;r=e.start&&h=i)break;s+=h-a}}return s},e.snapAwayFromHidden=function(t,i,s,o){var n=e.isHidden(i,t);return 1==n.hidden?0>s?1==o?n.startDate-(n.endDate-i)-1:n.startDate-1:1==o?n.endDate+(i-n.startDate)+1:n.endDate+1:i},e.isHidden=function(t,e){for(var i=0;i=s&&o>t)return{hidden:!0,startDate:s,endDate:o}}return{hidden:!1,startDate:s,endDate:o}}},function(t){function e(t,e,i,s,o){this.current=0,this.autoScale=!0,this.stepIndex=0,this.step=1,this.scale=1,this.marginStart,this.marginEnd,this.deadSpace=0,this.majorSteps=[1,2,5,10],this.minorSteps=[.25,.5,1,2],this.setRange(t,e,i,s,o)}e.prototype.setRange=function(t,e,i,s,o){this._start=void 0===o.min?t:o.min,this._end=void 0===o.max?e:o.max,this._start==this._end&&(this._start-=.75,this._end+=1),this.autoScale&&this.setMinimumStep(i,s),this.setFirst(o)},e.prototype.setMinimumStep=function(t,e){var i=this._end-this._start,s=1.2*i,o=t*(s/e),n=Math.round(Math.log(s)/Math.LN10),r=-1,a=Math.pow(10,n),h=0;0>n&&(h=n);for(var d=!1,l=h;Math.abs(l)<=Math.abs(n);l++){a=Math.pow(10,l);for(var c=0;c=o){d=!0,r=c;break}}if(1==d)break}this.stepIndex=r,this.scale=a,this.step=a*this.minorSteps[r]},e.prototype.setFirst=function(t){void 0===t&&(t={});var e=void 0===t.min?this._start-2*this.scale*this.minorSteps[this.stepIndex]:t.min,i=void 0===t.max?this._end+this.scale*this.minorSteps[this.stepIndex]:t.max;this.marginEnd=void 0===t.max?this.roundToMinor(i):t.max,this.marginStart=void 0===t.min?this.roundToMinor(e):t.min,this.deadSpace=this.roundToMinor(i)-i+this.roundToMinor(e)-e,this.marginRange=this.marginEnd-this.marginStart,this.current=this.marginEnd},e.prototype.roundToMinor=function(t){var e=t-t%(this.scale*this.minorSteps[this.stepIndex]);return t%(this.scale*this.minorSteps[this.stepIndex])>.5*this.scale*this.minorSteps[this.stepIndex]?e+this.scale*this.minorSteps[this.stepIndex]:e},e.prototype.hasNext=function(){return this.current>=this.marginStart},e.prototype.next=function(){var t=this.current;this.current-=this.step,this.current==t&&(this.current=this._end)},e.prototype.previous=function(){this.current+=this.step,this.marginEnd+=this.step,this.marginRange=this.marginEnd-this.marginStart},e.prototype.getCurrent=function(){var t=""+Number(this.current).toPrecision(5);if(-1!=t.indexOf(",")||-1!=t.indexOf("."))for(var e=t.length-1;e>0;e--){if("0"!=t[e]){if("."==t[e]||","==t[e]){t=t.slice(0,e);break}break}t=t.slice(0,e)}return t},e.prototype.snap=function(){},e.prototype.isMajor=function(){return this.current%(this.scale*this.majorSteps[this.stepIndex])==0},t.exports=e},function(t,e,i){function s(t,e){var i=h().hours(0).minutes(0).seconds(0).milliseconds(0);this.start=i.clone().add(-3,"days").valueOf(),this.end=i.clone().add(4,"days").valueOf(),this.body=t,this.deltaDifference=0,this.scaleOffset=0,this.startToFront=!1,this.endToFront=!0,this.defaultOptions={start:null,end:null,direction:"horizontal",moveable:!0,zoomable:!0,min:null,max:null,zoomMin:10,zoomMax:31536e10},this.options=r.extend({},this.defaultOptions),this.props={touch:{}},this.animateTimer=null,this.body.emitter.on("dragstart",this._onDragStart.bind(this)),this.body.emitter.on("drag",this._onDrag.bind(this)),this.body.emitter.on("dragend",this._onDragEnd.bind(this)),this.body.emitter.on("hold",this._onHold.bind(this)),this.body.emitter.on("mousewheel",this._onMouseWheel.bind(this)),this.body.emitter.on("DOMMouseScroll",this._onMouseWheel.bind(this)),this.body.emitter.on("touch",this._onTouch.bind(this)),this.body.emitter.on("pinch",this._onPinch.bind(this)),this.setOptions(e)}function o(t){if("horizontal"!=t&&"vertical"!=t)throw new TypeError('Unknown direction "'+t+'". Choose "horizontal" or "vertical".')}function n(t,e){return{x:t.pageX-r.getAbsoluteLeft(e),y:t.pageY-r.getAbsoluteTop(e)}}var r=i(1),a=i(46),h=i(43),d=i(19),l=i(14);s.prototype=new d,s.prototype.setOptions=function(t){if(t){var e=["direction","min","max","zoomMin","zoomMax","moveable","zoomable","activate","hiddenDates"];r.selectiveExtend(e,this.options,t),("start"in t||"end"in t)&&this.setRange(t.start,t.end)}},s.prototype.setRange=function(t,e,i){function s(){if(!a.props.touch.dragging){var t=(new Date).valueOf(),e=t-p,i=e>c,m=i||null===o?o:r.easeInOutQuad(e,h,o,c),g=i||null===n?n:r.easeInOutQuad(e,d,n,c);f=a._applyRange(m,g),l.updateHiddenDates(a.body,a.options.hiddenDates),u=u||f,f&&a.body.emitter.emit("rangechange",{start:new Date(a.start),end:new Date(a.end)}),i?u&&a.body.emitter.emit("rangechanged",{start:new Date(a.start),end:new Date(a.end)}):a.animateTimer=setTimeout(s,20)}}var o=void 0!=t?r.convert(t,"Date").valueOf():null,n=void 0!=e?r.convert(e,"Date").valueOf():null;if(this._cancelAnimation(),i){var a=this,h=this.start,d=this.end,c="number"==typeof i?i:500,p=(new Date).valueOf(),u=!1;return s()}var f=this._applyRange(o,n);if(l.updateHiddenDates(this.body,this.options.hiddenDates),f){var m={start:new Date(this.start),end:new Date(this.end)};this.body.emitter.emit("rangechange",m),this.body.emitter.emit("rangechanged",m)}},s.prototype._cancelAnimation=function(){this.animateTimer&&(clearTimeout(this.animateTimer),this.animateTimer=null)},s.prototype._applyRange=function(t,e){var i,s=null!=t?r.convert(t,"Date").valueOf():this.start,o=null!=e?r.convert(e,"Date").valueOf():this.end,n=null!=this.options.max?r.convert(this.options.max,"Date").valueOf():null,a=null!=this.options.min?r.convert(this.options.min,"Date").valueOf():null;if(isNaN(s)||null===s)throw new Error('Invalid start "'+t+'"');if(isNaN(o)||null===o)throw new Error('Invalid end "'+e+'"');if(s>o&&(o=s),null!==a&&a>s&&(i=a-s,s+=i,o+=i,null!=n&&o>n&&(o=n)),null!==n&&o>n&&(i=o-n,s-=i,o-=i,null!=a&&a>s&&(s=a)),null!==this.options.zoomMin){var h=parseFloat(this.options.zoomMin);0>h&&(h=0),h>o-s&&(this.end-this.start===h?(s=this.start,o=this.end):(i=h-(o-s),s-=i/2,o+=i/2))}if(null!==this.options.zoomMax){var d=parseFloat(this.options.zoomMax);0>d&&(d=0),o-s>d&&(this.end-this.start===d?(s=this.start,o=this.end):(i=o-s-d,s+=i/2,o-=i/2))}var l=this.start!=s||this.end!=o;return this.start=s,this.end=o,l},s.prototype.getRange=function(){return{start:this.start,end:this.end}},s.prototype.conversion=function(t,e){return s.conversion(this.start,this.end,t,e)},s.conversion=function(t,e,i,s){return void 0===s&&(s=0),0!=i&&e-t!=0?{offset:t,scale:i/(e-t-s)}:{offset:0,scale:1}},s.prototype._onDragStart=function(){this.deltaDifference=0,this.previousDelta=0,this.options.moveable&&this.props.touch.allowDragging&&(this.props.touch.start=this.start,this.props.touch.end=this.end,this.props.touch.dragging=!0,this.body.dom.root&&(this.body.dom.root.style.cursor="move"))},s.prototype._onDrag=function(t){if(this.options.moveable&&this.props.touch.allowDragging){var e=this.options.direction;o(e);var i="horizontal"==e?t.gesture.deltaX:t.gesture.deltaY;i-=this.deltaDifference;var s=this.props.touch.end-this.props.touch.start,n=l.getHiddenDurationBetween(this.body.hiddenDates,this.start,this.end);s-=n;var r="horizontal"==e?this.body.domProps.center.width:this.body.domProps.center.height,a=-i/r*s,h=this.props.touch.start+a,d=this.props.touch.end+a,c=l.snapAwayFromHidden(this.body.hiddenDates,h,this.previousDelta-i,!0),p=l.snapAwayFromHidden(this.body.hiddenDates,d,this.previousDelta-i,!0);if(c!=h||p!=d)return this.deltaDifference+=i,this.props.touch.start=c,this.props.touch.end=p,void this._onDrag(t);this.previousDelta=i,this._applyRange(h,d),this.body.emitter.emit("rangechange",{start:new Date(this.start),end:new Date(this.end)})}},s.prototype._onDragEnd=function(){this.options.moveable&&this.props.touch.allowDragging&&(this.props.touch.dragging=!1,this.body.dom.root&&(this.body.dom.root.style.cursor="auto"),this.body.emitter.emit("rangechanged",{start:new Date(this.start),end:new Date(this.end)}))},s.prototype._onMouseWheel=function(t){if(this.options.zoomable&&this.options.moveable){var e=0;if(t.wheelDelta?e=t.wheelDelta/120:t.detail&&(e=-t.detail/3),e){var i;i=0>e?1-e/5:1/(1+e/5);var s=a.fakeGesture(this,t),o=n(s.center,this.body.dom.center),r=this._pointerToDate(o);this.zoom(i,r,e)}t.preventDefault()}},s.prototype._onTouch=function(){this.props.touch.start=this.start,this.props.touch.end=this.end,this.props.touch.allowDragging=!0,this.props.touch.center=null,this.scaleOffset=0,this.deltaDifference=0},s.prototype._onHold=function(){this.props.touch.allowDragging=!1},s.prototype._onPinch=function(t){if(this.options.zoomable&&this.options.moveable&&(this.props.touch.allowDragging=!1,t.gesture.touches.length>1)){this.props.touch.center||(this.props.touch.center=n(t.gesture.center,this.body.dom.center));var e=1/(t.gesture.scale+this.scaleOffset),i=this._pointerToDate(this.props.touch.center),s=l.getHiddenDurationBetween(this.body.hiddenDates,this.start,this.end),o=l.getHiddenDurationBefore(this.body.hiddenDates,this,i),r=s-o,a=i-o+(this.start-(i-o))*e,h=i+r+(this.end-(i+r))*e;this.startToFront=1-e>0?!1:!0,this.endToFront=e-1>0?!1:!0;var d=l.snapAwayFromHidden(this.body.hiddenDates,a,1-e,!0),c=l.snapAwayFromHidden(this.body.hiddenDates,h,e-1,!0);(d!=a||c!=h)&&(this.props.touch.start=d,this.props.touch.end=c,this.scaleOffset=1-t.gesture.scale,a=d,h=c),this.setRange(a,h),this.startToFront=!1,this.endToFront=!0}},s.prototype._pointerToDate=function(t){var e,i=this.options.direction;if(o(i),"horizontal"==i)return this.body.util.toTime(t.x).valueOf();var s=this.body.domProps.center.height;return e=this.conversion(s),t.y/e.scale+e.offset},s.prototype.zoom=function(t,e,i){null==e&&(e=(this.start+this.end)/2);var s=l.getHiddenDurationBetween(this.body.hiddenDates,this.start,this.end),o=l.getHiddenDurationBefore(this.body.hiddenDates,this,e),n=s-o,r=e-o+(this.start-(e-o))*t,a=e+n+(this.end-(e+n))*t;this.startToFront=i>0?!1:!0,this.endToFront=-i>0?!1:!0;var h=l.snapAwayFromHidden(this.body.hiddenDates,r,i,!0),d=l.snapAwayFromHidden(this.body.hiddenDates,a,-i,!0);(h!=r||d!=a)&&(r=h,a=d),this.setRange(r,a),this.startToFront=!1,this.endToFront=!0},s.prototype.move=function(t){var e=this.end-this.start,i=this.start+e*t,s=this.end+e*t;this.start=i,this.end=s},s.prototype.moveTo=function(t){var e=(this.start+this.end)/2,i=e-t,s=this.start-i,o=this.end-i;this.setRange(s,o)},t.exports=s},function(t,e){var i=.001;e.orderByStart=function(t){t.sort(function(t,e){return t.data.start-e.data.start})},e.orderByEnd=function(t){t.sort(function(t,e){var i="end"in t.data?t.data.end:t.data.start,s="end"in e.data?e.data.end:e.data.start;return i-s})},e.stack=function(t,i,s){var o,n;if(s)for(o=0,n=t.length;n>o;o++)t[o].top=null;for(o=0,n=t.length;n>o;o++){var r=t[o];if(r.stack&&null===r.top){r.top=i.axis;do{for(var a=null,h=0,d=t.length;d>h;h++){var l=t[h];if(null!==l.top&&l!==r&&l.stack&&e.collision(r,l,i.item)){a=l;break}}null!=a&&(r.top=a.top+a.height+i.item.vertical)}while(a)}}},e.nostack=function(t,e,i){var s,o,n;for(s=0,o=t.length;o>s;s++)if(void 0!==t[s].data.subgroup){n=e.axis;for(var r in i)i.hasOwnProperty(r)&&1==i[r].visible&&i[r].indexe.left&&t.top-s.vertical+ie.top}},function(t,e,i){function s(t,e,i,o){this.current=new Date,this._start=new Date,this._end=new Date,this.autoScale=!0,this.scale=s.SCALE.DAY,this.step=1,this.setRange(t,e,i),this.switchedDay=!1,this.switchedMonth=!1,this.switchedYear=!1,this.hiddenDates=o,void 0===o&&(this.hiddenDates=[])}var o=i(43),n=i(14);s.SCALE={MILLISECOND:1,SECOND:2,MINUTE:3,HOUR:4,DAY:5,WEEKDAY:6,MONTH:7,YEAR:8},s.prototype.setRange=function(t,e,i){if(!(t instanceof Date&&e instanceof Date))throw"No legal start or end date in method setRange";this._start=void 0!=t?new Date(t.valueOf()):new Date,this._end=void 0!=e?new Date(e.valueOf()):new Date,this.autoScale&&this.setMinimumStep(i)},s.prototype.first=function(){this.current=new Date(this._start.valueOf()),this.roundToMinor()},s.prototype.roundToMinor=function(){switch(this.scale){case s.SCALE.YEAR:this.current.setFullYear(this.step*Math.floor(this.current.getFullYear()/this.step)),this.current.setMonth(0);case s.SCALE.MONTH:this.current.setDate(1);case s.SCALE.DAY:case s.SCALE.WEEKDAY:this.current.setHours(0);case s.SCALE.HOUR:this.current.setMinutes(0);case s.SCALE.MINUTE:this.current.setSeconds(0);case s.SCALE.SECOND:this.current.setMilliseconds(0)}if(1!=this.step)switch(this.scale){case s.SCALE.MILLISECOND:this.current.setMilliseconds(this.current.getMilliseconds()-this.current.getMilliseconds()%this.step);break;case s.SCALE.SECOND:this.current.setSeconds(this.current.getSeconds()-this.current.getSeconds()%this.step);break;case s.SCALE.MINUTE:this.current.setMinutes(this.current.getMinutes()-this.current.getMinutes()%this.step);break;case s.SCALE.HOUR:this.current.setHours(this.current.getHours()-this.current.getHours()%this.step);break;case s.SCALE.WEEKDAY:case s.SCALE.DAY:this.current.setDate(this.current.getDate()-1-(this.current.getDate()-1)%this.step+1);break;case s.SCALE.MONTH:this.current.setMonth(this.current.getMonth()-this.current.getMonth()%this.step);break;case s.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()-this.current.getFullYear()%this.step)}},s.prototype.hasNext=function(){return this.current.valueOf()<=this._end.valueOf()},s.prototype.next=function(){var t=this.current.valueOf();if(this.current.getMonth()<6)switch(this.scale){case s.SCALE.MILLISECOND:this.current=new Date(this.current.valueOf()+this.step);break;case s.SCALE.SECOND:this.current=new Date(this.current.valueOf()+1e3*this.step);break;case s.SCALE.MINUTE:this.current=new Date(this.current.valueOf()+1e3*this.step*60);break;case s.SCALE.HOUR:this.current=new Date(this.current.valueOf()+1e3*this.step*60*60);var e=this.current.getHours();this.current.setHours(e-e%this.step);break;case s.SCALE.WEEKDAY:case s.SCALE.DAY:this.current.setDate(this.current.getDate()+this.step);break;case s.SCALE.MONTH:this.current.setMonth(this.current.getMonth()+this.step);break;case s.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()+this.step)}else switch(this.scale){case s.SCALE.MILLISECOND:this.current=new Date(this.current.valueOf()+this.step);break;case s.SCALE.SECOND:this.current.setSeconds(this.current.getSeconds()+this.step);break;case s.SCALE.MINUTE:this.current.setMinutes(this.current.getMinutes()+this.step);break;case s.SCALE.HOUR:this.current.setHours(this.current.getHours()+this.step);break;case s.SCALE.WEEKDAY:case s.SCALE.DAY:this.current.setDate(this.current.getDate()+this.step);break;case s.SCALE.MONTH:this.current.setMonth(this.current.getMonth()+this.step);break;case s.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()+this.step)}if(1!=this.step)switch(this.scale){case s.SCALE.MILLISECOND:this.current.getMilliseconds()0&&(this.step=e),this.autoScale=!1},s.prototype.setAutoScale=function(t){this.autoScale=t},s.prototype.setMinimumStep=function(t){if(void 0!=t){var e=31104e6,i=2592e6,o=864e5,n=36e5,r=6e4,a=1e3,h=1;1e3*e>t&&(this.scale=s.SCALE.YEAR,this.step=1e3),500*e>t&&(this.scale=s.SCALE.YEAR,this.step=500),100*e>t&&(this.scale=s.SCALE.YEAR,this.step=100),50*e>t&&(this.scale=s.SCALE.YEAR,this.step=50),10*e>t&&(this.scale=s.SCALE.YEAR,this.step=10),5*e>t&&(this.scale=s.SCALE.YEAR,this.step=5),e>t&&(this.scale=s.SCALE.YEAR,this.step=1),3*i>t&&(this.scale=s.SCALE.MONTH,this.step=3),i>t&&(this.scale=s.SCALE.MONTH,this.step=1),5*o>t&&(this.scale=s.SCALE.DAY,this.step=5),2*o>t&&(this.scale=s.SCALE.DAY,this.step=2),o>t&&(this.scale=s.SCALE.DAY,this.step=1),o/2>t&&(this.scale=s.SCALE.WEEKDAY,this.step=1),4*n>t&&(this.scale=s.SCALE.HOUR,this.step=4),n>t&&(this.scale=s.SCALE.HOUR,this.step=1),15*r>t&&(this.scale=s.SCALE.MINUTE,this.step=15),10*r>t&&(this.scale=s.SCALE.MINUTE,this.step=10),5*r>t&&(this.scale=s.SCALE.MINUTE,this.step=5),r>t&&(this.scale=s.SCALE.MINUTE,this.step=1),15*a>t&&(this.scale=s.SCALE.SECOND,this.step=15),10*a>t&&(this.scale=s.SCALE.SECOND,this.step=10),5*a>t&&(this.scale=s.SCALE.SECOND,this.step=5),a>t&&(this.scale=s.SCALE.SECOND,this.step=1),200*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=200),100*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=100),50*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=50),10*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=10),5*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=5),h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=1)}},s.prototype.snap=function(t){var e=new Date(t.valueOf());if(this.scale==s.SCALE.YEAR){var i=e.getFullYear()+Math.round(e.getMonth()/12);e.setFullYear(Math.round(i/this.step)*this.step),e.setMonth(0),e.setDate(0),e.setHours(0),e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.MONTH)e.getDate()>15?(e.setDate(1),e.setMonth(e.getMonth()+1)):e.setDate(1),e.setHours(0),e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0);else if(this.scale==s.SCALE.DAY){switch(this.step){case 5:case 2:e.setHours(24*Math.round(e.getHours()/24));break;default:e.setHours(12*Math.round(e.getHours()/12))}e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.WEEKDAY){switch(this.step){case 5:case 2:e.setHours(12*Math.round(e.getHours()/12));break;default:e.setHours(6*Math.round(e.getHours()/6))}e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.HOUR){switch(this.step){case 4:e.setMinutes(60*Math.round(e.getMinutes()/60));break;default:e.setMinutes(30*Math.round(e.getMinutes()/30))}e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.MINUTE){switch(this.step){case 15:case 10:e.setMinutes(5*Math.round(e.getMinutes()/5)),e.setSeconds(0);break;case 5:e.setSeconds(60*Math.round(e.getSeconds()/60));break;default:e.setSeconds(30*Math.round(e.getSeconds()/30))}e.setMilliseconds(0)}else if(this.scale==s.SCALE.SECOND)switch(this.step){case 15:case 10:e.setSeconds(5*Math.round(e.getSeconds()/5)),e.setMilliseconds(0);break;case 5:e.setMilliseconds(1e3*Math.round(e.getMilliseconds()/1e3));break;default:e.setMilliseconds(500*Math.round(e.getMilliseconds()/500))}else if(this.scale==s.SCALE.MILLISECOND){var o=this.step>5?this.step/2:1;e.setMilliseconds(Math.round(e.getMilliseconds()/o)*o)}return e},s.prototype.isMajor=function(){if(1==this.switchedYear)switch(this.switchedYear=!1,this.scale){case s.SCALE.YEAR:case s.SCALE.MONTH:case s.SCALE.WEEKDAY:case s.SCALE.DAY:case s.SCALE.HOUR:case s.SCALE.MINUTE:case s.SCALE.SECOND:case s.SCALE.MILLISECOND:return!0;default:return!1}else if(1==this.switchedMonth)switch(this.switchedMonth=!1,this.scale){case s.SCALE.WEEKDAY:case s.SCALE.DAY:case s.SCALE.HOUR:case s.SCALE.MINUTE:case s.SCALE.SECOND:case s.SCALE.MILLISECOND:return!0;default:return!1}else if(1==this.switchedDay)switch(this.switchedDay=!1,this.scale){case s.SCALE.MILLISECOND:case s.SCALE.SECOND:case s.SCALE.MINUTE:case s.SCALE.HOUR:return!0;default:return!1}switch(this.scale){case s.SCALE.MILLISECOND:return 0==this.current.getMilliseconds();case s.SCALE.SECOND:return 0==this.current.getSeconds();case s.SCALE.MINUTE:return 0==this.current.getHours()&&0==this.current.getMinutes();case s.SCALE.HOUR:return 0==this.current.getHours();case s.SCALE.WEEKDAY:case s.SCALE.DAY:return 1==this.current.getDate();case s.SCALE.MONTH:return 0==this.current.getMonth();case s.SCALE.YEAR:return!1;default:return!1}},s.prototype.getLabelMinor=function(t){switch(void 0==t&&(t=this.current),this.scale){case s.SCALE.MILLISECOND:return o(t).format("SSS");case s.SCALE.SECOND:return o(t).format("s");case s.SCALE.MINUTE:return o(t).format("HH:mm");case s.SCALE.HOUR:return o(t).format("HH:mm");case s.SCALE.WEEKDAY:return o(t).format("ddd D");case s.SCALE.DAY:return o(t).format("D");case s.SCALE.MONTH:return o(t).format("MMM");case s.SCALE.YEAR:return o(t).format("YYYY");default:return""}},s.prototype.getLabelMajor=function(t){switch(void 0==t&&(t=this.current),this.scale){case s.SCALE.MILLISECOND:return o(t).format("HH:mm:ss");case s.SCALE.SECOND:return o(t).format("D MMMM HH:mm");case s.SCALE.MINUTE:case s.SCALE.HOUR:return o(t).format("ddd D MMMM");case s.SCALE.WEEKDAY:case s.SCALE.DAY:return o(t).format("MMMM YYYY");case s.SCALE.MONTH:return o(t).format("YYYY");case s.SCALE.YEAR:return"";default:return""}},t.exports=s},function(t){function e(){this.options=null,this.props=null}e.prototype.setOptions=function(t){t&&util.extend(this.options,t)},e.prototype.redraw=function(){return!1},e.prototype.destroy=function(){},e.prototype._isResized=function(){var t=this.props._previousWidth!==this.props.width||this.props._previousHeight!==this.props.height;return this.props._previousWidth=this.props.width,this.props._previousHeight=this.props.height,t},t.exports=e},function(t,e,i){function s(t,e){this.body=t,this.defaultOptions={showCurrentTime:!0,locales:a,locale:"en"},this.options=o.extend({},this.defaultOptions),this.offset=0,this._create(),this.setOptions(e)}var o=i(1),n=i(19),r=i(43),a=i(47);s.prototype=new n,s.prototype._create=function(){var t=document.createElement("div");t.className="currenttime",t.style.position="absolute",t.style.top="0px",t.style.height="100%",this.bar=t},s.prototype.destroy=function(){this.options.showCurrentTime=!1,this.redraw(),this.body=null},s.prototype.setOptions=function(t){t&&o.selectiveExtend(["showCurrentTime","locale","locales"],this.options,t)},s.prototype.redraw=function(){if(this.options.showCurrentTime){var t=this.body.dom.backgroundVertical;this.bar.parentNode!=t&&(this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar),t.appendChild(this.bar),this.start());var e=new Date((new Date).valueOf()+this.offset),i=this.body.util.toScreen(e),s=this.options.locales[this.options.locale],o=s.current+" "+s.time+": "+r(e).format("dddd, MMMM Do YYYY, H:mm:ss");o=o.charAt(0).toUpperCase()+o.substring(1),this.bar.style.left=i+"px",this.bar.title=o}else this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar),this.stop();return!1},s.prototype.start=function(){function t(){e.stop();var i=e.body.range.conversion(e.body.domProps.center.width).scale,s=1/i/10;30>s&&(s=30),s>1e3&&(s=1e3),e.redraw(),e.currentTimeTimer=setTimeout(t,s)}var e=this;t()},s.prototype.stop=function(){void 0!==this.currentTimeTimer&&(clearTimeout(this.currentTimeTimer),delete this.currentTimeTimer)},s.prototype.setCurrentTime=function(t){var e=o.convert(t,"Date").valueOf(),i=(new Date).valueOf();this.offset=e-i,this.redraw()},s.prototype.getCurrentTime=function(){return new Date((new Date).valueOf()+this.offset)},t.exports=s},function(t,e,i){function s(t,e){this.body=t,this.defaultOptions={showCustomTime:!1,locales:h,locale:"en"},this.options=n.extend({},this.defaultOptions),this.customTime=new Date,this.eventParams={},this._create(),this.setOptions(e)}var o=i(44),n=i(1),r=i(19),a=i(43),h=i(47);s.prototype=new r,s.prototype.setOptions=function(t){t&&n.selectiveExtend(["showCustomTime","locale","locales"],this.options,t)},s.prototype._create=function(){var t=document.createElement("div");t.className="customtime",t.style.position="absolute",t.style.top="0px",t.style.height="100%",this.bar=t;var e=document.createElement("div");e.style.position="relative",e.style.top="0px",e.style.left="-10px",e.style.height="100%",e.style.width="20px",t.appendChild(e),this.hammer=o(t,{prevent_default:!0}),this.hammer.on("dragstart",this._onDragStart.bind(this)),this.hammer.on("drag",this._onDrag.bind(this)),this.hammer.on("dragend",this._onDragEnd.bind(this))},s.prototype.destroy=function(){this.options.showCustomTime=!1,this.redraw(),this.hammer.enable(!1),this.hammer=null,this.body=null},s.prototype.redraw=function(){if(this.options.showCustomTime){var t=this.body.dom.backgroundVertical;this.bar.parentNode!=t&&(this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar),t.appendChild(this.bar));var e=this.body.util.toScreen(this.customTime),i=this.options.locales[this.options.locale],s=i.time+": "+a(this.customTime).format("dddd, MMMM Do YYYY, H:mm:ss");s=s.charAt(0).toUpperCase()+s.substring(1),this.bar.style.left=e+"px",this.bar.title=s}else this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar);return!1},s.prototype.setCustomTime=function(t){this.customTime=n.convert(t,"Date"),this.redraw()},s.prototype.getCustomTime=function(){return new Date(this.customTime.valueOf())},s.prototype._onDragStart=function(t){this.eventParams.dragging=!0,this.eventParams.customTime=this.customTime,t.stopPropagation(),t.preventDefault()},s.prototype._onDrag=function(t){if(this.eventParams.dragging){var e=t.gesture.deltaX,i=this.body.util.toScreen(this.eventParams.customTime)+e,s=this.body.util.toTime(i);this.setCustomTime(s),this.body.emitter.emit("timechange",{time:new Date(this.customTime.valueOf())}),t.stopPropagation(),t.preventDefault()}},s.prototype._onDragEnd=function(t){this.eventParams.dragging&&(this.body.emitter.emit("timechanged",{time:new Date(this.customTime.valueOf())}),t.stopPropagation(),t.preventDefault())},t.exports=s},function(t,e,i){function s(t,e,i,s){this.id=o.randomUUID(),this.body=t,this.defaultOptions={orientation:"left",showMinorLabels:!0,showMajorLabels:!0,icons:!0,majorLinesOffset:7,minorLinesOffset:4,labelOffsetX:10,labelOffsetY:2,iconWidth:20,width:"40px",visible:!0,customRange:{left:{min:void 0,max:void 0},right:{min:void 0,max:void 0}}},this.linegraphOptions=s,this.linegraphSVG=i,this.props={},this.DOMelements={lines:{},labels:{}},this.dom={},this.range={start:0,end:0},this.options=o.extend({},this.defaultOptions),this.conversionFactor=1,this.setOptions(e),this.width=Number((""+this.options.width).replace("px","")),this.minWidth=this.width,this.height=this.linegraphSVG.offsetHeight,this.stepPixels=25,this.stepPixelsForced=25,this.lineOffset=0,this.master=!0,this.svgElements={},this.groups={},this.amountOfGroups=0,this._create()}var o=i(1),n=i(2),r=i(19),a=i(15);s.prototype=new r,s.prototype.addGroup=function(t,e){this.groups.hasOwnProperty(t)||(this.groups[t]=e),this.amountOfGroups+=1},s.prototype.updateGroup=function(t,e){this.groups[t]=e},s.prototype.removeGroup=function(t){this.groups.hasOwnProperty(t)&&(delete this.groups[t],this.amountOfGroups-=1)},s.prototype.setOptions=function(t){if(t){var e=!1;this.options.orientation!=t.orientation&&void 0!==t.orientation&&(e=!0);var i=["orientation","showMinorLabels","showMajorLabels","icons","majorLinesOffset","minorLinesOffset","labelOffsetX","labelOffsetY","iconWidth","width","visible","customRange"];o.selectiveExtend(i,this.options,t),this.minWidth=Number((""+this.options.width).replace("px","")),1==e&&this.dom.frame&&(this.hide(),this.show())}},s.prototype._create=function(){this.dom.frame=document.createElement("div"),this.dom.frame.style.width=this.options.width,this.dom.frame.style.height=this.height,this.dom.lineContainer=document.createElement("div"),this.dom.lineContainer.style.width="100%",this.dom.lineContainer.style.height=this.height,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0px",this.svg.style.height="100%",this.svg.style.width="100%",this.svg.style.display="block",this.dom.frame.appendChild(this.svg)},s.prototype._redrawGroupIcons=function(){n.prepareElements(this.svgElements);var t,e=this.options.iconWidth,i=15,s=4,o=s+.5*i;t="left"==this.options.orientation?s:this.width-e-s;for(var r in this.groups)this.groups.hasOwnProperty(r)&&(1!=this.groups[r].visible||void 0!==this.linegraphOptions.visibility[r]&&1!=this.linegraphOptions.visibility[r]||(this.groups[r].drawIcon(t,o,this.svgElements,this.svg,e,i),o+=i+s));n.cleanupElements(this.svgElements)},s.prototype.show=function(){this.dom.frame.parentNode||("left"==this.options.orientation?this.body.dom.left.appendChild(this.dom.frame):this.body.dom.right.appendChild(this.dom.frame)),this.dom.lineContainer.parentNode||this.body.dom.backgroundHorizontal.appendChild(this.dom.lineContainer)},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame),this.dom.lineContainer.parentNode&&this.dom.lineContainer.parentNode.removeChild(this.dom.lineContainer)},s.prototype.setRange=function(t,e){this.range.start=t,this.range.end=e},s.prototype.redraw=function(){var t=!1,e=0;for(var i in this.groups)this.groups.hasOwnProperty(i)&&(1!=this.groups[i].visible||void 0!==this.linegraphOptions.visibility[i]&&1!=this.linegraphOptions.visibility[i]||e++);if(0==this.amountOfGroups||0==e)this.hide();else{this.show(),this.height=Number(this.linegraphSVG.style.height.replace("px","")),this.dom.lineContainer.style.height=this.height+"px",this.width=1==this.options.visible?Number((""+this.options.width).replace("px","")):0;var s=this.props,o=this.dom.frame;o.className="dataaxis",this._calculateCharSize();var n=this.options.orientation,r=this.options.showMinorLabels,a=this.options.showMajorLabels;s.minorLabelHeight=r?s.minorCharHeight:0,s.majorLabelHeight=a?s.majorCharHeight:0,s.minorLineWidth=this.body.dom.backgroundHorizontal.offsetWidth-this.lineOffset-this.width+2*this.options.minorLinesOffset,s.minorLineHeight=1,s.majorLineWidth=this.body.dom.backgroundHorizontal.offsetWidth-this.lineOffset-this.width+2*this.options.majorLinesOffset,s.majorLineHeight=1,"left"==n?(o.style.top="0",o.style.left="0",o.style.bottom="",o.style.width=this.width+"px",o.style.height=this.height+"px"):(o.style.top="",o.style.bottom="0",o.style.left="0",o.style.width=this.width+"px",o.style.height=this.height+"px"),t=this._redrawLabels(),1==this.options.icons&&this._redrawGroupIcons()}return t},s.prototype._redrawLabels=function(){n.prepareElements(this.DOMelements.lines),n.prepareElements(this.DOMelements.labels);var t=this.options.orientation,e=this.master?this.props.majorCharHeight||10:this.stepPixelsForced,i=new a(this.range.start,this.range.end,e,this.dom.frame.offsetHeight,this.options.customRange[this.options.orientation]);this.step=i;var s=(this.dom.frame.offsetHeight-i.deadSpace*(this.dom.frame.offsetHeight/i.marginRange))/((i.marginRange-i.deadSpace)/i.step);this.stepPixels=s;var o=this.height/s,r=0;if(0==this.master){s=this.stepPixelsForced,r=Math.round(this.dom.frame.offsetHeight/s-o);for(var h=0;.5*r>h;h++)i.previous();o=this.height/s}else o+=.25;this.valueAtZero=i.marginEnd;var d=0,l=1;this.maxLabelSize=0;for(var c=0;l=0&&this._redrawLabel(c-2,i.getCurrent(),t,"yAxis major",this.props.majorCharHeight),this._redrawLine(c,t,"grid horizontal major",this.options.majorLinesOffset,this.props.majorLineWidth)):this._redrawLine(c,t,"grid horizontal minor",this.options.minorLinesOffset,this.props.minorLineWidth),l++}this.conversionFactor=0==this.master?c/(this.valueAtZero-i.current):this.dom.frame.offsetHeight/i.marginRange;var u=1==this.options.icons?this.options.iconWidth+this.options.labelOffsetX+15:this.options.labelOffsetX+15;return this.maxLabelSize>this.width-u&&1==this.options.visible?(this.width=this.maxLabelSize+u,this.options.width=this.width+"px",n.cleanupElements(this.DOMelements.lines),n.cleanupElements(this.DOMelements.labels),this.redraw(),!0):this.maxLabelSizethis.minWidth?(this.width=Math.max(this.minWidth,this.maxLabelSize+u),this.options.width=this.width+"px",n.cleanupElements(this.DOMelements.lines),n.cleanupElements(this.DOMelements.labels),this.redraw(),!0):(n.cleanupElements(this.DOMelements.lines),n.cleanupElements(this.DOMelements.labels),!1)},s.prototype.convertValue=function(t){var e=this.valueAtZero-t,i=e*this.conversionFactor;return i},s.prototype._redrawLabel=function(t,e,i,s,o){var r=n.getDOMElement("div",this.DOMelements.labels,this.dom.frame);r.className=s,r.innerHTML=e,"left"==i?(r.style.left="-"+this.options.labelOffsetX+"px",r.style.textAlign="right"):(r.style.right="-"+this.options.labelOffsetX+"px",r.style.textAlign="left"),r.style.top=t-.5*o+this.options.labelOffsetY+"px",e+="";var a=Math.max(this.props.majorCharWidth,this.props.minorCharWidth);this.maxLabelSized;d++){var c=this.visibleItems[d];c.repositionY(e)}return s},s.prototype._calculateHeight=function(t){var e,i=this.visibleItems;this.resetSubgroups();var s=this;if(i.length){var n=i[0].top,r=i[0].top+i[0].height;if(o.forEach(i,function(t){n=Math.min(n,t.top),r=Math.max(r,t.top+t.height),void 0!==t.data.subgroup&&(s.subgroups[t.data.subgroup].height=Math.max(s.subgroups[t.data.subgroup].height,t.height),s.subgroups[t.data.subgroup].visible=!0)}),n>t.axis){var a=n-t.axis;r-=a,o.forEach(i,function(t){t.top-=a})}e=r+t.item.vertical/2}else e=t.axis+t.item.vertical;return e=Math.max(e,this.props.label.height)},s.prototype.show=function(){this.dom.label.parentNode||this.itemSet.dom.labelSet.appendChild(this.dom.label),this.dom.foreground.parentNode||this.itemSet.dom.foreground.appendChild(this.dom.foreground),this.dom.background.parentNode||this.itemSet.dom.background.appendChild(this.dom.background),this.dom.axis.parentNode||this.itemSet.dom.axis.appendChild(this.dom.axis)},s.prototype.hide=function(){var t=this.dom.label;t.parentNode&&t.parentNode.removeChild(t);var e=this.dom.foreground;e.parentNode&&e.parentNode.removeChild(e);var i=this.dom.background;i.parentNode&&i.parentNode.removeChild(i);var s=this.dom.axis;s.parentNode&&s.parentNode.removeChild(s)},s.prototype.add=function(t){if(this.items[t.id]=t,t.setParent(this),void 0!==t.data.subgroup&&(void 0===this.subgroups[t.data.subgroup]&&(this.subgroups[t.data.subgroup]={height:0,visible:!1,index:this.subgroupIndex,items:[]},this.subgroupIndex++),this.subgroups[t.data.subgroup].items.push(t)),this.orderSubgroups(),-1==this.visibleItems.indexOf(t)){var e=this.itemSet.body.range;this._checkIfVisible(t,this.visibleItems,e)}},s.prototype.orderSubgroups=function(){if(void 0!==this.subgroupOrderer){var t=[];if("string"==typeof this.subgroupOrderer){for(var e in this.subgroups)t.push({subgroup:e,sortField:this.subgroups[e].items[0].data[this.subgroupOrderer]});t.sort(function(t,e){return t.sortField-e.sortField})}else if("function"==typeof this.subgroupOrderer){for(var e in this.subgroups)t.push(this.subgroups[e].items[0].data);t.sort(this.subgroupOrderer)}if(t.length>0)for(var i=0;i0)for(n=0;n=0&&!this._checkIfInvisible(t.byStart[n],r,i);n--);for(n=s+1;n=0&&!this._checkIfInvisible(t.byEnd[n],r,i);n--);for(n=a+1;ns;s++){var n=this.visibleItems[s];n.repositionY(e)}return i},s.prototype.show=function(){this.dom.background.parentNode||this.itemSet.dom.background.appendChild(this.dom.background)},t.exports=s},function(t,e,i){function s(t,e){this.body=t,this.defaultOptions={type:null,orientation:"bottom",align:"auto",stack:!0,groupOrder:null,selectable:!0,editable:{updateTime:!1,updateGroup:!1,add:!1,remove:!1},onAdd:function(t,e){e(t)},onUpdate:function(t,e){e(t)},onMove:function(t,e){e(t)},onRemove:function(t,e){e(t)},onMoving:function(t,e){e(t)},margin:{item:{horizontal:10,vertical:10},axis:20},padding:5},this.options=n.extend({},this.defaultOptions),this.itemOptions={type:{start:"Date",end:"Date"}},this.conversion={toScreen:t.util.toScreen,toTime:t.util.toTime},this.dom={},this.props={},this.hammer=null;var i=this;this.itemsData=null,this.groupsData=null,this.itemListeners={add:function(t,e){i._onAdd(e.items)},update:function(t,e){i._onUpdate(e.items)},remove:function(t,e){i._onRemove(e.items)}},this.groupListeners={add:function(t,e){i._onAddGroups(e.items)},update:function(t,e){i._onUpdateGroups(e.items)},remove:function(t,e){i._onRemoveGroups(e.items)}},this.items={},this.groups={},this.groupIds=[],this.selection=[],this.stackDirty=!0,this.touchParams={},this._create(),this.setOptions(e)}var o=i(44),n=i(1),r=i(3),a=i(4),h=i(19),d=i(24),l=i(25),c=i(32),p=i(33),u=i(34),f=i(31),m="__ungrouped__",g="__background__";s.prototype=new h,s.types={background:f,box:c,range:u,point:p},s.prototype._create=function(){var t=document.createElement("div");t.className="itemset",t["timeline-itemset"]=this,this.dom.frame=t;var e=document.createElement("div");e.className="background",t.appendChild(e),this.dom.background=e;var i=document.createElement("div");i.className="foreground",t.appendChild(i),this.dom.foreground=i;var s=document.createElement("div");s.className="axis",this.dom.axis=s;var n=document.createElement("div");n.className="labelset",this.dom.labelSet=n,this._updateUngrouped();var r=new l(g,null,this);r.show(),this.groups[g]=r,this.hammer=o(this.body.dom.centerContainer,{prevent_default:!0}),this.hammer.on("touch",this._onTouch.bind(this)),this.hammer.on("dragstart",this._onDragStart.bind(this)),this.hammer.on("drag",this._onDrag.bind(this)),this.hammer.on("dragend",this._onDragEnd.bind(this)),this.hammer.on("tap",this._onSelectItem.bind(this)),this.hammer.on("hold",this._onMultiSelectItem.bind(this)),this.hammer.on("doubletap",this._onAddItem.bind(this)),this.show()},s.prototype.setOptions=function(t){if(t){var e=["type","align","orientation","padding","stack","selectable","groupOrder","dataAttributes","template","hide"];n.selectiveExtend(e,this.options,t),"margin"in t&&("number"==typeof t.margin?(this.options.margin.axis=t.margin,this.options.margin.item.horizontal=t.margin,this.options.margin.item.vertical=t.margin):"object"==typeof t.margin&&(n.selectiveExtend(["axis"],this.options.margin,t.margin),"item"in t.margin&&("number"==typeof t.margin.item?(this.options.margin.item.horizontal=t.margin.item,this.options.margin.item.vertical=t.margin.item):"object"==typeof t.margin.item&&n.selectiveExtend(["horizontal","vertical"],this.options.margin.item,t.margin.item)))),"editable"in t&&("boolean"==typeof t.editable?(this.options.editable.updateTime=t.editable,this.options.editable.updateGroup=t.editable,this.options.editable.add=t.editable,this.options.editable.remove=t.editable):"object"==typeof t.editable&&n.selectiveExtend(["updateTime","updateGroup","add","remove"],this.options.editable,t.editable)); -var i=function(e){var i=t[e];if(i){if(!(i instanceof Function))throw new Error("option "+e+" must be a function "+e+"(item, callback)");this.options[e]=i}}.bind(this);["onAdd","onUpdate","onRemove","onMove","onMoving"].forEach(i),this.markDirty()}},s.prototype.markDirty=function(){this.groupIds=[],this.stackDirty=!0},s.prototype.destroy=function(){this.hide(),this.setItems(null),this.setGroups(null),this.hammer=null,this.body=null,this.conversion=null},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame),this.dom.axis.parentNode&&this.dom.axis.parentNode.removeChild(this.dom.axis),this.dom.labelSet.parentNode&&this.dom.labelSet.parentNode.removeChild(this.dom.labelSet)},s.prototype.show=function(){this.dom.frame.parentNode||this.body.dom.center.appendChild(this.dom.frame),this.dom.axis.parentNode||this.body.dom.backgroundVertical.appendChild(this.dom.axis),this.dom.labelSet.parentNode||this.body.dom.left.appendChild(this.dom.labelSet)},s.prototype.setSelection=function(t){var e,i,s,o;for(void 0==t&&(t=[]),Array.isArray(t)||(t=[t]),e=0,i=this.selection.length;i>e;e++)s=this.selection[e],o=this.items[s],o&&o.unselect();for(this.selection=[],e=0,i=t.length;i>e;e++)s=t[e],o=this.items[s],o&&(this.selection.push(s),o.select())},s.prototype.getSelection=function(){return this.selection.concat([])},s.prototype.getVisibleItems=function(){var t=this.body.range.getRange(),e=this.body.util.toScreen(t.start),i=this.body.util.toScreen(t.end),s=[];for(var o in this.groups)if(this.groups.hasOwnProperty(o))for(var n=this.groups[o],r=n.visibleItems,a=0;ae&&s.push(h.id)}return s},s.prototype._deselect=function(t){for(var e=this.selection,i=0,s=e.length;s>i;i++)if(e[i]==t){e.splice(i,1);break}},s.prototype.redraw=function(){var t=this.options.margin,e=this.body.range,i=n.option.asSize,s=this.options,o=s.orientation,r=!1,a=this.dom.frame,h=s.editable.updateTime||s.editable.updateGroup;this.props.top=this.body.domProps.top.height+this.body.domProps.border.top,this.props.left=this.body.domProps.left.width+this.body.domProps.border.left,a.className="itemset"+(h?" editable":""),r=this._orderGroups()||r;var d=e.end-e.start,l=d!=this.lastVisibleInterval||this.props.width!=this.props.lastWidth;l&&(this.stackDirty=!0),this.lastVisibleInterval=d,this.props.lastWidth=this.props.width,this.groups[g].redraw(e,f,c);var c=this.stackDirty,p=this._firstGroup(),u={item:t.item,axis:t.axis},f={item:t.item,axis:t.item.vertical/2},m=0,v=t.axis+t.item.vertical;return n.forEach(this.groups,function(t){var i=t==p?u:f,s=t.redraw(e,i,c);r=s||r,m+=t.height}),m=Math.max(m,v),this.stackDirty=!1,a.style.height=i(m),this.props.width=a.offsetWidth,this.props.height=m,this.dom.axis.style.top=i("top"==o?this.body.domProps.top.height+this.body.domProps.border.top:this.body.domProps.top.height+this.body.domProps.centerContainer.height),this.dom.axis.style.left="0",r=this._isResized()||r},s.prototype._firstGroup=function(){var t="top"==this.options.orientation?0:this.groupIds.length-1,e=this.groupIds[t],i=this.groups[e]||this.groups[m];return i||null},s.prototype._updateUngrouped=function(){{var t,e,i=this.groups[m];this.groups[g]}if(this.groupsData){if(i){i.hide(),delete this.groups[m];for(e in this.items)if(this.items.hasOwnProperty(e)){t=this.items[e],t.parent&&t.parent.remove(t);var s=this._getGroupId(t.data),o=this.groups[s];o&&o.add(t)||t.hide()}}}else if(!i){var n=null,r=null;i=new d(n,r,this),this.groups[m]=i;for(e in this.items)this.items.hasOwnProperty(e)&&(t=this.items[e],i.add(t));i.show()}},s.prototype.getLabelSet=function(){return this.dom.labelSet},s.prototype.setItems=function(t){var e,i=this,s=this.itemsData;if(t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.itemsData=t}else this.itemsData=null;if(s&&(n.forEach(this.itemListeners,function(t,e){s.off(e,t)}),e=s.getIds(),this._onRemove(e)),this.itemsData){var o=this.id;n.forEach(this.itemListeners,function(t,e){i.itemsData.on(e,t,o)}),e=this.itemsData.getIds(),this._onAdd(e),this._updateUngrouped()}},s.prototype.getItems=function(){return this.itemsData},s.prototype.setGroups=function(t){var e,i=this;if(this.groupsData&&(n.forEach(this.groupListeners,function(t,e){i.groupsData.unsubscribe(e,t)}),e=this.groupsData.getIds(),this.groupsData=null,this._onRemoveGroups(e)),t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.groupsData=t}else this.groupsData=null;if(this.groupsData){var s=this.id;n.forEach(this.groupListeners,function(t,e){i.groupsData.on(e,t,s)}),e=this.groupsData.getIds(),this._onAddGroups(e)}this._updateUngrouped(),this._order(),this.body.emitter.emit("change")},s.prototype.getGroups=function(){return this.groupsData},s.prototype.removeItem=function(t){var e=this.itemsData.get(t),i=this.itemsData.getDataSet();e&&this.options.onRemove(e,function(e){e&&i.remove(t)})},s.prototype._getType=function(t){return t.type||this.options.type||(t.end?"range":"box")},s.prototype._getGroupId=function(t){var e=this._getType(t);return"background"==e&&void 0==t.group?g:this.groupsData?t.group:m},s.prototype._onUpdate=function(t){var e=this;t.forEach(function(t){var i=e.itemsData.get(t,e.itemOptions),o=e.items[t],n=e._getType(i),r=s.types[n];if(o&&(r&&o instanceof r?e._updateItem(o,i):(e._removeItem(o),o=null)),!o){if(!r)throw new TypeError("rangeoverflow"==n?'Item type "rangeoverflow" is deprecated. Use css styling instead: .vis.timeline .item.range .content {overflow: visible;}':'Unknown item type "'+n+'"');o=new r(i,e.conversion,e.options),o.id=t,e._addItem(o)}}),this._order(),this.stackDirty=!0,this.body.emitter.emit("change")},s.prototype._onAdd=s.prototype._onUpdate,s.prototype._onRemove=function(t){var e=0,i=this;t.forEach(function(t){var s=i.items[t];s&&(e++,i._removeItem(s))}),e&&(this._order(),this.stackDirty=!0,this.body.emitter.emit("change"))},s.prototype._order=function(){n.forEach(this.groups,function(t){t.order()})},s.prototype._onUpdateGroups=function(t){this._onAddGroups(t)},s.prototype._onAddGroups=function(t){var e=this;t.forEach(function(t){var i=e.groupsData.get(t),s=e.groups[t];if(s)s.setData(i);else{if(t==m||t==g)throw new Error("Illegal group id. "+t+" is a reserved id.");var o=Object.create(e.options);n.extend(o,{height:null}),s=new d(t,i,e),e.groups[t]=s;for(var r in e.items)if(e.items.hasOwnProperty(r)){var a=e.items[r];a.data.group==t&&s.add(a)}s.order(),s.show()}}),this.body.emitter.emit("change")},s.prototype._onRemoveGroups=function(t){var e=this.groups;t.forEach(function(t){var i=e[t];i&&(i.hide(),delete e[t])}),this.markDirty(),this.body.emitter.emit("change")},s.prototype._orderGroups=function(){if(this.groupsData){var t=this.groupsData.getIds({order:this.options.groupOrder}),e=!n.equalArray(t,this.groupIds);if(e){var i=this.groups;t.forEach(function(t){i[t].hide()}),t.forEach(function(t){i[t].show()}),this.groupIds=t}return e}return!1},s.prototype._addItem=function(t){this.items[t.id]=t;var e=this._getGroupId(t.data),i=this.groups[e];i&&i.add(t)},s.prototype._updateItem=function(t,e){var i=t.data.group;if(t.setData(e),i!=t.data.group){var s=this.groups[i];s&&s.remove(t);var o=this._getGroupId(t.data),n=this.groups[o];n&&n.add(t)}},s.prototype._removeItem=function(t){t.hide(),delete this.items[t.id];var e=this.selection.indexOf(t.id);-1!=e&&this.selection.splice(e,1),t.parent&&t.parent.remove(t)},s.prototype._constructByEndArray=function(t){for(var e=[],i=0;i0||o.length>0)&&this.body.emitter.emit("select",{items:this.getSelection()})}},s.prototype._onAddItem=function(t){if(this.options.selectable&&this.options.editable.add){var e=this,i=this.body.util.snap||null,o=s.itemFromTarget(t);if(o){var r=e.itemsData.get(o.id);this.options.onUpdate(r,function(t){t&&e.itemsData.update(t)})}else{var a=n.getAbsoluteLeft(this.dom.frame),h=t.gesture.center.pageX-a,d=this.body.util.toTime(h),l={start:i?i(d):d,content:"new item"};if("range"===this.options.type){var c=this.body.util.toTime(h+this.props.width/5);l.end=i?i(c):c}l[this.itemsData._fieldId]=n.randomUUID();var p=s.groupFromTarget(t);p&&(l.group=p.groupId),this.options.onAdd(l,function(t){t&&e.itemsData.add(t)})}}},s.prototype._onMultiSelectItem=function(t){if(this.options.selectable){var e,i=s.itemFromTarget(t);if(i){e=this.getSelection();var o=e.indexOf(i.id);-1==o?e.push(i.id):e.splice(o,1),this.setSelection(e),this.body.emitter.emit("select",{items:this.getSelection()})}}},s.itemFromTarget=function(t){for(var e=t.target;e;){if(e.hasOwnProperty("timeline-item"))return e["timeline-item"];e=e.parentNode}return null},s.groupFromTarget=function(t){for(var e=t.target;e;){if(e.hasOwnProperty("timeline-group"))return e["timeline-group"];e=e.parentNode}return null},s.itemSetFromTarget=function(t){for(var e=t.target;e;){if(e.hasOwnProperty("timeline-itemset"))return e["timeline-itemset"];e=e.parentNode}return null},t.exports=s},function(t,e,i){function s(t,e,i,s){this.body=t,this.defaultOptions={enabled:!0,icons:!0,iconSize:20,iconSpacing:6,left:{visible:!0,position:"top-left"},right:{visible:!0,position:"top-left"}},this.side=i,this.options=o.extend({},this.defaultOptions),this.linegraphOptions=s,this.svgElements={},this.dom={},this.groups={},this.amountOfGroups=0,this._create(),this.setOptions(e)}var o=i(1),n=i(2),r=i(19);s.prototype=new r,s.prototype.addGroup=function(t,e){this.groups.hasOwnProperty(t)||(this.groups[t]=e),this.amountOfGroups+=1},s.prototype.updateGroup=function(t,e){this.groups[t]=e},s.prototype.removeGroup=function(t){this.groups.hasOwnProperty(t)&&(delete this.groups[t],this.amountOfGroups-=1)},s.prototype._create=function(){this.dom.frame=document.createElement("div"),this.dom.frame.className="legend",this.dom.frame.style.position="absolute",this.dom.frame.style.top="10px",this.dom.frame.style.display="block",this.dom.textArea=document.createElement("div"),this.dom.textArea.className="legendText",this.dom.textArea.style.position="relative",this.dom.textArea.style.top="0px",this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0px",this.svg.style.width=this.options.iconSize+5+"px",this.svg.style.height="100%",this.dom.frame.appendChild(this.svg),this.dom.frame.appendChild(this.dom.textArea)},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame)},s.prototype.show=function(){this.dom.frame.parentNode||this.body.dom.center.appendChild(this.dom.frame)},s.prototype.setOptions=function(t){var e=["enabled","orientation","icons","left","right"];o.selectiveDeepExtend(e,this.options,t)},s.prototype.redraw=function(){var t=0;for(var e in this.groups)this.groups.hasOwnProperty(e)&&(1!=this.groups[e].visible||void 0!==this.linegraphOptions.visibility[e]&&1!=this.linegraphOptions.visibility[e]||t++);if(0==this.options[this.side].visible||0==this.amountOfGroups||0==this.options.enabled||0==t)this.hide();else{this.show(),"top-left"==this.options[this.side].position||"bottom-left"==this.options[this.side].position?(this.dom.frame.style.left="4px",this.dom.frame.style.textAlign="left",this.dom.textArea.style.textAlign="left",this.dom.textArea.style.left=this.options.iconSize+15+"px",this.dom.textArea.style.right="",this.svg.style.left="0px",this.svg.style.right=""):(this.dom.frame.style.right="4px",this.dom.frame.style.textAlign="right",this.dom.textArea.style.textAlign="right",this.dom.textArea.style.right=this.options.iconSize+15+"px",this.dom.textArea.style.left="",this.svg.style.right="0px",this.svg.style.left=""),"top-left"==this.options[this.side].position||"top-right"==this.options[this.side].position?(this.dom.frame.style.top=4-Number(this.body.dom.center.style.top.replace("px",""))+"px",this.dom.frame.style.bottom=""):(this.dom.frame.style.bottom=4-Number(this.body.dom.center.style.top.replace("px",""))+"px",this.dom.frame.style.top=""),0==this.options.icons?(this.dom.frame.style.width=this.dom.textArea.offsetWidth+10+"px",this.dom.textArea.style.right="",this.dom.textArea.style.left="",this.svg.style.width="0px"):(this.dom.frame.style.width=this.options.iconSize+15+this.dom.textArea.offsetWidth+10+"px",this.drawLegendIcons());var i="";for(var e in this.groups)this.groups.hasOwnProperty(e)&&(1!=this.groups[e].visible||void 0!==this.linegraphOptions.visibility[e]&&1!=this.linegraphOptions.visibility[e]||(i+=this.groups[e].content+"
"));this.dom.textArea.innerHTML=i,this.dom.textArea.style.lineHeight=.75*this.options.iconSize+this.options.iconSpacing+"px"}},s.prototype.drawLegendIcons=function(){if(this.dom.frame.parentNode){n.prepareElements(this.svgElements);var t=window.getComputedStyle(this.dom.frame).paddingTop,e=Number(t.replace("px","")),i=e,s=this.options.iconSize,o=.75*this.options.iconSize,r=e+.5*o+3;this.svg.style.width=s+5+e+"px";for(var a in this.groups)this.groups.hasOwnProperty(a)&&(1!=this.groups[a].visible||void 0!==this.linegraphOptions.visibility[a]&&1!=this.linegraphOptions.visibility[a]||(this.groups[a].drawIcon(i,r,this.svgElements,this.svg,s,o),r+=o+this.options.iconSpacing));n.cleanupElements(this.svgElements)}},t.exports=s},function(t,e,i){function s(t,e){this.id=o.randomUUID(),this.body=t,this.defaultOptions={yAxisOrientation:"left",defaultGroup:"default",sort:!0,sampling:!0,graphHeight:"400px",shaded:{enabled:!1,orientation:"bottom"},style:"line",barChart:{width:50,handleOverlap:"overlap",align:"center"},catmullRom:{enabled:!0,parametrization:"centripetal",alpha:.5},drawPoints:{enabled:!0,size:6,style:"square"},dataAxis:{showMinorLabels:!0,showMajorLabels:!0,icons:!1,width:"40px",visible:!0,customRange:{left:{min:void 0,max:void 0},right:{min:void 0,max:void 0}}},legend:{enabled:!1,icons:!0,left:{visible:!0,position:"top-left"},right:{visible:!0,position:"top-right"}},groups:{visibility:{}}},this.options=o.extend({},this.defaultOptions),this.dom={},this.props={},this.hammer=null,this.groups={},this.abortedGraphUpdate=!1;var i=this;this.itemsData=null,this.groupsData=null,this.itemListeners={add:function(t,e){i._onAdd(e.items)},update:function(t,e){i._onUpdate(e.items)},remove:function(t,e){i._onRemove(e.items)}},this.groupListeners={add:function(t,e){i._onAddGroups(e.items)},update:function(t,e){i._onUpdateGroups(e.items)},remove:function(t,e){i._onRemoveGroups(e.items)}},this.items={},this.selection=[],this.lastStart=this.body.range.start,this.touchParams={},this.svgElements={},this.setOptions(e),this.groupsUsingDefaultStyles=[0],this.body.emitter.on("rangechanged",function(){i.lastStart=i.body.range.start,i.svg.style.left=o.option.asSize(-i.width),i._updateGraph.apply(i)}),this._create(),this.body.emitter.emit("change")}var o=i(1),n=i(2),r=i(3),a=i(4),h=i(19),d=i(22),l=i(23),c=i(27),p="__ungrouped__";s.prototype=new h,s.prototype._create=function(){var t=document.createElement("div");t.className="LineGraph",this.dom.frame=t,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="relative",this.svg.style.height=(""+this.options.graphHeight).replace("px","")+"px",this.svg.style.display="block",t.appendChild(this.svg),this.options.dataAxis.orientation="left",this.yAxisLeft=new d(this.body,this.options.dataAxis,this.svg,this.options.groups),this.options.dataAxis.orientation="right",this.yAxisRight=new d(this.body,this.options.dataAxis,this.svg,this.options.groups),delete this.options.dataAxis.orientation,this.legendLeft=new c(this.body,this.options.legend,"left",this.options.groups),this.legendRight=new c(this.body,this.options.legend,"right",this.options.groups),this.show()},s.prototype.setOptions=function(t){if(t){var e=["sampling","defaultGroup","graphHeight","yAxisOrientation","style","barChart","dataAxis","sort","groups"];o.selectiveDeepExtend(e,this.options,t),o.mergeOptions(this.options,t,"catmullRom"),o.mergeOptions(this.options,t,"drawPoints"),o.mergeOptions(this.options,t,"shaded"),o.mergeOptions(this.options,t,"legend"),t.catmullRom&&"object"==typeof t.catmullRom&&t.catmullRom.parametrization&&("uniform"==t.catmullRom.parametrization?this.options.catmullRom.alpha=0:"chordal"==t.catmullRom.parametrization?this.options.catmullRom.alpha=1:(this.options.catmullRom.parametrization="centripetal",this.options.catmullRom.alpha=.5)),this.yAxisLeft&&void 0!==t.dataAxis&&(this.yAxisLeft.setOptions(this.options.dataAxis),this.yAxisRight.setOptions(this.options.dataAxis)),this.legendLeft&&void 0!==t.legend&&(this.legendLeft.setOptions(this.options.legend),this.legendRight.setOptions(this.options.legend)),this.groups.hasOwnProperty(p)&&this.groups[p].setOptions(t)}this.dom.frame&&this._updateGraph()},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame)},s.prototype.show=function(){this.dom.frame.parentNode||this.body.dom.center.appendChild(this.dom.frame)},s.prototype.setItems=function(t){var e,i=this,s=this.itemsData;if(t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.itemsData=t}else this.itemsData=null;if(s&&(o.forEach(this.itemListeners,function(t,e){s.off(e,t)}),e=s.getIds(),this._onRemove(e)),this.itemsData){var n=this.id;o.forEach(this.itemListeners,function(t,e){i.itemsData.on(e,t,n)}),e=this.itemsData.getIds(),this._onAdd(e)}this._updateUngrouped(),this._updateGraph(),this.redraw()},s.prototype.setGroups=function(t){var e,i=this;if(this.groupsData&&(o.forEach(this.groupListeners,function(t,e){i.groupsData.unsubscribe(e,t)}),e=this.groupsData.getIds(),this.groupsData=null,this._onRemoveGroups(e)),t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.groupsData=t}else this.groupsData=null;if(this.groupsData){var s=this.id;o.forEach(this.groupListeners,function(t,e){i.groupsData.on(e,t,s)}),e=this.groupsData.getIds(),this._onAddGroups(e)}this._onUpdate()},s.prototype._onUpdate=function(){this._updateUngrouped(),this._updateAllGroupData(),this._updateGraph(),this.redraw()},s.prototype._onAdd=function(t){this._onUpdate(t)},s.prototype._onRemove=function(t){this._onUpdate(t)},s.prototype._onUpdateGroups=function(t){for(var e=0;e0){var d=this.body.util.toGlobalTime(-this.body.domProps.root.width),l=this.body.util.toGlobalTime(2*this.body.domProps.root.width),c={};for(this._getRelevantData(a,c,d,l),e=0;e0)for(r=0;rs){d.push(h);break}d.push(h)}}else for(a=0;ai&&h.x0)for(var s=0;s0){var n=1,r=o.length,a=this.body.util.toGlobalScreen(o[o.length-1].x)-this.body.util.toGlobalScreen(o[0].x),h=r/a;n=Math.min(Math.ceil(.2*r),Math.max(1,Math.round(h)));for(var d=[],l=0;r>l;l+=n)d.push(o[l]);e[t[s]]=d}}},s.prototype._getYRanges=function(t,e,i){var s,o,n,r,a,h=[],d=[];if(t.length>0){for(n=0;n0)if(o=this.groups[t[n]],"line"==o.options.style||"stack"!=o.options.barChart.handleOverlap){var l=s[0].y,c=s[0].y;for(r=0;rs[r].y?s[r].y:l,c=c0&&(h.sort(function(t,e){return t.x==e.x?t.groupId-e.groupId:t.x-e.x}),p={},this._getDataIntersections(p,h),i.__barchartLeft=this._getStackedBarYRange(p,h),i.__barchartLeft.yAxisOrientation="left",t.push("__barchartLeft")),d.length>0&&(d.sort(function(t,e){return t.x==e.x?t.groupId-e.groupId:t.x-e.x}),p={},this._getDataIntersections(p,d),i.__barchartRight=this._getStackedBarYRange(p,d),i.__barchartRight.yAxisOrientation="right",t.push("__barchartRight"))}},s.prototype._getStackedBarYRange=function(t,e){for(var i,s=e[0].y,o=e[0].y,n=0;ne[n].y?e[n].y:s,o=ot[r].accumulated?t[r].accumulated:s,o=o0){for(var c=0;ci?i:a,d=s>d?s:d):(r=!0,h=h>i?i:h,l=s>l?s:l));1==n&&this.yAxisLeft.setRange(a,d),1==r&&this.yAxisRight.setRange(h,l)}return o=this._toggleAxisVisiblity(n,this.yAxisLeft)||o,o=this._toggleAxisVisiblity(r,this.yAxisRight)||o,1==r&&1==n?(this.yAxisLeft.drawIcons=!0,this.yAxisRight.drawIcons=!0):(this.yAxisLeft.drawIcons=!1,this.yAxisRight.drawIcons=!1),this.yAxisRight.master=!n,0==this.yAxisRight.master?(this.yAxisLeft.lineOffset=1==r?this.yAxisRight.width:0,o=this.yAxisLeft.redraw()||o,this.yAxisRight.stepPixelsForced=this.yAxisLeft.stepPixels,o=this.yAxisRight.redraw()||o):o=this.yAxisRight.redraw()||o,-1!=t.indexOf("__barchartLeft")&&t.splice(t.indexOf("__barchartLeft"),1),-1!=t.indexOf("__barchartRight")&&t.splice(t.indexOf("__barchartRight"),1),o},s.prototype._toggleAxisVisiblity=function(t,e){var i=!1;return 0==t?e.dom.frame.parentNode&&(e.hide(),i=!0):e.dom.frame.parentNode||(e.show(),i=!0),i},s.prototype._drawBarGraphs=function(t,e){var i,s,o,r,a,h,d=[],l={},c=0;for(a=0;a0&&(i=Math.min(i,Math.abs(d[a-1].x-s))),o=this._getSafeDrawData(i,r,p);else{var f=a+(l[s].amount-l[s].resolved),m=a-(l[s].resolved+1);f0&&(i=Math.min(i,Math.abs(d[m].x-s))),o=this._getSafeDrawData(i,r,p),l[s].resolved+=1,"stack"==r.options.barChart.handleOverlap?(u=l[s].accumulated,l[s].accumulated+=r.zeroPosition-d[a].y):"sideBySide"==r.options.barChart.handleOverlap&&(o.width=o.width/l[s].amount,o.offset+=l[s].resolved*o.width-.5*o.width*(l[s].amount+1),"left"==r.options.barChart.align?o.offset-=.5*o.width:"right"==r.options.barChart.align&&(o.offset+=.5*o.width))}n.drawBar(d[a].x+o.offset,d[a].y-u,o.width,r.zeroPosition-d[a].y,r.className+" bar",this.svgElements,this.svg),1==r.options.drawPoints.enabled&&n.drawPoint(d[a].x+o.offset,d[a].y-u,r,this.svgElements,this.svg)}},s.prototype._getDataIntersections=function(t,e){for(var i,s=0;s0&&(i=Math.min(i,Math.abs(e[s-1].x-e[s].x))),0==i&&(void 0===t[e[s].x]&&(t[e[s].x]={amount:0,resolved:0,accumulated:0}),t[e[s].x].amount+=1)},s.prototype._getSafeDrawData=function(t,e,i){var s,o;return t0?(s=i>t?i:t,o=0,"left"==e.options.barChart.align?o-=.5*t:"right"==e.options.barChart.align&&(o+=.5*t)):(s=e.options.barChart.width,o=0,"left"==e.options.barChart.align?o-=.5*e.options.barChart.width:"right"==e.options.barChart.align&&(o+=.5*e.options.barChart.width)),{width:s,offset:o}},s.prototype._drawLineGraph=function(t,e){if(null!=t&&t.length>0){var i,s,o=Number(this.svg.style.height.replace("px",""));if(i=n.getSVGElement("path",this.svgElements,this.svg),i.setAttributeNS(null,"class",e.className),s=1==e.options.catmullRom.enabled?this._catmullRom(t,e):this._linear(t),1==e.options.shaded.enabled){var r,a=n.getSVGElement("path",this.svgElements,this.svg);r="top"==e.options.shaded.orientation?"M"+t[0].x+",0 "+s+"L"+t[t.length-1].x+",0":"M"+t[0].x+","+o+" "+s+"L"+t[t.length-1].x+","+o,a.setAttributeNS(null,"class",e.className+" fill"),a.setAttributeNS(null,"d",r)}i.setAttributeNS(null,"d","M"+s),1==e.options.drawPoints.enabled&&this._drawPoints(t,e,this.svgElements,this.svg) -}},s.prototype._drawPoints=function(t,e,i,s,o){void 0===o&&(o=0);for(var r=0;rl;l++)e=0==l?t[0]:t[l-1],i=t[l],s=t[l+1],o=d>l+2?t[l+2]:s,n={x:(-e.x+6*i.x+s.x)*h,y:(-e.y+6*i.y+s.y)*h},r={x:(i.x+6*s.x-o.x)*h,y:(i.y+6*s.y-o.y)*h},a+="C"+n.x+","+n.y+" "+r.x+","+r.y+" "+s.x+","+s.y+" ";return a},s.prototype._catmullRom=function(t,e){var i=e.options.catmullRom.alpha;if(0==i||void 0===i)return this._catmullRomUniform(t);for(var s,o,n,r,a,h,d,l,c,p,u,f,m,g,v,y,b,_,x,w=Math.round(t[0].x)+","+Math.round(t[0].y)+" ",S=t.length,D=0;S-1>D;D++)s=0==D?t[0]:t[D-1],o=t[D],n=t[D+1],r=S>D+2?t[D+2]:n,d=Math.sqrt(Math.pow(s.x-o.x,2)+Math.pow(s.y-o.y,2)),l=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),c=Math.sqrt(Math.pow(n.x-r.x,2)+Math.pow(n.y-r.y,2)),g=Math.pow(c,i),y=Math.pow(c,2*i),v=Math.pow(l,i),b=Math.pow(l,2*i),x=Math.pow(d,i),_=Math.pow(d,2*i),p=2*_+3*x*v+b,u=2*y+3*g*v+b,f=3*x*(x+v),f>0&&(f=1/f),m=3*g*(g+v),m>0&&(m=1/m),a={x:(-b*s.x+p*o.x+_*n.x)*f,y:(-b*s.y+p*o.y+_*n.y)*f},h={x:(y*o.x+u*n.x-b*r.x)*m,y:(y*o.y+u*n.y-b*r.y)*m},0==a.x&&0==a.y&&(a=o),0==h.x&&0==h.y&&(h=n),w+="C"+a.x+","+a.y+" "+h.x+","+h.y+" "+n.x+","+n.y+" ";return w},s.prototype._linear=function(t){for(var e="",i=0;ic;){c++;var p=h.getCurrent(),u=this.body.util.toScreen(p),f=h.isMajor();this.options.showMinorLabels&&this._repaintMinorText(u,h.getLabelMinor(),t),f&&this.options.showMajorLabels?(u>0&&(void 0==l&&(l=u),this._repaintMajorText(u,h.getLabelMajor(),t)),this._repaintMajorLine(u,t)):this._repaintMinorLine(u,t),h.next()}if(this.options.showMajorLabels){var m=this.body.util.toTime(0),g=h.getLabelMajor(m),v=g.length*(this.props.majorCharWidth||10)+10;(void 0==l||l>v)&&this._repaintMajorText(0,g,t)}o.forEach(this.dom.redundant,function(t){for(;t.length;){var e=t.pop();e&&e.parentNode&&e.parentNode.removeChild(e)}})},s.prototype._repaintMinorText=function(t,e,i){var s=this.dom.redundant.minorTexts.shift();if(!s){var o=document.createTextNode("");s=document.createElement("div"),s.appendChild(o),s.className="text minor",this.dom.foreground.appendChild(s)}this.dom.minorTexts.push(s),s.childNodes[0].nodeValue=e,s.style.top="top"==i?this.props.majorLabelHeight+"px":"0",s.style.left=t+"px"},s.prototype._repaintMajorText=function(t,e,i){var s=this.dom.redundant.majorTexts.shift();if(!s){var o=document.createTextNode(e);s=document.createElement("div"),s.className="text major",s.appendChild(o),this.dom.foreground.appendChild(s)}this.dom.majorTexts.push(s),s.childNodes[0].nodeValue=e,s.style.top="top"==i?"0":this.props.minorLabelHeight+"px",s.style.left=t+"px"},s.prototype._repaintMinorLine=function(t,e){var i=this.dom.redundant.minorLines.shift();i||(i=document.createElement("div"),i.className="grid vertical minor",this.dom.background.appendChild(i)),this.dom.minorLines.push(i);var s=this.props;i.style.top="top"==e?s.majorLabelHeight+"px":this.body.domProps.top.height+"px",i.style.height=s.minorLineHeight+"px",i.style.left=t-s.minorLineWidth/2+"px"},s.prototype._repaintMajorLine=function(t,e){var i=this.dom.redundant.majorLines.shift();i||(i=document.createElement("DIV"),i.className="grid vertical major",this.dom.background.appendChild(i)),this.dom.majorLines.push(i);var s=this.props;i.style.top="top"==e?"0":this.body.domProps.top.height+"px",i.style.left=t-s.majorLineWidth/2+"px",i.style.height=s.majorLineHeight+"px"},s.prototype._calculateCharSize=function(){this.dom.measureCharMinor||(this.dom.measureCharMinor=document.createElement("DIV"),this.dom.measureCharMinor.className="text minor measure",this.dom.measureCharMinor.style.position="absolute",this.dom.measureCharMinor.appendChild(document.createTextNode("0")),this.dom.foreground.appendChild(this.dom.measureCharMinor)),this.props.minorCharHeight=this.dom.measureCharMinor.clientHeight,this.props.minorCharWidth=this.dom.measureCharMinor.clientWidth,this.dom.measureCharMajor||(this.dom.measureCharMajor=document.createElement("DIV"),this.dom.measureCharMajor.className="text major measure",this.dom.measureCharMajor.style.position="absolute",this.dom.measureCharMajor.appendChild(document.createTextNode("0")),this.dom.foreground.appendChild(this.dom.measureCharMajor)),this.props.majorCharHeight=this.dom.measureCharMajor.clientHeight,this.props.majorCharWidth=this.dom.measureCharMajor.clientWidth},s.prototype.snap=function(t){return this.step.snap(t)},t.exports=s},function(t,e,i){function s(t,e,i){this.id=null,this.parent=null,this.data=t,this.dom=null,this.conversion=e||{},this.options=i||{},this.selected=!1,this.displayed=!1,this.dirty=!0,this.top=null,this.left=null,this.width=null,this.height=null}var o=i(44),n=i(1);s.prototype.stack=!0,s.prototype.select=function(){this.selected=!0,this.dirty=!0,this.displayed&&this.redraw()},s.prototype.unselect=function(){this.selected=!1,this.dirty=!0,this.displayed&&this.redraw()},s.prototype.setData=function(t){this.data=t,this.dirty=!0,this.displayed&&this.redraw()},s.prototype.setParent=function(t){this.displayed?(this.hide(),this.parent=t,this.parent&&this.show()):this.parent=t},s.prototype.isVisible=function(){return!1},s.prototype.show=function(){return!1},s.prototype.hide=function(){return!1},s.prototype.redraw=function(){},s.prototype.repositionX=function(){},s.prototype.repositionY=function(){},s.prototype._repaintDeleteButton=function(t){if(this.selected&&this.options.editable.remove&&!this.dom.deleteButton){var e=this,i=document.createElement("div");i.className="delete",i.title="Delete this item",o(i,{preventDefault:!0}).on("tap",function(t){e.parent.removeFromDataSet(e),t.stopPropagation()}),t.appendChild(i),this.dom.deleteButton=i}else!this.selected&&this.dom.deleteButton&&(this.dom.deleteButton.parentNode&&this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton),this.dom.deleteButton=null)},s.prototype._updateContents=function(t){var e;if(this.options.template){var i=this.parent.itemSet.itemsData.get(this.id);e=this.options.template(i)}else e=this.data.content;if(e!==this.content){if(e instanceof Element)t.innerHTML="",t.appendChild(e);else if(void 0!=e)t.innerHTML=e;else if("background"!=this.data.type||void 0!==this.data.content)throw new Error('Property "content" missing in item '+this.id);this.content=e}},s.prototype._updateTitle=function(t){null!=this.data.title?t.title=this.data.title||"":t.removeAttribute("title")},s.prototype._updateDataAttributes=function(t){if(this.options.dataAttributes&&this.options.dataAttributes.length>0){var e=[];if(Array.isArray(this.options.dataAttributes))e=this.options.dataAttributes;else{if("all"!=this.options.dataAttributes)return;e=Object.keys(this.data)}for(var i=0;it.start},s.prototype.redraw=function(){var t=this.dom;if(t||(this.dom={},t=this.dom,t.box=document.createElement("div"),t.content=document.createElement("div"),t.content.className="content",t.box.appendChild(t.content),t.box["timeline-item"]=this,this.dirty=!0),!this.parent)throw new Error("Cannot redraw item: no parent attached");if(!t.box.parentNode){var e=this.parent.dom.background;if(!e)throw new Error("Cannot redraw item: parent has no background container element");e.appendChild(t.box)}if(this.displayed=!0,this.dirty){this._updateContents(this.dom.content),this._updateTitle(this.dom.content),this._updateDataAttributes(this.dom.content),this._updateStyle(this.dom.box);var i=(this.data.className?" "+this.data.className:"")+(this.selected?" selected":"");t.box.className=this.baseClassName+i,this.overflow="hidden"!==window.getComputedStyle(t.content).overflow,this.props.content.width=this.dom.content.offsetWidth,this.height=0,this.dirty=!1}},s.prototype.show=r.prototype.show,s.prototype.hide=r.prototype.hide,s.prototype.repositionX=r.prototype.repositionX,s.prototype.repositionY=function(t){var e="top"===this.options.orientation;this.dom.content.style.top=e?"":"0",this.dom.content.style.bottom=e?"0":"";var i;if(void 0!==this.data.subgroup){var s=this.data.subgroup,o=this.parent.subgroups,r=o[s].index;if(1==e){i=this.parent.subgroups[s].height+t.item.vertical,i+=0==r?t.axis-.5*t.item.vertical:0;var a=this.parent.top;for(var h in o)o.hasOwnProperty(h)&&1==o[h].visible&&o[h].indexr&&(a+=o[h].height+t.item.vertical);i=this.parent.subgroups[s].height+t.item.vertical,this.dom.box.style.top=a+"px",this.dom.box.style.bottom=""}}else this.parent instanceof n?(i=Math.max(this.parent.height,this.parent.itemSet.body.domProps.centerContainer.height),this.dom.box.style.top=e?"0":"",this.dom.box.style.bottom=e?"":"0"):(i=this.parent.height,this.dom.box.style.top=this.parent.top+"px",this.dom.box.style.bottom="");this.dom.box.style.height=i+"px"},t.exports=s},function(t,e,i){function s(t,e,i){if(this.props={dot:{width:0,height:0},line:{width:0,height:0}},t&&void 0==t.start)throw new Error('Property "start" missing in item '+t);o.call(this,t,e,i)}{var o=i(30);i(1)}s.prototype=new o(null,null,null),s.prototype.isVisible=function(t){var e=(t.end-t.start)/4;return this.data.start>t.start-e&&this.data.startt.start-e&&this.data.startt.start},s.prototype.redraw=function(){var t=this.dom;if(t||(this.dom={},t=this.dom,t.box=document.createElement("div"),t.content=document.createElement("div"),t.content.className="content",t.box.appendChild(t.content),t.box["timeline-item"]=this,this.dirty=!0),!this.parent)throw new Error("Cannot redraw item: no parent attached");if(!t.box.parentNode){var e=this.parent.dom.foreground;if(!e)throw new Error("Cannot redraw item: parent has no foreground container element");e.appendChild(t.box)}if(this.displayed=!0,this.dirty){this._updateContents(this.dom.content),this._updateTitle(this.dom.box),this._updateDataAttributes(this.dom.box),this._updateStyle(this.dom.box);var i=(this.data.className?" "+this.data.className:"")+(this.selected?" selected":"");t.box.className=this.baseClassName+i,this.overflow="hidden"!==window.getComputedStyle(t.content).overflow,this.props.content.width=this.dom.content.offsetWidth,this.height=this.dom.box.offsetHeight,this.dirty=!1}this._repaintDeleteButton(t.box),this._repaintDragLeft(),this._repaintDragRight()},s.prototype.show=function(){this.displayed||this.redraw()},s.prototype.hide=function(){if(this.displayed){var t=this.dom.box;t.parentNode&&t.parentNode.removeChild(t),this.top=null,this.left=null,this.displayed=!1}},s.prototype.repositionX=function(){var t,e,i=this.parent.width,s=this.conversion.toScreen(this.data.start),o=this.conversion.toScreen(this.data.end);-i>s&&(s=-i),o>2*i&&(o=2*i);var n=Math.max(o-s,1);switch(this.overflow?(this.left=s,this.width=n+this.props.content.width,e=this.props.content.width):(this.left=s,this.width=n,e=Math.min(o-s,this.props.content.width)),this.dom.box.style.left=this.left+"px",this.dom.box.style.width=n+"px",this.options.align){case"left":this.dom.content.style.left="0";break;case"right":this.dom.content.style.left=Math.max(n-e-2*this.options.padding,0)+"px";break;case"center":this.dom.content.style.left=Math.max((n-e-2*this.options.padding)/2,0)+"px";break;default:t=this.overflow?Math.max(-s,0):0>s?Math.min(-s,o-s-this.props.content.width-2*this.options.padding):0,this.dom.content.style.left=t+"px"}},s.prototype.repositionY=function(){var t=this.options.orientation,e=this.dom.box;e.style.top="top"==t?this.top+"px":this.parent.height-this.top-this.height+"px"},s.prototype._repaintDragLeft=function(){if(this.selected&&this.options.editable.updateTime&&!this.dom.dragLeft){var t=document.createElement("div");t.className="drag-left",t.dragLeftItem=this,o(t,{preventDefault:!0}).on("drag",function(){}),this.dom.box.appendChild(t),this.dom.dragLeft=t}else!this.selected&&this.dom.dragLeft&&(this.dom.dragLeft.parentNode&&this.dom.dragLeft.parentNode.removeChild(this.dom.dragLeft),this.dom.dragLeft=null)},s.prototype._repaintDragRight=function(){if(this.selected&&this.options.editable.updateTime&&!this.dom.dragRight){var t=document.createElement("div");t.className="drag-right",t.dragRightItem=this,o(t,{preventDefault:!0}).on("drag",function(){}),this.dom.box.appendChild(t),this.dom.dragRight=t}else!this.selected&&this.dom.dragRight&&(this.dom.dragRight.parentNode&&this.dom.dragRight.parentNode.removeChild(this.dom.dragRight),this.dom.dragRight=null)},t.exports=s},function(t,e,i){function s(t,e,i){if(!(this instanceof s))throw new SyntaxError("Constructor must be called with the new operator");this._initializeMixinLoaders(),this.containerElement=t,this.renderRefreshRate=60,this.renderTimestep=1e3/this.renderRefreshRate,this.renderTime=.5*this.renderTimestep,this.maxPhysicsTicksPerRender=3,this.physicsDiscreteStepsize=.5,this.initializing=!0,this.triggerFunctions={add:null,edit:null,editEdge:null,connect:null,del:null},this.defaultOptions={nodes:{mass:1,radiusMin:10,radiusMax:30,radius:10,shape:"ellipse",image:void 0,widthMin:16,widthMax:64,fontColor:"black",fontSize:14,fontFace:"verdana",fontFill:void 0,level:-1,color:{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},borderColor:"#2B7CE9",backgroundColor:"#97C2FC",highlightColor:"#D2E5FF",group:void 0,borderWidth:1,borderWidthSelected:void 0},edges:{widthMin:1,widthMax:15,width:1,widthSelectionMultiplier:2,hoverWidth:1.5,style:"line",color:{color:"#848484",highlight:"#848484",hover:"#848484"},fontColor:"#343434",fontSize:14,fontFace:"arial",fontFill:"white",arrowScaleFactor:1,dash:{length:10,gap:5,altLength:void 0},inheritColor:"from"},configurePhysics:!1,physics:{barnesHut:{enabled:!0,theta:1/.6,gravitationalConstant:-2e3,centralGravity:.3,springLength:95,springConstant:.04,damping:.09},repulsion:{centralGravity:0,springLength:200,springConstant:.05,nodeDistance:100,damping:.09},hierarchicalRepulsion:{enabled:!1,centralGravity:0,springLength:100,springConstant:.01,nodeDistance:150,damping:.09},damping:null,centralGravity:null,springLength:null,springConstant:null},clustering:{enabled:!1,initialMaxNodes:100,clusterThreshold:500,reduceToNodes:300,chainThreshold:.4,clusterEdgeThreshold:20,sectorThreshold:100,screenSizeThreshold:.2,fontSizeMultiplier:4,maxFontSize:1e3,forceAmplification:.1,distanceAmplification:.1,edgeGrowth:20,nodeScaling:{width:1,height:1,radius:1},maxNodeSizeIncrements:600,activeAreaBoxSize:80,clusterLevelDifference:2},navigation:{enabled:!1},keyboard:{enabled:!1,speed:{x:10,y:10,zoom:.02}},dataManipulation:{enabled:!1,initiallyVisible:!1},hierarchicalLayout:{enabled:!1,levelSeparation:150,nodeSpacing:100,direction:"UD",layout:"hubsize"},freezeForStabilization:!1,smoothCurves:{enabled:!0,dynamic:!0,type:"continuous",roundness:.5},dynamicSmoothCurves:!0,maxVelocity:30,minVelocity:.1,stabilize:!0,stabilizationIterations:1e3,locale:"en",locales:_,tooltip:{delay:300,fontColor:"black",fontSize:14,fontFace:"verdana",color:{border:"#666",background:"#FFFFC6"}},dragNetwork:!0,dragNodes:!0,zoomable:!0,hover:!1,hideEdgesOnDrag:!1,hideNodesOnDrag:!1,width:"100%",height:"100%",selectable:!0},this.constants=a.extend({},this.defaultOptions),this.hoverObj={nodes:{},edges:{}},this.controlNodesActive=!1,this.navigationHammers={existing:[],"new":[]},this.animationSpeed=1/this.renderRefreshRate,this.animationEasingFunction="easeInOutQuint",this.easingTime=0,this.sourceScale=0,this.targetScale=0,this.sourceTranslation=0,this.targetTranslation=0,this.lockedOnNodeId=null,this.lockedOnNodeOffset=null;var o=this;this.groups=new u,this.images=new f,this.images.setOnloadCallback(function(){o._redraw()}),this.xIncrement=0,this.yIncrement=0,this.zoomIncrement=0,this._loadPhysicsSystem(),this._create(),this._loadSectorSystem(),this._loadClusterSystem(),this._loadSelectionSystem(),this._loadHierarchySystem(),this._setTranslation(this.frame.clientWidth/2,this.frame.clientHeight/2),this._setScale(1),this.setOptions(i),this.freezeSimulation=!1,this.cachedFunctions={},this.startedStabilization=!1,this.stabilized=!1,this.stabilizationIterations=null,this.calculationNodes={},this.calculationNodeIndices=[],this.nodeIndices=[],this.nodes={},this.edges={},this.canvasTopLeft={x:0,y:0},this.canvasBottomRight={x:0,y:0},this.pointerPosition={x:0,y:0},this.areaCenter={},this.scale=1,this.previousScale=this.scale,this.nodesData=null,this.edgesData=null,this.nodesListeners={add:function(t,e){o._addNodes(e.items),o.start()},update:function(t,e){o._updateNodes(e.items,e.data),o.start()},remove:function(t,e){o._removeNodes(e.items),o.start()}},this.edgesListeners={add:function(t,e){o._addEdges(e.items),o.start()},update:function(t,e){o._updateEdges(e.items),o.start()},remove:function(t,e){o._removeEdges(e.items),o.start()}},this.moving=!0,this.timer=void 0,this.setData(e,this.constants.clustering.enabled||this.constants.hierarchicalLayout.enabled),this.initializing=!1,1==this.constants.hierarchicalLayout.enabled?this._setupHierarchicalLayout():0==this.constants.stabilize&&this.zoomExtent(void 0,!0,this.constants.clustering.enabled),this.constants.clustering.enabled&&this.startWithClustering()}var o=i(52),n=i(44),r=i(54),a=i(1),h=i(46),d=i(3),l=i(4),c=i(41),p=i(42),u=i(37),f=i(38),m=i(39),g=i(36),v=i(40),y=i(50),b=i(51),_=i(48);i(49),o(s.prototype),s.prototype._getScriptPath=function(){for(var t=document.getElementsByTagName("script"),e=0;et.x&&(s=t.x),ot.y&&(e=t.y),i=this.constants.clustering.initialMaxNodes?49.07548/(n+142.05338)+91444e-8:12.662/(n+7.4147)+.0964822:1==this.constants.clustering.enabled&&n>=this.constants.clustering.initialMaxNodes?77.5271985/(n+187.266146)+476710517e-13:30.5062972/(n+19.93597763)+.08413486;var r=Math.min(this.frame.canvas.clientWidth/600,this.frame.canvas.clientHeight/600);s*=r}else{var a=1.1*Math.abs(o.maxX-o.minX),h=1.1*Math.abs(o.maxY-o.minY),d=this.frame.canvas.clientWidth/a,l=this.frame.canvas.clientHeight/h;s=l>=d?d:l}s>1&&(s=1);var c=this._findCenter(o);if(0==i){var p={position:c,scale:s,animation:t};this.moveTo(p),this.moving=!0,this.start()}else c.x*=s,c.y*=s,c.x-=.5*this.frame.canvas.clientWidth,c.y-=.5*this.frame.canvas.clientHeight,this._setScale(s),this._setTranslation(-c.x,-c.y)},s.prototype._updateNodeIndexList=function(){this._clearNodeIndexList();for(var t in this.nodes)this.nodes.hasOwnProperty(t)&&this.nodeIndices.push(t)},s.prototype.setData=function(t,e){if(void 0===e&&(e=!1),this.initializing=!0,t&&t.dot&&(t.nodes||t.edges))throw new SyntaxError('Data must contain either parameter "dot" or parameter pair "nodes" and "edges", but not both.');if(this.setOptions(t&&t.options),t&&t.dot){if(t&&t.dot){var i=c.DOTToGraph(t.dot);return void this.setData(i)}}else if(t&&t.gephi){if(t&&t.gephi){var s=p.parseGephi(t.gephi);return void this.setData(s)}}else this._setNodes(t&&t.nodes),this._setEdges(t&&t.edges);this._putDataInSector(),0==e&&(1==this.constants.hierarchicalLayout.enabled?(this._resetLevels(),this._setupHierarchicalLayout()):this.constants.stabilize&&this._stabilize(),this.start()),this.initializing=!1},s.prototype.setOptions=function(t){if(t){var e,i=["nodes","edges","smoothCurves","hierarchicalLayout","clustering","navigation","keyboard","dataManipulation","onAdd","onEdit","onEditEdge","onConnect","onDelete","clickToUse"];if(a.selectiveNotDeepExtend(i,this.constants,t),a.selectiveNotDeepExtend(["color"],this.constants.nodes,t.nodes),a.selectiveNotDeepExtend(["color","length"],this.constants.edges,t.edges),t.physics&&(a.mergeOptions(this.constants.physics,t.physics,"barnesHut"),a.mergeOptions(this.constants.physics,t.physics,"repulsion"),t.physics.hierarchicalRepulsion)){this.constants.hierarchicalLayout.enabled=!0,this.constants.physics.hierarchicalRepulsion.enabled=!0,this.constants.physics.barnesHut.enabled=!1;for(e in t.physics.hierarchicalRepulsion)t.physics.hierarchicalRepulsion.hasOwnProperty(e)&&(this.constants.physics.hierarchicalRepulsion[e]=t.physics.hierarchicalRepulsion[e])}if(t.onAdd&&(this.triggerFunctions.add=t.onAdd),t.onEdit&&(this.triggerFunctions.edit=t.onEdit),t.onEditEdge&&(this.triggerFunctions.editEdge=t.onEditEdge),t.onConnect&&(this.triggerFunctions.connect=t.onConnect),t.onDelete&&(this.triggerFunctions.del=t.onDelete),a.mergeOptions(this.constants,t,"smoothCurves"),a.mergeOptions(this.constants,t,"hierarchicalLayout"),a.mergeOptions(this.constants,t,"clustering"),a.mergeOptions(this.constants,t,"navigation"),a.mergeOptions(this.constants,t,"keyboard"),a.mergeOptions(this.constants,t,"dataManipulation"),t.dataManipulation&&(this.editMode=this.constants.dataManipulation.initiallyVisible),t.edges&&(void 0!==t.edges.color&&(a.isString(t.edges.color)?(this.constants.edges.color={},this.constants.edges.color.color=t.edges.color,this.constants.edges.color.highlight=t.edges.color,this.constants.edges.color.hover=t.edges.color):(void 0!==t.edges.color.color&&(this.constants.edges.color.color=t.edges.color.color),void 0!==t.edges.color.highlight&&(this.constants.edges.color.highlight=t.edges.color.highlight),void 0!==t.edges.color.hover&&(this.constants.edges.color.hover=t.edges.color.hover))),t.edges.fontColor||void 0!==t.edges.color&&(a.isString(t.edges.color)?this.constants.edges.fontColor=t.edges.color:void 0!==t.edges.color.color&&(this.constants.edges.fontColor=t.edges.color.color))),t.nodes&&t.nodes.color){var s=a.parseColor(t.nodes.color);this.constants.nodes.color.background=s.background,this.constants.nodes.color.border=s.border,this.constants.nodes.color.highlight.background=s.highlight.background,this.constants.nodes.color.highlight.border=s.highlight.border,this.constants.nodes.color.hover.background=s.hover.background,this.constants.nodes.color.hover.border=s.hover.border +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.vis=e():t.vis=e()}(this,function(){return function(t){function e(s){if(i[s])return i[s].exports;var o=i[s]={exports:{},id:s,loaded:!1};return t[s].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){e.util=i(1),e.DOMutil=i(2),e.DataSet=i(3),e.DataView=i(4),e.Graph3d=i(5),e.graph3d={Camera:i(6),Filter:i(7),Point2d:i(8),Point3d:i(9),Slider:i(10),StepNumber:i(11)},e.Timeline=i(12),e.Graph2d=i(13),e.timeline={DateUtil:i(14),DataStep:i(15),Range:i(16),stack:i(17),TimeStep:i(18),components:{items:{Item:i(30),BackgroundItem:i(31),BoxItem:i(32),PointItem:i(33),RangeItem:i(34)},Component:i(19),CurrentTime:i(20),CustomTime:i(21),DataAxis:i(22),GraphGroup:i(23),Group:i(24),BackgroundGroup:i(25),ItemSet:i(26),Legend:i(27),LineGraph:i(28),TimeAxis:i(29)}},e.Network=i(35),e.network={Edge:i(36),Groups:i(37),Images:i(38),Node:i(39),Popup:i(40),dotparser:i(41),gephiParser:i(42)},e.Graph=function(){throw new Error("Graph is renamed to Network. Please create a graph as new vis.Network(...)")},e.moment=i(43),e.hammer=i(44)},function(module,exports,__webpack_require__){var moment=__webpack_require__(43);exports.isNumber=function(t){return t instanceof Number||"number"==typeof t},exports.isString=function(t){return t instanceof String||"string"==typeof t},exports.isDate=function(t){if(t instanceof Date)return!0;if(exports.isString(t)){var e=ASPDateRegex.exec(t);if(e)return!0;if(!isNaN(Date.parse(t)))return!0}return!1},exports.isDataTable=function(t){return"undefined"!=typeof google&&google.visualization&&google.visualization.DataTable&&t instanceof google.visualization.DataTable},exports.randomUUID=function(){var t=function(){return Math.floor(65536*Math.random()).toString(16)};return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()},exports.extend=function(t){for(var e=1,i=arguments.length;i>e;e++){var s=arguments[e];for(var o in s)s.hasOwnProperty(o)&&(t[o]=s[o])}return t},exports.selectiveExtend=function(t,e){if(!Array.isArray(t))throw new Error("Array with property names expected as first argument");for(var i=2;ii;i++)if(t[i]!=e[i])return!1;return!0},exports.convert=function(t,e){var i;if(void 0===t)return void 0;if(null===t)return null;if(!e)return t;if("string"!=typeof e&&!(e instanceof String))throw new Error("Type must be a string");switch(e){case"boolean":case"Boolean":return Boolean(t);case"number":case"Number":return Number(t.valueOf());case"string":case"String":return String(t);case"Date":if(exports.isNumber(t))return new Date(t);if(t instanceof Date)return new Date(t.valueOf());if(moment.isMoment(t))return new Date(t.valueOf());if(exports.isString(t))return i=ASPDateRegex.exec(t),i?new Date(Number(i[1])):moment(t).toDate();throw new Error("Cannot convert object of type "+exports.getType(t)+" to type Date");case"Moment":if(exports.isNumber(t))return moment(t);if(t instanceof Date)return moment(t.valueOf());if(moment.isMoment(t))return moment(t);if(exports.isString(t))return i=ASPDateRegex.exec(t),moment(i?Number(i[1]):t);throw new Error("Cannot convert object of type "+exports.getType(t)+" to type Date");case"ISODate":if(exports.isNumber(t))return new Date(t);if(t instanceof Date)return t.toISOString();if(moment.isMoment(t))return t.toDate().toISOString();if(exports.isString(t))return i=ASPDateRegex.exec(t),i?new Date(Number(i[1])).toISOString():new Date(t).toISOString();throw new Error("Cannot convert object of type "+exports.getType(t)+" to type ISODate");case"ASPDate":if(exports.isNumber(t))return"/Date("+t+")/";if(t instanceof Date)return"/Date("+t.valueOf()+")/";if(exports.isString(t)){i=ASPDateRegex.exec(t);var s;return s=i?new Date(Number(i[1])).valueOf():new Date(t).valueOf(),"/Date("+s+")/"}throw new Error("Cannot convert object of type "+exports.getType(t)+" to type ASPDate");default:throw new Error('Unknown type "'+e+'"')}};var ASPDateRegex=/^\/?Date\((\-?\d+)/i;exports.getType=function(t){var e=typeof t;return"object"==e?null==t?"null":t instanceof Boolean?"Boolean":t instanceof Number?"Number":t instanceof String?"String":Array.isArray(t)?"Array":t instanceof Date?"Date":"Object":"number"==e?"Number":"boolean"==e?"Boolean":"string"==e?"String":e},exports.getAbsoluteLeft=function(t){return t.getBoundingClientRect().left+window.pageXOffset},exports.getAbsoluteTop=function(t){return t.getBoundingClientRect().top+window.pageYOffset},exports.addClassName=function(t,e){var i=t.className.split(" ");-1==i.indexOf(e)&&(i.push(e),t.className=i.join(" "))},exports.removeClassName=function(t,e){var i=t.className.split(" "),s=i.indexOf(e);-1!=s&&(i.splice(s,1),t.className=i.join(" "))},exports.forEach=function(t,e){var i,s;if(Array.isArray(t))for(i=0,s=t.length;s>i;i++)e(t[i],i,t);else for(i in t)t.hasOwnProperty(i)&&e(t[i],i,t)},exports.toArray=function(t){var e=[];for(var i in t)t.hasOwnProperty(i)&&e.push(t[i]);return e},exports.updateProperty=function(t,e,i){return t[e]!==i?(t[e]=i,!0):!1},exports.addEventListener=function(t,e,i,s){t.addEventListener?(void 0===s&&(s=!1),"mousewheel"===e&&navigator.userAgent.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.addEventListener(e,i,s)):t.attachEvent("on"+e,i)},exports.removeEventListener=function(t,e,i,s){t.removeEventListener?(void 0===s&&(s=!1),"mousewheel"===e&&navigator.userAgent.indexOf("Firefox")>=0&&(e="DOMMouseScroll"),t.removeEventListener(e,i,s)):t.detachEvent("on"+e,i)},exports.preventDefault=function(t){t||(t=window.event),t.preventDefault?t.preventDefault():t.returnValue=!1},exports.getTarget=function(t){t||(t=window.event);var e;return t.target?e=t.target:t.srcElement&&(e=t.srcElement),void 0!=e.nodeType&&3==e.nodeType&&(e=e.parentNode),e},exports.option={},exports.option.asBoolean=function(t,e){return"function"==typeof t&&(t=t()),null!=t?0!=t:e||null},exports.option.asNumber=function(t,e){return"function"==typeof t&&(t=t()),null!=t?Number(t)||e||null:e||null},exports.option.asString=function(t,e){return"function"==typeof t&&(t=t()),null!=t?String(t):e||null},exports.option.asSize=function(t,e){return"function"==typeof t&&(t=t()),exports.isString(t)?t:exports.isNumber(t)?t+"px":e||null},exports.option.asElement=function(t,e){return"function"==typeof t&&(t=t()),t||e||null},exports.GiveDec=function(Hex){var Value;return Value="A"==Hex?10:"B"==Hex?11:"C"==Hex?12:"D"==Hex?13:"E"==Hex?14:"F"==Hex?15:eval(Hex)},exports.GiveHex=function(t){var e;return e=10==t?"A":11==t?"B":12==t?"C":13==t?"D":14==t?"E":15==t?"F":""+t},exports.parseColor=function(t){var e;if(exports.isString(t)){if(exports.isValidRGB(t)){var i=t.substr(4).substr(0,t.length-5).split(",");t=exports.RGBToHex(i[0],i[1],i[2])}if(exports.isValidHex(t)){var s=exports.hexToHSV(t),o={h:s.h,s:.45*s.s,v:Math.min(1,1.05*s.v)},n={h:s.h,s:Math.min(1,1.25*s.v),v:.6*s.v},r=exports.HSVToHex(n.h,n.h,n.v),a=exports.HSVToHex(o.h,o.s,o.v);e={background:t,border:r,highlight:{background:a,border:r},hover:{background:a,border:r}}}else e={background:t,border:t,highlight:{background:t,border:t},hover:{background:t,border:t}}}else e={},e.background=t.background||"white",e.border=t.border||e.background,exports.isString(t.highlight)?e.highlight={border:t.highlight,background:t.highlight}:(e.highlight={},e.highlight.background=t.highlight&&t.highlight.background||e.background,e.highlight.border=t.highlight&&t.highlight.border||e.border),exports.isString(t.hover)?e.hover={border:t.hover,background:t.hover}:(e.hover={},e.hover.background=t.hover&&t.hover.background||e.background,e.hover.border=t.hover&&t.hover.border||e.border);return e},exports.hexToRGB=function(t){t=t.replace("#","").toUpperCase();var e=exports.GiveDec(t.substring(0,1)),i=exports.GiveDec(t.substring(1,2)),s=exports.GiveDec(t.substring(2,3)),o=exports.GiveDec(t.substring(3,4)),n=exports.GiveDec(t.substring(4,5)),r=exports.GiveDec(t.substring(5,6)),a=16*e+i,h=16*s+o,i=16*n+r;return{r:a,g:h,b:i}},exports.RGBToHex=function(t,e,i){var s=exports.GiveHex(Math.floor(t/16)),o=exports.GiveHex(t%16),n=exports.GiveHex(Math.floor(e/16)),r=exports.GiveHex(e%16),a=exports.GiveHex(Math.floor(i/16)),h=exports.GiveHex(i%16),d=s+o+n+r+a+h;return"#"+d},exports.RGBToHSV=function(t,e,i){t/=255,e/=255,i/=255;var s=Math.min(t,Math.min(e,i)),o=Math.max(t,Math.max(e,i));if(s==o)return{h:0,s:0,v:s};var n=t==s?e-i:i==s?t-e:i-t,r=t==s?3:i==s?1:5,a=60*(r-n/(o-s))/360,h=(o-s)/o,d=o;return{h:a,s:h,v:d}};var cssUtil={split:function(t){var e={};return t.split(";").forEach(function(t){if(""!=t.trim()){var i=t.split(":"),s=i[0].trim(),o=i[1].trim();e[s]=o}}),e},join:function(t){return Object.keys(t).map(function(e){return e+": "+t[e]}).join("; ")}};exports.addCssText=function(t,e){var i=cssUtil.split(t.style.cssText),s=cssUtil.split(e),o=exports.extend(i,s);t.style.cssText=cssUtil.join(o)},exports.removeCssText=function(t,e){var i=cssUtil.split(t.style.cssText),s=cssUtil.split(e);for(var o in s)s.hasOwnProperty(o)&&delete i[o];t.style.cssText=cssUtil.join(i)},exports.HSVToRGB=function(t,e,i){var s,o,n,r=Math.floor(6*t),a=6*t-r,h=i*(1-e),d=i*(1-a*e),l=i*(1-(1-a)*e);switch(r%6){case 0:s=i,o=l,n=h;break;case 1:s=d,o=i,n=h;break;case 2:s=h,o=i,n=l;break;case 3:s=h,o=d,n=i;break;case 4:s=l,o=h,n=i;break;case 5:s=i,o=h,n=d}return{r:Math.floor(255*s),g:Math.floor(255*o),b:Math.floor(255*n)}},exports.HSVToHex=function(t,e,i){var s=exports.HSVToRGB(t,e,i);return exports.RGBToHex(s.r,s.g,s.b)},exports.hexToHSV=function(t){var e=exports.hexToRGB(t);return exports.RGBToHSV(e.r,e.g,e.b)},exports.isValidHex=function(t){var e=/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(t);return e},exports.isValidRGB=function(t){t=t.replace(" ","");var e=/rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/i.test(t);return e},exports.selectiveBridgeObject=function(t,e){if("object"==typeof e){for(var i=Object.create(e),s=0;s=r&&o>n;){var h=Math.floor((r+a)/2),d=t[h];if(d.isVisible(e))return h;var l=void 0===s?d[i]:d[i][s];ld;)n=l[Math.max(0,g-1)][i],r=l[g][i],a=l[Math.min(l.length-1,g+1)][i],r==e||e>n&&r>e||e>r&&a>e?(c=!0,r!=e&&("before"==s?e>n&&r>e&&(g=Math.max(0,g-1)):e>r&&a>e&&(g=Math.min(l.length-1,g+1)))):(e>r?f=Math.floor(.5*(u+p)):m=Math.floor(.5*(u+p)),o=Math.floor(.5*(u+p)),p==f&&u==m?(g=-1,c=!0):(u=m,p=f,g=Math.floor(.5*(u+p)))),d++;d>=h&&console.log("BinarySearch too many iterations. Aborting.")}return g},exports.easeInOutQuad=function(t,e,i,s){var o=i-e;return t/=s/2,1>t?o/2*t*t+e:(t--,-o/2*(t*(t-2)-1)+e)},exports.easingFunctions={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return t*(2-t)},easeInOutQuad:function(t){return.5>t?2*t*t:-1+(4-2*t)*t},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return--t*t*t+1},easeInOutCubic:function(t){return.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return 1- --t*t*t*t},easeInOutQuart:function(t){return.5>t?8*t*t*t*t:1-8*--t*t*t*t},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return 1+--t*t*t*t*t},easeInOutQuint:function(t){return.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t}}},function(t,e){e.prepareElements=function(t){for(var e in t)t.hasOwnProperty(e)&&(t[e].redundant=t[e].used,t[e].used=[])},e.cleanupElements=function(t){for(var e in t)if(t.hasOwnProperty(e)&&t[e].redundant){for(var i=0;i0?(s=e[t].redundant[0],e[t].redundant.shift()):(s=document.createElementNS("http://www.w3.org/2000/svg",t),i.appendChild(s)):(s=document.createElementNS("http://www.w3.org/2000/svg",t),e[t]={used:[],redundant:[]},i.appendChild(s)),e[t].used.push(s),s},e.getDOMElement=function(t,e,i,s){var o;return e.hasOwnProperty(t)?e[t].redundant.length>0?(o=e[t].redundant[0],e[t].redundant.shift()):(o=document.createElement(t),void 0!==s?i.insertBefore(o,s):i.appendChild(o)):(o=document.createElement(t),e[t]={used:[],redundant:[]},void 0!==s?i.insertBefore(o,s):i.appendChild(o)),e[t].used.push(o),o},e.drawPoint=function(t,i,s,o,n){var r;return"circle"==s.options.drawPoints.style?(r=e.getSVGElement("circle",o,n),r.setAttributeNS(null,"cx",t),r.setAttributeNS(null,"cy",i),r.setAttributeNS(null,"r",.5*s.options.drawPoints.size),r.setAttributeNS(null,"class",s.className+" point")):(r=e.getSVGElement("rect",o,n),r.setAttributeNS(null,"x",t-.5*s.options.drawPoints.size),r.setAttributeNS(null,"y",i-.5*s.options.drawPoints.size),r.setAttributeNS(null,"width",s.options.drawPoints.size),r.setAttributeNS(null,"height",s.options.drawPoints.size),r.setAttributeNS(null,"class",s.className+" point")),r},e.drawBar=function(t,i,s,o,n,r,a){if(0!=o){0>o&&(o*=-1,i-=o);var h=e.getSVGElement("rect",r,a);h.setAttributeNS(null,"x",t-.5*s),h.setAttributeNS(null,"y",i),h.setAttributeNS(null,"width",s),h.setAttributeNS(null,"height",o),h.setAttributeNS(null,"class",n)}}},function(t,e,i){function s(t,e){if(!t||Array.isArray(t)||o.isDataTable(t)||(e=t,t=null),this._options=e||{},this._data={},this._fieldId=this._options.fieldId||"id",this._type={},this._options.type)for(var i in this._options.type)if(this._options.type.hasOwnProperty(i)){var s=this._options.type[i];this._type[i]="Date"==s||"ISODate"==s||"ASPDate"==s?"Date":s}if(this._options.convert)throw new Error('Option "convert" is deprecated. Use "type" instead.');this._subscribers={},t&&this.add(t)}var o=i(1);s.prototype.on=function(t,e){var i=this._subscribers[t];i||(i=[],this._subscribers[t]=i),i.push({callback:e})},s.prototype.subscribe=s.prototype.on,s.prototype.off=function(t,e){var i=this._subscribers[t];i&&(this._subscribers[t]=i.filter(function(t){return t.callback!=e}))},s.prototype.unsubscribe=s.prototype.off,s.prototype._trigger=function(t,e,i){if("*"==t)throw new Error("Cannot trigger event *");var s=[];t in this._subscribers&&(s=s.concat(this._subscribers[t])),"*"in this._subscribers&&(s=s.concat(this._subscribers["*"]));for(var o=0;or;r++)i=n._addItem(t[r]),s.push(i);else if(o.isDataTable(t))for(var h=this._getColumnNames(t),d=0,l=t.getNumberOfRows();l>d;d++){for(var c={},p=0,u=h.length;u>p;p++){var f=h[p];c[f]=t.getValue(d,p)}i=n._addItem(c),s.push(i)}else{if(!(t instanceof Object))throw new Error("Unknown dataType");i=n._addItem(t),s.push(i)}return s.length&&this._trigger("add",{items:s},e),s},s.prototype.update=function(t,e){var i=[],s=[],n=[],r=this,a=r._fieldId,h=function(t){var e=t[a];r._data[e]?(e=r._updateItem(t),s.push(e),n.push(t)):(e=r._addItem(t),i.push(e))};if(Array.isArray(t))for(var d=0,l=t.length;l>d;d++)h(t[d]);else if(o.isDataTable(t))for(var c=this._getColumnNames(t),p=0,u=t.getNumberOfRows();u>p;p++){for(var f={},m=0,g=c.length;g>m;m++){var v=c[m];f[v]=t.getValue(p,m)}h(f)}else{if(!(t instanceof Object))throw new Error("Unknown dataType");h(t)}return i.length&&this._trigger("add",{items:i},e),s.length&&this._trigger("update",{items:s,data:n},e),i.concat(s)},s.prototype.get=function(){var t,e,i,s,n=this,r=o.getType(arguments[0]);"String"==r||"Number"==r?(t=arguments[0],i=arguments[1],s=arguments[2]):"Array"==r?(e=arguments[0],i=arguments[1],s=arguments[2]):(i=arguments[0],s=arguments[1]);var a;if(i&&i.returnType){var h=["DataTable","Array","Object"];if(a=-1==h.indexOf(i.returnType)?"Array":i.returnType,s&&a!=o.getType(s))throw new Error('Type of parameter "data" ('+o.getType(s)+") does not correspond with specified options.type ("+i.type+")");if("DataTable"==a&&!o.isDataTable(s))throw new Error('Parameter "data" must be a DataTable when options.type is "DataTable"')}else a=s&&"DataTable"==o.getType(s)?"DataTable":"Array";var d,l,c,p,u=i&&i.type||this._options.type,f=i&&i.filter,m=[];if(void 0!=t)d=n._getItem(t,u),f&&!f(d)&&(d=null);else if(void 0!=e)for(c=0,p=e.length;p>c;c++)d=n._getItem(e[c],u),(!f||f(d))&&m.push(d);else for(l in this._data)this._data.hasOwnProperty(l)&&(d=n._getItem(l,u),(!f||f(d))&&m.push(d));if(i&&i.order&&void 0==t&&this._sort(m,i.order),i&&i.fields){var g=i.fields;if(void 0!=t)d=this._filterFields(d,g);else for(c=0,p=m.length;p>c;c++)m[c]=this._filterFields(m[c],g)}if("DataTable"==a){var v=this._getColumnNames(s);if(void 0!=t)n._appendRow(s,v,d);else for(c=0;cc;c++)s.push(m[c]);return s}return m},s.prototype.getIds=function(t){var e,i,s,o,n,r=this._data,a=t&&t.filter,h=t&&t.order,d=t&&t.type||this._options.type,l=[];if(a)if(h){n=[];for(s in r)r.hasOwnProperty(s)&&(o=this._getItem(s,d),a(o)&&n.push(o));for(this._sort(n,h),e=0,i=n.length;i>e;e++)l[e]=n[e][this._fieldId]}else for(s in r)r.hasOwnProperty(s)&&(o=this._getItem(s,d),a(o)&&l.push(o[this._fieldId]));else if(h){n=[];for(s in r)r.hasOwnProperty(s)&&n.push(r[s]);for(this._sort(n,h),e=0,i=n.length;i>e;e++)l[e]=n[e][this._fieldId]}else for(s in r)r.hasOwnProperty(s)&&(o=r[s],l.push(o[this._fieldId]));return l},s.prototype.getDataSet=function(){return this},s.prototype.forEach=function(t,e){var i,s,o=e&&e.filter,n=e&&e.type||this._options.type,r=this._data;if(e&&e.order)for(var a=this.get(e),h=0,d=a.length;d>h;h++)i=a[h],s=i[this._fieldId],t(i,s);else for(s in r)r.hasOwnProperty(s)&&(i=this._getItem(s,n),(!o||o(i))&&t(i,s))},s.prototype.map=function(t,e){var i,s=e&&e.filter,o=e&&e.type||this._options.type,n=[],r=this._data;for(var a in r)r.hasOwnProperty(a)&&(i=this._getItem(a,o),(!s||s(i))&&n.push(t(i,a)));return e&&e.order&&this._sort(n,e.order),n},s.prototype._filterFields=function(t,e){var i={};for(var s in t)t.hasOwnProperty(s)&&-1!=e.indexOf(s)&&(i[s]=t[s]);return i},s.prototype._sort=function(t,e){if(o.isString(e)){var i=e;t.sort(function(t,e){var s=t[i],o=e[i];return s>o?1:o>s?-1:0})}else{if("function"!=typeof e)throw new TypeError("Order must be a function or a string");t.sort(e)}},s.prototype.remove=function(t,e){var i,s,o,n=[];if(Array.isArray(t))for(i=0,s=t.length;s>i;i++)o=this._remove(t[i]),null!=o&&n.push(o);else o=this._remove(t),null!=o&&n.push(o);return n.length&&this._trigger("remove",{items:n},e),n},s.prototype._remove=function(t){if(o.isNumber(t)||o.isString(t)){if(this._data[t])return delete this._data[t],t}else if(t instanceof Object){var e=t[this._fieldId];if(e&&this._data[e])return delete this._data[e],e}return null},s.prototype.clear=function(t){var e=Object.keys(this._data);return this._data={},this._trigger("remove",{items:e},t),e},s.prototype.max=function(t){var e=this._data,i=null,s=null;for(var o in e)if(e.hasOwnProperty(o)){var n=e[o],r=n[t];null!=r&&(!i||r>s)&&(i=n,s=r)}return i},s.prototype.min=function(t){var e=this._data,i=null,s=null;for(var o in e)if(e.hasOwnProperty(o)){var n=e[o],r=n[t];null!=r&&(!i||s>r)&&(i=n,s=r)}return i},s.prototype.distinct=function(t){var e,i=this._data,s=[],n=this._options.type&&this._options.type[t]||null,r=0;for(var a in i)if(i.hasOwnProperty(a)){var h=i[a],d=h[t],l=!1;for(e=0;r>e;e++)if(s[e]==d){l=!0;break}l||void 0===d||(s[r]=d,r++)}if(n)for(e=0;ei;i++)e[i]=t.getColumnId(i)||t.getColumnLabel(i);return e},s.prototype._appendRow=function(t,e,i){for(var s=t.addRow(),o=0,n=e.length;n>o;o++){var r=e[o];t.setValue(s,o,i[r])}},t.exports=s},function(t,e,i){function s(t,e){this._data=null,this._ids={},this._options=e||{},this._fieldId="id",this._subscribers={};var i=this;this.listener=function(){i._onEvent.apply(i,arguments)},this.setData(t)}var o=i(1),n=i(3);s.prototype.setData=function(t){var e,i,s;if(this._data){this._data.unsubscribe&&this._data.unsubscribe("*",this.listener),e=[];for(var o in this._ids)this._ids.hasOwnProperty(o)&&e.push(o);this._ids={},this._trigger("remove",{items:e})}if(this._data=t,this._data){for(this._fieldId=this._options.fieldId||this._data&&this._data.options&&this._data.options.fieldId||"id",e=this._data.getIds({filter:this._options&&this._options.filter}),i=0,s=e.length;s>i;i++)o=e[i],this._ids[o]=!0;this._trigger("add",{items:e}),this._data.on&&this._data.on("*",this.listener)}},s.prototype.get=function(){var t,e,i,s=this,n=o.getType(arguments[0]);"String"==n||"Number"==n||"Array"==n?(t=arguments[0],e=arguments[1],i=arguments[2]):(e=arguments[0],i=arguments[1]);var r=o.extend({},this._options,e);this._options.filter&&e&&e.filter&&(r.filter=function(t){return s._options.filter(t)&&e.filter(t)});var a=[];return void 0!=t&&a.push(t),a.push(r),a.push(i),this._data&&this._data.get.apply(this._data,a)},s.prototype.getIds=function(t){var e;if(this._data){var i,s=this._options.filter;i=t&&t.filter?s?function(e){return s(e)&&t.filter(e)}:t.filter:s,e=this._data.getIds({filter:i,order:t&&t.order})}else e=[];return e},s.prototype.getDataSet=function(){for(var t=this;t instanceof s;)t=t._data;return t||null},s.prototype._onEvent=function(t,e,i){var s,o,n,r,a=e&&e.items,h=this._data,d=[],l=[],c=[];if(a&&h){switch(t){case"add":for(s=0,o=a.length;o>s;s++)n=a[s],r=this.get(n),r&&(this._ids[n]=!0,d.push(n));break;case"update":for(s=0,o=a.length;o>s;s++)n=a[s],r=this.get(n),r?this._ids[n]?l.push(n):(this._ids[n]=!0,d.push(n)):this._ids[n]&&(delete this._ids[n],c.push(n));break;case"remove":for(s=0,o=a.length;o>s;s++)n=a[s],this._ids[n]&&(delete this._ids[n],c.push(n))}d.length&&this._trigger("add",{items:d},i),l.length&&this._trigger("update",{items:l},i),c.length&&this._trigger("remove",{items:c},i)}},s.prototype.on=n.prototype.on,s.prototype.off=n.prototype.off,s.prototype._trigger=n.prototype._trigger,s.prototype.subscribe=s.prototype.on,s.prototype.unsubscribe=s.prototype.off,t.exports=s},function(t,e,i){function s(t,e,i){if(!(this instanceof s))throw new SyntaxError("Constructor must be called with the new operator");this.containerElement=t,this.width="400px",this.height="400px",this.margin=10,this.defaultXCenter="55%",this.defaultYCenter="50%",this.xLabel="x",this.yLabel="y",this.zLabel="z";var o=function(t){return t};this.xValueLabel=o,this.yValueLabel=o,this.zValueLabel=o,this.filterLabel="time",this.legendLabel="value",this.style=s.STYLE.DOT,this.showPerspective=!0,this.showGrid=!0,this.keepAspectRatio=!0,this.showShadow=!1,this.showGrayBottom=!1,this.showTooltip=!1,this.verticalRatio=.5,this.animationInterval=1e3,this.animationPreload=!1,this.camera=new l,this.eye=new h(0,0,-1),this.dataTable=null,this.dataPoints=null,this.colX=void 0,this.colY=void 0,this.colZ=void 0,this.colValue=void 0,this.colFilter=void 0,this.xMin=0,this.xStep=void 0,this.xMax=1,this.yMin=0,this.yStep=void 0,this.yMax=1,this.zMin=0,this.zStep=void 0,this.zMax=1,this.valueMin=0,this.valueMax=1,this.xBarWidth=1,this.yBarWidth=1,this.colorAxis="#4D4D4D",this.colorGrid="#D3D3D3",this.colorDot="#7DC1FF",this.colorDotBorder="#3267D2",this.create(),this.setOptions(i),e&&this.setData(e)}var o=i(52),n=i(3),r=i(4),a=i(1),h=i(9),d=i(8),l=i(6),c=i(7),p=i(10),u=i(11);o(s.prototype),s.prototype._setScale=function(){this.scale=new h(1/(this.xMax-this.xMin),1/(this.yMax-this.yMin),1/(this.zMax-this.zMin)),this.keepAspectRatio&&(this.scale.x3&&(this.colFilter=3);else{if(this.style!==s.STYLE.DOTCOLOR&&this.style!==s.STYLE.DOTSIZE&&this.style!==s.STYLE.BARCOLOR&&this.style!==s.STYLE.BARSIZE)throw'Unknown style "'+this.style+'"';this.colX=0,this.colY=1,this.colZ=2,this.colValue=3,t.getNumberOfColumns()>4&&(this.colFilter=4)}},s.prototype.getNumberOfRows=function(t){return t.length},s.prototype.getNumberOfColumns=function(t){var e=0;for(var i in t[0])t[0].hasOwnProperty(i)&&e++;return e},s.prototype.getDistinctValues=function(t,e){for(var i=[],s=0;st[s][e]&&(i.min=t[s][e]),i.maxt;t++){var m=(t-p)/(f-p),g=240*m,v=this._hsv2rgb(g,1,1);c.strokeStyle=v,c.beginPath(),c.moveTo(h,r+t),c.lineTo(a,r+t),c.stroke()}c.strokeStyle=this.colorAxis,c.strokeRect(h,r,i,n)}if(this.style===s.STYLE.DOTSIZE&&(c.strokeStyle=this.colorAxis,c.fillStyle=this.colorDot,c.beginPath(),c.moveTo(h,r),c.lineTo(a,r),c.lineTo(a-i+e,d),c.lineTo(h,d),c.closePath(),c.fill(),c.stroke()),this.style===s.STYLE.DOTCOLOR||this.style===s.STYLE.DOTSIZE){var y=5,b=new u(this.valueMin,this.valueMax,(this.valueMax-this.valueMin)/5,!0);for(b.start(),b.getCurrent()0?this.yMin:this.yMax,o=this._convert3Dto2D(new h(x,r,this.zMin)),Math.cos(2*_)>0?(g.textAlign="center",g.textBaseline="top",o.y+=b):Math.sin(2*_)<0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(" "+this.xValueLabel(i.getCurrent())+" ",o.x,o.y),i.next()}for(g.lineWidth=1,s=void 0===this.defaultYStep,i=new u(this.yMin,this.yMax,this.yStep,s),i.start(),i.getCurrent()0?this.xMin:this.xMax,o=this._convert3Dto2D(new h(n,i.getCurrent(),this.zMin)),Math.cos(2*_)<0?(g.textAlign="center",g.textBaseline="top",o.y+=b):Math.sin(2*_)>0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(" "+this.yValueLabel(i.getCurrent())+" ",o.x,o.y),i.next();for(g.lineWidth=1,s=void 0===this.defaultZStep,i=new u(this.zMin,this.zMax,this.zStep,s),i.start(),i.getCurrent()0?this.xMin:this.xMax,r=Math.sin(_)<0?this.yMin:this.yMax;!i.end();)t=this._convert3Dto2D(new h(n,r,i.getCurrent())),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(t.x-b,t.y),g.stroke(),g.textAlign="right",g.textBaseline="middle",g.fillStyle=this.colorAxis,g.fillText(this.zValueLabel(i.getCurrent())+" ",t.x-5,t.y),i.next();g.lineWidth=1,t=this._convert3Dto2D(new h(n,r,this.zMin)),e=this._convert3Dto2D(new h(n,r,this.zMax)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(e.x,e.y),g.stroke(),g.lineWidth=1,p=this._convert3Dto2D(new h(this.xMin,this.yMin,this.zMin)),f=this._convert3Dto2D(new h(this.xMax,this.yMin,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(p.x,p.y),g.lineTo(f.x,f.y),g.stroke(),p=this._convert3Dto2D(new h(this.xMin,this.yMax,this.zMin)),f=this._convert3Dto2D(new h(this.xMax,this.yMax,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(p.x,p.y),g.lineTo(f.x,f.y),g.stroke(),g.lineWidth=1,t=this._convert3Dto2D(new h(this.xMin,this.yMin,this.zMin)),e=this._convert3Dto2D(new h(this.xMin,this.yMax,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(e.x,e.y),g.stroke(),t=this._convert3Dto2D(new h(this.xMax,this.yMin,this.zMin)),e=this._convert3Dto2D(new h(this.xMax,this.yMax,this.zMin)),g.strokeStyle=this.colorAxis,g.beginPath(),g.moveTo(t.x,t.y),g.lineTo(e.x,e.y),g.stroke();var w=this.xLabel;w.length>0&&(c=.1/this.scale.y,n=(this.xMin+this.xMax)/2,r=Math.cos(_)>0?this.yMin-c:this.yMax+c,o=this._convert3Dto2D(new h(n,r,this.zMin)),Math.cos(2*_)>0?(g.textAlign="center",g.textBaseline="top"):Math.sin(2*_)<0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(w,o.x,o.y));var S=this.yLabel;S.length>0&&(l=.1/this.scale.x,n=Math.sin(_)>0?this.xMin-l:this.xMax+l,r=(this.yMin+this.yMax)/2,o=this._convert3Dto2D(new h(n,r,this.zMin)),Math.cos(2*_)<0?(g.textAlign="center",g.textBaseline="top"):Math.sin(2*_)>0?(g.textAlign="right",g.textBaseline="middle"):(g.textAlign="left",g.textBaseline="middle"),g.fillStyle=this.colorAxis,g.fillText(S,o.x,o.y));var D=this.zLabel;D.length>0&&(d=30,n=Math.cos(_)>0?this.xMin:this.xMax,r=Math.sin(_)<0?this.yMin:this.yMax,a=(this.zMin+this.zMax)/2,o=this._convert3Dto2D(new h(n,r,a)),g.textAlign="right",g.textBaseline="middle",g.fillStyle=this.colorAxis,g.fillText(D,o.x-d,o.y))},s.prototype._hsv2rgb=function(t,e,i){var s,o,n,r,a,h;switch(r=i*e,a=Math.floor(t/60),h=r*(1-Math.abs(t/60%2-1)),a){case 0:s=r,o=h,n=0;break;case 1:s=h,o=r,n=0;break;case 2:s=0,o=r,n=h;break;case 3:s=0,o=h,n=r;break;case 4:s=h,o=0,n=r;break;case 5:s=r,o=0,n=h;break;default:s=0,o=0,n=0}return"RGB("+parseInt(255*s)+","+parseInt(255*o)+","+parseInt(255*n)+")"},s.prototype._redrawDataGrid=function(){var t,e,i,o,n,r,a,d,l,c,p,u,f,m=this.frame.canvas,g=m.getContext("2d");if(!(void 0===this.dataPoints||this.dataPoints.length<=0)){for(n=0;n0}else r=!0;r?(f=(t.point.z+e.point.z+i.point.z+o.point.z)/4,c=240*(1-(f-this.zMin)*this.scale.z/this.verticalRatio),p=1,this.showShadow?(u=Math.min(1+S.x/D/2,1),a=this._hsv2rgb(c,p,u),d=a):(u=1,a=this._hsv2rgb(c,p,u),d=this.colorAxis)):(a="gray",d=this.colorAxis),l=.5,g.lineWidth=l,g.fillStyle=a,g.strokeStyle=d,g.beginPath(),g.moveTo(t.screen.x,t.screen.y),g.lineTo(e.screen.x,e.screen.y),g.lineTo(o.screen.x,o.screen.y),g.lineTo(i.screen.x,i.screen.y),g.closePath(),g.fill(),g.stroke()}}else for(n=0;np&&(p=0);var u,f,m;this.style===s.STYLE.DOTCOLOR?(u=240*(1-(d.point.value-this.valueMin)*this.scale.value),f=this._hsv2rgb(u,1,1),m=this._hsv2rgb(u,1,.8)):this.style===s.STYLE.DOTSIZE?(f=this.colorDot,m=this.colorDotBorder):(u=240*(1-(d.point.z-this.zMin)*this.scale.z/this.verticalRatio),f=this._hsv2rgb(u,1,1),m=this._hsv2rgb(u,1,.8)),i.lineWidth=1,i.strokeStyle=m,i.fillStyle=f,i.beginPath(),i.arc(d.screen.x,d.screen.y,p,0,2*Math.PI,!0),i.fill(),i.stroke()}}},s.prototype._redrawDataBar=function(){var t,e,i,o,n=this.frame.canvas,r=n.getContext("2d");if(!(void 0===this.dataPoints||this.dataPoints.length<=0)){for(t=0;t0&&(t=this.dataPoints[0],s.lineWidth=1,s.strokeStyle="blue",s.beginPath(),s.moveTo(t.screen.x,t.screen.y)),e=1;e0&&s.stroke()}},s.prototype._onMouseDown=function(t){if(t=t||window.event,this.leftButtonDown&&this._onMouseUp(t),this.leftButtonDown=t.which?1===t.which:1===t.button,this.leftButtonDown||this.touchDown){this.startMouseX=getMouseX(t),this.startMouseY=getMouseY(t),this.startStart=new Date(this.start),this.startEnd=new Date(this.end),this.startArmRotation=this.camera.getArmRotation(),this.frame.style.cursor="move";var e=this;this.onmousemove=function(t){e._onMouseMove(t)},this.onmouseup=function(t){e._onMouseUp(t)},a.addEventListener(document,"mousemove",e.onmousemove),a.addEventListener(document,"mouseup",e.onmouseup),a.preventDefault(t)}},s.prototype._onMouseMove=function(t){t=t||window.event;var e=parseFloat(getMouseX(t))-this.startMouseX,i=parseFloat(getMouseY(t))-this.startMouseY,s=this.startArmRotation.horizontal+e/200,o=this.startArmRotation.vertical+i/200,n=4,r=Math.sin(n/360*2*Math.PI);Math.abs(Math.sin(s))0?1:0>t?-1:0}var s=e[0],o=e[1],n=e[2],r=i((o.x-s.x)*(t.y-s.y)-(o.y-s.y)*(t.x-s.x)),a=i((n.x-o.x)*(t.y-o.y)-(n.y-o.y)*(t.x-o.x)),h=i((s.x-n.x)*(t.y-n.y)-(s.y-n.y)*(t.x-n.x));return!(0!=r&&0!=a&&r!=a||0!=a&&0!=h&&a!=h||0!=r&&0!=h&&r!=h)},s.prototype._dataPointFromXY=function(t,e){var i,o=100,n=null,r=null,a=null,h=new d(t,e);if(this.style===s.STYLE.BAR||this.style===s.STYLE.BARCOLOR||this.style===s.STYLE.BARSIZE)for(i=this.dataPoints.length-1;i>=0;i--){n=this.dataPoints[i];var l=n.surfaces;if(l)for(var c=l.length-1;c>=0;c--){var p=l[c],u=p.corners,f=[u[0].screen,u[1].screen,u[2].screen],m=[u[2].screen,u[3].screen,u[0].screen];if(this._insideTriangle(h,f)||this._insideTriangle(h,m))return n}}else for(i=0;ib)&&o>b&&(a=b,r=n)}}return r},s.prototype._showTooltip=function(t){var e,i,s;this.tooltip?(e=this.tooltip.dom.content,i=this.tooltip.dom.line,s=this.tooltip.dom.dot):(e=document.createElement("div"),e.style.position="absolute",e.style.padding="10px",e.style.border="1px solid #4d4d4d",e.style.color="#1a1a1a",e.style.background="rgba(255,255,255,0.7)",e.style.borderRadius="2px",e.style.boxShadow="5px 5px 10px rgba(128,128,128,0.5)",i=document.createElement("div"),i.style.position="absolute",i.style.height="40px",i.style.width="0",i.style.borderLeft="1px solid #4d4d4d",s=document.createElement("div"),s.style.position="absolute",s.style.height="0",s.style.width="0",s.style.border="5px solid #4d4d4d",s.style.borderRadius="5px",this.tooltip={dataPoint:null,dom:{content:e,line:i,dot:s}}),this._hideTooltip(),this.tooltip.dataPoint=t,e.innerHTML="function"==typeof this.showTooltip?this.showTooltip(t.point):"
x:"+t.point.x+"
y:"+t.point.y+"
z:"+t.point.z+"
",e.style.left="0",e.style.top="0",this.frame.appendChild(e),this.frame.appendChild(i),this.frame.appendChild(s);var o=e.offsetWidth,n=e.offsetHeight,r=i.offsetHeight,a=s.offsetWidth,h=s.offsetHeight,d=t.screen.x-o/2;d=Math.min(Math.max(d,10),this.frame.clientWidth-10-o),i.style.left=t.screen.x+"px",i.style.top=t.screen.y-r+"px",e.style.left=d+"px",e.style.top=t.screen.y-r-n+"px",s.style.left=t.screen.x-a/2+"px",s.style.top=t.screen.y-h/2+"px"},s.prototype._hideTooltip=function(){if(this.tooltip){this.tooltip.dataPoint=null;for(var t in this.tooltip.dom)if(this.tooltip.dom.hasOwnProperty(t)){var e=this.tooltip.dom[t];e&&e.parentNode&&e.parentNode.removeChild(e)}}},getMouseX=function(t){return"clientX"in t?t.clientX:t.targetTouches[0]&&t.targetTouches[0].clientX||0},getMouseY=function(t){return"clientY"in t?t.clientY:t.targetTouches[0]&&t.targetTouches[0].clientY||0},t.exports=s},function(t,e,i){var s=i(9);Camera=function(){this.armLocation=new s,this.armRotation={},this.armRotation.horizontal=0,this.armRotation.vertical=0,this.armLength=1.7,this.cameraLocation=new s,this.cameraRotation=new s(.5*Math.PI,0,0),this.calculateCameraOrientation()},Camera.prototype.setArmLocation=function(t,e,i){this.armLocation.x=t,this.armLocation.y=e,this.armLocation.z=i,this.calculateCameraOrientation()},Camera.prototype.setArmRotation=function(t,e){void 0!==t&&(this.armRotation.horizontal=t),void 0!==e&&(this.armRotation.vertical=e,this.armRotation.vertical<0&&(this.armRotation.vertical=0),this.armRotation.vertical>.5*Math.PI&&(this.armRotation.vertical=.5*Math.PI)),(void 0!==t||void 0!==e)&&this.calculateCameraOrientation()},Camera.prototype.getArmRotation=function(){var t={};return t.horizontal=this.armRotation.horizontal,t.vertical=this.armRotation.vertical,t},Camera.prototype.setArmLength=function(t){void 0!==t&&(this.armLength=t,this.armLength<.71&&(this.armLength=.71),this.armLength>5&&(this.armLength=5),this.calculateCameraOrientation())},Camera.prototype.getArmLength=function(){return this.armLength},Camera.prototype.getCameraLocation=function(){return this.cameraLocation},Camera.prototype.getCameraRotation=function(){return this.cameraRotation},Camera.prototype.calculateCameraOrientation=function(){this.cameraLocation.x=this.armLocation.x-this.armLength*Math.sin(this.armRotation.horizontal)*Math.cos(this.armRotation.vertical),this.cameraLocation.y=this.armLocation.y-this.armLength*Math.cos(this.armRotation.horizontal)*Math.cos(this.armRotation.vertical),this.cameraLocation.z=this.armLocation.z+this.armLength*Math.sin(this.armRotation.vertical),this.cameraRotation.x=Math.PI/2-this.armRotation.vertical,this.cameraRotation.y=0,this.cameraRotation.z=-this.armRotation.horizontal},t.exports=Camera},function(t,e,i){function s(t,e,i){this.data=t,this.column=e,this.graph=i,this.index=void 0,this.value=void 0,this.values=i.getDistinctValues(t.get(),this.column),this.values.sort(function(t,e){return t>e?1:e>t?-1:0}),this.values.length>0&&this.selectValue(0),this.dataPoints=[],this.loaded=!1,this.onLoadCallback=void 0,i.animationPreload?(this.loaded=!1,this.loadInBackground()):this.loaded=!0}var o=i(4);s.prototype.isLoaded=function(){return this.loaded},s.prototype.getLoadedProgress=function(){for(var t=this.values.length,e=0;this.dataPoints[e];)e++;return Math.round(e/t*100)},s.prototype.getLabel=function(){return this.graph.filterLabel},s.prototype.getColumn=function(){return this.column},s.prototype.getSelectedValue=function(){return void 0===this.index?void 0:this.values[this.index]},s.prototype.getValues=function(){return this.values},s.prototype.getValue=function(t){if(t>=this.values.length)throw"Error: index out of range";return this.values[t]},s.prototype._getDataPoints=function(t){if(void 0===t&&(t=this.index),void 0===t)return[];var e;if(this.dataPoints[t])e=this.dataPoints[t];else{var i={};i.column=this.column,i.value=this.values[t];var s=new o(this.data,{filter:function(t){return t[i.column]==i.value}}).get();e=this.graph._getDataPoints(s),this.dataPoints[t]=e}return e},s.prototype.setOnLoadCallback=function(t){this.onLoadCallback=t},s.prototype.selectValue=function(t){if(t>=this.values.length)throw"Error: index out of range";this.index=t,this.value=this.values[t]},s.prototype.loadInBackground=function(t){void 0===t&&(t=0);var e=this.graph.frame;if(t0&&(t--,this.setIndex(t))},s.prototype.next=function(){var t=this.getIndex();t0?this.setIndex(0):this.index=void 0},s.prototype.setIndex=function(t){if(!(ts&&(s=0),s>this.values.length-1&&(s=this.values.length-1),s},s.prototype.indexToLeft=function(t){var e=parseFloat(this.frame.bar.style.width)-this.frame.slide.clientWidth-10,i=t/(this.values.length-1)*e,s=i+3;return s},s.prototype._onMouseMove=function(t){var e=t.clientX-this.startClientX,i=this.startSlideX+e,s=this.leftToIndex(i);this.setIndex(s),o.preventDefault()},s.prototype._onMouseUp=function(){this.frame.style.cursor="auto",o.removeEventListener(document,"mousemove",this.onmousemove),o.removeEventListener(document,"mouseup",this.onmouseup),o.preventDefault()},t.exports=s},function(t){function e(t,e,i,s){this._start=0,this._end=0,this._step=1,this.prettyStep=!0,this.precision=5,this._current=0,this.setRange(t,e,i,s)}e.prototype.setRange=function(t,e,i,s){this._start=t?t:0,this._end=e?e:0,this.setStep(i,s)},e.prototype.setStep=function(t,i){void 0===t||0>=t||(void 0!==i&&(this.prettyStep=i),this._step=this.prettyStep===!0?e.calculatePrettyStep(t):t)},e.calculatePrettyStep=function(t){var e=function(t){return Math.log(t)/Math.LN10},i=Math.pow(10,Math.round(e(t))),s=2*Math.pow(10,Math.round(e(t/2))),o=5*Math.pow(10,Math.round(e(t/5))),n=i;return Math.abs(s-t)<=Math.abs(n-t)&&(n=s),Math.abs(o-t)<=Math.abs(n-t)&&(n=o),0>=n&&(n=1),n},e.prototype.getCurrent=function(){return parseFloat(this._current.toPrecision(this.precision))},e.prototype.getStep=function(){return this._step},e.prototype.start=function(){this._current=this._start-this._start%this._step},e.prototype.next=function(){this._current+=this._step},e.prototype.end=function(){return this._current>this._end},t.exports=e},function(t,e,i){function s(t,e,i,r){if(!(this instanceof s))throw new SyntaxError("Constructor must be called with the new operator");if(!(Array.isArray(i)||i instanceof n)&&i instanceof Object){var h=r;r=i,i=h}var u=this;this.defaultOptions={start:null,end:null,autoResize:!0,orientation:"bottom",width:null,height:null,maxHeight:null,minHeight:null},this.options=o.deepExtend({},this.defaultOptions),this._create(t),this.components=[],this.body={dom:this.dom,domProps:this.props,emitter:{on:this.on.bind(this),off:this.off.bind(this),emit:this.emit.bind(this)},hiddenDates:[],util:{snap:null,toScreen:u._toScreen.bind(u),toGlobalScreen:u._toGlobalScreen.bind(u),toTime:u._toTime.bind(u),toGlobalTime:u._toGlobalTime.bind(u)}},this.range=new a(this.body),this.components.push(this.range),this.body.range=this.range,this.timeAxis=new d(this.body),this.components.push(this.timeAxis),this.body.util.snap=this.timeAxis.snap.bind(this.timeAxis),this.currentTime=new l(this.body),this.components.push(this.currentTime),this.customTime=new c(this.body),this.components.push(this.customTime),this.itemSet=new p(this.body),this.components.push(this.itemSet),this.itemsData=null,this.groupsData=null,r&&this.setOptions(r),i&&this.setGroups(i),e?this.setItems(e):this.redraw()}var o=(i(52),i(44),i(1)),n=i(3),r=i(4),a=i(16),h=i(45),d=i(29),l=i(20),c=i(21),p=i(26);s.prototype=new h,s.prototype.setItems=function(t){var e,i=null==this.itemsData;if(e=t?t instanceof n||t instanceof r?t:new n(t,{type:{start:"Date",end:"Date"}}):null,this.itemsData=e,this.itemSet&&this.itemSet.setItems(e),i)if(void 0!=this.options.start||void 0!=this.options.end){var s=void 0!=this.options.start?this.options.start:null,o=void 0!=this.options.end?this.options.end:null;this.setWindow(s,o,{animate:!1})}else this.fit({animate:!1})},s.prototype.setGroups=function(t){var e;e=t?t instanceof n||t instanceof r?t:new n(t):null,this.groupsData=e,this.itemSet.setGroups(e)},s.prototype.setSelection=function(t,e){this.itemSet&&this.itemSet.setSelection(t),e&&e.focus&&this.focus(t,e)},s.prototype.getSelection=function(){return this.itemSet&&this.itemSet.getSelection()||[]},s.prototype.focus=function(t,e){if(this.itemsData&&void 0!=t){var i=Array.isArray(t)?t:[t],s=this.itemsData.getDataSet().get(i,{type:{start:"Date",end:"Date"}}),o=null,n=null;if(s.forEach(function(t){var e=t.start.valueOf(),i="end"in t?t.end.valueOf():t.start.valueOf();(null===o||o>e)&&(o=e),(null===n||i>n)&&(n=i)}),null!==o&&null!==n){var r=(o+n)/2,a=Math.max(this.range.end-this.range.start,1.1*(n-o)),h=e&&void 0!==e.animate?e.animate:!0;this.range.setRange(r-a/2,r+a/2,h)}}},s.prototype.getItemRange=function(){var t=this.itemsData.getDataSet(),e=null,i=null;if(t){var s=t.min("start");e=s?o.convert(s.start,"Date").valueOf():null;var n=t.max("start");n&&(i=o.convert(n.start,"Date").valueOf());var r=t.max("end");r&&(i=null==i?o.convert(r.end,"Date").valueOf():Math.max(i,o.convert(r.end,"Date").valueOf()))}return{min:null!=e?new Date(e):null,max:null!=i?new Date(i):null}},t.exports=s},function(t,e,i){function s(t,e,i,s){if(!(Array.isArray(i)||i instanceof n)&&i instanceof Object){var r=s;s=i,i=r}var h=this;this.defaultOptions={start:null,end:null,autoResize:!0,orientation:"bottom",width:null,height:null,maxHeight:null,minHeight:null},this.options=o.deepExtend({},this.defaultOptions),this._create(t),this.components=[],this.body={dom:this.dom,domProps:this.props,emitter:{on:this.on.bind(this),off:this.off.bind(this),emit:this.emit.bind(this)},hiddenDates:[],util:{snap:null,toScreen:h._toScreen.bind(h),toGlobalScreen:h._toGlobalScreen.bind(h),toTime:h._toTime.bind(h),toGlobalTime:h._toGlobalTime.bind(h)}},this.range=new a(this.body),this.components.push(this.range),this.body.range=this.range,this.timeAxis=new d(this.body),this.components.push(this.timeAxis),this.body.util.snap=this.timeAxis.snap.bind(this.timeAxis),this.currentTime=new l(this.body),this.components.push(this.currentTime),this.customTime=new c(this.body),this.components.push(this.customTime),this.linegraph=new p(this.body),this.components.push(this.linegraph),this.itemsData=null,this.groupsData=null,s&&this.setOptions(s),i&&this.setGroups(i),e?this.setItems(e):this.redraw()}var o=(i(52),i(44),i(1)),n=i(3),r=i(4),a=i(16),h=i(45),d=i(29),l=i(20),c=i(21),p=i(28);s.prototype=new h,s.prototype.setItems=function(t){var e,i=null==this.itemsData;if(e=t?t instanceof n||t instanceof r?t:new n(t,{type:{start:"Date",end:"Date"}}):null,this.itemsData=e,this.linegraph&&this.linegraph.setItems(e),i)if(void 0!=this.options.start||void 0!=this.options.end){var s=void 0!=this.options.start?this.options.start:null,o=void 0!=this.options.end?this.options.end:null;this.setWindow(s,o,{animate:!1})}else this.fit({animate:!1})},s.prototype.setGroups=function(t){var e;e=t?t instanceof n||t instanceof r?t:new n(t):null,this.groupsData=e,this.linegraph.setGroups(e)},s.prototype.getLegend=function(t,e,i){return void 0===e&&(e=15),void 0===i&&(i=15),void 0!==this.linegraph.groups[t]?this.linegraph.groups[t].getLegend(e,i):"cannot find group:"+t},s.prototype.isGroupVisible=function(t){return void 0!==this.linegraph.groups[t]?this.linegraph.groups[t].visible&&(void 0===this.linegraph.options.groups.visibility[t]||1==this.linegraph.options.groups.visibility[t]):!1},s.prototype.getItemRange=function(){var t=null,e=null;for(var i in this.linegraph.groups)if(this.linegraph.groups.hasOwnProperty(i)&&1==this.linegraph.groups[i].visible)for(var s=0;sr?r:t,e=null==e?r:r>e?r:e}return{min:null!=t?new Date(t):null,max:null!=e?new Date(e):null}},t.exports=s},function(t,e,i){var s=i(43);e.convertHiddenOptions=function(t,e){if(t.hiddenDates=[],e&&1==Array.isArray(e)){for(var i=0;i=4*a){var p=0,u=n.clone();switch(i[h].repeat){case"daily":d.day()!=l.day()&&(p=1),d.dayOfYear(o.dayOfYear()),d.year(o.year()),d.subtract(7,"days"),l.dayOfYear(o.dayOfYear()),l.year(o.year()),l.subtract(7-p,"days"),u.add(1,"weeks");break;case"weekly":var f=l.diff(d,"days"),m=d.day();d.date(o.date()),d.month(o.month()),d.year(o.year()),l=d.clone(),d.day(m),l.day(m),l.add(f,"days"),d.subtract(1,"weeks"),l.subtract(1,"weeks"),u.add(1,"weeks");break;case"monthly":d.month()!=l.month()&&(p=1),d.month(o.month()),d.year(o.year()),d.subtract(1,"months"),l.month(o.month()),l.year(o.year()),l.subtract(1,"months"),l.add(p,"months"),u.add(1,"months");break;case"yearly":d.year()!=l.year()&&(p=1),d.year(o.year()),d.subtract(1,"years"),l.year(o.year()),l.subtract(1,"years"),l.add(p,"years"),u.add(1,"years");break;default:return void console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:",i[h].repeat)}for(;u>d;)switch(t.hiddenDates.push({start:d.valueOf(),end:l.valueOf()}),i[h].repeat){case"daily":d.add(1,"days"),l.add(1,"days");break;case"weekly":d.add(1,"weeks"),l.add(1,"weeks");break;case"monthly":d.add(1,"months"),l.add(1,"months");break;case"yearly":d.add(1,"y"),l.add(1,"y");break;default:return void console.log("Wrong repeat format, allowed are: daily, weekly, monthly, yearly. Given:",i[h].repeat)}t.hiddenDates.push({start:d.valueOf(),end:l.valueOf()})}}e.removeDuplicates(t);var g=e.isHidden(t.range.start,t.hiddenDates),v=e.isHidden(t.range.end,t.hiddenDates),y=t.range.start,b=t.range.end;1==g.hidden&&(y=1==t.range.startToFront?g.startDate-1:g.endDate+1),1==v.hidden&&(b=1==t.range.endToFront?v.startDate-1:v.endDate+1),(1==g.hidden||1==v.hidden)&&t.range._applyRange(y,b)}},e.removeDuplicates=function(t){for(var e=t.hiddenDates,i=[],s=0;s=e[s].start&&e[o].end<=e[s].end?e[o].remove=!0:e[o].start>=e[s].start&&e[o].start<=e[s].end?(e[s].end=e[o].end,e[o].remove=!0):e[o].end>=e[s].start&&e[o].end<=e[s].end&&(e[s].start=e[o].start,e[o].remove=!0));for(var s=0;s=r&&a>o){i=!0;break}}if(1==i&&o=n&&r>i){e=!0;break}}if(1==e&&i<=t._end.valueOf()){var a=s(r);t.current=a.toDate()}},e.toScreen=function(t,i,s){var o=e.isHidden(i,t.body.hiddenDates);1==o.hidden&&(i=o.startDate);var n=e.getHiddenDurationBetween(t.body.hiddenDates,t.range.start,t.range.end);i=e.correctTimeForHidden(t.body.hiddenDates,t.range,i);var r=t.range.conversion(s,n);return(i.valueOf()-r.offset)*r.scale},e.toTime=function(t,i,s,o){var n=e.getHiddenDurationBetween(t.hiddenDates,i.start,i.end),r=i.end-i.start-n,a=r*s/o,h=e.getAccumulatedHiddenDuration(t.hiddenDates,i,a),d=new Date(h+a+i.start);return d},e.getHiddenDurationBetween=function(t,e,i){for(var s=0,o=0;o=e&&i>r&&(s+=r-n)}return s},e.correctTimeForHidden=function(t,i,o){return o=s(o).toDate().valueOf(),o-=e.getHiddenDurationBefore(t,i,o)},e.getHiddenDurationBefore=function(t,e,i){var o=0;i=s(i).toDate().valueOf();for(var n=0;n=e.start&&a=a&&(o+=a-r)}return o},e.getAccumulatedHiddenDuration=function(t,e,i){for(var s=0,o=0,n=e.start,r=0;r=e.start&&h=i)break;s+=h-a}}return s},e.snapAwayFromHidden=function(t,i,s,o){var n=e.isHidden(i,t);return 1==n.hidden?0>s?1==o?n.startDate-(n.endDate-i)-1:n.startDate-1:1==o?n.endDate+(i-n.startDate)+1:n.endDate+1:i},e.isHidden=function(t,e){for(var i=0;i=s&&o>t)return{hidden:!0,startDate:s,endDate:o}}return{hidden:!1,startDate:s,endDate:o}}},function(t){function e(t,e,i,s,o){this.current=0,this.autoScale=!0,this.stepIndex=0,this.step=1,this.scale=1,this.marginStart,this.marginEnd,this.deadSpace=0,this.majorSteps=[1,2,5,10],this.minorSteps=[.25,.5,1,2],this.setRange(t,e,i,s,o)}e.prototype.setRange=function(t,e,i,s,o){this._start=void 0===o.min?t:o.min,this._end=void 0===o.max?e:o.max,this._start==this._end&&(this._start-=.75,this._end+=1),this.autoScale&&this.setMinimumStep(i,s),this.setFirst(o)},e.prototype.setMinimumStep=function(t,e){var i=this._end-this._start,s=1.2*i,o=t*(s/e),n=Math.round(Math.log(s)/Math.LN10),r=-1,a=Math.pow(10,n),h=0;0>n&&(h=n);for(var d=!1,l=h;Math.abs(l)<=Math.abs(n);l++){a=Math.pow(10,l);for(var c=0;c=o){d=!0,r=c;break}}if(1==d)break}this.stepIndex=r,this.scale=a,this.step=a*this.minorSteps[r]},e.prototype.setFirst=function(t){void 0===t&&(t={});var e=void 0===t.min?this._start-2*this.scale*this.minorSteps[this.stepIndex]:t.min,i=void 0===t.max?this._end+this.scale*this.minorSteps[this.stepIndex]:t.max;this.marginEnd=void 0===t.max?this.roundToMinor(i):t.max,this.marginStart=void 0===t.min?this.roundToMinor(e):t.min,this.deadSpace=this.roundToMinor(i)-i+this.roundToMinor(e)-e,this.marginRange=this.marginEnd-this.marginStart,this.current=this.marginEnd},e.prototype.roundToMinor=function(t){var e=t-t%(this.scale*this.minorSteps[this.stepIndex]);return t%(this.scale*this.minorSteps[this.stepIndex])>.5*this.scale*this.minorSteps[this.stepIndex]?e+this.scale*this.minorSteps[this.stepIndex]:e},e.prototype.hasNext=function(){return this.current>=this.marginStart},e.prototype.next=function(){var t=this.current;this.current-=this.step,this.current==t&&(this.current=this._end)},e.prototype.previous=function(){this.current+=this.step,this.marginEnd+=this.step,this.marginRange=this.marginEnd-this.marginStart},e.prototype.getCurrent=function(){var t=""+Number(this.current).toPrecision(5);if(-1!=t.indexOf(",")||-1!=t.indexOf("."))for(var e=t.length-1;e>0;e--){if("0"!=t[e]){if("."==t[e]||","==t[e]){t=t.slice(0,e);break}break}t=t.slice(0,e)}return t},e.prototype.snap=function(){},e.prototype.isMajor=function(){return this.current%(this.scale*this.majorSteps[this.stepIndex])==0},t.exports=e},function(t,e,i){function s(t,e){var i=h().hours(0).minutes(0).seconds(0).milliseconds(0);this.start=i.clone().add(-3,"days").valueOf(),this.end=i.clone().add(4,"days").valueOf(),this.body=t,this.deltaDifference=0,this.scaleOffset=0,this.startToFront=!1,this.endToFront=!0,this.defaultOptions={start:null,end:null,direction:"horizontal",moveable:!0,zoomable:!0,min:null,max:null,zoomMin:10,zoomMax:31536e10},this.options=r.extend({},this.defaultOptions),this.props={touch:{}},this.animateTimer=null,this.body.emitter.on("dragstart",this._onDragStart.bind(this)),this.body.emitter.on("drag",this._onDrag.bind(this)),this.body.emitter.on("dragend",this._onDragEnd.bind(this)),this.body.emitter.on("hold",this._onHold.bind(this)),this.body.emitter.on("mousewheel",this._onMouseWheel.bind(this)),this.body.emitter.on("DOMMouseScroll",this._onMouseWheel.bind(this)),this.body.emitter.on("touch",this._onTouch.bind(this)),this.body.emitter.on("pinch",this._onPinch.bind(this)),this.setOptions(e)}function o(t){if("horizontal"!=t&&"vertical"!=t)throw new TypeError('Unknown direction "'+t+'". Choose "horizontal" or "vertical".')}function n(t,e){return{x:t.pageX-r.getAbsoluteLeft(e),y:t.pageY-r.getAbsoluteTop(e)}}var r=i(1),a=i(46),h=i(43),d=i(19),l=i(14);s.prototype=new d,s.prototype.setOptions=function(t){if(t){var e=["direction","min","max","zoomMin","zoomMax","moveable","zoomable","activate","hiddenDates"];r.selectiveExtend(e,this.options,t),("start"in t||"end"in t)&&this.setRange(t.start,t.end)}},s.prototype.setRange=function(t,e,i){function s(){if(!a.props.touch.dragging){var t=(new Date).valueOf(),e=t-p,i=e>c,m=i||null===o?o:r.easeInOutQuad(e,h,o,c),g=i||null===n?n:r.easeInOutQuad(e,d,n,c);f=a._applyRange(m,g),l.updateHiddenDates(a.body,a.options.hiddenDates),u=u||f,f&&a.body.emitter.emit("rangechange",{start:new Date(a.start),end:new Date(a.end)}),i?u&&a.body.emitter.emit("rangechanged",{start:new Date(a.start),end:new Date(a.end)}):a.animateTimer=setTimeout(s,20)}}var o=void 0!=t?r.convert(t,"Date").valueOf():null,n=void 0!=e?r.convert(e,"Date").valueOf():null;if(this._cancelAnimation(),i){var a=this,h=this.start,d=this.end,c="number"==typeof i?i:500,p=(new Date).valueOf(),u=!1;return s()}var f=this._applyRange(o,n);if(l.updateHiddenDates(this.body,this.options.hiddenDates),f){var m={start:new Date(this.start),end:new Date(this.end)};this.body.emitter.emit("rangechange",m),this.body.emitter.emit("rangechanged",m)}},s.prototype._cancelAnimation=function(){this.animateTimer&&(clearTimeout(this.animateTimer),this.animateTimer=null)},s.prototype._applyRange=function(t,e){var i,s=null!=t?r.convert(t,"Date").valueOf():this.start,o=null!=e?r.convert(e,"Date").valueOf():this.end,n=null!=this.options.max?r.convert(this.options.max,"Date").valueOf():null,a=null!=this.options.min?r.convert(this.options.min,"Date").valueOf():null;if(isNaN(s)||null===s)throw new Error('Invalid start "'+t+'"');if(isNaN(o)||null===o)throw new Error('Invalid end "'+e+'"');if(s>o&&(o=s),null!==a&&a>s&&(i=a-s,s+=i,o+=i,null!=n&&o>n&&(o=n)),null!==n&&o>n&&(i=o-n,s-=i,o-=i,null!=a&&a>s&&(s=a)),null!==this.options.zoomMin){var h=parseFloat(this.options.zoomMin);0>h&&(h=0),h>o-s&&(this.end-this.start===h?(s=this.start,o=this.end):(i=h-(o-s),s-=i/2,o+=i/2))}if(null!==this.options.zoomMax){var d=parseFloat(this.options.zoomMax);0>d&&(d=0),o-s>d&&(this.end-this.start===d?(s=this.start,o=this.end):(i=o-s-d,s+=i/2,o-=i/2))}var l=this.start!=s||this.end!=o;return this.start=s,this.end=o,l},s.prototype.getRange=function(){return{start:this.start,end:this.end}},s.prototype.conversion=function(t,e){return s.conversion(this.start,this.end,t,e)},s.conversion=function(t,e,i,s){return void 0===s&&(s=0),0!=i&&e-t!=0?{offset:t,scale:i/(e-t-s)}:{offset:0,scale:1}},s.prototype._onDragStart=function(){this.deltaDifference=0,this.previousDelta=0,this.options.moveable&&this.props.touch.allowDragging&&(this.props.touch.start=this.start,this.props.touch.end=this.end,this.props.touch.dragging=!0,this.body.dom.root&&(this.body.dom.root.style.cursor="move"))},s.prototype._onDrag=function(t){if(this.options.moveable&&this.props.touch.allowDragging){var e=this.options.direction;o(e);var i="horizontal"==e?t.gesture.deltaX:t.gesture.deltaY;i-=this.deltaDifference;var s=this.props.touch.end-this.props.touch.start,n=l.getHiddenDurationBetween(this.body.hiddenDates,this.start,this.end);s-=n;var r="horizontal"==e?this.body.domProps.center.width:this.body.domProps.center.height,a=-i/r*s,h=this.props.touch.start+a,d=this.props.touch.end+a,c=l.snapAwayFromHidden(this.body.hiddenDates,h,this.previousDelta-i,!0),p=l.snapAwayFromHidden(this.body.hiddenDates,d,this.previousDelta-i,!0);if(c!=h||p!=d)return this.deltaDifference+=i,this.props.touch.start=c,this.props.touch.end=p,void this._onDrag(t);this.previousDelta=i,this._applyRange(h,d),this.body.emitter.emit("rangechange",{start:new Date(this.start),end:new Date(this.end)})}},s.prototype._onDragEnd=function(){this.options.moveable&&this.props.touch.allowDragging&&(this.props.touch.dragging=!1,this.body.dom.root&&(this.body.dom.root.style.cursor="auto"),this.body.emitter.emit("rangechanged",{start:new Date(this.start),end:new Date(this.end)}))},s.prototype._onMouseWheel=function(t){if(this.options.zoomable&&this.options.moveable){var e=0;if(t.wheelDelta?e=t.wheelDelta/120:t.detail&&(e=-t.detail/3),e){var i;i=0>e?1-e/5:1/(1+e/5);var s=a.fakeGesture(this,t),o=n(s.center,this.body.dom.center),r=this._pointerToDate(o);this.zoom(i,r,e)}t.preventDefault()}},s.prototype._onTouch=function(){this.props.touch.start=this.start,this.props.touch.end=this.end,this.props.touch.allowDragging=!0,this.props.touch.center=null,this.scaleOffset=0,this.deltaDifference=0},s.prototype._onHold=function(){this.props.touch.allowDragging=!1},s.prototype._onPinch=function(t){if(this.options.zoomable&&this.options.moveable&&(this.props.touch.allowDragging=!1,t.gesture.touches.length>1)){this.props.touch.center||(this.props.touch.center=n(t.gesture.center,this.body.dom.center));var e=1/(t.gesture.scale+this.scaleOffset),i=this._pointerToDate(this.props.touch.center),s=l.getHiddenDurationBetween(this.body.hiddenDates,this.start,this.end),o=l.getHiddenDurationBefore(this.body.hiddenDates,this,i),r=s-o,a=i-o+(this.start-(i-o))*e,h=i+r+(this.end-(i+r))*e;this.startToFront=1-e>0?!1:!0,this.endToFront=e-1>0?!1:!0;var d=l.snapAwayFromHidden(this.body.hiddenDates,a,1-e,!0),c=l.snapAwayFromHidden(this.body.hiddenDates,h,e-1,!0);(d!=a||c!=h)&&(this.props.touch.start=d,this.props.touch.end=c,this.scaleOffset=1-t.gesture.scale,a=d,h=c),this.setRange(a,h),this.startToFront=!1,this.endToFront=!0}},s.prototype._pointerToDate=function(t){var e,i=this.options.direction;if(o(i),"horizontal"==i)return this.body.util.toTime(t.x).valueOf();var s=this.body.domProps.center.height;return e=this.conversion(s),t.y/e.scale+e.offset},s.prototype.zoom=function(t,e,i){null==e&&(e=(this.start+this.end)/2);var s=l.getHiddenDurationBetween(this.body.hiddenDates,this.start,this.end),o=l.getHiddenDurationBefore(this.body.hiddenDates,this,e),n=s-o,r=e-o+(this.start-(e-o))*t,a=e+n+(this.end-(e+n))*t;this.startToFront=i>0?!1:!0,this.endToFront=-i>0?!1:!0;var h=l.snapAwayFromHidden(this.body.hiddenDates,r,i,!0),d=l.snapAwayFromHidden(this.body.hiddenDates,a,-i,!0);(h!=r||d!=a)&&(r=h,a=d),this.setRange(r,a),this.startToFront=!1,this.endToFront=!0},s.prototype.move=function(t){var e=this.end-this.start,i=this.start+e*t,s=this.end+e*t;this.start=i,this.end=s},s.prototype.moveTo=function(t){var e=(this.start+this.end)/2,i=e-t,s=this.start-i,o=this.end-i;this.setRange(s,o)},t.exports=s},function(t,e){var i=.001;e.orderByStart=function(t){t.sort(function(t,e){return t.data.start-e.data.start})},e.orderByEnd=function(t){t.sort(function(t,e){var i="end"in t.data?t.data.end:t.data.start,s="end"in e.data?e.data.end:e.data.start;return i-s})},e.stack=function(t,i,s){var o,n;if(s)for(o=0,n=t.length;n>o;o++)t[o].top=null;for(o=0,n=t.length;n>o;o++){var r=t[o];if(r.stack&&null===r.top){r.top=i.axis;do{for(var a=null,h=0,d=t.length;d>h;h++){var l=t[h];if(null!==l.top&&l!==r&&l.stack&&e.collision(r,l,i.item)){a=l;break}}null!=a&&(r.top=a.top+a.height+i.item.vertical)}while(a)}}},e.nostack=function(t,e,i){var s,o,n;for(s=0,o=t.length;o>s;s++)if(void 0!==t[s].data.subgroup){n=e.axis;for(var r in i)i.hasOwnProperty(r)&&1==i[r].visible&&i[r].indexe.left&&t.top-s.vertical+ie.top}},function(t,e,i){function s(t,e,i,o){this.current=new Date,this._start=new Date,this._end=new Date,this.autoScale=!0,this.scale=s.SCALE.DAY,this.step=1,this.setRange(t,e,i),this.switchedDay=!1,this.switchedMonth=!1,this.switchedYear=!1,this.hiddenDates=o,void 0===o&&(this.hiddenDates=[])}var o=i(43),n=i(14);s.SCALE={MILLISECOND:1,SECOND:2,MINUTE:3,HOUR:4,DAY:5,WEEKDAY:6,MONTH:7,YEAR:8},s.prototype.setRange=function(t,e,i){if(!(t instanceof Date&&e instanceof Date))throw"No legal start or end date in method setRange";this._start=void 0!=t?new Date(t.valueOf()):new Date,this._end=void 0!=e?new Date(e.valueOf()):new Date,this.autoScale&&this.setMinimumStep(i)},s.prototype.first=function(){this.current=new Date(this._start.valueOf()),this.roundToMinor()},s.prototype.roundToMinor=function(){switch(this.scale){case s.SCALE.YEAR:this.current.setFullYear(this.step*Math.floor(this.current.getFullYear()/this.step)),this.current.setMonth(0);case s.SCALE.MONTH:this.current.setDate(1);case s.SCALE.DAY:case s.SCALE.WEEKDAY:this.current.setHours(0);case s.SCALE.HOUR:this.current.setMinutes(0);case s.SCALE.MINUTE:this.current.setSeconds(0);case s.SCALE.SECOND:this.current.setMilliseconds(0)}if(1!=this.step)switch(this.scale){case s.SCALE.MILLISECOND:this.current.setMilliseconds(this.current.getMilliseconds()-this.current.getMilliseconds()%this.step);break;case s.SCALE.SECOND:this.current.setSeconds(this.current.getSeconds()-this.current.getSeconds()%this.step);break;case s.SCALE.MINUTE:this.current.setMinutes(this.current.getMinutes()-this.current.getMinutes()%this.step);break;case s.SCALE.HOUR:this.current.setHours(this.current.getHours()-this.current.getHours()%this.step);break;case s.SCALE.WEEKDAY:case s.SCALE.DAY:this.current.setDate(this.current.getDate()-1-(this.current.getDate()-1)%this.step+1);break;case s.SCALE.MONTH:this.current.setMonth(this.current.getMonth()-this.current.getMonth()%this.step);break;case s.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()-this.current.getFullYear()%this.step)}},s.prototype.hasNext=function(){return this.current.valueOf()<=this._end.valueOf()},s.prototype.next=function(){var t=this.current.valueOf();if(this.current.getMonth()<6)switch(this.scale){case s.SCALE.MILLISECOND:this.current=new Date(this.current.valueOf()+this.step);break;case s.SCALE.SECOND:this.current=new Date(this.current.valueOf()+1e3*this.step);break;case s.SCALE.MINUTE:this.current=new Date(this.current.valueOf()+1e3*this.step*60);break;case s.SCALE.HOUR:this.current=new Date(this.current.valueOf()+1e3*this.step*60*60);var e=this.current.getHours();this.current.setHours(e-e%this.step);break;case s.SCALE.WEEKDAY:case s.SCALE.DAY:this.current.setDate(this.current.getDate()+this.step);break;case s.SCALE.MONTH:this.current.setMonth(this.current.getMonth()+this.step);break;case s.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()+this.step)}else switch(this.scale){case s.SCALE.MILLISECOND:this.current=new Date(this.current.valueOf()+this.step);break;case s.SCALE.SECOND:this.current.setSeconds(this.current.getSeconds()+this.step);break;case s.SCALE.MINUTE:this.current.setMinutes(this.current.getMinutes()+this.step);break;case s.SCALE.HOUR:this.current.setHours(this.current.getHours()+this.step);break;case s.SCALE.WEEKDAY:case s.SCALE.DAY:this.current.setDate(this.current.getDate()+this.step);break;case s.SCALE.MONTH:this.current.setMonth(this.current.getMonth()+this.step);break;case s.SCALE.YEAR:this.current.setFullYear(this.current.getFullYear()+this.step)}if(1!=this.step)switch(this.scale){case s.SCALE.MILLISECOND:this.current.getMilliseconds()0&&(this.step=e),this.autoScale=!1},s.prototype.setAutoScale=function(t){this.autoScale=t},s.prototype.setMinimumStep=function(t){if(void 0!=t){var e=31104e6,i=2592e6,o=864e5,n=36e5,r=6e4,a=1e3,h=1;1e3*e>t&&(this.scale=s.SCALE.YEAR,this.step=1e3),500*e>t&&(this.scale=s.SCALE.YEAR,this.step=500),100*e>t&&(this.scale=s.SCALE.YEAR,this.step=100),50*e>t&&(this.scale=s.SCALE.YEAR,this.step=50),10*e>t&&(this.scale=s.SCALE.YEAR,this.step=10),5*e>t&&(this.scale=s.SCALE.YEAR,this.step=5),e>t&&(this.scale=s.SCALE.YEAR,this.step=1),3*i>t&&(this.scale=s.SCALE.MONTH,this.step=3),i>t&&(this.scale=s.SCALE.MONTH,this.step=1),5*o>t&&(this.scale=s.SCALE.DAY,this.step=5),2*o>t&&(this.scale=s.SCALE.DAY,this.step=2),o>t&&(this.scale=s.SCALE.DAY,this.step=1),o/2>t&&(this.scale=s.SCALE.WEEKDAY,this.step=1),4*n>t&&(this.scale=s.SCALE.HOUR,this.step=4),n>t&&(this.scale=s.SCALE.HOUR,this.step=1),15*r>t&&(this.scale=s.SCALE.MINUTE,this.step=15),10*r>t&&(this.scale=s.SCALE.MINUTE,this.step=10),5*r>t&&(this.scale=s.SCALE.MINUTE,this.step=5),r>t&&(this.scale=s.SCALE.MINUTE,this.step=1),15*a>t&&(this.scale=s.SCALE.SECOND,this.step=15),10*a>t&&(this.scale=s.SCALE.SECOND,this.step=10),5*a>t&&(this.scale=s.SCALE.SECOND,this.step=5),a>t&&(this.scale=s.SCALE.SECOND,this.step=1),200*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=200),100*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=100),50*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=50),10*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=10),5*h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=5),h>t&&(this.scale=s.SCALE.MILLISECOND,this.step=1)}},s.prototype.snap=function(t){var e=new Date(t.valueOf());if(this.scale==s.SCALE.YEAR){var i=e.getFullYear()+Math.round(e.getMonth()/12);e.setFullYear(Math.round(i/this.step)*this.step),e.setMonth(0),e.setDate(0),e.setHours(0),e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.MONTH)e.getDate()>15?(e.setDate(1),e.setMonth(e.getMonth()+1)):e.setDate(1),e.setHours(0),e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0);else if(this.scale==s.SCALE.DAY){switch(this.step){case 5:case 2:e.setHours(24*Math.round(e.getHours()/24));break;default:e.setHours(12*Math.round(e.getHours()/12))}e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.WEEKDAY){switch(this.step){case 5:case 2:e.setHours(12*Math.round(e.getHours()/12));break;default:e.setHours(6*Math.round(e.getHours()/6))}e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.HOUR){switch(this.step){case 4:e.setMinutes(60*Math.round(e.getMinutes()/60));break;default:e.setMinutes(30*Math.round(e.getMinutes()/30))}e.setSeconds(0),e.setMilliseconds(0)}else if(this.scale==s.SCALE.MINUTE){switch(this.step){case 15:case 10:e.setMinutes(5*Math.round(e.getMinutes()/5)),e.setSeconds(0);break;case 5:e.setSeconds(60*Math.round(e.getSeconds()/60));break;default:e.setSeconds(30*Math.round(e.getSeconds()/30))}e.setMilliseconds(0)}else if(this.scale==s.SCALE.SECOND)switch(this.step){case 15:case 10:e.setSeconds(5*Math.round(e.getSeconds()/5)),e.setMilliseconds(0);break;case 5:e.setMilliseconds(1e3*Math.round(e.getMilliseconds()/1e3));break;default:e.setMilliseconds(500*Math.round(e.getMilliseconds()/500))}else if(this.scale==s.SCALE.MILLISECOND){var o=this.step>5?this.step/2:1;e.setMilliseconds(Math.round(e.getMilliseconds()/o)*o)}return e},s.prototype.isMajor=function(){if(1==this.switchedYear)switch(this.switchedYear=!1,this.scale){case s.SCALE.YEAR:case s.SCALE.MONTH:case s.SCALE.WEEKDAY:case s.SCALE.DAY:case s.SCALE.HOUR:case s.SCALE.MINUTE:case s.SCALE.SECOND:case s.SCALE.MILLISECOND:return!0;default:return!1}else if(1==this.switchedMonth)switch(this.switchedMonth=!1,this.scale){case s.SCALE.WEEKDAY:case s.SCALE.DAY:case s.SCALE.HOUR:case s.SCALE.MINUTE:case s.SCALE.SECOND:case s.SCALE.MILLISECOND:return!0;default:return!1}else if(1==this.switchedDay)switch(this.switchedDay=!1,this.scale){case s.SCALE.MILLISECOND:case s.SCALE.SECOND:case s.SCALE.MINUTE:case s.SCALE.HOUR:return!0;default:return!1}switch(this.scale){case s.SCALE.MILLISECOND:return 0==this.current.getMilliseconds();case s.SCALE.SECOND:return 0==this.current.getSeconds();case s.SCALE.MINUTE:return 0==this.current.getHours()&&0==this.current.getMinutes();case s.SCALE.HOUR:return 0==this.current.getHours();case s.SCALE.WEEKDAY:case s.SCALE.DAY:return 1==this.current.getDate();case s.SCALE.MONTH:return 0==this.current.getMonth();case s.SCALE.YEAR:return!1;default:return!1}},s.prototype.getLabelMinor=function(t){switch(void 0==t&&(t=this.current),this.scale){case s.SCALE.MILLISECOND:return o(t).format("SSS");case s.SCALE.SECOND:return o(t).format("s");case s.SCALE.MINUTE:return o(t).format("HH:mm");case s.SCALE.HOUR:return o(t).format("HH:mm");case s.SCALE.WEEKDAY:return o(t).format("ddd D");case s.SCALE.DAY:return o(t).format("D");case s.SCALE.MONTH:return o(t).format("MMM");case s.SCALE.YEAR:return o(t).format("YYYY");default:return""}},s.prototype.getLabelMajor=function(t){switch(void 0==t&&(t=this.current),this.scale){case s.SCALE.MILLISECOND:return o(t).format("HH:mm:ss");case s.SCALE.SECOND:return o(t).format("D MMMM HH:mm");case s.SCALE.MINUTE:case s.SCALE.HOUR:return o(t).format("ddd D MMMM");case s.SCALE.WEEKDAY:case s.SCALE.DAY:return o(t).format("MMMM YYYY");case s.SCALE.MONTH:return o(t).format("YYYY");case s.SCALE.YEAR:return"";default:return""}},t.exports=s},function(t){function e(){this.options=null,this.props=null}e.prototype.setOptions=function(t){t&&util.extend(this.options,t)},e.prototype.redraw=function(){return!1},e.prototype.destroy=function(){},e.prototype._isResized=function(){var t=this.props._previousWidth!==this.props.width||this.props._previousHeight!==this.props.height;return this.props._previousWidth=this.props.width,this.props._previousHeight=this.props.height,t},t.exports=e},function(t,e,i){function s(t,e){this.body=t,this.defaultOptions={showCurrentTime:!0,locales:a,locale:"en"},this.options=o.extend({},this.defaultOptions),this.offset=0,this._create(),this.setOptions(e)}var o=i(1),n=i(19),r=i(43),a=i(47);s.prototype=new n,s.prototype._create=function(){var t=document.createElement("div");t.className="currenttime",t.style.position="absolute",t.style.top="0px",t.style.height="100%",this.bar=t},s.prototype.destroy=function(){this.options.showCurrentTime=!1,this.redraw(),this.body=null},s.prototype.setOptions=function(t){t&&o.selectiveExtend(["showCurrentTime","locale","locales"],this.options,t)},s.prototype.redraw=function(){if(this.options.showCurrentTime){var t=this.body.dom.backgroundVertical;this.bar.parentNode!=t&&(this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar),t.appendChild(this.bar),this.start());var e=new Date((new Date).valueOf()+this.offset),i=this.body.util.toScreen(e),s=this.options.locales[this.options.locale],o=s.current+" "+s.time+": "+r(e).format("dddd, MMMM Do YYYY, H:mm:ss");o=o.charAt(0).toUpperCase()+o.substring(1),this.bar.style.left=i+"px",this.bar.title=o}else this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar),this.stop();return!1},s.prototype.start=function(){function t(){e.stop();var i=e.body.range.conversion(e.body.domProps.center.width).scale,s=1/i/10;30>s&&(s=30),s>1e3&&(s=1e3),e.redraw(),e.currentTimeTimer=setTimeout(t,s)}var e=this;t()},s.prototype.stop=function(){void 0!==this.currentTimeTimer&&(clearTimeout(this.currentTimeTimer),delete this.currentTimeTimer)},s.prototype.setCurrentTime=function(t){var e=o.convert(t,"Date").valueOf(),i=(new Date).valueOf();this.offset=e-i,this.redraw()},s.prototype.getCurrentTime=function(){return new Date((new Date).valueOf()+this.offset)},t.exports=s},function(t,e,i){function s(t,e){this.body=t,this.defaultOptions={showCustomTime:!1,locales:h,locale:"en"},this.options=n.extend({},this.defaultOptions),this.customTime=new Date,this.eventParams={},this._create(),this.setOptions(e)}var o=i(44),n=i(1),r=i(19),a=i(43),h=i(47);s.prototype=new r,s.prototype.setOptions=function(t){t&&n.selectiveExtend(["showCustomTime","locale","locales"],this.options,t)},s.prototype._create=function(){var t=document.createElement("div");t.className="customtime",t.style.position="absolute",t.style.top="0px",t.style.height="100%",this.bar=t;var e=document.createElement("div");e.style.position="relative",e.style.top="0px",e.style.left="-10px",e.style.height="100%",e.style.width="20px",t.appendChild(e),this.hammer=o(t,{prevent_default:!0}),this.hammer.on("dragstart",this._onDragStart.bind(this)),this.hammer.on("drag",this._onDrag.bind(this)),this.hammer.on("dragend",this._onDragEnd.bind(this))},s.prototype.destroy=function(){this.options.showCustomTime=!1,this.redraw(),this.hammer.enable(!1),this.hammer=null,this.body=null},s.prototype.redraw=function(){if(this.options.showCustomTime){var t=this.body.dom.backgroundVertical;this.bar.parentNode!=t&&(this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar),t.appendChild(this.bar));var e=this.body.util.toScreen(this.customTime),i=this.options.locales[this.options.locale],s=i.time+": "+a(this.customTime).format("dddd, MMMM Do YYYY, H:mm:ss");s=s.charAt(0).toUpperCase()+s.substring(1),this.bar.style.left=e+"px",this.bar.title=s}else this.bar.parentNode&&this.bar.parentNode.removeChild(this.bar);return!1},s.prototype.setCustomTime=function(t){this.customTime=n.convert(t,"Date"),this.redraw()},s.prototype.getCustomTime=function(){return new Date(this.customTime.valueOf())},s.prototype._onDragStart=function(t){this.eventParams.dragging=!0,this.eventParams.customTime=this.customTime,t.stopPropagation(),t.preventDefault()},s.prototype._onDrag=function(t){if(this.eventParams.dragging){var e=t.gesture.deltaX,i=this.body.util.toScreen(this.eventParams.customTime)+e,s=this.body.util.toTime(i);this.setCustomTime(s),this.body.emitter.emit("timechange",{time:new Date(this.customTime.valueOf())}),t.stopPropagation(),t.preventDefault()}},s.prototype._onDragEnd=function(t){this.eventParams.dragging&&(this.body.emitter.emit("timechanged",{time:new Date(this.customTime.valueOf())}),t.stopPropagation(),t.preventDefault())},t.exports=s},function(t,e,i){function s(t,e,i,s){this.id=o.randomUUID(),this.body=t,this.defaultOptions={orientation:"left",showMinorLabels:!0,showMajorLabels:!0,icons:!0,majorLinesOffset:7,minorLinesOffset:4,labelOffsetX:10,labelOffsetY:2,iconWidth:20,width:"40px",visible:!0,customRange:{left:{min:void 0,max:void 0},right:{min:void 0,max:void 0}}},this.linegraphOptions=s,this.linegraphSVG=i,this.props={},this.DOMelements={lines:{},labels:{}},this.dom={},this.range={start:0,end:0},this.options=o.extend({},this.defaultOptions),this.conversionFactor=1,this.setOptions(e),this.width=Number((""+this.options.width).replace("px","")),this.minWidth=this.width,this.height=this.linegraphSVG.offsetHeight,this.stepPixels=25,this.stepPixelsForced=25,this.lineOffset=0,this.master=!0,this.svgElements={},this.groups={},this.amountOfGroups=0,this._create()}var o=i(1),n=i(2),r=i(19),a=i(15);s.prototype=new r,s.prototype.addGroup=function(t,e){this.groups.hasOwnProperty(t)||(this.groups[t]=e),this.amountOfGroups+=1},s.prototype.updateGroup=function(t,e){this.groups[t]=e},s.prototype.removeGroup=function(t){this.groups.hasOwnProperty(t)&&(delete this.groups[t],this.amountOfGroups-=1)},s.prototype.setOptions=function(t){if(t){var e=!1;this.options.orientation!=t.orientation&&void 0!==t.orientation&&(e=!0);var i=["orientation","showMinorLabels","showMajorLabels","icons","majorLinesOffset","minorLinesOffset","labelOffsetX","labelOffsetY","iconWidth","width","visible","customRange"];o.selectiveExtend(i,this.options,t),this.minWidth=Number((""+this.options.width).replace("px","")),1==e&&this.dom.frame&&(this.hide(),this.show())}},s.prototype._create=function(){this.dom.frame=document.createElement("div"),this.dom.frame.style.width=this.options.width,this.dom.frame.style.height=this.height,this.dom.lineContainer=document.createElement("div"),this.dom.lineContainer.style.width="100%",this.dom.lineContainer.style.height=this.height,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0px",this.svg.style.height="100%",this.svg.style.width="100%",this.svg.style.display="block",this.dom.frame.appendChild(this.svg)},s.prototype._redrawGroupIcons=function(){n.prepareElements(this.svgElements);var t,e=this.options.iconWidth,i=15,s=4,o=s+.5*i;t="left"==this.options.orientation?s:this.width-e-s;for(var r in this.groups)this.groups.hasOwnProperty(r)&&(1!=this.groups[r].visible||void 0!==this.linegraphOptions.visibility[r]&&1!=this.linegraphOptions.visibility[r]||(this.groups[r].drawIcon(t,o,this.svgElements,this.svg,e,i),o+=i+s));n.cleanupElements(this.svgElements)},s.prototype.show=function(){this.dom.frame.parentNode||("left"==this.options.orientation?this.body.dom.left.appendChild(this.dom.frame):this.body.dom.right.appendChild(this.dom.frame)),this.dom.lineContainer.parentNode||this.body.dom.backgroundHorizontal.appendChild(this.dom.lineContainer)},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame),this.dom.lineContainer.parentNode&&this.dom.lineContainer.parentNode.removeChild(this.dom.lineContainer)},s.prototype.setRange=function(t,e){this.range.start=t,this.range.end=e},s.prototype.redraw=function(){var t=!1,e=0;for(var i in this.groups)this.groups.hasOwnProperty(i)&&(1!=this.groups[i].visible||void 0!==this.linegraphOptions.visibility[i]&&1!=this.linegraphOptions.visibility[i]||e++);if(0==this.amountOfGroups||0==e)this.hide();else{this.show(),this.height=Number(this.linegraphSVG.style.height.replace("px","")),this.dom.lineContainer.style.height=this.height+"px",this.width=1==this.options.visible?Number((""+this.options.width).replace("px","")):0;var s=this.props,o=this.dom.frame;o.className="dataaxis",this._calculateCharSize();var n=this.options.orientation,r=this.options.showMinorLabels,a=this.options.showMajorLabels;s.minorLabelHeight=r?s.minorCharHeight:0,s.majorLabelHeight=a?s.majorCharHeight:0,s.minorLineWidth=this.body.dom.backgroundHorizontal.offsetWidth-this.lineOffset-this.width+2*this.options.minorLinesOffset,s.minorLineHeight=1,s.majorLineWidth=this.body.dom.backgroundHorizontal.offsetWidth-this.lineOffset-this.width+2*this.options.majorLinesOffset,s.majorLineHeight=1,"left"==n?(o.style.top="0",o.style.left="0",o.style.bottom="",o.style.width=this.width+"px",o.style.height=this.height+"px"):(o.style.top="",o.style.bottom="0",o.style.left="0",o.style.width=this.width+"px",o.style.height=this.height+"px"),t=this._redrawLabels(),1==this.options.icons&&this._redrawGroupIcons()}return t},s.prototype._redrawLabels=function(){n.prepareElements(this.DOMelements.lines),n.prepareElements(this.DOMelements.labels);var t=this.options.orientation,e=this.master?this.props.majorCharHeight||10:this.stepPixelsForced,i=new a(this.range.start,this.range.end,e,this.dom.frame.offsetHeight,this.options.customRange[this.options.orientation]);this.step=i;var s=(this.dom.frame.offsetHeight-i.deadSpace*(this.dom.frame.offsetHeight/i.marginRange))/((i.marginRange-i.deadSpace)/i.step);this.stepPixels=s;var o=this.height/s,r=0;if(0==this.master){s=this.stepPixelsForced,r=Math.round(this.dom.frame.offsetHeight/s-o);for(var h=0;.5*r>h;h++)i.previous();o=this.height/s}else o+=.25;this.valueAtZero=i.marginEnd;var d=0,l=1;this.maxLabelSize=0;for(var c=0;l=0&&this._redrawLabel(c-2,i.getCurrent(),t,"yAxis major",this.props.majorCharHeight),this._redrawLine(c,t,"grid horizontal major",this.options.majorLinesOffset,this.props.majorLineWidth)):this._redrawLine(c,t,"grid horizontal minor",this.options.minorLinesOffset,this.props.minorLineWidth),l++}this.conversionFactor=0==this.master?c/(this.valueAtZero-i.current):this.dom.frame.offsetHeight/i.marginRange;var u=1==this.options.icons?this.options.iconWidth+this.options.labelOffsetX+15:this.options.labelOffsetX+15;return this.maxLabelSize>this.width-u&&1==this.options.visible?(this.width=this.maxLabelSize+u,this.options.width=this.width+"px",n.cleanupElements(this.DOMelements.lines),n.cleanupElements(this.DOMelements.labels),this.redraw(),!0):this.maxLabelSizethis.minWidth?(this.width=Math.max(this.minWidth,this.maxLabelSize+u),this.options.width=this.width+"px",n.cleanupElements(this.DOMelements.lines),n.cleanupElements(this.DOMelements.labels),this.redraw(),!0):(n.cleanupElements(this.DOMelements.lines),n.cleanupElements(this.DOMelements.labels),!1)},s.prototype.convertValue=function(t){var e=this.valueAtZero-t,i=e*this.conversionFactor;return i},s.prototype._redrawLabel=function(t,e,i,s,o){var r=n.getDOMElement("div",this.DOMelements.labels,this.dom.frame);r.className=s,r.innerHTML=e,"left"==i?(r.style.left="-"+this.options.labelOffsetX+"px",r.style.textAlign="right"):(r.style.right="-"+this.options.labelOffsetX+"px",r.style.textAlign="left"),r.style.top=t-.5*o+this.options.labelOffsetY+"px",e+="";var a=Math.max(this.props.majorCharWidth,this.props.minorCharWidth);this.maxLabelSized;d++){var c=this.visibleItems[d];c.repositionY(e)}return s},s.prototype._calculateHeight=function(t){var e,i=this.visibleItems;this.resetSubgroups();var s=this;if(i.length){var n=i[0].top,r=i[0].top+i[0].height;if(o.forEach(i,function(t){n=Math.min(n,t.top),r=Math.max(r,t.top+t.height),void 0!==t.data.subgroup&&(s.subgroups[t.data.subgroup].height=Math.max(s.subgroups[t.data.subgroup].height,t.height),s.subgroups[t.data.subgroup].visible=!0)}),n>t.axis){var a=n-t.axis;r-=a,o.forEach(i,function(t){t.top-=a})}e=r+t.item.vertical/2}else e=t.axis+t.item.vertical;return e=Math.max(e,this.props.label.height)},s.prototype.show=function(){this.dom.label.parentNode||this.itemSet.dom.labelSet.appendChild(this.dom.label),this.dom.foreground.parentNode||this.itemSet.dom.foreground.appendChild(this.dom.foreground),this.dom.background.parentNode||this.itemSet.dom.background.appendChild(this.dom.background),this.dom.axis.parentNode||this.itemSet.dom.axis.appendChild(this.dom.axis)},s.prototype.hide=function(){var t=this.dom.label;t.parentNode&&t.parentNode.removeChild(t);var e=this.dom.foreground;e.parentNode&&e.parentNode.removeChild(e);var i=this.dom.background;i.parentNode&&i.parentNode.removeChild(i);var s=this.dom.axis;s.parentNode&&s.parentNode.removeChild(s)},s.prototype.add=function(t){if(this.items[t.id]=t,t.setParent(this),void 0!==t.data.subgroup&&(void 0===this.subgroups[t.data.subgroup]&&(this.subgroups[t.data.subgroup]={height:0,visible:!1,index:this.subgroupIndex,items:[]},this.subgroupIndex++),this.subgroups[t.data.subgroup].items.push(t)),this.orderSubgroups(),-1==this.visibleItems.indexOf(t)){var e=this.itemSet.body.range;this._checkIfVisible(t,this.visibleItems,e)}},s.prototype.orderSubgroups=function(){if(void 0!==this.subgroupOrderer){var t=[];if("string"==typeof this.subgroupOrderer){for(var e in this.subgroups)t.push({subgroup:e,sortField:this.subgroups[e].items[0].data[this.subgroupOrderer]});t.sort(function(t,e){return t.sortField-e.sortField})}else if("function"==typeof this.subgroupOrderer){for(var e in this.subgroups)t.push(this.subgroups[e].items[0].data);t.sort(this.subgroupOrderer)}if(t.length>0)for(var i=0;i0)for(n=0;n=0&&!this._checkIfInvisible(t.byStart[n],r,i);n--);for(n=s+1;n=0&&!this._checkIfInvisible(t.byEnd[n],r,i);n--);for(n=a+1;ns;s++){var n=this.visibleItems[s];n.repositionY(e)}return i},s.prototype.show=function(){this.dom.background.parentNode||this.itemSet.dom.background.appendChild(this.dom.background)},t.exports=s},function(t,e,i){function s(t,e){this.body=t,this.defaultOptions={type:null,orientation:"bottom",align:"auto",stack:!0,groupOrder:null,selectable:!0,editable:{updateTime:!1,updateGroup:!1,add:!1,remove:!1},onAdd:function(t,e){e(t)},onUpdate:function(t,e){e(t)},onMove:function(t,e){e(t)},onRemove:function(t,e){e(t)},onMoving:function(t,e){e(t)},margin:{item:{horizontal:10,vertical:10},axis:20},padding:5},this.options=n.extend({},this.defaultOptions),this.itemOptions={type:{start:"Date",end:"Date"}},this.conversion={toScreen:t.util.toScreen,toTime:t.util.toTime},this.dom={},this.props={},this.hammer=null;var i=this;this.itemsData=null,this.groupsData=null,this.itemListeners={add:function(t,e){i._onAdd(e.items)},update:function(t,e){i._onUpdate(e.items)},remove:function(t,e){i._onRemove(e.items)}},this.groupListeners={add:function(t,e){i._onAddGroups(e.items)},update:function(t,e){i._onUpdateGroups(e.items)},remove:function(t,e){i._onRemoveGroups(e.items)}},this.items={},this.groups={},this.groupIds=[],this.selection=[],this.stackDirty=!0,this.touchParams={},this._create(),this.setOptions(e)}var o=i(44),n=i(1),r=i(3),a=i(4),h=i(19),d=i(24),l=i(25),c=i(32),p=i(33),u=i(34),f=i(31),m="__ungrouped__",g="__background__";s.prototype=new h,s.types={background:f,box:c,range:u,point:p},s.prototype._create=function(){var t=document.createElement("div");t.className="itemset",t["timeline-itemset"]=this,this.dom.frame=t;var e=document.createElement("div");e.className="background",t.appendChild(e),this.dom.background=e;var i=document.createElement("div");i.className="foreground",t.appendChild(i),this.dom.foreground=i;var s=document.createElement("div");s.className="axis",this.dom.axis=s;var n=document.createElement("div");n.className="labelset",this.dom.labelSet=n,this._updateUngrouped();var r=new l(g,null,this);r.show(),this.groups[g]=r,this.hammer=o(this.body.dom.centerContainer,{prevent_default:!0}),this.hammer.on("touch",this._onTouch.bind(this)),this.hammer.on("dragstart",this._onDragStart.bind(this)),this.hammer.on("drag",this._onDrag.bind(this)),this.hammer.on("dragend",this._onDragEnd.bind(this)),this.hammer.on("tap",this._onSelectItem.bind(this)),this.hammer.on("hold",this._onMultiSelectItem.bind(this)),this.hammer.on("doubletap",this._onAddItem.bind(this)),this.show()},s.prototype.setOptions=function(t){if(t){var e=["type","align","orientation","padding","stack","selectable","groupOrder","dataAttributes","template","hide"];n.selectiveExtend(e,this.options,t),"margin"in t&&("number"==typeof t.margin?(this.options.margin.axis=t.margin,this.options.margin.item.horizontal=t.margin,this.options.margin.item.vertical=t.margin):"object"==typeof t.margin&&(n.selectiveExtend(["axis"],this.options.margin,t.margin),"item"in t.margin&&("number"==typeof t.margin.item?(this.options.margin.item.horizontal=t.margin.item,this.options.margin.item.vertical=t.margin.item):"object"==typeof t.margin.item&&n.selectiveExtend(["horizontal","vertical"],this.options.margin.item,t.margin.item)))),"editable"in t&&("boolean"==typeof t.editable?(this.options.editable.updateTime=t.editable,this.options.editable.updateGroup=t.editable,this.options.editable.add=t.editable,this.options.editable.remove=t.editable):"object"==typeof t.editable&&n.selectiveExtend(["updateTime","updateGroup","add","remove"],this.options.editable,t.editable)); +var i=function(e){var i=t[e];if(i){if(!(i instanceof Function))throw new Error("option "+e+" must be a function "+e+"(item, callback)");this.options[e]=i}}.bind(this);["onAdd","onUpdate","onRemove","onMove","onMoving"].forEach(i),this.markDirty()}},s.prototype.markDirty=function(){this.groupIds=[],this.stackDirty=!0},s.prototype.destroy=function(){this.hide(),this.setItems(null),this.setGroups(null),this.hammer=null,this.body=null,this.conversion=null},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame),this.dom.axis.parentNode&&this.dom.axis.parentNode.removeChild(this.dom.axis),this.dom.labelSet.parentNode&&this.dom.labelSet.parentNode.removeChild(this.dom.labelSet)},s.prototype.show=function(){this.dom.frame.parentNode||this.body.dom.center.appendChild(this.dom.frame),this.dom.axis.parentNode||this.body.dom.backgroundVertical.appendChild(this.dom.axis),this.dom.labelSet.parentNode||this.body.dom.left.appendChild(this.dom.labelSet)},s.prototype.setSelection=function(t){var e,i,s,o;for(void 0==t&&(t=[]),Array.isArray(t)||(t=[t]),e=0,i=this.selection.length;i>e;e++)s=this.selection[e],o=this.items[s],o&&o.unselect();for(this.selection=[],e=0,i=t.length;i>e;e++)s=t[e],o=this.items[s],o&&(this.selection.push(s),o.select())},s.prototype.getSelection=function(){return this.selection.concat([])},s.prototype.getVisibleItems=function(){var t=this.body.range.getRange(),e=this.body.util.toScreen(t.start),i=this.body.util.toScreen(t.end),s=[];for(var o in this.groups)if(this.groups.hasOwnProperty(o))for(var n=this.groups[o],r=n.visibleItems,a=0;ae&&s.push(h.id)}return s},s.prototype._deselect=function(t){for(var e=this.selection,i=0,s=e.length;s>i;i++)if(e[i]==t){e.splice(i,1);break}},s.prototype.redraw=function(){var t=this.options.margin,e=this.body.range,i=n.option.asSize,s=this.options,o=s.orientation,r=!1,a=this.dom.frame,h=s.editable.updateTime||s.editable.updateGroup;this.props.top=this.body.domProps.top.height+this.body.domProps.border.top,this.props.left=this.body.domProps.left.width+this.body.domProps.border.left,a.className="itemset"+(h?" editable":""),r=this._orderGroups()||r;var d=e.end-e.start,l=d!=this.lastVisibleInterval||this.props.width!=this.props.lastWidth;l&&(this.stackDirty=!0),this.lastVisibleInterval=d,this.props.lastWidth=this.props.width;var c=this.stackDirty,p=this._firstGroup(),u={item:t.item,axis:t.axis},f={item:t.item,axis:t.item.vertical/2},m=0,v=t.axis+t.item.vertical;return this.groups[g].redraw(e,f,c),n.forEach(this.groups,function(t){var i=t==p?u:f,s=t.redraw(e,i,c);r=s||r,m+=t.height}),m=Math.max(m,v),this.stackDirty=!1,a.style.height=i(m),this.props.width=a.offsetWidth,this.props.height=m,this.dom.axis.style.top=i("top"==o?this.body.domProps.top.height+this.body.domProps.border.top:this.body.domProps.top.height+this.body.domProps.centerContainer.height),this.dom.axis.style.left="0",r=this._isResized()||r},s.prototype._firstGroup=function(){var t="top"==this.options.orientation?0:this.groupIds.length-1,e=this.groupIds[t],i=this.groups[e]||this.groups[m];return i||null},s.prototype._updateUngrouped=function(){{var t,e,i=this.groups[m];this.groups[g]}if(this.groupsData){if(i){i.hide(),delete this.groups[m];for(e in this.items)if(this.items.hasOwnProperty(e)){t=this.items[e],t.parent&&t.parent.remove(t);var s=this._getGroupId(t.data),o=this.groups[s];o&&o.add(t)||t.hide()}}}else if(!i){var n=null,r=null;i=new d(n,r,this),this.groups[m]=i;for(e in this.items)this.items.hasOwnProperty(e)&&(t=this.items[e],i.add(t));i.show()}},s.prototype.getLabelSet=function(){return this.dom.labelSet},s.prototype.setItems=function(t){var e,i=this,s=this.itemsData;if(t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.itemsData=t}else this.itemsData=null;if(s&&(n.forEach(this.itemListeners,function(t,e){s.off(e,t)}),e=s.getIds(),this._onRemove(e)),this.itemsData){var o=this.id;n.forEach(this.itemListeners,function(t,e){i.itemsData.on(e,t,o)}),e=this.itemsData.getIds(),this._onAdd(e),this._updateUngrouped()}},s.prototype.getItems=function(){return this.itemsData},s.prototype.setGroups=function(t){var e,i=this;if(this.groupsData&&(n.forEach(this.groupListeners,function(t,e){i.groupsData.unsubscribe(e,t)}),e=this.groupsData.getIds(),this.groupsData=null,this._onRemoveGroups(e)),t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.groupsData=t}else this.groupsData=null;if(this.groupsData){var s=this.id;n.forEach(this.groupListeners,function(t,e){i.groupsData.on(e,t,s)}),e=this.groupsData.getIds(),this._onAddGroups(e)}this._updateUngrouped(),this._order(),this.body.emitter.emit("change")},s.prototype.getGroups=function(){return this.groupsData},s.prototype.removeItem=function(t){var e=this.itemsData.get(t),i=this.itemsData.getDataSet();e&&this.options.onRemove(e,function(e){e&&i.remove(t)})},s.prototype._getType=function(t){return t.type||this.options.type||(t.end?"range":"box")},s.prototype._getGroupId=function(t){var e=this._getType(t);return"background"==e&&void 0==t.group?g:this.groupsData?t.group:m},s.prototype._onUpdate=function(t){var e=this;t.forEach(function(t){var i=e.itemsData.get(t,e.itemOptions),o=e.items[t],n=e._getType(i),r=s.types[n];if(o&&(r&&o instanceof r?e._updateItem(o,i):(e._removeItem(o),o=null)),!o){if(!r)throw new TypeError("rangeoverflow"==n?'Item type "rangeoverflow" is deprecated. Use css styling instead: .vis.timeline .item.range .content {overflow: visible;}':'Unknown item type "'+n+'"');o=new r(i,e.conversion,e.options),o.id=t,e._addItem(o)}}),this._order(),this.stackDirty=!0,this.body.emitter.emit("change")},s.prototype._onAdd=s.prototype._onUpdate,s.prototype._onRemove=function(t){var e=0,i=this;t.forEach(function(t){var s=i.items[t];s&&(e++,i._removeItem(s))}),e&&(this._order(),this.stackDirty=!0,this.body.emitter.emit("change"))},s.prototype._order=function(){n.forEach(this.groups,function(t){t.order()})},s.prototype._onUpdateGroups=function(t){this._onAddGroups(t)},s.prototype._onAddGroups=function(t){var e=this;t.forEach(function(t){var i=e.groupsData.get(t),s=e.groups[t];if(s)s.setData(i);else{if(t==m||t==g)throw new Error("Illegal group id. "+t+" is a reserved id.");var o=Object.create(e.options);n.extend(o,{height:null}),s=new d(t,i,e),e.groups[t]=s;for(var r in e.items)if(e.items.hasOwnProperty(r)){var a=e.items[r];a.data.group==t&&s.add(a)}s.order(),s.show()}}),this.body.emitter.emit("change")},s.prototype._onRemoveGroups=function(t){var e=this.groups;t.forEach(function(t){var i=e[t];i&&(i.hide(),delete e[t])}),this.markDirty(),this.body.emitter.emit("change")},s.prototype._orderGroups=function(){if(this.groupsData){var t=this.groupsData.getIds({order:this.options.groupOrder}),e=!n.equalArray(t,this.groupIds);if(e){var i=this.groups;t.forEach(function(t){i[t].hide()}),t.forEach(function(t){i[t].show()}),this.groupIds=t}return e}return!1},s.prototype._addItem=function(t){this.items[t.id]=t;var e=this._getGroupId(t.data),i=this.groups[e];i&&i.add(t)},s.prototype._updateItem=function(t,e){var i=t.data.group;if(t.setData(e),i!=t.data.group){var s=this.groups[i];s&&s.remove(t);var o=this._getGroupId(t.data),n=this.groups[o];n&&n.add(t)}},s.prototype._removeItem=function(t){t.hide(),delete this.items[t.id];var e=this.selection.indexOf(t.id);-1!=e&&this.selection.splice(e,1),t.parent&&t.parent.remove(t)},s.prototype._constructByEndArray=function(t){for(var e=[],i=0;i0||o.length>0)&&this.body.emitter.emit("select",{items:this.getSelection()})}},s.prototype._onAddItem=function(t){if(this.options.selectable&&this.options.editable.add){var e=this,i=this.body.util.snap||null,o=s.itemFromTarget(t);if(o){var r=e.itemsData.get(o.id);this.options.onUpdate(r,function(t){t&&e.itemsData.update(t)})}else{var a=n.getAbsoluteLeft(this.dom.frame),h=t.gesture.center.pageX-a,d=this.body.util.toTime(h),l={start:i?i(d):d,content:"new item"};if("range"===this.options.type){var c=this.body.util.toTime(h+this.props.width/5);l.end=i?i(c):c}l[this.itemsData._fieldId]=n.randomUUID();var p=s.groupFromTarget(t);p&&(l.group=p.groupId),this.options.onAdd(l,function(t){t&&e.itemsData.add(t)})}}},s.prototype._onMultiSelectItem=function(t){if(this.options.selectable){var e,i=s.itemFromTarget(t);if(i){e=this.getSelection();var o=e.indexOf(i.id);-1==o?e.push(i.id):e.splice(o,1),this.setSelection(e),this.body.emitter.emit("select",{items:this.getSelection()})}}},s.itemFromTarget=function(t){for(var e=t.target;e;){if(e.hasOwnProperty("timeline-item"))return e["timeline-item"];e=e.parentNode}return null},s.groupFromTarget=function(t){for(var e=t.target;e;){if(e.hasOwnProperty("timeline-group"))return e["timeline-group"];e=e.parentNode}return null},s.itemSetFromTarget=function(t){for(var e=t.target;e;){if(e.hasOwnProperty("timeline-itemset"))return e["timeline-itemset"];e=e.parentNode}return null},t.exports=s},function(t,e,i){function s(t,e,i,s){this.body=t,this.defaultOptions={enabled:!0,icons:!0,iconSize:20,iconSpacing:6,left:{visible:!0,position:"top-left"},right:{visible:!0,position:"top-left"}},this.side=i,this.options=o.extend({},this.defaultOptions),this.linegraphOptions=s,this.svgElements={},this.dom={},this.groups={},this.amountOfGroups=0,this._create(),this.setOptions(e)}var o=i(1),n=i(2),r=i(19);s.prototype=new r,s.prototype.addGroup=function(t,e){this.groups.hasOwnProperty(t)||(this.groups[t]=e),this.amountOfGroups+=1},s.prototype.updateGroup=function(t,e){this.groups[t]=e},s.prototype.removeGroup=function(t){this.groups.hasOwnProperty(t)&&(delete this.groups[t],this.amountOfGroups-=1)},s.prototype._create=function(){this.dom.frame=document.createElement("div"),this.dom.frame.className="legend",this.dom.frame.style.position="absolute",this.dom.frame.style.top="10px",this.dom.frame.style.display="block",this.dom.textArea=document.createElement("div"),this.dom.textArea.className="legendText",this.dom.textArea.style.position="relative",this.dom.textArea.style.top="0px",this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0px",this.svg.style.width=this.options.iconSize+5+"px",this.svg.style.height="100%",this.dom.frame.appendChild(this.svg),this.dom.frame.appendChild(this.dom.textArea)},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame)},s.prototype.show=function(){this.dom.frame.parentNode||this.body.dom.center.appendChild(this.dom.frame)},s.prototype.setOptions=function(t){var e=["enabled","orientation","icons","left","right"];o.selectiveDeepExtend(e,this.options,t)},s.prototype.redraw=function(){var t=0;for(var e in this.groups)this.groups.hasOwnProperty(e)&&(1!=this.groups[e].visible||void 0!==this.linegraphOptions.visibility[e]&&1!=this.linegraphOptions.visibility[e]||t++);if(0==this.options[this.side].visible||0==this.amountOfGroups||0==this.options.enabled||0==t)this.hide();else{this.show(),"top-left"==this.options[this.side].position||"bottom-left"==this.options[this.side].position?(this.dom.frame.style.left="4px",this.dom.frame.style.textAlign="left",this.dom.textArea.style.textAlign="left",this.dom.textArea.style.left=this.options.iconSize+15+"px",this.dom.textArea.style.right="",this.svg.style.left="0px",this.svg.style.right=""):(this.dom.frame.style.right="4px",this.dom.frame.style.textAlign="right",this.dom.textArea.style.textAlign="right",this.dom.textArea.style.right=this.options.iconSize+15+"px",this.dom.textArea.style.left="",this.svg.style.right="0px",this.svg.style.left=""),"top-left"==this.options[this.side].position||"top-right"==this.options[this.side].position?(this.dom.frame.style.top=4-Number(this.body.dom.center.style.top.replace("px",""))+"px",this.dom.frame.style.bottom=""):(this.dom.frame.style.bottom=4-Number(this.body.dom.center.style.top.replace("px",""))+"px",this.dom.frame.style.top=""),0==this.options.icons?(this.dom.frame.style.width=this.dom.textArea.offsetWidth+10+"px",this.dom.textArea.style.right="",this.dom.textArea.style.left="",this.svg.style.width="0px"):(this.dom.frame.style.width=this.options.iconSize+15+this.dom.textArea.offsetWidth+10+"px",this.drawLegendIcons());var i="";for(var e in this.groups)this.groups.hasOwnProperty(e)&&(1!=this.groups[e].visible||void 0!==this.linegraphOptions.visibility[e]&&1!=this.linegraphOptions.visibility[e]||(i+=this.groups[e].content+"
"));this.dom.textArea.innerHTML=i,this.dom.textArea.style.lineHeight=.75*this.options.iconSize+this.options.iconSpacing+"px"}},s.prototype.drawLegendIcons=function(){if(this.dom.frame.parentNode){n.prepareElements(this.svgElements);var t=window.getComputedStyle(this.dom.frame).paddingTop,e=Number(t.replace("px","")),i=e,s=this.options.iconSize,o=.75*this.options.iconSize,r=e+.5*o+3;this.svg.style.width=s+5+e+"px";for(var a in this.groups)this.groups.hasOwnProperty(a)&&(1!=this.groups[a].visible||void 0!==this.linegraphOptions.visibility[a]&&1!=this.linegraphOptions.visibility[a]||(this.groups[a].drawIcon(i,r,this.svgElements,this.svg,s,o),r+=o+this.options.iconSpacing));n.cleanupElements(this.svgElements)}},t.exports=s},function(t,e,i){function s(t,e){this.id=o.randomUUID(),this.body=t,this.defaultOptions={yAxisOrientation:"left",defaultGroup:"default",sort:!0,sampling:!0,graphHeight:"400px",shaded:{enabled:!1,orientation:"bottom"},style:"line",barChart:{width:50,handleOverlap:"overlap",align:"center"},catmullRom:{enabled:!0,parametrization:"centripetal",alpha:.5},drawPoints:{enabled:!0,size:6,style:"square"},dataAxis:{showMinorLabels:!0,showMajorLabels:!0,icons:!1,width:"40px",visible:!0,customRange:{left:{min:void 0,max:void 0},right:{min:void 0,max:void 0}}},legend:{enabled:!1,icons:!0,left:{visible:!0,position:"top-left"},right:{visible:!0,position:"top-right"}},groups:{visibility:{}}},this.options=o.extend({},this.defaultOptions),this.dom={},this.props={},this.hammer=null,this.groups={},this.abortedGraphUpdate=!1;var i=this;this.itemsData=null,this.groupsData=null,this.itemListeners={add:function(t,e){i._onAdd(e.items)},update:function(t,e){i._onUpdate(e.items)},remove:function(t,e){i._onRemove(e.items)}},this.groupListeners={add:function(t,e){i._onAddGroups(e.items)},update:function(t,e){i._onUpdateGroups(e.items)},remove:function(t,e){i._onRemoveGroups(e.items)}},this.items={},this.selection=[],this.lastStart=this.body.range.start,this.touchParams={},this.svgElements={},this.setOptions(e),this.groupsUsingDefaultStyles=[0],this.body.emitter.on("rangechanged",function(){i.lastStart=i.body.range.start,i.svg.style.left=o.option.asSize(-i.width),i._updateGraph.apply(i)}),this._create(),this.body.emitter.emit("change")}var o=i(1),n=i(2),r=i(3),a=i(4),h=i(19),d=i(22),l=i(23),c=i(27),p="__ungrouped__";s.prototype=new h,s.prototype._create=function(){var t=document.createElement("div");t.className="LineGraph",this.dom.frame=t,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="relative",this.svg.style.height=(""+this.options.graphHeight).replace("px","")+"px",this.svg.style.display="block",t.appendChild(this.svg),this.options.dataAxis.orientation="left",this.yAxisLeft=new d(this.body,this.options.dataAxis,this.svg,this.options.groups),this.options.dataAxis.orientation="right",this.yAxisRight=new d(this.body,this.options.dataAxis,this.svg,this.options.groups),delete this.options.dataAxis.orientation,this.legendLeft=new c(this.body,this.options.legend,"left",this.options.groups),this.legendRight=new c(this.body,this.options.legend,"right",this.options.groups),this.show()},s.prototype.setOptions=function(t){if(t){var e=["sampling","defaultGroup","graphHeight","yAxisOrientation","style","barChart","dataAxis","sort","groups"];o.selectiveDeepExtend(e,this.options,t),o.mergeOptions(this.options,t,"catmullRom"),o.mergeOptions(this.options,t,"drawPoints"),o.mergeOptions(this.options,t,"shaded"),o.mergeOptions(this.options,t,"legend"),t.catmullRom&&"object"==typeof t.catmullRom&&t.catmullRom.parametrization&&("uniform"==t.catmullRom.parametrization?this.options.catmullRom.alpha=0:"chordal"==t.catmullRom.parametrization?this.options.catmullRom.alpha=1:(this.options.catmullRom.parametrization="centripetal",this.options.catmullRom.alpha=.5)),this.yAxisLeft&&void 0!==t.dataAxis&&(this.yAxisLeft.setOptions(this.options.dataAxis),this.yAxisRight.setOptions(this.options.dataAxis)),this.legendLeft&&void 0!==t.legend&&(this.legendLeft.setOptions(this.options.legend),this.legendRight.setOptions(this.options.legend)),this.groups.hasOwnProperty(p)&&this.groups[p].setOptions(t)}this.dom.frame&&this._updateGraph()},s.prototype.hide=function(){this.dom.frame.parentNode&&this.dom.frame.parentNode.removeChild(this.dom.frame)},s.prototype.show=function(){this.dom.frame.parentNode||this.body.dom.center.appendChild(this.dom.frame)},s.prototype.setItems=function(t){var e,i=this,s=this.itemsData;if(t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.itemsData=t}else this.itemsData=null;if(s&&(o.forEach(this.itemListeners,function(t,e){s.off(e,t)}),e=s.getIds(),this._onRemove(e)),this.itemsData){var n=this.id;o.forEach(this.itemListeners,function(t,e){i.itemsData.on(e,t,n)}),e=this.itemsData.getIds(),this._onAdd(e)}this._updateUngrouped(),this._updateGraph(),this.redraw()},s.prototype.setGroups=function(t){var e,i=this;if(this.groupsData&&(o.forEach(this.groupListeners,function(t,e){i.groupsData.unsubscribe(e,t)}),e=this.groupsData.getIds(),this.groupsData=null,this._onRemoveGroups(e)),t){if(!(t instanceof r||t instanceof a))throw new TypeError("Data must be an instance of DataSet or DataView");this.groupsData=t}else this.groupsData=null;if(this.groupsData){var s=this.id;o.forEach(this.groupListeners,function(t,e){i.groupsData.on(e,t,s)}),e=this.groupsData.getIds(),this._onAddGroups(e)}this._onUpdate()},s.prototype._onUpdate=function(){this._updateUngrouped(),this._updateAllGroupData(),this._updateGraph(),this.redraw()},s.prototype._onAdd=function(t){this._onUpdate(t)},s.prototype._onRemove=function(t){this._onUpdate(t)},s.prototype._onUpdateGroups=function(t){for(var e=0;e0){var d=this.body.util.toGlobalTime(-this.body.domProps.root.width),l=this.body.util.toGlobalTime(2*this.body.domProps.root.width),c={};for(this._getRelevantData(a,c,d,l),e=0;e0)for(r=0;rs){d.push(h);break}d.push(h)}}else for(a=0;ai&&h.x0)for(var s=0;s0){var n=1,r=o.length,a=this.body.util.toGlobalScreen(o[o.length-1].x)-this.body.util.toGlobalScreen(o[0].x),h=r/a;n=Math.min(Math.ceil(.2*r),Math.max(1,Math.round(h)));for(var d=[],l=0;r>l;l+=n)d.push(o[l]);e[t[s]]=d}}},s.prototype._getYRanges=function(t,e,i){var s,o,n,r,a,h=[],d=[];if(t.length>0){for(n=0;n0)if(o=this.groups[t[n]],"line"==o.options.style||"stack"!=o.options.barChart.handleOverlap){var l=s[0].y,c=s[0].y;for(r=0;rs[r].y?s[r].y:l,c=c0&&(h.sort(function(t,e){return t.x==e.x?t.groupId-e.groupId:t.x-e.x}),p={},this._getDataIntersections(p,h),i.__barchartLeft=this._getStackedBarYRange(p,h),i.__barchartLeft.yAxisOrientation="left",t.push("__barchartLeft")),d.length>0&&(d.sort(function(t,e){return t.x==e.x?t.groupId-e.groupId:t.x-e.x}),p={},this._getDataIntersections(p,d),i.__barchartRight=this._getStackedBarYRange(p,d),i.__barchartRight.yAxisOrientation="right",t.push("__barchartRight"))}},s.prototype._getStackedBarYRange=function(t,e){for(var i,s=e[0].y,o=e[0].y,n=0;ne[n].y?e[n].y:s,o=ot[r].accumulated?t[r].accumulated:s,o=o0){for(var c=0;ci?i:a,d=s>d?s:d):(r=!0,h=h>i?i:h,l=s>l?s:l));1==n&&this.yAxisLeft.setRange(a,d),1==r&&this.yAxisRight.setRange(h,l)}return o=this._toggleAxisVisiblity(n,this.yAxisLeft)||o,o=this._toggleAxisVisiblity(r,this.yAxisRight)||o,1==r&&1==n?(this.yAxisLeft.drawIcons=!0,this.yAxisRight.drawIcons=!0):(this.yAxisLeft.drawIcons=!1,this.yAxisRight.drawIcons=!1),this.yAxisRight.master=!n,0==this.yAxisRight.master?(this.yAxisLeft.lineOffset=1==r?this.yAxisRight.width:0,o=this.yAxisLeft.redraw()||o,this.yAxisRight.stepPixelsForced=this.yAxisLeft.stepPixels,o=this.yAxisRight.redraw()||o):o=this.yAxisRight.redraw()||o,-1!=t.indexOf("__barchartLeft")&&t.splice(t.indexOf("__barchartLeft"),1),-1!=t.indexOf("__barchartRight")&&t.splice(t.indexOf("__barchartRight"),1),o},s.prototype._toggleAxisVisiblity=function(t,e){var i=!1;return 0==t?e.dom.frame.parentNode&&(e.hide(),i=!0):e.dom.frame.parentNode||(e.show(),i=!0),i},s.prototype._drawBarGraphs=function(t,e){var i,s,o,r,a,h,d=[],l={},c=0;for(a=0;a0&&(i=Math.min(i,Math.abs(d[a-1].x-s))),o=this._getSafeDrawData(i,r,p);else{var f=a+(l[s].amount-l[s].resolved),m=a-(l[s].resolved+1);f0&&(i=Math.min(i,Math.abs(d[m].x-s))),o=this._getSafeDrawData(i,r,p),l[s].resolved+=1,"stack"==r.options.barChart.handleOverlap?(u=l[s].accumulated,l[s].accumulated+=r.zeroPosition-d[a].y):"sideBySide"==r.options.barChart.handleOverlap&&(o.width=o.width/l[s].amount,o.offset+=l[s].resolved*o.width-.5*o.width*(l[s].amount+1),"left"==r.options.barChart.align?o.offset-=.5*o.width:"right"==r.options.barChart.align&&(o.offset+=.5*o.width))}n.drawBar(d[a].x+o.offset,d[a].y-u,o.width,r.zeroPosition-d[a].y,r.className+" bar",this.svgElements,this.svg),1==r.options.drawPoints.enabled&&n.drawPoint(d[a].x+o.offset,d[a].y-u,r,this.svgElements,this.svg)}},s.prototype._getDataIntersections=function(t,e){for(var i,s=0;s0&&(i=Math.min(i,Math.abs(e[s-1].x-e[s].x))),0==i&&(void 0===t[e[s].x]&&(t[e[s].x]={amount:0,resolved:0,accumulated:0}),t[e[s].x].amount+=1)},s.prototype._getSafeDrawData=function(t,e,i){var s,o;return t0?(s=i>t?i:t,o=0,"left"==e.options.barChart.align?o-=.5*t:"right"==e.options.barChart.align&&(o+=.5*t)):(s=e.options.barChart.width,o=0,"left"==e.options.barChart.align?o-=.5*e.options.barChart.width:"right"==e.options.barChart.align&&(o+=.5*e.options.barChart.width)),{width:s,offset:o}},s.prototype._drawLineGraph=function(t,e){if(null!=t&&t.length>0){var i,s,o=Number(this.svg.style.height.replace("px",""));if(i=n.getSVGElement("path",this.svgElements,this.svg),i.setAttributeNS(null,"class",e.className),s=1==e.options.catmullRom.enabled?this._catmullRom(t,e):this._linear(t),1==e.options.shaded.enabled){var r,a=n.getSVGElement("path",this.svgElements,this.svg);r="top"==e.options.shaded.orientation?"M"+t[0].x+",0 "+s+"L"+t[t.length-1].x+",0":"M"+t[0].x+","+o+" "+s+"L"+t[t.length-1].x+","+o,a.setAttributeNS(null,"class",e.className+" fill"),a.setAttributeNS(null,"d",r)}i.setAttributeNS(null,"d","M"+s),1==e.options.drawPoints.enabled&&this._drawPoints(t,e,this.svgElements,this.svg) +}},s.prototype._drawPoints=function(t,e,i,s,o){void 0===o&&(o=0);for(var r=0;rl;l++)e=0==l?t[0]:t[l-1],i=t[l],s=t[l+1],o=d>l+2?t[l+2]:s,n={x:(-e.x+6*i.x+s.x)*h,y:(-e.y+6*i.y+s.y)*h},r={x:(i.x+6*s.x-o.x)*h,y:(i.y+6*s.y-o.y)*h},a+="C"+n.x+","+n.y+" "+r.x+","+r.y+" "+s.x+","+s.y+" ";return a},s.prototype._catmullRom=function(t,e){var i=e.options.catmullRom.alpha;if(0==i||void 0===i)return this._catmullRomUniform(t);for(var s,o,n,r,a,h,d,l,c,p,u,f,m,g,v,y,b,_,x,w=Math.round(t[0].x)+","+Math.round(t[0].y)+" ",S=t.length,D=0;S-1>D;D++)s=0==D?t[0]:t[D-1],o=t[D],n=t[D+1],r=S>D+2?t[D+2]:n,d=Math.sqrt(Math.pow(s.x-o.x,2)+Math.pow(s.y-o.y,2)),l=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),c=Math.sqrt(Math.pow(n.x-r.x,2)+Math.pow(n.y-r.y,2)),g=Math.pow(c,i),y=Math.pow(c,2*i),v=Math.pow(l,i),b=Math.pow(l,2*i),x=Math.pow(d,i),_=Math.pow(d,2*i),p=2*_+3*x*v+b,u=2*y+3*g*v+b,f=3*x*(x+v),f>0&&(f=1/f),m=3*g*(g+v),m>0&&(m=1/m),a={x:(-b*s.x+p*o.x+_*n.x)*f,y:(-b*s.y+p*o.y+_*n.y)*f},h={x:(y*o.x+u*n.x-b*r.x)*m,y:(y*o.y+u*n.y-b*r.y)*m},0==a.x&&0==a.y&&(a=o),0==h.x&&0==h.y&&(h=n),w+="C"+a.x+","+a.y+" "+h.x+","+h.y+" "+n.x+","+n.y+" ";return w},s.prototype._linear=function(t){for(var e="",i=0;ic;){c++;var p=h.getCurrent(),u=this.body.util.toScreen(p),f=h.isMajor();this.options.showMinorLabels&&this._repaintMinorText(u,h.getLabelMinor(),t),f&&this.options.showMajorLabels?(u>0&&(void 0==l&&(l=u),this._repaintMajorText(u,h.getLabelMajor(),t)),this._repaintMajorLine(u,t)):this._repaintMinorLine(u,t),h.next()}if(this.options.showMajorLabels){var m=this.body.util.toTime(0),g=h.getLabelMajor(m),v=g.length*(this.props.majorCharWidth||10)+10;(void 0==l||l>v)&&this._repaintMajorText(0,g,t)}o.forEach(this.dom.redundant,function(t){for(;t.length;){var e=t.pop();e&&e.parentNode&&e.parentNode.removeChild(e)}})},s.prototype._repaintMinorText=function(t,e,i){var s=this.dom.redundant.minorTexts.shift();if(!s){var o=document.createTextNode("");s=document.createElement("div"),s.appendChild(o),s.className="text minor",this.dom.foreground.appendChild(s)}this.dom.minorTexts.push(s),s.childNodes[0].nodeValue=e,s.style.top="top"==i?this.props.majorLabelHeight+"px":"0",s.style.left=t+"px"},s.prototype._repaintMajorText=function(t,e,i){var s=this.dom.redundant.majorTexts.shift();if(!s){var o=document.createTextNode(e);s=document.createElement("div"),s.className="text major",s.appendChild(o),this.dom.foreground.appendChild(s)}this.dom.majorTexts.push(s),s.childNodes[0].nodeValue=e,s.style.top="top"==i?"0":this.props.minorLabelHeight+"px",s.style.left=t+"px"},s.prototype._repaintMinorLine=function(t,e){var i=this.dom.redundant.minorLines.shift();i||(i=document.createElement("div"),i.className="grid vertical minor",this.dom.background.appendChild(i)),this.dom.minorLines.push(i);var s=this.props;i.style.top="top"==e?s.majorLabelHeight+"px":this.body.domProps.top.height+"px",i.style.height=s.minorLineHeight+"px",i.style.left=t-s.minorLineWidth/2+"px"},s.prototype._repaintMajorLine=function(t,e){var i=this.dom.redundant.majorLines.shift();i||(i=document.createElement("DIV"),i.className="grid vertical major",this.dom.background.appendChild(i)),this.dom.majorLines.push(i);var s=this.props;i.style.top="top"==e?"0":this.body.domProps.top.height+"px",i.style.left=t-s.majorLineWidth/2+"px",i.style.height=s.majorLineHeight+"px"},s.prototype._calculateCharSize=function(){this.dom.measureCharMinor||(this.dom.measureCharMinor=document.createElement("DIV"),this.dom.measureCharMinor.className="text minor measure",this.dom.measureCharMinor.style.position="absolute",this.dom.measureCharMinor.appendChild(document.createTextNode("0")),this.dom.foreground.appendChild(this.dom.measureCharMinor)),this.props.minorCharHeight=this.dom.measureCharMinor.clientHeight,this.props.minorCharWidth=this.dom.measureCharMinor.clientWidth,this.dom.measureCharMajor||(this.dom.measureCharMajor=document.createElement("DIV"),this.dom.measureCharMajor.className="text major measure",this.dom.measureCharMajor.style.position="absolute",this.dom.measureCharMajor.appendChild(document.createTextNode("0")),this.dom.foreground.appendChild(this.dom.measureCharMajor)),this.props.majorCharHeight=this.dom.measureCharMajor.clientHeight,this.props.majorCharWidth=this.dom.measureCharMajor.clientWidth},s.prototype.snap=function(t){return this.step.snap(t)},t.exports=s},function(t,e,i){function s(t,e,i){this.id=null,this.parent=null,this.data=t,this.dom=null,this.conversion=e||{},this.options=i||{},this.selected=!1,this.displayed=!1,this.dirty=!0,this.top=null,this.left=null,this.width=null,this.height=null}var o=i(44),n=i(1);s.prototype.stack=!0,s.prototype.select=function(){this.selected=!0,this.dirty=!0,this.displayed&&this.redraw()},s.prototype.unselect=function(){this.selected=!1,this.dirty=!0,this.displayed&&this.redraw()},s.prototype.setData=function(t){this.data=t,this.dirty=!0,this.displayed&&this.redraw()},s.prototype.setParent=function(t){this.displayed?(this.hide(),this.parent=t,this.parent&&this.show()):this.parent=t},s.prototype.isVisible=function(){return!1},s.prototype.show=function(){return!1},s.prototype.hide=function(){return!1},s.prototype.redraw=function(){},s.prototype.repositionX=function(){},s.prototype.repositionY=function(){},s.prototype._repaintDeleteButton=function(t){if(this.selected&&this.options.editable.remove&&!this.dom.deleteButton){var e=this,i=document.createElement("div");i.className="delete",i.title="Delete this item",o(i,{preventDefault:!0}).on("tap",function(t){e.parent.removeFromDataSet(e),t.stopPropagation()}),t.appendChild(i),this.dom.deleteButton=i}else!this.selected&&this.dom.deleteButton&&(this.dom.deleteButton.parentNode&&this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton),this.dom.deleteButton=null)},s.prototype._updateContents=function(t){var e;if(this.options.template){var i=this.parent.itemSet.itemsData.get(this.id);e=this.options.template(i)}else e=this.data.content;if(e!==this.content){if(e instanceof Element)t.innerHTML="",t.appendChild(e);else if(void 0!=e)t.innerHTML=e;else if("background"!=this.data.type||void 0!==this.data.content)throw new Error('Property "content" missing in item '+this.id);this.content=e}},s.prototype._updateTitle=function(t){null!=this.data.title?t.title=this.data.title||"":t.removeAttribute("title")},s.prototype._updateDataAttributes=function(t){if(this.options.dataAttributes&&this.options.dataAttributes.length>0){var e=[];if(Array.isArray(this.options.dataAttributes))e=this.options.dataAttributes;else{if("all"!=this.options.dataAttributes)return;e=Object.keys(this.data)}for(var i=0;it.start},s.prototype.redraw=function(){var t=this.dom;if(t||(this.dom={},t=this.dom,t.box=document.createElement("div"),t.content=document.createElement("div"),t.content.className="content",t.box.appendChild(t.content),t.box["timeline-item"]=this,this.dirty=!0),!this.parent)throw new Error("Cannot redraw item: no parent attached");if(!t.box.parentNode){var e=this.parent.dom.background;if(!e)throw new Error("Cannot redraw item: parent has no background container element");e.appendChild(t.box)}if(this.displayed=!0,this.dirty){this._updateContents(this.dom.content),this._updateTitle(this.dom.content),this._updateDataAttributes(this.dom.content),this._updateStyle(this.dom.box);var i=(this.data.className?" "+this.data.className:"")+(this.selected?" selected":"");t.box.className=this.baseClassName+i,this.overflow="hidden"!==window.getComputedStyle(t.content).overflow,this.props.content.width=this.dom.content.offsetWidth,this.height=0,this.dirty=!1}},s.prototype.show=r.prototype.show,s.prototype.hide=r.prototype.hide,s.prototype.repositionX=r.prototype.repositionX,s.prototype.repositionY=function(t){var e="top"===this.options.orientation;this.dom.content.style.top=e?"":"0",this.dom.content.style.bottom=e?"0":"";var i;if(void 0!==this.data.subgroup){var s=this.data.subgroup,o=this.parent.subgroups,r=o[s].index;if(1==e){i=this.parent.subgroups[s].height+t.item.vertical,i+=0==r?t.axis-.5*t.item.vertical:0;var a=this.parent.top;for(var h in o)o.hasOwnProperty(h)&&1==o[h].visible&&o[h].indexr&&(a+=o[h].height+t.item.vertical);i=this.parent.subgroups[s].height+t.item.vertical,this.dom.box.style.top=a+"px",this.dom.box.style.bottom=""}}else this.parent instanceof n?(i=Math.max(this.parent.height,this.parent.itemSet.body.domProps.centerContainer.height),this.dom.box.style.top=e?"0":"",this.dom.box.style.bottom=e?"":"0"):(i=this.parent.height,this.dom.box.style.top=this.parent.top+"px",this.dom.box.style.bottom="");this.dom.box.style.height=i+"px"},t.exports=s},function(t,e,i){function s(t,e,i){if(this.props={dot:{width:0,height:0},line:{width:0,height:0}},t&&void 0==t.start)throw new Error('Property "start" missing in item '+t);o.call(this,t,e,i)}{var o=i(30);i(1)}s.prototype=new o(null,null,null),s.prototype.isVisible=function(t){var e=(t.end-t.start)/4;return this.data.start>t.start-e&&this.data.startt.start-e&&this.data.startt.start},s.prototype.redraw=function(){var t=this.dom;if(t||(this.dom={},t=this.dom,t.box=document.createElement("div"),t.content=document.createElement("div"),t.content.className="content",t.box.appendChild(t.content),t.box["timeline-item"]=this,this.dirty=!0),!this.parent)throw new Error("Cannot redraw item: no parent attached");if(!t.box.parentNode){var e=this.parent.dom.foreground;if(!e)throw new Error("Cannot redraw item: parent has no foreground container element");e.appendChild(t.box)}if(this.displayed=!0,this.dirty){this._updateContents(this.dom.content),this._updateTitle(this.dom.box),this._updateDataAttributes(this.dom.box),this._updateStyle(this.dom.box);var i=(this.data.className?" "+this.data.className:"")+(this.selected?" selected":"");t.box.className=this.baseClassName+i,this.overflow="hidden"!==window.getComputedStyle(t.content).overflow,this.props.content.width=this.dom.content.offsetWidth,this.height=this.dom.box.offsetHeight,this.dirty=!1}this._repaintDeleteButton(t.box),this._repaintDragLeft(),this._repaintDragRight()},s.prototype.show=function(){this.displayed||this.redraw()},s.prototype.hide=function(){if(this.displayed){var t=this.dom.box;t.parentNode&&t.parentNode.removeChild(t),this.top=null,this.left=null,this.displayed=!1}},s.prototype.repositionX=function(){var t,e,i=this.parent.width,s=this.conversion.toScreen(this.data.start),o=this.conversion.toScreen(this.data.end);-i>s&&(s=-i),o>2*i&&(o=2*i);var n=Math.max(o-s,1);switch(this.overflow?(this.left=s,this.width=n+this.props.content.width,e=this.props.content.width):(this.left=s,this.width=n,e=Math.min(o-s,this.props.content.width)),this.dom.box.style.left=this.left+"px",this.dom.box.style.width=n+"px",this.options.align){case"left":this.dom.content.style.left="0";break;case"right":this.dom.content.style.left=Math.max(n-e-2*this.options.padding,0)+"px";break;case"center":this.dom.content.style.left=Math.max((n-e-2*this.options.padding)/2,0)+"px";break;default:t=this.overflow?Math.max(-s,0):0>s?Math.min(-s,o-s-this.props.content.width-2*this.options.padding):0,this.dom.content.style.left=t+"px"}},s.prototype.repositionY=function(){var t=this.options.orientation,e=this.dom.box;e.style.top="top"==t?this.top+"px":this.parent.height-this.top-this.height+"px"},s.prototype._repaintDragLeft=function(){if(this.selected&&this.options.editable.updateTime&&!this.dom.dragLeft){var t=document.createElement("div");t.className="drag-left",t.dragLeftItem=this,o(t,{preventDefault:!0}).on("drag",function(){}),this.dom.box.appendChild(t),this.dom.dragLeft=t}else!this.selected&&this.dom.dragLeft&&(this.dom.dragLeft.parentNode&&this.dom.dragLeft.parentNode.removeChild(this.dom.dragLeft),this.dom.dragLeft=null)},s.prototype._repaintDragRight=function(){if(this.selected&&this.options.editable.updateTime&&!this.dom.dragRight){var t=document.createElement("div");t.className="drag-right",t.dragRightItem=this,o(t,{preventDefault:!0}).on("drag",function(){}),this.dom.box.appendChild(t),this.dom.dragRight=t}else!this.selected&&this.dom.dragRight&&(this.dom.dragRight.parentNode&&this.dom.dragRight.parentNode.removeChild(this.dom.dragRight),this.dom.dragRight=null)},t.exports=s},function(t,e,i){function s(t,e,i){if(!(this instanceof s))throw new SyntaxError("Constructor must be called with the new operator");this._initializeMixinLoaders(),this.containerElement=t,this.renderRefreshRate=60,this.renderTimestep=1e3/this.renderRefreshRate,this.renderTime=.5*this.renderTimestep,this.maxPhysicsTicksPerRender=3,this.physicsDiscreteStepsize=.5,this.initializing=!0,this.triggerFunctions={add:null,edit:null,editEdge:null,connect:null,del:null},this.defaultOptions={nodes:{mass:1,radiusMin:10,radiusMax:30,radius:10,shape:"ellipse",image:void 0,widthMin:16,widthMax:64,fontColor:"black",fontSize:14,fontFace:"verdana",fontFill:void 0,level:-1,color:{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},borderColor:"#2B7CE9",backgroundColor:"#97C2FC",highlightColor:"#D2E5FF",group:void 0,borderWidth:1,borderWidthSelected:void 0},edges:{widthMin:1,widthMax:15,width:1,widthSelectionMultiplier:2,hoverWidth:1.5,style:"line",color:{color:"#848484",highlight:"#848484",hover:"#848484"},fontColor:"#343434",fontSize:14,fontFace:"arial",fontFill:"white",arrowScaleFactor:1,dash:{length:10,gap:5,altLength:void 0},inheritColor:"from"},configurePhysics:!1,physics:{barnesHut:{enabled:!0,theta:1/.6,gravitationalConstant:-2e3,centralGravity:.3,springLength:95,springConstant:.04,damping:.09},repulsion:{centralGravity:0,springLength:200,springConstant:.05,nodeDistance:100,damping:.09},hierarchicalRepulsion:{enabled:!1,centralGravity:0,springLength:100,springConstant:.01,nodeDistance:150,damping:.09},damping:null,centralGravity:null,springLength:null,springConstant:null},clustering:{enabled:!1,initialMaxNodes:100,clusterThreshold:500,reduceToNodes:300,chainThreshold:.4,clusterEdgeThreshold:20,sectorThreshold:100,screenSizeThreshold:.2,fontSizeMultiplier:4,maxFontSize:1e3,forceAmplification:.1,distanceAmplification:.1,edgeGrowth:20,nodeScaling:{width:1,height:1,radius:1},maxNodeSizeIncrements:600,activeAreaBoxSize:80,clusterLevelDifference:2},navigation:{enabled:!1},keyboard:{enabled:!1,speed:{x:10,y:10,zoom:.02}},dataManipulation:{enabled:!1,initiallyVisible:!1},hierarchicalLayout:{enabled:!1,levelSeparation:150,nodeSpacing:100,direction:"UD",layout:"hubsize"},freezeForStabilization:!1,smoothCurves:{enabled:!0,dynamic:!0,type:"continuous",roundness:.5},dynamicSmoothCurves:!0,maxVelocity:30,minVelocity:.1,stabilize:!0,stabilizationIterations:1e3,locale:"en",locales:_,tooltip:{delay:300,fontColor:"black",fontSize:14,fontFace:"verdana",color:{border:"#666",background:"#FFFFC6"}},dragNetwork:!0,dragNodes:!0,zoomable:!0,hover:!1,hideEdgesOnDrag:!1,hideNodesOnDrag:!1,width:"100%",height:"100%",selectable:!0},this.constants=a.extend({},this.defaultOptions),this.hoverObj={nodes:{},edges:{}},this.controlNodesActive=!1,this.navigationHammers={existing:[],"new":[]},this.animationSpeed=1/this.renderRefreshRate,this.animationEasingFunction="easeInOutQuint",this.easingTime=0,this.sourceScale=0,this.targetScale=0,this.sourceTranslation=0,this.targetTranslation=0,this.lockedOnNodeId=null,this.lockedOnNodeOffset=null;var o=this;this.groups=new u,this.images=new f,this.images.setOnloadCallback(function(){o._redraw()}),this.xIncrement=0,this.yIncrement=0,this.zoomIncrement=0,this._loadPhysicsSystem(),this._create(),this._loadSectorSystem(),this._loadClusterSystem(),this._loadSelectionSystem(),this._loadHierarchySystem(),this._setTranslation(this.frame.clientWidth/2,this.frame.clientHeight/2),this._setScale(1),this.setOptions(i),this.freezeSimulation=!1,this.cachedFunctions={},this.startedStabilization=!1,this.stabilized=!1,this.stabilizationIterations=null,this.calculationNodes={},this.calculationNodeIndices=[],this.nodeIndices=[],this.nodes={},this.edges={},this.canvasTopLeft={x:0,y:0},this.canvasBottomRight={x:0,y:0},this.pointerPosition={x:0,y:0},this.areaCenter={},this.scale=1,this.previousScale=this.scale,this.nodesData=null,this.edgesData=null,this.nodesListeners={add:function(t,e){o._addNodes(e.items),o.start()},update:function(t,e){o._updateNodes(e.items,e.data),o.start()},remove:function(t,e){o._removeNodes(e.items),o.start()}},this.edgesListeners={add:function(t,e){o._addEdges(e.items),o.start()},update:function(t,e){o._updateEdges(e.items),o.start()},remove:function(t,e){o._removeEdges(e.items),o.start()}},this.moving=!0,this.timer=void 0,this.setData(e,this.constants.clustering.enabled||this.constants.hierarchicalLayout.enabled),this.initializing=!1,1==this.constants.hierarchicalLayout.enabled?this._setupHierarchicalLayout():0==this.constants.stabilize&&this.zoomExtent(void 0,!0,this.constants.clustering.enabled),this.constants.clustering.enabled&&this.startWithClustering()}var o=i(52),n=i(44),r=i(55),a=i(1),h=i(46),d=i(3),l=i(4),c=i(41),p=i(42),u=i(37),f=i(38),m=i(39),g=i(36),v=i(40),y=i(50),b=i(51),_=i(48);i(49),o(s.prototype),s.prototype._getScriptPath=function(){for(var t=document.getElementsByTagName("script"),e=0;et.x&&(s=t.x),ot.y&&(e=t.y),i=this.constants.clustering.initialMaxNodes?49.07548/(n+142.05338)+91444e-8:12.662/(n+7.4147)+.0964822:1==this.constants.clustering.enabled&&n>=this.constants.clustering.initialMaxNodes?77.5271985/(n+187.266146)+476710517e-13:30.5062972/(n+19.93597763)+.08413486;var r=Math.min(this.frame.canvas.clientWidth/600,this.frame.canvas.clientHeight/600);s*=r}else{var a=1.1*Math.abs(o.maxX-o.minX),h=1.1*Math.abs(o.maxY-o.minY),d=this.frame.canvas.clientWidth/a,l=this.frame.canvas.clientHeight/h;s=l>=d?d:l}s>1&&(s=1);var c=this._findCenter(o);if(0==i){var p={position:c,scale:s,animation:t};this.moveTo(p),this.moving=!0,this.start()}else c.x*=s,c.y*=s,c.x-=.5*this.frame.canvas.clientWidth,c.y-=.5*this.frame.canvas.clientHeight,this._setScale(s),this._setTranslation(-c.x,-c.y)},s.prototype._updateNodeIndexList=function(){this._clearNodeIndexList();for(var t in this.nodes)this.nodes.hasOwnProperty(t)&&this.nodeIndices.push(t)},s.prototype.setData=function(t,e){if(void 0===e&&(e=!1),this.initializing=!0,t&&t.dot&&(t.nodes||t.edges))throw new SyntaxError('Data must contain either parameter "dot" or parameter pair "nodes" and "edges", but not both.');if(this.setOptions(t&&t.options),t&&t.dot){if(t&&t.dot){var i=c.DOTToGraph(t.dot);return void this.setData(i)}}else if(t&&t.gephi){if(t&&t.gephi){var s=p.parseGephi(t.gephi);return void this.setData(s)}}else this._setNodes(t&&t.nodes),this._setEdges(t&&t.edges);this._putDataInSector(),0==e&&(1==this.constants.hierarchicalLayout.enabled?(this._resetLevels(),this._setupHierarchicalLayout()):this.constants.stabilize&&this._stabilize(),this.start()),this.initializing=!1},s.prototype.setOptions=function(t){if(t){var e,i=["nodes","edges","smoothCurves","hierarchicalLayout","clustering","navigation","keyboard","dataManipulation","onAdd","onEdit","onEditEdge","onConnect","onDelete","clickToUse"];if(a.selectiveNotDeepExtend(i,this.constants,t),a.selectiveNotDeepExtend(["color"],this.constants.nodes,t.nodes),a.selectiveNotDeepExtend(["color","length"],this.constants.edges,t.edges),t.physics&&(a.mergeOptions(this.constants.physics,t.physics,"barnesHut"),a.mergeOptions(this.constants.physics,t.physics,"repulsion"),t.physics.hierarchicalRepulsion)){this.constants.hierarchicalLayout.enabled=!0,this.constants.physics.hierarchicalRepulsion.enabled=!0,this.constants.physics.barnesHut.enabled=!1;for(e in t.physics.hierarchicalRepulsion)t.physics.hierarchicalRepulsion.hasOwnProperty(e)&&(this.constants.physics.hierarchicalRepulsion[e]=t.physics.hierarchicalRepulsion[e])}if(t.onAdd&&(this.triggerFunctions.add=t.onAdd),t.onEdit&&(this.triggerFunctions.edit=t.onEdit),t.onEditEdge&&(this.triggerFunctions.editEdge=t.onEditEdge),t.onConnect&&(this.triggerFunctions.connect=t.onConnect),t.onDelete&&(this.triggerFunctions.del=t.onDelete),a.mergeOptions(this.constants,t,"smoothCurves"),a.mergeOptions(this.constants,t,"hierarchicalLayout"),a.mergeOptions(this.constants,t,"clustering"),a.mergeOptions(this.constants,t,"navigation"),a.mergeOptions(this.constants,t,"keyboard"),a.mergeOptions(this.constants,t,"dataManipulation"),t.dataManipulation&&(this.editMode=this.constants.dataManipulation.initiallyVisible),t.edges&&(void 0!==t.edges.color&&(a.isString(t.edges.color)?(this.constants.edges.color={},this.constants.edges.color.color=t.edges.color,this.constants.edges.color.highlight=t.edges.color,this.constants.edges.color.hover=t.edges.color):(void 0!==t.edges.color.color&&(this.constants.edges.color.color=t.edges.color.color),void 0!==t.edges.color.highlight&&(this.constants.edges.color.highlight=t.edges.color.highlight),void 0!==t.edges.color.hover&&(this.constants.edges.color.hover=t.edges.color.hover))),t.edges.fontColor||void 0!==t.edges.color&&(a.isString(t.edges.color)?this.constants.edges.fontColor=t.edges.color:void 0!==t.edges.color.color&&(this.constants.edges.fontColor=t.edges.color.color))),t.nodes&&t.nodes.color){var s=a.parseColor(t.nodes.color);this.constants.nodes.color.background=s.background,this.constants.nodes.color.border=s.border,this.constants.nodes.color.highlight.background=s.highlight.background,this.constants.nodes.color.highlight.border=s.highlight.border,this.constants.nodes.color.hover.background=s.hover.background,this.constants.nodes.color.hover.border=s.hover.border }if(t.groups)for(var o in t.groups)if(t.groups.hasOwnProperty(o)){var n=t.groups[o];this.groups.add(o,n)}if(t.tooltip){for(e in t.tooltip)t.tooltip.hasOwnProperty(e)&&(this.constants.tooltip[e]=t.tooltip[e]);t.tooltip.color&&(this.constants.tooltip.color=a.parseColor(t.tooltip.color))}if("clickToUse"in t&&(t.clickToUse?(this.activator=new b(this.frame),this.activator.on("change",this._createKeyBinds.bind(this))):this.activator&&(this.activator.destroy(),delete this.activator)),t.labels)throw new Error('Option "labels" is deprecated. Use options "locale" and "locales" instead.')}this._loadPhysicsSystem(),this._loadNavigationControls(),this._loadManipulationSystem(),this._configureSmoothCurves(),this._createKeyBinds(),this.setSize(this.constants.width,this.constants.height),this.moving=!0,this.start()},s.prototype._create=function(){for(;this.containerElement.hasChildNodes();)this.containerElement.removeChild(this.containerElement.firstChild);if(this.frame=document.createElement("div"),this.frame.className="vis network-frame",this.frame.style.position="relative",this.frame.style.overflow="hidden",this.frame.canvas=document.createElement("canvas"),this.frame.canvas.style.position="relative",this.frame.appendChild(this.frame.canvas),!this.frame.canvas.getContext){var t=document.createElement("DIV");t.style.color="red",t.style.fontWeight="bold",t.style.padding="10px",t.innerHTML="Error: your browser does not support HTML canvas",this.frame.canvas.appendChild(t)}var e=this;this.drag={},this.pinch={},this.hammer=n(this.frame.canvas,{prevent_default:!0}),this.hammer.on("tap",e._onTap.bind(e)),this.hammer.on("doubletap",e._onDoubleTap.bind(e)),this.hammer.on("hold",e._onHold.bind(e)),this.hammer.on("pinch",e._onPinch.bind(e)),this.hammer.on("touch",e._onTouch.bind(e)),this.hammer.on("dragstart",e._onDragStart.bind(e)),this.hammer.on("drag",e._onDrag.bind(e)),this.hammer.on("dragend",e._onDragEnd.bind(e)),this.hammer.on("release",e._onRelease.bind(e)),this.hammer.on("mousewheel",e._onMouseWheel.bind(e)),this.hammer.on("DOMMouseScroll",e._onMouseWheel.bind(e)),this.hammer.on("mousemove",e._onMouseMoveTitle.bind(e)),this.containerElement.appendChild(this.frame)},s.prototype._createKeyBinds=function(){var t=this;this.mousetrap=r,this.mousetrap.reset(),this.constants.keyboard.enabled&&this.isActive()&&(this.mousetrap.bind("up",this._moveUp.bind(t),"keydown"),this.mousetrap.bind("up",this._yStopMoving.bind(t),"keyup"),this.mousetrap.bind("down",this._moveDown.bind(t),"keydown"),this.mousetrap.bind("down",this._yStopMoving.bind(t),"keyup"),this.mousetrap.bind("left",this._moveLeft.bind(t),"keydown"),this.mousetrap.bind("left",this._xStopMoving.bind(t),"keyup"),this.mousetrap.bind("right",this._moveRight.bind(t),"keydown"),this.mousetrap.bind("right",this._xStopMoving.bind(t),"keyup"),this.mousetrap.bind("=",this._zoomIn.bind(t),"keydown"),this.mousetrap.bind("=",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("-",this._zoomOut.bind(t),"keydown"),this.mousetrap.bind("-",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("[",this._zoomIn.bind(t),"keydown"),this.mousetrap.bind("[",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("]",this._zoomOut.bind(t),"keydown"),this.mousetrap.bind("]",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("pageup",this._zoomIn.bind(t),"keydown"),this.mousetrap.bind("pageup",this._stopZoom.bind(t),"keyup"),this.mousetrap.bind("pagedown",this._zoomOut.bind(t),"keydown"),this.mousetrap.bind("pagedown",this._stopZoom.bind(t),"keyup")),1==this.constants.dataManipulation.enabled&&(this.mousetrap.bind("escape",this._createManipulatorBar.bind(t)),this.mousetrap.bind("del",this._deleteSelected.bind(t)))},s.prototype._getPointer=function(t){return{x:t.pageX-a.getAbsoluteLeft(this.frame.canvas),y:t.pageY-a.getAbsoluteTop(this.frame.canvas)}},s.prototype._onTouch=function(t){this.drag.pointer=this._getPointer(t.gesture.center),this.drag.pinched=!1,this.pinch.scale=this._getScale(),this._handleTouch(this.drag.pointer)},s.prototype._onDragStart=function(){this._handleDragStart()},s.prototype._handleDragStart=function(){var t=this.drag,e=this._getNodeAt(t.pointer);if(t.dragging=!0,t.selection=[],t.translation=this._getTranslation(),t.nodeId=null,null!=e&&1==this.constants.dragNodes){t.nodeId=e.id,e.isSelected()||this._selectObject(e,!1),this.emit("dragStart",{nodeIds:this.getSelection().nodes});for(var i in this.selectionObj.nodes)if(this.selectionObj.nodes.hasOwnProperty(i)){var s=this.selectionObj.nodes[i],o={id:s.id,node:s,x:s.x,y:s.y,xFixed:s.xFixed,yFixed:s.yFixed};s.xFixed=!0,s.yFixed=!0,t.selection.push(o)}}},s.prototype._onDrag=function(t){this._handleOnDrag(t)},s.prototype._handleOnDrag=function(t){if(!this.drag.pinched){this.releaseNode();var e=this._getPointer(t.gesture.center),i=this,s=this.drag,o=s.selection;if(o&&o.length&&1==this.constants.dragNodes){var n=e.x-s.pointer.x,r=e.y-s.pointer.y;o.forEach(function(t){var e=t.node;t.xFixed||(e.x=i._XconvertDOMtoCanvas(i._XconvertCanvasToDOM(t.x)+n)),t.yFixed||(e.y=i._YconvertDOMtoCanvas(i._YconvertCanvasToDOM(t.y)+r))}),this.moving||(this.moving=!0,this.start())}else if(1==this.constants.dragNetwork){var a=e.x-this.drag.pointer.x,h=e.y-this.drag.pointer.y;this._setTranslation(this.drag.translation.x+a,this.drag.translation.y+h),this._redraw()}}},s.prototype._onDragEnd=function(t){this._handleDragEnd(t)},s.prototype._handleDragEnd=function(){this.drag.dragging=!1;var t=this.drag.selection;t&&t.length?(t.forEach(function(t){t.node.xFixed=t.xFixed,t.node.yFixed=t.yFixed}),this.moving=!0,this.start()):this._redraw(),this.emit("dragEnd",{nodeIds:this.getSelection().nodes})},s.prototype._onTap=function(t){var e=this._getPointer(t.gesture.center);this.pointerPosition=e,this._handleTap(e)},s.prototype._onDoubleTap=function(t){var e=this._getPointer(t.gesture.center);this._handleDoubleTap(e)},s.prototype._onHold=function(t){var e=this._getPointer(t.gesture.center);this.pointerPosition=e,this._handleOnHold(e)},s.prototype._onRelease=function(t){var e=this._getPointer(t.gesture.center);this._handleOnRelease(e)},s.prototype._onPinch=function(t){var e=this._getPointer(t.gesture.center);this.drag.pinched=!0,"scale"in this.pinch||(this.pinch.scale=1);var i=this.pinch.scale*t.gesture.scale;this._zoom(i,e)},s.prototype._zoom=function(t,e){if(1==this.constants.zoomable){var i=this._getScale();1e-5>t&&(t=1e-5),t>10&&(t=10);var s=null;void 0!==this.drag&&1==this.drag.dragging&&(s=this.DOMtoCanvas(this.drag.pointer));var o=this._getTranslation(),n=t/i,r=(1-n)*e.x+o.x*n,a=(1-n)*e.y+o.y*n;if(this.areaCenter={x:this._XconvertDOMtoCanvas(e.x),y:this._YconvertDOMtoCanvas(e.y)},this._setScale(t),this._setTranslation(r,a),this.updateClustersDefault(),null!=s){var h=this.canvasToDOM(s);this.drag.pointer.x=h.x,this.drag.pointer.y=h.y}return this._redraw(),t>i?this.emit("zoom",{direction:"+"}):this.emit("zoom",{direction:"-"}),t}},s.prototype._onMouseWheel=function(t){var e=0;if(t.wheelDelta?e=t.wheelDelta/120:t.detail&&(e=-t.detail/3),e){var i=this._getScale(),s=e/10;0>e&&(s/=1-s),i*=1+s;var o=h.fakeGesture(this,t),n=this._getPointer(o.center);this._zoom(i,n)}t.preventDefault()},s.prototype._onMouseMoveTitle=function(t){var e=h.fakeGesture(this,t),i=this._getPointer(e.center);this.popupObj&&this._checkHidePopup(i);var s=this,o=function(){s._checkShowPopup(i)};if(this.popupTimer&&clearInterval(this.popupTimer),this.drag.dragging||(this.popupTimer=setTimeout(o,this.constants.tooltip.delay)),1==this.constants.hover){for(var n in this.hoverObj.edges)this.hoverObj.edges.hasOwnProperty(n)&&(this.hoverObj.edges[n].hover=!1,delete this.hoverObj.edges[n]);var r=this._getNodeAt(i);null==r&&(r=this._getEdgeAt(i)),null!=r&&this._hoverObject(r);for(var a in this.hoverObj.nodes)this.hoverObj.nodes.hasOwnProperty(a)&&(r instanceof m&&r.id!=a||r instanceof g||null==r)&&(this._blurObject(this.hoverObj.nodes[a]),delete this.hoverObj.nodes[a]);this.redraw()}},s.prototype._checkShowPopup=function(t){var e,i={left:this._XconvertDOMtoCanvas(t.x),top:this._YconvertDOMtoCanvas(t.y),right:this._XconvertDOMtoCanvas(t.x),bottom:this._YconvertDOMtoCanvas(t.y)},s=this.popupObj;if(void 0==this.popupObj){var o=this.nodes;for(e in o)if(o.hasOwnProperty(e)){var n=o[e];if(void 0!==n.getTitle()&&n.isOverlappingWith(i)){this.popupObj=n;break}}}if(void 0===this.popupObj){var r=this.edges;for(e in r)if(r.hasOwnProperty(e)){var a=r[e];if(a.connected&&void 0!==a.getTitle()&&a.isOverlappingWith(i)){this.popupObj=a;break}}}if(this.popupObj){if(this.popupObj!=s){var h=this;h.popup||(h.popup=new v(h.frame,h.constants.tooltip)),h.popup.setPosition(t.x-3,t.y-3),h.popup.setText(h.popupObj.getTitle()),h.popup.show()}}else this.popup&&this.popup.hide()},s.prototype._checkHidePopup=function(t){this.popupObj&&this._getNodeAt(t)||(this.popupObj=void 0,this.popup&&this.popup.hide())},s.prototype.setSize=function(t,e){var i=!1,s=this.frame.canvas.width,o=this.frame.canvas.height;t!=this.constants.width||e!=this.constants.height||this.frame.style.width!=t||this.frame.style.height!=e?(this.frame.style.width=t,this.frame.style.height=e,this.frame.canvas.style.width="100%",this.frame.canvas.style.height="100%",this.frame.canvas.width=this.frame.canvas.clientWidth,this.frame.canvas.height=this.frame.canvas.clientHeight,this.constants.width=t,this.constants.height=e,i=!0):(this.frame.canvas.width!=this.frame.canvas.clientWidth&&(this.frame.canvas.width=this.frame.canvas.clientWidth,i=!0),this.frame.canvas.height!=this.frame.canvas.clientHeight&&(this.frame.canvas.height=this.frame.canvas.clientHeight,i=!0)),1==i&&this.emit("resize",{width:this.frame.canvas.width,height:this.frame.canvas.height,oldWidth:s,oldHeight:o})},s.prototype._setNodes=function(t){var e=this.nodesData;if(t instanceof d||t instanceof l)this.nodesData=t;else if(Array.isArray(t))this.nodesData=new d,this.nodesData.add(t);else{if(t)throw new TypeError("Array or DataSet expected");this.nodesData=new d}if(e&&a.forEach(this.nodesListeners,function(t,i){e.off(i,t)}),this.nodes={},this.nodesData){var i=this;a.forEach(this.nodesListeners,function(t,e){i.nodesData.on(e,t)});var s=this.nodesData.getIds();this._addNodes(s)}this._updateSelection()},s.prototype._addNodes=function(t){for(var e,i=0,s=t.length;s>i;i++){e=t[i];var o=this.nodesData.get(e),n=new m(o,this.images,this.groups,this.constants);if(this.nodes[e]=n,!(0!=n.xFixed&&0!=n.yFixed||null!==n.x&&null!==n.y)){var r=1*t.length+10,a=2*Math.PI*Math.random();0==n.xFixed&&(n.x=r*Math.cos(a)),0==n.yFixed&&(n.y=r*Math.sin(a))}this.moving=!0}this._updateNodeIndexList(),1==this.constants.hierarchicalLayout.enabled&&0==this.initializing&&(this._resetLevels(),this._setupHierarchicalLayout()),this._updateCalculationNodes(),this._reconnectEdges(),this._updateValueRange(this.nodes),this.updateLabels()},s.prototype._updateNodes=function(t,e){for(var i=this.nodes,s=0,o=t.length;o>s;s++){var n=t[s],r=i[n],a=e[s];r?r.setProperties(a,this.constants):(r=new m(properties,this.images,this.groups,this.constants),i[n]=r)}this.moving=!0,1==this.constants.hierarchicalLayout.enabled&&0==this.initializing&&(this._resetLevels(),this._setupHierarchicalLayout()),this._updateNodeIndexList(),this._updateValueRange(i)},s.prototype._removeNodes=function(t){for(var e=this.nodes,i=0,s=t.length;s>i;i++){var o=t[i];delete e[o]}this._updateNodeIndexList(),1==this.constants.hierarchicalLayout.enabled&&0==this.initializing&&(this._resetLevels(),this._setupHierarchicalLayout()),this._updateCalculationNodes(),this._reconnectEdges(),this._updateSelection(),this._updateValueRange(e)},s.prototype._setEdges=function(t){var e=this.edgesData;if(t instanceof d||t instanceof l)this.edgesData=t;else if(Array.isArray(t))this.edgesData=new d,this.edgesData.add(t);else{if(t)throw new TypeError("Array or DataSet expected");this.edgesData=new d}if(e&&a.forEach(this.edgesListeners,function(t,i){e.off(i,t)}),this.edges={},this.edgesData){var i=this;a.forEach(this.edgesListeners,function(t,e){i.edgesData.on(e,t)});var s=this.edgesData.getIds();this._addEdges(s)}this._reconnectEdges()},s.prototype._addEdges=function(t){for(var e=this.edges,i=this.edgesData,s=0,o=t.length;o>s;s++){var n=t[s],r=e[n];r&&r.disconnect();var a=i.get(n,{showInternalIds:!0});e[n]=new g(a,this,this.constants)}this.moving=!0,this._updateValueRange(e),this._createBezierNodes(),this._updateCalculationNodes(),1==this.constants.hierarchicalLayout.enabled&&0==this.initializing&&(this._resetLevels(),this._setupHierarchicalLayout())},s.prototype._updateEdges=function(t){for(var e=this.edges,i=this.edgesData,s=0,o=t.length;o>s;s++){var n=t[s],r=i.get(n),a=e[n];a?(a.disconnect(),a.setProperties(r,this.constants),a.connect()):(a=new g(r,this,this.constants),this.edges[n]=a)}this._createBezierNodes(),1==this.constants.hierarchicalLayout.enabled&&0==this.initializing&&(this._resetLevels(),this._setupHierarchicalLayout()),this.moving=!0,this._updateValueRange(e)},s.prototype._removeEdges=function(t){for(var e=this.edges,i=0,s=t.length;s>i;i++){var o=t[i],n=e[o];n&&(null!=n.via&&delete this.sectors.support.nodes[n.via.id],n.disconnect(),delete e[o])}this.moving=!0,this._updateValueRange(e),1==this.constants.hierarchicalLayout.enabled&&0==this.initializing&&(this._resetLevels(),this._setupHierarchicalLayout()),this._updateCalculationNodes()},s.prototype._reconnectEdges=function(){var t,e=this.nodes,i=this.edges;for(t in e)e.hasOwnProperty(t)&&(e[t].edges=[],e[t].dynamicEdges=[]);for(t in i)if(i.hasOwnProperty(t)){var s=i[t];s.from=null,s.to=null,s.connect()}},s.prototype._updateValueRange=function(t){var e,i=void 0,s=void 0;for(e in t)if(t.hasOwnProperty(e)){var o=t[e].getValue();void 0!==o&&(i=void 0===i?o:Math.min(o,i),s=void 0===s?o:Math.max(o,s))}if(void 0!==i&&void 0!==s)for(e in t)t.hasOwnProperty(e)&&t[e].setValueRange(i,s)},s.prototype.redraw=function(){this.setSize(this.constants.width,this.constants.height),this._redraw()},s.prototype._redraw=function(){var t=this.frame.canvas.getContext("2d"),e=this.frame.canvas.width,i=this.frame.canvas.height;t.clearRect(0,0,e,i),t.save(),t.translate(this.translation.x,this.translation.y),t.scale(this.scale,this.scale),this.canvasTopLeft={x:this._XconvertDOMtoCanvas(0),y:this._YconvertDOMtoCanvas(0)},this.canvasBottomRight={x:this._XconvertDOMtoCanvas(this.frame.canvas.clientWidth),y:this._YconvertDOMtoCanvas(this.frame.canvas.clientHeight)},this._doInAllSectors("_drawAllSectorNodes",t),(0==this.drag.dragging||void 0===this.drag.dragging||0==this.constants.hideEdgesOnDrag)&&this._doInAllSectors("_drawEdges",t),(0==this.drag.dragging||void 0===this.drag.dragging||0==this.constants.hideNodesOnDrag)&&this._doInAllSectors("_drawNodes",t,!1),1==this.controlNodesActive&&this._doInAllSectors("_drawControlNodes",t),t.restore()},s.prototype._setTranslation=function(t,e){void 0===this.translation&&(this.translation={x:0,y:0}),void 0!==t&&(this.translation.x=t),void 0!==e&&(this.translation.y=e),this.emit("viewChanged")},s.prototype._getTranslation=function(){return{x:this.translation.x,y:this.translation.y}},s.prototype._setScale=function(t){this.scale=t},s.prototype._getScale=function(){return this.scale},s.prototype._XconvertDOMtoCanvas=function(t){return(t-this.translation.x)/this.scale},s.prototype._XconvertCanvasToDOM=function(t){return t*this.scale+this.translation.x},s.prototype._YconvertDOMtoCanvas=function(t){return(t-this.translation.y)/this.scale},s.prototype._YconvertCanvasToDOM=function(t){return t*this.scale+this.translation.y},s.prototype.canvasToDOM=function(t){return{x:this._XconvertCanvasToDOM(t.x),y:this._YconvertCanvasToDOM(t.y)}},s.prototype.DOMtoCanvas=function(t){return{x:this._XconvertDOMtoCanvas(t.x),y:this._YconvertDOMtoCanvas(t.y)}},s.prototype._drawNodes=function(t,e){void 0===e&&(e=!1);var i=this.nodes,s=[];for(var o in i)i.hasOwnProperty(o)&&(i[o].setScaleAndPos(this.scale,this.canvasTopLeft,this.canvasBottomRight),i[o].isSelected()?s.push(o):(i[o].inArea()||e)&&i[o].draw(t));for(var n=0,r=s.length;r>n;n++)(i[s[n]].inArea()||e)&&i[s[n]].draw(t)},s.prototype._drawEdges=function(t){var e=this.edges;for(var i in e)if(e.hasOwnProperty(i)){var s=e[i];s.setScale(this.scale),s.connected&&e[i].draw(t)}},s.prototype._drawControlNodes=function(t){var e=this.edges;for(var i in e)e.hasOwnProperty(i)&&e[i]._drawControlNodes(t)},s.prototype._stabilize=function(){1==this.constants.freezeForStabilization&&this._freezeDefinedNodes();for(var t=0;this.moving&&t0)for(t in i)i.hasOwnProperty(t)&&(i[t].discreteStepLimited(e,this.constants.maxVelocity),s=!0);else for(t in i)i.hasOwnProperty(t)&&(i[t].discreteStep(e),s=!0);if(1==s){var o=this.constants.minVelocity/Math.max(this.scale,.05);return o>.5*this.constants.maxVelocity?!0:this._isMoving(o)}return!1},s.prototype._physicsTick=function(){if(!this.freezeSimulation&&1==this.moving){var t=!1,e=!1;this._doInAllActiveSectors("_initializeForceCalculation");var i=this._doInAllActiveSectors("_discreteStepNodes");1==this.constants.smoothCurves.enabled&&1==this.constants.smoothCurves.dynamic&&(e=this._doInSupportSector("_discreteStepNodes"));for(var s=0;s0){var i=this,s={iterations:i.stabilizationIterations};i.stabilizationIterations=0,i.startedStabilization=!1,setTimeout(function(){i.emit("stabilized",s)},0)}},s.prototype._handleNavigation=function(){if(0!=this.xIncrement||0!=this.yIncrement){var t=this._getTranslation();this._setTranslation(t.x+this.xIncrement,t.y+this.yIncrement)}if(0!=this.zoomIncrement){var e={x:this.frame.canvas.clientWidth/2,y:this.frame.canvas.clientHeight/2};this._zoom(this.scale*(1+this.zoomIncrement),e)}},s.prototype.toggleFreeze=function(){0==this.freezeSimulation?this.freezeSimulation=!0:(this.freezeSimulation=!1,this.start())},s.prototype._configureSmoothCurves=function(t){if(void 0===t&&(t=!0),1==this.constants.smoothCurves.enabled&&1==this.constants.smoothCurves.dynamic){this._createBezierNodes();for(var e in this.sectors.support.nodes)this.sectors.support.nodes.hasOwnProperty(e)&&void 0===this.edges[this.sectors.support.nodes[e].parentEdgeId]&&delete this.sectors.support.nodes[e]}else{this.sectors.support.nodes={};for(var i in this.edges)this.edges.hasOwnProperty(i)&&(this.edges[i].via=null)}this._updateCalculationNodes(),t||(this.moving=!0,this.start())},s.prototype._createBezierNodes=function(){if(1==this.constants.smoothCurves.enabled&&1==this.constants.smoothCurves.dynamic)for(var t in this.edges)if(this.edges.hasOwnProperty(t)){var e=this.edges[t];if(null==e.via){var i="edgeId:".concat(e.id);this.sectors.support.nodes[i]=new m({id:i,mass:1,shape:"circle",image:"",internalMultiplier:1},{},{},this.constants),e.via=this.sectors.support.nodes[i],e.via.parentEdgeId=e.id,e.positionBezierNode()}}},s.prototype._initializeMixinLoaders=function(){for(var t in y)y.hasOwnProperty(t)&&(s.prototype[t]=y[t])},s.prototype.storePosition=function(){console.log("storePosition is depricated: use .storePositions() from now on."),this.storePositions()},s.prototype.storePositions=function(){var t=[];for(var e in this.nodes)if(this.nodes.hasOwnProperty(e)){var i=this.nodes[e],s=!this.nodes.xFixed,o=!this.nodes.yFixed;(this.nodesData._data[e].x!=Math.round(i.x)||this.nodesData._data[e].y!=Math.round(i.y))&&t.push({id:e,x:Math.round(i.x),y:Math.round(i.y),allowedToMoveX:s,allowedToMoveY:o})}this.nodesData.update(t)},s.prototype.getPositions=function(t){var e={};if(void 0!==t){if(1==Array.isArray(t)){for(var i=0;i=1&&(this.easingTime=0,this._redraw=null!=this.lockedOnNodeId?this._lockedRedraw:this._classicRedraw,this.emit("animationFinished"))},s.prototype._classicRedraw=function(){},s.prototype.isActive=function(){return!this.activator||this.activator.active},s.prototype.setScale=function(){return this._setScale()},s.prototype.getScale=function(){return this._getScale()},s.prototype.getCenterCoordinates=function(){return this.DOMtoCanvas({x:.5*this.frame.canvas.clientWidth,y:.5*this.frame.canvas.clientHeight})},t.exports=s},function(t,e,i){function s(t,e,i){if(!e)throw"No network provided";var s=["edges","physics"],n=o.selectiveBridgeObject(s,i);this.options=n.edges,this.physics=n.physics,this.options.smoothCurves=i.smoothCurves,this.network=e,this.id=void 0,this.fromId=void 0,this.toId=void 0,this.title=void 0,this.widthSelected=this.options.width*this.options.widthSelectionMultiplier,this.value=void 0,this.selected=!1,this.hover=!1,this.labelDimensions={top:0,left:0,width:0,height:0,yLine:0},this.dirtyLabel=!0,this.from=null,this.to=null,this.via=null,this.originalFromId=[],this.originalToId=[],this.connected=!1,this.widthFixed=!1,this.lengthFixed=!1,this.setProperties(t),this.controlNodesEnabled=!1,this.controlNodes={from:null,to:null,positions:{}},this.connectedNode=null}var o=i(1),n=i(39);s.prototype.setProperties=function(t){if(t){var e=["style","fontSize","fontFace","fontColor","fontFill","width","widthSelectionMultiplier","hoverWidth","arrowScaleFactor","dash","inheritColor"];switch(o.selectiveDeepExtend(e,this.options,t),void 0!==t.from&&(this.fromId=t.from),void 0!==t.to&&(this.toId=t.to),void 0!==t.id&&(this.id=t.id),void 0!==t.label&&(this.label=t.label,this.dirtyLabel=!0),void 0!==t.title&&(this.title=t.title),void 0!==t.value&&(this.value=t.value),void 0!==t.length&&(this.physics.springLength=t.length),void 0!==t.color&&(this.options.inheritColor=!1,o.isString(t.color)?(this.options.color.color=t.color,this.options.color.highlight=t.color):(void 0!==t.color.color&&(this.options.color.color=t.color.color),void 0!==t.color.highlight&&(this.options.color.highlight=t.color.highlight),void 0!==t.color.hover&&(this.options.color.hover=t.color.hover))),this.connect(),this.widthFixed=this.widthFixed||void 0!==t.width,this.lengthFixed=this.lengthFixed||void 0!==t.length,this.widthSelected=this.options.width*this.options.widthSelectionMultiplier,this.options.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}}},s.prototype.connect=function(){this.disconnect(),this.from=this.network.nodes[this.fromId]||null,this.to=this.network.nodes[this.toId]||null,this.connected=this.from&&this.to,this.connected?(this.from.attachEdge(this),this.to.attachEdge(this)):(this.from&&this.from.detachEdge(this),this.to&&this.to.detachEdge(this))},s.prototype.disconnect=function(){this.from&&(this.from.detachEdge(this),this.from=null),this.to&&(this.to.detachEdge(this),this.to=null),this.connected=!1},s.prototype.getTitle=function(){return"function"==typeof this.title?this.title():this.title},s.prototype.getValue=function(){return this.value},s.prototype.setValueRange=function(t,e){if(!this.widthFixed&&void 0!==this.value){var i=(this.options.widthMax-this.options.widthMin)/(e-t);this.options.width=(this.value-t)*i+this.options.widthMin,this.widthSelected=this.options.width*this.options.widthSelectionMultiplier}},s.prototype.draw=function(){throw"Method draw not initialized in edge"},s.prototype.isOverlappingWith=function(t){if(this.connected){var e=10,i=this.from.x,s=this.from.y,o=this.to.x,n=this.to.y,r=t.left,a=t.top,h=this._getDistanceToEdge(i,s,o,n,r,a);return e>h}return!1},s.prototype._getColor=function(){var t=this.options.color;return"to"==this.options.inheritColor?t={highlight:this.to.options.color.highlight.border,hover:this.to.options.color.hover.border,color:this.to.options.color.border}:("from"==this.options.inheritColor||1==this.options.inheritColor)&&(t={highlight:this.from.options.color.highlight.border,hover:this.from.options.color.hover.border,color:this.from.options.color.border}),1==this.selected?t.highlight:1==this.hover?t.hover:t.color},s.prototype._drawLine=function(t){if(t.strokeStyle=this._getColor(),t.lineWidth=this._getLineWidth(),this.from!=this.to){var e,i=this._line(t);if(this.label){if(1==this.options.smoothCurves.enabled&&null!=i){var s=.5*(.5*(this.from.x+i.x)+.5*(this.to.x+i.x)),o=.5*(.5*(this.from.y+i.y)+.5*(this.to.y+i.y));e={x:s,y:o}}else e=this._pointOnLine(.5);this._label(t,this.label,e.x,e.y)}}else{var n,r,a=this.physics.springLength/4,h=this.from;h.width||h.resize(t),h.width>h.height?(n=h.x+h.width/2,r=h.y-a):(n=h.x+a,r=h.y-h.height/2),this._circle(t,n,r,a),e=this._pointOnCircle(n,r,a,.5),this._label(t,this.label,e.x,e.y)}},s.prototype._getLineWidth=function(){return 1==this.selected?Math.max(Math.min(this.widthSelected,this.options.widthMax),.3*this.networkScaleInv):1==this.hover?Math.max(Math.min(this.options.hoverWidth,this.options.widthMax),.3*this.networkScaleInv):Math.max(this.options.width,.3*this.networkScaleInv)},s.prototype._getViaCoordinates=function(){var t=null,e=null,i=this.options.smoothCurves.roundness,s=this.options.smoothCurves.type,o=Math.abs(this.from.x-this.to.x),n=Math.abs(this.from.y-this.to.y);return"discrete"==s||"diagonalCross"==s?Math.abs(this.from.x-this.to.x)this.to.y?this.from.xthis.to.x&&(t=this.from.x-i*n,e=this.from.y-i*n):this.from.ythis.to.x&&(t=this.from.x-i*n,e=this.from.y+i*n)),"discrete"==s&&(t=i*n>o?this.from.x:t)):Math.abs(this.from.x-this.to.x)>Math.abs(this.from.y-this.to.y)&&(this.from.y>this.to.y?this.from.xthis.to.x&&(t=this.from.x-i*o,e=this.from.y-i*o):this.from.ythis.to.x&&(t=this.from.x-i*o,e=this.from.y+i*o)),"discrete"==s&&(e=i*o>n?this.from.y:e)):"straightCross"==s?Math.abs(this.from.x-this.to.x)Math.abs(this.from.y-this.to.y)&&(t=this.from.xthis.to.y?this.from.xthis.to.x&&(t=this.from.x-i*n,e=this.from.y-i*n,t=this.to.x>t?this.to.x:t):this.from.ythis.to.x&&(t=this.from.x-i*n,e=this.from.y+i*n,t=this.to.x>t?this.to.x:t)):Math.abs(this.from.x-this.to.x)>Math.abs(this.from.y-this.to.y)&&(this.from.y>this.to.y?this.from.xe?this.to.y:e):this.from.x>this.to.x&&(t=this.from.x-i*o,e=this.from.y-i*o,e=this.to.y>e?this.to.y:e):this.from.ythis.to.x&&(t=this.from.x-i*o,e=this.from.y+i*o,e=this.to.yd;d++){var l=t.measureText(n[d]).width;h=l>h?l:h}var c=this.options.fontSize*r,p=i-h/2,u=s-c/2;this.labelDimensions={top:u,left:p,width:h,height:c,yLine:o}}void 0!==this.options.fontFill&&null!==this.options.fontFill&&"none"!==this.options.fontFill&&(t.fillStyle=this.options.fontFill,t.fillRect(this.labelDimensions.left,this.labelDimensions.top,this.labelDimensions.width,this.labelDimensions.height)),t.fillStyle=this.options.fontColor||"black",t.textAlign="center",t.textBaseline="middle",o=this.labelDimensions.yLine;for(var d=0;r>d;d++)t.fillText(n[d],i,o),o+=a}},s.prototype._drawDashLine=function(t){t.strokeStyle=1==this.selected?this.options.color.highlight:1==this.hover?this.options.color.hover:this.options.color.color,t.lineWidth=this._getLineWidth();var e=null;if(void 0!==t.mozDash||void 0!==t.setLineDash){var i=[0];i=void 0!==this.options.dash.length&&void 0!==this.options.dash.gap?[this.options.dash.length,this.options.dash.gap]:[5,5],"undefined"!=typeof t.setLineDash?(t.setLineDash(i),t.lineDashOffset=0):(t.mozDash=i,t.mozDashOffset=0),e=this._line(t),"undefined"!=typeof t.setLineDash?(t.setLineDash([0]),t.lineDashOffset=0):(t.mozDash=[0],t.mozDashOffset=0)}else t.beginPath(),t.lineCap="round",void 0!==this.options.dash.altLength?t.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,[this.options.dash.length,this.options.dash.gap,this.options.dash.altLength,this.options.dash.gap]):void 0!==this.options.dash.length&&void 0!==this.options.dash.gap?t.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,[this.options.dash.length,this.options.dash.gap]):(t.moveTo(this.from.x,this.from.y),t.lineTo(this.to.x,this.to.y)),t.stroke();if(this.label){var s;if(1==this.options.smoothCurves.enabled&&null!=e){var o=.5*(.5*(this.from.x+e.x)+.5*(this.to.x+e.x)),n=.5*(.5*(this.from.y+e.y)+.5*(this.to.y+e.y));s={x:o,y:n}}else s=this._pointOnLine(.5);this._label(t,this.label,s.x,s.y)}},s.prototype._pointOnLine=function(t){return{x:(1-t)*this.from.x+t*this.to.x,y:(1-t)*this.from.y+t*this.to.y}},s.prototype._pointOnCircle=function(t,e,i,s){var o=2*(s-3/8)*Math.PI;return{x:t+i*Math.cos(o),y:e-i*Math.sin(o)}},s.prototype._drawArrowCenter=function(t){var e;if(1==this.selected?(t.strokeStyle=this.options.color.highlight,t.fillStyle=this.options.color.highlight):1==this.hover?(t.strokeStyle=this.options.color.hover,t.fillStyle=this.options.color.hover):(t.strokeStyle=this.options.color.color,t.fillStyle=this.options.color.color),t.lineWidth=this._getLineWidth(),this.from!=this.to){var i=this._line(t),s=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x),o=(10+5*this.options.width)*this.options.arrowScaleFactor;if(1==this.options.smoothCurves.enabled&&null!=i){var n=.5*(.5*(this.from.x+i.x)+.5*(this.to.x+i.x)),r=.5*(.5*(this.from.y+i.y)+.5*(this.to.y+i.y));e={x:n,y:r}}else e=this._pointOnLine(.5);t.arrow(e.x,e.y,s,o),t.fill(),t.stroke(),this.label&&this._label(t,this.label,e.x,e.y)}else{var a,h,d=.25*Math.max(100,this.physics.springLength),l=this.from;l.width||l.resize(t),l.width>l.height?(a=l.x+.5*l.width,h=l.y-d):(a=l.x+d,h=l.y-.5*l.height),this._circle(t,a,h,d);var s=.2*Math.PI,o=(10+5*this.options.width)*this.options.arrowScaleFactor;e=this._pointOnCircle(a,h,d,.5),t.arrow(e.x,e.y,s,o),t.fill(),t.stroke(),this.label&&(e=this._pointOnCircle(a,h,d,.5),this._label(t,this.label,e.x,e.y))}},s.prototype._drawArrow=function(t){1==this.selected?(t.strokeStyle=this.options.color.highlight,t.fillStyle=this.options.color.highlight):1==this.hover?(t.strokeStyle=this.options.color.hover,t.fillStyle=this.options.color.hover):(t.strokeStyle=this.options.color.color,t.fillStyle=this.options.color.color),t.lineWidth=this._getLineWidth();var e,i;if(this.from!=this.to){e=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x);var s,o=this.to.x-this.from.x,n=this.to.y-this.from.y,r=Math.sqrt(o*o+n*n),a=this.from.distanceToBorder(t,e+Math.PI),h=(r-a)/r,d=h*this.from.x+(1-h)*this.to.x,l=h*this.from.y+(1-h)*this.to.y;1==this.options.smoothCurves.dynamic&&1==this.options.smoothCurves.enabled?s=this.via:1==this.options.smoothCurves.enabled&&(s=this._getViaCoordinates()),1==this.options.smoothCurves.enabled&&null!=s.x&&(e=Math.atan2(this.to.y-s.y,this.to.x-s.x),o=this.to.x-s.x,n=this.to.y-s.y,r=Math.sqrt(o*o+n*n));var c,p,u=this.to.distanceToBorder(t,e),f=(r-u)/r;if(1==this.options.smoothCurves.enabled&&null!=s.x?(c=(1-f)*s.x+f*this.to.x,p=(1-f)*s.y+f*this.to.y):(c=(1-f)*this.from.x+f*this.to.x,p=(1-f)*this.from.y+f*this.to.y),t.beginPath(),t.moveTo(d,l),1==this.options.smoothCurves.enabled&&null!=s.x?t.quadraticCurveTo(s.x,s.y,c,p):t.lineTo(c,p),t.stroke(),i=(10+5*this.options.width)*this.options.arrowScaleFactor,t.arrow(c,p,e,i),t.fill(),t.stroke(),this.label){var m;if(1==this.options.smoothCurves.enabled&&null!=s){var g=.5*(.5*(this.from.x+s.x)+.5*(this.to.x+s.x)),v=.5*(.5*(this.from.y+s.y)+.5*(this.to.y+s.y));m={x:g,y:v}}else m=this._pointOnLine(.5);this._label(t,this.label,m.x,m.y)}}else{var y,b,_,x=this.from,w=.25*Math.max(100,this.physics.springLength);x.width||x.resize(t),x.width>x.height?(y=x.x+.5*x.width,b=x.y-w,_={x:y,y:x.y,angle:.9*Math.PI}):(y=x.x+w,b=x.y-.5*x.height,_={x:x.x,y:b,angle:.6*Math.PI}),t.beginPath(),t.arc(y,b,w,0,2*Math.PI,!1),t.stroke();var i=(10+5*this.options.width)*this.options.arrowScaleFactor;t.arrow(_.x,_.y,_.angle,i),t.fill(),t.stroke(),this.label&&(m=this._pointOnCircle(y,b,w,.5),this._label(t,this.label,m.x,m.y))}},s.prototype._getDistanceToEdge=function(t,e,i,s,o,n){var r=0;if(this.from!=this.to)if(1==this.options.smoothCurves.enabled){var a,h;if(1==this.options.smoothCurves.enabled&&1==this.options.smoothCurves.dynamic)a=this.via.x,h=this.via.y;else{var d=this._getViaCoordinates();a=d.x,h=d.y}var l,c,p,u,f,m,g,v=1e9;for(c=0;10>c;c++)p=.1*c,u=Math.pow(1-p,2)*t+2*p*(1-p)*a+Math.pow(p,2)*i,f=Math.pow(1-p,2)*e+2*p*(1-p)*h+Math.pow(p,2)*s,c>0&&(l=this._getDistanceToLine(m,g,u,f,o,n),v=v>l?l:v),m=u,g=f;r=v}else r=this._getDistanceToLine(t,e,i,s,o,n);else{var u,f,y,b,_=.25*this.physics.springLength,x=this.from;x.width>x.height?(u=x.x+.5*x.width,f=x.y-_):(u=x.x+_,f=x.y-.5*x.height),y=u-o,b=f-n,r=Math.abs(Math.sqrt(y*y+b*b)-_)}return this.labelDimensions.lefto&&this.labelDimensions.topn?0:r},s.prototype._getDistanceToLine=function(t,e,i,s,o,n){var r=i-t,a=s-e,h=r*r+a*a,d=((o-t)*r+(n-e)*a)/h;d>1?d=1:0>d&&(d=0);var l=t+d*r,c=e+d*a,p=l-o,u=c-n;return Math.sqrt(p*p+u*u)},s.prototype.setScale=function(t){this.networkScaleInv=1/t},s.prototype.select=function(){this.selected=!0},s.prototype.unselect=function(){this.selected=!1},s.prototype.positionBezierNode=function(){null!==this.via&&null!==this.from&&null!==this.to&&(this.via.x=.5*(this.from.x+this.to.x),this.via.y=.5*(this.from.y+this.to.y))},s.prototype._drawControlNodes=function(t){if(1==this.controlNodesEnabled){if(null===this.controlNodes.from&&null===this.controlNodes.to){var e="edgeIdFrom:".concat(this.id),i="edgeIdTo:".concat(this.id),s={nodes:{group:"",radius:8},physics:{damping:0},clustering:{maxNodeSizeIncrements:0,nodeScaling:{width:0,height:0,radius:0}}};this.controlNodes.from=new n({id:e,shape:"dot",color:{background:"#ff4e00",border:"#3c3c3c",highlight:{background:"#07f968"}}},{},{},s),this.controlNodes.to=new n({id:i,shape:"dot",color:{background:"#ff4e00",border:"#3c3c3c",highlight:{background:"#07f968"}}},{},{},s)}0==this.controlNodes.from.selected&&0==this.controlNodes.to.selected&&(this.controlNodes.positions=this.getControlNodePositions(t),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(t),this.controlNodes.to.draw(t)}else this.controlNodes={from:null,to:null,positions:{}}},s.prototype._enableControlNodes=function(){this.controlNodesEnabled=!0},s.prototype._disableControlNodes=function(){this.controlNodesEnabled=!1},s.prototype._getSelectedControlNode=function(t,e){var i=this.controlNodes.positions,s=Math.sqrt(Math.pow(t-i.from.x,2)+Math.pow(e-i.from.y,2)),o=Math.sqrt(Math.pow(t-i.to.x,2)+Math.pow(e-i.to.y,2));return 15>s?(this.connectedNode=this.from,this.from=this.controlNodes.from,this.controlNodes.from):15>o?(this.connectedNode=this.to,this.to=this.controlNodes.to,this.controlNodes.to):null},s.prototype._restoreControlNodes=function(){1==this.controlNodes.from.selected&&(this.from=this.connectedNode,this.connectedNode=null,this.controlNodes.from.unselect()),1==this.controlNodes.to.selected&&(this.to=this.connectedNode,this.connectedNode=null,this.controlNodes.to.unselect())},s.prototype.getControlNodePositions=function(t){var e,i=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x),s=this.to.x-this.from.x,o=this.to.y-this.from.y,n=Math.sqrt(s*s+o*o),r=this.from.distanceToBorder(t,i+Math.PI),a=(n-r)/n,h=a*this.from.x+(1-a)*this.to.x,d=a*this.from.y+(1-a)*this.to.y;1==this.options.smoothCurves.dynamic&&1==this.options.smoothCurves.enabled?e=this.via:1==this.options.smoothCurves.enabled&&(e=this._getViaCoordinates()),1==this.options.smoothCurves.enabled&&null!=e.x&&(i=Math.atan2(this.to.y-e.y,this.to.x-e.x),s=this.to.x-e.x,o=this.to.y-e.y,n=Math.sqrt(s*s+o*o));var l,c,p=this.to.distanceToBorder(t,i),u=(n-p)/n;return 1==this.options.smoothCurves.enabled&&null!=e.x?(l=(1-u)*e.x+u*this.to.x,c=(1-u)*e.y+u*this.to.y):(l=(1-u)*this.from.x+u*this.to.x,c=(1-u)*this.from.y+u*this.to.y),{from:{x:h,y:d},to:{x:l,y:c}}},t.exports=s},function(t,e,i){function s(){this.clear(),this.defaultIndex=0}var o=i(1);s.DEFAULT=[{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},{border:"#FFA500",background:"#FFFF00",highlight:{border:"#FFA500",background:"#FFFFA3"},hover:{border:"#FFA500",background:"#FFFFA3"}},{border:"#FA0A10",background:"#FB7E81",highlight:{border:"#FA0A10",background:"#FFAFB1"},hover:{border:"#FA0A10",background:"#FFAFB1"}},{border:"#41A906",background:"#7BE141",highlight:{border:"#41A906",background:"#A1EC76"},hover:{border:"#41A906",background:"#A1EC76"}},{border:"#E129F0",background:"#EB7DF4",highlight:{border:"#E129F0",background:"#F0B3F5"},hover:{border:"#E129F0",background:"#F0B3F5"}},{border:"#7C29F0",background:"#AD85E4",highlight:{border:"#7C29F0",background:"#D3BDF0"},hover:{border:"#7C29F0",background:"#D3BDF0"}},{border:"#C37F00",background:"#FFA807",highlight:{border:"#C37F00",background:"#FFCA66"},hover:{border:"#C37F00",background:"#FFCA66"}},{border:"#4220FB",background:"#6E6EFD",highlight:{border:"#4220FB",background:"#9B9BFD"},hover:{border:"#4220FB",background:"#9B9BFD"}},{border:"#FD5A77",background:"#FFC0CB",highlight:{border:"#FD5A77",background:"#FFD1D9"},hover:{border:"#FD5A77",background:"#FFD1D9"}},{border:"#4AD63A",background:"#C2FABC",highlight:{border:"#4AD63A",background:"#E6FFE3"},hover:{border:"#4AD63A",background:"#E6FFE3"}}],s.prototype.clear=function(){this.groups={},this.groups.length=function(){var t=0;for(var e in this)this.hasOwnProperty(e)&&t++;return t}},s.prototype.get=function(t){var e=this.groups[t];if(void 0==e){var i=this.defaultIndex%s.DEFAULT.length;this.defaultIndex++,e={},e.color=s.DEFAULT[i],this.groups[t]=e}return e},s.prototype.add=function(t,e){return this.groups[t]=e,e.color&&(e.color=o.parseColor(e.color)),e},t.exports=s},function(t){function e(){this.images={},this.callback=void 0}e.prototype.setOnloadCallback=function(t){this.callback=t},e.prototype.load=function(t,e){var i=this.images[t];if(void 0==i){var s=this;i=new Image,this.images[t]=i,i.onload=function(){s.callback&&s.callback(this)},i.onerror=function(){this.src=e,s.callback&&s.callback(this)},i.src=t}return i},t.exports=e},function(t,e,i){function s(t,e,i,s){var n=o.selectiveBridgeObject(["nodes"],s);this.options=n.nodes,this.selected=!1,this.hover=!1,this.edges=[],this.dynamicEdges=[],this.reroutedEdges={},this.fontDrawThreshold=3,this.id=void 0,this.x=null,this.y=null,this.allowedToMoveX=!1,this.allowedToMoveY=!1,this.xFixed=!1,this.yFixed=!1,this.horizontalAlignLeft=!0,this.verticalAlignTop=!0,this.baseRadiusValue=s.nodes.radius,this.radiusFixed=!1,this.level=-1,this.preassignedLevel=!1,this.hierarchyEnumerated=!1,this.labelDimensions={top:0,left:0,width:0,height:0,yLine:0},this.imagelist=e,this.grouplist=i,this.fx=0,this.fy=0,this.vx=0,this.vy=0,this.damping=s.physics.damping,this.fixedData={x:null,y:null},this.setProperties(t,n),this.resetCluster(),this.dynamicEdgesLength=0,this.clusterSession=0,this.clusterSizeWidthFactor=s.clustering.nodeScaling.width,this.clusterSizeHeightFactor=s.clustering.nodeScaling.height,this.clusterSizeRadiusFactor=s.clustering.nodeScaling.radius,this.maxNodeSizeIncrements=s.clustering.maxNodeSizeIncrements,this.growthIndicator=0,this.networkScaleInv=1,this.networkScale=1,this.canvasTopLeft={x:-300,y:-300},this.canvasBottomRight={x:300,y:300},this.parentEdgeId=null}var o=i(1);s.prototype.resetCluster=function(){this.formationScale=void 0,this.clusterSize=1,this.containedNodes={},this.containedEdges={},this.clusterSessions=[]},s.prototype.attachEdge=function(t){-1==this.edges.indexOf(t)&&this.edges.push(t),-1==this.dynamicEdges.indexOf(t)&&this.dynamicEdges.push(t),this.dynamicEdgesLength=this.dynamicEdges.length},s.prototype.detachEdge=function(t){var e=this.edges.indexOf(t);-1!=e&&this.edges.splice(e,1),e=this.dynamicEdges.indexOf(t),-1!=e&&this.dynamicEdges.splice(e,1),this.dynamicEdgesLength=this.dynamicEdges.length},s.prototype.setProperties=function(t,e){if(t){var i=["borderWidth","borderWidthSelected","shape","image","brokenImage","radius","fontColor","fontSize","fontFace","fontFill","group","mass"];if(o.selectiveDeepExtend(i,this.options,t),void 0!==t.id&&(this.id=t.id),void 0!==t.label&&(this.label=t.label,this.originalLabel=t.label),void 0!==t.title&&(this.title=t.title),void 0!==t.x&&(this.x=t.x),void 0!==t.y&&(this.y=t.y),void 0!==t.value&&(this.value=t.value),void 0!==t.level&&(this.level=t.level,this.preassignedLevel=!0),void 0!==t.horizontalAlignLeft&&(this.horizontalAlignLeft=t.horizontalAlignLeft),void 0!==t.verticalAlignTop&&(this.verticalAlignTop=t.verticalAlignTop),void 0!==t.triggerFunction&&(this.triggerFunction=t.triggerFunction),void 0===this.id)throw"Node must have an id";if("number"==typeof this.options.group||"string"==typeof this.options.group&&""!=this.options.group){var s=this.grouplist.get(this.options.group);for(var n in s)s.hasOwnProperty(n)&&(this.options[n]=s[n])}if(void 0!==t.radius&&(this.baseRadiusValue=this.options.radius),void 0!==t.color&&(this.options.color=o.parseColor(t.color)),void 0!==this.options.image&&""!=this.options.image){if(!this.imagelist)throw"No imagelist provided";this.imageObj=this.imagelist.load(this.options.image,this.options.brokenImage)}switch(void 0!==t.allowedToMoveX?(this.xFixed=!t.allowedToMoveX,this.allowedToMoveX=t.allowedToMoveX):void 0!==t.x&&0==this.allowedToMoveX&&(this.xFixed=!0),void 0!==t.allowedToMoveY?(this.yFixed=!t.allowedToMoveY,this.allowedToMoveY=t.allowedToMoveY):void 0!==t.y&&0==this.allowedToMoveY&&(this.yFixed=!0),this.radiusFixed=this.radiusFixed||void 0!==t.radius,"image"==this.options.shape&&(this.options.radiusMin=e.nodes.widthMin,this.options.radiusMax=e.nodes.widthMax),this.options.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;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}this._reset()}},s.prototype.select=function(){this.selected=!0,this._reset()},s.prototype.unselect=function(){this.selected=!1,this._reset()},s.prototype.clearSizeCache=function(){this._reset()},s.prototype._reset=function(){this.width=void 0,this.height=void 0},s.prototype.getTitle=function(){return"function"==typeof this.title?this.title():this.title},s.prototype.distanceToBorder=function(t,e){var i=1;switch(this.width||this.resize(t),this.options.shape){case"circle":case"dot":return this.options.radius+i;case"ellipse":var s=this.width/2,o=this.height/2,n=Math.sin(e)*s,r=Math.cos(e)*o;return s*o/Math.sqrt(n*n+r*r);case"box":case"image":case"text":default:return this.width?Math.min(Math.abs(this.width/2/Math.cos(e)),Math.abs(this.height/2/Math.sin(e)))+i:0}},s.prototype._setForce=function(t,e){this.fx=t,this.fy=e},s.prototype._addForce=function(t,e){this.fx+=t,this.fy+=e},s.prototype.discreteStep=function(t){if(this.xFixed)this.fx=0,this.vx=0;else{var e=this.damping*this.vx,i=(this.fx-e)/this.options.mass;this.vx+=i*t,this.x+=this.vx*t}if(this.yFixed)this.fy=0,this.vy=0;else{var s=this.damping*this.vy,o=(this.fy-s)/this.options.mass;this.vy+=o*t,this.y+=this.vy*t}},s.prototype.discreteStepLimited=function(t,e){if(this.xFixed)this.fx=0,this.vx=0;else{var i=this.damping*this.vx,s=(this.fx-i)/this.options.mass;this.vx+=s*t,this.vx=Math.abs(this.vx)>e?this.vx>0?e:-e:this.vx,this.x+=this.vx*t}if(this.yFixed)this.fy=0,this.vy=0;else{var o=this.damping*this.vy,n=(this.fy-o)/this.options.mass;this.vy+=n*t,this.vy=Math.abs(this.vy)>e?this.vy>0?e:-e:this.vy,this.y+=this.vy*t}},s.prototype.isFixed=function(){return this.xFixed&&this.yFixed},s.prototype.isMoving=function(t){var e=Math.sqrt(Math.pow(this.vx,2)+Math.pow(this.vy,2));return e>t},s.prototype.isSelected=function(){return this.selected},s.prototype.getValue=function(){return this.value},s.prototype.getDistance=function(t,e){var i=this.x-t,s=this.y-e;return Math.sqrt(i*i+s*s)},s.prototype.setValueRange=function(t,e){if(!this.radiusFixed&&void 0!==this.value)if(e==t)this.options.radius=(this.options.radiusMin+this.options.radiusMax)/2;else{var i=(this.options.radiusMax-this.options.radiusMin)/(e-t);this.options.radius=(this.value-t)*i+this.options.radiusMin}this.baseRadiusValue=this.options.radius},s.prototype.draw=function(){throw"Draw method not initialized for node"},s.prototype.resize=function(){throw"Resize method not initialized for node"},s.prototype.isOverlappingWith=function(t){return this.leftt.left&&this.topt.top},s.prototype._resizeImage=function(){if(!this.width||!this.height){var t,e;if(this.value){this.options.radius=this.baseRadiusValue;var i=this.imageObj.height/this.imageObj.width;void 0!==i?(t=this.options.radius||this.imageObj.width,e=this.options.radius*i||this.imageObj.height):(t=0,e=0)}else t=this.imageObj.width,e=this.imageObj.height;this.width=t,this.height=e,this.growthIndicator=0,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.options.radius+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-t)}},s.prototype._drawImage=function(t){this._resizeImage(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e;if(0!=this.imageObj.width){if(this.clusterSize>1){var i=this.clusterSize>1?10:0;i*=this.networkScaleInv,i=Math.min(.2*this.width,i),t.globalAlpha=.5,t.drawImage(this.imageObj,this.left-i,this.top-i,this.width+2*i,this.height+2*i)}t.globalAlpha=1,t.drawImage(this.imageObj,this.left,this.top,this.width,this.height),e=this.y+this.height/2}else e=this.y;this._label(t,this.label,this.x,e,void 0,"top")},s.prototype._resizeBox=function(t){if(!this.width){var e=5,i=this.getTextSize(t);this.width=i.width+2*e,this.height=i.height+2*e,this.width+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.growthIndicator=this.width-(i.width+2*e)}},s.prototype._drawBox=function(t){this._resizeBox(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=this.options.borderWidth,s=this.options.borderWidthSelected||2*this.options.borderWidth;t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.roundRect(this.left-2*t.lineWidth,this.top-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth,this.options.radius),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.options.color.background,t.roundRect(this.left,this.top,this.width,this.height,this.options.radius),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._resizeDatabase=function(t){if(!this.width){var e=5,i=this.getTextSize(t),s=i.width+2*e;this.width=s,this.height=s,this.width+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.options.radius+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-s}},s.prototype._drawDatabase=function(t){this._resizeDatabase(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=this.options.borderWidth,s=this.options.borderWidthSelected||2*this.options.borderWidth;t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.database(this.x-this.width/2-2*t.lineWidth,this.y-.5*this.height-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t.database(this.x-this.width/2,this.y-.5*this.height,this.width,this.height),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._resizeCircle=function(t){if(!this.width){var e=5,i=this.getTextSize(t),s=Math.max(i.width,i.height)+2*e;this.options.radius=s/2,this.width=s,this.height=s,this.options.radius+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.options.radius-.5*s}},s.prototype._drawCircle=function(t){this._resizeCircle(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=this.options.borderWidth,s=this.options.borderWidthSelected||2*this.options.borderWidth;t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.circle(this.x,this.y,this.options.radius+2*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t.circle(this.x,this.y,this.options.radius),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._resizeEllipse=function(t){if(!this.width){var e=this.getTextSize(t);this.width=1.5*e.width,this.height=2*e.height,this.width1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.ellipse(this.left-2*t.lineWidth,this.top-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t.ellipse(this.left,this.top,this.width,this.height),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._drawDot=function(t){this._drawShape(t,"circle")},s.prototype._drawTriangle=function(t){this._drawShape(t,"triangle")},s.prototype._drawTriangleDown=function(t){this._drawShape(t,"triangleDown")},s.prototype._drawSquare=function(t){this._drawShape(t,"square")},s.prototype._drawStar=function(t){this._drawShape(t,"star")},s.prototype._resizeShape=function(){if(!this.width){this.options.radius=this.baseRadiusValue;var t=2*this.options.radius;this.width=t,this.height=t,this.width+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.options.radius+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-t}},s.prototype._drawShape=function(t,e){this._resizeShape(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var i=2.5,s=this.options.borderWidth,o=this.options.borderWidthSelected||2*this.options.borderWidth,n=2;switch(e){case"dot":n=2;break;case"square":n=2;break;case"triangle":n=3;break;case"triangleDown":n=3;break;case"star":n=4}t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?o:s)+(this.clusterSize>1?i:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t[e](this.x,this.y,this.options.radius+n*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?o:s)+(this.clusterSize>1?i:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t[e](this.x,this.y,this.options.radius),t.fill(),t.stroke(),this.label&&this._label(t,this.label,this.x,this.y+this.height/2,void 0,"top",!0)},s.prototype._resizeText=function(t){if(!this.width){var e=5,i=this.getTextSize(t);this.width=i.width+2*e,this.height=i.height+2*e,this.width+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.options.radius+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-(i.width+2*e)}},s.prototype._drawText=function(t){this._resizeText(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2,this._label(t,this.label,this.x,this.y)},s.prototype._label=function(t,e,i,s,o,n,r){if(e&&Number(this.options.fontSize)*this.networkScale>this.fontDrawThreshold){t.font=(this.selected?"bold ":"")+this.options.fontSize+"px "+this.options.fontFace;var a=e.split("\n"),h=a.length,d=Number(this.options.fontSize)+4,l=s+(1-h)/2*d;1==r&&(l=s+(1-h)/(2*d));for(var c=t.measureText(a[0]).width,p=1;h>p;p++){var u=t.measureText(a[p]).width;c=u>c?u:c}var f=this.options.fontSize*h,m=i-c/2,g=s-f/2;"top"==n&&(g+=.5*d),this.labelDimensions={top:g,left:m,width:c,height:f,yLine:l},void 0!==this.options.fontFill&&null!==this.options.fontFill&&"none"!==this.options.fontFill&&(t.fillStyle=this.options.fontFill,t.fillRect(m,g,c,f)),t.fillStyle=this.options.fontColor||"black",t.textAlign=o||"center",t.textBaseline=n||"middle";for(var p=0;h>p;p++)t.fillText(a[p],i,l),l+=d}},s.prototype.getTextSize=function(t){if(void 0!==this.label){t.font=(this.selected?"bold ":"")+this.options.fontSize+"px "+this.options.fontFace;for(var e=this.label.split("\n"),i=(Number(this.options.fontSize)+4)*e.length,s=0,o=0,n=e.length;n>o;o++)s=Math.max(s,t.measureText(e[o]).width);return{width:s,height:i}}return{width:0,height:0}},s.prototype.inArea=function(){return void 0!==this.width?this.x+this.width*this.networkScaleInv>=this.canvasTopLeft.x&&this.x-this.width*this.networkScaleInv=this.canvasTopLeft.y&&this.y-this.height*this.networkScaleInv=this.canvasTopLeft.x&&this.x=this.canvasTopLeft.y&&this.ys&&(n=s-e-this.padding),no&&(r=o-i-this.padding),ri;i++)if(e.id===r.nodes[i].id){o=r.nodes[i];break}for(o||(o={id:e.id},t.node&&(o.attr=a(o.attr,t.node))),i=n.length-1;i>=0;i--){var h=n[i];h.nodes||(h.nodes=[]),-1==h.nodes.indexOf(o)&&h.nodes.push(o)}e.attr&&(o.attr=a(o.attr,e.attr))}function l(t,e){if(t.edges||(t.edges=[]),t.edges.push(e),t.edge){var i=a({},t.edge);e.attr=a(i,e.attr)}}function c(t,e,i,s,o){var n={from:e,to:i,type:s};return t.edge&&(n.attr=a({},t.edge)),n.attr=a(n.attr||{},o),n}function p(){for(k=M.NULL,L="";" "==O||" "==O||"\n"==O||"\r"==O;)o();do{var t=!1;if("#"==O){for(var e=T-1;" "==E.charAt(e)||" "==E.charAt(e);)e--;if("\n"==E.charAt(e)||""==E.charAt(e)){for(;""!=O&&"\n"!=O;)o();t=!0}}if("/"==O&&"/"==n()){for(;""!=O&&"\n"!=O;)o();t=!0}if("/"==O&&"*"==n()){for(;""!=O;){if("*"==O&&"/"==n()){o(),o();break}o()}t=!0}for(;" "==O||" "==O||"\n"==O||"\r"==O;)o()}while(t);if(""==O)return void(k=M.DELIMITER);var i=O+n();if(C[i])return k=M.DELIMITER,L=i,o(),void o();if(C[O])return k=M.DELIMITER,L=O,void o();if(r(O)||"-"==O){for(L+=O,o();r(O);)L+=O,o();return"false"==L?L=!1:"true"==L?L=!0:isNaN(Number(L))||(L=Number(L)),void(k=M.IDENTIFIER)}if('"'==O){for(o();""!=O&&('"'!=O||'"'==O&&'"'==n());)L+=O,'"'==O&&o(),o();if('"'!=O)throw x('End of string " expected');return o(),void(k=M.IDENTIFIER)}for(k=M.UNKNOWN;""!=O;)L+=O,o();throw new SyntaxError('Syntax error in part "'+w(L,30)+'"')}function u(){var t={};if(s(),p(),"strict"==L&&(t.strict=!0,p()),("graph"==L||"digraph"==L)&&(t.type=L,p()),k==M.IDENTIFIER&&(t.id=L,p()),"{"!=L)throw x("Angle bracket { expected");if(p(),f(t),"}"!=L)throw x("Angle bracket } expected");if(p(),""!==L)throw x("End of file expected");return p(),delete t.node,delete t.edge,delete t.graph,t}function f(t){for(;""!==L&&"}"!=L;)m(t),";"==L&&p()}function m(t){var e=g(t);if(e)return void b(t,e);var i=v(t);if(!i){if(k!=M.IDENTIFIER)throw x("Identifier expected");var s=L;if(p(),"="==L){if(p(),k!=M.IDENTIFIER)throw x("Identifier expected");t[s]=L,p()}else y(t,s)}}function g(t){var e=null;if("subgraph"==L&&(e={},e.type="subgraph",p(),k==M.IDENTIFIER&&(e.id=L,p())),"{"==L){if(p(),e||(e={}),e.parent=t,e.node=t.node,e.edge=t.edge,e.graph=t.graph,f(e),"}"!=L)throw x("Angle bracket } expected");p(),delete e.node,delete e.edge,delete e.graph,delete e.parent,t.subgraphs||(t.subgraphs=[]),t.subgraphs.push(e)}return e}function v(t){return"node"==L?(p(),t.node=_(),"node"):"edge"==L?(p(),t.edge=_(),"edge"):"graph"==L?(p(),t.graph=_(),"graph"):null}function y(t,e){var i={id:e},s=_();s&&(i.attr=s),d(t,i),b(t,e)}function b(t,e){for(;"->"==L||"--"==L;){var i,s=L;p();var o=g(t);if(o)i=o;else{if(k!=M.IDENTIFIER)throw x("Identifier or subgraph expected");i=L,d(t,{id:i}),p()}var n=_(),r=c(t,e,i,s,n);l(t,r),e=i}}function _(){for(var t=null;"["==L;){for(p(),t={};""!==L&&"]"!=L;){if(k!=M.IDENTIFIER)throw x("Attribute name expected");var e=L;if(p(),"="!=L)throw x("Equal sign = expected");if(p(),k!=M.IDENTIFIER)throw x("Attribute value expected");var i=L;h(t,e,i),p(),","==L&&p()}if("]"!=L)throw x("Bracket ] expected");p()}return t}function x(t){return new SyntaxError(t+', got "'+w(L,30)+'" (char '+T+")")}function w(t,e){return t.length<=e?t:t.substr(0,27)+"..."}function S(t,e,i){Array.isArray(t)?t.forEach(function(t){Array.isArray(e)?e.forEach(function(e){i(t,e)}):i(t,e)}):Array.isArray(e)?e.forEach(function(e){i(t,e)}):i(t,e)}function D(t){function e(t){var e={from:t.from,to:t.to};return a(e,t.attr),e.style="->"==t.type?"arrow":"line",e}var s=i(t),o={nodes:[],edges:[],options:{}};return s.nodes&&s.nodes.forEach(function(t){var e={id:t.id,label:String(t.label||t.id)};a(e,t.attr),e.image&&(e.shape="image"),o.nodes.push(e)}),s.edges&&s.edges.forEach(function(t){var i,s;i=t.from instanceof Object?t.from.nodes:{id:t.from},s=t.to instanceof Object?t.to.nodes:{id:t.to},t.from instanceof Object&&t.from.edges&&t.from.edges.forEach(function(t){var i=e(t);o.edges.push(i)}),S(i,s,function(i,s){var n=c(o,i.id,s.id,t.type,t.attr),r=e(n);o.edges.push(r)}),t.to instanceof Object&&t.to.edges&&t.to.edges.forEach(function(t){var i=e(t);o.edges.push(i)})}),s.attr&&(o.options=s.attr),o}var M={NULL:0,DELIMITER:1,IDENTIFIER:2,UNKNOWN:3},C={"{":!0,"}":!0,"[":!0,"]":!0,";":!0,"=":!0,",":!0,"->":!0,"--":!0},E="",T=0,O="",L="",k=M.NULL,N=/[a-zA-Z_0-9.:#]/;e.parseDOT=i,e.DOTToGraph=D},function(t,e){function i(t,e){var i=[],s=[];this.options={edges:{inheritColor:!0},nodes:{allowedToMove:!1,parseColor:!1}},void 0!==e&&(this.options.nodes.allowedToMove=e.allowedToMove|!1,this.options.nodes.parseColor=e.parseColor|!1,this.options.edges.inheritColor=e.inheritColor|!0);for(var o=t.edges,n=t.nodes,r=0;r=o&&(o=864e5),i=new Date(i.valueOf()-.05*o),s=new Date(s.valueOf()+.05*o)}if(null!==i||null!==s){var n=t&&void 0!==t.animate?t.animate:!0;this.range.setRange(i,s,n)}},s.prototype.setWindow=function(t,e,i){var s=i&&void 0!==i.animate?i.animate:!0;if(1==arguments.length){var o=arguments[0];this.range.setRange(o.start,o.end,s)}else this.range.setRange(t,e,s)},s.prototype.moveTo=function(t,e){var i=this.range.end-this.range.start,s=r.convert(t,"Date").valueOf(),o=s-i/2,n=s+i/2,a=e&&void 0!==e.animate?e.animate:!0;this.range.setRange(o,n,a)},s.prototype.getWindow=function(){var t=this.range.getRange();return{start:new Date(t.start),end:new Date(t.end)}},s.prototype.redraw=function(){var t=!1,e=this.options,i=this.props,s=this.dom;if(s){h.updateHiddenDates(this.body,this.options.hiddenDates),"top"==e.orientation?(r.addClassName(s.root,"top"),r.removeClassName(s.root,"bottom")):(r.removeClassName(s.root,"top"),r.addClassName(s.root,"bottom")),s.root.style.maxHeight=r.option.asSize(e.maxHeight,""),s.root.style.minHeight=r.option.asSize(e.minHeight,""),s.root.style.width=r.option.asSize(e.width,""),i.border.left=(s.centerContainer.offsetWidth-s.centerContainer.clientWidth)/2,i.border.right=i.border.left,i.border.top=(s.centerContainer.offsetHeight-s.centerContainer.clientHeight)/2,i.border.bottom=i.border.top;var o=s.root.offsetHeight-s.root.clientHeight,n=s.root.offsetWidth-s.root.clientWidth;0===s.centerContainer.clientHeight&&(i.border.left=i.border.top,i.border.right=i.border.left),0===s.root.clientHeight&&(n=o),i.center.height=s.center.offsetHeight,i.left.height=s.left.offsetHeight,i.right.height=s.right.offsetHeight,i.top.height=s.top.clientHeight||-i.border.top,i.bottom.height=s.bottom.clientHeight||-i.border.bottom;var a=Math.max(i.left.height,i.center.height,i.right.height),d=i.top.height+a+i.bottom.height+o+i.border.top+i.border.bottom;s.root.style.height=r.option.asSize(e.height,d+"px"),i.root.height=s.root.offsetHeight,i.background.height=i.root.height-o;var l=i.root.height-i.top.height-i.bottom.height-o;i.centerContainer.height=l,i.leftContainer.height=l,i.rightContainer.height=i.leftContainer.height,i.root.width=s.root.offsetWidth,i.background.width=i.root.width-n,i.left.width=s.leftContainer.clientWidth||-i.border.left,i.leftContainer.width=i.left.width,i.right.width=s.rightContainer.clientWidth||-i.border.right,i.rightContainer.width=i.right.width;var c=i.root.width-i.left.width-i.right.width-n;i.center.width=c,i.centerContainer.width=c,i.top.width=c,i.bottom.width=c,s.background.style.height=i.background.height+"px",s.backgroundVertical.style.height=i.background.height+"px",s.backgroundHorizontal.style.height=i.centerContainer.height+"px",s.centerContainer.style.height=i.centerContainer.height+"px",s.leftContainer.style.height=i.leftContainer.height+"px",s.rightContainer.style.height=i.rightContainer.height+"px",s.background.style.width=i.background.width+"px",s.backgroundVertical.style.width=i.centerContainer.width+"px",s.backgroundHorizontal.style.width=i.background.width+"px",s.centerContainer.style.width=i.center.width+"px",s.top.style.width=i.top.width+"px",s.bottom.style.width=i.bottom.width+"px",s.background.style.left="0",s.background.style.top="0",s.backgroundVertical.style.left=i.left.width+i.border.left+"px",s.backgroundVertical.style.top="0",s.backgroundHorizontal.style.left="0",s.backgroundHorizontal.style.top=i.top.height+"px",s.centerContainer.style.left=i.left.width+"px",s.centerContainer.style.top=i.top.height+"px",s.leftContainer.style.left="0",s.leftContainer.style.top=i.top.height+"px",s.rightContainer.style.left=i.left.width+i.center.width+"px",s.rightContainer.style.top=i.top.height+"px",s.top.style.left=i.left.width+"px",s.top.style.top="0",s.bottom.style.left=i.left.width+"px",s.bottom.style.top=i.top.height+i.centerContainer.height+"px",this._updateScrollTop();var p=this.props.scrollTop;"bottom"==e.orientation&&(p+=Math.max(this.props.centerContainer.height-this.props.center.height-this.props.border.top-this.props.border.bottom,0)),s.center.style.left="0",s.center.style.top=p+"px",s.left.style.left="0",s.left.style.top=p+"px",s.right.style.left="0",s.right.style.top=p+"px";var u=0==this.props.scrollTop?"hidden":"",f=this.props.scrollTop==this.props.scrollTopMin?"hidden":"";s.shadowTop.style.visibility=u,s.shadowBottom.style.visibility=f,s.shadowTopLeft.style.visibility=u,s.shadowBottomLeft.style.visibility=f,s.shadowTopRight.style.visibility=u,s.shadowBottomRight.style.visibility=f,this.components.forEach(function(e){t=e.redraw()||t}),t&&this.redraw()}},s.prototype.repaint=function(){throw new Error("Function repaint is deprecated. Use redraw instead.")},s.prototype.setCurrentTime=function(t){if(!this.currentTime)throw new Error("Option showCurrentTime must be true");this.currentTime.setCurrentTime(t)},s.prototype.getCurrentTime=function(){if(!this.currentTime)throw new Error("Option showCurrentTime must be true");return this.currentTime.getCurrentTime()},s.prototype._toTime=function(t){return h.toTime(this.body,this.range,t,this.props.center.width)},s.prototype._toGlobalTime=function(t){return h.toTime(this.body,this.range,t,this.props.root.width)},s.prototype._toScreen=function(t){return h.toScreen(this,t,this.props.center.width)},s.prototype._toGlobalScreen=function(t){return h.toScreen(this,t,this.props.root.width)},s.prototype._initAutoResize=function(){1==this.options.autoResize?this._startAutoResize():this._stopAutoResize()},s.prototype._startAutoResize=function(){var t=this;this._stopAutoResize(),this._onResize=function(){return 1!=t.options.autoResize?void t._stopAutoResize():void(t.dom.root&&(t.dom.root.offsetWidth!=t.props.lastWidth||t.dom.root.offsetHeight!=t.props.lastHeight)&&(t.props.lastWidth=t.dom.root.offsetWidth,t.props.lastHeight=t.dom.root.offsetHeight,t.emit("change")))},r.addEventListener(window,"resize",this._onResize),this.watchTimer=setInterval(this._onResize,1e3)},s.prototype._stopAutoResize=function(){this.watchTimer&&(clearInterval(this.watchTimer),this.watchTimer=void 0),r.removeEventListener(window,"resize",this._onResize),this._onResize=null},s.prototype._onTouch=function(){this.touch.allowDragging=!0},s.prototype._onPinch=function(){this.touch.allowDragging=!1},s.prototype._onDragStart=function(){this.touch.initialScrollTop=this.props.scrollTop},s.prototype._onDrag=function(t){if(this.touch.allowDragging){var e=t.gesture.deltaY,i=this._getScrollTop(),s=this._setScrollTop(this.touch.initialScrollTop+e);s!=i&&this.redraw()}},s.prototype._setScrollTop=function(t){return this.props.scrollTop=t,this._updateScrollTop(),this.props.scrollTop},s.prototype._updateScrollTop=function(){var t=Math.min(this.props.centerContainer.height-this.props.center.height,0);return t!=this.props.scrollTopMin&&("bottom"==this.options.orientation&&(this.props.scrollTop+=t-this.props.scrollTopMin),this.props.scrollTopMin=t),this.props.scrollTop>0&&(this.props.scrollTop=0),this.props.scrollTops;s++){var o=s%2===0?1.3*i:.5*i;this.lineTo(t+o*Math.sin(2*s*Math.PI/10),e-o*Math.cos(2*s*Math.PI/10))}this.closePath()},CanvasRenderingContext2D.prototype.roundRect=function(t,e,i,s,o){var n=Math.PI/180;0>i-2*o&&(o=i/2),0>s-2*o&&(o=s/2),this.beginPath(),this.moveTo(t+o,e),this.lineTo(t+i-o,e),this.arc(t+i-o,e+o,o,270*n,360*n,!1),this.lineTo(t+i,e+s-o),this.arc(t+i-o,e+s-o,o,0,90*n,!1),this.lineTo(t+o,e+s),this.arc(t+o,e+s-o,o,90*n,180*n,!1),this.lineTo(t,e+o),this.arc(t+o,e+o,o,180*n,270*n,!1)},CanvasRenderingContext2D.prototype.ellipse=function(t,e,i,s){var o=.5522848,n=i/2*o,r=s/2*o,a=t+i,h=e+s,d=t+i/2,l=e+s/2;this.beginPath(),this.moveTo(t,l),this.bezierCurveTo(t,l-r,d-n,e,d,e),this.bezierCurveTo(d+n,e,a,l-r,a,l),this.bezierCurveTo(a,l+r,d+n,h,d,h),this.bezierCurveTo(d-n,h,t,l+r,t,l)},CanvasRenderingContext2D.prototype.database=function(t,e,i,s){var o=1/3,n=i,r=s*o,a=.5522848,h=n/2*a,d=r/2*a,l=t+n,c=e+r,p=t+n/2,u=e+r/2,f=e+(s-r/2),m=e+s;this.beginPath(),this.moveTo(l,u),this.bezierCurveTo(l,u+d,p+h,c,p,c),this.bezierCurveTo(p-h,c,t,u+d,t,u),this.bezierCurveTo(t,u-d,p-h,e,p,e),this.bezierCurveTo(p+h,e,l,u-d,l,u),this.lineTo(l,f),this.bezierCurveTo(l,f+d,p+h,m,p,m),this.bezierCurveTo(p-h,m,t,f+d,t,f),this.lineTo(t,u)},CanvasRenderingContext2D.prototype.arrow=function(t,e,i,s){var o=t-s*Math.cos(i),n=e-s*Math.sin(i),r=t-.9*s*Math.cos(i),a=e-.9*s*Math.sin(i),h=o+s/3*Math.cos(i+.5*Math.PI),d=n+s/3*Math.sin(i+.5*Math.PI),l=o+s/3*Math.cos(i-.5*Math.PI),c=n+s/3*Math.sin(i-.5*Math.PI);this.beginPath(),this.moveTo(t,e),this.lineTo(h,d),this.lineTo(r,a),this.lineTo(l,c),this.closePath()},CanvasRenderingContext2D.prototype.dashedLine=function(t,e,i,s,o){o||(o=[10,5]),0==p&&(p=.001);var n=o.length;this.moveTo(t,e);for(var r=i-t,a=s-e,h=a/r,d=Math.sqrt(r*r+a*a),l=0,c=!0;d>=.1;){var p=o[l++%n];p>d&&(p=d);var u=Math.sqrt(p*p/(1+h*h));0>r&&(u=-u),t+=u,e+=h*u,this[c?"lineTo":"moveTo"](t,e),d-=p,c=!c}})},function(t,e,i){var s=i(62),o=i(56),n=i(57),r=i(58),a=i(59),h=i(60),d=i(61);e._loadMixin=function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e])},e._clearMixin=function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=void 0)},e._loadPhysicsSystem=function(){this._loadMixin(s),this._loadSelectedForceSolver(),1==this.constants.configurePhysics&&this._loadPhysicsConfiguration()},e._loadClusterSystem=function(){this.clusterSession=0,this.hubThreshold=5,this._loadMixin(o)},e._loadSectorSystem=function(){this.sectors={},this.activeSector=["default"],this.sectors.active={},this.sectors.active["default"]={nodes:{},edges:{},nodeIndices:[],formationScale:1,drawingNode:void 0},this.sectors.frozen={},this.sectors.support={nodes:{},edges:{},nodeIndices:[],formationScale:1,drawingNode:void 0},this.nodeIndices=this.sectors.active["default"].nodeIndices,this._loadMixin(n)},e._loadSelectionSystem=function(){this.selectionObj={nodes:{},edges:{}},this._loadMixin(r)},e._loadManipulationSystem=function(){this.blockConnectingEdgeSelection=!1,this.forceAppendSelection=!1,1==this.constants.dataManipulation.enabled?(void 0===this.manipulationDiv&&(this.manipulationDiv=document.createElement("div"),this.manipulationDiv.className="network-manipulationDiv",this.manipulationDiv.id="network-manipulationDiv",this.manipulationDiv.style.display=1==this.editMode?"block":"none",this.frame.appendChild(this.manipulationDiv)),void 0===this.editModeDiv&&(this.editModeDiv=document.createElement("div"),this.editModeDiv.className="network-manipulation-editMode",this.editModeDiv.id="network-manipulation-editMode",this.editModeDiv.style.display=1==this.editMode?"none":"block",this.frame.appendChild(this.editModeDiv)),void 0===this.closeDiv&&(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.frame.appendChild(this.closeDiv)),this._loadMixin(a),this._createManipulatorBar()):void 0!==this.manipulationDiv&&(this._createManipulatorBar(),this.frame.removeChild(this.manipulationDiv),this.frame.removeChild(this.editModeDiv),this.frame.removeChild(this.closeDiv),this.manipulationDiv=void 0,this.editModeDiv=void 0,this.closeDiv=void 0,this._clearMixin(a))},e._loadNavigationControls=function(){this._loadMixin(h),this._cleanNavigation(),1==this.constants.navigation.enabled&&this._loadNavigationElements()},e._loadHierarchySystem=function(){this._loadMixin(d)}},function(t,e,i){function s(t){this.active=!1,this.dom={container:t},this.dom.overlay=document.createElement("div"),this.dom.overlay.className="overlay",this.dom.container.appendChild(this.dom.overlay),this.hammer=a(this.dom.overlay,{prevent_default:!1}),this.hammer.on("tap",this._onTapOverlay.bind(this));var e=this,i=["touch","pinch","doubletap","hold","dragstart","drag","dragend","mousewheel","DOMMouseScroll"];i.forEach(function(t){e.hammer.on(t,function(t){t.stopPropagation()})}),this.windowHammer=a(window,{prevent_default:!1}),this.windowHammer.on("tap",function(i){o(i.target,t)||e.deactivate()}),this.escListener=this.deactivate.bind(this)}function o(t,e){for(;t;){if(t===e)return!0;t=t.parentNode}return!1}var n=i(54),r=i(52),a=i(44),h=i(1);r(s.prototype),s.current=null,s.prototype.destroy=function(){this.deactivate(),this.dom.overlay.parentNode.removeChild(this.dom.overlay),this.hammer=null,this.windowHammer=null},s.prototype.activate=function(){s.current&&s.current.deactivate(),s.current=this,this.active=!0,this.dom.overlay.style.display="none",h.addClassName(this.dom.container,"vis-active"),this.emit("change"),this.emit("activate"),n.bind("esc",this.escListener)},s.prototype.deactivate=function(){this.active=!1,this.dom.overlay.style.display="",h.removeClassName(this.dom.container,"vis-active"),n.unbind("esc",this.escListener),this.emit("change"),this.emit("deactivate")},s.prototype._onTapOverlay=function(t){this.activate(),t.stopPropagation()},t.exports=s},function(t){function e(t){return t?i(t):void 0}function i(t){for(var i in e.prototype)t[i]=e.prototype[i];return t}t.exports=e,e.prototype.on=e.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks[t]=this._callbacks[t]||[]).push(e),this},e.prototype.once=function(t,e){function i(){s.off(t,i),e.apply(this,arguments)}var s=this;return this._callbacks=this._callbacks||{},i.fn=e,this.on(t,i),this},e.prototype.off=e.prototype.removeListener=e.prototype.removeAllListeners=e.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var i=this._callbacks[t];if(!i)return this;if(1==arguments.length)return delete this._callbacks[t],this;for(var s,o=0;os;++s)i[s].apply(this,e)}return this},e.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks[t]||[]},e.prototype.hasListeners=function(t){return!!this.listeners(t).length}},function(t,e,i){var s;!function(o,n){"use strict";function r(){a.READY||(w.determineEventTypes(),x.each(a.gestures,function(t){D.register(t)}),w.onTouch(a.DOCUMENT,v,D.detect),w.onTouch(a.DOCUMENT,y,D.detect),a.READY=!0)}var a=function M(t,e){return new M.Instance(t,e||{})};a.VERSION="1.1.3",a.defaults={behavior:{userSelect:"none",touchAction:"pan-y",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},a.DOCUMENT=document,a.HAS_POINTEREVENTS=navigator.pointerEnabled||navigator.msPointerEnabled,a.HAS_TOUCHEVENTS="ontouchstart"in o,a.IS_MOBILE=/mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent),a.NO_MOUSEEVENTS=a.HAS_TOUCHEVENTS&&a.IS_MOBILE||a.HAS_POINTEREVENTS,a.CALCULATE_INTERVAL=25;var h={},d=a.DIRECTION_DOWN="down",l=a.DIRECTION_LEFT="left",c=a.DIRECTION_UP="up",p=a.DIRECTION_RIGHT="right",u=a.POINTER_MOUSE="mouse",f=a.POINTER_TOUCH="touch",m=a.POINTER_PEN="pen",g=a.EVENT_START="start",v=a.EVENT_MOVE="move",y=a.EVENT_END="end",b=a.EVENT_RELEASE="release",_=a.EVENT_TOUCH="touch";a.READY=!1,a.plugins=a.plugins||{},a.gestures=a.gestures||{};var x=a.utils={extend:function(t,e,i){for(var s in e)!e.hasOwnProperty(s)||t[s]!==n&&i||(t[s]=e[s]);return t},on:function(t,e,i){t.addEventListener(e,i,!1)},off:function(t,e,i){t.removeEventListener(e,i,!1)},each:function(t,e,i){var s,o;if("forEach"in t)t.forEach(e,i);else if(t.length!==n){for(s=0,o=t.length;o>s;s++)if(e.call(i,t[s],s,t)===!1)return}else for(s in t)if(t.hasOwnProperty(s)&&e.call(i,t[s],s,t)===!1)return},inStr:function(t,e){return t.indexOf(e)>-1},inArray:function(t,e){if(t.indexOf){var i=t.indexOf(e);return-1===i?!1:i}for(var s=0,o=t.length;o>s;s++)if(t[s]===e)return s;return!1},toArray:function(t){return Array.prototype.slice.call(t,0)},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){var e=[],i=[],s=[],o=[],n=Math.min,r=Math.max;return 1===t.length?{pageX:t[0].pageX,pageY:t[0].pageY,clientX:t[0].clientX,clientY:t[0].clientY}:(x.each(t,function(t){e.push(t.pageX),i.push(t.pageY),s.push(t.clientX),o.push(t.clientY)}),{pageX:(n.apply(Math,e)+r.apply(Math,e))/2,pageY:(n.apply(Math,i)+r.apply(Math,i))/2,clientX:(n.apply(Math,s)+r.apply(Math,s))/2,clientY:(n.apply(Math,o)+r.apply(Math,o))/2})},getVelocity:function(t,e,i){return{x:Math.abs(e/t)||0,y:Math.abs(i/t)||0}},getAngle:function(t,e){var i=e.clientX-t.clientX,s=e.clientY-t.clientY;return 180*Math.atan2(s,i)/Math.PI},getDirection:function(t,e){var i=Math.abs(t.clientX-e.clientX),s=Math.abs(t.clientY-e.clientY);return i>=s?t.clientX-e.clientX>0?l:p:t.clientY-e.clientY>0?c:d},getDistance:function(t,e){var i=e.clientX-t.clientX,s=e.clientY-t.clientY;return Math.sqrt(i*i+s*s)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(t){return t==c||t==d},setPrefixedCss:function(t,e,i,s){var o=["","Webkit","Moz","O","ms"];e=x.toCamelCase(e);for(var n=0;n0&&this.started&&(r=v),this.started=!0;var d=this.collectEventData(i,r,o,t);return e!=y&&s.call(D,d),a&&(d.changedLength=h,d.eventType=a,s.call(D,d),d.eventType=r,delete d.changedLength),r==y&&(s.call(D,d),this.started=!1),r},determineEventTypes:function(){var t;return t=a.HAS_POINTEREVENTS?o.PointerEvent?["pointerdown","pointermove","pointerup pointercancel lostpointercapture"]:["MSPointerDown","MSPointerMove","MSPointerUp MSPointerCancel MSLostPointerCapture"]:a.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],h[g]=t[0],h[v]=t[1],h[y]=t[2],h},getTouchList:function(t,e){if(a.HAS_POINTEREVENTS)return S.getTouchList();if(t.touches){if(e==v)return t.touches;var i=[],s=[].concat(x.toArray(t.touches),x.toArray(t.changedTouches)),o=[];return x.each(s,function(t){x.inArray(i,t.identifier)===!1&&o.push(t),i.push(t.identifier)}),o}return t.identifier=1,[t]},collectEventData:function(t,e,i,s){var o=f;return x.inStr(s.type,"mouse")||S.matchType(u,s)?o=u:S.matchType(m,s)&&(o=m),{center:x.getCenter(i),timeStamp:Date.now(),target:s.target,touches:i,eventType:e,pointerType:o,srcEvent:s,preventDefault:function(){var t=this.srcEvent;t.preventManipulation&&t.preventManipulation(),t.preventDefault&&t.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return D.stopDetect()}}}},S=a.PointerEvent={pointers:{},getTouchList:function(){var t=[];return x.each(this.pointers,function(e){t.push(e)}),t},updatePointer:function(t,e){t==y||t!=y&&1!==e.buttons?delete this.pointers[e.pointerId]:(e.identifier=e.pointerId,this.pointers[e.pointerId]=e)},matchType:function(t,e){if(!e.pointerType)return!1;var i=e.pointerType,s={};return s[u]=i===(e.MSPOINTER_TYPE_MOUSE||u),s[f]=i===(e.MSPOINTER_TYPE_TOUCH||f),s[m]=i===(e.MSPOINTER_TYPE_PEN||m),s[t]},reset:function(){this.pointers={}}},D=a.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(t,e){this.current||(this.stopped=!1,this.current={inst:t,startEvent:x.extend({},e),lastEvent:!1,lastCalcEvent:!1,futureCalcEvent:!1,lastCalcData:{},name:""},this.detect(e))},detect:function(t){if(this.current&&!this.stopped){t=this.extendEventData(t);var e=this.current.inst,i=e.options;return x.each(this.gestures,function(s){!this.stopped&&e.enabled&&i[s.name]&&s.handler.call(s,t,e)},this),this.current&&(this.current.lastEvent=t),t.eventType==y&&this.stopDetect(),t}},stopDetect:function(){this.previous=x.extend({},this.current),this.current=null,this.stopped=!0},getCalculatedData:function(t,e,i,s,o){var n=this.current,r=!1,h=n.lastCalcEvent,d=n.lastCalcData;h&&t.timeStamp-h.timeStamp>a.CALCULATE_INTERVAL&&(e=h.center,i=t.timeStamp-h.timeStamp,s=t.center.clientX-h.center.clientX,o=t.center.clientY-h.center.clientY,r=!0),(t.eventType==_||t.eventType==b)&&(n.futureCalcEvent=t),(!n.lastCalcEvent||r)&&(d.velocity=x.getVelocity(i,s,o),d.angle=x.getAngle(e,t.center),d.direction=x.getDirection(e,t.center),n.lastCalcEvent=n.futureCalcEvent||t,n.futureCalcEvent=t),t.velocityX=d.velocity.x,t.velocityY=d.velocity.y,t.interimAngle=d.angle,t.interimDirection=d.direction},extendEventData:function(t){var e=this.current,i=e.startEvent,s=e.lastEvent||i;(t.eventType==_||t.eventType==b)&&(i.touches=[],x.each(t.touches,function(t){i.touches.push({clientX:t.clientX,clientY:t.clientY})}));var o=t.timeStamp-i.timeStamp,n=t.center.clientX-i.center.clientX,r=t.center.clientY-i.center.clientY;return this.getCalculatedData(t,s.center,o,n,r),x.extend(t,{startEvent:i,deltaTime:o,deltaX:n,deltaY:r,distance:x.getDistance(i.center,t.center),angle:x.getAngle(i.center,t.center),direction:x.getDirection(i.center,t.center),scale:x.getScale(i.touches,t.touches),rotation:x.getRotation(i.touches,t.touches)}),t},register:function(t){var e=t.defaults||{};return e[t.name]===n&&(e[t.name]=!0),x.extend(a.defaults,e,!0),t.index=t.index||1e3,this.gestures.push(t),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}};a.Instance=function(t,e){var i=this;r(),this.element=t,this.enabled=!0,x.each(e,function(t,i){delete e[i],e[x.toCamelCase(i)]=t}),this.options=x.extend(x.extend({},a.defaults),e||{}),this.options.behavior&&x.toggleBehavior(this.element,this.options.behavior,!0),this.eventStartHandler=w.onTouch(t,g,function(t){i.enabled&&t.eventType==g?D.startDetect(i,t):t.eventType==_&&D.detect(t)}),this.eventHandlers=[]},a.Instance.prototype={on:function(t,e){var i=this;return w.on(i.element,t,e,function(t){i.eventHandlers.push({gesture:t,handler:e})}),i},off:function(t,e){var i=this;return w.off(i.element,t,e,function(t){var s=x.inArray({gesture:t,handler:e});s!==!1&&i.eventHandlers.splice(s,1)}),i},trigger:function(t,e){e||(e={});var i=a.DOCUMENT.createEvent("Event");i.initEvent(t,!0,!0),i.gesture=e;var s=this.element;return x.hasParent(e.target,s)&&(s=e.target),s.dispatchEvent(i),this},enable:function(t){return this.enabled=t,this},dispose:function(){var t,e;for(x.toggleBehavior(this.element,this.options.behavior,!1),t=-1;e=this.eventHandlers[++t];)x.off(this.element,e.gesture,e.handler);return this.eventHandlers=[],w.off(this.element,h[g],this.eventStartHandler),null}},function(t){function e(e,s){var o=D.current;if(!(s.options.dragMaxTouches>0&&e.touches.length>s.options.dragMaxTouches))switch(e.eventType){case g:i=!1;break;case v:if(e.distance0)){var r=Math.abs(s.options.dragMinDistance/e.distance);n.pageX+=e.deltaX*r,n.pageY+=e.deltaY*r,n.clientX+=e.deltaX*r,n.clientY+=e.deltaY*r,e=D.extendEventData(e)}(o.lastEvent.dragLockToAxis||s.options.dragLockToAxis&&s.options.dragLockMinDistance<=e.distance)&&(e.dragLockToAxis=!0);var a=o.lastEvent.direction;e.dragLockToAxis&&a!==e.direction&&(e.direction=x.isVertical(a)?e.deltaY<0?c:d:e.deltaX<0?l:p),i||(s.trigger(t+"start",e),i=!0),s.trigger(t,e),s.trigger(t+e.direction,e);var h=x.isVertical(e.direction);(s.options.dragBlockVertical&&h||s.options.dragBlockHorizontal&&!h)&&e.preventDefault();break;case b:i&&e.changedLength<=s.options.dragMaxTouches&&(s.trigger(t+"end",e),i=!1);break;case y:i=!1}}var i=!1;a.gestures.Drag={name:t,index:50,handler:e,defaults:{dragMinDistance:10,dragDistanceCorrection:!0,dragMaxTouches:1,dragBlockHorizontal:!1,dragBlockVertical:!1,dragLockToAxis:!1,dragLockMinDistance:25}}}("drag"),a.gestures.Gesture={name:"gesture",index:1337,handler:function(t,e){e.trigger(this.name,t)}},function(t){function e(e,s){var o=s.options,n=D.current;switch(e.eventType){case g:clearTimeout(i),n.name=t,i=setTimeout(function(){n&&n.name==t&&s.trigger(t,e)},o.holdTimeout);break;case v:e.distance>o.holdThreshold&&clearTimeout(i);break;case b:clearTimeout(i)}}var i;a.gestures.Hold={name:t,index:10,defaults:{holdTimeout:500,holdThreshold:2},handler:e}}("hold"),a.gestures.Release={name:"release",index:1/0,handler:function(t,e){t.eventType==b&&e.trigger(this.name,t)}},a.gestures.Swipe={name:"swipe",index:40,defaults:{swipeMinTouches:1,swipeMaxTouches:1,swipeVelocityX:.6,swipeVelocityY:.6},handler:function(t,e){if(t.eventType==b){var i=t.touches.length,s=e.options;if(is.swipeMaxTouches)return;(t.velocityX>s.swipeVelocityX||t.velocityY>s.swipeVelocityY)&&(e.trigger(this.name,t),e.trigger(this.name+t.direction,t))}}},function(t){function e(e,s){var o,n,r=s.options,a=D.current,h=D.previous;switch(e.eventType){case g:i=!1;break;case v:i=i||e.distance>r.tapMaxDistance;break;case y:!x.inStr(e.srcEvent.type,"cancel")&&e.deltaTimes.options.transformMinRotation&&s.trigger("rotate",e),o>s.options.transformMinScale&&(s.trigger("pinch",e),s.trigger("pinch"+(e.scale<1?"in":"out"),e));break;case b:i&&e.changedLength<2&&(s.trigger(t+"end",e),i=!1)}}var i=!1;a.gestures.Transform={name:t,index:45,defaults:{transformMinScale:.01,transformMinRotation:1},handler:e}}("transform"),s=function(){return a}.call(e,i,e,t),!(s!==n&&(t.exports=s))}(window)},function(t){function e(t,e,i){return t.addEventListener?t.addEventListener(e,i,!1):void t.attachEvent("on"+e,i)}function i(t){return"keypress"==t.type?String.fromCharCode(t.which):_[t.which]?_[t.which]:x[t.which]?x[t.which]:String.fromCharCode(t.which).toLowerCase()}function s(t){var e=t.target||t.srcElement,i=e.tagName;return(" "+e.className+" ").indexOf(" mousetrap ")>-1?!1:"INPUT"==i||"SELECT"==i||"TEXTAREA"==i||e.contentEditable&&"true"==e.contentEditable}function o(t,e){return t.sort().join(",")===e.sort().join(",")}function n(t){t=t||{};var e,i=!1;for(e in C)t[e]?i=!0:C[e]=0;i||(T=!1)}function r(t,e,i,s,n){var r,a,h=[];if(!D[t])return[];for("keyup"==i&&c(t)&&(e=[t]),r=0;r95&&112>t||_.hasOwnProperty(t)&&(y[_[t]]=t)}return y}function f(t,e,i){return i||(i=u()[t]?"keydown":"keypress"),"keypress"==i&&e.length&&(i="keydown"),i}function m(t,e,s,o){C[t]=0,o||(o=f(e[0],[]));var r,a=function(){T=o,++C[t],p()},d=function(t){h(s,t),"keyup"!==o&&(E=i(t)),setTimeout(n,10)};for(r=0;r1)return m(t,d,e,i);for(h="+"===t?["+"]:t.split("+"),n=0;n":".","?":"/","|":"\\"},S={option:"alt",command:"meta","return":"enter",escape:"esc"},D={},M={},C={},E=!1,T=!1,O=1;20>O;++O)_[111+O]="f"+O;for(O=0;9>=O;++O)_[O+96]=O;e(document,"keypress",l),e(document,"keydown",l),e(document,"keyup",l);var L={bind:function(t,e,i){return v(t instanceof Array?t:[t],e,i),M[t+":"+i]=e,this},unbind:function(t,e){return M[t+":"+e]&&(delete M[t+":"+e],this.bind(t,function(){},e)),this},trigger:function(t,e){return M[t+":"+e](),this},reset:function(){return D={},M={},this}};t.exports=L},function(t,e,i){var s;(function(t,o){(function(n){function r(t,e,i){switch(arguments.length){case 2:return null!=t?t:e;case 3:return null!=t?t:null!=e?e:i;default:throw new Error("Implement me")}}function a(t,e){return Le.call(t,e)}function h(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function d(t){De.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function l(t,e){var i=!0;return v(function(){return i&&(d(t),i=!1),e.apply(this,arguments)},e)}function c(t,e){xi[t]||(d(e),xi[t]=!0)}function p(t,e){return function(i){return _(t.call(this,i),e)}}function u(t,e){return function(i){return this.localeData().ordinal(t.call(this,i),e)}}function f(){}function m(t,e){e!==!1&&P(t),y(this,t),this._d=new Date(+t._d)}function g(t){var e=O(t),i=e.year||0,s=e.quarter||0,o=e.month||0,n=e.week||0,r=e.day||0,a=e.hour||0,h=e.minute||0,d=e.second||0,l=e.millisecond||0;this._milliseconds=+l+1e3*d+6e4*h+36e5*a,this._days=+r+7*n,this._months=+o+3*s+12*i,this._data={},this._locale=De.localeData(),this._bubble()}function v(t,e){for(var i in e)a(e,i)&&(t[i]=e[i]);return a(e,"toString")&&(t.toString=e.toString),a(e,"valueOf")&&(t.valueOf=e.valueOf),t}function y(t,e){var i,s,o;if("undefined"!=typeof e._isAMomentObject&&(t._isAMomentObject=e._isAMomentObject),"undefined"!=typeof e._i&&(t._i=e._i),"undefined"!=typeof e._f&&(t._f=e._f),"undefined"!=typeof e._l&&(t._l=e._l),"undefined"!=typeof e._strict&&(t._strict=e._strict),"undefined"!=typeof e._tzm&&(t._tzm=e._tzm),"undefined"!=typeof e._isUTC&&(t._isUTC=e._isUTC),"undefined"!=typeof e._offset&&(t._offset=e._offset),"undefined"!=typeof e._pf&&(t._pf=e._pf),"undefined"!=typeof e._locale&&(t._locale=e._locale),He.length>0)for(i in He)s=He[i],o=e[s],"undefined"!=typeof o&&(t[s]=o);return t}function b(t){return 0>t?Math.ceil(t):Math.floor(t)}function _(t,e,i){for(var s=""+Math.abs(t),o=t>=0;s.lengths;s++)(i&&t[s]!==e[s]||!i&&k(t[s])!==k(e[s]))&&r++;return r+n}function T(t){if(t){var e=t.toLowerCase().replace(/(.)s$/,"$1");t=fi[t]||mi[e]||e}return t}function O(t){var e,i,s={};for(i in t)a(t,i)&&(e=T(i),e&&(s[e]=t[i]));return s}function L(t){var e,i;if(0===t.indexOf("week"))e=7,i="day";else{if(0!==t.indexOf("month"))return;e=12,i="month"}De[t]=function(s,o){var r,a,h=De._locale[t],d=[];if("number"==typeof s&&(o=s,s=n),a=function(t){var e=De().utc().set(i,t);return h.call(De._locale,e,s||"")},null!=o)return a(o);for(r=0;e>r;r++)d.push(a(r));return d}}function k(t){var e=+t,i=0;return 0!==e&&isFinite(e)&&(i=e>=0?Math.floor(e):Math.ceil(e)),i}function N(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function I(t,e,i){return pe(De([t,11,31+e-i]),e,i).week}function A(t){return z(t)?366:365}function z(t){return t%4===0&&t%100!==0||t%400===0}function P(t){var e;t._a&&-2===t._pf.overflow&&(e=t._a[Ne]<0||t._a[Ne]>11?Ne:t._a[Ie]<1||t._a[Ie]>N(t._a[ke],t._a[Ne])?Ie:t._a[Ae]<0||t._a[Ae]>23?Ae:t._a[ze]<0||t._a[ze]>59?ze:t._a[Pe]<0||t._a[Pe]>59?Pe:t._a[Re]<0||t._a[Re]>999?Re:-1,t._pf._overflowDayOfYear&&(ke>e||e>Ie)&&(e=Ie),t._pf.overflow=e)}function R(t){return null==t._isValid&&(t._isValid=!isNaN(t._d.getTime())&&t._pf.overflow<0&&!t._pf.empty&&!t._pf.invalidMonth&&!t._pf.nullInput&&!t._pf.invalidFormat&&!t._pf.userInvalidated,t._strict&&(t._isValid=t._isValid&&0===t._pf.charsLeftOver&&0===t._pf.unusedTokens.length)),t._isValid}function F(t){return t?t.toLowerCase().replace("_","-"):t}function H(t){for(var e,i,s,o,n=0;n0;){if(s=Y(o.slice(0,e).join("-")))return s;if(i&&i.length>=e&&E(o,i,!0)>=e-1)break;e--}n++}return null}function Y(t){var e=null;if(!Fe[t]&&Ye)try{e=De.locale(),!function(){var t=new Error('Cannot find module "./locale"');throw t.code="MODULE_NOT_FOUND",t}(),De.locale(e)}catch(i){}return Fe[t]}function B(t,e){return e._isUTC?De(t).zone(e._offset||0):De(t).local()}function W(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function G(t){var e,i,s=t.match(je);for(e=0,i=s.length;i>e;e++)s[e]=_i[s[e]]?_i[s[e]]:W(s[e]);return function(o){var n="";for(e=0;i>e;e++)n+=s[e]instanceof Function?s[e].call(o,t):s[e];return n}}function j(t,e){return t.isValid()?(e=U(e,t.localeData()),gi[e]||(gi[e]=G(e)),gi[e](t)):t.localeData().invalidDate()}function U(t,e){function i(t){return e.longDateFormat(t)||t}var s=5;for(Ue.lastIndex=0;s>=0&&Ue.test(t);)t=t.replace(Ue,i),Ue.lastIndex=0,s-=1;return t}function V(t,e){var i,s=e._strict;switch(t){case"Q":return ii;case"DDDD":return oi;case"YYYY":case"GGGG":case"gggg":return s?ni:Ze;case"Y":case"G":case"g":return ai;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return s?ri:qe;case"S":if(s)return ii;case"SS":if(s)return si;case"SSS":if(s)return oi;case"DDD":return Xe;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Qe;case"a":case"A":return e._locale._meridiemParse;case"X":return ti;case"Z":case"ZZ":return $e;case"T":return Je;case"SSSS":return Ke;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return s?si:Ve;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Ve;case"Do":return ei;default:return i=new RegExp(ee(te(t.replace("\\","")),"i"))}}function X(t){t=t||"";var e=t.match($e)||[],i=e[e.length-1]||[],s=(i+"").match(pi)||["-",0,0],o=+(60*s[1])+k(s[2]);return"+"===s[0]?-o:o}function Z(t,e,i){var s,o=i._a;switch(t){case"Q":null!=e&&(o[Ne]=3*(k(e)-1));break;case"M":case"MM":null!=e&&(o[Ne]=k(e)-1);break;case"MMM":case"MMMM":s=i._locale.monthsParse(e),null!=s?o[Ne]=s:i._pf.invalidMonth=e;break;case"D":case"DD":null!=e&&(o[Ie]=k(e));break;case"Do":null!=e&&(o[Ie]=k(parseInt(e,10)));break;case"DDD":case"DDDD":null!=e&&(i._dayOfYear=k(e));break;case"YY":o[ke]=De.parseTwoDigitYear(e);break;case"YYYY":case"YYYYY":case"YYYYYY":o[ke]=k(e);break;case"a":case"A":i._isPm=i._locale.isPM(e);break;case"H":case"HH":case"h":case"hh":o[Ae]=k(e);break;case"m":case"mm":o[ze]=k(e);break;case"s":case"ss":o[Pe]=k(e);break;case"S":case"SS":case"SSS":case"SSSS":o[Re]=k(1e3*("0."+e));break;case"X":i._d=new Date(1e3*parseFloat(e));break;case"Z":case"ZZ":i._useUTC=!0,i._tzm=X(e);break;case"dd":case"ddd":case"dddd":s=i._locale.weekdaysParse(e),null!=s?(i._w=i._w||{},i._w.d=s):i._pf.invalidWeekday=e;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":t=t.substr(0,1);case"gggg":case"GGGG":case"GGGGG":t=t.substr(0,2),e&&(i._w=i._w||{},i._w[t]=k(e));break;case"gg":case"GG":i._w=i._w||{},i._w[t]=De.parseTwoDigitYear(e)}}function q(t){var e,i,s,o,n,a,h;e=t._w,null!=e.GG||null!=e.W||null!=e.E?(n=1,a=4,i=r(e.GG,t._a[ke],pe(De(),1,4).year),s=r(e.W,1),o=r(e.E,1)):(n=t._locale._week.dow,a=t._locale._week.doy,i=r(e.gg,t._a[ke],pe(De(),n,a).year),s=r(e.w,1),null!=e.d?(o=e.d,n>o&&++s):o=null!=e.e?e.e+n:n),h=ue(i,s,o,a,n),t._a[ke]=h.year,t._dayOfYear=h.dayOfYear}function K(t){var e,i,s,o,n=[];if(!t._d){for(s=$(t),t._w&&null==t._a[Ie]&&null==t._a[Ne]&&q(t),t._dayOfYear&&(o=r(t._a[ke],s[ke]),t._dayOfYear>A(o)&&(t._pf._overflowDayOfYear=!0),i=he(o,0,t._dayOfYear),t._a[Ne]=i.getUTCMonth(),t._a[Ie]=i.getUTCDate()),e=0;3>e&&null==t._a[e];++e)t._a[e]=n[e]=s[e];for(;7>e;e++)t._a[e]=n[e]=null==t._a[e]?2===e?1:0:t._a[e];t._d=(t._useUTC?he:ae).apply(null,n),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()+t._tzm)}}function Q(t){var e;t._d||(e=O(t._i),t._a=[e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond],K(t))}function $(t){var e=new Date;return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function J(t){if(t._f===De.ISO_8601)return void se(t);t._a=[],t._pf.empty=!0;var e,i,s,o,n,r=""+t._i,a=r.length,h=0;for(s=U(t._f,t._locale).match(je)||[],e=0;e0&&t._pf.unusedInput.push(n),r=r.slice(r.indexOf(i)+i.length),h+=i.length),_i[o]?(i?t._pf.empty=!1:t._pf.unusedTokens.push(o),Z(o,i,t)):t._strict&&!i&&t._pf.unusedTokens.push(o);t._pf.charsLeftOver=a-h,r.length>0&&t._pf.unusedInput.push(r),t._isPm&&t._a[Ae]<12&&(t._a[Ae]+=12),t._isPm===!1&&12===t._a[Ae]&&(t._a[Ae]=0),K(t),P(t)}function te(t){return t.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,i,s,o){return e||i||s||o})}function ee(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function ie(t){var e,i,s,o,n;if(0===t._f.length)return t._pf.invalidFormat=!0,void(t._d=new Date(0/0));for(o=0;on)&&(s=n,i=e));v(t,i||e)}function se(t){var e,i,s=t._i,o=hi.exec(s);if(o){for(t._pf.iso=!0,e=0,i=li.length;i>e;e++)if(li[e][1].exec(s)){t._f=li[e][0]+(o[6]||" ");break}for(e=0,i=ci.length;i>e;e++)if(ci[e][1].exec(s)){t._f+=ci[e][0];break}s.match($e)&&(t._f+="Z"),J(t)}else t._isValid=!1}function oe(t){se(t),t._isValid===!1&&(delete t._isValid,De.createFromInputFallback(t))}function ne(t,e){var i,s=[];for(i=0;it&&a.setFullYear(t),a}function he(t){var e=new Date(Date.UTC.apply(null,arguments));return 1970>t&&e.setUTCFullYear(t),e}function de(t,e){if("string"==typeof t)if(isNaN(t)){if(t=e.weekdaysParse(t),"number"!=typeof t)return null}else t=parseInt(t,10);return t}function le(t,e,i,s,o){return o.relativeTime(e||1,!!i,t,s)}function ce(t,e,i){var s=De.duration(t).abs(),o=Oe(s.as("s")),n=Oe(s.as("m")),r=Oe(s.as("h")),a=Oe(s.as("d")),h=Oe(s.as("M")),d=Oe(s.as("y")),l=o0,l[4]=i,le.apply({},l)}function pe(t,e,i){var s,o=i-e,n=i-t.day();return n>o&&(n-=7),o-7>n&&(n+=7),s=De(t).add(n,"d"),{week:Math.ceil(s.dayOfYear()/7),year:s.year()}}function ue(t,e,i,s,o){var n,r,a=he(t,0,1).getUTCDay();return a=0===a?7:a,i=null!=i?i:o,n=o-a+(a>s?7:0)-(o>a?7:0),r=7*(e-1)+(i-o)+n+1,{year:r>0?t:t-1,dayOfYear:r>0?r:A(t-1)+r}}function fe(t){var e=t._i,i=t._f;return t._locale=t._locale||De.localeData(t._l),null===e||i===n&&""===e?De.invalid({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),De.isMoment(e)?new m(e,!0):(i?M(i)?ie(t):J(t):re(t),new m(t)))}function me(t,e){var i,s;if(1===e.length&&M(e[0])&&(e=e[0]),!e.length)return De();for(i=e[0],s=1;s=0?"+":"-";return e+_(Math.abs(t),6)},gg:function(){return _(this.weekYear()%100,2)},gggg:function(){return _(this.weekYear(),4)},ggggg:function(){return _(this.weekYear(),5)},GG:function(){return _(this.isoWeekYear()%100,2)},GGGG:function(){return _(this.isoWeekYear(),4)},GGGGG:function(){return _(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return k(this.milliseconds()/100)},SS:function(){return _(k(this.milliseconds()/10),2)},SSS:function(){return _(this.milliseconds(),3)},SSSS:function(){return _(this.milliseconds(),3)},Z:function(){var t=-this.zone(),e="+";return 0>t&&(t=-t,e="-"),e+_(k(t/60),2)+":"+_(k(t)%60,2)},ZZ:function(){var t=-this.zone(),e="+";return 0>t&&(t=-t,e="-"),e+_(k(t/60),2)+_(k(t)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},xi={},wi=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];yi.length;)Ce=yi.pop(),_i[Ce+"o"]=u(_i[Ce],Ce);for(;bi.length;)Ce=bi.pop(),_i[Ce+Ce]=p(_i[Ce],2);_i.DDDD=p(_i.DDD,3),v(f.prototype,{set:function(t){var e,i;for(i in t)e=t[i],"function"==typeof e?this[i]=e:this["_"+i]=e},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(t){return this._months[t.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(t){return this._monthsShort[t.month()]},monthsParse:function(t){var e,i,s;for(this._monthsParse||(this._monthsParse=[]),e=0;12>e;e++)if(this._monthsParse[e]||(i=De.utc([2e3,e]),s="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[e]=new RegExp(s.replace(".",""),"i")),this._monthsParse[e].test(t))return e},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(t){return this._weekdays[t.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(t){return this._weekdaysShort[t.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(t){return this._weekdaysMin[t.day()]},weekdaysParse:function(t){var e,i,s;for(this._weekdaysParse||(this._weekdaysParse=[]),e=0;7>e;e++)if(this._weekdaysParse[e]||(i=De([2e3,1]).day(e),s="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[e]=new RegExp(s.replace(".",""),"i")),this._weekdaysParse[e].test(t))return e},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM D, YYYY LT"},longDateFormat:function(t){var e=this._longDateFormat[t]; -return!e&&this._longDateFormat[t.toUpperCase()]&&(e=this._longDateFormat[t.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t]=e),e},isPM:function(t){return"p"===(t+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(t,e,i){return t>11?i?"pm":"PM":i?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(t,e){var i=this._calendar[t];return"function"==typeof i?i.apply(e):i},_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"},relativeTime:function(t,e,i,s){var o=this._relativeTime[i];return"function"==typeof o?o(t,e,i,s):o.replace(/%d/i,t)},pastFuture:function(t,e){var i=this._relativeTime[t>0?"future":"past"];return"function"==typeof i?i(e):i.replace(/%s/i,e)},ordinal:function(t){return this._ordinal.replace("%d",t)},_ordinal:"%d",preparse:function(t){return t},postformat:function(t){return t},week:function(t){return pe(t,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),De=function(t,e,i,s){var o;return"boolean"==typeof i&&(s=i,i=n),o={},o._isAMomentObject=!0,o._i=t,o._f=e,o._l=i,o._strict=s,o._isUTC=!1,o._pf=h(),fe(o)},De.suppressDeprecationWarnings=!1,De.createFromInputFallback=l("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(t){t._d=new Date(t._i)}),De.min=function(){var t=[].slice.call(arguments,0);return me("isBefore",t)},De.max=function(){var t=[].slice.call(arguments,0);return me("isAfter",t)},De.utc=function(t,e,i,s){var o;return"boolean"==typeof i&&(s=i,i=n),o={},o._isAMomentObject=!0,o._useUTC=!0,o._isUTC=!0,o._l=i,o._i=t,o._f=e,o._strict=s,o._pf=h(),fe(o).utc()},De.unix=function(t){return De(1e3*t)},De.duration=function(t,e){var i,s,o,n,r=t,h=null;return De.isDuration(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:"number"==typeof t?(r={},e?r[e]=t:r.milliseconds=t):(h=We.exec(t))?(i="-"===h[1]?-1:1,r={y:0,d:k(h[Ie])*i,h:k(h[Ae])*i,m:k(h[ze])*i,s:k(h[Pe])*i,ms:k(h[Re])*i}):(h=Ge.exec(t))?(i="-"===h[1]?-1:1,o=function(t){var e=t&&parseFloat(t.replace(",","."));return(isNaN(e)?0:e)*i},r={y:o(h[2]),M:o(h[3]),d:o(h[4]),h:o(h[5]),m:o(h[6]),s:o(h[7]),w:o(h[8])}):"object"==typeof r&&("from"in r||"to"in r)&&(n=w(De(r.from),De(r.to)),r={},r.ms=n.milliseconds,r.M=n.months),s=new g(r),De.isDuration(t)&&a(t,"_locale")&&(s._locale=t._locale),s},De.version=Ee,De.defaultFormat=di,De.ISO_8601=function(){},De.momentProperties=He,De.updateOffset=function(){},De.relativeTimeThreshold=function(t,e){return vi[t]===n?!1:e===n?vi[t]:(vi[t]=e,!0)},De.lang=l("moment.lang is deprecated. Use moment.locale instead.",function(t,e){return De.locale(t,e)}),De.locale=function(t,e){var i;return t&&(i="undefined"!=typeof e?De.defineLocale(t,e):De.localeData(t),i&&(De.duration._locale=De._locale=i)),De._locale._abbr},De.defineLocale=function(t,e){return null!==e?(e.abbr=t,Fe[t]||(Fe[t]=new f),Fe[t].set(e),De.locale(t),Fe[t]):(delete Fe[t],null)},De.langData=l("moment.langData is deprecated. Use moment.localeData instead.",function(t){return De.localeData(t)}),De.localeData=function(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return De._locale;if(!M(t)){if(e=Y(t))return e;t=[t]}return H(t)},De.isMoment=function(t){return t instanceof m||null!=t&&a(t,"_isAMomentObject")},De.isDuration=function(t){return t instanceof g};for(Ce=wi.length-1;Ce>=0;--Ce)L(wi[Ce]);De.normalizeUnits=function(t){return T(t)},De.invalid=function(t){var e=De.utc(0/0);return null!=t?v(e._pf,t):e._pf.userInvalidated=!0,e},De.parseZone=function(){return De.apply(null,arguments).parseZone()},De.parseTwoDigitYear=function(t){return k(t)+(k(t)>68?1900:2e3)},v(De.fn=m.prototype,{clone:function(){return De(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var t=De(this).utc();return 00:!1},parsingFlags:function(){return v({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(t){return this.zone(0,t)},local:function(t){return this._isUTC&&(this.zone(0,t),this._isUTC=!1,t&&this.add(this._dateTzOffset(),"m")),this},format:function(t){var e=j(this,t||De.defaultFormat);return this.localeData().postformat(e)},add:S(1,"add"),subtract:S(-1,"subtract"),diff:function(t,e,i){var s,o,n,r=B(t,this),a=6e4*(this.zone()-r.zone());return e=T(e),"year"===e||"month"===e?(s=432e5*(this.daysInMonth()+r.daysInMonth()),o=12*(this.year()-r.year())+(this.month()-r.month()),n=this-De(this).startOf("month")-(r-De(r).startOf("month")),n-=6e4*(this.zone()-De(this).startOf("month").zone()-(r.zone()-De(r).startOf("month").zone())),o+=n/s,"year"===e&&(o/=12)):(s=this-r,o="second"===e?s/1e3:"minute"===e?s/6e4:"hour"===e?s/36e5:"day"===e?(s-a)/864e5:"week"===e?(s-a)/6048e5:s),i?o:b(o)},from:function(t,e){return De.duration({to:this,from:t}).locale(this.locale()).humanize(!e)},fromNow:function(t){return this.from(De(),t)},calendar:function(t){var e=t||De(),i=B(e,this).startOf("day"),s=this.diff(i,"days",!0),o=-6>s?"sameElse":-1>s?"lastWeek":0>s?"lastDay":1>s?"sameDay":2>s?"nextDay":7>s?"nextWeek":"sameElse";return this.format(this.localeData().calendar(o,this))},isLeapYear:function(){return z(this.year())},isDST:function(){return this.zone()+t):+this.clone().startOf(e)>+De(t).startOf(e)},isBefore:function(t,e){return e=T("undefined"!=typeof e?e:"millisecond"),"millisecond"===e?(t=De.isMoment(t)?t:De(t),+t>+this):+this.clone().startOf(e)<+De(t).startOf(e)},isSame:function(t,e){return e=T(e||"millisecond"),"millisecond"===e?(t=De.isMoment(t)?t:De(t),+this===+t):+this.clone().startOf(e)===+B(t,this).startOf(e)},min:l("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(t){return t=De.apply(null,arguments),this>t?this:t}),max:l("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(t){return t=De.apply(null,arguments),t>this?this:t}),zone:function(t,e){var i,s=this._offset||0;return null==t?this._isUTC?s:this._dateTzOffset():("string"==typeof t&&(t=X(t)),Math.abs(t)<16&&(t=60*t),!this._isUTC&&e&&(i=this._dateTzOffset()),this._offset=t,this._isUTC=!0,null!=i&&this.subtract(i,"m"),s!==t&&(!e||this._changeInProgress?D(this,De.duration(s-t,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,De.updateOffset(this,!0),this._changeInProgress=null)),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(t){return t=t?De(t).zone():0,(this.zone()-t)%60===0},daysInMonth:function(){return N(this.year(),this.month())},dayOfYear:function(t){var e=Oe((De(this).startOf("day")-De(this).startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},quarter:function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},weekYear:function(t){var e=pe(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==t?e:this.add(t-e,"y")},isoWeekYear:function(t){var e=pe(this,1,4).year;return null==t?e:this.add(t-e,"y")},week:function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},isoWeek:function(t){var e=pe(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},weekday:function(t){var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},isoWeekday:function(t){return null==t?this.day()||7:this.day(this.day()%7?t:t-7)},isoWeeksInYear:function(){return I(this.year(),1,4)},weeksInYear:function(){var t=this.localeData()._week;return I(this.year(),t.dow,t.doy)},get:function(t){return t=T(t),this[t]()},set:function(t,e){return t=T(t),"function"==typeof this[t]&&this[t](e),this},locale:function(t){var e;return t===n?this._locale._abbr:(e=De.localeData(t),null!=e&&(this._locale=e),this)},lang:l("moment().lang() is deprecated. Use moment().localeData() instead.",function(t){return t===n?this.localeData():this.locale(t)}),localeData:function(){return this._locale},_dateTzOffset:function(){return 15*Math.round(this._d.getTimezoneOffset()/15)}}),De.fn.millisecond=De.fn.milliseconds=be("Milliseconds",!1),De.fn.second=De.fn.seconds=be("Seconds",!1),De.fn.minute=De.fn.minutes=be("Minutes",!1),De.fn.hour=De.fn.hours=be("Hours",!0),De.fn.date=be("Date",!0),De.fn.dates=l("dates accessor is deprecated. Use date instead.",be("Date",!0)),De.fn.year=be("FullYear",!0),De.fn.years=l("years accessor is deprecated. Use year instead.",be("FullYear",!0)),De.fn.days=De.fn.day,De.fn.months=De.fn.month,De.fn.weeks=De.fn.week,De.fn.isoWeeks=De.fn.isoWeek,De.fn.quarters=De.fn.quarter,De.fn.toJSON=De.fn.toISOString,v(De.duration.fn=g.prototype,{_bubble:function(){var t,e,i,s=this._milliseconds,o=this._days,n=this._months,r=this._data,a=0;r.milliseconds=s%1e3,t=b(s/1e3),r.seconds=t%60,e=b(t/60),r.minutes=e%60,i=b(e/60),r.hours=i%24,o+=b(i/24),a=b(_e(o)),o-=b(xe(a)),n+=b(o/30),o%=30,a+=b(n/12),n%=12,r.days=o,r.months=n,r.years=a},abs:function(){return this._milliseconds=Math.abs(this._milliseconds),this._days=Math.abs(this._days),this._months=Math.abs(this._months),this._data.milliseconds=Math.abs(this._data.milliseconds),this._data.seconds=Math.abs(this._data.seconds),this._data.minutes=Math.abs(this._data.minutes),this._data.hours=Math.abs(this._data.hours),this._data.months=Math.abs(this._data.months),this._data.years=Math.abs(this._data.years),this},weeks:function(){return b(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12)},humanize:function(t){var e=ce(this,!t,this.localeData());return t&&(e=this.localeData().pastFuture(+this,e)),this.localeData().postformat(e)},add:function(t,e){var i=De.duration(t,e);return this._milliseconds+=i._milliseconds,this._days+=i._days,this._months+=i._months,this._bubble(),this},subtract:function(t,e){var i=De.duration(t,e);return this._milliseconds-=i._milliseconds,this._days-=i._days,this._months-=i._months,this._bubble(),this},get:function(t){return t=T(t),this[t.toLowerCase()+"s"]()},as:function(t){var e,i;if(t=T(t),"month"===t||"year"===t)return e=this._days+this._milliseconds/864e5,i=this._months+12*_e(e),"month"===t?i:i/12;switch(e=this._days+xe(this._months/12),t){case"week":return e/7+this._milliseconds/6048e5;case"day":return e+this._milliseconds/864e5;case"hour":return 24*e+this._milliseconds/36e5;case"minute":return 24*e*60+this._milliseconds/6e4;case"second":return 24*e*60*60+this._milliseconds/1e3;case"millisecond":return Math.floor(24*e*60*60*1e3)+this._milliseconds;default:throw new Error("Unknown unit "+t)}},lang:De.fn.lang,locale:De.fn.locale,toIsoString:l("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",function(){return this.toISOString()}),toISOString:function(){var t=Math.abs(this.years()),e=Math.abs(this.months()),i=Math.abs(this.days()),s=Math.abs(this.hours()),o=Math.abs(this.minutes()),n=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(t?t+"Y":"")+(e?e+"M":"")+(i?i+"D":"")+(s||o||n?"T":"")+(s?s+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"},localeData:function(){return this._locale}}),De.duration.fn.toString=De.duration.fn.toISOString;for(Ce in ui)a(ui,Ce)&&we(Ce.toLowerCase());De.duration.fn.asMilliseconds=function(){return this.as("ms")},De.duration.fn.asSeconds=function(){return this.as("s")},De.duration.fn.asMinutes=function(){return this.as("m")},De.duration.fn.asHours=function(){return this.as("h")},De.duration.fn.asDays=function(){return this.as("d")},De.duration.fn.asWeeks=function(){return this.as("weeks")},De.duration.fn.asMonths=function(){return this.as("M")},De.duration.fn.asYears=function(){return this.as("y")},De.locale("en",{ordinal:function(t){var e=t%10,i=1===k(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+i}}),Ye?o.exports=De:(s=function(t,e,i){return i.config&&i.config()&&i.config().noGlobal===!0&&(Te.moment=Me),De}.call(e,i,e,o),!(s!==n&&(o.exports=s)),Se(!0))}).call(this)}).call(e,function(){return this}(),i(67)(t))},function(t,e){e.startWithClustering=function(){this.clusterToFit(this.constants.clustering.initialMaxNodes,!0),this.updateLabels(),this.stabilize&&this._stabilize(),this.start()},e.clusterToFit=function(t,e){for(var i=this.nodeIndices.length,s=50,o=0;i>t&&s>o;)o%3==0?(this.forceAggregateHubs(!0),this.normalizeClusterLevels()):this.increaseClusterLevel(),i=this.nodeIndices.length,o+=1;o>0&&1==e&&this.repositionNodes(),this._updateCalculationNodes()},e.openCluster=function(t){var e=this.moving;if(t.clusterSize>this.constants.clustering.sectorThreshold&&this._nodeInActiveArea(t)&&("default"!=this._sector()||1!=this.nodeIndices.length)){this._addSector(t);for(var i=0;this.nodeIndices.lengthi;)this.decreaseClusterLevel(),i+=1}else this._expandClusterNode(t,!1,!0),this._updateNodeIndexList(),this._updateDynamicEdges(),this._updateCalculationNodes(),this.updateLabels();this.moving!=e&&this.start()},e.updateClustersDefault=function(){1==this.constants.clustering.enabled&&this.updateClusters(0,!1,!1)},e.increaseClusterLevel=function(){this.updateClusters(-1,!1,!0)},e.decreaseClusterLevel=function(){this.updateClusters(1,!1,!0)},e.updateClusters=function(t,e,i,s){var o=this.moving,n=this.nodeIndices.length;this.previousScale>this.scale&&0==t&&this._collapseSector(),this.previousScale>this.scale||-1==t?this._formClusters(i):(this.previousScalethis.scale||-1==t)&&(this._aggregateHubs(i),this._updateNodeIndexList()),(this.previousScale>this.scale||-1==t)&&(this.handleChains(),this._updateNodeIndexList()),this.previousScale=this.scale,this._updateDynamicEdges(),this.updateLabels(),this.nodeIndices.lengththis.constants.clustering.chainThreshold&&this._reduceAmountOfChains(1-this.constants.clustering.chainThreshold/t)},e._aggregateHubs=function(t){this._getHubSize(),this._formClustersByHub(t,!1)},e.forceAggregateHubs=function(t){var e=this.moving,i=this.nodeIndices.length;this._aggregateHubs(!0),this._updateNodeIndexList(),this._updateDynamicEdges(),this.updateLabels(),this.nodeIndices.length!=i&&(this.clusterSession+=1),(0==t||void 0===t)&&this.moving!=e&&this.start()},e._openClustersBySize=function(){for(var t in this.nodes)if(this.nodes.hasOwnProperty(t)){var e=this.nodes[t];1==e.inView()&&(e.width*this.scale>this.constants.clustering.screenSizeThreshold*this.frame.canvas.clientWidth||e.height*this.scale>this.constants.clustering.screenSizeThreshold*this.frame.canvas.clientHeight)&&this.openCluster(e)}},e._openClusters=function(t,e){for(var i=0;i1&&(t.clusterSizei)){var r=n.from,a=n.to;n.to.options.mass>n.from.options.mass&&(r=n.to,a=n.from),1==a.dynamicEdgesLength?this._addToCluster(r,a,!1):1==r.dynamicEdgesLength&&this._addToCluster(a,r,!1)}}},e._forceClustersByZoom=function(){for(var t in this.nodes)if(this.nodes.hasOwnProperty(t)){var e=this.nodes[t];if(1==e.dynamicEdgesLength&&0!=e.dynamicEdges.length){var i=e.dynamicEdges[0],s=i.toId==e.id?this.nodes[i.fromId]:this.nodes[i.toId];e.id!=s.id&&(s.options.mass>e.options.mass?this._addToCluster(s,e,!0):this._addToCluster(e,s,!0))}}},e._clusterToSmallestNeighbour=function(t){for(var e=-1,i=null,s=0;so.clusterSessions.length&&(e=o.clusterSessions.length,i=o)}null!=o&&void 0!==this.nodes[o.id]&&this._addToCluster(o,t,!0)},e._formClustersByHub=function(t,e){for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&this._formClusterFromHub(this.nodes[i],t,e)},e._formClusterFromHub=function(t,e,i,s){if(void 0===s&&(s=0),t.dynamicEdgesLength>=this.hubThreshold&&0==i||t.dynamicEdgesLength==this.hubThreshold&&1==i){for(var o,n,r,a=this.constants.clustering.clusterEdgeThreshold/this.scale,h=!1,d=[],l=t.dynamicEdges.length,c=0;l>c;c++)d.push(t.dynamicEdges[c].id);if(0==e)for(h=!1,c=0;l>c;c++){var p=this.edges[d[c]];if(void 0!==p&&p.connected&&p.toId!=p.fromId&&(o=p.to.x-p.from.x,n=p.to.y-p.from.y,r=Math.sqrt(o*o+n*n),a>r)){h=!0;break}}if(!e&&h||e)for(c=0;l>c;c++)if(p=this.edges[d[c]],void 0!==p){var u=this.nodes[p.fromId==t.id?p.toId:p.fromId];u.dynamicEdges.length<=this.hubThreshold+s&&u.id!=t.id&&this._addToCluster(t,u,e)}}},e._addToCluster=function(t,e,i){t.containedNodes[e.id]=e;for(var s=0;s1)for(var s=0;s1&&(e.label="[".concat(String(e.clusterSize),"]"))}for(t in this.nodes)this.nodes.hasOwnProperty(t)&&(e=this.nodes[t],1==e.clusterSize&&(e.label=void 0!==e.originalLabel?e.originalLabel:String(e.id)))},e.normalizeClusterLevels=function(){var t,e=0,i=1e9,s=0;for(t in this.nodes)this.nodes.hasOwnProperty(t)&&(s=this.nodes[t].clusterSessions.length,s>e&&(e=s),i>s&&(i=s));if(e-i>this.constants.clustering.clusterLevelDifference){var o=this.nodeIndices.length,n=e-this.constants.clustering.clusterLevelDifference;for(t in this.nodes)this.nodes.hasOwnProperty(t)&&this.nodes[t].clusterSessions.lengths&&(s=n.dynamicEdgesLength),t+=n.dynamicEdgesLength,e+=Math.pow(n.dynamicEdgesLength,2),i+=1}t/=i,e/=i;var r=e-Math.pow(t,2),a=Math.sqrt(r);this.hubThreshold=Math.floor(t+2*a),this.hubThreshold>s&&(this.hubThreshold=s)},e._reduceAmountOfChains=function(t){this.hubThreshold=2;var e=Math.floor(this.nodeIndices.length*t);for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&2==this.nodes[i].dynamicEdgesLength&&this.nodes[i].dynamicEdges.length>=2&&e>0&&(this._formClusterFromHub(this.nodes[i],!0,!0,1),e-=1)},e._getChainFraction=function(){var t=0,e=0;for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&(2==this.nodes[i].dynamicEdgesLength&&this.nodes[i].dynamicEdges.length>=2&&(t+=1),e+=1);return t/e}},function(t,e,i){var s=i(1),o=i(39);e._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},e._switchToSector=function(t,e){void 0===e||"active"==e?this._switchToActiveSector(t):this._switchToFrozenSector(t)},e._switchToActiveSector=function(t){this.nodeIndices=this.sectors.active[t].nodeIndices,this.nodes=this.sectors.active[t].nodes,this.edges=this.sectors.active[t].edges},e._switchToSupportSector=function(){this.nodeIndices=this.sectors.support.nodeIndices,this.nodes=this.sectors.support.nodes,this.edges=this.sectors.support.edges},e._switchToFrozenSector=function(t){this.nodeIndices=this.sectors.frozen[t].nodeIndices,this.nodes=this.sectors.frozen[t].nodes,this.edges=this.sectors.frozen[t].edges},e._loadLatestSector=function(){this._switchToSector(this._sector())},e._sector=function(){return this.activeSector[this.activeSector.length-1]},e._previousSector=function(){if(this.activeSector.length>1)return this.activeSector[this.activeSector.length-2];throw new TypeError("there are not enough sectors in the this.activeSector array.")},e._setActiveSector=function(t){this.activeSector.push(t)},e._forgetLastSector=function(){this.activeSector.pop()},e._createNewSector=function(t){this.sectors.active[t]={nodes:{},edges:{},nodeIndices:[],formationScale:this.scale,drawingNode:void 0},this.sectors.active[t].drawingNode=new o({id:t,color:{background:"#eaefef",border:"495c5e"}},{},{},this.constants),this.sectors.active[t].drawingNode.clusterSize=2},e._deleteActiveSector=function(t){delete this.sectors.active[t]},e._deleteFrozenSector=function(t){delete this.sectors.frozen[t]},e._freezeSector=function(t){this.sectors.frozen[t]=this.sectors.active[t],this._deleteActiveSector(t)},e._activateSector=function(t){this.sectors.active[t]=this.sectors.frozen[t],this._deleteFrozenSector(t)},e._mergeThisWithFrozen=function(t){for(var e in this.nodes)this.nodes.hasOwnProperty(e)&&(this.sectors.frozen[t].nodes[e]=this.nodes[e]);for(var i in this.edges)this.edges.hasOwnProperty(i)&&(this.sectors.frozen[t].edges[i]=this.edges[i]);for(var s=0;s1?this[t](o[0],o[1]):this[t](e))}return this._loadLatestSector(),i},e._doInSupportSector=function(t,e){var i=!1;if(void 0===e)this._switchToSupportSector(),i=this[t]();else{this._switchToSupportSector();var s=Array.prototype.splice.call(arguments,1);i=s.length>1?this[t](s[0],s[1]):this[t](e)}return this._loadLatestSector(),i},e._doInAllFrozenSectors=function(t,e){if(void 0===e)for(var i in this.sectors.frozen)this.sectors.frozen.hasOwnProperty(i)&&(this._switchToFrozenSector(i),this[t]());else for(var i in this.sectors.frozen)if(this.sectors.frozen.hasOwnProperty(i)){this._switchToFrozenSector(i);var s=Array.prototype.splice.call(arguments,1);s.length>1?this[t](s[0],s[1]):this[t](e)}this._loadLatestSector()},e._doInAllSectors=function(t,e){var i=Array.prototype.splice.call(arguments,1);void 0===e?(this._doInAllActiveSectors(t),this._doInAllFrozenSectors(t)):i.length>1?(this._doInAllActiveSectors(t,i[0],i[1]),this._doInAllFrozenSectors(t,i[0],i[1])):(this._doInAllActiveSectors(t,e),this._doInAllFrozenSectors(t,e))},e._clearNodeIndexList=function(){var t=this._sector();this.sectors.active[t].nodeIndices=[],this.nodeIndices=this.sectors.active[t].nodeIndices},e._drawSectorNodes=function(t,e){var i,s=1e9,o=-1e9,n=1e9,r=-1e9;for(var a in this.sectors[e])if(this.sectors[e].hasOwnProperty(a)&&void 0!==this.sectors[e][a].drawingNode){this._switchToSector(a,e),s=1e9,o=-1e9,n=1e9,r=-1e9;for(var h in this.nodes)this.nodes.hasOwnProperty(h)&&(i=this.nodes[h],i.resize(t),n>i.x-.5*i.width&&(n=i.x-.5*i.width),ri.y-.5*i.height&&(s=i.y-.5*i.height),o0?this.nodes[i[i.length-1]]:null},e._getEdgesOverlappingWith=function(t,e){var i=this.edges;for(var s in i)i.hasOwnProperty(s)&&i[s].isOverlappingWith(t)&&e.push(s)},e._getAllEdgesOverlappingWith=function(t){var e=[]; -return this._doInAllActiveSectors("_getEdgesOverlappingWith",t,e),e},e._getEdgeAt=function(t){var e=this._pointerToPositionObject(t),i=this._getAllEdgesOverlappingWith(e);return i.length>0?this.edges[i[i.length-1]]:null},e._addToSelection=function(t){t instanceof s?this.selectionObj.nodes[t.id]=t:this.selectionObj.edges[t.id]=t},e._addToHover=function(t){t instanceof s?this.hoverObj.nodes[t.id]=t:this.hoverObj.edges[t.id]=t},e._removeFromSelection=function(t){t instanceof s?delete this.selectionObj.nodes[t.id]:delete this.selectionObj.edges[t.id]},e._unselectAll=function(t){void 0===t&&(t=!1);for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&this.selectionObj.nodes[e].unselect();for(var i in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(i)&&this.selectionObj.edges[i].unselect();this.selectionObj={nodes:{},edges:{}},0==t&&this.emit("select",this.getSelection())},e._unselectClusters=function(t){void 0===t&&(t=!1);for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&this.selectionObj.nodes[e].clusterSize>1&&(this.selectionObj.nodes[e].unselect(),this._removeFromSelection(this.selectionObj.nodes[e]));0==t&&this.emit("select",this.getSelection())},e._getSelectedNodeCount=function(){var t=0;for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&(t+=1);return t},e._getSelectedNode=function(){for(var t in this.selectionObj.nodes)if(this.selectionObj.nodes.hasOwnProperty(t))return this.selectionObj.nodes[t];return null},e._getSelectedEdge=function(){for(var t in this.selectionObj.edges)if(this.selectionObj.edges.hasOwnProperty(t))return this.selectionObj.edges[t];return null},e._getSelectedEdgeCount=function(){var t=0;for(var e in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(e)&&(t+=1);return t},e._getSelectedObjectCount=function(){var t=0;for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&(t+=1);for(var i in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(i)&&(t+=1);return t},e._selectionIsEmpty=function(){for(var t in this.selectionObj.nodes)if(this.selectionObj.nodes.hasOwnProperty(t))return!1;for(var e in this.selectionObj.edges)if(this.selectionObj.edges.hasOwnProperty(e))return!1;return!0},e._clusterInSelection=function(){for(var t in this.selectionObj.nodes)if(this.selectionObj.nodes.hasOwnProperty(t)&&this.selectionObj.nodes[t].clusterSize>1)return!0;return!1},e._selectConnectedEdges=function(t){for(var e=0;ei;i++){o=t[i];var n=this.nodes[o];if(!n)throw new RangeError('Node with id "'+o+'" not found');this._selectObject(n,!0,!0,e,!0)}this.redraw()},e.selectEdges=function(t){var e,i,s;if(!t||void 0==t.length)throw"Selection must be an array with ids";for(this._unselectAll(!0),e=0,i=t.length;i>e;e++){s=t[e];var o=this.edges[s];if(!o)throw new RangeError('Edge with id "'+s+'" not found');this._selectObject(o,!0,!0,!1,!0)}this.redraw()},e._updateSelection=function(){for(var t in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(t)&&(this.nodes.hasOwnProperty(t)||delete this.selectionObj.nodes[t]);for(var e in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(e)&&(this.edges.hasOwnProperty(e)||delete this.selectionObj.edges[e])}},function(t,e,i){var s=i(1),o=i(39),n=i(36);e._clearManipulatorBar=function(){for(;this.manipulationDiv.hasChildNodes();)this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);this._manipulationReleaseOverload=function(){},delete this.sectors.support.nodes.targetNode,delete this.sectors.support.nodes.targetViaNode,this.controlNodesActive=!1},e._restoreOverloadedFunctions=function(){for(var t in this.cachedFunctions)this.cachedFunctions.hasOwnProperty(t)&&(this[t]=this.cachedFunctions[t])},e._toggleEditMode=function(){this.editMode=!this.editMode;var t=document.getElementById("network-manipulationDiv"),e=document.getElementById("network-manipulation-closeDiv"),i=document.getElementById("network-manipulation-editMode");1==this.editMode?(t.style.display="block",e.style.display="block",i.style.display="none",e.onclick=this._toggleEditMode.bind(this)):(t.style.display="none",e.style.display="none",i.style.display="block",e.onclick=null),this._createManipulatorBar()},e._createManipulatorBar=function(){this.boundFunction&&this.off("select",this.boundFunction);var t=this.constants.locales[this.constants.locale];if(void 0!==this.edgeBeingEdited&&(this.edgeBeingEdited._disableControlNodes(),this.edgeBeingEdited=void 0,this.selectedControlNode=null,this.controlNodesActive=!1),this._restoreOverloadedFunctions(),this.freezeSimulation=!1,this.blockConnectingEdgeSelection=!1,this.forceAppendSelection=!1,1==this.editMode){for(;this.manipulationDiv.hasChildNodes();)this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);this.manipulationDiv.innerHTML=""+t.addNode+"
"+t.addEdge+"",1==this._getSelectedNodeCount()&&this.triggerFunctions.edit?this.manipulationDiv.innerHTML+="
"+t.editNode+"":1==this._getSelectedEdgeCount()&&0==this._getSelectedNodeCount()&&(this.manipulationDiv.innerHTML+="
"+t.editEdge+""),0==this._selectionIsEmpty()&&(this.manipulationDiv.innerHTML+="
"+t.del+"");var e=document.getElementById("network-manipulate-addNode");e.onclick=this._createAddNodeToolbar.bind(this);var i=document.getElementById("network-manipulate-connectNode");if(i.onclick=this._createAddEdgeToolbar.bind(this),1==this._getSelectedNodeCount()&&this.triggerFunctions.edit){var s=document.getElementById("network-manipulate-editNode");s.onclick=this._editNode.bind(this)}else if(1==this._getSelectedEdgeCount()&&0==this._getSelectedNodeCount()){var s=document.getElementById("network-manipulate-editEdge");s.onclick=this._createEditEdgeToolbar.bind(this)}if(0==this._selectionIsEmpty()){var o=document.getElementById("network-manipulate-delete");o.onclick=this._deleteSelected.bind(this)}var n=document.getElementById("network-manipulation-closeDiv");n.onclick=this._toggleEditMode.bind(this),this.boundFunction=this._createManipulatorBar.bind(this),this.on("select",this.boundFunction)}else{this.editModeDiv.innerHTML=""+t.edit+"";var r=document.getElementById("network-manipulate-editModeButton");r.onclick=this._toggleEditMode.bind(this)}},e._createAddNodeToolbar=function(){this._clearManipulatorBar(),this.boundFunction&&this.off("select",this.boundFunction);var t=this.constants.locales[this.constants.locale];this.manipulationDiv.innerHTML=""+t.back+"
"+t.addDescription+"";var e=document.getElementById("network-manipulate-back");e.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._addNode.bind(this),this.on("select",this.boundFunction)},e._createAddEdgeToolbar=function(){this._clearManipulatorBar(),this._unselectAll(!0),this.freezeSimulation=!0;var t=this.constants.locales[this.constants.locale];this.boundFunction&&this.off("select",this.boundFunction),this._unselectAll(),this.forceAppendSelection=!1,this.blockConnectingEdgeSelection=!0,this.manipulationDiv.innerHTML=""+t.back+"
"+t.edgeDescription+"";var e=document.getElementById("network-manipulate-back");e.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._handleConnect.bind(this),this.on("select",this.boundFunction),this.cachedFunctions._handleTouch=this._handleTouch,this.cachedFunctions._manipulationReleaseOverload=this._manipulationReleaseOverload,this.cachedFunctions._handleDragStart=this._handleDragStart,this.cachedFunctions._handleDragEnd=this._handleDragEnd,this._handleTouch=this._handleConnect,this._manipulationReleaseOverload=function(){},this._handleDragStart=function(){},this._handleDragEnd=this._finishConnect,this._redraw()},e._createEditEdgeToolbar=function(){this._clearManipulatorBar(),this.controlNodesActive=!0,this.boundFunction&&this.off("select",this.boundFunction),this.edgeBeingEdited=this._getSelectedEdge(),this.edgeBeingEdited._enableControlNodes();var t=this.constants.locales[this.constants.locale];this.manipulationDiv.innerHTML=""+t.back+"
"+t.editEdgeDescription+"";var e=document.getElementById("network-manipulate-back");e.onclick=this._createManipulatorBar.bind(this),this.cachedFunctions._handleTouch=this._handleTouch,this.cachedFunctions._manipulationReleaseOverload=this._manipulationReleaseOverload,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._manipulationReleaseOverload=this._releaseControlNode,this._redraw()},e._selectControlNode=function(t){this.edgeBeingEdited.controlNodes.from.unselect(),this.edgeBeingEdited.controlNodes.to.unselect(),this.selectedControlNode=this.edgeBeingEdited._getSelectedControlNode(this._XconvertDOMtoCanvas(t.x),this._YconvertDOMtoCanvas(t.y)),null!==this.selectedControlNode&&(this.selectedControlNode.select(),this.freezeSimulation=!0),this._redraw()},e._controlNodeDrag=function(t){var e=this._getPointer(t.gesture.center);null!==this.selectedControlNode&&void 0!==this.selectedControlNode&&(this.selectedControlNode.x=this._XconvertDOMtoCanvas(e.x),this.selectedControlNode.y=this._YconvertDOMtoCanvas(e.y)),this._redraw()},e._releaseControlNode=function(t){var e=this._getNodeAt(t);null!=e?(1==this.edgeBeingEdited.controlNodes.from.selected&&(this._editEdge(e.id,this.edgeBeingEdited.to.id),this.edgeBeingEdited.controlNodes.from.unselect()),1==this.edgeBeingEdited.controlNodes.to.selected&&(this._editEdge(this.edgeBeingEdited.from.id,e.id),this.edgeBeingEdited.controlNodes.to.unselect())):this.edgeBeingEdited._restoreControlNodes(),this.freezeSimulation=!1,this._redraw()},e._handleConnect=function(t){if(0==this._getSelectedNodeCount()){var e=this._getNodeAt(t);if(null!=e)if(e.clusterSize>1)alert(this.constants.locales[this.constants.locale].createEdgeError);else{this._selectObject(e,!1);var i=this.sectors.support.nodes;i.targetNode=new o({id:"targetNode"},{},{},this.constants);var s=i.targetNode;s.x=e.x,s.y=e.y,this.edges.connectionEdge=new n({id:"connectionEdge",from:e.id,to:s.id},this,this.constants);var r=this.edges.connectionEdge;r.from=e,r.connected=!0,r.options.smoothCurves={enabled:!0,dynamic:!1,type:"continuous",roundness:.5},r.selected=!0,r.to=s,this.cachedFunctions._handleOnDrag=this._handleOnDrag,this._handleOnDrag=function(t){var e=this._getPointer(t.gesture.center),i=this.edges.connectionEdge;i.to.x=this._XconvertDOMtoCanvas(e.x),i.to.y=this._YconvertDOMtoCanvas(e.y)},this.moving=!0,this.start()}}},e._finishConnect=function(t){if(1==this._getSelectedNodeCount()){var e=this._getPointer(t.gesture.center);this._handleOnDrag=this.cachedFunctions._handleOnDrag,delete this.cachedFunctions._handleOnDrag;var i=this.edges.connectionEdge.fromId;delete this.edges.connectionEdge,delete this.sectors.support.nodes.targetNode,delete this.sectors.support.nodes.targetViaNode;var s=this._getNodeAt(e);null!=s&&(s.clusterSize>1?alert(this.constants.locales[this.constants.locale].createEdgeError):(this._createEdge(i,s.id),this._createManipulatorBar())),this._unselectAll()}},e._addNode=function(){if(this._selectionIsEmpty()&&1==this.editMode){var t=this._pointerToPositionObject(this.pointerPosition),e={id:s.randomUUID(),x:t.left,y:t.top,label:"new",allowedToMoveX:!0,allowedToMoveY:!0};if(this.triggerFunctions.add){if(2!=this.triggerFunctions.add.length)throw new Error("The function for add does not support two arguments (data,callback)");var i=this;this.triggerFunctions.add(e,function(t){i.nodesData.add(t),i._createManipulatorBar(),i.moving=!0,i.start()})}else this.nodesData.add(e),this._createManipulatorBar(),this.moving=!0,this.start()}},e._createEdge=function(t,e){if(1==this.editMode){var i={from:t,to:e};if(this.triggerFunctions.connect){if(2!=this.triggerFunctions.connect.length)throw new Error("The function for connect does not support two arguments (data,callback)");var s=this;this.triggerFunctions.connect(i,function(t){s.edgesData.add(t),s.moving=!0,s.start()})}else this.edgesData.add(i),this.moving=!0,this.start()}},e._editEdge=function(t,e){if(1==this.editMode){var i={id:this.edgeBeingEdited.id,from:t,to:e};if(this.triggerFunctions.editEdge){if(2!=this.triggerFunctions.editEdge.length)throw new Error("The function for edit does not support two arguments (data, callback)");var s=this;this.triggerFunctions.editEdge(i,function(t){s.edgesData.update(t),s.moving=!0,s.start()})}else this.edgesData.update(i),this.moving=!0,this.start()}},e._editNode=function(){if(!this.triggerFunctions.edit||1!=this.editMode)throw new Error("No edit function has been bound to this button");var t=this._getSelectedNode(),e={id:t.id,label:t.label,group:t.options.group,shape:t.options.shape,color:{background:t.options.color.background,border:t.options.color.border,highlight:{background:t.options.color.highlight.background,border:t.options.color.highlight.border}}};if(2!=this.triggerFunctions.edit.length)throw new Error("The function for edit does not support two arguments (data, callback)");var i=this;this.triggerFunctions.edit(e,function(t){i.nodesData.update(t),i._createManipulatorBar(),i.moving=!0,i.start()})},e._deleteSelected=function(){if(!this._selectionIsEmpty()&&1==this.editMode)if(this._clusterInSelection())alert(this.constants.locales[this.constants.locale].deleteClusterError);else{var t=this.getSelectedNodes(),e=this.getSelectedEdges();if(this.triggerFunctions.del){var i=this,s={nodes:t,edges:e};if(!(this.triggerFunctions.del.length=2))throw new Error("The function for delete does not support two arguments (data, callback)");this.triggerFunctions.del(s,function(t){i.edgesData.remove(t.edges),i.nodesData.remove(t.nodes),i._unselectAll(),i.moving=!0,i.start()})}else this.edgesData.remove(e),this.nodesData.remove(t),this._unselectAll(),this.moving=!0,this.start()}}},function(t,e,i){var s=(i(1),i(44));e._cleanNavigation=function(){if(0!=this.navigationHammers.existing.length){for(var t=0;t0){"RL"==this.constants.hierarchicalLayout.direction||"DU"==this.constants.hierarchicalLayout.direction?this.constants.hierarchicalLayout.levelSeparation*=-1:this.constants.hierarchicalLayout.levelSeparation=Math.abs(this.constants.hierarchicalLayout.levelSeparation),"RL"==this.constants.hierarchicalLayout.direction||"LR"==this.constants.hierarchicalLayout.direction?1==this.constants.smoothCurves.enabled&&(this.constants.smoothCurves.type="vertical"):1==this.constants.smoothCurves.enabled&&(this.constants.smoothCurves.type="horizontal");var t,e,i=0,s=!1,o=!1;for(e in this.nodes)this.nodes.hasOwnProperty(e)&&(t=this.nodes[e],-1!=t.level?s=!0:o=!0,is&&(n.xFixed=!1,n.x=i[n.level].minPos,r=!0):n.yFixed&&n.level>s&&(n.yFixed=!1,n.y=i[n.level].minPos,r=!0),1==r&&(i[n.level].minPos+=i[n.level].nodeSpacing,n.edges.length>1&&this._placeBranchNodes(n.edges,n.id,i,n.level))}},e._setLevel=function(t,e,i){for(var s=0;st)&&(o.level=t,o.edges.length>1&&this._setLevel(t+1,o.edges,o.id))}},e._setLevelDirected=function(t,e,i){this.nodes[i].hierarchyEnumerated=!0;for(var s=0;s1&&o.hierarchyEnumerated===!1&&this._setLevelDirected(o.level,o.edges,o.id)}},e._restoreNodes=function(){for(var t in this.nodes)this.nodes.hasOwnProperty(t)&&(this.nodes[t].xFixed=!1,this.nodes[t].yFixed=!1)}},function(t,e,i){function s(){this.constants.smoothCurves.enabled=!this.constants.smoothCurves.enabled;var t=document.getElementById("graph_toggleSmooth");t.style.background=1==this.constants.smoothCurves.enabled?"#A4FF56":"#FF8532",this._configureSmoothCurves(!1)}function o(){for(var t in this.calculationNodes)this.calculationNodes.hasOwnProperty(t)&&(this.calculationNodes[t].vx=0,this.calculationNodes[t].vy=0,this.calculationNodes[t].fx=0,this.calculationNodes[t].fy=0);1==this.constants.hierarchicalLayout.enabled?(this._setupHierarchicalLayout(),a.call(this,"graph_H_nd",1,"physics_hierarchicalRepulsion_nodeDistance"),a.call(this,"graph_H_cg",1,"physics_centralGravity"),a.call(this,"graph_H_sc",1,"physics_springConstant"),a.call(this,"graph_H_sl",1,"physics_springLength"),a.call(this,"graph_H_damp",1,"physics_damping")):this.repositionNodes(),this.moving=!0,this.start()}function n(){var t="No options are required, default values used.",e=[],i=document.getElementById("graph_physicsMethod1"),s=document.getElementById("graph_physicsMethod2");if(1==i.checked){if(this.constants.physics.barnesHut.gravitationalConstant!=this.backupConstants.physics.barnesHut.gravitationalConstant&&e.push("gravitationalConstant: "+this.constants.physics.barnesHut.gravitationalConstant),this.constants.physics.centralGravity!=this.backupConstants.physics.barnesHut.centralGravity&&e.push("centralGravity: "+this.constants.physics.centralGravity),this.constants.physics.springLength!=this.backupConstants.physics.barnesHut.springLength&&e.push("springLength: "+this.constants.physics.springLength),this.constants.physics.springConstant!=this.backupConstants.physics.barnesHut.springConstant&&e.push("springConstant: "+this.constants.physics.springConstant),this.constants.physics.damping!=this.backupConstants.physics.barnesHut.damping&&e.push("damping: "+this.constants.physics.damping),0!=e.length){t="var options = {",t+="physics: {barnesHut: {";for(var o=0;othis.constants.clustering.clusterThreshold&&1==this.constants.clustering.enabled&&this.clusterToFit(this.constants.clustering.reduceToNodes,!1),this._calculateForces())},e._calculateForces=function(){this._calculateGravitationalForces(),this._calculateNodeForces(),this.constants.physics.springConstant>0&&(1==this.constants.smoothCurves.enabled&&1==this.constants.smoothCurves.dynamic?this._calculateSpringForcesWithSupport():1==this.constants.physics.hierarchicalRepulsion.enabled?this._calculateHierarchicalSpringForces():this._calculateSpringForces())},e._updateCalculationNodes=function(){if(1==this.constants.smoothCurves.enabled&&1==this.constants.smoothCurves.dynamic){this.calculationNodes={},this.calculationNodeIndices=[];for(var t in this.nodes)this.nodes.hasOwnProperty(t)&&(this.calculationNodes[t]=this.nodes[t]);var e=this.sectors.support.nodes;for(var i in e)e.hasOwnProperty(i)&&(this.edges.hasOwnProperty(e[i].parentEdgeId)?this.calculationNodes[i]=e[i]:e[i]._setForce(0,0));for(var s in this.calculationNodes)this.calculationNodes.hasOwnProperty(s)&&this.calculationNodeIndices.push(s)}else this.calculationNodes=this.nodes,this.calculationNodeIndices=this.nodeIndices},e._calculateGravitationalForces=function(){var t,e,i,s,o,n=this.calculationNodes,r=this.constants.physics.centralGravity,a=0;for(o=0;oSimulation Mode:Barnes HutRepulsionHierarchical
Options:
',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 e;e=document.getElementById("graph_BH_gc"),e.onchange=a.bind(this,"graph_BH_gc",-1,"physics_barnesHut_gravitationalConstant"),e=document.getElementById("graph_BH_cg"),e.onchange=a.bind(this,"graph_BH_cg",1,"physics_centralGravity"),e=document.getElementById("graph_BH_sc"),e.onchange=a.bind(this,"graph_BH_sc",1,"physics_springConstant"),e=document.getElementById("graph_BH_sl"),e.onchange=a.bind(this,"graph_BH_sl",1,"physics_springLength"),e=document.getElementById("graph_BH_damp"),e.onchange=a.bind(this,"graph_BH_damp",1,"physics_damping"),e=document.getElementById("graph_R_nd"),e.onchange=a.bind(this,"graph_R_nd",1,"physics_repulsion_nodeDistance"),e=document.getElementById("graph_R_cg"),e.onchange=a.bind(this,"graph_R_cg",1,"physics_centralGravity"),e=document.getElementById("graph_R_sc"),e.onchange=a.bind(this,"graph_R_sc",1,"physics_springConstant"),e=document.getElementById("graph_R_sl"),e.onchange=a.bind(this,"graph_R_sl",1,"physics_springLength"),e=document.getElementById("graph_R_damp"),e.onchange=a.bind(this,"graph_R_damp",1,"physics_damping"),e=document.getElementById("graph_H_nd"),e.onchange=a.bind(this,"graph_H_nd",1,"physics_hierarchicalRepulsion_nodeDistance"),e=document.getElementById("graph_H_cg"),e.onchange=a.bind(this,"graph_H_cg",1,"physics_centralGravity"),e=document.getElementById("graph_H_sc"),e.onchange=a.bind(this,"graph_H_sc",1,"physics_springConstant"),e=document.getElementById("graph_H_sl"),e.onchange=a.bind(this,"graph_H_sl",1,"physics_springLength"),e=document.getElementById("graph_H_damp"),e.onchange=a.bind(this,"graph_H_damp",1,"physics_damping"),e=document.getElementById("graph_H_direction"),e.onchange=a.bind(this,"graph_H_direction",t,"hierarchicalLayout_direction"),e=document.getElementById("graph_H_levsep"),e.onchange=a.bind(this,"graph_H_levsep",1,"hierarchicalLayout_levelSeparation"),e=document.getElementById("graph_H_nspac"),e.onchange=a.bind(this,"graph_H_nspac",1,"hierarchicalLayout_nodeSpacing");var i=document.getElementById("graph_physicsMethod1"),d=document.getElementById("graph_physicsMethod2"),l=document.getElementById("graph_physicsMethod3");d.checked=!0,this.constants.physics.barnesHut.enabled&&(i.checked=!0),this.constants.hierarchicalLayout.enabled&&(l.checked=!0);var c=document.getElementById("graph_toggleSmooth"),p=document.getElementById("graph_repositionNodes"),u=document.getElementById("graph_generateOptions");c.onclick=s.bind(this),p.onclick=o.bind(this),u.onclick=n.bind(this),c.style.background=1==this.constants.smoothCurves&&0==this.constants.dynamicSmoothCurves?"#A4FF56":"#FF8532",r.apply(this),i.onchange=r.bind(this),d.onchange=r.bind(this),l.onchange=r.bind(this)}},e._overWriteGraphConstants=function(t,e){var i=t.split("_");1==i.length?this.constants[i[0]]=e:2==i.length?this.constants[i[0]][i[1]]=e:3==i.length&&(this.constants[i[0]][i[1]][i[2]]=e)}},function(t){function e(t){throw new Error("Cannot find module '"+t+"'.")}e.keys=function(){return[]},e.resolve=e,t.exports=e,e.id=63},function(t,e){e._calculateNodeForces=function(){var t,e,i,s,o,n,r,a,h,d,l,c=this.calculationNodes,p=this.calculationNodeIndices,u=-2/3,f=4/3,m=this.constants.physics.repulsion.nodeDistance,g=m;for(d=0;di&&(r=.5*g>i?1:v*i+f,r*=0==n?1:1+n*this.constants.clustering.forceAmplification,r/=i,s=t*r,o=e*r,a.fx-=s,a.fy-=o,h.fx+=s,h.fy+=o)}}},function(t,e){e._calculateNodeForces=function(){var t,e,i,s,o,n,r,a,h,d,l=this.calculationNodes,c=this.calculationNodeIndices,p=this.constants.physics.hierarchicalRepulsion.nodeDistance;for(h=0;hi?-Math.pow(u*i,2)+Math.pow(u*p,2):0,0==i?i=.01:n/=i,s=t*n,o=e*n,r.fx-=s,r.fy-=o,a.fx+=s,a.fy+=o}},e._calculateHierarchicalSpringForces=function(){for(var t,e,i,s,o,n,r,a,h,d=this.edges,l=this.calculationNodes,c=this.calculationNodeIndices,p=0;pn;n++)t=e[i[n]],t.options.mass>0&&(this._getForceContribution(o.root.children.NW,t),this._getForceContribution(o.root.children.NE,t),this._getForceContribution(o.root.children.SW,t),this._getForceContribution(o.root.children.SE,t))}},e._getForceContribution=function(t,e){if(t.childrenCount>0){var i,s,o;if(i=t.centerOfMass.x-e.x,s=t.centerOfMass.y-e.y,o=Math.sqrt(i*i+s*s),o*t.calcSize>this.constants.physics.barnesHut.theta){0==o&&(o=.1*Math.random(),i=o);var n=this.constants.physics.barnesHut.gravitationalConstant*t.mass*e.options.mass/(o*o*o),r=i*n,a=s*n;e.fx+=r,e.fy+=a}else if(4==t.childrenCount)this._getForceContribution(t.children.NW,e),this._getForceContribution(t.children.NE,e),this._getForceContribution(t.children.SW,e),this._getForceContribution(t.children.SE,e);else if(t.children.data.id!=e.id){0==o&&(o=.5*Math.random(),i=o);var n=this.constants.physics.barnesHut.gravitationalConstant*t.mass*e.options.mass/(o*o*o),r=i*n,a=s*n;e.fx+=r,e.fy+=a}}},e._formBarnesHutTree=function(t,e){for(var i,s=e.length,o=Number.MAX_VALUE,n=Number.MAX_VALUE,r=-Number.MAX_VALUE,a=-Number.MAX_VALUE,h=0;s>h;h++){var d=t[e[h]].x,l=t[e[h]].y;t[e[h]].options.mass>0&&(o>d&&(o=d),d>r&&(r=d),n>l&&(n=l),l>a&&(a=l))}var c=Math.abs(r-o)-Math.abs(a-n);c>0?(n-=.5*c,a+=.5*c):(o+=.5*c,r-=.5*c);var p=1e-5,u=Math.max(p,Math.abs(r-o)),f=.5*u,m=.5*(o+r),g=.5*(n+a),v={root:{centerOfMass:{x:0,y:0},mass:0,range:{minX:m-f,maxX:m+f,minY:g-f,maxY:g+f},size:u,calcSize:1/u,children:{data:null},maxWidth:0,level:0,childrenCount:4}};for(this._splitBranch(v.root),h=0;s>h;h++)i=t[e[h]],i.options.mass>0&&this._placeInTree(v.root,i);this.barnesHutTree=v},e._updateBranchMass=function(t,e){var i=t.mass+e.options.mass,s=1/i;t.centerOfMass.x=t.centerOfMass.x*t.mass+e.x*e.options.mass,t.centerOfMass.x*=s,t.centerOfMass.y=t.centerOfMass.y*t.mass+e.y*e.options.mass,t.centerOfMass.y*=s,t.mass=i;var o=Math.max(Math.max(e.height,e.radius),e.width);t.maxWidth=t.maxWidthe.x?t.children.NW.range.maxY>e.y?this._placeInRegion(t,e,"NW"):this._placeInRegion(t,e,"SW"):t.children.NW.range.maxY>e.y?this._placeInRegion(t,e,"NE"):this._placeInRegion(t,e,"SE")},e._placeInRegion=function(t,e,i){switch(t.children[i].childrenCount){case 0:t.children[i].children.data=e,t.children[i].childrenCount=1,this._updateBranchMass(t.children[i],e);break;case 1:t.children[i].children.data.x==e.x&&t.children[i].children.data.y==e.y?(e.x+=Math.random(),e.y+=Math.random()):(this._splitBranch(t.children[i]),this._placeInTree(t.children[i],e));break;case 4:this._placeInTree(t.children[i],e)}},e._splitBranch=function(t){var e=null;1==t.childrenCount&&(e=t.children.data,t.mass=0,t.centerOfMass.x=0,t.centerOfMass.y=0),t.childrenCount=4,t.children.data=null,this._insertRegion(t,"NW"),this._insertRegion(t,"NE"),this._insertRegion(t,"SW"),this._insertRegion(t,"SE"),null!=e&&this._placeInTree(t,e)},e._insertRegion=function(t,e){var i,s,o,n,r=.5*t.size;switch(e){case"NW":i=t.range.minX,s=t.range.minX+r,o=t.range.minY,n=t.range.minY+r;break;case"NE":i=t.range.minX+r,s=t.range.maxX,o=t.range.minY,n=t.range.minY+r;break;case"SW":i=t.range.minX,s=t.range.minX+r,o=t.range.minY+r,n=t.range.maxY;break;case"SE":i=t.range.minX+r,s=t.range.maxX,o=t.range.minY+r,n=t.range.maxY}t.children[e]={centerOfMass:{x:0,y:0},mass:0,range:{minX:i,maxX:s,minY:o,maxY:n},size:.5*t.size,calcSize:2*t.calcSize,children:{data:null},maxWidth:0,level:t.level+1,childrenCount:0}},e._drawTree=function(t,e){void 0!==this.barnesHutTree&&(t.lineWidth=1,this._drawBranch(this.barnesHutTree.root,t,e))},e._drawBranch=function(t,e,i){void 0===i&&(i="#FF0000"),4==t.childrenCount&&(this._drawBranch(t.children.NW,e),this._drawBranch(t.children.NE,e),this._drawBranch(t.children.SE,e),this._drawBranch(t.children.SW,e)),e.strokeStyle=i,e.beginPath(),e.moveTo(t.range.minX,t.range.minY),e.lineTo(t.range.maxX,t.range.minY),e.stroke(),e.beginPath(),e.moveTo(t.range.maxX,t.range.minY),e.lineTo(t.range.maxX,t.range.maxY),e.stroke(),e.beginPath(),e.moveTo(t.range.maxX,t.range.maxY),e.lineTo(t.range.minX,t.range.maxY),e.stroke(),e.beginPath(),e.moveTo(t.range.minX,t.range.maxY),e.lineTo(t.range.minX,t.range.minY),e.stroke()}},function(t){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}}])}); +},s.prototype._line=function(t){if(t.beginPath(),t.moveTo(this.from.x,this.from.y),1==this.options.smoothCurves.enabled){if(0==this.options.smoothCurves.dynamic){var e=this._getViaCoordinates();return null==e.x?(t.lineTo(this.to.x,this.to.y),t.stroke(),null):(t.quadraticCurveTo(e.x,e.y,this.to.x,this.to.y),t.stroke(),e)}return t.quadraticCurveTo(this.via.x,this.via.y,this.to.x,this.to.y),t.stroke(),this.via}return t.lineTo(this.to.x,this.to.y),t.stroke(),null},s.prototype._circle=function(t,e,i,s){t.beginPath(),t.arc(e,i,s,0,2*Math.PI,!1),t.stroke()},s.prototype._label=function(t,e,i,s){if(e){t.font=(this.from.selected||this.to.selected?"bold ":"")+this.options.fontSize+"px "+this.options.fontFace;var o;if(1==this.dirtyLabel){var n=String(e).split("\n"),r=n.length,a=Number(this.options.fontSize)+4;o=s+(1-r)/2*a;for(var h=t.measureText(n[0]).width,d=1;r>d;d++){var l=t.measureText(n[d]).width;h=l>h?l:h}var c=this.options.fontSize*r,p=i-h/2,u=s-c/2;this.labelDimensions={top:u,left:p,width:h,height:c,yLine:o}}void 0!==this.options.fontFill&&null!==this.options.fontFill&&"none"!==this.options.fontFill&&(t.fillStyle=this.options.fontFill,t.fillRect(this.labelDimensions.left,this.labelDimensions.top,this.labelDimensions.width,this.labelDimensions.height)),t.fillStyle=this.options.fontColor||"black",t.textAlign="center",t.textBaseline="middle",o=this.labelDimensions.yLine;for(var d=0;r>d;d++)t.fillText(n[d],i,o),o+=a}},s.prototype._drawDashLine=function(t){t.strokeStyle=this._getColor(),t.lineWidth=this._getLineWidth();var e=null;if(void 0!==t.mozDash||void 0!==t.setLineDash){var i=[0];i=void 0!==this.options.dash.length&&void 0!==this.options.dash.gap?[this.options.dash.length,this.options.dash.gap]:[5,5],"undefined"!=typeof t.setLineDash?(t.setLineDash(i),t.lineDashOffset=0):(t.mozDash=i,t.mozDashOffset=0),e=this._line(t),"undefined"!=typeof t.setLineDash?(t.setLineDash([0]),t.lineDashOffset=0):(t.mozDash=[0],t.mozDashOffset=0)}else t.beginPath(),t.lineCap="round",void 0!==this.options.dash.altLength?t.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,[this.options.dash.length,this.options.dash.gap,this.options.dash.altLength,this.options.dash.gap]):void 0!==this.options.dash.length&&void 0!==this.options.dash.gap?t.dashedLine(this.from.x,this.from.y,this.to.x,this.to.y,[this.options.dash.length,this.options.dash.gap]):(t.moveTo(this.from.x,this.from.y),t.lineTo(this.to.x,this.to.y)),t.stroke();if(this.label){var s;if(1==this.options.smoothCurves.enabled&&null!=e){var o=.5*(.5*(this.from.x+e.x)+.5*(this.to.x+e.x)),n=.5*(.5*(this.from.y+e.y)+.5*(this.to.y+e.y));s={x:o,y:n}}else s=this._pointOnLine(.5);this._label(t,this.label,s.x,s.y)}},s.prototype._pointOnLine=function(t){return{x:(1-t)*this.from.x+t*this.to.x,y:(1-t)*this.from.y+t*this.to.y}},s.prototype._pointOnCircle=function(t,e,i,s){var o=2*(s-3/8)*Math.PI;return{x:t+i*Math.cos(o),y:e-i*Math.sin(o)}},s.prototype._drawArrowCenter=function(t){var e;if(t.strokeStyle=this._getColor(),t.lineWidth=this._getLineWidth(),this.from!=this.to){var i=this._line(t),s=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x),o=(10+5*this.options.width)*this.options.arrowScaleFactor;if(1==this.options.smoothCurves.enabled&&null!=i){var n=.5*(.5*(this.from.x+i.x)+.5*(this.to.x+i.x)),r=.5*(.5*(this.from.y+i.y)+.5*(this.to.y+i.y));e={x:n,y:r}}else e=this._pointOnLine(.5);t.arrow(e.x,e.y,s,o),t.fill(),t.stroke(),this.label&&this._label(t,this.label,e.x,e.y)}else{var a,h,d=.25*Math.max(100,this.physics.springLength),l=this.from;l.width||l.resize(t),l.width>l.height?(a=l.x+.5*l.width,h=l.y-d):(a=l.x+d,h=l.y-.5*l.height),this._circle(t,a,h,d);var s=.2*Math.PI,o=(10+5*this.options.width)*this.options.arrowScaleFactor;e=this._pointOnCircle(a,h,d,.5),t.arrow(e.x,e.y,s,o),t.fill(),t.stroke(),this.label&&(e=this._pointOnCircle(a,h,d,.5),this._label(t,this.label,e.x,e.y))}},s.prototype._drawArrow=function(t){t.strokeStyle=this._getColor(),t.lineWidth=this._getLineWidth();var e,i;if(this.from!=this.to){e=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x);var s,o=this.to.x-this.from.x,n=this.to.y-this.from.y,r=Math.sqrt(o*o+n*n),a=this.from.distanceToBorder(t,e+Math.PI),h=(r-a)/r,d=h*this.from.x+(1-h)*this.to.x,l=h*this.from.y+(1-h)*this.to.y;1==this.options.smoothCurves.dynamic&&1==this.options.smoothCurves.enabled?s=this.via:1==this.options.smoothCurves.enabled&&(s=this._getViaCoordinates()),1==this.options.smoothCurves.enabled&&null!=s.x&&(e=Math.atan2(this.to.y-s.y,this.to.x-s.x),o=this.to.x-s.x,n=this.to.y-s.y,r=Math.sqrt(o*o+n*n));var c,p,u=this.to.distanceToBorder(t,e),f=(r-u)/r;if(1==this.options.smoothCurves.enabled&&null!=s.x?(c=(1-f)*s.x+f*this.to.x,p=(1-f)*s.y+f*this.to.y):(c=(1-f)*this.from.x+f*this.to.x,p=(1-f)*this.from.y+f*this.to.y),t.beginPath(),t.moveTo(d,l),1==this.options.smoothCurves.enabled&&null!=s.x?t.quadraticCurveTo(s.x,s.y,c,p):t.lineTo(c,p),t.stroke(),i=(10+5*this.options.width)*this.options.arrowScaleFactor,t.arrow(c,p,e,i),t.fill(),t.stroke(),this.label){var m;if(1==this.options.smoothCurves.enabled&&null!=s){var g=.5*(.5*(this.from.x+s.x)+.5*(this.to.x+s.x)),v=.5*(.5*(this.from.y+s.y)+.5*(this.to.y+s.y));m={x:g,y:v}}else m=this._pointOnLine(.5);this._label(t,this.label,m.x,m.y)}}else{var y,b,_,x=this.from,w=.25*Math.max(100,this.physics.springLength);x.width||x.resize(t),x.width>x.height?(y=x.x+.5*x.width,b=x.y-w,_={x:y,y:x.y,angle:.9*Math.PI}):(y=x.x+w,b=x.y-.5*x.height,_={x:x.x,y:b,angle:.6*Math.PI}),t.beginPath(),t.arc(y,b,w,0,2*Math.PI,!1),t.stroke();var i=(10+5*this.options.width)*this.options.arrowScaleFactor;t.arrow(_.x,_.y,_.angle,i),t.fill(),t.stroke(),this.label&&(m=this._pointOnCircle(y,b,w,.5),this._label(t,this.label,m.x,m.y))}},s.prototype._getDistanceToEdge=function(t,e,i,s,o,n){var r=0;if(this.from!=this.to)if(1==this.options.smoothCurves.enabled){var a,h;if(1==this.options.smoothCurves.enabled&&1==this.options.smoothCurves.dynamic)a=this.via.x,h=this.via.y;else{var d=this._getViaCoordinates();a=d.x,h=d.y}var l,c,p,u,f,m,g,v=1e9;for(c=0;10>c;c++)p=.1*c,u=Math.pow(1-p,2)*t+2*p*(1-p)*a+Math.pow(p,2)*i,f=Math.pow(1-p,2)*e+2*p*(1-p)*h+Math.pow(p,2)*s,c>0&&(l=this._getDistanceToLine(m,g,u,f,o,n),v=v>l?l:v),m=u,g=f;r=v}else r=this._getDistanceToLine(t,e,i,s,o,n);else{var u,f,y,b,_=.25*this.physics.springLength,x=this.from;x.width>x.height?(u=x.x+.5*x.width,f=x.y-_):(u=x.x+_,f=x.y-.5*x.height),y=u-o,b=f-n,r=Math.abs(Math.sqrt(y*y+b*b)-_)}return this.labelDimensions.lefto&&this.labelDimensions.topn?0:r},s.prototype._getDistanceToLine=function(t,e,i,s,o,n){var r=i-t,a=s-e,h=r*r+a*a,d=((o-t)*r+(n-e)*a)/h;d>1?d=1:0>d&&(d=0);var l=t+d*r,c=e+d*a,p=l-o,u=c-n;return Math.sqrt(p*p+u*u)},s.prototype.setScale=function(t){this.networkScaleInv=1/t},s.prototype.select=function(){this.selected=!0},s.prototype.unselect=function(){this.selected=!1},s.prototype.positionBezierNode=function(){null!==this.via&&null!==this.from&&null!==this.to&&(this.via.x=.5*(this.from.x+this.to.x),this.via.y=.5*(this.from.y+this.to.y))},s.prototype._drawControlNodes=function(t){if(1==this.controlNodesEnabled){if(null===this.controlNodes.from&&null===this.controlNodes.to){var e="edgeIdFrom:".concat(this.id),i="edgeIdTo:".concat(this.id),s={nodes:{group:"",radius:8},physics:{damping:0},clustering:{maxNodeSizeIncrements:0,nodeScaling:{width:0,height:0,radius:0}}};this.controlNodes.from=new n({id:e,shape:"dot",color:{background:"#ff4e00",border:"#3c3c3c",highlight:{background:"#07f968"}}},{},{},s),this.controlNodes.to=new n({id:i,shape:"dot",color:{background:"#ff4e00",border:"#3c3c3c",highlight:{background:"#07f968"}}},{},{},s)}0==this.controlNodes.from.selected&&0==this.controlNodes.to.selected&&(this.controlNodes.positions=this.getControlNodePositions(t),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(t),this.controlNodes.to.draw(t)}else this.controlNodes={from:null,to:null,positions:{}}},s.prototype._enableControlNodes=function(){this.controlNodesEnabled=!0},s.prototype._disableControlNodes=function(){this.controlNodesEnabled=!1},s.prototype._getSelectedControlNode=function(t,e){var i=this.controlNodes.positions,s=Math.sqrt(Math.pow(t-i.from.x,2)+Math.pow(e-i.from.y,2)),o=Math.sqrt(Math.pow(t-i.to.x,2)+Math.pow(e-i.to.y,2));return 15>s?(this.connectedNode=this.from,this.from=this.controlNodes.from,this.controlNodes.from):15>o?(this.connectedNode=this.to,this.to=this.controlNodes.to,this.controlNodes.to):null},s.prototype._restoreControlNodes=function(){1==this.controlNodes.from.selected&&(this.from=this.connectedNode,this.connectedNode=null,this.controlNodes.from.unselect()),1==this.controlNodes.to.selected&&(this.to=this.connectedNode,this.connectedNode=null,this.controlNodes.to.unselect())},s.prototype.getControlNodePositions=function(t){var e,i=Math.atan2(this.to.y-this.from.y,this.to.x-this.from.x),s=this.to.x-this.from.x,o=this.to.y-this.from.y,n=Math.sqrt(s*s+o*o),r=this.from.distanceToBorder(t,i+Math.PI),a=(n-r)/n,h=a*this.from.x+(1-a)*this.to.x,d=a*this.from.y+(1-a)*this.to.y;1==this.options.smoothCurves.dynamic&&1==this.options.smoothCurves.enabled?e=this.via:1==this.options.smoothCurves.enabled&&(e=this._getViaCoordinates()),1==this.options.smoothCurves.enabled&&null!=e.x&&(i=Math.atan2(this.to.y-e.y,this.to.x-e.x),s=this.to.x-e.x,o=this.to.y-e.y,n=Math.sqrt(s*s+o*o));var l,c,p=this.to.distanceToBorder(t,i),u=(n-p)/n;return 1==this.options.smoothCurves.enabled&&null!=e.x?(l=(1-u)*e.x+u*this.to.x,c=(1-u)*e.y+u*this.to.y):(l=(1-u)*this.from.x+u*this.to.x,c=(1-u)*this.from.y+u*this.to.y),{from:{x:h,y:d},to:{x:l,y:c}}},t.exports=s},function(t,e,i){function s(){this.clear(),this.defaultIndex=0}var o=i(1);s.DEFAULT=[{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},{border:"#FFA500",background:"#FFFF00",highlight:{border:"#FFA500",background:"#FFFFA3"},hover:{border:"#FFA500",background:"#FFFFA3"}},{border:"#FA0A10",background:"#FB7E81",highlight:{border:"#FA0A10",background:"#FFAFB1"},hover:{border:"#FA0A10",background:"#FFAFB1"}},{border:"#41A906",background:"#7BE141",highlight:{border:"#41A906",background:"#A1EC76"},hover:{border:"#41A906",background:"#A1EC76"}},{border:"#E129F0",background:"#EB7DF4",highlight:{border:"#E129F0",background:"#F0B3F5"},hover:{border:"#E129F0",background:"#F0B3F5"}},{border:"#7C29F0",background:"#AD85E4",highlight:{border:"#7C29F0",background:"#D3BDF0"},hover:{border:"#7C29F0",background:"#D3BDF0"}},{border:"#C37F00",background:"#FFA807",highlight:{border:"#C37F00",background:"#FFCA66"},hover:{border:"#C37F00",background:"#FFCA66"}},{border:"#4220FB",background:"#6E6EFD",highlight:{border:"#4220FB",background:"#9B9BFD"},hover:{border:"#4220FB",background:"#9B9BFD"}},{border:"#FD5A77",background:"#FFC0CB",highlight:{border:"#FD5A77",background:"#FFD1D9"},hover:{border:"#FD5A77",background:"#FFD1D9"}},{border:"#4AD63A",background:"#C2FABC",highlight:{border:"#4AD63A",background:"#E6FFE3"},hover:{border:"#4AD63A",background:"#E6FFE3"}}],s.prototype.clear=function(){this.groups={},this.groups.length=function(){var t=0;for(var e in this)this.hasOwnProperty(e)&&t++;return t}},s.prototype.get=function(t){var e=this.groups[t];if(void 0==e){var i=this.defaultIndex%s.DEFAULT.length;this.defaultIndex++,e={},e.color=s.DEFAULT[i],this.groups[t]=e}return e},s.prototype.add=function(t,e){return this.groups[t]=e,e.color&&(e.color=o.parseColor(e.color)),e},t.exports=s},function(t){function e(){this.images={},this.callback=void 0}e.prototype.setOnloadCallback=function(t){this.callback=t},e.prototype.load=function(t,e){var i=this.images[t];if(void 0==i){var s=this;i=new Image,this.images[t]=i,i.onload=function(){s.callback&&s.callback(this)},i.onerror=function(){this.src=e,s.callback&&s.callback(this)},i.src=t}return i},t.exports=e},function(t,e,i){function s(t,e,i,s){var n=o.selectiveBridgeObject(["nodes"],s);this.options=n.nodes,this.selected=!1,this.hover=!1,this.edges=[],this.dynamicEdges=[],this.reroutedEdges={},this.fontDrawThreshold=3,this.id=void 0,this.x=null,this.y=null,this.allowedToMoveX=!1,this.allowedToMoveY=!1,this.xFixed=!1,this.yFixed=!1,this.horizontalAlignLeft=!0,this.verticalAlignTop=!0,this.baseRadiusValue=s.nodes.radius,this.radiusFixed=!1,this.level=-1,this.preassignedLevel=!1,this.hierarchyEnumerated=!1,this.labelDimensions={top:0,left:0,width:0,height:0,yLine:0},this.imagelist=e,this.grouplist=i,this.fx=0,this.fy=0,this.vx=0,this.vy=0,this.damping=s.physics.damping,this.fixedData={x:null,y:null},this.setProperties(t,n),this.resetCluster(),this.dynamicEdgesLength=0,this.clusterSession=0,this.clusterSizeWidthFactor=s.clustering.nodeScaling.width,this.clusterSizeHeightFactor=s.clustering.nodeScaling.height,this.clusterSizeRadiusFactor=s.clustering.nodeScaling.radius,this.maxNodeSizeIncrements=s.clustering.maxNodeSizeIncrements,this.growthIndicator=0,this.networkScaleInv=1,this.networkScale=1,this.canvasTopLeft={x:-300,y:-300},this.canvasBottomRight={x:300,y:300},this.parentEdgeId=null}var o=i(1);s.prototype.resetCluster=function(){this.formationScale=void 0,this.clusterSize=1,this.containedNodes={},this.containedEdges={},this.clusterSessions=[]},s.prototype.attachEdge=function(t){-1==this.edges.indexOf(t)&&this.edges.push(t),-1==this.dynamicEdges.indexOf(t)&&this.dynamicEdges.push(t),this.dynamicEdgesLength=this.dynamicEdges.length},s.prototype.detachEdge=function(t){var e=this.edges.indexOf(t);-1!=e&&this.edges.splice(e,1),e=this.dynamicEdges.indexOf(t),-1!=e&&this.dynamicEdges.splice(e,1),this.dynamicEdgesLength=this.dynamicEdges.length},s.prototype.setProperties=function(t,e){if(t){var i=["borderWidth","borderWidthSelected","shape","image","brokenImage","radius","fontColor","fontSize","fontFace","fontFill","group","mass"];if(o.selectiveDeepExtend(i,this.options,t),void 0!==t.id&&(this.id=t.id),void 0!==t.label&&(this.label=t.label,this.originalLabel=t.label),void 0!==t.title&&(this.title=t.title),void 0!==t.x&&(this.x=t.x),void 0!==t.y&&(this.y=t.y),void 0!==t.value&&(this.value=t.value),void 0!==t.level&&(this.level=t.level,this.preassignedLevel=!0),void 0!==t.horizontalAlignLeft&&(this.horizontalAlignLeft=t.horizontalAlignLeft),void 0!==t.verticalAlignTop&&(this.verticalAlignTop=t.verticalAlignTop),void 0!==t.triggerFunction&&(this.triggerFunction=t.triggerFunction),void 0===this.id)throw"Node must have an id";if("number"==typeof this.options.group||"string"==typeof this.options.group&&""!=this.options.group){var s=this.grouplist.get(this.options.group);for(var n in s)s.hasOwnProperty(n)&&(this.options[n]=s[n])}if(void 0!==t.radius&&(this.baseRadiusValue=this.options.radius),void 0!==t.color&&(this.options.color=o.parseColor(t.color)),void 0!==this.options.image&&""!=this.options.image){if(!this.imagelist)throw"No imagelist provided";this.imageObj=this.imagelist.load(this.options.image,this.options.brokenImage)}switch(void 0!==t.allowedToMoveX?(this.xFixed=!t.allowedToMoveX,this.allowedToMoveX=t.allowedToMoveX):void 0!==t.x&&0==this.allowedToMoveX&&(this.xFixed=!0),void 0!==t.allowedToMoveY?(this.yFixed=!t.allowedToMoveY,this.allowedToMoveY=t.allowedToMoveY):void 0!==t.y&&0==this.allowedToMoveY&&(this.yFixed=!0),this.radiusFixed=this.radiusFixed||void 0!==t.radius,"image"==this.options.shape&&(this.options.radiusMin=e.nodes.widthMin,this.options.radiusMax=e.nodes.widthMax),this.options.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;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}this._reset()}},s.prototype.select=function(){this.selected=!0,this._reset()},s.prototype.unselect=function(){this.selected=!1,this._reset()},s.prototype.clearSizeCache=function(){this._reset()},s.prototype._reset=function(){this.width=void 0,this.height=void 0},s.prototype.getTitle=function(){return"function"==typeof this.title?this.title():this.title},s.prototype.distanceToBorder=function(t,e){var i=1;switch(this.width||this.resize(t),this.options.shape){case"circle":case"dot":return this.options.radius+i;case"ellipse":var s=this.width/2,o=this.height/2,n=Math.sin(e)*s,r=Math.cos(e)*o;return s*o/Math.sqrt(n*n+r*r);case"box":case"image":case"text":default:return this.width?Math.min(Math.abs(this.width/2/Math.cos(e)),Math.abs(this.height/2/Math.sin(e)))+i:0}},s.prototype._setForce=function(t,e){this.fx=t,this.fy=e},s.prototype._addForce=function(t,e){this.fx+=t,this.fy+=e},s.prototype.discreteStep=function(t){if(this.xFixed)this.fx=0,this.vx=0;else{var e=this.damping*this.vx,i=(this.fx-e)/this.options.mass;this.vx+=i*t,this.x+=this.vx*t}if(this.yFixed)this.fy=0,this.vy=0;else{var s=this.damping*this.vy,o=(this.fy-s)/this.options.mass;this.vy+=o*t,this.y+=this.vy*t}},s.prototype.discreteStepLimited=function(t,e){if(this.xFixed)this.fx=0,this.vx=0;else{var i=this.damping*this.vx,s=(this.fx-i)/this.options.mass;this.vx+=s*t,this.vx=Math.abs(this.vx)>e?this.vx>0?e:-e:this.vx,this.x+=this.vx*t}if(this.yFixed)this.fy=0,this.vy=0;else{var o=this.damping*this.vy,n=(this.fy-o)/this.options.mass;this.vy+=n*t,this.vy=Math.abs(this.vy)>e?this.vy>0?e:-e:this.vy,this.y+=this.vy*t}},s.prototype.isFixed=function(){return this.xFixed&&this.yFixed},s.prototype.isMoving=function(t){var e=Math.sqrt(Math.pow(this.vx,2)+Math.pow(this.vy,2));return e>t},s.prototype.isSelected=function(){return this.selected},s.prototype.getValue=function(){return this.value},s.prototype.getDistance=function(t,e){var i=this.x-t,s=this.y-e;return Math.sqrt(i*i+s*s)},s.prototype.setValueRange=function(t,e){if(!this.radiusFixed&&void 0!==this.value)if(e==t)this.options.radius=(this.options.radiusMin+this.options.radiusMax)/2;else{var i=(this.options.radiusMax-this.options.radiusMin)/(e-t);this.options.radius=(this.value-t)*i+this.options.radiusMin}this.baseRadiusValue=this.options.radius},s.prototype.draw=function(){throw"Draw method not initialized for node"},s.prototype.resize=function(){throw"Resize method not initialized for node"},s.prototype.isOverlappingWith=function(t){return this.leftt.left&&this.topt.top},s.prototype._resizeImage=function(){if(!this.width||!this.height){var t,e;if(this.value){this.options.radius=this.baseRadiusValue;var i=this.imageObj.height/this.imageObj.width;void 0!==i?(t=this.options.radius||this.imageObj.width,e=this.options.radius*i||this.imageObj.height):(t=0,e=0)}else t=this.imageObj.width,e=this.imageObj.height;this.width=t,this.height=e,this.growthIndicator=0,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.options.radius+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-t)}},s.prototype._drawImage=function(t){this._resizeImage(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e;if(0!=this.imageObj.width){if(this.clusterSize>1){var i=this.clusterSize>1?10:0;i*=this.networkScaleInv,i=Math.min(.2*this.width,i),t.globalAlpha=.5,t.drawImage(this.imageObj,this.left-i,this.top-i,this.width+2*i,this.height+2*i)}t.globalAlpha=1,t.drawImage(this.imageObj,this.left,this.top,this.width,this.height),e=this.y+this.height/2}else e=this.y;this._label(t,this.label,this.x,e,void 0,"top")},s.prototype._resizeBox=function(t){if(!this.width){var e=5,i=this.getTextSize(t);this.width=i.width+2*e,this.height=i.height+2*e,this.width+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.growthIndicator=this.width-(i.width+2*e)}},s.prototype._drawBox=function(t){this._resizeBox(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=this.options.borderWidth,s=this.options.borderWidthSelected||2*this.options.borderWidth;t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.roundRect(this.left-2*t.lineWidth,this.top-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth,this.options.radius),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.options.color.background,t.roundRect(this.left,this.top,this.width,this.height,this.options.radius),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._resizeDatabase=function(t){if(!this.width){var e=5,i=this.getTextSize(t),s=i.width+2*e;this.width=s,this.height=s,this.width+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.options.radius+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-s}},s.prototype._drawDatabase=function(t){this._resizeDatabase(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=this.options.borderWidth,s=this.options.borderWidthSelected||2*this.options.borderWidth;t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.database(this.x-this.width/2-2*t.lineWidth,this.y-.5*this.height-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t.database(this.x-this.width/2,this.y-.5*this.height,this.width,this.height),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._resizeCircle=function(t){if(!this.width){var e=5,i=this.getTextSize(t),s=Math.max(i.width,i.height)+2*e;this.options.radius=s/2,this.width=s,this.height=s,this.options.radius+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.options.radius-.5*s}},s.prototype._drawCircle=function(t){this._resizeCircle(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var e=2.5,i=this.options.borderWidth,s=this.options.borderWidthSelected||2*this.options.borderWidth;t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.circle(this.x,this.y,this.options.radius+2*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t.circle(this.x,this.y,this.options.radius),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._resizeEllipse=function(t){if(!this.width){var e=this.getTextSize(t);this.width=1.5*e.width,this.height=2*e.height,this.width1&&(t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.ellipse(this.left-2*t.lineWidth,this.top-2*t.lineWidth,this.width+4*t.lineWidth,this.height+4*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?s:i)+(this.clusterSize>1?e:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t.ellipse(this.left,this.top,this.width,this.height),t.fill(),t.stroke(),this._label(t,this.label,this.x,this.y)},s.prototype._drawDot=function(t){this._drawShape(t,"circle")},s.prototype._drawTriangle=function(t){this._drawShape(t,"triangle")},s.prototype._drawTriangleDown=function(t){this._drawShape(t,"triangleDown")},s.prototype._drawSquare=function(t){this._drawShape(t,"square")},s.prototype._drawStar=function(t){this._drawShape(t,"star")},s.prototype._resizeShape=function(){if(!this.width){this.options.radius=this.baseRadiusValue;var t=2*this.options.radius;this.width=t,this.height=t,this.width+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.options.radius+=.5*Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-t}},s.prototype._drawShape=function(t,e){this._resizeShape(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2;var i=2.5,s=this.options.borderWidth,o=this.options.borderWidthSelected||2*this.options.borderWidth,n=2;switch(e){case"dot":n=2;break;case"square":n=2;break;case"triangle":n=3;break;case"triangleDown":n=3;break;case"star":n=4}t.strokeStyle=this.selected?this.options.color.highlight.border:this.hover?this.options.color.hover.border:this.options.color.border,this.clusterSize>1&&(t.lineWidth=(this.selected?o:s)+(this.clusterSize>1?i:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t[e](this.x,this.y,this.options.radius+n*t.lineWidth),t.stroke()),t.lineWidth=(this.selected?o:s)+(this.clusterSize>1?i:0),t.lineWidth*=this.networkScaleInv,t.lineWidth=Math.min(this.width,t.lineWidth),t.fillStyle=this.selected?this.options.color.highlight.background:this.hover?this.options.color.hover.background:this.options.color.background,t[e](this.x,this.y,this.options.radius),t.fill(),t.stroke(),this.label&&this._label(t,this.label,this.x,this.y+this.height/2,void 0,"top",!0)},s.prototype._resizeText=function(t){if(!this.width){var e=5,i=this.getTextSize(t);this.width=i.width+2*e,this.height=i.height+2*e,this.width+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeWidthFactor,this.height+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeHeightFactor,this.options.radius+=Math.min(this.clusterSize-1,this.maxNodeSizeIncrements)*this.clusterSizeRadiusFactor,this.growthIndicator=this.width-(i.width+2*e)}},s.prototype._drawText=function(t){this._resizeText(t),this.left=this.x-this.width/2,this.top=this.y-this.height/2,this._label(t,this.label,this.x,this.y)},s.prototype._label=function(t,e,i,s,o,n,r){if(e&&Number(this.options.fontSize)*this.networkScale>this.fontDrawThreshold){t.font=(this.selected?"bold ":"")+this.options.fontSize+"px "+this.options.fontFace;var a=e.split("\n"),h=a.length,d=Number(this.options.fontSize)+4,l=s+(1-h)/2*d;1==r&&(l=s+(1-h)/(2*d));for(var c=t.measureText(a[0]).width,p=1;h>p;p++){var u=t.measureText(a[p]).width;c=u>c?u:c}var f=this.options.fontSize*h,m=i-c/2,g=s-f/2;"top"==n&&(g+=.5*d),this.labelDimensions={top:g,left:m,width:c,height:f,yLine:l},void 0!==this.options.fontFill&&null!==this.options.fontFill&&"none"!==this.options.fontFill&&(t.fillStyle=this.options.fontFill,t.fillRect(m,g,c,f)),t.fillStyle=this.options.fontColor||"black",t.textAlign=o||"center",t.textBaseline=n||"middle";for(var p=0;h>p;p++)t.fillText(a[p],i,l),l+=d}},s.prototype.getTextSize=function(t){if(void 0!==this.label){t.font=(this.selected?"bold ":"")+this.options.fontSize+"px "+this.options.fontFace;for(var e=this.label.split("\n"),i=(Number(this.options.fontSize)+4)*e.length,s=0,o=0,n=e.length;n>o;o++)s=Math.max(s,t.measureText(e[o]).width);return{width:s,height:i}}return{width:0,height:0}},s.prototype.inArea=function(){return void 0!==this.width?this.x+this.width*this.networkScaleInv>=this.canvasTopLeft.x&&this.x-this.width*this.networkScaleInv=this.canvasTopLeft.y&&this.y-this.height*this.networkScaleInv=this.canvasTopLeft.x&&this.x=this.canvasTopLeft.y&&this.ys&&(n=s-e-this.padding),no&&(r=o-i-this.padding),ri;i++)if(e.id===r.nodes[i].id){o=r.nodes[i];break}for(o||(o={id:e.id},t.node&&(o.attr=a(o.attr,t.node))),i=n.length-1;i>=0;i--){var h=n[i];h.nodes||(h.nodes=[]),-1==h.nodes.indexOf(o)&&h.nodes.push(o)}e.attr&&(o.attr=a(o.attr,e.attr))}function l(t,e){if(t.edges||(t.edges=[]),t.edges.push(e),t.edge){var i=a({},t.edge);e.attr=a(i,e.attr)}}function c(t,e,i,s,o){var n={from:e,to:i,type:s};return t.edge&&(n.attr=a({},t.edge)),n.attr=a(n.attr||{},o),n}function p(){for(k=M.NULL,L="";" "==O||" "==O||"\n"==O||"\r"==O;)o();do{var t=!1;if("#"==O){for(var e=T-1;" "==E.charAt(e)||" "==E.charAt(e);)e--;if("\n"==E.charAt(e)||""==E.charAt(e)){for(;""!=O&&"\n"!=O;)o();t=!0}}if("/"==O&&"/"==n()){for(;""!=O&&"\n"!=O;)o();t=!0}if("/"==O&&"*"==n()){for(;""!=O;){if("*"==O&&"/"==n()){o(),o();break}o()}t=!0}for(;" "==O||" "==O||"\n"==O||"\r"==O;)o()}while(t);if(""==O)return void(k=M.DELIMITER);var i=O+n();if(C[i])return k=M.DELIMITER,L=i,o(),void o();if(C[O])return k=M.DELIMITER,L=O,void o();if(r(O)||"-"==O){for(L+=O,o();r(O);)L+=O,o();return"false"==L?L=!1:"true"==L?L=!0:isNaN(Number(L))||(L=Number(L)),void(k=M.IDENTIFIER)}if('"'==O){for(o();""!=O&&('"'!=O||'"'==O&&'"'==n());)L+=O,'"'==O&&o(),o();if('"'!=O)throw x('End of string " expected');return o(),void(k=M.IDENTIFIER)}for(k=M.UNKNOWN;""!=O;)L+=O,o();throw new SyntaxError('Syntax error in part "'+w(L,30)+'"')}function u(){var t={};if(s(),p(),"strict"==L&&(t.strict=!0,p()),("graph"==L||"digraph"==L)&&(t.type=L,p()),k==M.IDENTIFIER&&(t.id=L,p()),"{"!=L)throw x("Angle bracket { expected");if(p(),f(t),"}"!=L)throw x("Angle bracket } expected");if(p(),""!==L)throw x("End of file expected");return p(),delete t.node,delete t.edge,delete t.graph,t}function f(t){for(;""!==L&&"}"!=L;)m(t),";"==L&&p()}function m(t){var e=g(t);if(e)return void b(t,e);var i=v(t);if(!i){if(k!=M.IDENTIFIER)throw x("Identifier expected");var s=L;if(p(),"="==L){if(p(),k!=M.IDENTIFIER)throw x("Identifier expected");t[s]=L,p()}else y(t,s)}}function g(t){var e=null;if("subgraph"==L&&(e={},e.type="subgraph",p(),k==M.IDENTIFIER&&(e.id=L,p())),"{"==L){if(p(),e||(e={}),e.parent=t,e.node=t.node,e.edge=t.edge,e.graph=t.graph,f(e),"}"!=L)throw x("Angle bracket } expected");p(),delete e.node,delete e.edge,delete e.graph,delete e.parent,t.subgraphs||(t.subgraphs=[]),t.subgraphs.push(e)}return e}function v(t){return"node"==L?(p(),t.node=_(),"node"):"edge"==L?(p(),t.edge=_(),"edge"):"graph"==L?(p(),t.graph=_(),"graph"):null}function y(t,e){var i={id:e},s=_();s&&(i.attr=s),d(t,i),b(t,e)}function b(t,e){for(;"->"==L||"--"==L;){var i,s=L;p();var o=g(t);if(o)i=o;else{if(k!=M.IDENTIFIER)throw x("Identifier or subgraph expected");i=L,d(t,{id:i}),p()}var n=_(),r=c(t,e,i,s,n);l(t,r),e=i}}function _(){for(var t=null;"["==L;){for(p(),t={};""!==L&&"]"!=L;){if(k!=M.IDENTIFIER)throw x("Attribute name expected");var e=L;if(p(),"="!=L)throw x("Equal sign = expected");if(p(),k!=M.IDENTIFIER)throw x("Attribute value expected");var i=L;h(t,e,i),p(),","==L&&p()}if("]"!=L)throw x("Bracket ] expected");p()}return t}function x(t){return new SyntaxError(t+', got "'+w(L,30)+'" (char '+T+")")}function w(t,e){return t.length<=e?t:t.substr(0,27)+"..."}function S(t,e,i){Array.isArray(t)?t.forEach(function(t){Array.isArray(e)?e.forEach(function(e){i(t,e)}):i(t,e)}):Array.isArray(e)?e.forEach(function(e){i(t,e)}):i(t,e)}function D(t){function e(t){var e={from:t.from,to:t.to};return a(e,t.attr),e.style="->"==t.type?"arrow":"line",e}var s=i(t),o={nodes:[],edges:[],options:{}};return s.nodes&&s.nodes.forEach(function(t){var e={id:t.id,label:String(t.label||t.id)};a(e,t.attr),e.image&&(e.shape="image"),o.nodes.push(e)}),s.edges&&s.edges.forEach(function(t){var i,s;i=t.from instanceof Object?t.from.nodes:{id:t.from},s=t.to instanceof Object?t.to.nodes:{id:t.to},t.from instanceof Object&&t.from.edges&&t.from.edges.forEach(function(t){var i=e(t);o.edges.push(i)}),S(i,s,function(i,s){var n=c(o,i.id,s.id,t.type,t.attr),r=e(n);o.edges.push(r)}),t.to instanceof Object&&t.to.edges&&t.to.edges.forEach(function(t){var i=e(t);o.edges.push(i)})}),s.attr&&(o.options=s.attr),o}var M={NULL:0,DELIMITER:1,IDENTIFIER:2,UNKNOWN:3},C={"{":!0,"}":!0,"[":!0,"]":!0,";":!0,"=":!0,",":!0,"->":!0,"--":!0},E="",T=0,O="",L="",k=M.NULL,N=/[a-zA-Z_0-9.:#]/;e.parseDOT=i,e.DOTToGraph=D},function(t,e){function i(t,e){var i=[],s=[];this.options={edges:{inheritColor:!0},nodes:{allowedToMove:!1,parseColor:!1}},void 0!==e&&(this.options.nodes.allowedToMove=e.allowedToMove|!1,this.options.nodes.parseColor=e.parseColor|!1,this.options.edges.inheritColor=e.inheritColor|!0);for(var o=t.edges,n=t.nodes,r=0;r=o&&(o=864e5),i=new Date(i.valueOf()-.05*o),s=new Date(s.valueOf()+.05*o)}if(null!==i||null!==s){var n=t&&void 0!==t.animate?t.animate:!0;this.range.setRange(i,s,n)}},s.prototype.setWindow=function(t,e,i){var s=i&&void 0!==i.animate?i.animate:!0;if(1==arguments.length){var o=arguments[0];this.range.setRange(o.start,o.end,s)}else this.range.setRange(t,e,s)},s.prototype.moveTo=function(t,e){var i=this.range.end-this.range.start,s=r.convert(t,"Date").valueOf(),o=s-i/2,n=s+i/2,a=e&&void 0!==e.animate?e.animate:!0;this.range.setRange(o,n,a)},s.prototype.getWindow=function(){var t=this.range.getRange();return{start:new Date(t.start),end:new Date(t.end)}},s.prototype.redraw=function(){var t=!1,e=this.options,i=this.props,s=this.dom;if(s){h.updateHiddenDates(this.body,this.options.hiddenDates),"top"==e.orientation?(r.addClassName(s.root,"top"),r.removeClassName(s.root,"bottom")):(r.removeClassName(s.root,"top"),r.addClassName(s.root,"bottom")),s.root.style.maxHeight=r.option.asSize(e.maxHeight,""),s.root.style.minHeight=r.option.asSize(e.minHeight,""),s.root.style.width=r.option.asSize(e.width,""),i.border.left=(s.centerContainer.offsetWidth-s.centerContainer.clientWidth)/2,i.border.right=i.border.left,i.border.top=(s.centerContainer.offsetHeight-s.centerContainer.clientHeight)/2,i.border.bottom=i.border.top;var o=s.root.offsetHeight-s.root.clientHeight,n=s.root.offsetWidth-s.root.clientWidth;0===s.centerContainer.clientHeight&&(i.border.left=i.border.top,i.border.right=i.border.left),0===s.root.clientHeight&&(n=o),i.center.height=s.center.offsetHeight,i.left.height=s.left.offsetHeight,i.right.height=s.right.offsetHeight,i.top.height=s.top.clientHeight||-i.border.top,i.bottom.height=s.bottom.clientHeight||-i.border.bottom;var a=Math.max(i.left.height,i.center.height,i.right.height),d=i.top.height+a+i.bottom.height+o+i.border.top+i.border.bottom;s.root.style.height=r.option.asSize(e.height,d+"px"),i.root.height=s.root.offsetHeight,i.background.height=i.root.height-o;var l=i.root.height-i.top.height-i.bottom.height-o;i.centerContainer.height=l,i.leftContainer.height=l,i.rightContainer.height=i.leftContainer.height,i.root.width=s.root.offsetWidth,i.background.width=i.root.width-n,i.left.width=s.leftContainer.clientWidth||-i.border.left,i.leftContainer.width=i.left.width,i.right.width=s.rightContainer.clientWidth||-i.border.right,i.rightContainer.width=i.right.width;var c=i.root.width-i.left.width-i.right.width-n;i.center.width=c,i.centerContainer.width=c,i.top.width=c,i.bottom.width=c,s.background.style.height=i.background.height+"px",s.backgroundVertical.style.height=i.background.height+"px",s.backgroundHorizontal.style.height=i.centerContainer.height+"px",s.centerContainer.style.height=i.centerContainer.height+"px",s.leftContainer.style.height=i.leftContainer.height+"px",s.rightContainer.style.height=i.rightContainer.height+"px",s.background.style.width=i.background.width+"px",s.backgroundVertical.style.width=i.centerContainer.width+"px",s.backgroundHorizontal.style.width=i.background.width+"px",s.centerContainer.style.width=i.center.width+"px",s.top.style.width=i.top.width+"px",s.bottom.style.width=i.bottom.width+"px",s.background.style.left="0",s.background.style.top="0",s.backgroundVertical.style.left=i.left.width+i.border.left+"px",s.backgroundVertical.style.top="0",s.backgroundHorizontal.style.left="0",s.backgroundHorizontal.style.top=i.top.height+"px",s.centerContainer.style.left=i.left.width+"px",s.centerContainer.style.top=i.top.height+"px",s.leftContainer.style.left="0",s.leftContainer.style.top=i.top.height+"px",s.rightContainer.style.left=i.left.width+i.center.width+"px",s.rightContainer.style.top=i.top.height+"px",s.top.style.left=i.left.width+"px",s.top.style.top="0",s.bottom.style.left=i.left.width+"px",s.bottom.style.top=i.top.height+i.centerContainer.height+"px",this._updateScrollTop();var p=this.props.scrollTop;"bottom"==e.orientation&&(p+=Math.max(this.props.centerContainer.height-this.props.center.height-this.props.border.top-this.props.border.bottom,0)),s.center.style.left="0",s.center.style.top=p+"px",s.left.style.left="0",s.left.style.top=p+"px",s.right.style.left="0",s.right.style.top=p+"px";var u=0==this.props.scrollTop?"hidden":"",f=this.props.scrollTop==this.props.scrollTopMin?"hidden":"";s.shadowTop.style.visibility=u,s.shadowBottom.style.visibility=f,s.shadowTopLeft.style.visibility=u,s.shadowBottomLeft.style.visibility=f,s.shadowTopRight.style.visibility=u,s.shadowBottomRight.style.visibility=f,this.components.forEach(function(e){t=e.redraw()||t}),t&&this.redraw()}},s.prototype.repaint=function(){throw new Error("Function repaint is deprecated. Use redraw instead.")},s.prototype.setCurrentTime=function(t){if(!this.currentTime)throw new Error("Option showCurrentTime must be true");this.currentTime.setCurrentTime(t)},s.prototype.getCurrentTime=function(){if(!this.currentTime)throw new Error("Option showCurrentTime must be true");return this.currentTime.getCurrentTime()},s.prototype._toTime=function(t){return h.toTime(this.body,this.range,t,this.props.center.width)},s.prototype._toGlobalTime=function(t){return h.toTime(this.body,this.range,t,this.props.root.width)},s.prototype._toScreen=function(t){return h.toScreen(this,t,this.props.center.width)},s.prototype._toGlobalScreen=function(t){return h.toScreen(this,t,this.props.root.width)},s.prototype._initAutoResize=function(){1==this.options.autoResize?this._startAutoResize():this._stopAutoResize()},s.prototype._startAutoResize=function(){var t=this;this._stopAutoResize(),this._onResize=function(){return 1!=t.options.autoResize?void t._stopAutoResize():void(t.dom.root&&(t.dom.root.offsetWidth!=t.props.lastWidth||t.dom.root.offsetHeight!=t.props.lastHeight)&&(t.props.lastWidth=t.dom.root.offsetWidth,t.props.lastHeight=t.dom.root.offsetHeight,t.emit("change")))},r.addEventListener(window,"resize",this._onResize),this.watchTimer=setInterval(this._onResize,1e3)},s.prototype._stopAutoResize=function(){this.watchTimer&&(clearInterval(this.watchTimer),this.watchTimer=void 0),r.removeEventListener(window,"resize",this._onResize),this._onResize=null},s.prototype._onTouch=function(){this.touch.allowDragging=!0},s.prototype._onPinch=function(){this.touch.allowDragging=!1},s.prototype._onDragStart=function(){this.touch.initialScrollTop=this.props.scrollTop},s.prototype._onDrag=function(t){if(this.touch.allowDragging){var e=t.gesture.deltaY,i=this._getScrollTop(),s=this._setScrollTop(this.touch.initialScrollTop+e);s!=i&&this.redraw()}},s.prototype._setScrollTop=function(t){return this.props.scrollTop=t,this._updateScrollTop(),this.props.scrollTop},s.prototype._updateScrollTop=function(){var t=Math.min(this.props.centerContainer.height-this.props.center.height,0);return t!=this.props.scrollTopMin&&("bottom"==this.options.orientation&&(this.props.scrollTop+=t-this.props.scrollTopMin),this.props.scrollTopMin=t),this.props.scrollTop>0&&(this.props.scrollTop=0),this.props.scrollTops;s++){var o=s%2===0?1.3*i:.5*i;this.lineTo(t+o*Math.sin(2*s*Math.PI/10),e-o*Math.cos(2*s*Math.PI/10))}this.closePath()},CanvasRenderingContext2D.prototype.roundRect=function(t,e,i,s,o){var n=Math.PI/180;0>i-2*o&&(o=i/2),0>s-2*o&&(o=s/2),this.beginPath(),this.moveTo(t+o,e),this.lineTo(t+i-o,e),this.arc(t+i-o,e+o,o,270*n,360*n,!1),this.lineTo(t+i,e+s-o),this.arc(t+i-o,e+s-o,o,0,90*n,!1),this.lineTo(t+o,e+s),this.arc(t+o,e+s-o,o,90*n,180*n,!1),this.lineTo(t,e+o),this.arc(t+o,e+o,o,180*n,270*n,!1)},CanvasRenderingContext2D.prototype.ellipse=function(t,e,i,s){var o=.5522848,n=i/2*o,r=s/2*o,a=t+i,h=e+s,d=t+i/2,l=e+s/2;this.beginPath(),this.moveTo(t,l),this.bezierCurveTo(t,l-r,d-n,e,d,e),this.bezierCurveTo(d+n,e,a,l-r,a,l),this.bezierCurveTo(a,l+r,d+n,h,d,h),this.bezierCurveTo(d-n,h,t,l+r,t,l)},CanvasRenderingContext2D.prototype.database=function(t,e,i,s){var o=1/3,n=i,r=s*o,a=.5522848,h=n/2*a,d=r/2*a,l=t+n,c=e+r,p=t+n/2,u=e+r/2,f=e+(s-r/2),m=e+s;this.beginPath(),this.moveTo(l,u),this.bezierCurveTo(l,u+d,p+h,c,p,c),this.bezierCurveTo(p-h,c,t,u+d,t,u),this.bezierCurveTo(t,u-d,p-h,e,p,e),this.bezierCurveTo(p+h,e,l,u-d,l,u),this.lineTo(l,f),this.bezierCurveTo(l,f+d,p+h,m,p,m),this.bezierCurveTo(p-h,m,t,f+d,t,f),this.lineTo(t,u)},CanvasRenderingContext2D.prototype.arrow=function(t,e,i,s){var o=t-s*Math.cos(i),n=e-s*Math.sin(i),r=t-.9*s*Math.cos(i),a=e-.9*s*Math.sin(i),h=o+s/3*Math.cos(i+.5*Math.PI),d=n+s/3*Math.sin(i+.5*Math.PI),l=o+s/3*Math.cos(i-.5*Math.PI),c=n+s/3*Math.sin(i-.5*Math.PI);this.beginPath(),this.moveTo(t,e),this.lineTo(h,d),this.lineTo(r,a),this.lineTo(l,c),this.closePath()},CanvasRenderingContext2D.prototype.dashedLine=function(t,e,i,s,o){o||(o=[10,5]),0==p&&(p=.001);var n=o.length;this.moveTo(t,e);for(var r=i-t,a=s-e,h=a/r,d=Math.sqrt(r*r+a*a),l=0,c=!0;d>=.1;){var p=o[l++%n];p>d&&(p=d);var u=Math.sqrt(p*p/(1+h*h));0>r&&(u=-u),t+=u,e+=h*u,this[c?"lineTo":"moveTo"](t,e),d-=p,c=!c}})},function(t,e,i){var s=i(62),o=i(56),n=i(57),r=i(58),a=i(59),h=i(60),d=i(61);e._loadMixin=function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e])},e._clearMixin=function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=void 0)},e._loadPhysicsSystem=function(){this._loadMixin(s),this._loadSelectedForceSolver(),1==this.constants.configurePhysics&&this._loadPhysicsConfiguration()},e._loadClusterSystem=function(){this.clusterSession=0,this.hubThreshold=5,this._loadMixin(o)},e._loadSectorSystem=function(){this.sectors={},this.activeSector=["default"],this.sectors.active={},this.sectors.active["default"]={nodes:{},edges:{},nodeIndices:[],formationScale:1,drawingNode:void 0},this.sectors.frozen={},this.sectors.support={nodes:{},edges:{},nodeIndices:[],formationScale:1,drawingNode:void 0},this.nodeIndices=this.sectors.active["default"].nodeIndices,this._loadMixin(n)},e._loadSelectionSystem=function(){this.selectionObj={nodes:{},edges:{}},this._loadMixin(r)},e._loadManipulationSystem=function(){this.blockConnectingEdgeSelection=!1,this.forceAppendSelection=!1,1==this.constants.dataManipulation.enabled?(void 0===this.manipulationDiv&&(this.manipulationDiv=document.createElement("div"),this.manipulationDiv.className="network-manipulationDiv",this.manipulationDiv.id="network-manipulationDiv",this.manipulationDiv.style.display=1==this.editMode?"block":"none",this.frame.appendChild(this.manipulationDiv)),void 0===this.editModeDiv&&(this.editModeDiv=document.createElement("div"),this.editModeDiv.className="network-manipulation-editMode",this.editModeDiv.id="network-manipulation-editMode",this.editModeDiv.style.display=1==this.editMode?"none":"block",this.frame.appendChild(this.editModeDiv)),void 0===this.closeDiv&&(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.frame.appendChild(this.closeDiv)),this._loadMixin(a),this._createManipulatorBar()):void 0!==this.manipulationDiv&&(this._createManipulatorBar(),this.frame.removeChild(this.manipulationDiv),this.frame.removeChild(this.editModeDiv),this.frame.removeChild(this.closeDiv),this.manipulationDiv=void 0,this.editModeDiv=void 0,this.closeDiv=void 0,this._clearMixin(a))},e._loadNavigationControls=function(){this._loadMixin(h),this._cleanNavigation(),1==this.constants.navigation.enabled&&this._loadNavigationElements()},e._loadHierarchySystem=function(){this._loadMixin(d)}},function(t,e,i){function s(t){this.active=!1,this.dom={container:t},this.dom.overlay=document.createElement("div"),this.dom.overlay.className="overlay",this.dom.container.appendChild(this.dom.overlay),this.hammer=a(this.dom.overlay,{prevent_default:!1}),this.hammer.on("tap",this._onTapOverlay.bind(this));var e=this,i=["touch","pinch","doubletap","hold","dragstart","drag","dragend","mousewheel","DOMMouseScroll"];i.forEach(function(t){e.hammer.on(t,function(t){t.stopPropagation()})}),this.windowHammer=a(window,{prevent_default:!1}),this.windowHammer.on("tap",function(i){o(i.target,t)||e.deactivate()}),this.escListener=this.deactivate.bind(this)}function o(t,e){for(;t;){if(t===e)return!0;t=t.parentNode}return!1}var n=i(55),r=i(52),a=i(44),h=i(1);r(s.prototype),s.current=null,s.prototype.destroy=function(){this.deactivate(),this.dom.overlay.parentNode.removeChild(this.dom.overlay),this.hammer=null,this.windowHammer=null},s.prototype.activate=function(){s.current&&s.current.deactivate(),s.current=this,this.active=!0,this.dom.overlay.style.display="none",h.addClassName(this.dom.container,"vis-active"),this.emit("change"),this.emit("activate"),n.bind("esc",this.escListener)},s.prototype.deactivate=function(){this.active=!1,this.dom.overlay.style.display="",h.removeClassName(this.dom.container,"vis-active"),n.unbind("esc",this.escListener),this.emit("change"),this.emit("deactivate")},s.prototype._onTapOverlay=function(t){this.activate(),t.stopPropagation()},t.exports=s},function(t){function e(t){return t?i(t):void 0}function i(t){for(var i in e.prototype)t[i]=e.prototype[i];return t}t.exports=e,e.prototype.on=e.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks[t]=this._callbacks[t]||[]).push(e),this},e.prototype.once=function(t,e){function i(){s.off(t,i),e.apply(this,arguments)}var s=this;return this._callbacks=this._callbacks||{},i.fn=e,this.on(t,i),this},e.prototype.off=e.prototype.removeListener=e.prototype.removeAllListeners=e.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var i=this._callbacks[t];if(!i)return this;if(1==arguments.length)return delete this._callbacks[t],this;for(var s,o=0;os;++s)i[s].apply(this,e)}return this},e.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks[t]||[]},e.prototype.hasListeners=function(t){return!!this.listeners(t).length}},function(t,e,i){var s;(function(t,o){(function(n){function r(t,e,i){switch(arguments.length){case 2:return null!=t?t:e;case 3:return null!=t?t:null!=e?e:i;default:throw new Error("Implement me")}}function a(t,e){return Le.call(t,e)}function h(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function d(t){De.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function l(t,e){var i=!0;return v(function(){return i&&(d(t),i=!1),e.apply(this,arguments)},e)}function c(t,e){xi[t]||(d(e),xi[t]=!0)}function p(t,e){return function(i){return _(t.call(this,i),e)}}function u(t,e){return function(i){return this.localeData().ordinal(t.call(this,i),e)}}function f(){}function m(t,e){e!==!1&&P(t),y(this,t),this._d=new Date(+t._d)}function g(t){var e=O(t),i=e.year||0,s=e.quarter||0,o=e.month||0,n=e.week||0,r=e.day||0,a=e.hour||0,h=e.minute||0,d=e.second||0,l=e.millisecond||0;this._milliseconds=+l+1e3*d+6e4*h+36e5*a,this._days=+r+7*n,this._months=+o+3*s+12*i,this._data={},this._locale=De.localeData(),this._bubble()}function v(t,e){for(var i in e)a(e,i)&&(t[i]=e[i]);return a(e,"toString")&&(t.toString=e.toString),a(e,"valueOf")&&(t.valueOf=e.valueOf),t}function y(t,e){var i,s,o;if("undefined"!=typeof e._isAMomentObject&&(t._isAMomentObject=e._isAMomentObject),"undefined"!=typeof e._i&&(t._i=e._i),"undefined"!=typeof e._f&&(t._f=e._f),"undefined"!=typeof e._l&&(t._l=e._l),"undefined"!=typeof e._strict&&(t._strict=e._strict),"undefined"!=typeof e._tzm&&(t._tzm=e._tzm),"undefined"!=typeof e._isUTC&&(t._isUTC=e._isUTC),"undefined"!=typeof e._offset&&(t._offset=e._offset),"undefined"!=typeof e._pf&&(t._pf=e._pf),"undefined"!=typeof e._locale&&(t._locale=e._locale),He.length>0)for(i in He)s=He[i],o=e[s],"undefined"!=typeof o&&(t[s]=o);return t}function b(t){return 0>t?Math.ceil(t):Math.floor(t)}function _(t,e,i){for(var s=""+Math.abs(t),o=t>=0;s.lengths;s++)(i&&t[s]!==e[s]||!i&&k(t[s])!==k(e[s]))&&r++;return r+n}function T(t){if(t){var e=t.toLowerCase().replace(/(.)s$/,"$1");t=fi[t]||mi[e]||e}return t}function O(t){var e,i,s={};for(i in t)a(t,i)&&(e=T(i),e&&(s[e]=t[i]));return s}function L(t){var e,i;if(0===t.indexOf("week"))e=7,i="day";else{if(0!==t.indexOf("month"))return;e=12,i="month"}De[t]=function(s,o){var r,a,h=De._locale[t],d=[];if("number"==typeof s&&(o=s,s=n),a=function(t){var e=De().utc().set(i,t); +return h.call(De._locale,e,s||"")},null!=o)return a(o);for(r=0;e>r;r++)d.push(a(r));return d}}function k(t){var e=+t,i=0;return 0!==e&&isFinite(e)&&(i=e>=0?Math.floor(e):Math.ceil(e)),i}function N(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function I(t,e,i){return pe(De([t,11,31+e-i]),e,i).week}function A(t){return z(t)?366:365}function z(t){return t%4===0&&t%100!==0||t%400===0}function P(t){var e;t._a&&-2===t._pf.overflow&&(e=t._a[Ne]<0||t._a[Ne]>11?Ne:t._a[Ie]<1||t._a[Ie]>N(t._a[ke],t._a[Ne])?Ie:t._a[Ae]<0||t._a[Ae]>23?Ae:t._a[ze]<0||t._a[ze]>59?ze:t._a[Pe]<0||t._a[Pe]>59?Pe:t._a[Re]<0||t._a[Re]>999?Re:-1,t._pf._overflowDayOfYear&&(ke>e||e>Ie)&&(e=Ie),t._pf.overflow=e)}function R(t){return null==t._isValid&&(t._isValid=!isNaN(t._d.getTime())&&t._pf.overflow<0&&!t._pf.empty&&!t._pf.invalidMonth&&!t._pf.nullInput&&!t._pf.invalidFormat&&!t._pf.userInvalidated,t._strict&&(t._isValid=t._isValid&&0===t._pf.charsLeftOver&&0===t._pf.unusedTokens.length)),t._isValid}function F(t){return t?t.toLowerCase().replace("_","-"):t}function H(t){for(var e,i,s,o,n=0;n0;){if(s=Y(o.slice(0,e).join("-")))return s;if(i&&i.length>=e&&E(o,i,!0)>=e-1)break;e--}n++}return null}function Y(t){var e=null;if(!Fe[t]&&Ye)try{e=De.locale(),!function(){var t=new Error('Cannot find module "./locale"');throw t.code="MODULE_NOT_FOUND",t}(),De.locale(e)}catch(i){}return Fe[t]}function B(t,e){return e._isUTC?De(t).zone(e._offset||0):De(t).local()}function W(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function G(t){var e,i,s=t.match(je);for(e=0,i=s.length;i>e;e++)s[e]=_i[s[e]]?_i[s[e]]:W(s[e]);return function(o){var n="";for(e=0;i>e;e++)n+=s[e]instanceof Function?s[e].call(o,t):s[e];return n}}function j(t,e){return t.isValid()?(e=U(e,t.localeData()),gi[e]||(gi[e]=G(e)),gi[e](t)):t.localeData().invalidDate()}function U(t,e){function i(t){return e.longDateFormat(t)||t}var s=5;for(Ue.lastIndex=0;s>=0&&Ue.test(t);)t=t.replace(Ue,i),Ue.lastIndex=0,s-=1;return t}function V(t,e){var i,s=e._strict;switch(t){case"Q":return ii;case"DDDD":return oi;case"YYYY":case"GGGG":case"gggg":return s?ni:Ze;case"Y":case"G":case"g":return ai;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return s?ri:qe;case"S":if(s)return ii;case"SS":if(s)return si;case"SSS":if(s)return oi;case"DDD":return Xe;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Qe;case"a":case"A":return e._locale._meridiemParse;case"X":return ti;case"Z":case"ZZ":return $e;case"T":return Je;case"SSSS":return Ke;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return s?si:Ve;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Ve;case"Do":return ei;default:return i=new RegExp(ee(te(t.replace("\\","")),"i"))}}function X(t){t=t||"";var e=t.match($e)||[],i=e[e.length-1]||[],s=(i+"").match(pi)||["-",0,0],o=+(60*s[1])+k(s[2]);return"+"===s[0]?-o:o}function Z(t,e,i){var s,o=i._a;switch(t){case"Q":null!=e&&(o[Ne]=3*(k(e)-1));break;case"M":case"MM":null!=e&&(o[Ne]=k(e)-1);break;case"MMM":case"MMMM":s=i._locale.monthsParse(e),null!=s?o[Ne]=s:i._pf.invalidMonth=e;break;case"D":case"DD":null!=e&&(o[Ie]=k(e));break;case"Do":null!=e&&(o[Ie]=k(parseInt(e,10)));break;case"DDD":case"DDDD":null!=e&&(i._dayOfYear=k(e));break;case"YY":o[ke]=De.parseTwoDigitYear(e);break;case"YYYY":case"YYYYY":case"YYYYYY":o[ke]=k(e);break;case"a":case"A":i._isPm=i._locale.isPM(e);break;case"H":case"HH":case"h":case"hh":o[Ae]=k(e);break;case"m":case"mm":o[ze]=k(e);break;case"s":case"ss":o[Pe]=k(e);break;case"S":case"SS":case"SSS":case"SSSS":o[Re]=k(1e3*("0."+e));break;case"X":i._d=new Date(1e3*parseFloat(e));break;case"Z":case"ZZ":i._useUTC=!0,i._tzm=X(e);break;case"dd":case"ddd":case"dddd":s=i._locale.weekdaysParse(e),null!=s?(i._w=i._w||{},i._w.d=s):i._pf.invalidWeekday=e;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":t=t.substr(0,1);case"gggg":case"GGGG":case"GGGGG":t=t.substr(0,2),e&&(i._w=i._w||{},i._w[t]=k(e));break;case"gg":case"GG":i._w=i._w||{},i._w[t]=De.parseTwoDigitYear(e)}}function q(t){var e,i,s,o,n,a,h;e=t._w,null!=e.GG||null!=e.W||null!=e.E?(n=1,a=4,i=r(e.GG,t._a[ke],pe(De(),1,4).year),s=r(e.W,1),o=r(e.E,1)):(n=t._locale._week.dow,a=t._locale._week.doy,i=r(e.gg,t._a[ke],pe(De(),n,a).year),s=r(e.w,1),null!=e.d?(o=e.d,n>o&&++s):o=null!=e.e?e.e+n:n),h=ue(i,s,o,a,n),t._a[ke]=h.year,t._dayOfYear=h.dayOfYear}function K(t){var e,i,s,o,n=[];if(!t._d){for(s=$(t),t._w&&null==t._a[Ie]&&null==t._a[Ne]&&q(t),t._dayOfYear&&(o=r(t._a[ke],s[ke]),t._dayOfYear>A(o)&&(t._pf._overflowDayOfYear=!0),i=he(o,0,t._dayOfYear),t._a[Ne]=i.getUTCMonth(),t._a[Ie]=i.getUTCDate()),e=0;3>e&&null==t._a[e];++e)t._a[e]=n[e]=s[e];for(;7>e;e++)t._a[e]=n[e]=null==t._a[e]?2===e?1:0:t._a[e];t._d=(t._useUTC?he:ae).apply(null,n),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()+t._tzm)}}function Q(t){var e;t._d||(e=O(t._i),t._a=[e.year,e.month,e.day,e.hour,e.minute,e.second,e.millisecond],K(t))}function $(t){var e=new Date;return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function J(t){if(t._f===De.ISO_8601)return void se(t);t._a=[],t._pf.empty=!0;var e,i,s,o,n,r=""+t._i,a=r.length,h=0;for(s=U(t._f,t._locale).match(je)||[],e=0;e0&&t._pf.unusedInput.push(n),r=r.slice(r.indexOf(i)+i.length),h+=i.length),_i[o]?(i?t._pf.empty=!1:t._pf.unusedTokens.push(o),Z(o,i,t)):t._strict&&!i&&t._pf.unusedTokens.push(o);t._pf.charsLeftOver=a-h,r.length>0&&t._pf.unusedInput.push(r),t._isPm&&t._a[Ae]<12&&(t._a[Ae]+=12),t._isPm===!1&&12===t._a[Ae]&&(t._a[Ae]=0),K(t),P(t)}function te(t){return t.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,i,s,o){return e||i||s||o})}function ee(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function ie(t){var e,i,s,o,n;if(0===t._f.length)return t._pf.invalidFormat=!0,void(t._d=new Date(0/0));for(o=0;on)&&(s=n,i=e));v(t,i||e)}function se(t){var e,i,s=t._i,o=hi.exec(s);if(o){for(t._pf.iso=!0,e=0,i=li.length;i>e;e++)if(li[e][1].exec(s)){t._f=li[e][0]+(o[6]||" ");break}for(e=0,i=ci.length;i>e;e++)if(ci[e][1].exec(s)){t._f+=ci[e][0];break}s.match($e)&&(t._f+="Z"),J(t)}else t._isValid=!1}function oe(t){se(t),t._isValid===!1&&(delete t._isValid,De.createFromInputFallback(t))}function ne(t,e){var i,s=[];for(i=0;it&&a.setFullYear(t),a}function he(t){var e=new Date(Date.UTC.apply(null,arguments));return 1970>t&&e.setUTCFullYear(t),e}function de(t,e){if("string"==typeof t)if(isNaN(t)){if(t=e.weekdaysParse(t),"number"!=typeof t)return null}else t=parseInt(t,10);return t}function le(t,e,i,s,o){return o.relativeTime(e||1,!!i,t,s)}function ce(t,e,i){var s=De.duration(t).abs(),o=Oe(s.as("s")),n=Oe(s.as("m")),r=Oe(s.as("h")),a=Oe(s.as("d")),h=Oe(s.as("M")),d=Oe(s.as("y")),l=o0,l[4]=i,le.apply({},l)}function pe(t,e,i){var s,o=i-e,n=i-t.day();return n>o&&(n-=7),o-7>n&&(n+=7),s=De(t).add(n,"d"),{week:Math.ceil(s.dayOfYear()/7),year:s.year()}}function ue(t,e,i,s,o){var n,r,a=he(t,0,1).getUTCDay();return a=0===a?7:a,i=null!=i?i:o,n=o-a+(a>s?7:0)-(o>a?7:0),r=7*(e-1)+(i-o)+n+1,{year:r>0?t:t-1,dayOfYear:r>0?r:A(t-1)+r}}function fe(t){var e=t._i,i=t._f;return t._locale=t._locale||De.localeData(t._l),null===e||i===n&&""===e?De.invalid({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),De.isMoment(e)?new m(e,!0):(i?M(i)?ie(t):J(t):re(t),new m(t)))}function me(t,e){var i,s;if(1===e.length&&M(e[0])&&(e=e[0]),!e.length)return De();for(i=e[0],s=1;s=0?"+":"-";return e+_(Math.abs(t),6)},gg:function(){return _(this.weekYear()%100,2)},gggg:function(){return _(this.weekYear(),4)},ggggg:function(){return _(this.weekYear(),5)},GG:function(){return _(this.isoWeekYear()%100,2)},GGGG:function(){return _(this.isoWeekYear(),4)},GGGGG:function(){return _(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return k(this.milliseconds()/100)},SS:function(){return _(k(this.milliseconds()/10),2)},SSS:function(){return _(this.milliseconds(),3)},SSSS:function(){return _(this.milliseconds(),3)},Z:function(){var t=-this.zone(),e="+";return 0>t&&(t=-t,e="-"),e+_(k(t/60),2)+":"+_(k(t)%60,2)},ZZ:function(){var t=-this.zone(),e="+";return 0>t&&(t=-t,e="-"),e+_(k(t/60),2)+_(k(t)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},xi={},wi=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];yi.length;)Ce=yi.pop(),_i[Ce+"o"]=u(_i[Ce],Ce);for(;bi.length;)Ce=bi.pop(),_i[Ce+Ce]=p(_i[Ce],2);_i.DDDD=p(_i.DDD,3),v(f.prototype,{set:function(t){var e,i;for(i in t)e=t[i],"function"==typeof e?this[i]=e:this["_"+i]=e},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(t){return this._months[t.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(t){return this._monthsShort[t.month()]},monthsParse:function(t){var e,i,s;for(this._monthsParse||(this._monthsParse=[]),e=0;12>e;e++)if(this._monthsParse[e]||(i=De.utc([2e3,e]),s="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[e]=new RegExp(s.replace(".",""),"i")),this._monthsParse[e].test(t))return e},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(t){return this._weekdays[t.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(t){return this._weekdaysShort[t.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(t){return this._weekdaysMin[t.day()]},weekdaysParse:function(t){var e,i,s;for(this._weekdaysParse||(this._weekdaysParse=[]),e=0;7>e;e++)if(this._weekdaysParse[e]||(i=De([2e3,1]).day(e),s="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[e]=new RegExp(s.replace(".",""),"i")),this._weekdaysParse[e].test(t))return e},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM D, YYYY LT"},longDateFormat:function(t){var e=this._longDateFormat[t];return!e&&this._longDateFormat[t.toUpperCase()]&&(e=this._longDateFormat[t.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t]=e),e},isPM:function(t){return"p"===(t+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(t,e,i){return t>11?i?"pm":"PM":i?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(t,e){var i=this._calendar[t];return"function"==typeof i?i.apply(e):i},_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"},relativeTime:function(t,e,i,s){var o=this._relativeTime[i];return"function"==typeof o?o(t,e,i,s):o.replace(/%d/i,t)},pastFuture:function(t,e){var i=this._relativeTime[t>0?"future":"past"];return"function"==typeof i?i(e):i.replace(/%s/i,e)},ordinal:function(t){return this._ordinal.replace("%d",t)},_ordinal:"%d",preparse:function(t){return t},postformat:function(t){return t},week:function(t){return pe(t,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),De=function(t,e,i,s){var o;return"boolean"==typeof i&&(s=i,i=n),o={},o._isAMomentObject=!0,o._i=t,o._f=e,o._l=i,o._strict=s,o._isUTC=!1,o._pf=h(),fe(o)},De.suppressDeprecationWarnings=!1,De.createFromInputFallback=l("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(t){t._d=new Date(t._i)}),De.min=function(){var t=[].slice.call(arguments,0);return me("isBefore",t)},De.max=function(){var t=[].slice.call(arguments,0);return me("isAfter",t)},De.utc=function(t,e,i,s){var o;return"boolean"==typeof i&&(s=i,i=n),o={},o._isAMomentObject=!0,o._useUTC=!0,o._isUTC=!0,o._l=i,o._i=t,o._f=e,o._strict=s,o._pf=h(),fe(o).utc()},De.unix=function(t){return De(1e3*t)},De.duration=function(t,e){var i,s,o,n,r=t,h=null;return De.isDuration(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:"number"==typeof t?(r={},e?r[e]=t:r.milliseconds=t):(h=We.exec(t))?(i="-"===h[1]?-1:1,r={y:0,d:k(h[Ie])*i,h:k(h[Ae])*i,m:k(h[ze])*i,s:k(h[Pe])*i,ms:k(h[Re])*i}):(h=Ge.exec(t))?(i="-"===h[1]?-1:1,o=function(t){var e=t&&parseFloat(t.replace(",","."));return(isNaN(e)?0:e)*i},r={y:o(h[2]),M:o(h[3]),d:o(h[4]),h:o(h[5]),m:o(h[6]),s:o(h[7]),w:o(h[8])}):"object"==typeof r&&("from"in r||"to"in r)&&(n=w(De(r.from),De(r.to)),r={},r.ms=n.milliseconds,r.M=n.months),s=new g(r),De.isDuration(t)&&a(t,"_locale")&&(s._locale=t._locale),s},De.version=Ee,De.defaultFormat=di,De.ISO_8601=function(){},De.momentProperties=He,De.updateOffset=function(){},De.relativeTimeThreshold=function(t,e){return vi[t]===n?!1:e===n?vi[t]:(vi[t]=e,!0)},De.lang=l("moment.lang is deprecated. Use moment.locale instead.",function(t,e){return De.locale(t,e)}),De.locale=function(t,e){var i;return t&&(i="undefined"!=typeof e?De.defineLocale(t,e):De.localeData(t),i&&(De.duration._locale=De._locale=i)),De._locale._abbr},De.defineLocale=function(t,e){return null!==e?(e.abbr=t,Fe[t]||(Fe[t]=new f),Fe[t].set(e),De.locale(t),Fe[t]):(delete Fe[t],null)},De.langData=l("moment.langData is deprecated. Use moment.localeData instead.",function(t){return De.localeData(t)}),De.localeData=function(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return De._locale;if(!M(t)){if(e=Y(t))return e;t=[t]}return H(t)},De.isMoment=function(t){return t instanceof m||null!=t&&a(t,"_isAMomentObject")},De.isDuration=function(t){return t instanceof g};for(Ce=wi.length-1;Ce>=0;--Ce)L(wi[Ce]);De.normalizeUnits=function(t){return T(t)},De.invalid=function(t){var e=De.utc(0/0);return null!=t?v(e._pf,t):e._pf.userInvalidated=!0,e},De.parseZone=function(){return De.apply(null,arguments).parseZone()},De.parseTwoDigitYear=function(t){return k(t)+(k(t)>68?1900:2e3)},v(De.fn=m.prototype,{clone:function(){return De(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var t=De(this).utc();return 00:!1},parsingFlags:function(){return v({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(t){return this.zone(0,t)},local:function(t){return this._isUTC&&(this.zone(0,t),this._isUTC=!1,t&&this.add(this._dateTzOffset(),"m")),this},format:function(t){var e=j(this,t||De.defaultFormat);return this.localeData().postformat(e)},add:S(1,"add"),subtract:S(-1,"subtract"),diff:function(t,e,i){var s,o,n,r=B(t,this),a=6e4*(this.zone()-r.zone());return e=T(e),"year"===e||"month"===e?(s=432e5*(this.daysInMonth()+r.daysInMonth()),o=12*(this.year()-r.year())+(this.month()-r.month()),n=this-De(this).startOf("month")-(r-De(r).startOf("month")),n-=6e4*(this.zone()-De(this).startOf("month").zone()-(r.zone()-De(r).startOf("month").zone())),o+=n/s,"year"===e&&(o/=12)):(s=this-r,o="second"===e?s/1e3:"minute"===e?s/6e4:"hour"===e?s/36e5:"day"===e?(s-a)/864e5:"week"===e?(s-a)/6048e5:s),i?o:b(o)},from:function(t,e){return De.duration({to:this,from:t}).locale(this.locale()).humanize(!e)},fromNow:function(t){return this.from(De(),t)},calendar:function(t){var e=t||De(),i=B(e,this).startOf("day"),s=this.diff(i,"days",!0),o=-6>s?"sameElse":-1>s?"lastWeek":0>s?"lastDay":1>s?"sameDay":2>s?"nextDay":7>s?"nextWeek":"sameElse";return this.format(this.localeData().calendar(o,this))},isLeapYear:function(){return z(this.year())},isDST:function(){return this.zone()+t):+this.clone().startOf(e)>+De(t).startOf(e)},isBefore:function(t,e){return e=T("undefined"!=typeof e?e:"millisecond"),"millisecond"===e?(t=De.isMoment(t)?t:De(t),+t>+this):+this.clone().startOf(e)<+De(t).startOf(e)},isSame:function(t,e){return e=T(e||"millisecond"),"millisecond"===e?(t=De.isMoment(t)?t:De(t),+this===+t):+this.clone().startOf(e)===+B(t,this).startOf(e)},min:l("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(t){return t=De.apply(null,arguments),this>t?this:t}),max:l("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(t){return t=De.apply(null,arguments),t>this?this:t}),zone:function(t,e){var i,s=this._offset||0;return null==t?this._isUTC?s:this._dateTzOffset():("string"==typeof t&&(t=X(t)),Math.abs(t)<16&&(t=60*t),!this._isUTC&&e&&(i=this._dateTzOffset()),this._offset=t,this._isUTC=!0,null!=i&&this.subtract(i,"m"),s!==t&&(!e||this._changeInProgress?D(this,De.duration(s-t,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,De.updateOffset(this,!0),this._changeInProgress=null)),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(t){return t=t?De(t).zone():0,(this.zone()-t)%60===0},daysInMonth:function(){return N(this.year(),this.month())},dayOfYear:function(t){var e=Oe((De(this).startOf("day")-De(this).startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},quarter:function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},weekYear:function(t){var e=pe(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==t?e:this.add(t-e,"y")},isoWeekYear:function(t){var e=pe(this,1,4).year;return null==t?e:this.add(t-e,"y")},week:function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},isoWeek:function(t){var e=pe(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},weekday:function(t){var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},isoWeekday:function(t){return null==t?this.day()||7:this.day(this.day()%7?t:t-7)},isoWeeksInYear:function(){return I(this.year(),1,4)},weeksInYear:function(){var t=this.localeData()._week;return I(this.year(),t.dow,t.doy)},get:function(t){return t=T(t),this[t]()},set:function(t,e){return t=T(t),"function"==typeof this[t]&&this[t](e),this},locale:function(t){var e;return t===n?this._locale._abbr:(e=De.localeData(t),null!=e&&(this._locale=e),this)},lang:l("moment().lang() is deprecated. Use moment().localeData() instead.",function(t){return t===n?this.localeData():this.locale(t)}),localeData:function(){return this._locale},_dateTzOffset:function(){return 15*Math.round(this._d.getTimezoneOffset()/15)}}),De.fn.millisecond=De.fn.milliseconds=be("Milliseconds",!1),De.fn.second=De.fn.seconds=be("Seconds",!1),De.fn.minute=De.fn.minutes=be("Minutes",!1),De.fn.hour=De.fn.hours=be("Hours",!0),De.fn.date=be("Date",!0),De.fn.dates=l("dates accessor is deprecated. Use date instead.",be("Date",!0)),De.fn.year=be("FullYear",!0),De.fn.years=l("years accessor is deprecated. Use year instead.",be("FullYear",!0)),De.fn.days=De.fn.day,De.fn.months=De.fn.month,De.fn.weeks=De.fn.week,De.fn.isoWeeks=De.fn.isoWeek,De.fn.quarters=De.fn.quarter,De.fn.toJSON=De.fn.toISOString,v(De.duration.fn=g.prototype,{_bubble:function(){var t,e,i,s=this._milliseconds,o=this._days,n=this._months,r=this._data,a=0;r.milliseconds=s%1e3,t=b(s/1e3),r.seconds=t%60,e=b(t/60),r.minutes=e%60,i=b(e/60),r.hours=i%24,o+=b(i/24),a=b(_e(o)),o-=b(xe(a)),n+=b(o/30),o%=30,a+=b(n/12),n%=12,r.days=o,r.months=n,r.years=a},abs:function(){return this._milliseconds=Math.abs(this._milliseconds),this._days=Math.abs(this._days),this._months=Math.abs(this._months),this._data.milliseconds=Math.abs(this._data.milliseconds),this._data.seconds=Math.abs(this._data.seconds),this._data.minutes=Math.abs(this._data.minutes),this._data.hours=Math.abs(this._data.hours),this._data.months=Math.abs(this._data.months),this._data.years=Math.abs(this._data.years),this},weeks:function(){return b(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12)},humanize:function(t){var e=ce(this,!t,this.localeData());return t&&(e=this.localeData().pastFuture(+this,e)),this.localeData().postformat(e)},add:function(t,e){var i=De.duration(t,e);return this._milliseconds+=i._milliseconds,this._days+=i._days,this._months+=i._months,this._bubble(),this},subtract:function(t,e){var i=De.duration(t,e);return this._milliseconds-=i._milliseconds,this._days-=i._days,this._months-=i._months,this._bubble(),this},get:function(t){return t=T(t),this[t.toLowerCase()+"s"]()},as:function(t){var e,i;if(t=T(t),"month"===t||"year"===t)return e=this._days+this._milliseconds/864e5,i=this._months+12*_e(e),"month"===t?i:i/12;switch(e=this._days+xe(this._months/12),t){case"week":return e/7+this._milliseconds/6048e5;case"day":return e+this._milliseconds/864e5;case"hour":return 24*e+this._milliseconds/36e5;case"minute":return 24*e*60+this._milliseconds/6e4;case"second":return 24*e*60*60+this._milliseconds/1e3;case"millisecond":return Math.floor(24*e*60*60*1e3)+this._milliseconds;default:throw new Error("Unknown unit "+t)}},lang:De.fn.lang,locale:De.fn.locale,toIsoString:l("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",function(){return this.toISOString()}),toISOString:function(){var t=Math.abs(this.years()),e=Math.abs(this.months()),i=Math.abs(this.days()),s=Math.abs(this.hours()),o=Math.abs(this.minutes()),n=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(t?t+"Y":"")+(e?e+"M":"")+(i?i+"D":"")+(s||o||n?"T":"")+(s?s+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"},localeData:function(){return this._locale}}),De.duration.fn.toString=De.duration.fn.toISOString;for(Ce in ui)a(ui,Ce)&&we(Ce.toLowerCase());De.duration.fn.asMilliseconds=function(){return this.as("ms")},De.duration.fn.asSeconds=function(){return this.as("s")},De.duration.fn.asMinutes=function(){return this.as("m")},De.duration.fn.asHours=function(){return this.as("h")},De.duration.fn.asDays=function(){return this.as("d")},De.duration.fn.asWeeks=function(){return this.as("weeks")},De.duration.fn.asMonths=function(){return this.as("M")},De.duration.fn.asYears=function(){return this.as("y")},De.locale("en",{ordinal:function(t){var e=t%10,i=1===k(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+i}}),Ye?o.exports=De:(s=function(t,e,i){return i.config&&i.config()&&i.config().noGlobal===!0&&(Te.moment=Me),De}.call(e,i,e,o),!(s!==n&&(o.exports=s)),Se(!0))}).call(this)}).call(e,function(){return this}(),i(67)(t))},function(t,e,i){var s;!function(o,n){"use strict";function r(){a.READY||(w.determineEventTypes(),x.each(a.gestures,function(t){D.register(t)}),w.onTouch(a.DOCUMENT,v,D.detect),w.onTouch(a.DOCUMENT,y,D.detect),a.READY=!0)}var a=function M(t,e){return new M.Instance(t,e||{})};a.VERSION="1.1.3",a.defaults={behavior:{userSelect:"none",touchAction:"pan-y",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},a.DOCUMENT=document,a.HAS_POINTEREVENTS=navigator.pointerEnabled||navigator.msPointerEnabled,a.HAS_TOUCHEVENTS="ontouchstart"in o,a.IS_MOBILE=/mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent),a.NO_MOUSEEVENTS=a.HAS_TOUCHEVENTS&&a.IS_MOBILE||a.HAS_POINTEREVENTS,a.CALCULATE_INTERVAL=25;var h={},d=a.DIRECTION_DOWN="down",l=a.DIRECTION_LEFT="left",c=a.DIRECTION_UP="up",p=a.DIRECTION_RIGHT="right",u=a.POINTER_MOUSE="mouse",f=a.POINTER_TOUCH="touch",m=a.POINTER_PEN="pen",g=a.EVENT_START="start",v=a.EVENT_MOVE="move",y=a.EVENT_END="end",b=a.EVENT_RELEASE="release",_=a.EVENT_TOUCH="touch";a.READY=!1,a.plugins=a.plugins||{},a.gestures=a.gestures||{};var x=a.utils={extend:function(t,e,i){for(var s in e)!e.hasOwnProperty(s)||t[s]!==n&&i||(t[s]=e[s]);return t},on:function(t,e,i){t.addEventListener(e,i,!1)},off:function(t,e,i){t.removeEventListener(e,i,!1)},each:function(t,e,i){var s,o;if("forEach"in t)t.forEach(e,i);else if(t.length!==n){for(s=0,o=t.length;o>s;s++)if(e.call(i,t[s],s,t)===!1)return}else for(s in t)if(t.hasOwnProperty(s)&&e.call(i,t[s],s,t)===!1)return},inStr:function(t,e){return t.indexOf(e)>-1},inArray:function(t,e){if(t.indexOf){var i=t.indexOf(e);return-1===i?!1:i}for(var s=0,o=t.length;o>s;s++)if(t[s]===e)return s;return!1},toArray:function(t){return Array.prototype.slice.call(t,0)},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){var e=[],i=[],s=[],o=[],n=Math.min,r=Math.max;return 1===t.length?{pageX:t[0].pageX,pageY:t[0].pageY,clientX:t[0].clientX,clientY:t[0].clientY}:(x.each(t,function(t){e.push(t.pageX),i.push(t.pageY),s.push(t.clientX),o.push(t.clientY)}),{pageX:(n.apply(Math,e)+r.apply(Math,e))/2,pageY:(n.apply(Math,i)+r.apply(Math,i))/2,clientX:(n.apply(Math,s)+r.apply(Math,s))/2,clientY:(n.apply(Math,o)+r.apply(Math,o))/2})},getVelocity:function(t,e,i){return{x:Math.abs(e/t)||0,y:Math.abs(i/t)||0}},getAngle:function(t,e){var i=e.clientX-t.clientX,s=e.clientY-t.clientY;return 180*Math.atan2(s,i)/Math.PI},getDirection:function(t,e){var i=Math.abs(t.clientX-e.clientX),s=Math.abs(t.clientY-e.clientY);return i>=s?t.clientX-e.clientX>0?l:p:t.clientY-e.clientY>0?c:d},getDistance:function(t,e){var i=e.clientX-t.clientX,s=e.clientY-t.clientY;return Math.sqrt(i*i+s*s)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(t){return t==c||t==d},setPrefixedCss:function(t,e,i,s){var o=["","Webkit","Moz","O","ms"];e=x.toCamelCase(e);for(var n=0;n0&&this.started&&(r=v),this.started=!0;var d=this.collectEventData(i,r,o,t);return e!=y&&s.call(D,d),a&&(d.changedLength=h,d.eventType=a,s.call(D,d),d.eventType=r,delete d.changedLength),r==y&&(s.call(D,d),this.started=!1),r},determineEventTypes:function(){var t;return t=a.HAS_POINTEREVENTS?o.PointerEvent?["pointerdown","pointermove","pointerup pointercancel lostpointercapture"]:["MSPointerDown","MSPointerMove","MSPointerUp MSPointerCancel MSLostPointerCapture"]:a.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],h[g]=t[0],h[v]=t[1],h[y]=t[2],h},getTouchList:function(t,e){if(a.HAS_POINTEREVENTS)return S.getTouchList();if(t.touches){if(e==v)return t.touches;var i=[],s=[].concat(x.toArray(t.touches),x.toArray(t.changedTouches)),o=[];return x.each(s,function(t){x.inArray(i,t.identifier)===!1&&o.push(t),i.push(t.identifier)}),o}return t.identifier=1,[t]},collectEventData:function(t,e,i,s){var o=f;return x.inStr(s.type,"mouse")||S.matchType(u,s)?o=u:S.matchType(m,s)&&(o=m),{center:x.getCenter(i),timeStamp:Date.now(),target:s.target,touches:i,eventType:e,pointerType:o,srcEvent:s,preventDefault:function(){var t=this.srcEvent;t.preventManipulation&&t.preventManipulation(),t.preventDefault&&t.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return D.stopDetect()}}}},S=a.PointerEvent={pointers:{},getTouchList:function(){var t=[];return x.each(this.pointers,function(e){t.push(e)}),t},updatePointer:function(t,e){t==y||t!=y&&1!==e.buttons?delete this.pointers[e.pointerId]:(e.identifier=e.pointerId,this.pointers[e.pointerId]=e)},matchType:function(t,e){if(!e.pointerType)return!1;var i=e.pointerType,s={};return s[u]=i===(e.MSPOINTER_TYPE_MOUSE||u),s[f]=i===(e.MSPOINTER_TYPE_TOUCH||f),s[m]=i===(e.MSPOINTER_TYPE_PEN||m),s[t]},reset:function(){this.pointers={}}},D=a.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(t,e){this.current||(this.stopped=!1,this.current={inst:t,startEvent:x.extend({},e),lastEvent:!1,lastCalcEvent:!1,futureCalcEvent:!1,lastCalcData:{},name:""},this.detect(e))},detect:function(t){if(this.current&&!this.stopped){t=this.extendEventData(t);var e=this.current.inst,i=e.options;return x.each(this.gestures,function(s){!this.stopped&&e.enabled&&i[s.name]&&s.handler.call(s,t,e)},this),this.current&&(this.current.lastEvent=t),t.eventType==y&&this.stopDetect(),t}},stopDetect:function(){this.previous=x.extend({},this.current),this.current=null,this.stopped=!0},getCalculatedData:function(t,e,i,s,o){var n=this.current,r=!1,h=n.lastCalcEvent,d=n.lastCalcData;h&&t.timeStamp-h.timeStamp>a.CALCULATE_INTERVAL&&(e=h.center,i=t.timeStamp-h.timeStamp,s=t.center.clientX-h.center.clientX,o=t.center.clientY-h.center.clientY,r=!0),(t.eventType==_||t.eventType==b)&&(n.futureCalcEvent=t),(!n.lastCalcEvent||r)&&(d.velocity=x.getVelocity(i,s,o),d.angle=x.getAngle(e,t.center),d.direction=x.getDirection(e,t.center),n.lastCalcEvent=n.futureCalcEvent||t,n.futureCalcEvent=t),t.velocityX=d.velocity.x,t.velocityY=d.velocity.y,t.interimAngle=d.angle,t.interimDirection=d.direction},extendEventData:function(t){var e=this.current,i=e.startEvent,s=e.lastEvent||i;(t.eventType==_||t.eventType==b)&&(i.touches=[],x.each(t.touches,function(t){i.touches.push({clientX:t.clientX,clientY:t.clientY})}));var o=t.timeStamp-i.timeStamp,n=t.center.clientX-i.center.clientX,r=t.center.clientY-i.center.clientY;return this.getCalculatedData(t,s.center,o,n,r),x.extend(t,{startEvent:i,deltaTime:o,deltaX:n,deltaY:r,distance:x.getDistance(i.center,t.center),angle:x.getAngle(i.center,t.center),direction:x.getDirection(i.center,t.center),scale:x.getScale(i.touches,t.touches),rotation:x.getRotation(i.touches,t.touches)}),t},register:function(t){var e=t.defaults||{};return e[t.name]===n&&(e[t.name]=!0),x.extend(a.defaults,e,!0),t.index=t.index||1e3,this.gestures.push(t),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}};a.Instance=function(t,e){var i=this;r(),this.element=t,this.enabled=!0,x.each(e,function(t,i){delete e[i],e[x.toCamelCase(i)]=t}),this.options=x.extend(x.extend({},a.defaults),e||{}),this.options.behavior&&x.toggleBehavior(this.element,this.options.behavior,!0),this.eventStartHandler=w.onTouch(t,g,function(t){i.enabled&&t.eventType==g?D.startDetect(i,t):t.eventType==_&&D.detect(t)}),this.eventHandlers=[]},a.Instance.prototype={on:function(t,e){var i=this;return w.on(i.element,t,e,function(t){i.eventHandlers.push({gesture:t,handler:e})}),i},off:function(t,e){var i=this;return w.off(i.element,t,e,function(t){var s=x.inArray({gesture:t,handler:e});s!==!1&&i.eventHandlers.splice(s,1)}),i},trigger:function(t,e){e||(e={});var i=a.DOCUMENT.createEvent("Event");i.initEvent(t,!0,!0),i.gesture=e;var s=this.element;return x.hasParent(e.target,s)&&(s=e.target),s.dispatchEvent(i),this},enable:function(t){return this.enabled=t,this},dispose:function(){var t,e;for(x.toggleBehavior(this.element,this.options.behavior,!1),t=-1;e=this.eventHandlers[++t];)x.off(this.element,e.gesture,e.handler);return this.eventHandlers=[],w.off(this.element,h[g],this.eventStartHandler),null}},function(t){function e(e,s){var o=D.current;if(!(s.options.dragMaxTouches>0&&e.touches.length>s.options.dragMaxTouches))switch(e.eventType){case g:i=!1;break;case v:if(e.distance0)){var r=Math.abs(s.options.dragMinDistance/e.distance);n.pageX+=e.deltaX*r,n.pageY+=e.deltaY*r,n.clientX+=e.deltaX*r,n.clientY+=e.deltaY*r,e=D.extendEventData(e)}(o.lastEvent.dragLockToAxis||s.options.dragLockToAxis&&s.options.dragLockMinDistance<=e.distance)&&(e.dragLockToAxis=!0);var a=o.lastEvent.direction;e.dragLockToAxis&&a!==e.direction&&(e.direction=x.isVertical(a)?e.deltaY<0?c:d:e.deltaX<0?l:p),i||(s.trigger(t+"start",e),i=!0),s.trigger(t,e),s.trigger(t+e.direction,e);var h=x.isVertical(e.direction);(s.options.dragBlockVertical&&h||s.options.dragBlockHorizontal&&!h)&&e.preventDefault();break;case b:i&&e.changedLength<=s.options.dragMaxTouches&&(s.trigger(t+"end",e),i=!1);break;case y:i=!1}}var i=!1;a.gestures.Drag={name:t,index:50,handler:e,defaults:{dragMinDistance:10,dragDistanceCorrection:!0,dragMaxTouches:1,dragBlockHorizontal:!1,dragBlockVertical:!1,dragLockToAxis:!1,dragLockMinDistance:25}}}("drag"),a.gestures.Gesture={name:"gesture",index:1337,handler:function(t,e){e.trigger(this.name,t)}},function(t){function e(e,s){var o=s.options,n=D.current;switch(e.eventType){case g:clearTimeout(i),n.name=t,i=setTimeout(function(){n&&n.name==t&&s.trigger(t,e)},o.holdTimeout);break;case v:e.distance>o.holdThreshold&&clearTimeout(i);break;case b:clearTimeout(i)}}var i;a.gestures.Hold={name:t,index:10,defaults:{holdTimeout:500,holdThreshold:2},handler:e}}("hold"),a.gestures.Release={name:"release",index:1/0,handler:function(t,e){t.eventType==b&&e.trigger(this.name,t)}},a.gestures.Swipe={name:"swipe",index:40,defaults:{swipeMinTouches:1,swipeMaxTouches:1,swipeVelocityX:.6,swipeVelocityY:.6},handler:function(t,e){if(t.eventType==b){var i=t.touches.length,s=e.options;if(is.swipeMaxTouches)return;(t.velocityX>s.swipeVelocityX||t.velocityY>s.swipeVelocityY)&&(e.trigger(this.name,t),e.trigger(this.name+t.direction,t))}}},function(t){function e(e,s){var o,n,r=s.options,a=D.current,h=D.previous;switch(e.eventType){case g:i=!1;break;case v:i=i||e.distance>r.tapMaxDistance;break;case y:!x.inStr(e.srcEvent.type,"cancel")&&e.deltaTimes.options.transformMinRotation&&s.trigger("rotate",e),o>s.options.transformMinScale&&(s.trigger("pinch",e),s.trigger("pinch"+(e.scale<1?"in":"out"),e));break;case b:i&&e.changedLength<2&&(s.trigger(t+"end",e),i=!1)}}var i=!1;a.gestures.Transform={name:t,index:45,defaults:{transformMinScale:.01,transformMinRotation:1},handler:e}}("transform"),s=function(){return a}.call(e,i,e,t),!(s!==n&&(t.exports=s))}(window)},function(t){function e(t,e,i){return t.addEventListener?t.addEventListener(e,i,!1):void t.attachEvent("on"+e,i)}function i(t){return"keypress"==t.type?String.fromCharCode(t.which):_[t.which]?_[t.which]:x[t.which]?x[t.which]:String.fromCharCode(t.which).toLowerCase()}function s(t){var e=t.target||t.srcElement,i=e.tagName;return(" "+e.className+" ").indexOf(" mousetrap ")>-1?!1:"INPUT"==i||"SELECT"==i||"TEXTAREA"==i||e.contentEditable&&"true"==e.contentEditable}function o(t,e){return t.sort().join(",")===e.sort().join(",")}function n(t){t=t||{};var e,i=!1;for(e in C)t[e]?i=!0:C[e]=0;i||(T=!1)}function r(t,e,i,s,n){var r,a,h=[];if(!D[t])return[];for("keyup"==i&&c(t)&&(e=[t]),r=0;r95&&112>t||_.hasOwnProperty(t)&&(y[_[t]]=t)}return y}function f(t,e,i){return i||(i=u()[t]?"keydown":"keypress"),"keypress"==i&&e.length&&(i="keydown"),i}function m(t,e,s,o){C[t]=0,o||(o=f(e[0],[]));var r,a=function(){T=o,++C[t],p()},d=function(t){h(s,t),"keyup"!==o&&(E=i(t)),setTimeout(n,10)};for(r=0;r1)return m(t,d,e,i);for(h="+"===t?["+"]:t.split("+"),n=0;n":".","?":"/","|":"\\"},S={option:"alt",command:"meta","return":"enter",escape:"esc"},D={},M={},C={},E=!1,T=!1,O=1;20>O;++O)_[111+O]="f"+O;for(O=0;9>=O;++O)_[O+96]=O;e(document,"keypress",l),e(document,"keydown",l),e(document,"keyup",l);var L={bind:function(t,e,i){return v(t instanceof Array?t:[t],e,i),M[t+":"+i]=e,this},unbind:function(t,e){return M[t+":"+e]&&(delete M[t+":"+e],this.bind(t,function(){},e)),this},trigger:function(t,e){return M[t+":"+e](),this},reset:function(){return D={},M={},this}};t.exports=L},function(t,e){e.startWithClustering=function(){this.clusterToFit(this.constants.clustering.initialMaxNodes,!0),this.updateLabels(),this.stabilize&&this._stabilize(),this.start()},e.clusterToFit=function(t,e){for(var i=this.nodeIndices.length,s=50,o=0;i>t&&s>o;)o%3==0?(this.forceAggregateHubs(!0),this.normalizeClusterLevels()):this.increaseClusterLevel(),i=this.nodeIndices.length,o+=1;o>0&&1==e&&this.repositionNodes(),this._updateCalculationNodes()},e.openCluster=function(t){var e=this.moving;if(t.clusterSize>this.constants.clustering.sectorThreshold&&this._nodeInActiveArea(t)&&("default"!=this._sector()||1!=this.nodeIndices.length)){this._addSector(t);for(var i=0;this.nodeIndices.lengthi;)this.decreaseClusterLevel(),i+=1}else this._expandClusterNode(t,!1,!0),this._updateNodeIndexList(),this._updateDynamicEdges(),this._updateCalculationNodes(),this.updateLabels();this.moving!=e&&this.start()},e.updateClustersDefault=function(){1==this.constants.clustering.enabled&&this.updateClusters(0,!1,!1)},e.increaseClusterLevel=function(){this.updateClusters(-1,!1,!0)},e.decreaseClusterLevel=function(){this.updateClusters(1,!1,!0)},e.updateClusters=function(t,e,i,s){var o=this.moving,n=this.nodeIndices.length;this.previousScale>this.scale&&0==t&&this._collapseSector(),this.previousScale>this.scale||-1==t?this._formClusters(i):(this.previousScalethis.scale||-1==t)&&(this._aggregateHubs(i),this._updateNodeIndexList()),(this.previousScale>this.scale||-1==t)&&(this.handleChains(),this._updateNodeIndexList()),this.previousScale=this.scale,this._updateDynamicEdges(),this.updateLabels(),this.nodeIndices.lengththis.constants.clustering.chainThreshold&&this._reduceAmountOfChains(1-this.constants.clustering.chainThreshold/t)},e._aggregateHubs=function(t){this._getHubSize(),this._formClustersByHub(t,!1)},e.forceAggregateHubs=function(t){var e=this.moving,i=this.nodeIndices.length;this._aggregateHubs(!0),this._updateNodeIndexList(),this._updateDynamicEdges(),this.updateLabels(),this.nodeIndices.length!=i&&(this.clusterSession+=1),(0==t||void 0===t)&&this.moving!=e&&this.start()},e._openClustersBySize=function(){for(var t in this.nodes)if(this.nodes.hasOwnProperty(t)){var e=this.nodes[t];1==e.inView()&&(e.width*this.scale>this.constants.clustering.screenSizeThreshold*this.frame.canvas.clientWidth||e.height*this.scale>this.constants.clustering.screenSizeThreshold*this.frame.canvas.clientHeight)&&this.openCluster(e)}},e._openClusters=function(t,e){for(var i=0;i1&&(t.clusterSizei)){var r=n.from,a=n.to;n.to.options.mass>n.from.options.mass&&(r=n.to,a=n.from),1==a.dynamicEdgesLength?this._addToCluster(r,a,!1):1==r.dynamicEdgesLength&&this._addToCluster(a,r,!1)}}},e._forceClustersByZoom=function(){for(var t in this.nodes)if(this.nodes.hasOwnProperty(t)){var e=this.nodes[t];if(1==e.dynamicEdgesLength&&0!=e.dynamicEdges.length){var i=e.dynamicEdges[0],s=i.toId==e.id?this.nodes[i.fromId]:this.nodes[i.toId];e.id!=s.id&&(s.options.mass>e.options.mass?this._addToCluster(s,e,!0):this._addToCluster(e,s,!0))}}},e._clusterToSmallestNeighbour=function(t){for(var e=-1,i=null,s=0;so.clusterSessions.length&&(e=o.clusterSessions.length,i=o)}null!=o&&void 0!==this.nodes[o.id]&&this._addToCluster(o,t,!0)},e._formClustersByHub=function(t,e){for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&this._formClusterFromHub(this.nodes[i],t,e)},e._formClusterFromHub=function(t,e,i,s){if(void 0===s&&(s=0),t.dynamicEdgesLength>=this.hubThreshold&&0==i||t.dynamicEdgesLength==this.hubThreshold&&1==i){for(var o,n,r,a=this.constants.clustering.clusterEdgeThreshold/this.scale,h=!1,d=[],l=t.dynamicEdges.length,c=0;l>c;c++)d.push(t.dynamicEdges[c].id);if(0==e)for(h=!1,c=0;l>c;c++){var p=this.edges[d[c]];if(void 0!==p&&p.connected&&p.toId!=p.fromId&&(o=p.to.x-p.from.x,n=p.to.y-p.from.y,r=Math.sqrt(o*o+n*n),a>r)){h=!0;break}}if(!e&&h||e)for(c=0;l>c;c++)if(p=this.edges[d[c]],void 0!==p){var u=this.nodes[p.fromId==t.id?p.toId:p.fromId];u.dynamicEdges.length<=this.hubThreshold+s&&u.id!=t.id&&this._addToCluster(t,u,e)}}},e._addToCluster=function(t,e,i){t.containedNodes[e.id]=e;for(var s=0;s1)for(var s=0;s1&&(e.label="[".concat(String(e.clusterSize),"]"))}for(t in this.nodes)this.nodes.hasOwnProperty(t)&&(e=this.nodes[t],1==e.clusterSize&&(e.label=void 0!==e.originalLabel?e.originalLabel:String(e.id)))},e.normalizeClusterLevels=function(){var t,e=0,i=1e9,s=0;for(t in this.nodes)this.nodes.hasOwnProperty(t)&&(s=this.nodes[t].clusterSessions.length,s>e&&(e=s),i>s&&(i=s));if(e-i>this.constants.clustering.clusterLevelDifference){var o=this.nodeIndices.length,n=e-this.constants.clustering.clusterLevelDifference;for(t in this.nodes)this.nodes.hasOwnProperty(t)&&this.nodes[t].clusterSessions.lengths&&(s=n.dynamicEdgesLength),t+=n.dynamicEdgesLength,e+=Math.pow(n.dynamicEdgesLength,2),i+=1}t/=i,e/=i;var r=e-Math.pow(t,2),a=Math.sqrt(r);this.hubThreshold=Math.floor(t+2*a),this.hubThreshold>s&&(this.hubThreshold=s)},e._reduceAmountOfChains=function(t){this.hubThreshold=2;var e=Math.floor(this.nodeIndices.length*t);for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&2==this.nodes[i].dynamicEdgesLength&&this.nodes[i].dynamicEdges.length>=2&&e>0&&(this._formClusterFromHub(this.nodes[i],!0,!0,1),e-=1)},e._getChainFraction=function(){var t=0,e=0;for(var i in this.nodes)this.nodes.hasOwnProperty(i)&&(2==this.nodes[i].dynamicEdgesLength&&this.nodes[i].dynamicEdges.length>=2&&(t+=1),e+=1);return t/e}},function(t,e,i){var s=i(1),o=i(39);e._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},e._switchToSector=function(t,e){void 0===e||"active"==e?this._switchToActiveSector(t):this._switchToFrozenSector(t)},e._switchToActiveSector=function(t){this.nodeIndices=this.sectors.active[t].nodeIndices,this.nodes=this.sectors.active[t].nodes,this.edges=this.sectors.active[t].edges},e._switchToSupportSector=function(){this.nodeIndices=this.sectors.support.nodeIndices,this.nodes=this.sectors.support.nodes,this.edges=this.sectors.support.edges},e._switchToFrozenSector=function(t){this.nodeIndices=this.sectors.frozen[t].nodeIndices,this.nodes=this.sectors.frozen[t].nodes,this.edges=this.sectors.frozen[t].edges},e._loadLatestSector=function(){this._switchToSector(this._sector())},e._sector=function(){return this.activeSector[this.activeSector.length-1]},e._previousSector=function(){if(this.activeSector.length>1)return this.activeSector[this.activeSector.length-2];throw new TypeError("there are not enough sectors in the this.activeSector array.")},e._setActiveSector=function(t){this.activeSector.push(t)},e._forgetLastSector=function(){this.activeSector.pop()},e._createNewSector=function(t){this.sectors.active[t]={nodes:{},edges:{},nodeIndices:[],formationScale:this.scale,drawingNode:void 0},this.sectors.active[t].drawingNode=new o({id:t,color:{background:"#eaefef",border:"495c5e"}},{},{},this.constants),this.sectors.active[t].drawingNode.clusterSize=2},e._deleteActiveSector=function(t){delete this.sectors.active[t]},e._deleteFrozenSector=function(t){delete this.sectors.frozen[t]},e._freezeSector=function(t){this.sectors.frozen[t]=this.sectors.active[t],this._deleteActiveSector(t)},e._activateSector=function(t){this.sectors.active[t]=this.sectors.frozen[t],this._deleteFrozenSector(t)},e._mergeThisWithFrozen=function(t){for(var e in this.nodes)this.nodes.hasOwnProperty(e)&&(this.sectors.frozen[t].nodes[e]=this.nodes[e]);for(var i in this.edges)this.edges.hasOwnProperty(i)&&(this.sectors.frozen[t].edges[i]=this.edges[i]);for(var s=0;s1?this[t](o[0],o[1]):this[t](e))}return this._loadLatestSector(),i},e._doInSupportSector=function(t,e){var i=!1;if(void 0===e)this._switchToSupportSector(),i=this[t]();else{this._switchToSupportSector();var s=Array.prototype.splice.call(arguments,1);i=s.length>1?this[t](s[0],s[1]):this[t](e)}return this._loadLatestSector(),i},e._doInAllFrozenSectors=function(t,e){if(void 0===e)for(var i in this.sectors.frozen)this.sectors.frozen.hasOwnProperty(i)&&(this._switchToFrozenSector(i),this[t]());else for(var i in this.sectors.frozen)if(this.sectors.frozen.hasOwnProperty(i)){this._switchToFrozenSector(i);var s=Array.prototype.splice.call(arguments,1);s.length>1?this[t](s[0],s[1]):this[t](e)}this._loadLatestSector()},e._doInAllSectors=function(t,e){var i=Array.prototype.splice.call(arguments,1);void 0===e?(this._doInAllActiveSectors(t),this._doInAllFrozenSectors(t)):i.length>1?(this._doInAllActiveSectors(t,i[0],i[1]),this._doInAllFrozenSectors(t,i[0],i[1])):(this._doInAllActiveSectors(t,e),this._doInAllFrozenSectors(t,e))},e._clearNodeIndexList=function(){var t=this._sector();this.sectors.active[t].nodeIndices=[],this.nodeIndices=this.sectors.active[t].nodeIndices},e._drawSectorNodes=function(t,e){var i,s=1e9,o=-1e9,n=1e9,r=-1e9;for(var a in this.sectors[e])if(this.sectors[e].hasOwnProperty(a)&&void 0!==this.sectors[e][a].drawingNode){this._switchToSector(a,e),s=1e9,o=-1e9,n=1e9,r=-1e9;for(var h in this.nodes)this.nodes.hasOwnProperty(h)&&(i=this.nodes[h],i.resize(t),n>i.x-.5*i.width&&(n=i.x-.5*i.width),ri.y-.5*i.height&&(s=i.y-.5*i.height),o0?this.nodes[i[i.length-1]]:null},e._getEdgesOverlappingWith=function(t,e){var i=this.edges;for(var s in i)i.hasOwnProperty(s)&&i[s].isOverlappingWith(t)&&e.push(s)},e._getAllEdgesOverlappingWith=function(t){var e=[];return this._doInAllActiveSectors("_getEdgesOverlappingWith",t,e),e},e._getEdgeAt=function(t){var e=this._pointerToPositionObject(t),i=this._getAllEdgesOverlappingWith(e);return i.length>0?this.edges[i[i.length-1]]:null},e._addToSelection=function(t){t instanceof s?this.selectionObj.nodes[t.id]=t:this.selectionObj.edges[t.id]=t +},e._addToHover=function(t){t instanceof s?this.hoverObj.nodes[t.id]=t:this.hoverObj.edges[t.id]=t},e._removeFromSelection=function(t){t instanceof s?delete this.selectionObj.nodes[t.id]:delete this.selectionObj.edges[t.id]},e._unselectAll=function(t){void 0===t&&(t=!1);for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&this.selectionObj.nodes[e].unselect();for(var i in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(i)&&this.selectionObj.edges[i].unselect();this.selectionObj={nodes:{},edges:{}},0==t&&this.emit("select",this.getSelection())},e._unselectClusters=function(t){void 0===t&&(t=!1);for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&this.selectionObj.nodes[e].clusterSize>1&&(this.selectionObj.nodes[e].unselect(),this._removeFromSelection(this.selectionObj.nodes[e]));0==t&&this.emit("select",this.getSelection())},e._getSelectedNodeCount=function(){var t=0;for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&(t+=1);return t},e._getSelectedNode=function(){for(var t in this.selectionObj.nodes)if(this.selectionObj.nodes.hasOwnProperty(t))return this.selectionObj.nodes[t];return null},e._getSelectedEdge=function(){for(var t in this.selectionObj.edges)if(this.selectionObj.edges.hasOwnProperty(t))return this.selectionObj.edges[t];return null},e._getSelectedEdgeCount=function(){var t=0;for(var e in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(e)&&(t+=1);return t},e._getSelectedObjectCount=function(){var t=0;for(var e in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(e)&&(t+=1);for(var i in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(i)&&(t+=1);return t},e._selectionIsEmpty=function(){for(var t in this.selectionObj.nodes)if(this.selectionObj.nodes.hasOwnProperty(t))return!1;for(var e in this.selectionObj.edges)if(this.selectionObj.edges.hasOwnProperty(e))return!1;return!0},e._clusterInSelection=function(){for(var t in this.selectionObj.nodes)if(this.selectionObj.nodes.hasOwnProperty(t)&&this.selectionObj.nodes[t].clusterSize>1)return!0;return!1},e._selectConnectedEdges=function(t){for(var e=0;ei;i++){o=t[i];var n=this.nodes[o];if(!n)throw new RangeError('Node with id "'+o+'" not found');this._selectObject(n,!0,!0,e,!0)}this.redraw()},e.selectEdges=function(t){var e,i,s;if(!t||void 0==t.length)throw"Selection must be an array with ids";for(this._unselectAll(!0),e=0,i=t.length;i>e;e++){s=t[e];var o=this.edges[s];if(!o)throw new RangeError('Edge with id "'+s+'" not found');this._selectObject(o,!0,!0,!1,!0)}this.redraw()},e._updateSelection=function(){for(var t in this.selectionObj.nodes)this.selectionObj.nodes.hasOwnProperty(t)&&(this.nodes.hasOwnProperty(t)||delete this.selectionObj.nodes[t]);for(var e in this.selectionObj.edges)this.selectionObj.edges.hasOwnProperty(e)&&(this.edges.hasOwnProperty(e)||delete this.selectionObj.edges[e])}},function(t,e,i){var s=i(1),o=i(39),n=i(36);e._clearManipulatorBar=function(){for(;this.manipulationDiv.hasChildNodes();)this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);this._manipulationReleaseOverload=function(){},delete this.sectors.support.nodes.targetNode,delete this.sectors.support.nodes.targetViaNode,this.controlNodesActive=!1},e._restoreOverloadedFunctions=function(){for(var t in this.cachedFunctions)this.cachedFunctions.hasOwnProperty(t)&&(this[t]=this.cachedFunctions[t])},e._toggleEditMode=function(){this.editMode=!this.editMode;var t=document.getElementById("network-manipulationDiv"),e=document.getElementById("network-manipulation-closeDiv"),i=document.getElementById("network-manipulation-editMode");1==this.editMode?(t.style.display="block",e.style.display="block",i.style.display="none",e.onclick=this._toggleEditMode.bind(this)):(t.style.display="none",e.style.display="none",i.style.display="block",e.onclick=null),this._createManipulatorBar()},e._createManipulatorBar=function(){this.boundFunction&&this.off("select",this.boundFunction);var t=this.constants.locales[this.constants.locale];if(void 0!==this.edgeBeingEdited&&(this.edgeBeingEdited._disableControlNodes(),this.edgeBeingEdited=void 0,this.selectedControlNode=null,this.controlNodesActive=!1),this._restoreOverloadedFunctions(),this.freezeSimulation=!1,this.blockConnectingEdgeSelection=!1,this.forceAppendSelection=!1,1==this.editMode){for(;this.manipulationDiv.hasChildNodes();)this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);this.manipulationDiv.innerHTML=""+t.addNode+"
"+t.addEdge+"",1==this._getSelectedNodeCount()&&this.triggerFunctions.edit?this.manipulationDiv.innerHTML+="
"+t.editNode+"":1==this._getSelectedEdgeCount()&&0==this._getSelectedNodeCount()&&(this.manipulationDiv.innerHTML+="
"+t.editEdge+""),0==this._selectionIsEmpty()&&(this.manipulationDiv.innerHTML+="
"+t.del+"");var e=document.getElementById("network-manipulate-addNode");e.onclick=this._createAddNodeToolbar.bind(this);var i=document.getElementById("network-manipulate-connectNode");if(i.onclick=this._createAddEdgeToolbar.bind(this),1==this._getSelectedNodeCount()&&this.triggerFunctions.edit){var s=document.getElementById("network-manipulate-editNode");s.onclick=this._editNode.bind(this)}else if(1==this._getSelectedEdgeCount()&&0==this._getSelectedNodeCount()){var s=document.getElementById("network-manipulate-editEdge");s.onclick=this._createEditEdgeToolbar.bind(this)}if(0==this._selectionIsEmpty()){var o=document.getElementById("network-manipulate-delete");o.onclick=this._deleteSelected.bind(this)}var n=document.getElementById("network-manipulation-closeDiv");n.onclick=this._toggleEditMode.bind(this),this.boundFunction=this._createManipulatorBar.bind(this),this.on("select",this.boundFunction)}else{this.editModeDiv.innerHTML=""+t.edit+"";var r=document.getElementById("network-manipulate-editModeButton");r.onclick=this._toggleEditMode.bind(this)}},e._createAddNodeToolbar=function(){this._clearManipulatorBar(),this.boundFunction&&this.off("select",this.boundFunction);var t=this.constants.locales[this.constants.locale];this.manipulationDiv.innerHTML=""+t.back+"
"+t.addDescription+"";var e=document.getElementById("network-manipulate-back");e.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._addNode.bind(this),this.on("select",this.boundFunction)},e._createAddEdgeToolbar=function(){this._clearManipulatorBar(),this._unselectAll(!0),this.freezeSimulation=!0;var t=this.constants.locales[this.constants.locale];this.boundFunction&&this.off("select",this.boundFunction),this._unselectAll(),this.forceAppendSelection=!1,this.blockConnectingEdgeSelection=!0,this.manipulationDiv.innerHTML=""+t.back+"
"+t.edgeDescription+"";var e=document.getElementById("network-manipulate-back");e.onclick=this._createManipulatorBar.bind(this),this.boundFunction=this._handleConnect.bind(this),this.on("select",this.boundFunction),this.cachedFunctions._handleTouch=this._handleTouch,this.cachedFunctions._manipulationReleaseOverload=this._manipulationReleaseOverload,this.cachedFunctions._handleDragStart=this._handleDragStart,this.cachedFunctions._handleDragEnd=this._handleDragEnd,this._handleTouch=this._handleConnect,this._manipulationReleaseOverload=function(){},this._handleDragStart=function(){},this._handleDragEnd=this._finishConnect,this._redraw()},e._createEditEdgeToolbar=function(){this._clearManipulatorBar(),this.controlNodesActive=!0,this.boundFunction&&this.off("select",this.boundFunction),this.edgeBeingEdited=this._getSelectedEdge(),this.edgeBeingEdited._enableControlNodes();var t=this.constants.locales[this.constants.locale];this.manipulationDiv.innerHTML=""+t.back+"
"+t.editEdgeDescription+"";var e=document.getElementById("network-manipulate-back");e.onclick=this._createManipulatorBar.bind(this),this.cachedFunctions._handleTouch=this._handleTouch,this.cachedFunctions._manipulationReleaseOverload=this._manipulationReleaseOverload,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._manipulationReleaseOverload=this._releaseControlNode,this._redraw()},e._selectControlNode=function(t){this.edgeBeingEdited.controlNodes.from.unselect(),this.edgeBeingEdited.controlNodes.to.unselect(),this.selectedControlNode=this.edgeBeingEdited._getSelectedControlNode(this._XconvertDOMtoCanvas(t.x),this._YconvertDOMtoCanvas(t.y)),null!==this.selectedControlNode&&(this.selectedControlNode.select(),this.freezeSimulation=!0),this._redraw()},e._controlNodeDrag=function(t){var e=this._getPointer(t.gesture.center);null!==this.selectedControlNode&&void 0!==this.selectedControlNode&&(this.selectedControlNode.x=this._XconvertDOMtoCanvas(e.x),this.selectedControlNode.y=this._YconvertDOMtoCanvas(e.y)),this._redraw()},e._releaseControlNode=function(t){var e=this._getNodeAt(t);null!=e?(1==this.edgeBeingEdited.controlNodes.from.selected&&(this._editEdge(e.id,this.edgeBeingEdited.to.id),this.edgeBeingEdited.controlNodes.from.unselect()),1==this.edgeBeingEdited.controlNodes.to.selected&&(this._editEdge(this.edgeBeingEdited.from.id,e.id),this.edgeBeingEdited.controlNodes.to.unselect())):this.edgeBeingEdited._restoreControlNodes(),this.freezeSimulation=!1,this._redraw()},e._handleConnect=function(t){if(0==this._getSelectedNodeCount()){var e=this._getNodeAt(t);if(null!=e)if(e.clusterSize>1)alert(this.constants.locales[this.constants.locale].createEdgeError);else{this._selectObject(e,!1);var i=this.sectors.support.nodes;i.targetNode=new o({id:"targetNode"},{},{},this.constants);var s=i.targetNode;s.x=e.x,s.y=e.y,this.edges.connectionEdge=new n({id:"connectionEdge",from:e.id,to:s.id},this,this.constants);var r=this.edges.connectionEdge;r.from=e,r.connected=!0,r.options.smoothCurves={enabled:!0,dynamic:!1,type:"continuous",roundness:.5},r.selected=!0,r.to=s,this.cachedFunctions._handleOnDrag=this._handleOnDrag,this._handleOnDrag=function(t){var e=this._getPointer(t.gesture.center),i=this.edges.connectionEdge;i.to.x=this._XconvertDOMtoCanvas(e.x),i.to.y=this._YconvertDOMtoCanvas(e.y)},this.moving=!0,this.start()}}},e._finishConnect=function(t){if(1==this._getSelectedNodeCount()){var e=this._getPointer(t.gesture.center);this._handleOnDrag=this.cachedFunctions._handleOnDrag,delete this.cachedFunctions._handleOnDrag;var i=this.edges.connectionEdge.fromId;delete this.edges.connectionEdge,delete this.sectors.support.nodes.targetNode,delete this.sectors.support.nodes.targetViaNode;var s=this._getNodeAt(e);null!=s&&(s.clusterSize>1?alert(this.constants.locales[this.constants.locale].createEdgeError):(this._createEdge(i,s.id),this._createManipulatorBar())),this._unselectAll()}},e._addNode=function(){if(this._selectionIsEmpty()&&1==this.editMode){var t=this._pointerToPositionObject(this.pointerPosition),e={id:s.randomUUID(),x:t.left,y:t.top,label:"new",allowedToMoveX:!0,allowedToMoveY:!0};if(this.triggerFunctions.add){if(2!=this.triggerFunctions.add.length)throw new Error("The function for add does not support two arguments (data,callback)");var i=this;this.triggerFunctions.add(e,function(t){i.nodesData.add(t),i._createManipulatorBar(),i.moving=!0,i.start()})}else this.nodesData.add(e),this._createManipulatorBar(),this.moving=!0,this.start()}},e._createEdge=function(t,e){if(1==this.editMode){var i={from:t,to:e};if(this.triggerFunctions.connect){if(2!=this.triggerFunctions.connect.length)throw new Error("The function for connect does not support two arguments (data,callback)");var s=this;this.triggerFunctions.connect(i,function(t){s.edgesData.add(t),s.moving=!0,s.start()})}else this.edgesData.add(i),this.moving=!0,this.start()}},e._editEdge=function(t,e){if(1==this.editMode){var i={id:this.edgeBeingEdited.id,from:t,to:e};if(this.triggerFunctions.editEdge){if(2!=this.triggerFunctions.editEdge.length)throw new Error("The function for edit does not support two arguments (data, callback)");var s=this;this.triggerFunctions.editEdge(i,function(t){s.edgesData.update(t),s.moving=!0,s.start()})}else this.edgesData.update(i),this.moving=!0,this.start()}},e._editNode=function(){if(!this.triggerFunctions.edit||1!=this.editMode)throw new Error("No edit function has been bound to this button");var t=this._getSelectedNode(),e={id:t.id,label:t.label,group:t.options.group,shape:t.options.shape,color:{background:t.options.color.background,border:t.options.color.border,highlight:{background:t.options.color.highlight.background,border:t.options.color.highlight.border}}};if(2!=this.triggerFunctions.edit.length)throw new Error("The function for edit does not support two arguments (data, callback)");var i=this;this.triggerFunctions.edit(e,function(t){i.nodesData.update(t),i._createManipulatorBar(),i.moving=!0,i.start()})},e._deleteSelected=function(){if(!this._selectionIsEmpty()&&1==this.editMode)if(this._clusterInSelection())alert(this.constants.locales[this.constants.locale].deleteClusterError);else{var t=this.getSelectedNodes(),e=this.getSelectedEdges();if(this.triggerFunctions.del){var i=this,s={nodes:t,edges:e};if(!(this.triggerFunctions.del.length=2))throw new Error("The function for delete does not support two arguments (data, callback)");this.triggerFunctions.del(s,function(t){i.edgesData.remove(t.edges),i.nodesData.remove(t.nodes),i._unselectAll(),i.moving=!0,i.start()})}else this.edgesData.remove(e),this.nodesData.remove(t),this._unselectAll(),this.moving=!0,this.start()}}},function(t,e,i){var s=(i(1),i(44));e._cleanNavigation=function(){if(0!=this.navigationHammers.existing.length){for(var t=0;t0){"RL"==this.constants.hierarchicalLayout.direction||"DU"==this.constants.hierarchicalLayout.direction?this.constants.hierarchicalLayout.levelSeparation*=-1:this.constants.hierarchicalLayout.levelSeparation=Math.abs(this.constants.hierarchicalLayout.levelSeparation),"RL"==this.constants.hierarchicalLayout.direction||"LR"==this.constants.hierarchicalLayout.direction?1==this.constants.smoothCurves.enabled&&(this.constants.smoothCurves.type="vertical"):1==this.constants.smoothCurves.enabled&&(this.constants.smoothCurves.type="horizontal");var t,e,i=0,s=!1,o=!1;for(e in this.nodes)this.nodes.hasOwnProperty(e)&&(t=this.nodes[e],-1!=t.level?s=!0:o=!0,is&&(n.xFixed=!1,n.x=i[n.level].minPos,r=!0):n.yFixed&&n.level>s&&(n.yFixed=!1,n.y=i[n.level].minPos,r=!0),1==r&&(i[n.level].minPos+=i[n.level].nodeSpacing,n.edges.length>1&&this._placeBranchNodes(n.edges,n.id,i,n.level))}},e._setLevel=function(t,e,i){for(var s=0;st)&&(o.level=t,o.edges.length>1&&this._setLevel(t+1,o.edges,o.id))}},e._setLevelDirected=function(t,e,i){this.nodes[i].hierarchyEnumerated=!0;for(var s=0;s1&&o.hierarchyEnumerated===!1&&this._setLevelDirected(o.level,o.edges,o.id)}},e._restoreNodes=function(){for(var t in this.nodes)this.nodes.hasOwnProperty(t)&&(this.nodes[t].xFixed=!1,this.nodes[t].yFixed=!1)}},function(t,e,i){function s(){this.constants.smoothCurves.enabled=!this.constants.smoothCurves.enabled;var t=document.getElementById("graph_toggleSmooth");t.style.background=1==this.constants.smoothCurves.enabled?"#A4FF56":"#FF8532",this._configureSmoothCurves(!1)}function o(){for(var t in this.calculationNodes)this.calculationNodes.hasOwnProperty(t)&&(this.calculationNodes[t].vx=0,this.calculationNodes[t].vy=0,this.calculationNodes[t].fx=0,this.calculationNodes[t].fy=0);1==this.constants.hierarchicalLayout.enabled?(this._setupHierarchicalLayout(),a.call(this,"graph_H_nd",1,"physics_hierarchicalRepulsion_nodeDistance"),a.call(this,"graph_H_cg",1,"physics_centralGravity"),a.call(this,"graph_H_sc",1,"physics_springConstant"),a.call(this,"graph_H_sl",1,"physics_springLength"),a.call(this,"graph_H_damp",1,"physics_damping")):this.repositionNodes(),this.moving=!0,this.start()}function n(){var t="No options are required, default values used.",e=[],i=document.getElementById("graph_physicsMethod1"),s=document.getElementById("graph_physicsMethod2");if(1==i.checked){if(this.constants.physics.barnesHut.gravitationalConstant!=this.backupConstants.physics.barnesHut.gravitationalConstant&&e.push("gravitationalConstant: "+this.constants.physics.barnesHut.gravitationalConstant),this.constants.physics.centralGravity!=this.backupConstants.physics.barnesHut.centralGravity&&e.push("centralGravity: "+this.constants.physics.centralGravity),this.constants.physics.springLength!=this.backupConstants.physics.barnesHut.springLength&&e.push("springLength: "+this.constants.physics.springLength),this.constants.physics.springConstant!=this.backupConstants.physics.barnesHut.springConstant&&e.push("springConstant: "+this.constants.physics.springConstant),this.constants.physics.damping!=this.backupConstants.physics.barnesHut.damping&&e.push("damping: "+this.constants.physics.damping),0!=e.length){t="var options = {",t+="physics: {barnesHut: {";for(var o=0;othis.constants.clustering.clusterThreshold&&1==this.constants.clustering.enabled&&this.clusterToFit(this.constants.clustering.reduceToNodes,!1),this._calculateForces())},e._calculateForces=function(){this._calculateGravitationalForces(),this._calculateNodeForces(),this.constants.physics.springConstant>0&&(1==this.constants.smoothCurves.enabled&&1==this.constants.smoothCurves.dynamic?this._calculateSpringForcesWithSupport():1==this.constants.physics.hierarchicalRepulsion.enabled?this._calculateHierarchicalSpringForces():this._calculateSpringForces())},e._updateCalculationNodes=function(){if(1==this.constants.smoothCurves.enabled&&1==this.constants.smoothCurves.dynamic){this.calculationNodes={},this.calculationNodeIndices=[];for(var t in this.nodes)this.nodes.hasOwnProperty(t)&&(this.calculationNodes[t]=this.nodes[t]);var e=this.sectors.support.nodes;for(var i in e)e.hasOwnProperty(i)&&(this.edges.hasOwnProperty(e[i].parentEdgeId)?this.calculationNodes[i]=e[i]:e[i]._setForce(0,0));for(var s in this.calculationNodes)this.calculationNodes.hasOwnProperty(s)&&this.calculationNodeIndices.push(s)}else this.calculationNodes=this.nodes,this.calculationNodeIndices=this.nodeIndices},e._calculateGravitationalForces=function(){var t,e,i,s,o,n=this.calculationNodes,r=this.constants.physics.centralGravity,a=0;for(o=0;oSimulation Mode:Barnes HutRepulsionHierarchical
Options:
',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 e;e=document.getElementById("graph_BH_gc"),e.onchange=a.bind(this,"graph_BH_gc",-1,"physics_barnesHut_gravitationalConstant"),e=document.getElementById("graph_BH_cg"),e.onchange=a.bind(this,"graph_BH_cg",1,"physics_centralGravity"),e=document.getElementById("graph_BH_sc"),e.onchange=a.bind(this,"graph_BH_sc",1,"physics_springConstant"),e=document.getElementById("graph_BH_sl"),e.onchange=a.bind(this,"graph_BH_sl",1,"physics_springLength"),e=document.getElementById("graph_BH_damp"),e.onchange=a.bind(this,"graph_BH_damp",1,"physics_damping"),e=document.getElementById("graph_R_nd"),e.onchange=a.bind(this,"graph_R_nd",1,"physics_repulsion_nodeDistance"),e=document.getElementById("graph_R_cg"),e.onchange=a.bind(this,"graph_R_cg",1,"physics_centralGravity"),e=document.getElementById("graph_R_sc"),e.onchange=a.bind(this,"graph_R_sc",1,"physics_springConstant"),e=document.getElementById("graph_R_sl"),e.onchange=a.bind(this,"graph_R_sl",1,"physics_springLength"),e=document.getElementById("graph_R_damp"),e.onchange=a.bind(this,"graph_R_damp",1,"physics_damping"),e=document.getElementById("graph_H_nd"),e.onchange=a.bind(this,"graph_H_nd",1,"physics_hierarchicalRepulsion_nodeDistance"),e=document.getElementById("graph_H_cg"),e.onchange=a.bind(this,"graph_H_cg",1,"physics_centralGravity"),e=document.getElementById("graph_H_sc"),e.onchange=a.bind(this,"graph_H_sc",1,"physics_springConstant"),e=document.getElementById("graph_H_sl"),e.onchange=a.bind(this,"graph_H_sl",1,"physics_springLength"),e=document.getElementById("graph_H_damp"),e.onchange=a.bind(this,"graph_H_damp",1,"physics_damping"),e=document.getElementById("graph_H_direction"),e.onchange=a.bind(this,"graph_H_direction",t,"hierarchicalLayout_direction"),e=document.getElementById("graph_H_levsep"),e.onchange=a.bind(this,"graph_H_levsep",1,"hierarchicalLayout_levelSeparation"),e=document.getElementById("graph_H_nspac"),e.onchange=a.bind(this,"graph_H_nspac",1,"hierarchicalLayout_nodeSpacing");var i=document.getElementById("graph_physicsMethod1"),d=document.getElementById("graph_physicsMethod2"),l=document.getElementById("graph_physicsMethod3");d.checked=!0,this.constants.physics.barnesHut.enabled&&(i.checked=!0),this.constants.hierarchicalLayout.enabled&&(l.checked=!0);var c=document.getElementById("graph_toggleSmooth"),p=document.getElementById("graph_repositionNodes"),u=document.getElementById("graph_generateOptions");c.onclick=s.bind(this),p.onclick=o.bind(this),u.onclick=n.bind(this),c.style.background=1==this.constants.smoothCurves&&0==this.constants.dynamicSmoothCurves?"#A4FF56":"#FF8532",r.apply(this),i.onchange=r.bind(this),d.onchange=r.bind(this),l.onchange=r.bind(this)}},e._overWriteGraphConstants=function(t,e){var i=t.split("_");1==i.length?this.constants[i[0]]=e:2==i.length?this.constants[i[0]][i[1]]=e:3==i.length&&(this.constants[i[0]][i[1]][i[2]]=e)}},function(t){function e(t){throw new Error("Cannot find module '"+t+"'.")}e.keys=function(){return[]},e.resolve=e,t.exports=e,e.id=63},function(t,e){e._calculateNodeForces=function(){var t,e,i,s,o,n,r,a,h,d,l,c=this.calculationNodes,p=this.calculationNodeIndices,u=-2/3,f=4/3,m=this.constants.physics.repulsion.nodeDistance,g=m;for(d=0;di&&(r=.5*g>i?1:v*i+f,r*=0==n?1:1+n*this.constants.clustering.forceAmplification,r/=i,s=t*r,o=e*r,a.fx-=s,a.fy-=o,h.fx+=s,h.fy+=o)}}},function(t,e){e._calculateNodeForces=function(){var t,e,i,s,o,n,r,a,h,d,l=this.calculationNodes,c=this.calculationNodeIndices,p=this.constants.physics.hierarchicalRepulsion.nodeDistance;for(h=0;hi?-Math.pow(u*i,2)+Math.pow(u*p,2):0,0==i?i=.01:n/=i,s=t*n,o=e*n,r.fx-=s,r.fy-=o,a.fx+=s,a.fy+=o}},e._calculateHierarchicalSpringForces=function(){for(var t,e,i,s,o,n,r,a,h,d=this.edges,l=this.calculationNodes,c=this.calculationNodeIndices,p=0;pn;n++)t=e[i[n]],t.options.mass>0&&(this._getForceContribution(o.root.children.NW,t),this._getForceContribution(o.root.children.NE,t),this._getForceContribution(o.root.children.SW,t),this._getForceContribution(o.root.children.SE,t))}},e._getForceContribution=function(t,e){if(t.childrenCount>0){var i,s,o;if(i=t.centerOfMass.x-e.x,s=t.centerOfMass.y-e.y,o=Math.sqrt(i*i+s*s),o*t.calcSize>this.constants.physics.barnesHut.theta){0==o&&(o=.1*Math.random(),i=o);var n=this.constants.physics.barnesHut.gravitationalConstant*t.mass*e.options.mass/(o*o*o),r=i*n,a=s*n;e.fx+=r,e.fy+=a}else if(4==t.childrenCount)this._getForceContribution(t.children.NW,e),this._getForceContribution(t.children.NE,e),this._getForceContribution(t.children.SW,e),this._getForceContribution(t.children.SE,e);else if(t.children.data.id!=e.id){0==o&&(o=.5*Math.random(),i=o);var n=this.constants.physics.barnesHut.gravitationalConstant*t.mass*e.options.mass/(o*o*o),r=i*n,a=s*n;e.fx+=r,e.fy+=a}}},e._formBarnesHutTree=function(t,e){for(var i,s=e.length,o=Number.MAX_VALUE,n=Number.MAX_VALUE,r=-Number.MAX_VALUE,a=-Number.MAX_VALUE,h=0;s>h;h++){var d=t[e[h]].x,l=t[e[h]].y;t[e[h]].options.mass>0&&(o>d&&(o=d),d>r&&(r=d),n>l&&(n=l),l>a&&(a=l))}var c=Math.abs(r-o)-Math.abs(a-n);c>0?(n-=.5*c,a+=.5*c):(o+=.5*c,r-=.5*c);var p=1e-5,u=Math.max(p,Math.abs(r-o)),f=.5*u,m=.5*(o+r),g=.5*(n+a),v={root:{centerOfMass:{x:0,y:0},mass:0,range:{minX:m-f,maxX:m+f,minY:g-f,maxY:g+f},size:u,calcSize:1/u,children:{data:null},maxWidth:0,level:0,childrenCount:4}};for(this._splitBranch(v.root),h=0;s>h;h++)i=t[e[h]],i.options.mass>0&&this._placeInTree(v.root,i);this.barnesHutTree=v},e._updateBranchMass=function(t,e){var i=t.mass+e.options.mass,s=1/i;t.centerOfMass.x=t.centerOfMass.x*t.mass+e.x*e.options.mass,t.centerOfMass.x*=s,t.centerOfMass.y=t.centerOfMass.y*t.mass+e.y*e.options.mass,t.centerOfMass.y*=s,t.mass=i;var o=Math.max(Math.max(e.height,e.radius),e.width);t.maxWidth=t.maxWidthe.x?t.children.NW.range.maxY>e.y?this._placeInRegion(t,e,"NW"):this._placeInRegion(t,e,"SW"):t.children.NW.range.maxY>e.y?this._placeInRegion(t,e,"NE"):this._placeInRegion(t,e,"SE")},e._placeInRegion=function(t,e,i){switch(t.children[i].childrenCount){case 0:t.children[i].children.data=e,t.children[i].childrenCount=1,this._updateBranchMass(t.children[i],e);break;case 1:t.children[i].children.data.x==e.x&&t.children[i].children.data.y==e.y?(e.x+=Math.random(),e.y+=Math.random()):(this._splitBranch(t.children[i]),this._placeInTree(t.children[i],e));break;case 4:this._placeInTree(t.children[i],e)}},e._splitBranch=function(t){var e=null;1==t.childrenCount&&(e=t.children.data,t.mass=0,t.centerOfMass.x=0,t.centerOfMass.y=0),t.childrenCount=4,t.children.data=null,this._insertRegion(t,"NW"),this._insertRegion(t,"NE"),this._insertRegion(t,"SW"),this._insertRegion(t,"SE"),null!=e&&this._placeInTree(t,e)},e._insertRegion=function(t,e){var i,s,o,n,r=.5*t.size;switch(e){case"NW":i=t.range.minX,s=t.range.minX+r,o=t.range.minY,n=t.range.minY+r;break;case"NE":i=t.range.minX+r,s=t.range.maxX,o=t.range.minY,n=t.range.minY+r;break;case"SW":i=t.range.minX,s=t.range.minX+r,o=t.range.minY+r,n=t.range.maxY;break;case"SE":i=t.range.minX+r,s=t.range.maxX,o=t.range.minY+r,n=t.range.maxY}t.children[e]={centerOfMass:{x:0,y:0},mass:0,range:{minX:i,maxX:s,minY:o,maxY:n},size:.5*t.size,calcSize:2*t.calcSize,children:{data:null},maxWidth:0,level:t.level+1,childrenCount:0}},e._drawTree=function(t,e){void 0!==this.barnesHutTree&&(t.lineWidth=1,this._drawBranch(this.barnesHutTree.root,t,e))},e._drawBranch=function(t,e,i){void 0===i&&(i="#FF0000"),4==t.childrenCount&&(this._drawBranch(t.children.NW,e),this._drawBranch(t.children.NE,e),this._drawBranch(t.children.SE,e),this._drawBranch(t.children.SW,e)),e.strokeStyle=i,e.beginPath(),e.moveTo(t.range.minX,t.range.minY),e.lineTo(t.range.maxX,t.range.minY),e.stroke(),e.beginPath(),e.moveTo(t.range.maxX,t.range.minY),e.lineTo(t.range.maxX,t.range.maxY),e.stroke(),e.beginPath(),e.moveTo(t.range.maxX,t.range.maxY),e.lineTo(t.range.minX,t.range.maxY),e.stroke(),e.beginPath(),e.moveTo(t.range.minX,t.range.maxY),e.lineTo(t.range.minX,t.range.minY),e.stroke()}},function(t){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}}])}); //# sourceMappingURL=vis.map \ No newline at end of file