And dots represents the hits (wire positions) in the chamber. I want to make all hits (red dots) to buttons that when I click that button the waveform of that channel will be showed in a new window.
Any suggestion will be helpful! Even just telling me “It’s impossible”
I have read through these two tutorials, and I got what you mean “this part”, now I have one question related to the function in TCanvas::HighlightConnect() : UserFunction(TVirtualPad* pad, TObject* obj, Int_t ihp, Int_t y)
In my understanding this function will be called when the mouse is pointing to the ith point on the TGraph (or histogram). But what I need is:
I have a map of TGraphs which is channel to waveform (not all channels have waveform), so I use TGraph::SetPoint(channel, x, y) to set the point on the TGraph. The problem is the point that I didn’t set (let’s say I set 2,4,6th point) will be created automatically and result on the TGraph, is there a way to disable auto creation?
I solved the problem above by moving unused points out of window (99999, 99999). If you have better (or decent) solution please teach me!
Now I got another question:
I want to make the HighlightGraph(TVirtualPad* pad, TObject* obj, Int_t ihp, Int_t y) as a member function in the same class, but when I connected it to canvas:
TCanvas::HighlightConnect() method is simplified version which only allows to connect global functions, but not objects methods. See docu. You can use TQObject::Connect():
auto receiver = new ReceiverClass("receiver");
auto Canvas = new TCanvas("Canvas", "Canvas", 0, 0, 700, 500);
Canvas->Connect("Highlighted(TVirtualPad*,TObject*,Int_t,Int_t)",
"ReceiverClass", receiver, "HighlightHisto(TVirtualPad*,TObject*,Int_t,Int_t)");
I attach modified version of hlGraph1.C tutorial macro:
Thank you for the reply, I have tried this method (my last post) but it didn’t work and give this:
Error in <TQObject::CheckConnectArgs>: slot HighlightGraph(TVirtualPad*,TObject*,int,int) does not exist
But as you pointed my class EventDisplay is no derived from ROOT classes, so there is no dictionary of it. Should I derive it from TNamed and make a dictionary?
When code runs as macro ROOT automatically creates dictionary for all used classes.
If you build and run your application differently - you need to create dictionary for your EventDisplay class. It is not necessary to derive it from TObject.
Yes, you need to create new LinkDef.h file with minimal content:
#ifdef __CLING__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class EventDisplay+;
#endif
You can include your other classes - if it is required.
Surely the approach you are following now is possible one. However, let me propose another one. I modified an example I have (graphtext3.C) to retrieve which point has been clicked in a TGraph. Once you have it, you are then free to draw whatever you want. In this example, I redraw the graph (as I mentioned, this is an example I already had).
const int Npoints = 3; // Number of points in the graph
const double x[Npoints] = {1.0, 2.0, 5.0};
const double y[Npoints] = {0.5, 1.0, 2.0};
const char *c[Npoints] = {"a","b","c"};
void graphtext3() {
TGraph *gr = new TGraph(Npoints, x, y);
gr->SetMarkerStyle(kCircle);
TExec *ex = new TExec("ex","DrawText();");
gr->GetListOfFunctions()->Add(ex);
gr->Draw("ALP");
gr->GetXaxis()->SetLabelSize(0);
gr->GetXaxis()->SetTickLength(0);
}
void DrawText()
{
Int_t i,n;
Double_t x,y;
TLatex *t;
TLine *l;
double eps = 0.01;
TGraph *g = (TGraph*)gPad->GetListOfPrimitives()->FindObject("Graph");
// Get event information
int event = gPad->GetEvent();
int px = gPad->GetEventX();
int py = gPad->GetEventY();
// Get the coordinates
double xd = gPad->AbsPixeltoX(px);
double yd = gPad->AbsPixeltoY(py);
float xp = gPad->PadtoX(xd);
float yp = gPad->PadtoY(yd);
n = g->GetN();
for (i=0; i<n; i++) {
g->GetPoint(i,x,y);
if (TMath::Abs(x-xp)<eps && TMath::Abs(y-yp)<eps) printf("Point %d has been clicked\n",i);
}
double ymin = g->GetHistogram()->GetMinimum();
double ymax = g->GetHistogram()->GetMaximum();
double dy = (ymax-ymin);
for (i=0; i<n; i++) {
g->GetPoint(i,x,y);
t = new TLatex(x, ymin-0.03*dy, Form("%s (%4.2f,%4.2f)",c[i],x,y));
t->SetTextSize(0.025);
t->SetTextFont(42);
t->SetTextAlign(21);
t->Paint();
l = new TLine(x,ymin,x,ymin+0.03*dy);
l->Paint();
}
}