5

I would like to highlight a different node of the tikz flowchart every time I call the figure in the relevant chapter.

I was thinking of defining a new style "highlight" and then pass a parameter when including the tikz picture do this with the additional parameter that sets the style of <node name> == <parameter> to highlight. However, I'm new to tikz so I have no clue how to do this.

The code below (tikzpicture) is included in the relevant chapter using the following:

\includestandalone[width=\textwidth]{tikz/content}
\caption{Outline of this thesis.}
\label{fig:contents}
\end{figure}

Thanks in advance for reading me and your help.

Julien

\documentclass[border=2pt]{standalone}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usepackage{fix-cm}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{positioning}
\begin{document}
\pagestyle{empty}

% Define block styles

\tikzset{block/.style={draw, rectangle, fill=gray!20, text centered, minimum height = 3em,text width=7em}}
\tikzset{empty/.style={draw, rectangle, fill=none, text centered, minimum height = 3em,text width=7em}}
\tikzset{line/.style={draw, -latex'}}

\begin{tikzpicture}[node distance = 1cm, auto]

    % Place nodes
    \node [block, text width=30em] (init){\Large Aeroelastic modeling from wind tunnel tests using frequency domain identification};
    \node [block, text width=17em, below=1em of init] (sysid) {\large System identification\\ in aeroelasticity};


    \node [empty, text width = 12em, below=1em of sysid, node distance= 3em] (theory) {Theory \& Methods \\ \textit{Chapter \ref{chpt:theory}}};


    \node [block, text width = 16em, below left=1em and -5em of theory] (unsteady) {\textbf{Unsteady Aerodynamics} \\ 2D Full-Span (Part 1)};
    \node [block, text width = 18em, below right=1em and -5em of theory] (aeroelastic) {\textbf{Aeroelastic} \\3D Cantilever (Part 2)};

    \node [block, below left=0.5em and -7.8em of unsteady] (setupone) {Setup};
    \node [block, right=1em of setupone] (expone) {Experiments};
    \node [empty, below=0.5em of setupone] (setoneCh) {The AATB \\ \textit{Chapter \ref{chpt:AATB}}};
    \node [empty, below=0.5em of expone] (unsteadyExp) {Forced-motion \\ \textit{Chapter \ref{chpt:forced-motion}}};

        \node [block, text width =8em, below left=0.5em and -8.8em of aeroelastic] (setuptwo) {Setup};
    \node [block, right=1.2em of setuptwo, text width = 8em] (exptwo) {Experiments};
    \node [empty,  text width =8em, below=0.5em of setuptwo] (settwoCh) { Cantilver AATB \\ \textit{Chapter \ref{chpt:cantiAATB}}};

    \node [empty,text width = 7em, below right=0.5em and -7.8em of exptwo] (NL) {Nonlinear response \\ \textit{Chapter \ref{chpt:aeroelastic}}};
    \node [empty,text width = 7em, below=0.5em of NL] (gust) {Gust response \\ \textit{Chapter \ref{chpt:cantiGust}}};
    \node [empty,text width = 7em, below=0.5em of gust] (tv) {Time-varying \\ \textit{Chapter \ref{chpt:TV}}};

    \node [below left=-0.75em and -0.8em of exptwo] (startexp) {};   

    % Draw edges
    \path [line] (init) -- (sysid);
    \path [line] (sysid) -- (theory);
    \path [line] (sysid) -| (unsteady);
    \path [line] (sysid) -| (aeroelastic);
    \draw (unsteady) |- (setupone);
    \draw (unsteady) |- (expone);
    \draw (aeroelastic) |- (setuptwo);
    \draw (aeroelastic) |- (exptwo);
    \draw (startexp) |- (NL);
    \draw (startexp) |- (gust);
    \draw (startexp) |- (tv);
\end{tikzpicture}

\end{document}
Stefan Pinnow
  • 29,535
Julien
  • 53

2 Answers2

5

I would recommend you use a .provide style as defined in Is there something like \providetikzstyle similar to \providecommand?, and set it before you invoke your picture.

So in you picutre define the default styles using .provide style:

\tikzset{Node One Style/.provide style={block}}%
\tikzset{Node Two Style/.provide style={block}}%

and then override these with

\tikzset{Node One Style/.style={highlight block}}%

when you want to change, say the style of Node One.

Notes:

  • Please include a MWE (with emphasis on the M in MWE).
  • In the first solution, once you set a style, you need to set it again to disable it. To not require this you could set the style with a group, or use the Alternate Solution in which you pass in the node you want highlighted. If you are always going to ONLY change the style of one node than the alternate solution is better. The first solution provides more flexability.

enter image description here

Code:

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

%% https://tex.stackexchange.com/questions/22640/is-there-something-like-providetikzstyle-similar-to-providecommand
\tikzset{/handlers/.provide style/.code={%
    \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{}%
        {\pgfkeys {\pgfkeyscurrentpath /.code=\pgfkeysalso {#1}}}%
}}

% Define block styles

\tikzset{block/.style={draw, rectangle, fill=gray!20, text centered, minimum height = 3em,text width=7em}}
\tikzset{highlight block/.style={draw, rectangle, fill=red!20, text centered, minimum height = 3em,text width=7em}}

\newcommand{\MyPicture}{%
    \tikzset{Node One Style/.provide style={block}}%
    \tikzset{Node Two Style/.provide style={block}}%
    % -----------------
    \begin{tikzpicture}[node distance = 1cm, auto, text width=10em]
        \node [Node One Style]                   (one) {Node One};
        \node [Node Two Style, below=1em of one] (two) {Node Two};

    \end{tikzpicture}%
}%

\begin{document}
\textbf{First Time}
\par\hspace*{1.0cm}\MyPicture

\textbf{Second Time}
\tikzset{Node One Style/.style={highlight block}}%
\par\hspace*{1.0cm}\MyPicture

\textbf{Third Time}
\tikzset{Node One Style/.style={block}}%
\tikzset{Node Two Style/.style={highlight block}}%
\par\hspace*{1.0cm}\MyPicture
\end{document}

Code Alternate Solution

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

%% https://tex.stackexchange.com/questions/22640/is-there-something-like-providetikzstyle-similar-to-providecommand
\tikzset{/handlers/.provide style/.code={%
    \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{}%
        {\pgfkeys {\pgfkeyscurrentpath /.code=\pgfkeysalso {#1}}}%
}}

% Define block styles

\tikzset{block/.style={draw, rectangle, fill=gray!20, text centered, minimum height = 3em,text width=7em}}
\tikzset{highlight block/.style={draw, rectangle, fill=red!20, text centered, minimum height = 3em,text width=7em}}

\newcommand{\MyPicture}[1]{%
    \tikzset{#1/.style={highlight block}}%
    \tikzset{Node One Style/.provide style={block}}%
    \tikzset{Node Two Style/.provide style={block}}%
    % -----------------
    \begin{tikzpicture}[node distance = 1cm, auto, text width=10em]
        \node [Node One Style]                   (one) {Node One};
        \node [Node Two Style, below=1em of one] (two) {Node Two};

    \end{tikzpicture}%
}%

\begin{document}
\textbf{First Time}
\par\hspace*{1.0cm}\MyPicture{Unused Style}

\textbf{Second Time}
\par\hspace*{1.0cm}\MyPicture{Node One Style}

\textbf{Third Time}
\par\hspace*{1.0cm}\MyPicture{Node Two Style}
\end{document}
Peter Grill
  • 223,288
2

Replace the nodes that you want to manage from the outside as follows (for the other nodes it does not matter): instead of

\node[<node style>] (<node name>) {<node contents>};

write

\node[<node style>,managed=<node name>] {<node contents>};

This allows us in managed not only to set the name of the node but also to add extra style elements for highlighting the node. The definitions for managed:

\tikzset
 {managed/.unknown/.style={},% if managed/<node name> is unknown do nothing
  managed/.style={name=#1,managed/#1}% set the name of the node and apply the style managed/<node name>
 }

After that you can provide extra style elements for the node by saying

\begin{tikzpicture}[managed/<node name>/.style={<additional style for this node>}]

or even further outside by

\tikzset{managed/<node name>/.style={<additional style for this node>}}

In the latter case you can delimit the scope of the highlighting by surrounding \tikzset and the pictures it applies to by braces ({}).

Below is your example rewritten, with two nodes highlighted.

\documentclass[border=2pt]{standalone}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usepackage{fix-cm}
\usetikzlibrary{shapes,arrows}
\usetikzlibrary{positioning}
\pagestyle{empty}
\tikzset{block/.style={draw, rectangle, fill=gray!20, text centered, minimum height = 3em,text width=7em}}
\tikzset{empty/.style={draw, rectangle, fill=none, text centered, minimum height = 3em,text width=7em}}
\tikzset{line/.style={draw, -latex'}}
\tikzset
 {managed/.unknown/.style={},
  managed/.style={name=#1,managed/#1}
 }
\begin{document}
\begin{tikzpicture}[node distance = 1cm, auto,managed/exptwo/.style={text=red},managed/init/.style={fill=blue!20}]
\node [block, block, text width=30em,managed=init] {\Large Aeroelastic modeling from wind tunnel tests using frequency domain identification};
\node [block, text width=17em, below=1em of init,managed=sysid] {\large System identification\\ in aeroelasticity};
\node [empty, text width = 12em, below=1em of sysid, node distance= 3em,managed=theory] {Theory \& Methods \\ \textit{Chapter \ref{chpt:theory}}};
\node [block, text width = 16em, below left=1em and -5em of theory,managed=unsteady] {\textbf{Unsteady Aerodynamics} \\ 2D Full-Span (Part 1)};
\node [block, text width = 18em, below right=1em and -5em of theory,managed=aeroelastic] {\textbf{Aeroelastic} \\3D Cantilever (Part 2)};
\node [block, below left=0.5em and -7.8em of unsteady,managed=setupone] {Setup};
\node [block, right=1em of setupone,managed=expone] {Experiments};
\node [empty, below=0.5em of setupone,managed=setoneCh] {The AATB \\ \textit{Chapter \ref{chpt:AATB}}};
\node [empty, below=0.5em of expone,managed=unsteadyExp] {Forced-motion \\ \textit{Chapter \ref{chpt:forced-motion}}};
\node [block, text width =8em, below left=0.5em and -8.8em of aeroelastic,managed=setuptwo] {Setup};
\node [block, right=1.2em of setuptwo, text width = 8em, managed=exptwo] {Experiments};
\node [empty,  text width =8em, below=0.5em of setuptwo,managed=settwoCh] { Cantilver AATB \\ \textit{Chapter \ref{chpt:cantiAATB}}};
\node [empty,text width = 7em, below right=0.5em and -7.8em of exptwo,managed=NL] {Nonlinear response \\ \textit{Chapter \ref{chpt:aeroelastic}}};
\node [empty,text width = 7em, below=0.5em of NL,managed=gust] {Gust response \\ \textit{Chapter \ref{chpt:cantiGust}}};
\node [empty,text width = 7em, below=0.5em of gust,managed=tv] {Time-varying \\ \textit{Chapter \ref{chpt:TV}}};
\node [below left=-0.75em and -0.8em of exptwo,managed=startexp] {};   
\path [line] (init) -- (sysid);
\path [line] (sysid) -- (theory);
\path [line] (sysid) -| (unsteady);
\path [line] (sysid) -| (aeroelastic);
\draw (unsteady) |- (setupone);
\draw (unsteady) |- (expone);
\draw (aeroelastic) |- (setuptwo);
\draw (aeroelastic) |- (exptwo);
\draw (startexp) |- (NL);
\draw (startexp) |- (gust);
\draw (startexp) |- (tv);
\end{tikzpicture}
\end{document}
gernot
  • 49,614
  • Thanks a lot. I did have to move the \tikzset commands to below the \begin{document} to make the code work when using \includestandalone[]{<tikzfile>}in the main document as illustrated in the original question. – Julien Aug 12 '16 at 13:05