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.

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