Logo ROOT   6.18/05
Reference Guide
RPalette.cxx
Go to the documentation of this file.
1/// \file RPalette.cxx
2/// \ingroup Gpad ROOT7
3/// \author Axel Naumann <axel@cern.ch>
4/// \date 2017-09-27
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#include "ROOT/RPalette.hxx"
17
18#include "ROOT/RLogger.hxx"
19
20#include <algorithm>
21#include <cmath>
22#include <exception>
23#include <unordered_map>
24
25using namespace ROOT::Experimental;
26
27RPalette::RPalette(bool interpolate, bool knownNormalized, const std::vector<RPalette::OrdinalAndColor> &points)
28 : fColors(points), fInterpolate(interpolate), fNormalized(knownNormalized)
29{
30 if (points.size() < 2)
31 throw std::runtime_error("Must have at least two points to build a palette!");
32
33 std::sort(fColors.begin(), fColors.end());
34
35 if (!knownNormalized) {
36 // Is this a normalized palette? I.e. are the first and last ordinals 0 and 1?
37 double high = fColors.back().fOrdinal;
38 double low = fColors.front().fOrdinal;
39 double prec = (high - low) * 1E-6;
40
41 auto reasonablyEqual = [&](double val, double expected) -> bool { return std::fabs(val - expected) < prec; };
42 fNormalized = reasonablyEqual(low, 0.) && reasonablyEqual(high, 1.);
43 }
44}
45
46namespace {
47static std::vector<RPalette::OrdinalAndColor> AddOrdinals(const std::vector<RColor> &points)
48{
49 std::vector<RPalette::OrdinalAndColor> ret(points.size());
50 auto addOneOrdinal = [&](const RColor &col) -> RPalette::OrdinalAndColor {
51 return {1. / (points.size() - 1) * (&col - points.data()), col};
52 };
53 std::transform(points.begin(), points.end(), ret.begin(), addOneOrdinal);
54 return ret;
55}
56} // unnamed namespace
57
58RPalette::RPalette(bool interpolate, const std::vector<RColor> &points)
59 : RPalette(interpolate, true, AddOrdinals(points))
60{}
61
63{
64 if (fInterpolate) {
65 R__ERROR_HERE("Gpad") << "Not yet implemented!";
66 } else {
67 auto iColor = std::lower_bound(fColors.begin(), fColors.end(), ordinal);
68 if (iColor == fColors.end())
69 return fColors.back().fColor;
70 // Is iColor-1 closer to ordinal than iColor?
71 if (iColor != fColors.begin()
72 && (iColor - 1)->fOrdinal - ordinal < ordinal - iColor->fOrdinal)
73 return (iColor - 1)->fColor;
74 return iColor->fColor;
75 }
76 return RColor{};
77}
78
79namespace {
80using GlobalPalettes_t = std::unordered_map<std::string, RPalette>;
81static GlobalPalettes_t CreateDefaultPalettes()
82{
83 GlobalPalettes_t ret;
84 ret["default"] = RPalette({RColor::kRed, RColor::kBlue});
86 return ret;
87}
88
89static GlobalPalettes_t &GetGlobalPalettes()
90{
91 static GlobalPalettes_t globalPalettes = CreateDefaultPalettes();
92 return globalPalettes;
93}
94} // unnamed namespace
95
97{
98 GetGlobalPalettes()[std::string(name)] = palette;
99}
100
102{
103 static const RPalette sNoPaletteWithThatName;
104 auto iGlobalPalette = GetGlobalPalettes().find(std::string(name));
105 if (iGlobalPalette == GetGlobalPalettes().end())
106 return sNoPaletteWithThatName;
107 return iGlobalPalette->second;
108}
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
char name[80]
Definition: TGX11.cxx:109
point * points
Definition: X3DBuffer.c:22
A color: Red|Green|Blue|Alpha, or a position in a RPalette.
Definition: RColor.hxx:28
static constexpr RGBA kWhite
Definition: RColor.hxx:257
static constexpr RGBA kBlue
Definition: RColor.hxx:256
static constexpr RGBA kBlack
Definition: RColor.hxx:258
static constexpr RGBA kRed
Definition: RColor.hxx:254
static void RegisterPalette(std::string_view name, const RPalette &palette)
Register a palette in the set of global palettes, making it available to GetPalette().
Definition: RPalette.cxx:96
RColor GetColor(double ordinal)
Get the color associated with the ordinal value.
Definition: RPalette.cxx:62
std::vector< OrdinalAndColor > fColors
Palette colors: the color points and their ordinal value.
Definition: RPalette.hxx:58
bool fInterpolate
Whether to interpolate between the colors (in contrast to picking one of fColors).
Definition: RPalette.hxx:61
bool fNormalized
Whether the palette's ordinal numbers are normalized.
Definition: RPalette.hxx:64
static const RPalette & GetPalette(std::string_view name)
Get a global palette by name.
Definition: RPalette.cxx:101
basic_string_view< char > string_view
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
An ordinal value and its associated color.
Definition: RPalette.hxx:43