fix(render): floor the axes so chrome cannot erase it, one title row per titled axis
Two findings on the pass-1 fix: - The reserved strips were clamped only to the viewport, so a title wider than a narrow panel took the rest of it and the axes collapsed: draw_traces() returned on a zero-width rect (no trace drawn, nothing reported) and a zero-height one flattened every trace onto a single row. The chrome is now capped at half the viewport -- the label strip is served first, the title strip takes what is left of that allowance -- an over-long title is clipped to its strip by a walk that both measures and stages it, and draw_traces() tests the height as well as the width. - Every titled y axis was staged at the same centred position inside one strip, so a Left/Right pair of titles overprinted. Each titled axis now owns a text line: the x strip grows one line per titled x axis (x_title_height), and the y runs stack down the axes-tall strip, which needs no extra width for it. Tests: `narrow_panel_with_a_long_y_title_still_draws` and `short_panel_with_an_x_title_still_draws` pin the floor (the axes keeps half the panel and the trace still covers the columns, with the title clipped into its strip), `titled_axis_pairs_get_their_own_rows` pins one text row per titled axis in both directions, and `layout_stacks_one_title_line_per_titled_axis` pins the strip sizing. All fail against the pass-1 sources.
This commit is contained in:
1 parent
8f45108559
commit
1f5aa11de2
6 files changed
+330
-51
No files matched your search
+23
-10
@@ -36,10 +36,13 @@ struct PlotLayout {
|
||||
/// Bottom strip height. The default is used when no text backend has been set.
|
||||
f32 x_axis_height = 22.0f;
|
||||
/// Width of `y_title_area` and height of `x_title_area`, both 0.0f when nothing
|
||||
/// is reserved. An x title is one text line in a strip as wide as the axes; a y
|
||||
/// title is a horizontal run in a vertical strip, so the strip is as wide as the
|
||||
/// widest y title (plus the label padding) -- one text line would cut it off.
|
||||
/// With no text backend there is no title to measure and both stay 0.0f.
|
||||
/// is reserved. Every titled axis of a direction gets its own text line inside
|
||||
/// its strip -- which is what keeps a Left/Right (or Bottom/Top) pair from
|
||||
/// drawing two titles over each other -- so `x_title_height` is one line per
|
||||
/// titled x axis; `y_title_width` is the widest y title plus the padding, since
|
||||
/// y titles are horizontal runs that stack down the axes-tall strip and need
|
||||
/// width, not another row of it. With no text backend there is no title to
|
||||
/// measure and both stay 0.0f.
|
||||
f32 y_title_width = 0.0f;
|
||||
f32 x_title_height = 0.0f;
|
||||
};
|
||||
@@ -94,6 +97,11 @@ class Plot {
|
||||
|
||||
u32 x_axis_count() const noexcept { return static_cast<u32>(x_axes_.size()); }
|
||||
u32 y_axis_count() const noexcept { return static_cast<u32>(y_axes_.size()); }
|
||||
/// Axes of that direction that carry a title, i.e. that `layout()` reserves a
|
||||
/// text line for and `Renderer::draw_titles()` draws one for. Zero when no
|
||||
/// backend can measure a title, whatever the labels say.
|
||||
u32 titled_x_axis_count() const noexcept;
|
||||
u32 titled_y_axis_count() const noexcept;
|
||||
u32 trace_count() const noexcept { return static_cast<u32>(traces_.size()); }
|
||||
u32 cursor_count() const noexcept { return static_cast<u32>(cursors_.size()); }
|
||||
u32 measure_count() const noexcept { return static_cast<u32>(measures_.size()); }
|
||||
@@ -175,8 +183,17 @@ class Plot {
|
||||
/// `axes` is inset by the label strip of each occupied edge and, when that
|
||||
/// direction has a titled axis, by the strip that title lives in (`y_title_width`
|
||||
/// and `x_title_height` say how much that is): a title can then only be drawn
|
||||
/// outside the data, whatever the title says. Call this once per frame -- it
|
||||
/// rebuilds the ticks and the grid -- and pass the result down.
|
||||
/// outside the data, whatever the title says.
|
||||
///
|
||||
/// The chrome is capped so `axes` keeps half the viewport on each dimension
|
||||
/// whatever the labels and titles ask for: a plot with a title wider than a
|
||||
/// narrow panel shrinks, it does not vanish -- an axes rect with no width or no
|
||||
/// height selects no level, stages no segment and draws no trace, and says
|
||||
/// nothing about why. The label strip is what makes the tick values readable, so
|
||||
/// it is served first and the title strip takes what is left of the allowance.
|
||||
///
|
||||
/// Call this once per frame -- it rebuilds the ticks and the grid -- and pass
|
||||
/// the result down.
|
||||
const PlotLayout& layout();
|
||||
/// The layout as of the last refresh. The const overload never recomputes, so
|
||||
/// a lookup on a const Plot cannot move the axes out from under the caller.
|
||||
@@ -219,10 +236,6 @@ class Plot {
|
||||
/// Widest y tick label plus the label padding on both sides: the left strip the
|
||||
/// text backend asks for. Zero with no backend or no y axis.
|
||||
f32 y_label_width() const;
|
||||
/// True when any axis of that direction carries a title, i.e. when layout()
|
||||
/// must reserve the strip `Renderer::draw_titles()` draws it in.
|
||||
bool has_x_title() const noexcept;
|
||||
bool has_y_title() const noexcept;
|
||||
/// Widest y axis title plus the label padding on both sides: the vertical strip
|
||||
/// a horizontal y title fits in. Zero with no backend or no titled y axis.
|
||||
f32 y_title_strip_width() const;
|
||||
|
||||
Reference in new issue
Block a user