@@ -27,9 +27,11 @@ use crate::Axis;
2727use crate :: utils:: find_name_candidate;
2828
2929/// Padding between the label of the span and both the edge of the view and the
30- /// span borders. For example, for a horizontal span, this is the padding
31- /// between the top of the span label and the top edge of the plot view, but
32- /// also the margin between the left/right edges of the span and the span label.
30+ /// span borders.
31+ ///
32+ /// For example, for a horizontal span, this is the padding between the top of the span
33+ /// label and the top edge of the plot view, but also the margin between the left/right
34+ /// edges of the span and the span label.
3335const LABEL_PADDING : f32 = 4.0 ;
3436
3537/// A span covering a range on either axis.
@@ -238,45 +240,52 @@ impl Span {
238240
239241impl PlotItem for Span {
240242 fn shapes ( & self , ui : & Ui , transform : & PlotTransform , shapes : & mut Vec < Shape > ) {
243+ let plot_bounds = match self . axis {
244+ Axis :: X => transform. bounds ( ) . range_x ( ) ,
245+ Axis :: Y => transform. bounds ( ) . range_y ( ) ,
246+ } ;
247+
241248 let ( range_min, range_max) = self . range_sorted ( ) ;
242249
250+ // If the span is outside of the visible range, don't draw anything.
251+ if range_max < * plot_bounds. start ( ) || range_min > * plot_bounds. end ( ) {
252+ return ;
253+ }
254+
243255 let mut stroke = self . border_stroke ;
244256 let mut fill = self . fill ;
245257 if self . base . highlight {
246258 ( stroke, fill) = highlighted_color ( stroke, fill) ;
247259 }
248260
249- let range_min = range_min. clamp (
250- transform. bounds ( ) . min [ self . axis as usize ] ,
251- transform. bounds ( ) . max [ self . axis as usize ] ,
252- ) ;
253- let range_max = range_max. clamp (
254- transform. bounds ( ) . min [ self . axis as usize ] ,
255- transform. bounds ( ) . max [ self . axis as usize ] ,
256- ) ;
261+ // Clamp the range to support (half-)infinite spans
262+ let range_min_clamped = range_min. max ( * plot_bounds. start ( ) ) ;
263+ let range_max_clamped = range_max. min ( * plot_bounds. end ( ) ) ;
257264
265+ // Draw the rect first with the clamped range
258266 let span_rect = match self . axis {
259267 Axis :: X => transform. rect_from_values (
260- & PlotPoint :: new ( range_min , transform. bounds ( ) . min [ 1 ] ) ,
261- & PlotPoint :: new ( range_max , transform. bounds ( ) . max [ 1 ] ) ,
268+ & PlotPoint :: new ( range_min_clamped , transform. bounds ( ) . min [ 1 ] ) ,
269+ & PlotPoint :: new ( range_max_clamped , transform. bounds ( ) . max [ 1 ] ) ,
262270 ) ,
263271 Axis :: Y => transform. rect_from_values (
264- & PlotPoint :: new ( transform. bounds ( ) . min [ 0 ] , range_min ) ,
265- & PlotPoint :: new ( transform. bounds ( ) . max [ 0 ] , range_max ) ,
272+ & PlotPoint :: new ( transform. bounds ( ) . min [ 0 ] , range_min_clamped ) ,
273+ & PlotPoint :: new ( transform. bounds ( ) . max [ 0 ] , range_max_clamped ) ,
266274 ) ,
267275 } ;
268276
269277 if fill != Color32 :: TRANSPARENT && span_rect. is_positive ( ) {
270278 shapes. push ( Shape :: rect_filled ( span_rect, 0.0 , fill) ) ;
271279 }
272280
273- let mut border_values = vec ! [ range_min , range_max ] ;
274- if ( range_max - range_min) . abs ( ) <= f64 :: EPSILON {
275- border_values . truncate ( 1 ) ;
281+ // Draw the first border if it is in bounds
282+ if plot_bounds . contains ( & range_min) {
283+ self . draw_border ( range_min , stroke , transform , shapes ) ;
276284 }
277285
278- for value in border_values {
279- self . draw_border ( value, stroke, transform, shapes) ;
286+ // Draw the second border if it is in bounds
287+ if plot_bounds. contains ( & range_max) {
288+ self . draw_border ( range_max, stroke, transform, shapes) ;
280289 }
281290
282291 self . draw_name ( ui, transform, shapes, & span_rect) ;
0 commit comments