Skip to content

Commit fb74a41

Browse files
authored
New Method TPad::DivideRatios
New Method TPad::DivideRatios
1 parent 774ee3f commit fb74a41

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

graf2d/gpad/inc/TPad.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ friend class TWebCanvas;
186186
void CopyPixmaps() override;
187187
void DeleteExec(const char *name) override;
188188
void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0) override; // *MENU*
189+
void DivideRatios(Int_t nrows, Int_t ncolumns, const std::vector<double>& widthRatios={}, const std::vector<double>& heightRatios={}, const double canvasTopMargin=0., const double canvasLeftMargin=0.);
189190
virtual void DivideSquare(Int_t n, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0);
190191
void Draw(Option_t *option="") override;
191192
void DrawClassObject(const TObject *obj, Option_t *option="") override;

graf2d/gpad/src/TPad.cxx

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,108 @@ void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t co
13451345
Modified();
13461346
}
13471347

1348+
////////////////////////////////////////////////////////////////////////////////
1349+
/// Divide the canvas according to ratios.
1350+
///
1351+
/// The current canvas is divided in nx by ny according to the width and height ratios.
1352+
/// If the ratios are not specified they are assumed to be equal.
1353+
///
1354+
/// Pads are automatically named `canvasname_n` where `n` is the division number
1355+
/// starting from top left pad.
1356+
///
1357+
/// Top and left margins can be defined.
1358+
1359+
void TPad::DivideRatios(Int_t nx, Int_t ny,
1360+
const std::vector<double>& widthRatios,
1361+
const std::vector<double>& heightRatios,
1362+
const double canvasTopMargin,
1363+
const double canvasLeftMargin
1364+
)
1365+
{
1366+
cd();
1367+
1368+
int wrs = widthRatios.size();
1369+
int hrs = heightRatios.size();
1370+
int nxl = TMath::Min(nx,wrs), nyl = TMath::Min(ny,hrs);
1371+
1372+
if (wrs==0) nxl = nx;
1373+
if (hrs==0) nyl = ny;
1374+
1375+
int pn = 1;
1376+
double xr = 0.;
1377+
double yr = 0.;
1378+
double x = 0.;
1379+
double y = 1.;
1380+
double x1, y1, x2, y2;
1381+
1382+
// Check the validity of the margins
1383+
if (canvasTopMargin <0 || canvasTopMargin >1 ) {
1384+
Error("DivideRatios", "The canvas top margin must be >= 0 and <= 1");
1385+
return;
1386+
} else {
1387+
y = 1.- canvasTopMargin;
1388+
}
1389+
if (canvasLeftMargin <0 || canvasLeftMargin >1 ) {
1390+
Error("DivideRatios", "The canvas left margin must be >= 0 and <= 1");
1391+
return;
1392+
}
1393+
1394+
// Check the validity of the ratios
1395+
double sumOfHeightRatios = canvasTopMargin;
1396+
if (hrs) {
1397+
for (int i=0; i<nyl; i++) {
1398+
yr = heightRatios[i];
1399+
sumOfHeightRatios = sumOfHeightRatios + yr;
1400+
if (yr <0 || yr >1 ) {
1401+
Error("DivideRatios", "Y ratios plus the top margin must be >= 0 and <= 1");
1402+
return;
1403+
}
1404+
}
1405+
}
1406+
if (sumOfHeightRatios > 1.) {
1407+
Error("DivideRatios", "The sum of Y ratios plus the top margin must be <= 1 %g",sumOfHeightRatios);
1408+
return;
1409+
}
1410+
double sumOfWidthRatios = canvasLeftMargin;
1411+
if (wrs) {
1412+
for (int j=0; j<nxl; j++) {
1413+
xr = widthRatios[j];
1414+
sumOfWidthRatios = sumOfWidthRatios +xr;
1415+
if (xr <0 || xr >1 ) {
1416+
Error("DivideRatios", "X ratios must be >= 0 and <= 1");
1417+
return;
1418+
}
1419+
}
1420+
}
1421+
if (sumOfWidthRatios > 1.) {
1422+
Error("DivideRatios", "The sum of X ratios must be <= 1 %g ",sumOfWidthRatios);
1423+
return;
1424+
}
1425+
1426+
// Create the pads according to the ratios
1427+
for (int i=0; i<nyl; i++) {
1428+
x = canvasLeftMargin;
1429+
if (hrs) yr = heightRatios[i];
1430+
else yr = 1./nyl;
1431+
for (int j=0; j<nxl; j++) {
1432+
if (wrs) xr = widthRatios[j];
1433+
else xr = 1./nxl;
1434+
x1 = TMath::Max(0., x);
1435+
y1 = TMath::Max(0., y - yr);
1436+
x2 = TMath::Min(1., x + xr);
1437+
y2 = TMath::Min(1., y);
1438+
auto pad = new TPad(TString::Format("%s_%d", GetName(), pn),
1439+
TString::Format("%s_%d", GetName(), pn),
1440+
x1, y1, x2 ,y2);
1441+
pad->SetNumber(pn);
1442+
pad->Draw();
1443+
x = x + xr;
1444+
pn++;
1445+
}
1446+
y = y - yr;
1447+
}
1448+
}
1449+
13481450
////////////////////////////////////////////////////////////////////////////////
13491451
/// "n" is the total number of sub-pads. The number of sub-pads along the X
13501452
/// and Y axis are computed according to the square root of n.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/// \file
2+
/// \ingroup tutorial_graphics
3+
/// \preview Example of canvas partitioning with ratios
4+
/// The TPad::DivideRatios method enables partitioning of the canvas according to different
5+
///
6+
/// \macro_image
7+
/// \macro_code
8+
///
9+
/// \author Olivier Couet
10+
11+
void colorpads(TCanvas *C, int n) {
12+
TPad *p;
13+
for (int i =1; i<=n; i++) {
14+
p = (TPad*)C->cd(i);
15+
p->SetFillColor(100+i);
16+
p->Modified();
17+
p->Update();
18+
}
19+
}
20+
21+
void canvas3() {
22+
// canvas divided 2x2 with 4 different ratios along X and Y
23+
auto C1 = new TCanvas("C1", "C1", 400, 400);
24+
C1->DivideRatios(2, 2, {.2,.8}, {.4,.6}); colorpads(C1,4);
25+
26+
// canvas divided 2x3 with ratios defined only in X
27+
auto C2 = new TCanvas("C2", "C2", 400, 0, 400, 400);
28+
C2->DivideRatios(2, 3, {.2,.8}); colorpads(C2,6);
29+
30+
// canvas divided 2x2 with no ratios defined
31+
auto C3 = new TCanvas("C3", "C3", 0, 455, 400, 400);
32+
C3->DivideRatios(2, 2); colorpads(C3,4);
33+
34+
// canvas divided 2x2 with ratios and margins
35+
auto C4 = new TCanvas("C4", "C4", 400, 455, 400, 400);
36+
C4->DivideRatios(2, 2, {.2,.7}, {.4,.5}, 0.05, 0.01); colorpads(C4,4);
37+
}

0 commit comments

Comments
 (0)