#include "Riostream.h"
#include "TROOT.h"
#include "TPaletteAxis.h"
#include "TVirtualPad.h"
#include "TStyle.h"
#include "TMath.h"
#include "TView.h"
#include "TH1.h"
#include "TGaxis.h"
ClassImp(TPaletteAxis)
TPaletteAxis::TPaletteAxis(): TPave()
{
fH = 0;
SetName("");
}
TPaletteAxis::TPaletteAxis(Double_t x1, Double_t y1, Double_t x2, Double_t y2, TH1 *h)
: TPave(x1, y1, x2, y2)
{
fH = h;
SetName("palette");
TAxis *zaxis = fH->GetZaxis();
fAxis.ImportAxisAttributes(zaxis);
if (gPad->GetView()) SetBit(kHasView);
}
TPaletteAxis::~TPaletteAxis()
{
if (fH) fH->GetListOfFunctions()->Remove(this);
}
TPaletteAxis::TPaletteAxis(const TPaletteAxis &palette) : TPave(palette)
{
((TPaletteAxis&)palette).Copy(*this);
}
void TPaletteAxis::Copy(TObject &obj) const
{
TPave::Copy(obj);
((TPaletteAxis&)obj).fH = fH;
((TPaletteAxis&)obj).fName = fName;
}
Int_t TPaletteAxis::DistancetoPrimitive(Int_t px, Int_t py)
{
Int_t plxmax = gPad->XtoAbsPixel(fX2);
Int_t plymin = gPad->YtoAbsPixel(fY1);
Int_t plymax = gPad->YtoAbsPixel(fY2);
if (px > plxmax && px < plxmax + 30 && py >= plymax && py <= plymin) return px - plxmax;
return TPave::DistancetoPrimitive(px, py);
}
void TPaletteAxis::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
static Int_t kmode = 0;
Int_t plxmin = gPad->XtoAbsPixel(fX1);
Int_t plxmax = gPad->XtoAbsPixel(fX2);
if (kmode != 0 || px <= plxmax) {
if (event == kButton1Down) kmode = 1;
TBox::ExecuteEvent(event, px, py);
if (event == kButton1Up) kmode = 0;
Double_t dpx = gPad->GetX2() - gPad->GetX1();
Double_t dpy = gPad->GetY2() - gPad->GetY1();
Double_t xp1 = gPad->GetX1();
Double_t yp1 = gPad->GetY1();
fX1NDC = (fX1 - xp1) / dpx;
fY1NDC = (fY1 - yp1) / dpy;
fX2NDC = (fX2 - xp1) / dpx;
fY2NDC = (fY2 - yp1) / dpy;
return;
}
gPad->SetCursor(kHand);
static Double_t ratio1, ratio2;
static Int_t px1old, py1old, px2old, py2old;
Double_t temp, xmin, xmax;
switch (event) {
case kButton1Down:
ratio1 = (gPad->AbsPixeltoY(py) - fY1) / (fY2 - fY1);
py1old = gPad->YtoAbsPixel(fY1 + ratio1 * (fY2 - fY1));
px1old = plxmin;
px2old = plxmax;
py2old = py1old;
gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
gVirtualX->SetLineColor(-1);
case kButton1Motion:
gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
ratio2 = (gPad->AbsPixeltoY(py) - fY1) / (fY2 - fY1);
py2old = gPad->YtoAbsPixel(fY1 + ratio2 * (fY2 - fY1));
gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
break;
case kButton1Up:
if (gROOT->IsEscaped()) {
gROOT->SetEscape(kFALSE);
break;
}
ratio2 = (gPad->AbsPixeltoY(py) - fY1) / (fY2 - fY1);
xmin = ratio1;
xmax = ratio2;
if (xmin > xmax) {
temp = xmin;
xmin = xmax;
xmax = temp;
temp = ratio1;
ratio1 = ratio2;
ratio2 = temp;
}
if (ratio2 - ratio1 > 0.05) {
if (fH->GetDimension() == 2) {
Double_t zmin = fH->GetMinimum();
Double_t zmax = fH->GetMaximum();
if (gPad->GetLogz()) {
if (zmin <= 0 && zmax > 0) zmin = TMath::Min((Double_t)1,
(Double_t)0.001 * zmax);
zmin = TMath::Log10(zmin);
zmax = TMath::Log10(zmax);
}
Double_t newmin = zmin + (zmax - zmin) * ratio1;
Double_t newmax = zmin + (zmax - zmin) * ratio2;
if (newmin < zmin)newmin = fH->GetBinContent(fH->GetMinimumBin());
if (newmax > zmax)newmax = fH->GetBinContent(fH->GetMaximumBin());
if (gPad->GetLogz()) {
newmin = TMath::Exp(2.302585092994 * newmin);
newmax = TMath::Exp(2.302585092994 * newmax);
}
fH->SetMinimum(newmin);
fH->SetMaximum(newmax);
fH->SetBit(TH1::kIsZoomed);
}
gPad->Modified(kTRUE);
}
gVirtualX->SetLineColor(-1);
kmode = 0;
break;
}
}
Int_t TPaletteAxis::GetBinColor(Int_t i, Int_t j)
{
Double_t zc = fH->GetBinContent(i, j);
return GetValueColor(zc);
}
char *TPaletteAxis::GetObjectInfo(Int_t , Int_t py) const
{
Double_t z;
static char info[64];
Double_t zmin = fH->GetMinimum();
Double_t zmax = fH->GetMaximum();
Int_t y1 = gPad->GetWh() - gPad->VtoPixel(fY1NDC);
Int_t y2 = gPad->GetWh() - gPad->VtoPixel(fY2NDC);
Int_t y = gPad->GetWh() - py;
if (gPad->GetLogz()) {
if (zmin <= 0 && zmax > 0) zmin = TMath::Min((Double_t)1,
(Double_t)0.001 * zmax);
Double_t zminl = TMath::Log10(zmin);
Double_t zmaxl = TMath::Log10(zmax);
Double_t zl = (zmaxl - zminl) * ((Double_t)(y - y1) / (Double_t)(y2 - y1)) + zminl;
z = TMath::Power(10., zl);
} else {
z = (zmax - zmin) * ((Double_t)(y - y1) / (Double_t)(y2 - y1)) + zmin;
}
snprintf(info, 64, "(z=%g)", z);
return info;
}
Int_t TPaletteAxis::GetValueColor(Double_t zc)
{
Double_t wmin = fH->GetMinimum();
Double_t wmax = fH->GetMaximum();
Double_t wlmin = wmin;
Double_t wlmax = wmax;
if (gPad->GetLogz()) {
if (wmin <= 0 && wmax > 0) wmin = TMath::Min((Double_t)1,
(Double_t)0.001 * wmax);
wlmin = TMath::Log10(wmin);
wlmax = TMath::Log10(wmax);
}
Int_t ncolors = gStyle->GetNumberOfColors();
Int_t ndivz = fH->GetContour();
if (ndivz == 0) return 0;
ndivz = TMath::Abs(ndivz);
Int_t theColor, color;
Double_t scale = ndivz / (wlmax - wlmin);
if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz()) zc = TMath::Log10(zc);
if (zc < wlmin) zc = wlmin;
color = Int_t(0.01 + (zc - wlmin) * scale);
theColor = Int_t((color + 0.99) * Double_t(ncolors) / Double_t(ndivz));
return gStyle->GetColorPalette(theColor);
}
void TPaletteAxis::Paint(Option_t *)
{
ConvertNDCtoPad();
SetFillStyle(1001);
Double_t ymin = fY1;
Double_t ymax = fY2;
Double_t xmin = fX1;
Double_t xmax = fX2;
Double_t wmin = fH->GetMinimum();
Double_t wmax = fH->GetMaximum();
Double_t wlmin = wmin;
Double_t wlmax = wmax;
Double_t y1, y2, w1, w2, zc;
if ((wlmax - wlmin) <= 0) {
Double_t mz = wlmin * 0.1;
if (mz == 0) mz = 0.1;
wlmin = wlmin - mz;
wlmax = wlmax + mz;
wmin = wlmin;
wmax = wlmax;
}
if (gPad->GetLogz()) {
if (wmin <= 0 && wmax > 0) wmin = TMath::Min((Double_t)1,
(Double_t)0.001 * wmax);
wlmin = TMath::Log10(wmin);
wlmax = TMath::Log10(wmax);
}
Double_t ws = wlmax - wlmin;
Int_t ncolors = gStyle->GetNumberOfColors();
Int_t ndivz = fH->GetContour();
if (ndivz == 0) return;
ndivz = TMath::Abs(ndivz);
Int_t theColor, color;
Double_t scale = ndivz / (wlmax - wlmin);
for (Int_t i = 0; i < ndivz; i++) {
zc = fH->GetContourLevel(i);
if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
zc = TMath::Log10(zc);
w1 = zc;
if (w1 < wlmin) w1 = wlmin;
w2 = wlmax;
if (i < ndivz - 1) {
zc = fH->GetContourLevel(i + 1);
if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
zc = TMath::Log10(zc);
w2 = zc;
}
if (w2 <= wlmin) continue;
y1 = ymin + (w1 - wlmin) * (ymax - ymin) / ws;
y2 = ymin + (w2 - wlmin) * (ymax - ymin) / ws;
if (fH->TestBit(TH1::kUserContour)) {
color = i;
} else {
color = Int_t(0.01 + (w1 - wlmin) * scale);
}
theColor = Int_t((color + 0.99) * Double_t(ncolors) / Double_t(ndivz));
SetFillColor(gStyle->GetColorPalette(theColor));
TAttFill::Modify();
gPad->PaintBox(xmin, y1, xmax, y2);
}
Int_t ndiv = fH->GetZaxis()->GetNdivisions() % 100;
char chopt[6] = "S ";
chopt[1] = 0;
strncat(chopt, "+L", 2);
if (ndiv < 0) {
ndiv = TMath::Abs(ndiv);
strncat(chopt, "N", 1);
}
if (gPad->GetLogz()) {
wmin = TMath::Power(10., wlmin);
wmax = TMath::Power(10., wlmax);
strncat(chopt, "G", 1);
}
fAxis.PaintAxis(xmax, ymin, xmax, ymax, wmin, wmax, ndiv, chopt);
}
void TPaletteAxis::SavePrimitive(ostream &out, Option_t * )
{
out << " " << endl;
if (gROOT->ClassSaved(TPaletteAxis::Class())) {
out << " ";
} else {
out << " " << ClassName() << " *";
}
if (fOption.Contains("NDC")) {
out << "palette = new " << ClassName() << "(" << fX1NDC << "," << fY1NDC << "," << fX2NDC << "," << fY2NDC
<< "," << fH->GetName() << ");" << endl;
} else {
out << "palette = new " << ClassName() << "(" << fX1 << "," << fY1 << "," << fX2 << "," << fY2
<< "," << fH->GetName() << ");" << endl;
}
out << "palette->SetLabelColor(" << fAxis.GetLabelColor() << ");" << endl;
out << "palette->SetLabelFont(" << fAxis.GetLabelFont() << ");" << endl;
out << "palette->SetLabelOffset(" << fAxis.GetLabelOffset() << ");" << endl;
out << "palette->SetLabelSize(" << fAxis.GetLabelSize() << ");" << endl;
out << "palette->SetTitleOffset(" << fAxis.GetTitleOffset() << ");" << endl;
out << "palette->SetTitleSize(" << fAxis.GetTitleSize() << ");" << endl;
SaveFillAttributes(out, "palette", -1, -1);
SaveLineAttributes(out, "palette", 1, 1, 1);
}
void TPaletteAxis::UnZoom()
{
TView *view = gPad->GetView();
if (view) {
delete view;
gPad->SetView(0);
}
fH->GetZaxis()->SetRange(0, 0);
if (fH->GetDimension() == 2) {
fH->SetMinimum();
fH->SetMaximum();
fH->ResetBit(TH1::kIsZoomed);
}
}