diff --git a/crates/chart/src/render.rs b/crates/chart/src/render.rs index 63d30d9..0e4ebfd 100644 --- a/crates/chart/src/render.rs +++ b/crates/chart/src/render.rs @@ -266,8 +266,8 @@ fn draw_kind(ctx: &mut Ctx, chart: &Chart, data: &ChartData, area: Bx) { Scatter | ScatterLines | Bubble => scatter(ctx, chart, data, area), Histogram => histogram(ctx, chart, data, area), Waterfall => waterfall(ctx, chart, data, area), - BoxWhisker => box_whisker(ctx, data, area), - Stock => stock(ctx, data, area), + BoxWhisker => box_whisker(ctx, chart, data, area), + Stock => stock(ctx, chart, data, area), _ => cartesian(ctx, chart, data, area, false), } } @@ -1557,12 +1557,12 @@ fn quantile(sorted: &[f64], q: f64) -> f64 { a + (b - a) * frac } -fn box_whisker(ctx: &mut Ctx, data: &ChartData, area: Bx) { +fn box_whisker(ctx: &mut Ctx, chart: &Chart, data: &ChartData, area: Bx) { let labels: Vec = data.series.iter().map(|s| s.name.clone()).collect(); let Some((lo, hi)) = value_range(data.series.iter().flat_map(|s| s.values.iter().flatten().copied())) else { return }; let ys = nice_scale(lo, hi, false); let f = Fmt::new(data.series.first().map(|s| s.number_format.as_str()).unwrap_or("General")); - let plot = frame(ctx, area, CatAxis::Labels(&labels), &ValAxis { scale: ys, fmt: &f }, None, false, true); + let plot = frame(ctx, area, CatAxis::Labels(&labels), &ValAxis { scale: ys, fmt: &f }, None, false, chart.gridlines); if !plot.ok() { return; } @@ -1601,7 +1601,7 @@ fn box_whisker(ctx: &mut Ctx, data: &ChartData, area: Bx) { // ---------------------------------------------------------------- stock -fn stock(ctx: &mut Ctx, data: &ChartData, area: Bx) { +fn stock(ctx: &mut Ctx, chart: &Chart, data: &ChartData, area: Bx) { let ncat = data.categories.len().max(data.series.iter().map(|s| s.values.len()).max().unwrap_or(0)).min(MAX_CATS); if ncat == 0 { return; @@ -1610,7 +1610,7 @@ fn stock(ctx: &mut Ctx, data: &ChartData, area: Bx) { let Some((lo, hi)) = value_range(data.series.iter().flat_map(|s| s.values.iter().flatten().copied())) else { return }; let ys = nice_scale(lo, hi, false); let f = Fmt::new(data.series.first().map(|s| s.number_format.as_str()).unwrap_or("General")); - let plot = frame(ctx, area, CatAxis::Labels(&labels), &ValAxis { scale: ys, fmt: &f }, None, false, true); + let plot = frame(ctx, area, CatAxis::Labels(&labels), &ValAxis { scale: ys, fmt: &f }, None, false, chart.gridlines); if !plot.ok() { return; } diff --git a/crates/chart/src/tests.rs b/crates/chart/src/tests.rs index a942677..db821b7 100644 --- a/crates/chart/src/tests.rs +++ b/crates/chart/src/tests.rs @@ -902,3 +902,24 @@ fn union_series_references() { c.series[0].values = format!("{}Sheet1!$B$1,Sheet1!$B$2{}", "(".repeat(5000), ")".repeat(5000)); let _ = resolve(&wb, 0, &c); } + +#[test] +fn box_and_stock_charts_honour_the_gridlines_flag() { + // Horizontal full-width lines in the gridline colour are the value-axis gridlines. + let grid: Rgba = [217, 217, 217, 255]; + let is_grid = |p: &Prim| match p { + Prim::Line { color, pts, .. } => *color == grid && pts.len() == 2 && pts[0][1] == pts[1][1] && pts[1][0] - pts[0][0] > 200.0, + _ => false, + }; + let grids = |prims: &[Prim]| prims.iter().filter(|p| is_grid(p)).count(); + for kind in [ChartKind::BoxWhisker, ChartKind::Stock, ChartKind::ColumnClustered] { + let mut d = sample(kind); + d.series.push(series("Close", &[10000.0, 12000.0, 9000.0, 14000.0, 20000.0, 16000.0], [90, 90, 90, 255], kind)); + let mut c = chart(kind); + let on = render(&c, &d, 500.0, 350.0, &ApproxMeasure); + c.gridlines = false; + let off = render(&c, &d, 500.0, 350.0, &ApproxMeasure); + assert!(grids(&on) > 0, "{kind:?}: gridlines on must draw lines"); + assert_eq!(grids(&off), 0, "{kind:?}: gridlines off must hide them"); + } +}