Skip to content

Commit

Permalink
ui: add support for showing timestamps/durations in millis/micros
Browse files Browse the repository at this point in the history
We already have support for seconds, there's no reason we should also
not support milliseconds or microseconds as well.

Fixes: #879
Change-Id: I7705518d1184ad037451b568735501f192280cf2
  • Loading branch information
LalitMaganti committed Sep 7, 2024
1 parent f3ad59e commit 1687234
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 1 deletion.
44 changes: 43 additions & 1 deletion ui/src/base/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type duration = bigint;
// The conversion factor for converting between different time units.
const TIME_UNITS_PER_SEC = 1e9;
const TIME_UNITS_PER_MILLISEC = 1e6;
const TIME_UNITS_PER_MICROSEC = 1e3;

export class Time {
// Negative time is never found in a trace - so -1 is commonly used as a flag
Expand Down Expand Up @@ -87,6 +88,20 @@ export class Time {
return Number(t) / TIME_UNITS_PER_MILLISEC;
}

// Convert microseconds (number) to a time value.
// Note: number -> BigInt conversion is relatively slow.
static fromMicros(millis: number): time {
return Time.fromRaw(BigInt(Math.floor(millis * TIME_UNITS_PER_MICROSEC)));
}

// Convert time value to microseconds and return as a number (i.e. float).
// Warning: This function is lossy, i.e. precision is lost when converting
// BigInt -> number.
// Note: BigInt -> number conversion is relatively slow.
static toMicros(t: time): number {
return Number(t) / TIME_UNITS_PER_MICROSEC;
}

// Convert a Date object to a time value, given an offset from the unix epoch.
// Note: number -> BigInt conversion is relatively slow.
static fromDate(d: Date, offset: duration): time {
Expand Down Expand Up @@ -147,11 +162,18 @@ export class Time {
return Time.fromRaw(BigintMath.quant(a, b));
}

// Format time as seconds.
static formatSeconds(time: time): string {
return Time.toSeconds(time).toString() + ' s';
}

static formatMilliseconds(time: time): string {
return Time.toMillis(time).toString() + ' ms';
}

static formatMicroseconds(time: time): string {
return Time.toMicros(time).toString() + ' us';
}

static toTimecode(time: time): Timecode {
return new Timecode(time);
}
Expand Down Expand Up @@ -199,6 +221,18 @@ export class Duration {
return Number(d) / TIME_UNITS_PER_SEC;
}

// Convert time to seconds as a number.
// Use this function with caution. It loses precision and is slow.
static toMilliseconds(d: duration) {
return Number(d) / TIME_UNITS_PER_MILLISEC;
}

// Convert time to seconds as a number.
// Use this function with caution. It loses precision and is slow.
static toMicroSeconds(d: duration) {
return Number(d) / TIME_UNITS_PER_MICROSEC;
}

// Print duration as as human readable string - i.e. to only a handful of
// significant figues.
// Use this when readability is more desireable than precision.
Expand Down Expand Up @@ -245,6 +279,14 @@ export class Duration {
static formatSeconds(dur: duration): string {
return Duration.toSeconds(dur).toString() + ' s';
}

static formatMilliseconds(dur: duration): string {
return Duration.toMilliseconds(dur).toString() + ' s';
}

static formatMicroseconds(dur: duration): string {
return Duration.toMicroSeconds(dur).toString() + ' s';
}
}

// This class takes a time and converts it to a set of strings representing a
Expand Down
2 changes: 2 additions & 0 deletions ui/src/core/timestamp_format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export enum TimestampFormat {
TraceNs = 'traceNs',
TraceNsLocale = 'traceNsLocale',
Seconds = 'seconds',
Milliseoncds = 'milliseconds',
Microseconds = 'microseconds',
UTC = 'utc',
TraceTz = 'traceTz',
}
Expand Down
2 changes: 2 additions & 0 deletions ui/src/frontend/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ class Globals {
switch (fmt) {
case TimestampFormat.Timecode:
case TimestampFormat.Seconds:
case TimestampFormat.Milliseoncds:
case TimestampFormat.Microseconds:
return this.traceContext.start;
case TimestampFormat.TraceNs:
case TimestampFormat.TraceNsLocale:
Expand Down
6 changes: 6 additions & 0 deletions ui/src/frontend/overview_timeline_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ function renderTimestamp(
case TimestampFormat.Seconds:
ctx.fillText(Time.formatSeconds(time), x, y, minWidth);
break;
case TimestampFormat.Milliseoncds:
ctx.fillText(Time.formatMilliseconds(time), x, y, minWidth);
break;
case TimestampFormat.Microseconds:
ctx.fillText(Time.formatMicroseconds(time), x, y, minWidth);
break;
default:
const z: never = fmt;
throw new Error(`Invalid timestamp ${z}`);
Expand Down
16 changes: 16 additions & 0 deletions ui/src/frontend/time_axis_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@ function renderTimestamp(
return renderRawTimestamp(ctx, time.toLocaleString(), x, y, minWidth);
case TimestampFormat.Seconds:
return renderRawTimestamp(ctx, Time.formatSeconds(time), x, y, minWidth);
case TimestampFormat.Milliseoncds:
return renderRawTimestamp(
ctx,
Time.formatMilliseconds(time),
x,
y,
minWidth,
);
case TimestampFormat.Microseconds:
return renderRawTimestamp(
ctx,
Time.formatMicroseconds(time),
x,
y,
minWidth,
);
default:
const z: never = fmt;
throw new Error(`Invalid timestamp ${z}`);
Expand Down
4 changes: 4 additions & 0 deletions ui/src/frontend/time_selection_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ function stringifyTimestamp(time: time): string {
return time.toLocaleString();
case TimestampFormat.Seconds:
return Time.formatSeconds(time);
case TimestampFormat.Milliseoncds:
return Time.formatMilliseconds(time);
case TimestampFormat.Microseconds:
return Time.formatMicroseconds(time);
default:
const z: never = fmt;
throw new Error(`Invalid timestamp ${z}`);
Expand Down
2 changes: 2 additions & 0 deletions ui/src/frontend/ui_main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ export class UiMain implements m.ClassComponent {
displayName: 'Realtime (Trace TZ)',
},
{key: TimestampFormat.Seconds, displayName: 'Seconds'},
{key: TimestampFormat.Milliseoncds, displayName: 'Milliseconds'},
{key: TimestampFormat.Microseconds, displayName: 'Microseconds'},
{key: TimestampFormat.TraceNs, displayName: 'Trace nanoseconds'},
{
key: TimestampFormat.TraceNsLocale,
Expand Down
6 changes: 6 additions & 0 deletions ui/src/frontend/widgets/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export class DurationWidget implements m.ClassComponent<DurationWidgetAttrs> {
menuItemForFormat(TimestampFormat.UTC, 'Realtime (UTC)'),
menuItemForFormat(TimestampFormat.TraceTz, 'Realtime (Trace TZ)'),
menuItemForFormat(TimestampFormat.Seconds, 'Seconds'),
menuItemForFormat(TimestampFormat.Milliseoncds, 'Milliseconds'),
menuItemForFormat(TimestampFormat.Microseconds, 'Microseconds'),
menuItemForFormat(TimestampFormat.TraceNs, 'Raw'),
menuItemForFormat(
TimestampFormat.TraceNsLocale,
Expand Down Expand Up @@ -119,6 +121,10 @@ export function renderDuration(dur: duration): string {
return dur.toLocaleString();
case TimestampFormat.Seconds:
return Duration.formatSeconds(dur);
case TimestampFormat.Milliseoncds:
return Duration.formatMilliseconds(dur);
case TimestampFormat.Microseconds:
return Duration.formatMicroseconds(dur);
default:
const x: never = fmt;
throw new Error(`Invalid format ${x}`);
Expand Down
6 changes: 6 additions & 0 deletions ui/src/frontend/widgets/timestamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export class Timestamp implements m.ClassComponent<TimestampAttrs> {
menuItemForFormat(TimestampFormat.UTC, 'Realtime (UTC)'),
menuItemForFormat(TimestampFormat.TraceTz, 'Realtime (Trace TZ)'),
menuItemForFormat(TimestampFormat.Seconds, 'Seconds'),
menuItemForFormat(TimestampFormat.Milliseoncds, 'Milliseconds'),
menuItemForFormat(TimestampFormat.Microseconds, 'Microseconds'),
menuItemForFormat(TimestampFormat.TraceNs, 'Raw'),
menuItemForFormat(
TimestampFormat.TraceNsLocale,
Expand Down Expand Up @@ -115,6 +117,10 @@ function renderTimestamp(time: time): m.Children {
return domainTime.toLocaleString();
case TimestampFormat.Seconds:
return Time.formatSeconds(domainTime);
case TimestampFormat.Milliseoncds:
return Time.formatMilliseconds(domainTime);
case TimestampFormat.Microseconds:
return Time.formatMicroseconds(domainTime);
default:
const x: never = fmt;
throw new Error(`Invalid timestamp ${x}`);
Expand Down

0 comments on commit 1687234

Please sign in to comment.