Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
/// Which labels to show so none overlap: greedily, highest priority first
/// (then input order), keeping a label only if it clears every kept label by
/// at least padding. Touching is not overlapping. Result in input order.
///
/// # Panics
/// Panics on a negative padding or a box with negative size.
pub fn avoid_collisions(boxes: &[LabelBox], padding: f64) -> Vec<bool> {
if !(padding >= 0.0) {
panic!("padding must not be negative, received {}", padding);
}
for b in boxes {
if !(b.width >= 0.0 && b.height >= 0.0) {
panic!("label boxes must not have negative size");
}
}
let mut order: Vec<usize> = (0..boxes.len()).collect();
order.sort_by(|&a, &b| boxes[b].priority.cmp(&boxes[a].priority).then(a.cmp(&b)));
let mut shown = vec![false; boxes.len()];
let mut kept: Vec<&LabelBox> = Vec::new();
for i in order {
let a = &boxes[i];
let clash = kept.iter().any(|k| {
a.x < k.x + k.width + padding
&& k.x < a.x + a.width + padding
&& a.y < k.y + k.height + padding
&& k.y < a.y + a.height + padding
});
if !clash {
kept.push(a);
shown[i] = true;
}
}
shown
}
pub fn fune_vector(args: &[Value]) -> Value {
let boxes: Vec<LabelBox> = args[0]
.as_arr()
.iter()
.map(|b| LabelBox {
x: b.get("x").as_f64(),
y: b.get("y").as_f64(),
width: b.get("width").as_f64(),
height: b.get("height").as_f64(),
priority: b.get("priority").as_i64(),
})
.collect();
Value::Arr(avoid_collisions(&boxes, args[1].as_f64()).into_iter().map(Value::Bool).collect())
}