Add a public API for overriding plot legend traces' visibilities (#3534)

Added a public API in `egui_plot -> legend` to allow `hidden_items` to
be overridden in the plot legend widget. This allows convenient control
of traces' visibilities the selection of traces from the application
code.

### Example
```rust
    let legend_config = if plot_selection_changed {
        let hidden_items = match plot_selection {
            PlotSelection::SelectAll => Vec::new(),
            PlotSelection::DeselectAll => all_trace_names,
        };

        Legend::default()
            .position(Corner::RightTop)
            .hidden_items(hidden_items) // Overrides `hidden_items`
    } else {
        Legend::default().position(Corner::RightTop)
    };

    Plot::new(id)
        .legend(legend_config)
        .show(ui, draw_plot);
```

Closes <https://github.com/emilk/egui/issues/3533>.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
jayzhudev 2024-01-06 14:35:54 -07:00 committed by GitHub
parent 5ed2c0aa90
commit e13cc69d76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 1 deletions

View File

@ -32,6 +32,9 @@ pub struct Legend {
pub text_style: TextStyle, pub text_style: TextStyle,
pub background_alpha: f32, pub background_alpha: f32,
pub position: Corner, pub position: Corner,
/// Used for overriding the `hidden_items` set in [`LegendWidget`].
hidden_items: Option<ahash::HashSet<String>>,
} }
impl Default for Legend { impl Default for Legend {
@ -40,6 +43,8 @@ impl Default for Legend {
text_style: TextStyle::Body, text_style: TextStyle::Body,
background_alpha: 0.75, background_alpha: 0.75,
position: Corner::RightTop, position: Corner::RightTop,
hidden_items: None,
} }
} }
} }
@ -65,6 +70,17 @@ impl Legend {
self.position = corner; self.position = corner;
self self
} }
/// Specifies hidden items in the legend configuration to override the existing ones. This
/// allows the legend traces' visibility to be controlled from the application code.
#[inline]
pub fn hidden_items<I>(mut self, hidden_items: I) -> Self
where
I: IntoIterator<Item = String>,
{
self.hidden_items = Some(hidden_items.into_iter().collect());
self
}
} }
#[derive(Clone)] #[derive(Clone)]
@ -167,8 +183,11 @@ impl LegendWidget {
rect: Rect, rect: Rect,
config: Legend, config: Legend,
items: &[Box<dyn PlotItem>], items: &[Box<dyn PlotItem>],
hidden_items: &ahash::HashSet<String>, hidden_items: &ahash::HashSet<String>, // Existing hiddent items in the plot memory.
) -> Option<Self> { ) -> Option<Self> {
// If `config.hidden_items` is not `None`, it is used.
let hidden_items = config.hidden_items.as_ref().unwrap_or(hidden_items);
// Collect the legend entries. If multiple items have the same name, they share a // Collect the legend entries. If multiple items have the same name, they share a
// checkbox. If their colors don't match, we pick a neutral color for the checkbox. // checkbox. If their colors don't match, we pick a neutral color for the checkbox.
let mut entries: BTreeMap<String, LegendEntry> = BTreeMap::new(); let mut entries: BTreeMap<String, LegendEntry> = BTreeMap::new();