Skip to content

Commit

Permalink
Add insertion_order and color_conflict_handling to Legend
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Sep 15, 2024
1 parent 0fe0ea6 commit 11a1d63
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 12 deletions.
63 changes: 52 additions & 11 deletions egui_plot/src/legend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ impl Corner {
}
}

/// How to handle multiple conflicting color for a legend item.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ColorConflictHandling {
PickFirst,
PickLast,
RemoveColor,
}

/// The configuration for a plot legend.
#[derive(Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
Expand All @@ -38,6 +47,9 @@ pub struct Legend {
pub background_alpha: f32,
pub position: Corner,

insertion_order: bool,
color_conflict_handling: ColorConflictHandling,

/// Used for overriding the `hidden_items` set in [`LegendWidget`].
hidden_items: Option<ahash::HashSet<String>>,
}
Expand All @@ -48,7 +60,8 @@ impl Default for Legend {
text_style: TextStyle::Body,
background_alpha: 0.75,
position: Corner::RightTop,

insertion_order: false,
color_conflict_handling: ColorConflictHandling::RemoveColor,
hidden_items: None,
}
}
Expand Down Expand Up @@ -86,6 +99,23 @@ impl Legend {
self.hidden_items = Some(hidden_items.into_iter().collect());
self
}

/// Specifies if the legend item order should be the inserted order.
#[inline]
pub fn insertion_order(mut self, insertion_order: bool) -> Self {
self.insertion_order = insertion_order;
self
}

/// Specifies how to handle conflicting colors for an item.
#[inline]
pub fn color_conflict_handling(
mut self,
color_conflict_handling: ColorConflictHandling,
) -> Self {
self.color_conflict_handling = color_conflict_handling;
self
}
}

#[derive(Clone)]
Expand Down Expand Up @@ -180,7 +210,7 @@ impl LegendEntry {
#[derive(Clone)]
pub(super) struct LegendWidget {
rect: Rect,
entries: BTreeMap<String, LegendEntry>,
entries: Vec<(String, LegendEntry)>,
config: Legend,
}

Expand All @@ -198,17 +228,31 @@ impl LegendWidget {

// 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.
let mut entries: BTreeMap<String, LegendEntry> = BTreeMap::new();
let mut keys: BTreeMap<String, usize> = BTreeMap::new();
let mut entries: BTreeMap<(usize, String), LegendEntry> = BTreeMap::new();
items
.iter()
.filter(|item| !item.name().is_empty())
.for_each(|item| {
let next_entry = entries.len();
let key = if config.insertion_order {
*keys.entry(item.name().to_owned()).or_insert(next_entry)
} else {
// Use the same key if we don't want insertion order
0
};
entries
.entry(item.name().to_owned())
.entry((key, item.name().to_owned()))
.and_modify(|entry| {
if entry.color != item.color() {
// Multiple items with different colors
entry.color = Color32::TRANSPARENT;
match config.color_conflict_handling {
ColorConflictHandling::PickFirst => (),
ColorConflictHandling::PickLast => entry.color = item.color(),
ColorConflictHandling::RemoveColor => {
// Multiple items with different colors
entry.color = Color32::TRANSPARENT;
}
}
}
})
.or_insert_with(|| {
Expand All @@ -219,7 +263,7 @@ impl LegendWidget {
});
(!entries.is_empty()).then_some(Self {
rect,
entries,
entries: entries.into_iter().map(|((_, k), v)| (k, v)).collect(),
config,
})
}
Expand Down Expand Up @@ -313,10 +357,7 @@ fn handle_interaction_on_legend_item(response: &Response, entry: &mut LegendEntr
}

/// Handle alt-click interaction (which may affect all entries).
fn handle_focus_on_legend_item(
clicked_entry_name: &str,
entries: &mut BTreeMap<String, LegendEntry>,
) {
fn handle_focus_on_legend_item(clicked_entry_name: &str, entries: &mut [(String, LegendEntry)]) {
// if all other items are already hidden, we show everything
let is_focus_item_only_visible = entries
.iter()
Expand Down
2 changes: 1 addition & 1 deletion egui_plot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub use crate::{
MarkerShape, Orientation, PlotConfig, PlotGeometry, PlotImage, PlotItem, PlotPoint,
PlotPoints, Points, Polygon, Text, VLine,
},
legend::{Corner, Legend},
legend::{ColorConflictHandling, Corner, Legend},
memory::PlotMemory,
plot_ui::PlotUi,
transform::{PlotBounds, PlotTransform},
Expand Down

0 comments on commit 11a1d63

Please sign in to comment.