16 #include <unordered_map>
18 using namespace ROOT::Experimental;
20 RPalette::RPalette(
bool interpolate,
bool knownNormalized,
const std::vector<RPalette::OrdinalAndColor> &points)
21 : fColors(points), fInterpolate(interpolate), fNormalized(knownNormalized)
23 if (points.size() < 2)
24 throw std::runtime_error(
"Must have at least two points to build a palette!");
26 std::sort(fColors.begin(), fColors.end());
28 if (!knownNormalized) {
30 double high = fColors.back().fOrdinal;
31 double low = fColors.front().fOrdinal;
32 double prec = (high - low) * 1E-6;
34 auto reasonablyEqual = [&](
double val,
double expected) ->
bool {
return std::fabs(val - expected) < prec; };
35 fNormalized = reasonablyEqual(low, 0.) && reasonablyEqual(high, 1.);
40 static std::vector<RPalette::OrdinalAndColor> AddOrdinals(
const std::vector<RColor> &points)
42 std::vector<RPalette::OrdinalAndColor> ret(points.size());
43 auto addOneOrdinal = [&](
const RColor &col) -> RPalette::OrdinalAndColor {
44 return {1. / (points.size() - 1) * (&col - points.data()), col};
46 std::transform(points.begin(), points.end(), ret.begin(), addOneOrdinal);
51 RPalette::RPalette(
bool interpolate,
const std::vector<RColor> &points)
52 : RPalette(interpolate, true, AddOrdinals(points))
55 RColor RPalette::GetColor(
double ordinal)
58 R__ERROR_HERE(
"Gpad") <<
"Not yet implemented!";
60 auto iColor = std::lower_bound(fColors.begin(), fColors.end(), ordinal);
61 if (iColor == fColors.end())
62 return fColors.back().fColor;
64 if (iColor != fColors.begin() && (iColor - 1)->fOrdinal - ordinal < ordinal - iColor->fOrdinal)
65 return (iColor - 1)->fColor;
66 return iColor->fColor;
72 using GlobalPalettes_t = std::unordered_map<std::string, RPalette>;
73 static GlobalPalettes_t CreateDefaultPalettes()
76 ret[
"default"] = RPalette({RColor::kRed, RColor::kBlue});
77 ret[
"bw"] = RPalette({RColor::kBlack, RColor::kWhite});
81 static GlobalPalettes_t &GetGlobalPalettes()
83 static GlobalPalettes_t globalPalettes = CreateDefaultPalettes();
84 return globalPalettes;
88 void RPalette::RegisterPalette(std::string_view name,
const RPalette &palette)
90 GetGlobalPalettes()[std::string(name)] = palette;
93 const RPalette &RPalette::GetPalette(std::string_view name)
95 static const RPalette sNoPaletteWithThatName;
96 auto iGlobalPalette = GetGlobalPalettes().find(std::string(name));
97 if (iGlobalPalette == GetGlobalPalettes().end())
98 return sNoPaletteWithThatName;
99 return iGlobalPalette->second;