|
|
-
- /**
- * used in Core to convert the options into a volatile variable
- *
- * @param {function} moment
- * @param {Object} body
- * @param {Array | Object} hiddenDates
- * @returns {Number}
- */
- exports.convertHiddenOptions = function(moment, body, hiddenDates) {
- if (hiddenDates && !Array.isArray(hiddenDates)) {
- return exports.convertHiddenOptions(moment, 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
- }
- }
- };
-
-
- /**
- * create new entrees for the repeating hidden dates
- *
- * @param {function} moment
- * @param {Object} body
- * @param {Array | Object} hiddenDates
- * @returns {null}
- */
- exports.updateHiddenDates = function (moment, body, hiddenDates) {
- if (hiddenDates && !Array.isArray(hiddenDates)) {
- return exports.updateHiddenDates(moment, body, [hiddenDates])
- }
-
- if (hiddenDates && body.domProps.centerContainer.width !== undefined) {
- exports.convertHiddenOptions(moment, 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);
- }
- }
-
- };
-
-
- /**
- * remove duplicates from the hidden dates list. Duplicates are evil. They mess everything up.
- * Scales with N^2
- *
- * @param {Object} body
- */
- 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;
- }
- }
- }
- }
-
- for (i = 0; i < hiddenDates.length; i++) {
- if (hiddenDates[i].remove !== true) {
- safeDates.push(hiddenDates[i]);
- }
- }
-
- 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);
- }
- };
-
- /**
- * Used in TimeStep to avoid the hidden times.
- * @param {function} moment
- * @param {TimeStep} timeStep
- * @param {Date} previousTime
- */
- exports.stepOverHiddenDates = function(moment, 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;
- }
- };
-
-
- ///**
- // * Used in TimeStep to avoid the hidden times.
- // * @param timeStep
- // * @param previousTime
- // */
- //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();
- // }
- //};
-
- /**
- * replaces the Core toScreen methods
- *
- * @param {vis.Core} Core
- * @param {Date} time
- * @param {Number} width
- * @returns {Number}
- */
- exports.toScreen = function (Core, time, width) {
- var conversion;
- if (Core.body.hiddenDates.length == 0) {
- conversion = Core.range.conversion(width);
- return (time.valueOf() - conversion.offset) * conversion.scale;
- } else {
- var hidden = exports.isHidden(time, Core.body.hiddenDates);
- if (hidden.hidden == true) {
- time = hidden.startDate;
- }
-
- var duration = exports.getHiddenDurationBetween(Core.body.hiddenDates, Core.range.start, Core.range.end);
- if (time < Core.range.start) {
- conversion = Core.range.conversion(width, duration);
- var hiddenBeforeStart = exports.getHiddenDurationBeforeStart(Core.body.hiddenDates, time, conversion.offset);
- time = Core.options.moment(time).toDate().valueOf();
- time = time + hiddenBeforeStart;
- return -(conversion.offset - time.valueOf()) * conversion.scale;
-
- } else if (time > Core.range.end) {
- var rangeAfterEnd = {start: Core.range.start, end: time};
- time = exports.correctTimeForHidden(Core.options.moment, Core.body.hiddenDates, rangeAfterEnd, time);
- conversion = Core.range.conversion(width, duration);
- return (time.valueOf() - conversion.offset) * conversion.scale;
-
- } else {
- time = exports.correctTimeForHidden(Core.options.moment, Core.body.hiddenDates, Core.range, time);
- conversion = Core.range.conversion(width, duration);
- return (time.valueOf() - conversion.offset) * conversion.scale;
- }
- }
- };
-
-
- /**
- * Replaces the core toTime methods
- *
- * @param {vis.Core} Core
- * @param {number} x
- * @param {number} width
- * @returns {Date}
- */
- exports.toTime = function(Core, x, width) {
- if (Core.body.hiddenDates.length == 0) {
- var conversion = Core.range.conversion(width);
- return new Date(x / conversion.scale + conversion.offset);
- }
- else {
- var hiddenDuration = exports.getHiddenDurationBetween(Core.body.hiddenDates, Core.range.start, Core.range.end);
- var totalDuration = Core.range.end - Core.range.start - hiddenDuration;
- var partialDuration = totalDuration * x / width;
- var accumulatedHiddenDuration = exports.getAccumulatedHiddenDuration(Core.body.hiddenDates, Core.range, partialDuration);
-
- return new Date(accumulatedHiddenDuration + partialDuration + Core.range.start);
- }
- };
-
-
- /**
- * Support function
- *
- * @param {Array<{start: Window.start, end: *}>} hiddenDates
- * @param {number} start
- * @param {number} end
- * @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;
- }
- }
- return duration;
- };
-
- /**
- * Support function
- *
- * @param {Array<{start: Window.start, end: *}>} hiddenDates
- * @param {number} start
- * @param {number} end
- * @returns {number}
- */
- exports.getHiddenDurationBeforeStart = 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 (startDate >= start && endDate <= end) {
- duration += endDate - startDate;
- }
- }
- return duration;
- };
-
-
- /**
- * Support function
- * @param {function} moment
- * @param {Array<{start: Window.start, end: *}>} hiddenDates
- * @param {{start: number, end: number}} range
- * @param {Date} time
- * @returns {number}
- */
- exports.correctTimeForHidden = function(moment, hiddenDates, range, time) {
- time = moment(time).toDate().valueOf();
- time -= exports.getHiddenDurationBefore(moment, hiddenDates,range,time);
- return time;
- };
-
- exports.getHiddenDurationBefore = function(moment, 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 timeOffset;
- };
-
- /**
- * sum the duration from start to finish, including the hidden duration,
- * until the required amount has been reached, return the accumulated hidden duration
- * @param {Array<{start: Window.start, end: *}>} hiddenDates
- * @param {{start: number, end: number}} range
- * @param {number} [requiredDuration=0]
- * @returns {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;
- }
- }
- }
-
- return hiddenDuration;
- };
-
-
-
- /**
- * used to step over to either side of a hidden block. Correction is disabled on tablets, might be set to true
- * @param {Array<{start: Window.start, end: *}>} hiddenDates
- * @param {Date} time
- * @param {Number} direction
- * @param {Boolean} correctionEnabled
- * @returns {Date|Number}
- */
- 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;
- }
- }
- }
- else {
- return time;
- }
-
- };
-
-
- /**
- * Check if a time is hidden
- *
- * @param {Date} time
- * @param {Array<{start: Window.start, end: *}>} 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;
-
- if (time >= startDate && time < endDate) { // if the start is entering a hidden zone
- return {hidden: true, startDate: startDate, endDate: endDate};
- }
- }
- return {hidden: false, startDate: startDate, endDate: endDate};
- };
|