Logo ROOT  
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 "TPolyLine.h"
17#include "TList.h"
18#include "TVirtualPad.h"
19#include "TVirtualX.h"
20#include "TPoint.h"
21#include "TFrame.h"
22#include "TCanvas.h"
23#include "TString.h"
24
25#include <iostream>
26
28
29/** \class TParallelCoordRange
30A 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
98void 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;
179 gVirtualX->DrawPolyLine(5,p);
180 delete [] p;
181 } else {
182 mindragged = 0;
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");
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
419void 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
456A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used
457by TParallelCoord.
458
459Selections of specific entries can be defined over the data se using parallel
460coordinates. With that representation, a selection is an ensemble of ranges
461defined 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
463different axes are are conjugated with AND (an entry must be in all the ranges
464to be selected). Several selections can be defined with different colors. It is
465possible to generate an entry list from a given selection and apply it to the
466tree 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);
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);
522}
@ kMouseMotion
Definition: Buttons.h:23
@ kButton1Motion
Definition: Buttons.h:20
@ kButton1Up
Definition: Buttons.h:19
@ kButton1Down
Definition: Buttons.h:17
@ kMouseEnter
Definition: Buttons.h:23
size_t fSize
@ kPointer
Definition: GuiTypes.h:375
int Int_t
Definition: RtypesCore.h:45
unsigned int UInt_t
Definition: RtypesCore.h:46
const Bool_t kFALSE
Definition: RtypesCore.h:101
short Width_t
Definition: RtypesCore.h:91
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
short Color_t
Definition: RtypesCore.h:92
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:364
@ kBlue
Definition: Rtypes.h:66
#define gPad
Definition: TVirtualPad.h:287
#define gVirtualX
Definition: TVirtualX.h:338
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
Line Attributes class.
Definition: TAttLine.h:18
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
Double_t GetX1() const
Definition: TBox.h:50
Double_t GetY1() const
Definition: TBox.h:52
The Canvas class.
Definition: TCanvas.h:23
Define a Frame.
Definition: TFrame.h:19
A doubly linked list.
Definition: TList.h:44
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:822
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:100
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:470
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:152
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:107
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
A TParallelCoordRange is a range used for parallel coordinates plots.
virtual void Delete(const Option_t *options="")
Delete the range.
virtual void SetLineWidth(Width_t wid)
Set the selection line width.
TParallelCoordSelect * fSelect
Selection owning the range.
TParallelCoordVar * GetVar()
virtual ~TParallelCoordRange()
Destructor.
TParallelCoordVar * fVar
Variable owning the range.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute the distance to the primitive.
Bool_t IsIn(Double_t evtval)
Evaluate if the given value is within the range or not.
virtual void Paint(Option_t *options)
Paint a TParallelCoordRange.
virtual void SendToBack()
Make the selection which owns the range to be drawn under all the others.
virtual void BringOnTop()
Make the selection which owns the range to be drawn on top of the others.
virtual void SetLineColor(Color_t col)
Set the selection line color.
virtual void ExecuteEvent(Int_t entry, Int_t px, Int_t py)
Execute the entry.
void PaintSlider(Double_t value, Bool_t fill=kFALSE)
Paint a slider.
const Double_t fSize
Size of the painted range.
virtual void Print(Option_t *options) const
Print info about the range.
TPoint * GetBindingLinePoints(Int_t pos, Int_t mindragged)
Return the points of the line binding the two needles of the range.
virtual void Draw(Option_t *options="")
Draw a TParallelCoordRange.
Double_t fMin
Min value for the range.
Double_t fMax
Max value for the range.
TParallelCoordRange()
Default constructor.
TPoint * GetSliderPoints(Double_t value)
Return the points to paint the needles at "value".
A TParallelCoordSelect is a specialised TList to hold TParallelCoordRanges used by TParallelCoord.
void SetActivated(Bool_t on)
Activate the selection.
TParallelCoordSelect()
Default constructor.
void SetShowRanges(Bool_t s)
Show the ranges needles.
TParallelCoord axes.
Double_t GetValuefromXY(Double_t x, Double_t y)
Get the value corresponding to the position.
Double_t GetCurrentMax() const
TParallelCoord * GetParallel()
Double_t GetCurrentMin() const
void GetXYfromValue(Double_t value, Double_t &x, Double_t &y)
Get a position corresponding to the value on the axis.
TList * GetSelectList()
TParallelCoordSelect * GetCurrentSelection()
Return the selection currently being edited.
TParallelCoordSelect * SetCurrentSelection(const char *title)
Set the selection being edited.
void CleanUpSelections(TParallelCoordRange *range)
Clean up the selections from the ranges which could have been deleted when a variable has been delete...
@ kLiveUpdate
To paint the entries when being modified.
Definition: TPoint.h:31
Defined by an array on N points in a 2-D space.
Definition: TPolyLine.h:23
virtual void PaintPolyLine(Int_t n, Double_t *x, Double_t *y, Option_t *option="")
Draw this polyline with new coordinates.
Definition: TPolyLine.cxx:544
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
static constexpr double s
fill
Definition: fit1_py.py:6