fix(plot): a figure row's strip shows labels and title independently, and the shared axis is the bottom row's strip

This commit is contained in:
Martino Ferrari committed 2026-09-28 15:07:39 +02:00
1 parent 8f1e60a105
commit 770da4c2b2
9 files changed
+415 -175

No files matched your search

+13 -10
View File
@@ -661,12 +661,13 @@ const PlotLayout& Plot::layout() {
y_width = y_axes_.empty() ? 0.0f : 2.0f * pad;
x_height = text_->height() + 2.0f * pad;
}
// A row of a `Figure` gives its x strip to the figure's one shared axis, so it
// reserves none: the seed and the fixed point below both start from zero, and
// `axes` then reaches the viewport's bottom edge. Set here rather than in the
// loop, because the loop's `need_x` is what the strip wants and this overrides
// the want, not the measurement.
if (!x_label_strip_) x_height = 0.0f;
// A row of a `Figure` gives its x strip to the figure's one shared axis -- the
// bottom row's own strip, where that axis lives -- so it reserves none: the seed and
// the fixed point below both start from zero, and `axes` then reaches the viewport's
// bottom edge. Set here rather than in the loop, because the loop's `need_x` is what
// the strip wants and this overrides the want, not the measurement.
const bool x_labels = x_strip_has_labels(x_strip_);
if (!x_labels) x_height = 0.0f;
// The title strips, though, are needed before the loop and never change, unlike
// the label strips: a strip holds exactly one text line per titled axis and no
// tick label can change that. Nothing at all is reserved without a text backend
@@ -676,7 +677,10 @@ const PlotLayout& Plot::layout() {
// per titled y axis *wide*, because the y title is drawn rotated and so spends
// its length along the axes' height and takes a column, not a row, per titled
// axis (see y_title_strip_width).
const u32 x_titles = x_label_strip_ ? titled_x_axis_count() : 0u;
// The title strip is its own part of the mode: a mode that reserves the labels and
// no title reserves no row for a title either, and one that reserves the title and no
// labels still gets its row -- below where the labels would have been.
const u32 x_titles = x_strip_has_title(x_strip_) ? titled_x_axis_count() : 0u;
const f32 y_title_w = text_ != nullptr ? y_title_strip_width() : 0.0f;
const f32 x_title_h = text_ != nullptr && x_titles != 0u
? static_cast<f32>(x_titles) * text_->height() + 2.0f * pad
@@ -719,9 +723,8 @@ const PlotLayout& Plot::layout() {
// Overridden, not merely unmeasured: the strip is not reserved, so the fixed
// point has to be zero for a row that gave its strip away.
const f32 need_x =
x_label_strip_
? std::min(std::clamp(text_->height() + 2.0f * pad, 0.0f, viewport_.h), x_budget)
: 0.0f;
x_labels ? std::min(std::clamp(text_->height() + 2.0f * pad, 0.0f, viewport_.h), x_budget)
: 0.0f;
if (need_y == y_width && need_x == x_height) break; // strips are a fixed point
y_width = need_y;
x_height = need_x;