fix(plot): single-rounding clock labels, log-axis fits that refuse non-positive data

This commit is contained in:
Martino Ferrari committed 2026-09-27 22:28:56 +02:00
1 parent 93fc06f050
commit 606e40a9f1
7 files changed
+258 -73

No files matched your search

+30 -16
View File
@@ -94,23 +94,37 @@ void format_time(f64 seconds, char* buf, usize n) {
const char* const sign = seconds < 0.0 ? "-" : "";
const f64 t = std::fabs(seconds);
if (t >= 86400.0) {
std::snprintf(buf, n, "%s%.3gd", sign, t / 86400.0);
} else if (t >= 3600.0) {
const auto hours = static_cast<unsigned long long>(t / 3600.0);
const auto mins = static_cast<unsigned long long>((t - 3600.0 * static_cast<f64>(hours)) / 60.0);
const auto secs =
static_cast<unsigned long long>(std::llround(t - 3600.0 * static_cast<f64>(hours) -
60.0 * static_cast<f64>(mins)));
std::snprintf(buf, n, "%s%llu:%02llu:%02llu", sign, hours, mins, secs);
} else if (t >= 60.0) {
const auto mins = static_cast<unsigned long long>(t / 60.0);
const auto secs = static_cast<unsigned long long>(std::llround(t - 60.0 * static_cast<f64>(mins)));
std::snprintf(buf, n, "%s%llu:%02llu", sign, mins, secs);
} else if (t >= 1.0) {
std::snprintf(buf, n, "%s%.3gs", sign, t);
if (t < 1.0) {
// Sub-second: milliseconds. The 999.5 cut keeps %.3g out of scientific
// notation (it would print "1e+03ms") right below the one-second boundary.
const f64 ms = t * 1000.0;
if (ms < 999.5) {
std::snprintf(buf, n, "%s%.3gms", sign, ms);
} else {
std::snprintf(buf, n, "%s%.3gs", sign, t);
}
return;
}
// ONE rounding decision for the whole value. Deriving the fields from a single
// rounded second count is what keeps a field from reaching its radix: rounding
// the seconds leftover independently would print 119.5 s as "1:60".
const f64 whole = std::round(t);
if (whole >= 86400.0) {
// At or above a day the day field appears, so the h:mm:ss shape never sees an
// hour of 24 or more.
std::snprintf(buf, n, "%s%.3gd", sign, whole / 86400.0);
return;
}
const auto total = static_cast<unsigned long long>(whole);
if (whole >= 3600.0) {
std::snprintf(buf, n, "%s%llu:%02llu:%02llu", sign, total / 3600ull,
(total / 60ull) % 60ull, total % 60ull);
} else if (whole >= 60.0) {
std::snprintf(buf, n, "%s%llu:%02llu", sign, total / 60ull, total % 60ull);
} else {
std::snprintf(buf, n, "%s%.3gms", sign, t * 1000.0);
std::snprintf(buf, n, "%s%.3gs", sign, t);
}
}