1+ use std:: collections:: HashMap ;
12use std:: ops:: RangeInclusive ;
23use std:: { f64:: consts:: TAU , sync:: Arc } ;
34
5+ use egui:: mutex:: Mutex ;
46use egui:: {
5- Checkbox , Color32 , ComboBox , NumExt as _, Pos2 , Response , ScrollArea , Stroke , TextWrapMode ,
6- Vec2b , WidgetInfo , WidgetType , remap, vec2,
7+ remap, vec2, Checkbox , Color32 , ComboBox , Id , NumExt as _, Pos2 , Response , ScrollArea , Stroke , TextWrapMode , Vec2b , WidgetInfo , WidgetType
78} ;
89
910use egui_plot:: {
@@ -24,6 +25,7 @@ enum Panel {
2425 Interaction ,
2526 CustomAxes ,
2627 LinkedAxes ,
28+ Userdata ,
2729}
2830
2931impl Default for Panel {
@@ -44,6 +46,7 @@ pub struct PlotDemo {
4446 interaction_demo : InteractionDemo ,
4547 custom_axes_demo : CustomAxesDemo ,
4648 linked_axes_demo : LinkedAxesDemo ,
49+ userdata_demo : UserdataDemo ,
4750 open_panel : Panel ,
4851}
4952
@@ -131,6 +134,7 @@ impl PlotDemo {
131134 ui. selectable_value ( & mut self . open_panel , Panel :: Interaction , "Interaction" ) ;
132135 ui. selectable_value ( & mut self . open_panel , Panel :: CustomAxes , "Custom Axes" ) ;
133136 ui. selectable_value ( & mut self . open_panel , Panel :: LinkedAxes , "Linked Axes" ) ;
137+ ui. selectable_value ( & mut self . open_panel , Panel :: Userdata , "Userdata" ) ;
134138 } ) ;
135139 } ) ;
136140 ui. separator ( ) ;
@@ -160,6 +164,9 @@ impl PlotDemo {
160164 Panel :: LinkedAxes => {
161165 self . linked_axes_demo . ui ( ui) ;
162166 }
167+ Panel :: Userdata => {
168+ self . userdata_demo . ui ( ui) ;
169+ }
163170 }
164171 }
165172}
@@ -636,7 +643,7 @@ impl CustomAxesDemo {
636643 }
637644 } ;
638645
639- let label_fmt = |_s : & str , val : & PlotPoint | {
646+ let label_fmt = |_s : & str , val : & PlotPoint , _ | {
640647 format ! (
641648 "Day {d}, {h}:{m:02}\n {p:.2}%" ,
642649 d = day( val. x) ,
@@ -1191,6 +1198,61 @@ impl ChartsDemo {
11911198 }
11921199}
11931200
1201+ #[ derive( PartialEq , serde:: Deserialize , serde:: Serialize , Default ) ]
1202+ struct UserdataDemo { }
1203+
1204+ struct DemoPoint {
1205+ x : f64 ,
1206+ y : f64 ,
1207+ custom_info : bool ,
1208+ }
1209+
1210+ impl UserdataDemo {
1211+ #[ allow( clippy:: unused_self, clippy:: significant_drop_tightening) ]
1212+ fn ui ( & self , ui : & mut egui:: Ui ) -> Response {
1213+ let points = ( 1 ..=1000 )
1214+ . map ( |i| DemoPoint {
1215+ x : i as f64 / 1000.0 ,
1216+ y : ( ( i as f64 ) / 1000.0 * std:: f64:: consts:: PI * 2.0 ) . sin ( ) ,
1217+ custom_info : i % 2 == 0 ,
1218+ } )
1219+ . collect :: < Vec < _ > > ( ) ;
1220+
1221+
1222+ let custom_things = Arc :: new ( Mutex :: new ( HashMap :: <
1223+ Id ,
1224+ Vec < bool > ,
1225+ > :: new ( ) ) ) ;
1226+
1227+ let custom_things_ = custom_things. clone ( ) ;
1228+ Plot :: new ( "Userdata Plot Demo" )
1229+ . legend ( Legend :: default ( ) )
1230+ . label_formatter ( |_, _, item| {
1231+ format ! (
1232+ "item: {:?}\n custom_thing: {:?}" ,
1233+ item,
1234+ item. and_then( |( id, index) | custom_things_
1235+ . lock( )
1236+ . get( & id)
1237+ . and_then( |vec| vec. get( index) . copied( ) ) )
1238+ )
1239+ } )
1240+ . show ( ui, |plot_ui| {
1241+ let id = Id :: new ( 1234 ) ;
1242+ let mut lock = custom_things. lock ( ) ;
1243+ let entry = lock. entry ( id) . or_default ( ) ;
1244+
1245+ for p in & points {
1246+ entry. push ( p. custom_info ) ;
1247+ }
1248+
1249+ plot_ui
1250+ . line ( Line :: new ( "test" , points. iter ( ) . map ( |p| [ p. x , p. y ] ) . collect :: < Vec < _ > > ( ) ) . id ( id) ) ;
1251+ } )
1252+ . response
1253+ }
1254+ }
1255+
11941256fn is_approx_zero ( val : f64 ) -> bool {
11951257 val. abs ( ) < 1e-6
11961258}
0 commit comments