mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-13 01:15:56 -06:00
Fix chart legend ignores per-point colours (c:dPt) on pie charts
Fixes #2028. - crates/render/src/chart.rs - crates/render/tests/autocraft_regression_2028.rs
This commit is contained in:
@@ -97,6 +97,13 @@ fn bar_paint(ctx: &Ctx, c: &Chart, si: usize, pi: usize, s: &deckcraft_model::ch
|
||||
paint_of(ctx, s.fill.as_ref(), series_color(ctx, c, si))
|
||||
}
|
||||
|
||||
/// Colour of pie slice `i`: its `<c:dPt>` solid fill, else the palette's. Slices and legend keys share it.
|
||||
fn pie_slice_color(ctx: &Ctx, c: &Chart, s: Option<&deckcraft_model::chart::Series>, i: usize) -> Rgba {
|
||||
s.and_then(|s| s.point_fills.iter().find(|(k, _)| *k == i))
|
||||
.and_then(|(_, f)| if let Fill::Solid { color: cc } = f { Some(ctx.color(cc, None)) } else { None })
|
||||
.unwrap_or_else(|| series_color(ctx, c, i))
|
||||
}
|
||||
|
||||
fn polyline(pts: &[Point]) -> BezPath {
|
||||
let mut p = BezPath::new();
|
||||
for (k, q) in pts.iter().enumerate() {
|
||||
@@ -583,7 +590,7 @@ fn build_legend_items(rctx: &Ctx, c: &Chart, pie: bool, waterfall: bool) -> Vec<
|
||||
// A map draws its own colour scale.
|
||||
vec![]
|
||||
} else if pie {
|
||||
c.categories.iter().enumerate().map(|(i, n)| (n.clone(), Paint::Color(series_color(rctx, c, i)), None)).collect()
|
||||
c.categories.iter().enumerate().map(|(i, n)| (n.clone(), Paint::Color(pie_slice_color(rctx, c, c.series.first(), i)), None)).collect()
|
||||
} else {
|
||||
c.series
|
||||
.iter()
|
||||
@@ -1128,12 +1135,7 @@ fn draw_pie(ctx: &mut RenderContext, rctx: &Ctx, c: &Chart, m: Affine, area: Rec
|
||||
p.extend(arc.append_iter(0.1));
|
||||
p.close_path();
|
||||
ctx.set_transform(m);
|
||||
let col = s
|
||||
.point_fills
|
||||
.iter()
|
||||
.find(|(k, _)| *k == i)
|
||||
.and_then(|(_, f)| if let Fill::Solid { color: cc } = f { Some(rctx.color(cc, None)) } else { None })
|
||||
.unwrap_or_else(|| series_color(rctx, c, i));
|
||||
let col = pie_slice_color(rctx, c, Some(s), i);
|
||||
ctx.set_paint(color(col, 1.0));
|
||||
ctx.fill_path(&p);
|
||||
ctx.set_paint(color(Rgba::WHITE, 1.0));
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
use deckcraft_color::Rgba;
|
||||
use deckcraft_model::chart::ChartType;
|
||||
use deckcraft_model::style::{ColorRef, Fill};
|
||||
use deckcraft_model::{Chart, Presentation, Shape, ShapeId, ShapeKind, Xfrm};
|
||||
use deckcraft_render::{RenderOpts, render_slide};
|
||||
|
||||
#[test]
|
||||
fn pie_legend_keys_take_the_point_colours() {
|
||||
let mut c = Chart::sample(ChartType::Pie);
|
||||
c.title = None;
|
||||
c.legend = Some("r".into());
|
||||
c.series[0].point_fills = vec![(0, Fill::solid(ColorRef::rgb(Rgba::rgb(255, 0, 255))))];
|
||||
let sh = Shape { id: ShapeId(2028), xfrm: Some(Xfrm::new(0.0, 0.0, 960.0, 540.0)), kind: ShapeKind::Chart(Box::new(c)), ..Default::default() };
|
||||
let mut p = Presentation::default();
|
||||
std::sync::Arc::make_mut(&mut p.slides[0]).shapes = vec![sh];
|
||||
let img = render_slide(&p, 0, &RenderOpts { scale: 1.0, ..Default::default() });
|
||||
// The pie stays well left of x = 850; only the legend column lies beyond it.
|
||||
let key = (850..img.width).flat_map(|x| (0..img.height).map(move |y| (x, y))).filter(|(x, y)| img.pixel(*x, *y)[..3] == [255, 0, 255]).count();
|
||||
assert!(key > 20, "the legend key of the overridden slice is drawn in its colour: {key} px");
|
||||
}
|
||||
Reference in New Issue
Block a user