Skip to content

Commit 69332a4

Browse files
authored
Session details improvements (#568)
* feat: use hover mode "x unified" in activity plot * fix: update plot tick format * fix: hide plots with one or none data points * feat: go to closest capture on click if interval has no captures
1 parent bbc9195 commit 69332a4

File tree

4 files changed

+51
-40
lines changed

4 files changed

+51
-40
lines changed

ui/src/data-services/models/timeline-tick.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { getCompactTimespanString } from 'utils/date/getCompactTimespanString/getCompactTimespanString'
2-
31
export type ServerTimelineTick = {
42
start: string
53
end: string
@@ -60,16 +58,4 @@ export class TimelineTick {
6058
get representativeCaptureId(): string | undefined {
6159
return this.topCaptureId ?? this.firstCaptureId
6260
}
63-
64-
get tooltip(): string {
65-
const timespanString = getCompactTimespanString({
66-
date1: this.startDate,
67-
date2: this.endDate,
68-
options: {
69-
second: true,
70-
},
71-
})
72-
73-
return `${timespanString}<br>Captures: ${this.numCaptures}<br>Avg. detections: ${this.avgDetections}`
74-
}
7561
}

ui/src/design-system/components/plot/plot.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ const Plot = ({
8181
zeroline: false,
8282
tickvals: data.tickvals,
8383
ticktext: data.ticktext,
84-
tickformat: 'd',
8584
automargin: true,
8685
...(showRangeSlider
8786
? {

ui/src/pages/session-details/playback/activity-plot/activity-plot.tsx

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ import { SessionDetails } from 'data-services/models/session-details'
22
import { TimelineTick } from 'data-services/models/timeline-tick'
33
import { useRef } from 'react'
44
import Plot from 'react-plotly.js'
5+
import { getCompactTimespanString } from 'utils/date/getCompactTimespanString/getCompactTimespanString'
56
import { useDynamicPlotWidth } from './useDynamicPlotWidth'
7+
import { findClosestCaptureId } from '../session-captures-slider/utils'
68

79
const fontFamily = 'Mazzard, sans-serif'
810
const lineColorCaptures = '#4E4F57'
911
const lineColorDetections = '#5F8AC6'
12+
const spikeColor = '#FFFFFF'
1013
const textColor = '#303137'
11-
const tooltipBgColor = '#ffffff'
14+
const tooltipBgColor = '#FFFFFF'
1215
const tooltipBorderColor = '#303137'
13-
const gridLineColor = '#4E4F57'
1416

1517
export const ActivityPlot = ({
1618
session,
@@ -48,8 +50,7 @@ export const ActivityPlot = ({
4850
(timelineTick) => new Date(timelineTick.startDate)
4951
),
5052
y: timeline.map((timelineTick) => timelineTick.numCaptures),
51-
text: timeline.map((timelineTick) => timelineTick.tooltip),
52-
hovertemplate: '%{text}<extra></extra>',
53+
hovertemplate: 'Captures: %{y}<extra></extra>',
5354
fill: 'tozeroy',
5455
type: 'scatter',
5556
mode: 'lines',
@@ -62,8 +63,7 @@ export const ActivityPlot = ({
6263
(timelineTick) => new Date(timelineTick.startDate)
6364
),
6465
y: timeline.map((timelineTick) => timelineTick.avgDetections),
65-
text: timeline.map((timelineTick) => timelineTick.tooltip),
66-
hovertemplate: '%{text}<extra></extra>',
66+
hovertemplate: 'Avg. detections: %{y}<extra></extra>',
6767
fill: 'tozeroy',
6868
type: 'scatter',
6969
mode: 'lines',
@@ -84,6 +84,7 @@ export const ActivityPlot = ({
8484
t: 0,
8585
pad: 0,
8686
},
87+
hovermode: 'x unified',
8788
// y-axis for captures
8889
yaxis: {
8990
showgrid: false,
@@ -106,16 +107,26 @@ export const ActivityPlot = ({
106107
overlaying: 'y',
107108
},
108109
xaxis: {
110+
fixedrange: true,
111+
range: [new Date(session.startDate), new Date(session.endDate)],
112+
showgrid: false,
109113
showline: false,
110-
showgrid: true,
111-
griddash: 'dot',
112-
gridwidth: 1,
113-
gridcolor: gridLineColor,
114114
showticklabels: false,
115+
spikecolor: spikeColor,
116+
spikethickness: -2,
117+
ticktext: timeline.map((timelineTick) =>
118+
getCompactTimespanString({
119+
date1: timelineTick.startDate,
120+
date2: timelineTick.endDate,
121+
options: {
122+
second: true,
123+
},
124+
})
125+
),
126+
tickvals: timeline.map(
127+
(timelineTick) => new Date(timelineTick.startDate)
128+
),
115129
zeroline: false,
116-
fixedrange: true,
117-
range: [new Date(session.startDate), new Date(session.endDate)],
118-
dtick: 3600000, // milliseconds in an hour
119130
},
120131
hoverlabel: {
121132
bgcolor: tooltipBgColor,
@@ -134,8 +145,17 @@ export const ActivityPlot = ({
134145
onClick={(data) => {
135146
const timelineTickIndex = data.points[0].pointIndex
136147
const timelineTick = timeline[timelineTickIndex]
137-
if (timelineTick?.representativeCaptureId) {
138-
setActiveCaptureId(timelineTick.representativeCaptureId)
148+
149+
if (!timelineTick) {
150+
return
151+
}
152+
153+
const captureId =
154+
timelineTick.representativeCaptureId ??
155+
findClosestCaptureId(timeline, timelineTick.startDate)
156+
157+
if (captureId) {
158+
setActiveCaptureId(captureId)
139159
}
140160
}}
141161
/>

ui/src/pages/session-details/session-details.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,22 @@ export const SessionDetails = () => {
6060
<SessionInfo session={session} />
6161
</div>
6262
</Box>
63-
{session.summaryData.map((summary, index) => (
64-
<Box key={index}>
65-
<Plot
66-
title={summary.title}
67-
data={summary.data}
68-
orientation={summary.orientation}
69-
type={summary.type}
70-
/>
71-
</Box>
72-
))}
63+
{session.summaryData.map((summary, index) => {
64+
if (summary.data.x.length <= 1) {
65+
return null
66+
}
67+
68+
return (
69+
<Box key={index}>
70+
<Plot
71+
title={summary.title}
72+
data={summary.data}
73+
orientation={summary.orientation}
74+
type={summary.type}
75+
/>
76+
</Box>
77+
)
78+
})}
7379
</PlotGrid>
7480
</div>
7581
)

0 commit comments

Comments
 (0)