Logo ROOT   6.12/07
Reference Guide
TParallelCoordRange.cxx
Go to the documentation of this file.
1 // @(#)root/treeviewer:$Id$
2 // Author: Bastien Dalla Piazza 02/08/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TParallelCoordRange.h"
13 #include "TParallelCoord.h"
14 #include "TParallelCoordVar.h"
15 
16 #include "TBox.h"
17 #include "TPolyLine.h"
18 #include "TList.h"
19 #include "TVirtualPad.h"
20 #include "TVirtualX.h"
21 #include "TPoint.h"
22 #include "TFrame.h"
23 #include "Riostream.h"
24 #include "TCanvas.h"
25 #include "TString.h"
26 
28 
29 /** \class TParallelCoordRange
30 A TParallelCoordRange is a range used for parallel coordinates plots.
31 */
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// Default constructor.
35 
37  :TNamed("Range","Range"), TAttLine(), fSize(0.01)
38 {
39  fMin = 0;
40  fMax = 0;
41  fVar = NULL;
42  fSelect = NULL;
45 }
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// Destructor.
49 
51 {
52 }
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// Normal constructor.
56 
58  :TNamed("Range","Range"), TAttLine(1,1,1), fSize(0.01)
59 {
60  if(min == max) {
61  min = var->GetCurrentMin();
62  max = var->GetCurrentMax();
63  }
64  fMin = min;
65  fMax = max;
66 
67  fVar = var;
68  fSelect = NULL;
69 
70  if (!sel) {
72  if (s) fSelect = s;
73  else return;
74  } else {
75  fSelect = sel;
76  }
77 
79 
82 }
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 /// Make the selection which owns the range to be drawn on top of the others.
86 
88 {
89  TList *list = fVar->GetParallel()->GetSelectList();
90  list->Remove(fSelect);
91  list->AddLast(fSelect);
92  gPad->Update();
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Delete the range.
97 
98 void TParallelCoordRange::Delete(const Option_t* /*options*/)
99 {
100  fVar->GetRanges()->Remove(this);
102  delete this;
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Compute the distance to the primitive.
107 
109 {
110  if(TestBit(kShowOnPad)){
111  Double_t xx,yy,thisx=0,thisy=0;
112  xx = gPad->AbsPixeltoX(px);
113  yy = gPad->AbsPixeltoY(py);
114  fVar->GetXYfromValue(fMin,thisx,thisy);
115  Int_t dist = 9999;
116  if(fVar->GetVert()){
117  if(xx > thisx-2*fSize && xx < thisx && yy > thisy-fSize && yy<thisy+fSize) dist = 0;
118  fVar->GetXYfromValue(fMax,thisx,thisy);
119  if(xx > thisx-2*fSize && xx < thisx && yy > thisy-fSize && yy<thisy+fSize) dist = 0;
120  } else {
121  if(yy > thisy-2*fSize && yy < thisy && xx > thisx-fSize && xx<thisx+fSize) dist = 0;
122  fVar->GetXYfromValue(fMax,thisx,thisy);
123  if(yy > thisy-2*fSize && yy < thisy && xx > thisx-fSize && xx<thisx+fSize) dist = 0;
124  }
125  return dist;
126  } else return 9999;
127 }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Draw a TParallelCoordRange.
131 
133 {
134  AppendPad(options);
135 }
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 /// Execute the entry.
139 
141 {
142  if (!gPad) return;
143  if (!gPad->IsEditable() && entry!=kMouseEnter) return;
144 
145  Bool_t vert = fVar->GetVert();
146  static Int_t pxold, pyold;
147  static Int_t mindragged = -1; //-1:nothing dragged, 0:max dragged, 1:mindragged, 2:both dragged;
148  Int_t plx1,plx2,ply1,ply2;
149 
150  Double_t xx,yy,txxmin=0,txxmax=0,tyymin=0,tyymax=0;
151  TFrame *frame = gPad->GetFrame();
152  xx = gPad->AbsPixeltoX(px);
153  yy = gPad->AbsPixeltoY(py);
154  fVar->GetXYfromValue(fMin,txxmin,tyymin);
155  fVar->GetXYfromValue(fMax,txxmax,tyymax);
156  if (vert) {
157  plx1 = gPad->XtoAbsPixel(txxmin-2*fSize);
158  plx2 = gPad->XtoAbsPixel(txxmax-2*fSize);
159  ply1 = gPad->YtoAbsPixel(tyymin+fSize);
160  ply2 = gPad->YtoAbsPixel(tyymax-fSize);
161  } else {
162  plx1 = gPad->XtoAbsPixel(txxmin+fSize);
163  plx2 = gPad->XtoAbsPixel(txxmax-fSize);
164  ply1 = gPad->YtoAbsPixel(tyymin-2*fSize);
165  ply2 = gPad->YtoAbsPixel(tyymax-2*fSize);
166  }
167 
168  gPad->SetCursor(kPointer);
169  gVirtualX->SetLineColor(-1);
170  gVirtualX->SetLineWidth(1);
171  TPoint *p = NULL;
172  switch (entry) {
173  case kButton1Down:
175  ((TCanvas*)gPad)->Selected(gPad,fVar->GetParallel(),1);
176  if ((vert && yy<tyymax-fSize) || (!vert && xx < txxmax-fSize)) { //checks if the min slider is clicked.
177  mindragged = 1;
178  p = GetSliderPoints(fMin);
179  gVirtualX->DrawPolyLine(5,p);
180  delete [] p;
181  } else {
182  mindragged = 0;
183  p = GetSliderPoints(fMax);
184  gVirtualX->DrawPolyLine(5,p);
185  delete [] p;
186  }
187  gVirtualX->DrawLine(plx1,ply1,plx2,ply2);
188  break;
189  case kButton1Up: {
190  Double_t min = fMin, max= fMax;
191  if (mindragged == 1) min = fVar->GetValuefromXY(xx,yy);
192  if (mindragged == 0) max = fVar->GetValuefromXY(xx,yy);
193  if(fMin!=min || fMax != max) {
194  if (min>max) {
195  Double_t mem = min;
196  min = max;
197  max = mem;
198  }
199  fMin = min;
200  fMax = max;
201  gPad->Modified();
202  }
203  mindragged = -1;
204  break;
205  }
206  case kMouseMotion:
207  pxold = px;
208  pyold = py;
209  break;
210  case kButton1Motion:
211  if((vert && yy > frame->GetY1() && yy < frame->GetY2()) ||
212  (!vert && xx > frame->GetX1() && xx < frame->GetX2())){
213  if (vert) p = GetSliderPoints(pyold);
214  else p = GetSliderPoints(pxold);
215  gVirtualX->DrawPolyLine(5,p);
216  delete [] p;
217  if (vert) p = GetBindingLinePoints(pyold,mindragged);
218  else p = GetBindingLinePoints(pxold,mindragged);
219  gVirtualX->DrawPolyLine(2,p);
220  delete [] p;
221  if (vert) p = GetSliderPoints(py);
222  else p = GetSliderPoints(px);
223  gVirtualX->DrawPolyLine(5,p);
224  delete [] p;
225  if (vert) p = GetBindingLinePoints(py,mindragged);
226  else p = GetBindingLinePoints(px,mindragged);
227  gVirtualX->DrawPolyLine(2,p);
228  delete [] p;
229  if (TestBit(kLiveUpdate)){
230  Double_t min = fMin, max= fMax;
231  if (mindragged == 1) min = fVar->GetValuefromXY(xx,yy);
232  if (mindragged == 0) max = fVar->GetValuefromXY(xx,yy);
233  if(fMin!=min || fMax != max) {
234  if (min>max) {
235  Double_t mem = min;
236  min = max;
237  max = mem;
238  }
239  fMin = min;
240  fMax = max;
241  gPad->Modified();
242  gPad->Update();
243  }
244  }
245  }
246  pxold = px;
247  pyold = py;
248  break;
249  default:
250  //std::cout<<"entry: "<<entry<<std::endl;
251  break;
252  }
253 }
254 
255 ////////////////////////////////////////////////////////////////////////////////
256 /// Return the points of the line binding the two needles of the range.
257 
259 {
260  Double_t txx,tyy,txxo,tyyo=0;
261  if (fVar->GetVert()){
262  txx = fVar->GetX();
263  tyy = gPad->AbsPixeltoY(pos);
264  } else {
265  tyy = fVar->GetY();
266  txx = gPad->AbsPixeltoX(pos);
267  }
268  if (mindragged==1) fVar->GetXYfromValue(fMax,txxo,tyyo);
269  else fVar->GetXYfromValue(fMin,txxo,tyyo);
270 
271  TPoint *bindline = new TPoint[2];
272  if (fVar->GetVert()) {
273  if (mindragged==1) {
274  bindline[0] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyy+fSize));
275  bindline[1] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyyo-fSize));
276  } else {
277  bindline[0] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyyo+fSize));
278  bindline[1] = TPoint(gPad->XtoAbsPixel(txx-2*fSize),gPad->YtoAbsPixel(tyy-fSize));
279  }
280  } else {
281  if (mindragged==1) {
282  bindline[0] = TPoint(gPad->XtoAbsPixel(txx+fSize),gPad->YtoAbsPixel(tyy-2*fSize));
283  bindline[1] = TPoint(gPad->XtoAbsPixel(txxo-fSize),gPad->YtoAbsPixel(tyy-2*fSize));
284  } else {
285  bindline[0] = TPoint(gPad->XtoAbsPixel(txxo+fSize),gPad->YtoAbsPixel(tyy-2*fSize));
286  bindline[1] = TPoint(gPad->XtoAbsPixel(txx-fSize),gPad->YtoAbsPixel(tyy-2*fSize));
287  }
288  }
289  return bindline;
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Return the points to paint the needles at "value".
294 
296 {
297  Double_t txx=0,tyy=0;
298  fVar->GetXYfromValue(value,txx,tyy);
299  Int_t tx[5];
300  Int_t ty[5];
301  if (fVar->GetVert()) {
302  tx[0]=gPad->XtoAbsPixel(txx);
303  tx[1]=tx[4]=gPad->XtoAbsPixel(txx-fSize);
304  ty[0]=ty[1]=ty[4]=gPad->YtoAbsPixel(tyy);
305  tx[2]=tx[3]=gPad->XtoAbsPixel(txx-2*fSize);
306  ty[2]=gPad->YtoAbsPixel(tyy+fSize);
307  ty[3]=gPad->YtoAbsPixel(tyy-fSize);
308  } else {
309  ty[0]=gPad->YtoAbsPixel(tyy);
310  ty[1]=ty[4]=gPad->YtoAbsPixel(tyy-fSize);
311  tx[0]=tx[1]=tx[4]=gPad->XtoAbsPixel(txx);
312  ty[2]=ty[3]=gPad->YtoAbsPixel(tyy-2*fSize);
313  tx[2]=gPad->XtoAbsPixel(txx-fSize);
314  tx[3]=gPad->XtoAbsPixel(txx+fSize);
315  }
316  TPoint *slider = new TPoint[5];
317  for(UInt_t ui=0;ui<5;++ui) slider[ui] = TPoint(tx[ui],ty[ui]);
318  return slider;
319 }
320 
321 ////////////////////////////////////////////////////////////////////////////////
322 /// Return the points to paint the needle at "pos".
323 
325 {
326  Double_t txx,tyy;
327  if (fVar->GetVert()){
328  txx = fVar->GetX();
329  tyy = gPad->AbsPixeltoY(pos);
330  } else {
331  tyy = fVar->GetY();
332  txx = gPad->AbsPixeltoX(pos);
333  }
334 
335  Int_t tx[5];
336  Int_t ty[5];
337  if (fVar->GetVert()) {
338  tx[0]=gPad->XtoAbsPixel(txx);
339  tx[1]=tx[4]=gPad->XtoAbsPixel(txx-fSize);
340  ty[0]=ty[1]=ty[4]=gPad->YtoAbsPixel(tyy);
341  tx[2]=tx[3]=gPad->XtoAbsPixel(txx-2*fSize);
342  ty[2]=gPad->YtoAbsPixel(tyy+fSize);
343  ty[3]=gPad->YtoAbsPixel(tyy-fSize);
344  } else {
345  ty[0]=gPad->YtoAbsPixel(tyy);
346  ty[1]=ty[4]=gPad->YtoAbsPixel(tyy-fSize);
347  tx[0]=tx[1]=tx[4]=gPad->XtoAbsPixel(txx);
348  ty[2]=ty[3]=gPad->YtoAbsPixel(tyy-2*fSize);
349  tx[2]=gPad->XtoAbsPixel(txx-fSize);
350  tx[3]=gPad->XtoAbsPixel(txx+fSize);
351  }
352  TPoint *slider = new TPoint[5];
353  for(UInt_t ui=0;ui<5;++ui) slider[ui] = TPoint(tx[ui],ty[ui]);
354  return slider;
355 }
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Evaluate if the given value is within the range or not.
359 
361 {
362  return evtval>=fMin && evtval<=fMax;
363 }
364 
365 ////////////////////////////////////////////////////////////////////////////////
366 /// Paint a TParallelCoordRange.
367 
369 {
370  if(TestBit(kShowOnPad)){
373  }
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Paint a slider.
378 
380 {
382 
383  TPolyLine *p= new TPolyLine();
384  p->SetLineStyle(1);
385  p->SetLineColor(1);
386  p->SetLineWidth(1);
387 
388  Double_t *x = new Double_t[5];
389  Double_t *y = new Double_t[5];
390 
391  Double_t xx,yy;
392 
393  fVar->GetXYfromValue(value,xx,yy);
394  if(fVar->GetVert()){
395  x[0] = xx; x[1]=x[4]=xx-fSize; x[2]=x[3]=xx-2*fSize;
396  y[0]=y[1]=y[4]=yy; y[2] = yy+fSize; y[3] = yy-fSize;
397  } else {
398  y[0] = yy; y[1]=y[4]=yy-fSize; y[2]=y[3]= yy-2*fSize;
399  x[0]=x[1]=x[4]=xx; x[2]=xx-fSize; x[3] = xx+fSize;
400  }
401  if (fill) {
402  p->SetFillStyle(1001);
403  p->SetFillColor(0);
404  p->PaintPolyLine(4,&x[1],&y[1],"f");
405  p->SetFillColor(GetLineColor());
406  p->SetFillStyle(3001);
407  p->PaintPolyLine(4,&x[1],&y[1],"f");
408  }
409  p->PaintPolyLine(5,x,y);
410 
411  delete p;
412  delete [] x;
413  delete [] y;
414 }
415 
416 ////////////////////////////////////////////////////////////////////////////////
417 /// Print info about the range.
418 
419 void TParallelCoordRange::Print(Option_t* /*options*/) const
420 {
421  printf("On \"%s\" : min = %f, max = %f\n", fVar->GetTitle(), fMin, fMax);
422 }
423 
424 ////////////////////////////////////////////////////////////////////////////////
425 /// Make the selection which owns the range to be drawn under all the others.
426 
428 {
429  TList *list = fVar->GetParallel()->GetSelectList();
430  list->Remove(fSelect);
431  list->AddFirst(fSelect);
432  gPad->Update();
433 }
434 
435 ////////////////////////////////////////////////////////////////////////////////
436 /// Set the selection line color.
437 
439 {
440  fSelect->SetLineColor(col);
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Set the selection line width.
446 
448 {
449  fSelect->SetLineWidth(wid);
450 }
451 
452 
454 
455 /** \class TParallelCoordSelect
456 A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used
457 by TParallelCoord.
458 
459 Selections of specific entries can be defined over the data se using parallel
460 coordinates. With that representation, a selection is an ensemble of ranges
461 defined on the axes. Ranges defined on the same axis are conjugated with OR
462 (an entry must be in one or the other ranges to be selected). Ranges on
463 different axes are are conjugated with AND (an entry must be in all the ranges
464 to be selected). Several selections can be defined with different colors. It is
465 possible to generate an entry list from a given selection and apply it to the
466 tree using the editor ("Apply to tree" button).
467 */
468 
469 ////////////////////////////////////////////////////////////////////////////////
470 /// Default constructor.
471 
473  : TList(), TAttLine(kBlue,1,1)
474 {
475  fTitle = "Selection";
478 }
479 
480 ////////////////////////////////////////////////////////////////////////////////
481 /// Normal constructor.
482 
484  : TList(), TAttLine(kBlue,1,1)
485 {
486  fTitle = title;
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// Destructor.
493 
495 {
496  TIter next(this);
497  TParallelCoordRange* range;
498  while ((range = (TParallelCoordRange*)next())) range->GetVar()->GetRanges()->Remove(range);
499  TList::Delete();
500 }
501 
502 ////////////////////////////////////////////////////////////////////////////////
503 /// Activate the selection.
504 
506 {
507  TIter next(this);
508  TParallelCoordRange* range;
509  while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kShowOnPad,on);
510  SetBit(kActivated,on);
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 /// Show the ranges needles.
515 
517 {
518  TIter next(this);
519  TParallelCoordRange* range;
520  while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kShowOnPad,s);
521  SetBit(kShowRanges,s);
522 }
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used by TParallelCoord...
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
void PaintSlider(Double_t value, Bool_t fill=kFALSE)
Paint a slider.
TPoint * GetSliderPoints(Double_t value)
Return the points to paint the needles at "value".
TParallelCoordSelect()
Default constructor.
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
void CleanUpSelections(TParallelCoordRange *range)
Clean up the selections from the ranges which could have been deleted when a variable has been delete...
virtual void Delete(const Option_t *options="")
Delete the range.
TParallelCoordSelect * GetCurrentSelection()
Return the selection currently being edited.
Double_t GetX2() const
Definition: TBox.h:53
virtual void Draw(Option_t *options="")
Draw a TParallelCoordRange.
const char Option_t
Definition: RtypesCore.h:62
Double_t GetValuefromXY(Double_t x, Double_t y)
Get the value corresponding to the position.
fill
Definition: fit1_py.py:6
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:97
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
A TParallelCoordRange is a range used for parallel coordinates plots.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Double_t GetY2() const
Definition: TBox.h:55
~TParallelCoordRange()
Destructor.
void GetXYfromValue(Double_t value, Double_t &x, Double_t &y)
Get a position corresponding to the value on the axis.
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:149
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:105
TParallelCoord axes.
Double_t GetCurrentMin() const
Double_t x[n]
Definition: legend1.C:17
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance to the primitive.
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TParallelCoordSelect * fSelect
virtual void ExecuteEvent(Int_t entry, Int_t px, Int_t py)
Execute the entry.
Double_t GetCurrentMax() const
short Color_t
Definition: RtypesCore.h:79
virtual void SetLineColor(Color_t col)
Set the selection line color.
Definition: TPoint.h:31
A doubly linked list.
Definition: TList.h:44
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
~TParallelCoordSelect()
Destructor.
TParallelCoordVar * GetVar()
TParallelCoordVar * fVar
virtual void SendToBack()
Make the selection which owns the range to be drawn under all the others.
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
TList * GetSelectList()
unsigned int UInt_t
Definition: RtypesCore.h:42
#define gVirtualX
Definition: TVirtualX.h:350
Define a Frame.
Definition: TFrame.h:19
short Width_t
Definition: RtypesCore.h:78
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
TPoint * GetBindingLinePoints(Int_t pos, Int_t mindragged)
Return the points of the line binding the two needles of the range.
The Canvas class.
Definition: TCanvas.h:31
#define ClassImp(name)
Definition: Rtypes.h:359
Double_t GetX1() const
Definition: TBox.h:52
double Double_t
Definition: RtypesCore.h:55
virtual void SetLineWidth(Width_t wid)
Set the selection line width.
TParallelCoordSelect * SetCurrentSelection(const char *title)
Set the selection being edited.
virtual void Paint(Option_t *options)
Paint a TParallelCoordRange.
Double_t y[n]
Definition: legend1.C:17
static constexpr double s
TParallelCoord * GetParallel()
Bool_t IsIn(Double_t evtval)
Evaluate if the given value is within the range or not.
TParallelCoordRange()
Default constructor.
virtual void BringOnTop()
Make the selection which owns the range to be drawn on top of the others.
virtual void Print(Option_t *options) const
Print info about the range.
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:23
#define gPad
Definition: TVirtualPad.h:285
Double_t GetY1() const
Definition: TBox.h:54
Definition: Rtypes.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
Line Attributes class.
Definition: TAttLine.h:18
void SetShowRanges(Bool_t s)
Show the ranges needles.
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
void SetActivated(Bool_t on)
Activate the selection.