Logo ROOT   6.12/07
Reference Guide
TPalette.cxx
Go to the documentation of this file.
1 /// \file TPalette.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/TPalette.hxx"
17 
18 #include "ROOT/TLogger.hxx"
19 
20 #include <algorithm>
21 #include <cmath>
22 #include <exception>
23 #include <unordered_map>
24 
25 using namespace ROOT::Experimental;
26 
27 TPalette::TPalette(bool interpolate, bool knownNormalized, const std::vector<TPalette::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 
46 namespace {
47 static std::vector<TPalette::OrdinalAndColor> AddOrdinals(const std::vector<TColor> &points)
48 {
49  std::vector<TPalette::OrdinalAndColor> ret(points.size());
50  auto addOneOrdinal = [&](const TColor &col) -> TPalette::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 
58 TPalette::TPalette(bool interpolate, const std::vector<TColor> &points)
59  : TPalette(interpolate, true, AddOrdinals(points))
60 {}
61 
62 TColor TPalette::GetColor(double ordinal)
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 - 1)->fOrdinal - ordinal < ordinal - iColor->fOrdinal)
72  return (iColor - 1)->fColor;
73  return iColor->fColor;
74  }
75  return TColor{};
76 }
77 
78 namespace {
79 using GlobalPalettes_t = std::unordered_map<std::string, TPalette>;
80 static GlobalPalettes_t CreateDefaultPalettes()
81 {
82  GlobalPalettes_t ret;
83  ret["default"] = TPalette({TColor::kRed, TColor::kBlue});
84  ret["bw"] = TPalette({TColor::kBlack, TColor::kWhite});
85  return ret;
86 }
87 
88 static GlobalPalettes_t &GetGlobalPalettes()
89 {
90  static GlobalPalettes_t globalPalettes = CreateDefaultPalettes();
91  return globalPalettes;
92 }
93 } // unnamed namespace
94 
96 {
97  GetGlobalPalettes()[std::string(name)] = palette;
98 }
99 
101 {
102  static const TPalette sNoPaletteWithThatName;
103  auto iGlobalPalette = GetGlobalPalettes().find(std::string(name));
104  if (iGlobalPalette == GetGlobalPalettes().end())
105  return sNoPaletteWithThatName;
106  return iGlobalPalette->second;
107 }
bool fInterpolate
Whether to interpolate between the colors (in contrast to picking one of fColors).
Definition: TPalette.hxx:61
basic_string_view< char > string_view
Definition: RStringView.h:35
std::vector< OrdinalAndColor > fColors
Palette colors: the color points and their ordinal value.
Definition: TPalette.hxx:58
bool fNormalized
Whether the palette&#39;s ordinal numbers are normalized.
Definition: TPalette.hxx:64
An ordinal value and its associated color.
Definition: TPalette.hxx:43
static constexpr PredefinedRGB kBlack
Definition: TColor.hxx:189
point * points
Definition: X3DBuffer.c:20
TColor GetColor(double ordinal)
Get the color associated with the ordinal value.
Definition: TPalette.cxx:62
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
static constexpr PredefinedRGB kBlue
Definition: TColor.hxx:187
static const TPalette & GetPalette(std::string_view name)
Get a global palette by name.
Definition: TPalette.cxx:100
static constexpr PredefinedRGB kRed
Definition: TColor.hxx:185
static void RegisterPalette(std::string_view name, const TPalette &palette)
Register a palette in the set of global palettes, making it available to GetPalette().
Definition: TPalette.cxx:95
A set of colors.
Definition: TPalette.hxx:38
constexpr Double_t E()
Definition: TMath.h:74
static constexpr PredefinedRGB kWhite
Definition: TColor.hxx:188
A color: Red|Green|Blue|Alpha, or a position in a TPalette.
Definition: TColor.hxx:27
char name[80]
Definition: TGX11.cxx:109
#define R__ERROR_HERE(GROUP)
Definition: TLogger.hxx:126