33 std::size_t approx_num_ticks,
AxisTicks& ticks) {
34 constexpr std::size_t min_approx_num_ticks = 3;
35 approx_num_ticks = std::max(approx_num_ticks, min_approx_num_ticks);
37 const auto [min_value, max_value] = range;
38 const Real range_size = max_value - min_value;
40 assert(range_size > 0.0);
41 const Real approx_tick_interval =
42 range_size /
static_cast<Real>(approx_num_ticks - 1);
44 auto tick_interval_digits =
45 static_cast<int>(std::floor(std::log10(approx_tick_interval)));
46 Real tick_interval_order = std::pow(10.0, tick_interval_digits);
47 Real tick_interval_number = approx_tick_interval / tick_interval_order;
49 if (tick_interval_number < 1.5) {
50 tick_interval_number = 1.0;
51 }
else if (tick_interval_number < 3.5) {
52 tick_interval_number = 2.0;
53 }
else if (tick_interval_number < 7.5) {
54 tick_interval_number = 5.0;
56 tick_interval_number = 1.0;
57 tick_interval_digits += 1;
58 tick_interval_order *= 10.0;
60 const Real tick_interval = tick_interval_number * tick_interval_order;
64 const auto min_tick_index =
65 static_cast<TickIndexType
>(std::ceil(min_value / tick_interval));
66 const auto max_tick_index =
67 static_cast<TickIndexType
>(std::floor(max_value / tick_interval));
68 const auto num_ticks =
69 static_cast<std::size_t
>(max_tick_index - min_tick_index + 1);
70 ticks.
values.resize(num_ticks);
71 ticks.
strings.resize(num_ticks);
74 std::ranges::copy(std::views::iota(min_tick_index, max_tick_index + 1) |
75 std::views::transform([tick_interval](TickIndexType index) {
76 return static_cast<Real>(index) * tick_interval;
81 const int tick_digits =
static_cast<int>(std::floor(
82 std::log10(std::max(std::abs(min_value), std::abs(max_value)))));
83 const Real tick_order = std::pow(10.0, tick_digits);
84 constexpr int digits_threshold_for_scientific_notation = 4;
85 if (std::abs(tick_digits) >= digits_threshold_for_scientific_notation) {
86 const int tick_digits_after_decimal_point =
87 std::max(tick_digits - tick_interval_digits, 0);
89 [tick_order, tick_digits, tick_digits_after_decimal_point](
91 const Real tick_number = value / tick_order;
92 return fmt::format(
"{:.{}f}e{:+}", tick_number,
93 tick_digits_after_decimal_point, tick_digits);
96 const int tick_digits_after_decimal_point =
97 std::max(-tick_interval_digits, 0);
99 [tick_digits_after_decimal_point](
Real value) {
101 "{:.{}f}", value, tick_digits_after_decimal_point);