src/utils/timeUtils.js
// Time utilities
import moment from 'moment';
/**
* Snaps a moment object to the given resolution
* @param {moment} time The moment to snap
* @param {number} snapSeconds The snap time in seconds
* @returns {moment} Snapped moment
*/
export function timeSnap(time, snapSeconds) {
if (snapSeconds === 0) {
const newTime = time.clone();
newTime.set('millisecond', 0);
return newTime;
}
const newUnix = Math.round(time.unix() / snapSeconds) * snapSeconds;
return moment(newUnix * 1000);
}
/**
* Get the pixels per minute
* @param {moment} vis_start The moment specifying the start of the visible timeline range
* @param {moment} vis_end The moment specifying the end of the visible timeline range
* @param {number} total_width The width of the timeline in pixels
* @returns {float} The pixels per minute
*/
export function pixelsPerMinute(vis_start, vis_end, total_width) {
const start_end_min = vis_end.diff(vis_start, 'minutes');
return total_width / start_end_min;
}
/**
*
* @param {number} delta the delta distance in pixels
* @param {moment} vis_start the visible start of the timeline
* @param {moment} vis_end the visible end of the timeline
* @param {number} total_width the pixel width of the timeline
* @param {number} snapMinutes the number of minutes to snap to
*/
export function getSnapPixelFromDelta(delta, vis_start, vis_end, total_width, snapMinutes = 0) {
const pixelsPerSnapSegment = pixelsPerMinute(vis_start, vis_end, total_width) * snapMinutes;
return Math.round(delta / pixelsPerSnapSegment) * pixelsPerSnapSegment;
}
/**
* Get the time at a pixel location
* @param {number} pixel_location the pixel location (generally from left css style)
* @param {moment} vis_start The visible start of the timeline
* @param {moment} vis_end The visible end of the timeline
* @param {number} total_width The pixel width of the timeline (row portion)
* @param {number} snapMinutes The snap resolution (in mins)
* @returns {moment} Moment object
*/
export function getTimeAtPixel(pixel_location, vis_start, vis_end, total_width, snapMinutes = 0) {
let min_offset = pixel_location / pixelsPerMinute(vis_start, vis_end, total_width);
let timeAtPix = vis_start.clone().add(min_offset, 'minutes');
if (snapMinutes !== 0) timeAtPix = timeSnap(timeAtPix, snapMinutes * 60);
return timeAtPix;
}
/**
* Get the pixel location at a specific time
* @param {objects} time The time (moment) object
* @param {moment} vis_start The visible start of the timeline
* @param {moment} vis_end The visible end of the timeline
* @param {number} total_width The width in pixels of the grid
* @returns {number} The pixel offset
*/
export function getPixelAtTime(time, vis_start, vis_end, total_width) {
const min_from_start = time.diff(vis_start, 'minutes');
return min_from_start * pixelsPerMinute(vis_start, vis_end, total_width);
}
/**
* Returns the duration from the {@link vis_start}
* @param {number} pixels
* @param {moment} vis_start The visible start of the timeline
* @param {moment} vis_end The visible end of the timeline
* @param {number} total_width The width in pixels of the grid
* @returns {moment} Moment duration
*/
export function getDurationFromPixels(pixels, vis_start, vis_end, total_width) {
const start_end_min = vis_end.diff(vis_start, 'minutes');
if (start_end_min === 0) return moment.duration(0, 'minutes');
const pixels_per_min = total_width / start_end_min;
let mins = pixels / pixels_per_min;
return moment.duration(mins, 'minutes');
}