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.

188 lines
4.9 KiB

  1. var util = require('../../util');
  2. var Component = require('./Component');
  3. var moment = require('../../module/moment');
  4. var locales = require('../locales');
  5. /**
  6. * A current time bar
  7. * @param {{range: Range, dom: Object, domProps: Object}} body
  8. * @param {Object} [options] Available parameters:
  9. * {Boolean} [showCurrentTime]
  10. * {String} [alignCurrentTime]
  11. * @constructor CurrentTime
  12. * @extends Component
  13. */
  14. function CurrentTime (body, options) {
  15. this.body = body;
  16. // default options
  17. this.defaultOptions = {
  18. rtl: false,
  19. showCurrentTime: true,
  20. alignCurrentTime: undefined,
  21. moment: moment,
  22. locales: locales,
  23. locale: 'en'
  24. };
  25. this.options = util.extend({}, this.defaultOptions);
  26. this.offset = 0;
  27. this._create();
  28. this.setOptions(options);
  29. }
  30. CurrentTime.prototype = new Component();
  31. /**
  32. * Create the HTML DOM for the current time bar
  33. * @private
  34. */
  35. CurrentTime.prototype._create = function() {
  36. var bar = document.createElement('div');
  37. bar.className = 'vis-current-time';
  38. bar.style.position = 'absolute';
  39. bar.style.top = '0px';
  40. bar.style.height = '100%';
  41. this.bar = bar;
  42. };
  43. /**
  44. * Destroy the CurrentTime bar
  45. */
  46. CurrentTime.prototype.destroy = function () {
  47. this.options.showCurrentTime = false;
  48. this.redraw(); // will remove the bar from the DOM and stop refreshing
  49. this.body = null;
  50. };
  51. /**
  52. * Set options for the component. Options will be merged in current options.
  53. * @param {Object} options Available parameters:
  54. * {boolean} [showCurrentTime]
  55. * {String} [alignCurrentTime]
  56. */
  57. CurrentTime.prototype.setOptions = function(options) {
  58. if (options) {
  59. // copy all options that we know
  60. util.selectiveExtend(['rtl', 'showCurrentTime', 'alignCurrentTime', 'moment', 'locale', 'locales'], this.options, options);
  61. }
  62. };
  63. /**
  64. * Repaint the component
  65. * @return {boolean} Returns true if the component is resized
  66. */
  67. CurrentTime.prototype.redraw = function() {
  68. if (this.options.showCurrentTime) {
  69. var parent = this.body.dom.backgroundVertical;
  70. if (this.bar.parentNode != parent) {
  71. // attach to the dom
  72. if (this.bar.parentNode) {
  73. this.bar.parentNode.removeChild(this.bar);
  74. }
  75. parent.appendChild(this.bar);
  76. this.start();
  77. }
  78. var now = this.options.moment(new Date().valueOf() + this.offset);
  79. if (this.options.alignCurrentTime) {
  80. now = now.startOf(this.options.alignCurrentTime);
  81. }
  82. var x = this.body.util.toScreen(now);
  83. var locale = this.options.locales[this.options.locale];
  84. if (!locale) {
  85. if (!this.warned) {
  86. console.log('WARNING: options.locales[\'' + this.options.locale + '\'] not found. See http://visjs.org/docs/timeline/#Localization');
  87. this.warned = true;
  88. }
  89. locale = this.options.locales['en']; // fall back on english when not available
  90. }
  91. var title = locale.current + ' ' + locale.time + ': ' + now.format('dddd, MMMM Do YYYY, H:mm:ss');
  92. title = title.charAt(0).toUpperCase() + title.substring(1);
  93. if (this.options.rtl) {
  94. this.bar.style.right = x + 'px';
  95. } else {
  96. this.bar.style.left = x + 'px';
  97. }
  98. this.bar.title = title;
  99. }
  100. else {
  101. // remove the line from the DOM
  102. if (this.bar.parentNode) {
  103. this.bar.parentNode.removeChild(this.bar);
  104. }
  105. this.stop();
  106. }
  107. return false;
  108. };
  109. /**
  110. * Start auto refreshing the current time bar
  111. */
  112. CurrentTime.prototype.start = function() {
  113. var me = this;
  114. /**
  115. * Updates the current time.
  116. */
  117. function update () {
  118. me.stop();
  119. // determine interval to refresh
  120. var scale = me.body.range.conversion(me.body.domProps.center.width).scale;
  121. var interval = 1 / scale / 10;
  122. if (interval < 30) interval = 30;
  123. if (interval > 1000) interval = 1000;
  124. me.redraw();
  125. me.body.emitter.emit('currentTimeTick');
  126. // start a renderTimer to adjust for the new time
  127. me.currentTimeTimer = setTimeout(update, interval);
  128. }
  129. update();
  130. };
  131. /**
  132. * Stop auto refreshing the current time bar
  133. */
  134. CurrentTime.prototype.stop = function() {
  135. if (this.currentTimeTimer !== undefined) {
  136. clearTimeout(this.currentTimeTimer);
  137. delete this.currentTimeTimer;
  138. }
  139. };
  140. /**
  141. * Set a current time. This can be used for example to ensure that a client's
  142. * time is synchronized with a shared server time.
  143. * @param {Date | string | number} time A Date, unix timestamp, or
  144. * ISO date string.
  145. */
  146. CurrentTime.prototype.setCurrentTime = function(time) {
  147. var t = util.convert(time, 'Date').valueOf();
  148. var now = new Date().valueOf();
  149. this.offset = t - now;
  150. this.redraw();
  151. };
  152. /**
  153. * Get the current time.
  154. * @return {Date} Returns the current time.
  155. */
  156. CurrentTime.prototype.getCurrentTime = function() {
  157. return new Date(new Date().valueOf() + this.offset);
  158. };
  159. module.exports = CurrentTime;