使 TikZ 节点可超链接

使 TikZ 节点可超链接

我有一个 TikZ 树。现在我想让节点可点击,指向文档中的相关部分(或指向 URL)。节点中的某些内容不是文本。是否可以将节点转换为链接?如果可以,如何操作?我希望节点本身是链接,而不是它们包含的文本。

添加:我在这方面并不擅长,并且仍在学习,但这是我正在研究的想法的骨架轮廓......(图形目录)

\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}

在此处输入图片描述

还有更奇特的例子,例如这个将会成为一个伟大的目录。

答案1

这是一个名为 的新 TikZ 样式hyperlink node=<target>,它接受一个hypertarget引用。它的工作原理是测量它所提供给的节点,然后在其上放置一个新的不可见节点。新节点具有内容\hyperlink{<target>}{\phantom{\rule{<width of node>}{<height of node>}},因此它的大小与原始节点相同,但整个区域都是可点击的。

\documentclass{article}
\usepackage[hidelinks]{hyperref}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\tikzset{
    hyperlink node/.style={
        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} 

答案2

除了 Jake 的好主意之外,这里有一些代码可以在最近的文档中很好地运行,使用了以下代码使用 TikZ 中的 tree 命令绘制目录列表(A. Stacey 的回答)还有你的 MWE。它不像你的那么花哨,但可能也很时尚。

\documentclass{article} 

\usepackage{tikz}
%------------------%
\makeatletter
\newcount\dirtree@lvl
\newcount\dirtree@plvl
\newcount\dirtree@clvl
\def\dirtree@growth{%
  \ifnum\tikznumberofcurrentchild=1\relax
  \global\advance\dirtree@plvl by 1
  \expandafter\xdef\csname dirtree@p@\the\dirtree@plvl\endcsname{\the\dirtree@lvl}
  \fi
  \global\advance\dirtree@lvl by 1\relax
  \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
  \global\advance\dirtree@plvl by -1
  \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}

答案3

这是杰克的回答。 谢谢弗鲁贡的评论,outer xsep和的不同值outer ysep现在被正确考虑了。

问题

  • 选项line widthouter sep不予考虑。因此,链接框通常太大(唯一可行的情况是outer sep=0)。
  • DrBones 附录并不能解决这个问题,因为它只改变了超链接节点的大小,而不改变超链接区域本身。

解决方案

如果outer sep不设置,它是的一半line width。因此,我们只需要使用来outer sep解决以下情况。

我将\n0和定义\n1为和outer xsepouter ysep并将两个点根据该值移动到节点的中间:

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),

可视化与描述

以下代码的结果

  • 该节点具有粗青色边框。
  • 黑色矩形围绕节点锚点(north westsouth east)。
  • 黄色矩形是超链接区域的可视化。
  • 传递的选项如图下部所示。
  • 如果黄色(超链接区域)和青色(节点边框)重叠,我们就会得到绿色,就像我们在hyperlink dexteritas变体中看到的那样。

代码

\documentclass[border=2mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
\usepackage[hidelinks]{hyperref}

% NOTE: added option "test highlight" for testing (can be removed for normal usage)
\tikzset{
    test highlight/.style={draw=yellow, draw opacity=0.5},
    hyperlink Jake/.style={
        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
        }
    },
    hyperlink dexteritas/.style={
        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}

答案4

这只是对 Jake 的出色回答的一个小补充,遗憾的是由于我还不能发表评论,所以无法作为答案。

我必须将许多链接放在很近的地方,并且为了使新创建的 hyperref 节点不超出原始节点的范围,我必须通过 来补偿当前线宽inner sep=-0.5\pgflinewidth,并将 设置\XeTeXLinkMargin为零,即

\setlength{\XeTeXLinkMargin}{0pt}
\tikzset{
    hyperlink node/.style={
        alias=sourcenode,
        append after command={
            let \p1= (sourcenode.north west),
                \p2= (sourcenode.south east),
                \n1={\x2-\x1},
                \n2={\y1-\y2} in
            node [inner sep=-0.5\pgflinewidth,outer sep=0pt,anchor=center, at=(sourcenode.center)] {\hyperlink{#1}{\XeTeXLinkBox{\phantom{\rule{\n1}{\n2}}}}}
        }
    }
}

现在链接与(矩形)节点一样大。当使用不同的形状时,链接当然会突出。

也许这对某人有帮助

相关内容