axis title labels: limit to axis size and align right
- Dominant language
- C++
- Stars
- 6.2k
- Forks
- 693
- PR merge metrics
- No merged PRs in 30d
Description
First, thanks for your great library! :+1:
I may have found a bug/missing feature in ImPlot.
If the rendered axis title widths are larger than the plot axis widths they may overlap neighbouring widgets, e.g.:

My present workaround consists of estimating the axis title size and either suppressing (zero-sized string)
```cpp
const auto axis = is_horizontal ? ImAxis_X1 : ImAxis_Y1;
const auto estTextSize = is_horizontal ? ImGui::CalcTextSize(axisLabel.c_str()).x : ImGui::CalcTextSize(axisLabel.c_str()).y;
ImPlot::SetupAxis(axis, estTextSize > axis.width ? "" : axisLabel.c_str(), axisFlags);
axis.width = // presently derived from 'ImPlot::GetPlotSize()'
```
or to shorten it, e.g. `"super long axis title [unit]"` -> `"super l..."`. The issue is that the plot pixel size is much larger than the actual axis and I'd like to avoid recomputing and/or adding fudge factors to compensate for this.
Some questions:
1. How to obtain the axes' rect size information?
2. Could the suppression/shortening of axis title labels become a default feature? If yes:
Would it be possible to (optionally) align the axis title label to the right and add these options as flags to `enum ImPlotAxisFlags_ {...}`? This latter common for scientific plots and/or when only units (e.g. '[GeV/c]', '[UTC]', ...) are being displayed.
Any help/advice would be much appreciated!
**EDIT:**
I found the following workaround for adjusting the axis title length:
```cpp
const auto estTextSize = ImGui::CalcTextSize(axisLabel.c_str()).x;
if (estTextSize >= a.width) {
static const auto estDotSize = ImGui::CalcTextSize("...").x;
const std::size_t newSize = a.width / std::max(1.f, estTextSize) * axisLabel.length();
fmt::print("overlap {} > {} text: {} -> {} \n", estTextSize, a.width, axisLabel.c_str(), fmt::format("{1:{0}}", newSize, axisLabel));
ImPlot::SetupAxis(axis, fmt::format("...{}", axisLabel.substr(axisLabel.length() - newSize, axisLabel.length())).c_str(), axisFlags);
} else {
ImPlot::SetupAxis(axis, axisLabel.c_str(), axisFlags);
}
```
and once the axis is setup the computation of the axis width/height in pixel (works after the second frame draw):
```cpp
// compute axis pixel width for H and height for V
[&plot] {
const ImPlotRect axisLimits = ImPlot::GetPlotLimits(IMPLOT_AUTO, IMPLOT_AUTO);
const auto p0 = ImPlot::PlotToPixels(axisLimits.X.Min, axisLimits.Y.Min);
const auto p1 = ImPlot::PlotToPixels(axisLimits.X.Max, axisLimits.Y.Max);
const int xWidth = static_cast(std::abs(p1.x - p0.x));
const int yHeight = static_cast(std::abs(p1.y - p0.y));
std::for_each(plot.axes.begin(), plot.axes.end(), [xWidth, yHeight](auto &a) { a.width = (a.axis == Dashboard::Plot::Axis::X) ? xWidth : yHeight; });
}();
```

If someone has an easier/cleaner/more integrated solution ...thanks in advance.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.