# Making TikZ nodes hyperlinkable

I have a TikZ tree. Now I want to make the nodes click-able directing to relevant sections in the document (or directed to URLs). Some of the content in the nodes are not text. Is it possible to turn the nodes into links, and if so, how? I would prefer the nodes themselves to be links, and not the text they contain.

Addition: I am not really good at it, and still learning, but here is a skeletal outline of the idea I am working on... (a graphical table of contents)

\documentclass{minimal}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
\tikzstyle{level 1}=[sibling distance=60mm]
\tikzstyle{level 2}=[sibling distance=25mm]

\node[circle,draw,grow=down] {\textbf{COOL TOC}}
child {node {installation}
child {node {Linux}}
child {node {Mac}}
child {node {Windows}}
}
child {node {Get Started}
child {node {do A}}
child {node {do B}}
}
child {node {Looking Further}
child {node {manual}}
child {node {online}}
}
child[grow=up] {node {troubleshoot}
child {node {if X happens}}
child {node {if Y happens}}
};
\end{tikzpicture}

\end{document}


There are fancier examples for example this one would make for a great TOC.

• Please add a minimal working example (MWE) that shows what you've done thus far in terms of creating a tikz tree with some document elements.
– Werner
Nov 25, 2011 at 4:10
• @Werner I added the MWE.
– yayu
Nov 25, 2011 at 4:47
• I added a little code to complete the MWE. An MWE should provide sufficient code for a simple copy-paste-compile so that someone interested in finding a solution doesn't have to do any puzzling over what packages you're using, or type \documentclass etc. which gets boring. This is a nice question! Nov 25, 2011 at 14:47

Here's a new TikZ style called hyperlink node=<target> that takes a hypertarget reference. It works by measuring the node it is supplied to, and then placing a new invisible node on top of that. The new node has the content \hyperlink{<target>}{\phantom{\rule{<width of node>}{<height of node>}}, so it has the same size as the original node, but the whole area is clickable.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\tikzset{
alias=sourcenode,
append after command={
let     \p1 = (sourcenode.north west),
\p2=(sourcenode.south east),
\n1={\x2-\x1},
\n2={\y1-\y2} in
node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\p1)] {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n1}{\n2}}}}}
%xelatex needs \XeTeXLinkBox, won't create a link unless it
%finds text --- rules don't work without \XeTeXLinkBox.
%Still builds correctly with pdflatex and lualatex
}
}
}

\tikz \node [draw, inner sep=2ex,hyperlink node=pagetwo] {Go to Page Two};

\clearpage
\hypertarget{pagetwo}{Page Two}
\end{document}

• Very nice! I wanted to put a url link into the document so I exchanged \hyperlink with \href. This works as expected. Mar 4, 2013 at 16:15
• This doesn't work for me. The output PDF has the node but it is not clickable. There were no errors in compilation, and I tried it with both Okular and Evince.
– jja
Mar 12, 2013 at 14:50
• @jja: Are you using pdflatex for the compilation?
– Jake
Mar 12, 2013 at 15:05
• Ah, that was it. I was using xelatex and it didn't work, but I just compiled with pdflatex and it worked perfectly. I guess a follow-up question would be how to do this with xelatex, if it can be done at all...
– jja
Mar 12, 2013 at 16:23
• I've tried to add this to an existing drawing and get the error message Package pgf Error: No shape named is known. (note the two spaces after named. Any ideas? Feb 10, 2014 at 19:59

Apart from Jake's nice idea – here's some code that works fine here in a recent document using the code from Drawing a directory listing a la the tree command in TikZ (answer of A. Stacey) and your MWE. It's not as fancy as your's, but maybe stylish, too.

\documentclass{article}

\usepackage{tikz}
%------------------%
\makeatletter
\newcount\dirtree@lvl
\newcount\dirtree@plvl
\newcount\dirtree@clvl
\def\dirtree@growth{%
\ifnum\tikznumberofcurrentchild=1\relax
\expandafter\xdef\csname dirtree@p@\the\dirtree@plvl\endcsname{\the\dirtree@lvl}
\fi
\dirtree@clvl=\dirtree@lvl
\advance\dirtree@clvl by -\csname dirtree@p@\the\dirtree@plvl\endcsname
\pgf@xa=0.5cm\relax % change the length to your needs
\pgf@ya=-0.75cm\relax % change the length to your needs
\pgf@ya=\dirtree@clvl\pgf@ya
\pgftransformshift{\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}%
\ifnum\tikznumberofcurrentchild=\tikznumberofchildren
\fi
}
\tikzset{ %definition of a new style "dirtree"
dirtree/.style={
growth function=\dirtree@growth,
every node/.style={anchor=north},
every child node/.style={anchor=west},
edge from parent path={(\tikzparentnode\tikzparentanchor) |- (\tikzchildnode\tikzchildanchor)}
}
}
\makeatother
%------------------%

\usepackage{hyperref}

\begin{document}

\begin{tikzpicture}[dirtree] % it's what we defined above

\node {\textbf{COOL TOC}}
child { node {\hyperref[install]{installation} }
child { node {\hyperref[linux]{Linux}} }
child { node {\hyperref[mac]{Mac}} }
child { node {\hyperref[win]{Windows}} }
}
child {node {\hyperref[start]{Get Started}}
child { node {\hyperref[caseA]{do A}} }
child { node {\hyperref[caseB]{do B}} }
}
child {node {\hyperref[trbl-shoot]{troubleshoot}}
child {node {\hyperref[caseX]{if X happens}}}
child {node {\hyperref[caseY]{if Y happens}}}
}
% I've put the external resources to the end:
child {node {Looking Further}
child { node {\href{file:manual.pdf}{manual}} }% works only, if "manual.pdf" is in
% the same directory as the compiled
% version of this document
child { node {\href{http://website.example.com/online-resource/}{online}} }
};
\end{tikzpicture}

\section*{Installation}\label{install}
\subsection*{Linux}\label{linux}
Some content.

\subsection*{Mac}\label{mac}
Some content.

\subsection*{Windows}\label{win}
Some content.

\section*{Get started}\label{start}
\subsection*{First: Do A}\label{caseA}
Some content.

\subsection*{Second: Do B}\label{caseB}
Some content.

\section*{Trouble shooting}\label{trbl-shoot}
\subsection*{If X happens:}\label{caseX}
Some content.

\subsection*{If Y happens:}\label{caseY}
Some content.

\end{document}


Here is a little improvement of Jake's answer. Thanks to frougon's comment, different values for outer xsep and outer ysep are now correctly considered.

### Problem

• The options line width and outer sep are not considered. Therefore, the link box is usually too large (only working case is outer sep=0).
• DrBones addendum does not solve this problem, because it only changes the size of the hyperlink node, but not the hyperlink area itself.

### Solution

If outer sep is not set, it is half of line width. Therefore, we just have to use outer sep to solve the following cases.

I defined \n0 and \n1 as outer xsep and outer ysep and shifted the two points by that values to the middle of the node:

let \n0={\pgfkeysvalueof{/pgf/outer xsep}},
\n1={\pgfkeysvalueof{/pgf/outer ysep}},
\p1=([shift={(\n0, -\n1)}] sourcenode.north west),
\p2=([shift={(-\n0, \n1)}] sourcenode.south east),


### Visualization and Description

• The node has a thick cyan border.
• The black rectangle surrounds the node anchors (north west and south east).
• The yellow rectangle is the visualization of the hyperlink area.
• The passed options are shown in the lower part of the figure.
• If yellow (hyperlink areas) and cyan (node borders) overlap, we get green, as we see in the hyperlink dexteritas variant.

### Code

\documentclass[border=2mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

% NOTE: added option "test highlight" for testing (can be removed for normal usage)
\tikzset{
test highlight/.style={draw=yellow, draw opacity=0.5},
alias=sourcenode,
append after command={
let \p1=(sourcenode.north west),
\p2=(sourcenode.south east),
\n1={\x2-\x1},
\n2={\y1-\y2} in
node [inner sep=0pt, outer sep=0pt,anchor=north west,at=(\p1), test highlight] {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n1}{\n2}}}}}
%xelatex needs \XeTeXLinkBox, won't create a link unless it
%finds text --- rules don't work without \XeTeXLinkBox.
%Still builds correctly with pdflatex and lualatex
}
},
alias=sourcenode,
append after command={
let \n0={\pgfkeysvalueof{/pgf/outer xsep}},
\n1={\pgfkeysvalueof{/pgf/outer ysep}},
\p1=([shift={(\n0, -\n1)}] sourcenode.north west),
\p2=([shift={(-\n0, \n1)}] sourcenode.south east),
\n2={\x2-\x1},
\n3={\y1-\y2} in
node [inner sep=0pt, outer sep=0pt, anchor=north west, at=(\p1), test highlight] {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n2}{\n3}}}}}
%xelatex needs \XeTeXLinkBox, won't create a link unless it
%finds text --- rules don't work without \XeTeXLinkBox.
%Still builds correctly with pdflatex and lualatex
}
},
}

\begin{document}

\newcommand{\comparison}[1][]{
\begin{tikzpicture}[
line width=1mm,
node distance=5mm,
inner sep=2mm,
blend mode=darken,
#1
]

\foreach \variant [count=\i] in {Jake, dexteritas} {
\node[text width=25mm, font=\small\ttfamily] at (0,-6) {#1};
\node[draw=cyan, draw opacity=0.5, hyperlink \variant={test}] (a) at (0,-2*\i) {\variant};
\draw[very thin] (a.north west) rectangle (a.south east);
}
\end{tikzpicture}
}

\comparison
\comparison[outer sep=0mm]
\comparison[outer sep=3mm]
\comparison[outer xsep=1mm, outer ysep=4mm]

\end{document}

• Nice, can you please include this change in hyperlink dexteritas: append after command={ let \n0={\pgfkeysvalueof{/pgf/outer xsep}}, \n1={\pgfkeysvalueof{/pgf/outer ysep}}, \p1=([shift={(\n0, -\n1)}] sourcenode.north west), \p2=([shift={(-\n0, \n1)}] sourcenode.south east), \n2={\x2-\x1}, \n3={\y1-\y2} in node [inner sep=0pt, outer sep=0pt, anchor=north west, at=(\p1), draw=yellow, draw opacity=0.3] {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n2}{\n3}}}}}}? May 30 at 14:26
• Then it will work fine with e.g. \comparison[outer xsep=3mm, outer ysep=4mm]. (Less important: in order to visualize things better, I added draw opacity=0.3 next to the two draw=yellow options.) May 30 at 14:26
• @frougon Thank you for pointing this out, I have adjusted the answer accordingly. Actually, it should have been obvious that if there is an outer xsep also an outer ysep exists, but I had only ever used outer sep, which made this not noticeable. The idea with the transparency is also good :) Jun 2 at 15:23

Just a small addendum to Jake's excellent answer and unfortunately as an answer since I can't comment yet.

I had to place many links in close proximity and for the newly created hyperref node not to protrude the original node more than it has to I had to compensate for the current line width via inner sep=-0.5\pgflinewidth, and set the \XeTeXLinkMargin to zero i.e.

\setlength{\XeTeXLinkMargin}{0pt}
\tikzset{
alias=sourcenode,
append after command={
let \p1= (sourcenode.north west),
\p2= (sourcenode.south east),
\n1={\x2-\x1},
\n2={\y1-\y2} in