65 lines
2.3 KiB
C++
65 lines
2.3 KiB
C++
#pragma once
|
|
#include <cmath>
|
|
#include <string>
|
|
#include <vector>
|
|
#include "Abs_Axis_p.h"
|
|
#include "Axis_p.h"
|
|
#include "Frequency_Axis.h"
|
|
namespace renderive {
|
|
struct Frequency_Axis_Input_Data : Axis_Input_Data {};
|
|
struct Frequency_Axis_Render_State : Axis_Render_State {};
|
|
struct Frequency_Axis_Private : Typed_Render_Data_Base<Axis_Private, Frequency_Axis, Frequency_Axis_Render_State, Frequency_Axis_Input_Data> {
|
|
std::vector<std::string> create_label_vector(const std::vector<double>& ticks, Abs_Axis_Render_State* state) override {
|
|
const int exponent = unit_exponent(ticks);
|
|
if (!ticks.empty())
|
|
state->unit_text = "Frequency/" + unit_text(exponent);
|
|
std::vector<std::string> result;
|
|
result.reserve(ticks.size());
|
|
for (const double& tick_coord : ticks)
|
|
result.push_back(get_true_value(get_tick_label(tick_coord, state), exponent, state));
|
|
return result;
|
|
}
|
|
static int unit_exponent(const std::vector<double>& ticks) {
|
|
if (ticks.empty())
|
|
return 0;
|
|
const double range = std::abs(ticks.back() - ticks.front());
|
|
if (range >= 1e9)
|
|
return 9;
|
|
if (range >= 1e6)
|
|
return 6;
|
|
if (range >= 1e3)
|
|
return 3;
|
|
return 0;
|
|
}
|
|
static std::string unit_text(int exponent) {
|
|
switch (exponent) {
|
|
case 0:
|
|
return "Hz";
|
|
case 3:
|
|
return "kHz";
|
|
case 6:
|
|
return "MHz";
|
|
case 9:
|
|
return "GHz";
|
|
}
|
|
return "Hz";
|
|
}
|
|
std::string get_true_value(std::string value, int exponent, Abs_Axis_Render_State* state) {
|
|
auto s = static_cast<Frequency_Axis_Render_State*>(state);
|
|
int precision = s->label_precision;
|
|
auto dot_pos = value.find('.');
|
|
if (dot_pos == std::string::npos)
|
|
dot_pos = value.size();
|
|
std::string number = value.substr(0, dot_pos) + value.substr(dot_pos + 1);
|
|
int after_dot_index = static_cast<int>(dot_pos) - exponent;
|
|
if (after_dot_index < 1) {
|
|
for (int i = 0; i < 1 - after_dot_index; ++i)
|
|
number.insert(0, 1, '0');
|
|
after_dot_index = 1;
|
|
}
|
|
number.insert(after_dot_index, ".");
|
|
return format_number(std::stod(number), {.precision = precision});
|
|
}
|
|
};
|
|
} // namespace renderive
|