mirror of
https://github.com/wassname/optuna-dashboard.git
synced 2026-09-09 11:28:14 +08:00
Merge pull request #731 from nabenabe0928/bug-fix/make-running-trials-in-timeline-plot-visible
Make running trials in timeline plot visible
This commit is contained in:
@@ -56,6 +56,7 @@ const plotTimeline = (trials: Trial[], mode: string) => {
|
||||
Running: "green",
|
||||
Waiting: "gray",
|
||||
}
|
||||
const runningKey = "Running"
|
||||
|
||||
const lastTrials = trials.slice(-maxBars) // To only show last elements
|
||||
const minDatetime = new Date(
|
||||
@@ -65,13 +66,38 @@ const plotTimeline = (trials: Trial[], mode: string) => {
|
||||
)
|
||||
)
|
||||
)
|
||||
const maxDatetime = new Date(
|
||||
Math.max(
|
||||
...lastTrials.map(
|
||||
(t) => t.datetime_start?.getTime() ?? minDatetime.getTime()
|
||||
)
|
||||
)
|
||||
const maxRunDuration = Math.max(
|
||||
...trials.map((t) => {
|
||||
return t.datetime_start === undefined || t.datetime_complete === undefined
|
||||
? -Infinity
|
||||
: t.datetime_complete.getTime() - t.datetime_start.getTime()
|
||||
})
|
||||
)
|
||||
const hasRunning =
|
||||
(maxRunDuration === -Infinity &&
|
||||
trials.some((t) => t.state === runningKey)) ||
|
||||
trials.some((t) => {
|
||||
if (t.state !== runningKey) {
|
||||
return false
|
||||
}
|
||||
const now = new Date().getTime()
|
||||
const start = t.datetime_start?.getTime() ?? now
|
||||
// This is an ad-hoc handling to check if the trial is running.
|
||||
// We do not check via `trialState` because some trials may have state=RUNNING,
|
||||
// even if they are not running because of unexpected job kills.
|
||||
// In this case, we would like to ensure that these trials will not squash the timeline plot
|
||||
// for the other trials.
|
||||
return now - start < maxRunDuration * 5
|
||||
})
|
||||
const maxDatetime = hasRunning
|
||||
? new Date()
|
||||
: new Date(
|
||||
Math.max(
|
||||
...lastTrials.map(
|
||||
(t) => t.datetime_complete?.getTime() ?? minDatetime.getTime()
|
||||
)
|
||||
)
|
||||
)
|
||||
const layout: Partial<plotly.Layout> = {
|
||||
margin: {
|
||||
l: 50,
|
||||
@@ -93,11 +119,20 @@ const plotTimeline = (trials: Trial[], mode: string) => {
|
||||
}
|
||||
|
||||
const makeTrace = (bars: Trial[], state: string, color: string) => {
|
||||
const starts = bars.map((b) => b.datetime_start ?? new Date())
|
||||
const completes = bars.map((b, i) => b.datetime_complete ?? starts[i])
|
||||
const isRunning = state === runningKey
|
||||
// Waiting trials should not squash other trials, so use `maxDatetime` instead of `new Date()`.
|
||||
const starts = bars.map((b) => b.datetime_start ?? maxDatetime)
|
||||
const runDurations = bars.map((b, i) => {
|
||||
const startTime = starts[i].getTime()
|
||||
const completeTime = isRunning
|
||||
? maxDatetime.getTime()
|
||||
: b.datetime_complete?.getTime() ?? startTime
|
||||
// By using 1 as the min value, we can recognize these bars at least when zooming in.
|
||||
return Math.max(1, completeTime - startTime)
|
||||
})
|
||||
const trace: Partial<plotly.PlotData> = {
|
||||
type: "bar",
|
||||
x: starts.map((s, i) => completes[i].getTime() - s.getTime()),
|
||||
x: runDurations,
|
||||
y: bars.map((b) => b.number),
|
||||
// @ts-ignore: To suppress ts(2322)
|
||||
base: starts.map((s) => s.toISOString()),
|
||||
|
||||
Reference in New Issue
Block a user