vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
5.0 KiB

  1. var Hammer = require('../../module/hammer');
  2. var util = require('../../util');
  3. var Component = require('./Component');
  4. var moment = require('../../module/moment');
  5. var locales = require('../locales');
  6. /**
  7. * A custom time bar
  8. * @param {{range: Range, dom: Object}} body
  9. * @param {Object} [options] Available parameters:
  10. * {Boolean} [showCustomTime]
  11. * @constructor CustomTime
  12. * @extends Component
  13. */
  14. function CustomTime (body, options) {
  15. this.body = body;
  16. // default options
  17. this.defaultOptions = {
  18. showCustomTime: false,
  19. locales: locales,
  20. locale: 'en',
  21. id: 0
  22. };
  23. this.options = util.extend({}, this.defaultOptions);
  24. if (options && options.time) {
  25. this.customTime = options.time;
  26. } else {
  27. this.customTime = new Date();
  28. }
  29. this.eventParams = {}; // stores state parameters while dragging the bar
  30. // create the DOM
  31. this._create();
  32. this.setOptions(options);
  33. }
  34. CustomTime.prototype = new Component();
  35. /**
  36. * Set options for the component. Options will be merged in current options.
  37. * @param {Object} options Available parameters:
  38. * {boolean} [showCustomTime]
  39. */
  40. CustomTime.prototype.setOptions = function(options) {
  41. if (options) {
  42. // copy all options that we know
  43. util.selectiveExtend(['showCustomTime', 'locale', 'locales', 'id'], this.options, options);
  44. // Triggered by addCustomTimeBar, redraw to add new bar
  45. if (this.options.id) {
  46. this.redraw();
  47. }
  48. }
  49. };
  50. /**
  51. * Create the DOM for the custom time
  52. * @private
  53. */
  54. CustomTime.prototype._create = function() {
  55. var bar = document.createElement('div');
  56. bar.className = 'customtime';
  57. bar.style.position = 'absolute';
  58. bar.style.top = '0px';
  59. bar.style.height = '100%';
  60. this.bar = bar;
  61. var drag = document.createElement('div');
  62. drag.style.position = 'relative';
  63. drag.style.top = '0px';
  64. drag.style.left = '-10px';
  65. drag.style.height = '100%';
  66. drag.style.width = '20px';
  67. bar.appendChild(drag);
  68. // attach event listeners
  69. this.hammer = new Hammer(drag);
  70. this.hammer.on('panstart', this._onDragStart.bind(this));
  71. this.hammer.on('panmove', this._onDrag.bind(this));
  72. this.hammer.on('panend', this._onDragEnd.bind(this));
  73. this.hammer.on('pan', function (event) {
  74. event.preventDefault();
  75. });
  76. };
  77. /**
  78. * Destroy the CustomTime bar
  79. */
  80. CustomTime.prototype.destroy = function () {
  81. this.options.showCustomTime = false;
  82. this.redraw(); // will remove the bar from the DOM
  83. this.hammer.enable(false);
  84. this.hammer = null;
  85. this.body = null;
  86. };
  87. /**
  88. * Repaint the component
  89. * @return {boolean} Returns true if the component is resized
  90. */
  91. CustomTime.prototype.redraw = function () {
  92. if (this.options.showCustomTime) {
  93. var parent = this.body.dom.backgroundVertical;
  94. if (this.bar.parentNode != parent) {
  95. // attach to the dom
  96. if (this.bar.parentNode) {
  97. this.bar.parentNode.removeChild(this.bar);
  98. }
  99. parent.appendChild(this.bar);
  100. }
  101. var x = this.body.util.toScreen(this.customTime);
  102. var locale = this.options.locales[this.options.locale];
  103. var title = locale.time + ': ' + moment(this.customTime).format('dddd, MMMM Do YYYY, H:mm:ss');
  104. title = title.charAt(0).toUpperCase() + title.substring(1);
  105. this.bar.style.left = x + 'px';
  106. this.bar.title = title;
  107. }
  108. else {
  109. // remove the line from the DOM
  110. if (this.bar.parentNode) {
  111. this.bar.parentNode.removeChild(this.bar);
  112. }
  113. }
  114. return false;
  115. };
  116. /**
  117. * Set custom time.
  118. * @param {Date | number | string} time
  119. */
  120. CustomTime.prototype.setCustomTime = function(time) {
  121. this.customTime = util.convert(time, 'Date');
  122. this.redraw();
  123. };
  124. /**
  125. * Retrieve the current custom time.
  126. * @return {Date} customTime
  127. */
  128. CustomTime.prototype.getCustomTime = function() {
  129. return new Date(this.customTime.valueOf());
  130. };
  131. /**
  132. * Start moving horizontally
  133. * @param {Event} event
  134. * @private
  135. */
  136. CustomTime.prototype._onDragStart = function(event) {
  137. this.eventParams.dragging = true;
  138. this.eventParams.customTime = this.customTime;
  139. event.stopPropagation();
  140. event.preventDefault();
  141. };
  142. /**
  143. * Perform moving operating.
  144. * @param {Event} event
  145. * @private
  146. */
  147. CustomTime.prototype._onDrag = function (event) {
  148. if (!this.eventParams.dragging) return;
  149. var x = this.body.util.toScreen(this.eventParams.customTime) + event.deltaX;
  150. var time = this.body.util.toTime(x);
  151. this.setCustomTime(time);
  152. // fire a timechange event
  153. this.body.emitter.emit('timechange', {
  154. id: this.options.id,
  155. time: new Date(this.customTime.valueOf())
  156. });
  157. event.stopPropagation();
  158. event.preventDefault();
  159. };
  160. /**
  161. * Stop moving operating.
  162. * @param {Event} event
  163. * @private
  164. */
  165. CustomTime.prototype._onDragEnd = function (event) {
  166. if (!this.eventParams.dragging) return;
  167. // fire a timechanged event
  168. this.body.emitter.emit('timechanged', {
  169. id: this.options.id,
  170. time: new Date(this.customTime.valueOf())
  171. });
  172. event.stopPropagation();
  173. event.preventDefault();
  174. };
  175. module.exports = CustomTime;