6

I wrote a tikz diagram, which resides in its own dedicated file. I would like to include this file several times in my document, each time highlighting a different node in it. I tried defining a macro that would check for the argument, but alas, macro expansion within a path does not work. Any other ideas?

Here is my code:

  {
  \usetikzlibrary{arrows}
  \usetikzlibrary{mindmap}
  \begin{tikzpicture}[level 1/.append style={level distance=5ex,sibling angle=90}]
  \small\it
  \tikzstyle{show}=[draw,rectangle,thin,rounded corners]
  \node[show] {} 
    child {node[show] {Monomorphism} }
    child[missing]
    child {node[show] {Polymorphism}
      child { node[show] {Ad hoc}
    child {node[show] {Overloading} }
    child [missing]
    child {node[show] {Coercion}} 
    child [missing]
      }
      child [missing]
      child [missing]
      child [missing]
      child {node[show] {Universal}
    child {node[show] {Parametric} 
      child {node[show] {Polymorphic Functions}}
      child [missing]
      child [missing]
      child {node[show] {Polytypes}}
    }
    child[missing]
    child[missing]
    child {node[show] {Inclusion} child {node[show] {Subtype}}}
      }
    }
  ;
  \end{tikzpicture}
  }
  • 1
    What about defining a new counter to be used on the picture to identify the number of the node to be highlighted. Then you can call a command passing the number to set the counter and call the input. If you set the counter first then the highlighted node will change accordingly. – Sigur Dec 6 '13 at 19:09
  • 1
    You need to elaborate on how you want to specify the to-be-highlighted node. The best would be its name. In a tree, the names are given a special name after the name of the root (similar to a matrix). The third child of the second child of the root is named root>-2-3. How do you want to highlight the node? Do you simply want to change the border color for example? Do you want to change the font setting? Do you want to move it around or make it bigger? – Qrrbrbirlbel Dec 6 '13 at 23:56
6

First you have to give names to each node, with the syntax

node[<options>] (<name>) {<node text}

I define a macro \HighlightedNode that holds the name of the node to be highlighted, and a second one \Highlight to change the node to be highlighted. The highlighting is simply a thick red ellipse drawn around the centre of the node, please advise if you want something different. The \TikzFig node contains your tree and the additional

\draw [ultra thick,red] (\HighlightedNode.center) circle [x radius=5em,y radius=1.5em];

which creates the highlighting.

Using a macro defined by Martin Scharrer in How can I know if a node is already defined? I check for whether the node defined by \HighlightedNode exists, and only then draw the highlight. By defining \HighlightedNode to a string that is not a node name in the picture, this effectively turns off the highlighting.

I also changed from \tikzstyle to \tikzset, the latter is recommended. And don't use \it, these two-letter font switching macros are deprecated, use \itshape instead. Finally, rather than adding \small\itshape as you've done, I think I would use every node/.style={font=\small\itshape}.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{mindmap}

\newcommand\HighlightedNode{none}
\newcommand\Highlight[1]{\renewcommand\HighlightedNode{#1}}

\makeatletter % https://tex.stackexchange.com/questions/37709/how-can-i-know-if-a-node-is-already-defined
\long\def\ifnodedefined#1#2#3{%
    \@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
\makeatother

\newcommand\TikzFig{
  \begin{tikzpicture}[level 1/.append style={level distance=5ex,sibling angle=90},
  every node/.append style={font=\small\itshape}]
  \tikzset{show/.style={draw,rectangle,thin,rounded corners}}
  \node[show] {} 
    child {node[show] (mono) {Monomorphism} }
    child[missing]
    child {node[show] (poly) {Polymorphism}
      child { node[show] (adhoc) {Ad hoc}
    child {node[show] (overload) {Overloading} }
    child [missing]
    child {node[show] (coerce) {Coercion}} 
    child [missing]
      }
      child [missing]
      child [missing]
      child [missing]
      child {node[show] (uni) {Universal}
    child {node[show] (para) {Parametric} 
      child {node[show] (polyfunc) {Polymorphic Functions}}
      child [missing]
      child [missing]
      child {node[show] (polytype) {Polytypes}}
    }
    child[missing]
    child[missing]
    child {node[show] (inclusion) {Inclusion} child {node[show](subtype) {Subtype}}}
      }
    }
  ;
  \ifnodedefined{\HighlightedNode}{
    \draw [ultra thick,red] (\HighlightedNode.center) circle [x radius=5em,y radius=1.5em];}{}

  \end{tikzpicture}}
\begin{document}    

\TikzFig

\Highlight{poly}

\vspace{2cm}

\TikzFig

\Highlight{coerce}

\vspace{2cm}

\TikzFig

\end{document}

enter image description here

| improve this answer | |
  • Brilliant! I am still not sure how to apply this to my example. But, I am a real beginner with Tikz. – Yossi Gil Dec 6 '13 at 22:22
  • @YossiGil If you can create a minimal example showing what you've done, and explaining what kind of highlighting you're after, you might get better answers. As your question stands, it is hard to do any more than idealised examples such as this. – Torbjørn T. Dec 6 '13 at 22:26
2

Maybe a node-name-based style that activates a highlight style?

By the way, it looks like if you are using missing childs to correct the spacing of the tree. You might be interested in the forest package that automatically positions the nodes with a proper spacing between them (and much more). Though, I don’t think that this solution will work then.

Code

\begin{filecontents*}{\jobname.tikz}
\begin{tikzpicture}[
  level 1/.append style={level distance=+5ex, sibling angle=90},
  show/.style={draw,rectangle,thin,rounded corners}]
\small\itshape
\path[nodes=show] node (r) {} 
  child {node {Monomorphism} } child [missing]
  child {node  {Polymorphism}
    child {node  {Ad hoc}
      child {node  {Overloading}}  child [missing]
      child {node  {Coercion}}     child [missing] }
    child [missing] child [missing] child [missing]
    child {node {Universal}
      child {node {Parametric} 
        child {node {Polymorphic Functions}}
        child [missing] child [missing]
        child {node {Polytypes}}}
      child[missing] child[missing]
      child {node {Inclusion} child {node {Subtype}}}}};
\end{tikzpicture}
\end{filecontents*}
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{mindmap}
\tikzset{highlight/.style={draw=red, text=blue, fill=green!25}}
\makeatletter
\usepackage{etoolbox}
\patchcmd\tikz@@fig@main{\tikzset{every \tikz@shape\space node/.try}}{%
  \tikzset{every \tikz@shape\space node/.try}%
  \tikzset{every node named \tikz@fig@name/.try}%
}{}{}
\newcommand*\inpTikZ[2][]{%
  \begingroup
    \def\tikz@temp{#1}% is #1 empty?
    \ifx\tikz@temp\pgfutil@empty\else
      \tikzset{every node named #1/.append style=highlight}%
    \fi
    \input{#2}%
  \endgroup}
\makeatother
\begin{document}
\inpTikZ[r-1]{\jobname.tikz}

% r-2 is "missing"
\inpTikZ[r-3]{\jobname.tikz}

\inpTikZ[r-3-5]{\jobname.tikz}
\end{document}
| improve this answer | |

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.