13

I have been looking for a possibly difficult answer to a simple question. I would like to be able to highlight paths on a TikZ picture. I would like to highlight these paths by clicking on them and at each step retain the previous steps.

For instance, in the MWE below, I would like to start with the 4 empty squares, and have the color appear on each of them by clicking on it. And considering that any path can be chosen. I guess I can do it by using {hyperref} and identify all the possible ways, but there must be some easier way I am sure.

Any idea?

colored squares

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{box1/.style={draw=black, thick, rectangle,rounded corners, minimum height=2cm, minimum width=2cm}}

\begin{document}
\begin{tikzpicture}

\node[box1, fill=white] (c1) {1};
\node[box1, fill=white, right=1cm of c1] (c2) {2};
\node[box1, fill=white, below=1cm of c2] (c3) {3};
\node[box1, fill=white, left=1cm of c3] (c3) {4};

\node[box1, fill=red, right=5cm of c1] (c21) {1};
\node[box1, fill=blue, right=1cm of c21] (c22) {2};
\node[box1, fill=orange, below=1cm of c22] (c23) {3};
\node[box1, fill=green, left=1cm of c23] (c23) {4};
\end{tikzpicture}
\end{document}
jejuba
  • 1,471
  • 2
  • 13
  • 21

1 Answers1

13

This could be automated even further, and it would be nice if the hyperlinks were the same size as the nodes, but it shows - I think - the main idea.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/61020/86}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{box1/.style={draw=black, thick, rectangle,rounded corners, minimum height=2cm, minimum width=2cm}}
\usepackage{hyperref}

\colorlet{picture-1-1}{red}
\colorlet{picture-2-1}{blue}
\colorlet{picture-3-1}{orange}
\colorlet{picture-4-1}{green}
\colorlet{picture-1-0}{white}
\colorlet{picture-2-0}{white}
\colorlet{picture-3-0}{white}
\colorlet{picture-4-0}{white}

\begin{document}
\foreach \n in {0,...,15} {
  \pgfmathtruncatemacro\i{mod(\n,2)}
  \pgfmathtruncatemacro\j{mod(int(\n/2),2)}
  \pgfmathtruncatemacro\k{mod(int(\n/4),2)}
  \pgfmathtruncatemacro\l{mod(int(\n/8),2)}
  \pgfmathparse{\i == 0 ? "\noexpand\hyperlink{picture-1-\j-\k-\l}{1}" : 1}
  \let\pictexti=\pgfmathresult
  \pgfmathparse{\j == 0 ? "\noexpand\hyperlink{picture-\i-1-\k-\l}{2}" : 2}
  \let\pictextj=\pgfmathresult
  \pgfmathparse{\k == 0 ? "\noexpand\hyperlink{picture-\i-\j-1-\l}{3}" : 3}
  \let\pictextk=\pgfmathresult
  \pgfmathparse{\l == 0 ? "\noexpand\hyperlink{picture-\i-\j-\k-1}{4}" : 4}
  \let\pictextl=\pgfmathresult
\hypertarget{picture-\i-\j-\k-\l}{%
\begin{tikzpicture}
\node[box1, fill=picture-1-\i] (c1) {\pictexti};
\node[box1, fill=picture-2-\j, right=1cm of c1] (c2) {\pictextj};
\node[box1, fill=picture-3-\k, below=1cm of c2] (c3) {\pictextk};
\node[box1, fill=picture-4-\l, left=1cm of c3] (c3) {\pictextl};
\end{tikzpicture}}
\newpage
}
\end{document}

Each possible configuration is generated, and each unfilled square is linked to the next appropriate configuration. By labelling the configurations according to which squares are filled, it is very easy to sort out the paths in the graph linking the configurations.


Update 2013-08-31 This version allows for two-way clicking, so a coloured node is a link to the uncoloured one and vice versa. It actually makes the code a smidgeon simpler. To offset that, I've included Jake's excellent code for making the entire node clickable (and used hidelinks to hide the red boxes).

\documentclass{article}
%\url{http://tex.stackexchange.com/q/61020/86}
\usepackage{tikz}
\usepackage{hyperref}
\usetikzlibrary{positioning,calc}

\tikzset{
  box1/.style={
    draw=black,
    thick,
    rectangle,
    rounded corners,
    minimum height=2cm,
    minimum width=2cm
  },
  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}{\phantom{\rule{\n1}{\n2}}}}
    }
  }
}

\colorlet{picture-1-1}{red}
\colorlet{picture-2-1}{blue}
\colorlet{picture-3-1}{orange}
\colorlet{picture-4-1}{green}
\colorlet{picture-1-0}{white}
\colorlet{picture-2-0}{white}
\colorlet{picture-3-0}{white}
\colorlet{picture-4-0}{white}

\hypersetup{hidelinks}

\begin{document}
\foreach \n in {0,...,15} {
  \pgfmathtruncatemacro\i{mod(\n,2)}
  \pgfmathtruncatemacro\j{mod(int(\n/2),2)}
  \pgfmathtruncatemacro\k{mod(int(\n/4),2)}
  \pgfmathtruncatemacro\l{mod(int(\n/8),2)}
  \pgfmathparse{int(1-\i)}
  \edef\pictexti{picture-\pgfmathresult-\j-\k-\l}
  \pgfmathparse{int(1-\j)}
  \edef\pictextj{picture-\i-\pgfmathresult-\k-\l}
  \pgfmathparse{int(1-\k)}
  \edef\pictextk{picture-\i-\j-\pgfmathresult-\l}
  \pgfmathparse{int(1-\l)}
  \edef\pictextl{picture-\i-\j-\k-\pgfmathresult}
  \edef\picname{picture-\i-\j-\k-\l}
\hypertarget{picture-\i-\j-\k-\l}{%
\begin{tikzpicture}
\node[box1, fill=picture-1-\i, hyperlink node=\pictexti] (c1) {1};
\node[box1, fill=picture-2-\j, hyperlink node=\pictextj, right=1cm of c1] (c2) {2};
\node[box1, fill=picture-3-\k, hyperlink node=\pictextk, below=1cm of c2] (c3) {3};
\node[box1, fill=picture-4-\l, hyperlink node=\pictextl, left=1cm of c3] (c3) {4};
\end{tikzpicture}}
\newpage
}
\end{document}
Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • Very nice! Although I wonder if the OP wanted the colours to always be assigned in the same order (first red, then orange, etc.)? For making the whole nodes clickable, there are possible approaches here: http://tex.stackexchange.com/questions/36109/making-tikz-nodes-hyperlinkable and http://tex.stackexchange.com/questions/60329/how-to-hyperlink-a-shape-using-tikz – Jake Jun 24 '12 at 20:26
  • @Jake Then the graph would be a tree as you could reconstruct the path taken by the colours. Same principle, but more pages: I make it 64. – Andrew Stacey Jun 24 '12 at 20:58
  • Thanks Stacey. Although I get the following error when I run the code: package pgf math error: unknown function `int'}. It looks like I am going to have to reinstall TeXlive from http://tug.org/texlive/. Will come back ASAP. – jejuba Jun 24 '12 at 21:54
  • Hi Andrew, well it appears I won't be able to test your solution in the near future. I haven't been able to correct the error I get. I tried different things, but it doesn't work. I leave for 2 months at the end of the week, with no access to computer, and I have too much work to do before to sort this out. In case, there was some doubt, I do not wish the square to be highlighted in any specific order; i wish that anybody can choose a different route to get to the 4 colored squares, starting from the 4 empty ones. Hope this helps: see you in a few months to accept the answer. Best, – jejuba Jun 25 '12 at 22:55
  • Well, back from holiday. I eventually crashed my debian trying to install things to have your code work. Took me a long time to reinstall.. And it still doesn't work! So, unfortunately, I won't be able to test your answer. Sorry, – jejuba Aug 30 '12 at 13:11
  • @JeanUbai If you edit your question with the error message (or if it's short, in a comment here) I could try to guess what's going wrong. – Andrew Stacey Aug 30 '12 at 13:16
  • @Andrew. Well, i get the error message: package pgf math error unknown function `int'}. I am running Debian and I have installed TeX Live via apt-get. So it is outdated (vesion 2009-11+squeeze1). I am not sure about the manual install as recommended at http://tex.stackexchange.com/questions/1092/how-to-install-vanilla-texlive-on-debian-or-ubuntu. I kind of tried that in June and things went wrong. But I cannot remember what I did for sure. I am worried about dependencies, etc, between TeX Live and other packages. Any advice? – jejuba Aug 31 '12 at 12:21
  • I run TeXLive 2011 (will upgrade to 2012 soon) on my Debian machine and it installed fine into /usr/local so it plays well with Debian stuff. You could try installing pgf in your user TEXMF tree. Or you could look through the manual (texdoc pgf) to see if there's an alternative to int - it's been so long since I used the old version of pgf that I don't know if such exists. – Andrew Stacey Aug 31 '12 at 12:42
  • Thanks. I think I did try something else which failed too... I'm going to give it another try to upgrading TeXLive. Did you remove the old TeXLive before installing the new one? You used tlmgr? – jejuba Aug 31 '12 at 14:10
  • @JeanUbai No, I didn't remove the old one. I installed the new one alongside. It installs in /usr/local so providing /usr/local/bin is in your path and early in your path then there's no conflict. – Andrew Stacey Aug 31 '12 at 14:12
  • Well, i am trying to install texlive to /usr/local. Problem is that I don't have enough disk space there. Would it matter if I install it somewhere in my /home since I have a lot more space there? As long as I indicate this to the PATH? Sorry to bother you with this but reading your other post, it seems you would be able to answer. Thanks, – jejuba Sep 02 '12 at 16:38
  • @JeanUbai I've had an installation of TeXLive in my home directory before. I hid it in $HOME/local/texlive to keep it out of the way and then symlinked the binaries into $HOME/local/bin (which was in my path). I don't remember anything being complicated about this set-up, though there might be a configuration variable or two to configure. – Andrew Stacey Sep 02 '12 at 16:47
  • delay again... too much work. So I eventually installed texlive 2012 in another directory. I installed it into ~/.local/... not too sure whether this was a good idea but the install worked well. At the end, I got the message install successful (I think) and "Most importantly, add ~/.local/texlive/2012/bin/i386-linux to your PATH for current and future sessions". I did that and placed this dir. first. But I still get the same error message "unknown function `int'}". When i check the package version with "dpkg -l texlive"; it is still 2009 version. I didn't update info or manpaht. Any idea? – jejuba Sep 08 '12 at 09:30
  • @JeanUbai Well, dpkg isn't going to see your local installation. The test is kpsewhich, or just plain which. Try which tex or kpsewhich latex.ltx to see if they are finding your new installation. – Andrew Stacey Sep 10 '12 at 08:45
  • @Andrew. I am a little sorry to bother you with all this stuff. You probably have gazillions of better things to do. Should I start another thread on the topic so you're not the only one helping out? or look somewhere else? There/s already a fair number of threads on this topic; none that answers my problem clearly (to my eyes). Anyway, yes which tex returns ~/.local/texlive/2012/bin/i386-linux/tex and kpsewhich latex.ltx returns ~/.local/texlive/2012/texmf-dist/tex/latex/base/latex.ltx. – jejuba Sep 11 '12 at 20:09
  • @JeanUbai We could move the discussion to chat - then others might see the problem and have ideas. My next suggestion is to try kpsewhich pgfmath.code.tex and kpsewhich pgfmathfunctions.round.code.tex and see if they are in the texlive 2012 tree. – Andrew Stacey Sep 11 '12 at 20:19
  • well yes, both are in the 2012 tex live tree... I'll try to move things to discussion. Only probably a bit later because I have too much work right now. Thx for the help. How do we move things to discussion by the way? – jejuba Sep 15 '12 at 18:53
  • @JeanUbai Just join the main chat room and use the @ syntax to flag me. – Andrew Stacey Sep 17 '12 at 08:49
  • Dear Stacey,back on line! Probably a little late, but as I a newer tikz version I can confirm it works well. I was just wondering, now that I have tried your version, if there was a way to go backwards too in the highlighting sequence. For instance, say you click on square 2, then 1, and have both squares highlighted. Should you be willing to "turn off" square 2 by clicking on it. Could that work? – jejuba Aug 31 '13 at 07:19
  • @JeanUbai Going backwards isn't difficult. See latest edit. – Andrew Stacey Aug 31 '13 at 18:39
  • Dear Andrew: this is just great! – jejuba Sep 01 '13 at 08:13