UNPKG

vis-timeline

Version:

Create a fully customizable, interactive timeline with items and ranges.

192 lines (163 loc) 5.01 kB
import util from 'vis-util'; import Component from './Component'; import moment from '../../module/moment'; import locales from '../locales'; /** * A current time bar */ class CurrentTime extends Component { /** * @param {{range: Range, dom: Object, domProps: Object}} body * @param {Object} [options] Available parameters: * {Boolean} [showCurrentTime] * {String} [alignCurrentTime] * @constructor CurrentTime * @extends Component */ constructor(body, options) { super() this.body = body; // default options this.defaultOptions = { rtl: false, showCurrentTime: true, alignCurrentTime: undefined, moment, locales, locale: 'en' }; this.options = util.extend({}, this.defaultOptions); this.offset = 0; this._create(); this.setOptions(options); } /** * Create the HTML DOM for the current time bar * @private */ _create() { const bar = document.createElement('div'); bar.className = 'vis-current-time'; bar.style.position = 'absolute'; bar.style.top = '0px'; bar.style.height = '100%'; this.bar = bar; } /** * Destroy the CurrentTime bar */ destroy() { this.options.showCurrentTime = false; this.redraw(); // will remove the bar from the DOM and stop refreshing this.body = null; } /** * Set options for the component. Options will be merged in current options. * @param {Object} options Available parameters: * {boolean} [showCurrentTime] * {String} [alignCurrentTime] */ setOptions(options) { if (options) { // copy all options that we know util.selectiveExtend(['rtl', 'showCurrentTime', 'alignCurrentTime', 'moment', 'locale', 'locales'], this.options, options); } } /** * Repaint the component * @return {boolean} Returns true if the component is resized */ redraw() { if (this.options.showCurrentTime) { const parent = this.body.dom.backgroundVertical; if (this.bar.parentNode != parent) { // attach to the dom if (this.bar.parentNode) { this.bar.parentNode.removeChild(this.bar); } parent.appendChild(this.bar); this.start(); } let now = this.options.moment(new Date().valueOf() + this.offset); if (this.options.alignCurrentTime) { now = now.startOf(this.options.alignCurrentTime); } const x = this.body.util.toScreen(now); let locale = this.options.locales[this.options.locale]; if (!locale) { if (!this.warned) { console.warn(`WARNING: options.locales['${this.options.locale}'] not found. See https://visjs.github.io/vis-timeline/docs/timeline/#Localization`); this.warned = true; } locale = this.options.locales['en']; // fall back on english when not available } let title = `${locale.current} ${locale.time}: ${now.format('dddd, MMMM Do YYYY, H:mm:ss')}`; title = title.charAt(0).toUpperCase() + title.substring(1); if (this.options.rtl) { this.bar.style.right = `${x}px`; } else { this.bar.style.left = `${x}px`; } this.bar.title = title; } else { // remove the line from the DOM if (this.bar.parentNode) { this.bar.parentNode.removeChild(this.bar); } this.stop(); } return false; } /** * Start auto refreshing the current time bar */ start() { const me = this; /** * Updates the current time. */ function update () { me.stop(); // determine interval to refresh const scale = me.body.range.conversion(me.body.domProps.center.width).scale; let interval = 1 / scale / 10; if (interval < 30) interval = 30; if (interval > 1000) interval = 1000; me.redraw(); me.body.emitter.emit('currentTimeTick'); // start a renderTimer to adjust for the new time me.currentTimeTimer = setTimeout(update, interval); } update(); } /** * Stop auto refreshing the current time bar */ stop() { if (this.currentTimeTimer !== undefined) { clearTimeout(this.currentTimeTimer); delete this.currentTimeTimer; } } /** * Set a current time. This can be used for example to ensure that a client's * time is synchronized with a shared server time. * @param {Date | string | number} time A Date, unix timestamp, or * ISO date string. */ setCurrentTime(time) { const t = util.convert(time, 'Date').valueOf(); const now = new Date().valueOf(); this.offset = t - now; this.redraw(); } /** * Get the current time. * @return {Date} Returns the current time. */ getCurrentTime() { return new Date(new Date().valueOf() + this.offset); } } export default CurrentTime;