A declarative visualization grammar for creating interactive data visualizations through JSON specifications.
—
Vega's time processing system provides comprehensive temporal data handling with time intervals, binning, formatting, sequence generation, and calendar calculations for time-based visualizations.
Standard time unit definitions and identifiers.
/** Registry of all available time units */
const TIME_UNITS: {
year: 'year';
quarter: 'quarter';
month: 'month';
week: 'week';
date: 'date';
day: 'day';
dayofyear: 'dayofyear';
hours: 'hours';
minutes: 'minutes';
seconds: 'seconds';
milliseconds: 'milliseconds';
};
/** Year time unit constant */
const YEAR: 'year';
/** Quarter time unit constant */
const QUARTER: 'quarter';
/** Month time unit constant */
const MONTH: 'month';
/** Week time unit constant */
const WEEK: 'week';
/** Date (day of month) time unit constant */
const DATE: 'date';
/** Day of week time unit constant */
const DAY: 'day';
/** Day of year time unit constant */
const DAYOFYEAR: 'dayofyear';
/** Hours time unit constant */
const HOURS: 'hours';
/** Minutes time unit constant */
const MINUTES: 'minutes';
/** Seconds time unit constant */
const SECONDS: 'seconds';
/** Milliseconds time unit constant */
const MILLISECONDS: 'milliseconds';
type TimeUnit = 'year' | 'quarter' | 'month' | 'week' | 'date' | 'day' | 'dayofyear' | 'hours' | 'minutes' | 'seconds' | 'milliseconds';Time unit specification and utility functions.
/**
* Get time unit specifier string for formatting
* @param units - Time units array or single unit
* @returns Format specifier string
*/
function timeUnitSpecifier(units: TimeUnit[] | TimeUnit): string;
/**
* Get all available time units
* @returns Array of time unit identifiers
*/
function timeUnits(): TimeUnit[];
/**
* Calculate day of year for a date
* @param date - Date object
* @returns Day of year (1-366)
*/
function dayofyear(date: Date): number;
/**
* Calculate week number for a date
* @param date - Date object
* @returns Week number
*/
function week(date: Date): number;
/**
* Calculate day of year for a UTC date
* @param date - Date object
* @returns UTC day of year (1-366)
*/
function utcdayofyear(date: Date): number;
/**
* Calculate UTC week number for a date
* @param date - Date object
* @returns UTC week number
*/
function utcweek(date: Date): number;
/**
* Calculate quarter for a date
* @param date - Date object
* @returns Quarter number (1-4)
*/
function quarter(date: Date): number;
/**
* Calculate UTC quarter for a date
* @param date - Date object
* @returns UTC quarter number (1-4)
*/
function utcquarter(date: Date): number;Time interval creation and manipulation.
/**
* Create a time interval for the specified unit
* @param unit - Time unit identifier
* @returns Time interval object
*/
function timeInterval(unit: TimeUnit): TimeInterval;
/**
* Create UTC time interval for the specified unit
* @param unit - Time unit identifier
* @returns UTC time interval object
*/
function utcInterval(unit: TimeUnit): TimeInterval;
/**
* Calculate time offset for interval arithmetic
* @param unit - Time unit identifier
* @param step - Number of units to offset
* @returns Time offset function
*/
function timeOffset(unit: TimeUnit, step?: number): (date: Date) => Date;
/**
* Calculate UTC time offset for interval arithmetic
* @param unit - Time unit identifier
* @param step - Number of units to offset
* @returns UTC time offset function
*/
function utcOffset(unit: TimeUnit, step?: number): (date: Date) => Date;
/**
* Generate sequence of dates at regular intervals
* @param start - Start date
* @param stop - End date
* @param step - Time interval or step count
* @returns Array of dates
*/
function timeSequence(start: Date, stop: Date, step: TimeInterval | number): Date[];
/**
* Generate UTC sequence of dates at regular intervals
* @param start - Start date
* @param stop - End date
* @param step - Time interval or step count
* @returns Array of UTC dates
*/
function utcSequence(start: Date, stop: Date, step: TimeInterval | number): Date[];
interface TimeInterval {
/** Floor date to interval boundary */
floor(date: Date): Date;
/** Ceil date to interval boundary */
ceil(date: Date): Date;
/** Round date to nearest interval boundary */
round(date: Date): Date;
/** Offset date by specified number of intervals */
offset(date: Date, step?: number): Date;
/** Generate range of dates */
range(start: Date, stop: Date, step?: number): Date[];
/** Filter dates that match interval */
filter(test: (date: Date) => boolean): TimeInterval;
/** Create interval with different step size */
every(step: number): TimeInterval;
/** Count intervals between two dates */
count(start: Date, end: Date): number;
}Date flooring operations for time alignment.
/**
* Floor date to time unit boundary
* @param unit - Time unit for flooring
* @returns Date flooring function
*/
function timeFloor(unit: TimeUnit): (date: Date) => Date;
/**
* Floor date to UTC time unit boundary
* @param unit - Time unit for flooring
* @returns UTC date flooring function
*/
function utcFloor(unit: TimeUnit): (date: Date) => Date;Time-based data binning for temporal aggregation.
/**
* Create time binning function
* @param options - Time binning configuration
* @returns Time binning function
*/
function timeBin(options: TimeBinOptions): (date: Date) => Date;
interface TimeBinOptions {
/** Time unit for binning */
unit?: TimeUnit;
/** Step size for binning */
step?: number;
/** Use UTC time */
utc?: boolean;
/** Bin extent */
extent?: [Date, Date];
/** Maximum number of bins */
maxbins?: number;
/** Bin boundaries */
anchor?: Date;
/** Nice bin boundaries */
nice?: boolean;
}
interface TimeBin {
/** Bin start time */
start: Date;
/** Bin end time */
end: Date;
/** Bin step interval */
step: TimeInterval;
/** Bin unit */
unit: TimeUnit;
}Time scales work seamlessly with time operations for temporal visualizations.
/** Time scale configuration for temporal data mapping */
interface TimeScaleConfig {
/** Scale type */
type: 'time' | 'utc';
/** Time domain */
domain: Date[] | TimeScaleDomain;
/** Output range */
range: any[];
/** Nice domain boundaries */
nice?: TimeUnit | TimeInterval | boolean;
/** Clamp values to domain */
clamp?: boolean;
}
interface TimeScaleDomain {
/** Data source reference */
data: string;
/** Date field reference */
field: string;
/** Sort configuration */
sort?: boolean;
}import {
timeInterval,
timeFloor,
timeSequence,
dayofyear,
quarter
} from "vega";
const date = new Date('2023-06-15T14:30:00');
// Floor to different time units
const dayFloor = timeFloor('day');
const monthFloor = timeFloor('month');
console.log(dayFloor(date)); // 2023-06-15T00:00:00
console.log(monthFloor(date)); // 2023-06-01T00:00:00
// Calculate time properties
console.log(dayofyear(date)); // 166
console.log(quarter(date)); // 2import { timeInterval, timeOffset } from "vega";
// Create monthly interval
const monthly = timeInterval('month');
const startDate = new Date('2023-01-15');
// Floor to month boundary
const monthStart = monthly.floor(startDate); // 2023-01-01
// Generate monthly sequence
const months = monthly.range(
new Date('2023-01-01'),
new Date('2023-12-31'),
1
);
console.log(months.length); // 12 months
// Offset operations
const offset = timeOffset('month', 3);
const futureDate = offset(startDate); // 3 months laterimport { timeBin } from "vega";
const data = [
new Date('2023-01-15T08:30:00'),
new Date('2023-01-15T14:45:00'),
new Date('2023-01-15T20:15:00'),
new Date('2023-01-16T09:00:00')
];
// Create hourly bins
const hourlyBin = timeBin({
unit: 'hours',
step: 4,
nice: true
});
const bins = data.map(date => ({
original: date,
binned: hourlyBin(date)
}));
console.log(bins);
// Groups times into 4-hour binsimport { timeSequence, utcSequence } from "vega";
const start = new Date('2023-01-01');
const end = new Date('2023-01-31');
// Generate daily sequence
const dailySequence = timeSequence(start, end, timeInterval('day'));
console.log(dailySequence.length); // 31 days
// Generate weekly sequence
const weeklySequence = timeSequence(start, end, timeInterval('week'));
console.log(weeklySequence.length); // ~4-5 weeks
// UTC sequences for consistent timezone handling
const utcDaily = utcSequence(start, end, timeInterval('day'));import { timeUnitSpecifier, timeUnits } from "vega";
// Get format specifiers for time units
const yearSpec = timeUnitSpecifier('year'); // '%Y'
const monthDaySpec = timeUnitSpecifier(['month', 'date']); // '%b %d'
const timeSpec = timeUnitSpecifier(['hours', 'minutes']); // '%H:%M'
// Get all available time units
const allUnits = timeUnits();
console.log(allUnits); // ['year', 'month', 'day', ...]import { week, utcweek, dayofyear, quarter } from "vega";
const dates = [
new Date('2023-01-01'),
new Date('2023-04-15'),
new Date('2023-07-04'),
new Date('2023-12-31')
];
dates.forEach(date => {
console.log({
date: date.toISOString(),
week: week(date),
utcWeek: utcweek(date),
dayOfYear: dayofyear(date),
quarter: quarter(date)
});
});import { timeInterval, timeFloor } from "vega";
const transactions = [
{ date: new Date('2023-06-01T09:15:00'), amount: 100 },
{ date: new Date('2023-06-01T14:30:00'), amount: 250 },
{ date: new Date('2023-06-02T11:45:00'), amount: 75 },
{ date: new Date('2023-06-03T16:20:00'), amount: 200 }
];
// Group by day
const dayFloor = timeFloor('day');
const dailyGroups = new Map();
transactions.forEach(tx => {
const day = dayFloor(tx.date);
const dayKey = day.toISOString();
if (!dailyGroups.has(dayKey)) {
dailyGroups.set(dayKey, []);
}
dailyGroups.get(dayKey).push(tx);
});
// Calculate daily totals
const dailyTotals = Array.from(dailyGroups.entries()).map(([day, txs]) => ({
date: new Date(day),
total: txs.reduce((sum, tx) => sum + tx.amount, 0),
count: txs.length
}));
console.log(dailyTotals);// Example Vega specification using time scales
const timeScaleSpec = {
"scales": [
{
"name": "xscale",
"type": "time",
"domain": {"data": "timeseries", "field": "date"},
"range": "width",
"nice": "day"
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale",
"format": "%b %d",
"tickCount": 10
}
]
};import {
timeInterval,
utcInterval,
timeFloor,
utcFloor
} from "vega";
const date = new Date('2023-06-15T14:30:00Z');
// Local time operations
const localDay = timeInterval('day');
const localFloor = timeFloor('day');
// UTC time operations
const utcDay = utcInterval('day');
const utcFloorFunc = utcFloor('day');
console.log('Local day floor:', localFloor(date));
console.log('UTC day floor:', utcFloorFunc(date));
// Different results due to timezone differencesimport { timeBin, timeInterval } from "vega";
const eventData = [
{ time: new Date('2023-06-15T08:15:30'), value: 10 },
{ time: new Date('2023-06-15T08:47:22'), value: 15 },
{ time: new Date('2023-06-15T09:12:45'), value: 8 },
{ time: new Date('2023-06-15T09:33:18'), value: 20 }
];
// Create 30-minute bins
const binFunc = timeBin({
unit: 'minutes',
step: 30,
nice: true,
extent: [
new Date('2023-06-15T08:00:00'),
new Date('2023-06-15T10:00:00')
]
});
// Aggregate data by time bins
const binnedData = new Map();
eventData.forEach(d => {
const binStart = binFunc(d.time);
const binKey = binStart.toISOString();
if (!binnedData.has(binKey)) {
binnedData.set(binKey, {
bin: binStart,
values: [],
sum: 0,
count: 0
});
}
const bin = binnedData.get(binKey);
bin.values.push(d);
bin.sum += d.value;
bin.count += 1;
});
const aggregated = Array.from(binnedData.values()).map(bin => ({
time: bin.bin,
average: bin.sum / bin.count,
total: bin.sum,
count: bin.count
}));
console.log(aggregated);Install with Tessl CLI
npx tessl i tessl/npm-vega