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.

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