Skip to content

Commit 1080cfd

Browse files
committed
Add a tooltip to column header with information on the descriptor
1 parent 5f500eb commit 1080cfd

File tree

1 file changed

+112
-41
lines changed

1 file changed

+112
-41
lines changed

crates/viewer/re_dataframe_ui/src/datafusion_table_widget.rs

Lines changed: 112 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -393,48 +393,57 @@ impl egui_table::TableDelegate for DataFusionTableDelegate<'_> {
393393
});
394394

395395
header_ui(ui, |ui| {
396-
egui::Sides::new().show(
397-
ui,
398-
|ui| {
399-
ui.label(egui::RichText::new(name).strong().monospace());
400-
401-
if let Some(dir_icon) = current_sort_direction.map(SortDirection::icon) {
402-
ui.add_space(-5.0);
403-
ui.small_icon(
404-
dir_icon,
405-
Some(
406-
re_ui::design_tokens()
407-
.color(re_ui::ColorToken::blue(re_ui::Scale::S450)),
408-
),
409-
);
410-
}
411-
},
412-
|ui| {
413-
egui::containers::menu::MenuButton::from_button(
414-
ui.small_icon_button_widget(&re_ui::icons::MORE),
415-
)
416-
.ui(ui, |ui| {
417-
for sort_direction in SortDirection::iter() {
418-
let already_sorted =
419-
Some(&sort_direction) == current_sort_direction;
420-
421-
if ui
422-
.add_enabled_ui(!already_sorted, |ui| {
423-
sort_direction.menu_button(ui)
424-
})
425-
.inner
426-
.clicked()
427-
{
428-
self.new_blueprint.sort_by = Some(SortBy {
429-
column: column_name.to_owned(),
430-
direction: sort_direction,
431-
});
432-
ui.close();
433-
}
396+
egui::Sides::new()
397+
.show(
398+
ui,
399+
|ui| {
400+
let response = ui.label(egui::RichText::new(name).strong().monospace());
401+
402+
if let Some(dir_icon) = current_sort_direction.map(SortDirection::icon)
403+
{
404+
ui.add_space(-5.0);
405+
ui.small_icon(
406+
dir_icon,
407+
Some(
408+
re_ui::design_tokens()
409+
.color(re_ui::ColorToken::blue(re_ui::Scale::S450)),
410+
),
411+
);
434412
}
435-
});
436-
},
437-
);
413+
414+
response
415+
},
416+
|ui| {
417+
egui::containers::menu::MenuButton::from_button(
418+
ui.small_icon_button_widget(&re_ui::icons::MORE),
419+
)
420+
.ui(ui, |ui| {
421+
for sort_direction in SortDirection::iter() {
422+
let already_sorted =
423+
Some(&sort_direction) == current_sort_direction;
424+
425+
if ui
426+
.add_enabled_ui(!already_sorted, |ui| {
427+
sort_direction.menu_button(ui)
428+
})
429+
.inner
430+
.clicked()
431+
{
432+
self.new_blueprint.sort_by = Some(SortBy {
433+
column: column_name.to_owned(),
434+
direction: sort_direction,
435+
});
436+
ui.close();
437+
}
438+
}
439+
});
440+
},
441+
)
442+
.0
443+
})
444+
.inner
445+
.on_hover_ui(|ui| {
446+
header_tooltip_ui(ui, desc);
438447
});
439448
}
440449
}
@@ -481,3 +490,65 @@ impl egui_table::TableDelegate for DataFusionTableDelegate<'_> {
481490
re_ui::DesignTokens::table_line_height() + CELL_MARGIN.sum().y
482491
}
483492
}
493+
494+
fn header_tooltip_ui(ui: &mut egui::Ui, column: &ColumnDescriptorRef<'_>) {
495+
match column {
496+
ColumnDescriptorRef::RowId(desc) => {
497+
header_property_ui(ui, "Type", "row id");
498+
header_property_ui(ui, "Sorted", sorted_text(desc.is_sorted));
499+
}
500+
ColumnDescriptorRef::Time(desc) => {
501+
header_property_ui(ui, "Type", "index");
502+
header_property_ui(ui, "Timeline", desc.timeline_name());
503+
header_property_ui(ui, "Sorted", sorted_text(desc.is_sorted()));
504+
datatype_ui(ui, desc.datatype());
505+
}
506+
ColumnDescriptorRef::Component(desc) => {
507+
header_property_ui(ui, "Type", "component");
508+
header_property_ui(ui, "Name", desc.component_name.full_name());
509+
header_property_ui(ui, "Entity path", desc.entity_path.to_string());
510+
datatype_ui(ui, &desc.store_datatype);
511+
header_property_ui(
512+
ui,
513+
"Archetype",
514+
desc.archetype_name.map(|a| a.full_name()).unwrap_or("-"),
515+
);
516+
header_property_ui(
517+
ui,
518+
"Archetype field",
519+
desc.archetype_field_name.map(|a| a.as_str()).unwrap_or("-"),
520+
);
521+
header_property_ui(ui, "Static", format!("{}", desc.is_static));
522+
header_property_ui(ui, "Indicator", format!("{}", desc.is_indicator));
523+
header_property_ui(ui, "Tombstone", format!("{}", desc.is_tombstone));
524+
header_property_ui(ui, "Empty", format!("{}", desc.is_semantically_empty));
525+
}
526+
}
527+
}
528+
529+
fn sorted_text(sorted: bool) -> &'static str {
530+
if sorted {
531+
"true"
532+
} else {
533+
"unknown"
534+
}
535+
}
536+
537+
fn header_property_ui(ui: &mut egui::Ui, label: &str, value: impl AsRef<str>) {
538+
egui::Sides::new().show(ui, |ui| ui.strong(label), |ui| ui.monospace(value.as_ref()));
539+
}
540+
541+
fn datatype_ui(ui: &mut egui::Ui, datatype: &arrow::datatypes::DataType) {
542+
egui::Sides::new().show(
543+
ui,
544+
|ui| ui.strong("Datatype"),
545+
|ui| {
546+
if ui
547+
.button(egui::RichText::new(re_arrow_util::format_data_type(datatype)).monospace())
548+
.clicked()
549+
{
550+
ui.ctx().copy_text(format!("{datatype:#?}"));
551+
}
552+
},
553+
);
554+
}

0 commit comments

Comments
 (0)