15

I'd like to know if there's a way to make an arbitrary closed path in TikZ into a hyperlink; either directly or by turning it into a node. Here's an example of code to work with:

\documentclass[10pt,letterpaper]{article}
\usepackage{tikz}
\usepackage[colorlinks=true,urlcolor=blue,filecolor=magenta]{hyperref}
\begin{document}
\section{The Diagram}
\begin{center}
\begin{tikzpicture}
\node[draw,align=center] at (12, 0.2+.5) {Even \\ more};
\node[draw,align=center] at (12, 1.4+.5) {And \\ more1};
\node[draw,align=center] at (15, 2.8+.5) {Some \\ text };
\node[draw,align=center] at (15,1.8+.5) {More \\ text};
\draw[blue] (11,-.4+.5)--(13,-.4+.5)--(13,1.3+.5)--(16.5,1.3+.5)--(16.5,3.5+.5)--(11,3.5+.5) --(11,-.4+.5);
\end{tikzpicture}
\end{center}
\section{this is the target}
\hypertarget{target}{}
\end{document}

I'd like the path in blue to become a link going to the hypertarget labeled target. Since the path is oddly shaped, it doesn't correspond to any of the well-known node shapes in TikZ.

I've tried putting \hyperlink{target} around the \draw[blue] command, which didn't work. I'm fine either with the blue line being the link or the region inside the blue line being the link. I also don't care if it's still blue after the link is active; I've just colored it to make this question clearer.

Thank you for your time.

  • I assume it would be not okay if the lower right cut-out part of the rectangle is an active link also, right? – Qrrbrbirlbel Jun 24 '13 at 18:24
  • Welcome to TeX.SX! You can have a look on our starter guide to familiarize yourself further with our format. – Claudio Fiandrino Jun 24 '13 at 18:29
  • 1
    Very nice as first question: somehow Hyperlinked nodes in TikZ mindmap is related, but this is more general. – Claudio Fiandrino Jun 24 '13 at 18:36
  • Actually, I'd prefer that the lower right cutout portion not be part of the link. (In my actual document, there's other stuff there which shouldn't be linked; I took it out to simplify the example.) – Lauren Pearce Jun 24 '13 at 18:41
  • @LaurenPearce (If you respond to one particular comment, please include @<username> in your comment (as did I) so that the user gets notified.) I posted an answer that can be used for simple rectangular paths. For making the line itself hyper-active I could see a solution that uses decorations and places small boxes along the line, which would work with any arbitrary paths. – Qrrbrbirlbel Jun 24 '13 at 18:58
10

Alright, here is an idea for simple rectangular path that have to be split up in their convex sub-rectangles.

To get these sub-rectangles I save three coordinates for later use, the most lower-left corner, the most upper-right as well as the concave corner. There are named after their sub-rectangle (a, b) and where they lie relative to this sub-rectangle (bl = bottom-left, tr = top-right) but, of course, they can named whatever you want (and TikZ allows). The top-right coordinate of the a sub-rectangle is found by using (@b@bl |- @b@tr), i.e. the upper-left corner of the b sub-rectangle.

Your coordinates on the path were very complex. I will use here (cumulative) relative coordinates but your original path can be used too, of course (see commented section).

I have filled the sub-rectangles for clarification.

The path picture provides a special rectangular node, the path picture bounding box that usually can accessed via (path picture bounding box) and their anchors with, say (path picture bounding box.south west). Though, I will use low-level PGF macros to extract the x and y  values of the lower-left (south west) and the upper-right (north east) corner. At the and I’ll have the dimension of the path picture in the \pgf@?b dimensions.

The \pgftext is a very low-level macro to place text somewhere in the picture. It will placed with its upper-right corner (right,top) at the north east anchor of the path picture (\pgf@x and \pgf@y still hold the values from the north east anchor).

The content of the \pgftext will be a \vrule of the path pictures height (\pgf@yb) with no depth and no width and a \vrule with the width of the path picture and no other dimensions. This essentially makes a (TeX) box the size of the path picture with no visible content.

This all is wrapped inside a two-argumenty style called hyper. But this is only an auxiliary style that is used by the hyperlink style. You can simply expand this with \href or whatever is needed.

The implementation in TeX/PGF makes it compatible and slightly faster.

With the help of the calc library you could do:

\path let \p{@ppbb@dim}=
         ($(path picture bounding box.north east)-(path picture bounding box.south west)$)
      in  node[inner sep=+0pt,
               outer sep=+0pt,
               anchor=north east,
               at=(path picture bounding box.north east)]
                             {#1{#2}{\rule{\x{@ppbb@dim}}{0pt}\rule{0pt}{\y{@ppbb@dim}}}};

Code

\documentclass[10pt,letterpaper]{article}
\usepackage{tikz}
\usepackage[colorlinks=true,urlcolor=blue,filecolor=magenta]{hyperref}
\makeatletter
\tikzset{
  hyper/.style 2 args={
    path picture={%
      \pgfpointanchor{path picture bounding box}{south west}%
      \pgf@xb-\pgf@x
      \pgf@yb-\pgf@y
      \pgfpointanchor{path picture bounding box}{north east}%
      \advance\pgf@xb\pgf@x
      \advance\pgf@yb\pgf@y
      \pgftext[at={\pgfqpoint{\pgf@x}{\pgf@y}},right,top]{#1{#2}{\vrule height\pgf@yb depth0ptwidth0pt\vrule height0ptdepth0ptwidth\pgf@xb}}%
    }
  },
  hyperlink/.style={hyper=\hyperlink{#1}}
}
\makeatother

\begin{document}
\section{The Diagram}
\begin{center}
\begin{tikzpicture}
\node[draw,align=center] at (12, 0.2+.5) {Even \\ more};
\node[draw,align=center] at (12, 1.4+.5) {And \\ more1};
\node[draw,align=center] at (15, 2.8+.5) {Some \\ text};
\node[draw,align=center] at (15, 1.8+.5) {More \\ text};
%\draw[blue] (11,-.4+.5) coordinate (@a@bl) -- (13,-.4+.5)
%         -- (13,1.3+.5) coordinate (@b@bl) -- (16.5,1.3+.5)
%       -- (16.5,3.5+.5) coordinate (@b@tr) -- (11,3.5+.5) -| (@a@bl) -- cycle;

\draw[blue] (11,-.4+.5) coordinate (@a@bl)
         -| ++ (3  ,1.7) coordinate (@b@bl)
         -| ++ (3.5,2.2) coordinate (@b@tr) -| (@a@bl) -- cycle;
\fill[blue!20, fill opacity=.7, hyperlink=target] (@a@bl) rectangle (@b@bl |- @b@tr);
\fill[blue!40, fill opacity=.7, hyperlink=target] (@b@bl) rectangle (@b@tr);
\end{tikzpicture}
\end{center}
\section{This is the target}
\hypertarget{target}{Here is the target!}
\end{document}

Output

enter image description here

  • Thanks! Could you maybe explain the code a little bit? (I've got quite a few of these rectangles and I want to make sure I understand it.) It seems that I start at the bottom left corner, and then say how much to go up and right by, right? This defines a path and then the interior of the path gets hyperlinked. – Lauren Pearce Jun 24 '13 at 19:03
  • @LaurenPearce I have updated my answer with hopefully helpful comments. It doesn’t matter how you specify the path. I have used relative coordinates because it makes it easier to follow a rectangular path. The essence is to re-use sub-rectangles for the hyperlink. How you achieve that is independent from the actual approach taken here. (I don’t think it is possible to create non-rectangular areas for a link.) – Qrrbrbirlbel Jun 24 '13 at 20:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.