Hover CPU slices
Tracks get optional onMouseMove and onMouseOut methods which are called
with track-specific event coordinates from the TrackComponent.
The CpuSliceTrack uses these coordinates to find and highlight the
currently hovered slice.
Screenshot: https://screenshot.googleplex.com/yzNOmJqpnBp
Change-Id: Ibf67646607e3a1a5b8744d0e3e2738d8c0f68031
diff --git a/ui/src/frontend/track.ts b/ui/src/frontend/track.ts
index 14a42fe..aaad16b 100644
--- a/ui/src/frontend/track.ts
+++ b/ui/src/frontend/track.ts
@@ -45,4 +45,6 @@
abstract renderCanvas(
ctx: CanvasRenderingContext2D, timeScale: TimeScale,
visibleWindowMs: {start: number, end: number}): void;
+ onMouseMove(_position: {x: number, y: number}) {}
+ onMouseOut() {}
}
diff --git a/ui/src/frontend/track_component.ts b/ui/src/frontend/track_component.ts
index fad2a9b..ef9e90f 100644
--- a/ui/src/frontend/track_component.ts
+++ b/ui/src/frontend/track_component.ts
@@ -163,6 +163,13 @@
}))),
m('.track-content',
{
+ onmousemove: (e: MouseEvent) => {
+ // TODO(hjd): Trigger a repaint here not a full m.redraw.
+ this.track.onMouseMove({x: e.layerX, y: e.layerY});
+ },
+ onmouseout: () => {
+ this.track.onMouseOut();
+ },
style: {
width: `calc(100% - ${TRACK_SHELL_WIDTH}px)`,
left: `${TRACK_SHELL_WIDTH}px`,
diff --git a/ui/src/tracks/cpu_slices/common.ts b/ui/src/tracks/cpu_slices/common.ts
index d2b0a4b..c67b3c5 100644
--- a/ui/src/tracks/cpu_slices/common.ts
+++ b/ui/src/tracks/cpu_slices/common.ts
@@ -14,7 +14,7 @@
export const TRACK_KIND = 'CpuSliceTrack';
-interface CpuSlice {
+export interface CpuSlice {
start: number;
end: number;
title: string;
diff --git a/ui/src/tracks/cpu_slices/frontend.ts b/ui/src/tracks/cpu_slices/frontend.ts
index 1671a1e..97c4d22 100644
--- a/ui/src/tracks/cpu_slices/frontend.ts
+++ b/ui/src/tracks/cpu_slices/frontend.ts
@@ -16,7 +16,7 @@
import {TimeScale} from '../../frontend/time_scale';
import {Track} from '../../frontend/track';
import {trackRegistry} from '../../frontend/track_registry';
-import {CpuSliceTrackData, TRACK_KIND} from './common';
+import {CpuSlice, CpuSliceTrackData, TRACK_KIND} from './common';
function sliceIsVisible(
slice: {start: number, end: number},
@@ -31,6 +31,8 @@
}
private trackData: CpuSliceTrackData|undefined;
+ private timeScale: TimeScale|undefined;
+ private hoveredSlice: CpuSlice|null = null;
constructor(trackState: TrackState) {
super(trackState);
@@ -48,9 +50,30 @@
if (!sliceIsVisible(slice, visibleWindowMs)) continue;
const rectStart = timeScale.msToPx(slice.start);
const rectEnd = timeScale.msToPx(slice.end);
- ctx.fillStyle = '#4682b4';
+ ctx.fillStyle = slice === this.hoveredSlice ? '#b35846' : '#4682b4';
ctx.fillRect(rectStart, 40, rectEnd - rectStart, 30);
}
+ this.timeScale = timeScale;
+ }
+
+ onMouseMove({x, y}: {x: number, y: number}) {
+ if (!this.trackData || !this.timeScale) return;
+ if (y < 40 || y > 70) {
+ this.hoveredSlice = null;
+ return;
+ }
+ const xMs = this.timeScale.pxToMs(x);
+ this.hoveredSlice = null;
+
+ for (const slice of this.trackData.slices) {
+ if (slice.start <= xMs && slice.end >= xMs) {
+ this.hoveredSlice = slice;
+ }
+ }
+ }
+
+ onMouseOut() {
+ this.hoveredSlice = null;
}
}