@@ -156,6 +156,7 @@ pub struct Plot<'a> {
156156 center_axis : Vec2b ,
157157 allow_zoom : Vec2b ,
158158 allow_drag : Vec2b ,
159+ allow_axis_zoom_drag : Vec2b ,
159160 allow_scroll : Vec2b ,
160161 allow_double_click_reset : bool ,
161162 allow_boxed_zoom : bool ,
@@ -203,6 +204,7 @@ impl<'a> Plot<'a> {
203204 center_axis : false . into ( ) ,
204205 allow_zoom : true . into ( ) ,
205206 allow_drag : true . into ( ) ,
207+ allow_axis_zoom_drag : false . into ( ) ,
206208 allow_scroll : true . into ( ) ,
207209 allow_double_click_reset : true ,
208210 allow_boxed_zoom : true ,
@@ -388,6 +390,16 @@ impl<'a> Plot<'a> {
388390 self
389391 }
390392
393+ /// Whether to allow dragging in the axis areas to automaticall zoom the plot. Default: `true`.
394+ #[ inline]
395+ pub fn allow_axis_zoom_drag < T > ( mut self , on : T ) -> Self
396+ where
397+ T : Into < Vec2b > ,
398+ {
399+ self . allow_axis_zoom_drag = on. into ( ) ;
400+ self
401+ }
402+
391403 /// Provide a function to customize the on-hover label for the x and y axis
392404 ///
393405 /// ```
@@ -777,6 +789,7 @@ impl<'a> Plot<'a> {
777789 center_axis,
778790 allow_zoom,
779791 allow_drag,
792+ allow_axis_zoom_drag,
780793 allow_scroll,
781794 allow_double_click_reset,
782795 allow_boxed_zoom,
@@ -863,6 +876,31 @@ impl<'a> Plot<'a> {
863876 // Allocate the plot window.
864877 let response = ui. allocate_rect ( plot_rect, sense) ;
865878
879+ let x_axis_responses = x_axis_widgets
880+ . iter ( )
881+ . map ( |widget| {
882+ let axis_response = ui. allocate_rect ( widget. rect , Sense :: drag ( ) ) ;
883+ if allow_axis_zoom_drag. x {
884+ axis_response. on_hover_cursor ( CursorIcon :: ResizeHorizontal )
885+ } else {
886+ axis_response
887+ }
888+ } )
889+ . collect :: < Vec < _ > > ( ) ;
890+
891+ let y_axis_responses = y_axis_widgets
892+ . iter ( )
893+ . map ( |widget| {
894+ let axis_response = ui. allocate_rect ( widget. rect , Sense :: drag ( ) ) ;
895+
896+ if allow_axis_zoom_drag. y {
897+ axis_response. on_hover_cursor ( CursorIcon :: ResizeVertical )
898+ } else {
899+ axis_response
900+ }
901+ } )
902+ . collect :: < Vec < _ > > ( ) ;
903+
866904 // Load or initialize the memory.
867905 ui. ctx ( ) . check_for_id_clash ( plot_id, plot_rect, "Plot" ) ;
868906
@@ -1081,6 +1119,50 @@ impl<'a> Plot<'a> {
10811119 . translate_bounds ( ( delta. x as f64 , delta. y as f64 ) ) ;
10821120 mem. auto_bounds = mem. auto_bounds . and ( !allow_drag) ;
10831121 }
1122+ // Axis zoom dragging
1123+ if allow_axis_zoom_drag. x
1124+ && x_axis_responses
1125+ . iter ( )
1126+ . any ( |r| r. dragged_by ( PointerButton :: Primary ) )
1127+ {
1128+ let axis_response = x_axis_responses
1129+ . iter ( )
1130+ . find ( |r| r. dragged_by ( PointerButton :: Primary ) )
1131+ . expect ( "One x-axis response should be dragged" ) ;
1132+
1133+ if let Some ( _hover_pos) = axis_response. hover_pos ( ) {
1134+ let delta = axis_response. drag_delta ( ) ;
1135+ let mut zoom = delta. clamp ( Vec2 :: splat ( -10.0 ) , Vec2 :: splat ( 10.0 ) ) / 10.0 ;
1136+ zoom. x += 1.0 ;
1137+ zoom. y = 1.0 ;
1138+ if zoom. x != 1.0 {
1139+ mem. transform . zoom ( zoom, plot_rect. center ( ) ) ;
1140+ mem. auto_bounds = false . into ( ) ;
1141+ }
1142+ }
1143+ }
1144+
1145+ if allow_axis_zoom_drag. y
1146+ && y_axis_responses
1147+ . iter ( )
1148+ . any ( |r| r. dragged_by ( PointerButton :: Primary ) )
1149+ {
1150+ let axis_response = y_axis_responses
1151+ . iter ( )
1152+ . find ( |r| r. dragged_by ( PointerButton :: Primary ) )
1153+ . expect ( "One y-axis response should be dragged" ) ;
1154+
1155+ if let Some ( _hover_pos) = axis_response. hover_pos ( ) {
1156+ let delta = axis_response. drag_delta ( ) ;
1157+ let mut zoom = delta. clamp ( Vec2 :: splat ( -10.0 ) , Vec2 :: splat ( 10.0 ) ) / 10.0 ;
1158+ zoom. x = 1.0 ;
1159+ zoom. y += 1.0 ;
1160+ if zoom. y != 1.0 {
1161+ mem. transform . zoom ( zoom, plot_rect. center ( ) ) ;
1162+ mem. auto_bounds = false . into ( ) ;
1163+ }
1164+ }
1165+ }
10841166
10851167 // Zooming
10861168 let mut boxed_zoom_rect = None ;
0 commit comments