use crate::preview::mermaid::layout::Point;
use super::chart::{label_node, TITLE_GAP};
use super::{clusters, Diagram, Label, PlacedCluster, Size};
pub fn title_room(title: &str) -> f64 {
let label = Label::measure(title);
if label.is_blank() {
0.0
} else {
label.height + clusters::TITLE_PAD_Y * 2.0
}
}
pub fn frame(id: String, title: &str, l: f64, t: f64, r: f64, b: f64) -> PlacedCluster {
let label = Label::measure(title);
let t = t - title_room(title);
PlacedCluster {
id,
title: label,
center: Point::new((l + r) / 2.0, (t + b) / 2.0),
size: Size::new(r - l, b - t),
parent: None,
depth: 0,
dashed: false,
filled: true,
sections: Vec::new(),
}
}
pub fn add_title(diagram: &mut Diagram, title: Option<&str>) {
let Some(text) = title else { return };
let label = Label::measure(text);
if label.is_blank() {
return;
}
let (mut min_x, mut min_y) = (f64::INFINITY, f64::INFINITY);
let mut max_x = f64::NEG_INFINITY;
let mut grow = |l: f64, t: f64, r: f64| {
min_x = min_x.min(l);
min_y = min_y.min(t);
max_x = max_x.max(r);
};
for n in &diagram.nodes {
let (l, t, r, _) = n.bounds();
grow(l, t, r);
}
for c in &diagram.clusters {
let (l, t, r, _) = c.bounds();
grow(l, t, r);
}
for e in &diagram.edges {
for p in &e.points {
grow(p.x, p.y, p.x);
}
}
if !min_x.is_finite() {
return;
}
let center = Point::new(
(min_x + max_x) / 2.0,
min_y - TITLE_GAP - label.height / 2.0,
);
if let Some(n) = label_node("chart#title", label, center, None) {
diagram.nodes.push(n);
}
}