Skip to content

Commit a1c86ec

Browse files
committed
ui: delineat last counter sample in the trace
Use a gradiient + dashed line to indicate the last sample. This allows making clear that the last sample didn't have any further data and *not* that we know the sample had this value until the end of the trace
1 parent e43ef41 commit a1c86ec

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

ui/src/components/tracks/base_counter_track.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ export abstract class BaseCounterTrack implements TrackRenderer {
814814
const timestamp = Time.fromRaw(timestamps[0]);
815815
ctx.moveTo(Math.max(0, calculateX(timestamp)), zeroY);
816816
let lastDrawnY = zeroY;
817+
let lastX = 0;
817818
for (let i = 0; i < timestamps.length; i++) {
818819
const timestamp = Time.fromRaw(timestamps[i]);
819820
const x = Math.max(0, calculateX(timestamp));
@@ -831,12 +832,45 @@ export abstract class BaseCounterTrack implements TrackRenderer {
831832
ctx.lineTo(x, lastY);
832833
}
833834
lastDrawnY = lastY;
835+
lastX = x;
834836
}
835-
ctx.lineTo(endPx, lastDrawnY);
836-
ctx.lineTo(endPx, zeroY);
837+
838+
// Draw the main shape (without extension)
839+
// We need to stroke before closing the path to avoid stroking the vertical
840+
// line at lastX
841+
ctx.lineTo(lastX, lastDrawnY);
842+
ctx.stroke();
843+
844+
// Now close the fill without stroking
845+
ctx.lineTo(lastX, zeroY);
837846
ctx.closePath();
838847
ctx.fill();
839-
ctx.stroke();
848+
849+
// Draw fade-out from last sample to edge
850+
if (endPx > lastX) {
851+
// Gradient fill for fade-out (no vertical line at lastX)
852+
const gradient = ctx.createLinearGradient(lastX, 0, endPx, 0);
853+
gradient.addColorStop(0, `hsla(${hue}, 45%, 50%, 0.6)`);
854+
gradient.addColorStop(1, `hsla(${hue}, 45%, 50%, 0)`);
855+
856+
ctx.fillStyle = gradient;
857+
ctx.beginPath();
858+
ctx.moveTo(lastX, lastDrawnY);
859+
ctx.lineTo(endPx, lastDrawnY);
860+
ctx.lineTo(endPx, zeroY);
861+
ctx.lineTo(lastX, zeroY);
862+
ctx.closePath();
863+
ctx.fill();
864+
865+
// Dashed line
866+
ctx.strokeStyle = `hsl(${hue}, 10%, 71%)`;
867+
ctx.setLineDash([4, 4]);
868+
ctx.beginPath();
869+
ctx.moveTo(lastX, lastDrawnY);
870+
ctx.lineTo(endPx, lastDrawnY);
871+
ctx.stroke();
872+
ctx.setLineDash([]);
873+
}
840874

841875
if (yMin < 0 && yMax > 0) {
842876
// Draw the Y=0 dashed line.
@@ -874,7 +908,11 @@ export abstract class BaseCounterTrack implements TrackRenderer {
874908
ctx.moveTo(xStart, y);
875909
ctx.lineTo(xEnd, y);
876910
ctx.lineWidth = 3;
911+
if (hover.tsEnd === undefined) {
912+
ctx.setLineDash([4, 4]);
913+
}
877914
ctx.stroke();
915+
ctx.setLineDash([]);
878916
ctx.lineWidth = 1;
879917

880918
// Draw change marker if it would be visible.

ui/src/plugins/dev.perfetto.TraceProcessorTrack/counter_details_panel.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,12 @@ async function loadCounterDetails(
188188
});
189189
const value = row.value;
190190
const leftTs = Time.fromRaw(row.leftTs);
191-
const rightTs = row.rightTs !== null ? Time.fromRaw(row.rightTs) : leftTs;
192191
const prevValue = row.prevValue !== null ? row.prevValue : value;
193192

194193
const delta = value - prevValue;
195-
const duration = rightTs - leftTs;
194+
// If there's no next event, duration is -1 (no more events)
195+
const duration =
196+
row.rightTs !== null ? Time.fromRaw(row.rightTs) - leftTs : -1n;
196197
const argSetId = row.argSetId;
197198
const args =
198199
argSetId == null ? undefined : await getArgs(engine, asArgSetId(argSetId));

0 commit comments

Comments
 (0)