root-project / root

The official repository for ROOT: analyzing, storing and visualizing big data, scientifically
https://root.cern
Other
2.71k stars 1.29k forks source link

Enable embedding hyperlinks in TLegend #16512

Open vepadulano opened 2 months ago

vepadulano commented 2 months ago

Explain what you would like to see improved and how.

I have a simple snippet which produces a plot (in PDF or SVG) where the text items in the legend are clickable hyperlinks:

from matplotlib import pyplot as plt
plt.rcParams['svg.fonttype'] = 'none'
fig = plt.figure()
plt.scatter([1], [2], label="CERN")
plt.scatter([1], [2.25], label="ROOT")
leg = plt.legend()
for ta in leg.texts:
    t = ta.get_text()
    if t == "CERN":
        url = 'https://home.cern'
        ta.set_url(url)
    elif t == "ROOT":
        url = 'https://root.cern'
        ta.set_url(url)

fig.savefig('scatter.svg')
fig.savefig('scatter.pdf')

Can be run with python repro.py and saves both SVG and PDF files with the clickable links in the legend.

It would be nice to have the same feature also for TLegend. I have taken a look at TLink but despite what the docs hint at, that cannot be used to show hyperlinks, rather only links between different graphical components of the same canvas/browser.

ROOT version

Any

Installation method

Any

Operating system

Any

Additional context

No response

couet commented 1 month ago

@vepadulano can you post the 2 files generated by your macro ?

dpiparo commented 1 month ago

scatter.pdf scatter.svg.zip

scatter

couet commented 1 month ago

Thanks, I think I have an idea: TText inherits from TNamed. The text to be drawn is stored in the member fTitle of TNamed. The Member fName is not used. One can use this member to store the URL and if not null it will be added in SVG and PDF (may be PS via pdfmark). SVG should be easy. PDF is more tricky.

couet commented 1 month ago

I made a quick and dirty prototyping (for SVG only for the time being). The macro is:

void texturl() {
   auto t = new TText(.5,.5,"CERN");
   t->Draw();
   t->SetName("https://cern.ch"); // Will be SetUrl
   gPad->Print("texturl.svg");
}

The result is:
texturl

couet commented 1 month ago

After a discussion with @vepadulano it appears that it might be better to add a data member fUrl to TAttText, so that all the classes inheriting from it will benefit from this feature.

linev commented 1 month ago

I add preliminary support of URLs also in the JSROOT - see example link:

https://jsroot.gsi.de/dev/?file=../files/tmp/latex_url.root&item=c1

It also works when export into PDF.

And I do not think that TAttText class is proper place for additional data member. There are many derived classes like TGaxis or TStyle where such member will be useless - while there is no sense to provide URL for them.

Most straight solution - just introduce TLatexUrl which will have additional TString fUrl member. And if necessary - introduce special TLegendEntryUrl for same purposes.

linev commented 1 month ago

@couet

That also can be done - one can extend TLatex functionality, adding #url command:

auto l1 = new TLatex(0.5, 0.5, "Link on #url[https://root.cern]{root.cern} web site");

Using TLatex syntax, one can provide more attributes like colors or underline.

couet commented 1 month ago

@linev Yes that's also a nice possibility. Yes the TAttText approach might be not correct. You are right. What is the sense of TGaxis::SetUrl?

linev commented 1 month ago

What is the sense of TGaxis::SetUrl?

This is exactly my point.

I will provide preliminary implementation of #url[] in the latex parser of JSROOT. I also will add demo in webcanvas tutorials.

linev commented 1 month ago

16572 includes implementation of #url[link]{label} latex syntax for web canvas and provides demo for it.

Means in any place where TLatex used for rendering (histogram title, legend entry text, axis title) one can include any web link.

Unfortunately, such feature is very difficult to implement in interactive classical graphics :(

couet commented 1 month ago

#url can be implemented in the classic TLatex, but that's a new keyword and it is not as easy as in web graphics. If it is really needed it can be done. However having new funtionnalities in the new graphics, not present in the old one can also be a good way to motivate poeple to move toward the new graphics.

couet commented 1 month ago

I think instead of #url[link]{label} we might also use a simpler syntax like in markdown. something like [label](link). No need for a special #url keyword. Then it will be enough to look for the string ](http to know that there is a text with some link.

linev commented 1 month ago

Looking for #url[http will do the same with my approach. But it is detail.

couet commented 1 month ago

Yes, it is a detail. I am only saying that a new keyword is not mandatory if we follow the markdown syntax.

linev commented 1 month ago

if we follow the markdown syntax

I would not mix Markdown and TLatex.

TLatex is a single-line text, like axis or histogram title. It cannot provide Markdown features in this respect.

Markdown is more about page layout.

couet commented 1 month ago

Ok, up to you