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