From c36c2fab306b3f9c6c120d7d9e5d6eabee569cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Thebault?= Date: Thu, 7 May 2026 18:42:20 +0200 Subject: [PATCH] custom ticks locator --- examples/gauss.rs | 4 +++- src/des/axis.rs | 24 ++++++++++++++++++++++++ src/drawing/ticks.rs | 3 ++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/examples/gauss.rs b/examples/gauss.rs index 1d40331..b6adc71 100644 --- a/examples/gauss.rs +++ b/examples/gauss.rs @@ -29,9 +29,11 @@ fn main() { let title: des::figure::Title = format!("Normal distribution (\u{03bc}={}, \u{03c3}={})", MU, SIGMA).into(); + let ticks = vec![5.0, 9.0, 11.0, 13.0, 15.0, 17.0, 21.0]; + let x_axis = des::Axis::new() .with_title("x".into()) - .with_ticks(Default::default()); + .with_ticks(des::axis::Ticks::new().with_locator(ticks.into())); let y_axis = des::Axis::new().with_title("y".into()).with_ticks( des::axis::Ticks::new() .with_formatter(Some(des::axis::ticks::PercentFormatter::default().into())), diff --git a/src/des/axis.rs b/src/des/axis.rs index 27f5d5c..8b8ccad 100644 --- a/src/des/axis.rs +++ b/src/des/axis.rs @@ -385,6 +385,8 @@ pub mod ticks { /// on the axis data range (bounds) and whether the ticks are major or minor #[default] Auto, + /// Specifies the exact locations of the ticks in data space. + List(ListLocator), /// Places ticks automatically, using the specified number of bins and steps MaxN(MaxNLocator), /// Places the ticks automatically, using the specified number of bins and multiples of PI. @@ -403,6 +405,28 @@ pub mod ticks { TimeDelta(TimeDeltaLocator), } + /// A locator that places ticks at the specified locations in data space + #[derive(Debug, Clone)] + pub struct ListLocator(pub Vec); + + impl From> for Locator { + fn from(loc: Vec) -> Self { + Locator::List(ListLocator(loc)) + } + } + + impl From> for ListLocator { + fn from(loc: Vec) -> Self { + ListLocator(loc) + } + } + + impl From for Locator { + fn from(loc: ListLocator) -> Self { + Locator::List(loc) + } + } + /// A locator that places ticks automatically, using the specified number of bins and steps #[derive(Debug, Clone)] pub struct MaxNLocator { diff --git a/src/drawing/ticks.rs b/src/drawing/ticks.rs index 0652382..464957e 100644 --- a/src/drawing/ticks.rs +++ b/src/drawing/ticks.rs @@ -22,6 +22,7 @@ pub fn locate_num( (Locator::Auto, Scale::Log(LogScale { base, .. })) => { Ok(LogLocator::new_major(*base).ticks(nb)) } + (Locator::List(locator), _) => Ok(locator.0.clone()), (Locator::MaxN(locator), Scale::Auto | Scale::Linear { .. }) => { let ticker = MaxN::new(locator.bins, locator.steps.as_slice()); Ok(ticker.ticks(nb)) @@ -530,7 +531,7 @@ fn auto_label_formatter( (Locator::Auto, Scale::Log(LogScale { base, .. })) if *base == 10.0 => { Arc::new(SciLabelFormat) } - (Locator::Auto, _) => { + (Locator::Auto, _) | (Locator::List(..), _) => { let max = ab.start().abs().max(ab.end().abs()); if max >= 100000.0 || max < 0.001 { Arc::new(SciLabelFormat)