GPUI Box GitHub

Components / display

SpanTimeline builder

The waterfall alone: bars and a time axis, with each span named at its own bar instead of in a gutter.

A builder is RenderOnce. Construct and mount it in one expression.

use gpui_kit::display::trace::SpanTimeline;

Reviewed in trace trace-time.

Construct
new(ident: impl Into<Ident>, label: impl Into<SharedString>) -> Self
Options

Chain onto the value.

spans(spans: impl IntoIterator<Item = TraceSpan>) -> Self
shared_spans(spans: Rc<Vec<TraceSpan>>) -> Self
time_viewport(domain: [f64; 2]) -> Result<Self, ScaleError>
animate_viewport(animate: bool) -> Self
animate_layout(animate: bool) -> Self
layout_animation(spec: motion::MotionSpec) -> Self
selected_time(value: Option<[f64; 2]>) -> Result<Self, crate::interaction::range::RangeError>
on_time_selection(handler: impl Fn(crate::interaction::range::RangeEvent, &mut Window, &mut App) + 'static) -> Self
format_time(format: impl Fn(f64) -> SharedString + 'static) -> Self
on_viewport(handler: impl Fn(NumericScale, &mut Window, &mut App) + 'static) -> Self
collapsed(ids: impl IntoIterator<Item = SharedString>) -> Self
on_toggle(handler: impl Fn(SharedString, bool, &mut Window, &mut App) + 'static) -> Self
visible_rows(count: usize) -> Self
axis(start: impl Into<SharedString>, end: impl Into<SharedString>) -> Self
ticks<S: Into<SharedString>>(ticks: impl IntoIterator<Item = (f32, S)>) -> Self
current(id: impl Into<SharedString>) -> Self
on_select(handler: impl Fn(SharedString, &mut Window, &mut App) + 'static) -> Self
Example · trace
fn trace(_window: &mut Window, cx: &mut App) -> AnyElement {
    let theme = cx.theme().clone();
    let spans = [
        TraceSpan::new("plan", "Plan", 0.00, 0.18)
            .state(SpanState::Succeeded)
            .duration("216 ms")
            .detail("planner.finish"),
        TraceSpan::new("generate", "Generate", 0.18, 0.62)
            .depth(1)
            .state(SpanState::Running)
            .duration("528 ms")
            .detail("model.reply"),
        TraceSpan::new("tool", "Search", 0.40, 0.55)
            .depth(2)
            .duration("180 ms")
            .state(SpanState::Succeeded),
        TraceSpan::new("wait", "Review", 0.62, 0.80)
            .depth(1)
            .duration("216 ms")
            .state(SpanState::Pending),
        TraceSpan::new("fail", "Publish", 0.80, 1.00)
            .duration("240 ms")
            .state(SpanState::Failed),
    ];
    // The host owns every reading on the axis; the component only places them.
    let ticks = [(0.25, "300 ms"), (0.5, "600 ms"), (0.75, "900 ms")];
    stack(&theme)
        .w(px(640.0))
        .child(caption(
            &theme,
            "normalized intervals, host-owned labels, a refusal stays a failure",
        ))
        .child(
            TraceView::new("scene.trace.view", "Fixture run")
                .spans(spans.clone())
                .axis("0 ms", "1.2 s")
                .ticks(ticks)
                .current("generate")
                .on_select(|_, _, _| {}),
        )
        .child(
            SpanTimeline::new("scene.trace.timeline", "Fixture waterfall")
                .spans(spans)
                .axis("0 ms", "1.2 s")
                .ticks(ticks)
                .current("generate")
                .on_select(|_, _, _| {}),
        )
        .into_any_element()
}

Source: crates/gpui-kit/src/display/trace.rs