7

I would like to add some arrows like in the following picture from the code just below.

Output excpected

enter image description here

Code

\documentclass{article}
    \usepackage{tikz}
    \usepackage{xstring}

    \tikzset{
        raw sort entry/.style={rectangle, thick, draw, node distance=1.5em},
        sort entry black/.style={raw sort entry, black, fill=white},
        sort entry blackgray/.style={raw sort entry, black, fill=gray!25},
        s1/.style={raw sort entry, red, fill=yellow!30},
        s2/.style={raw sort entry, blue, fill=green!20},
        s3/.style={raw sort entry, violet, fill=orange!25}
    }

    \newcommand*{\List}[2][sort entry black]{%
      \par\noindent%
      \edef\listtoprocess{#2}%
      \def\ListToProcess{}%
      \begin{tikzpicture}[inner sep=2pt, outer sep=0]
        \foreach \content in \listtoprocess{
          \IfSubStr{\content}{/}{% true
            \xdef\ListToProcess{\ListToProcess,\content}
          }{%                      false
            \xdef\ListToProcess{\ListToProcess,#1/\content}
          }
        }
        \StrGobbleLeft{\ListToProcess}{1}[\ListToProcess]% removes the first comma (\listToProcess is empty at the start)
        \foreach [count=\i] \Style/\Value in \ListToProcess {
          \ifnum\i=1\relax
            \node [raw sort entry, \Style] (sortnode\i) {\Value};
          \else
            \node [raw sort entry, right of=sortnode\number\numexpr\i-1\relax, \Style] (sortnode\i) {\Value};
          \fi
        }
      \end{tikzpicture}%
    }

\begin{document}

\List[sort entry blackgray]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}

\bigskip

\List[sort entry blackgray]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}

\end{document}
3
  • 1
    This feels like a follow-up question to another question … If you want to draw arrows between different TikZ pictures (as in your example), you'll need the option overlay and remember picture. Is this intentionally in two different TikZ pictures? Because both pictures can fall on different pages (unless enclosed in a float environment, minipage or similar). Jan 16, 2013 at 21:35
  • You're right, I've not choose a good way to put the two lists.
    – projetmbc
    Jan 16, 2013 at 21:54
  • As pointed out by @Qrrbrbirlbel adding remember picture lets you do this, but this introduces globally active picture labels. Unless you really need to separate your Lists as shown, I think it's better if you turn the two Lists into a single tikzpicture. That way all labels remain local so you can reuse them in other tikzpictures. Another possible problem with your current solution is that it may introduce a page break between the two Lists. Turing the Lists into a single tikzpicture makes introducing page breaks impossible.
    – user10274
    Jan 17, 2013 at 7:07

1 Answer 1

5

Addition

  • remember picture to the tikzpicture environment
  • two internal styles/keys:

    • /qrr/default and
    • /qrr/name row

    that are set by

  • two external styles:
    • default and
    • name row.

name row is initially blank so the nodes are named -1, -2, ….

The default default style is sort entry black (as previously in your optional \List argument). See also the in-code comment.

Code

\documentclass{article}
    \usepackage{tikz}
    \usepackage{xstring}
    \usetikzlibrary{calc}
    \tikzset{
        raw sort entry/.style={rectangle, thick, draw, node distance=1.5em},
        sort entry black/.style={raw sort entry, black, fill=white},
        sort entry blackgray/.style={raw sort entry, black, fill=gray!25},
        s1/.style={raw sort entry, red, fill=yellow!30},
        s2/.style={raw sort entry, blue, fill=green!20},
        s3/.style={raw sort entry, violet, fill=orange!25},
        /qrr/default/.style=sort entry black,
        name row/.initial={},
        default/.style={/qrr/default/.style={#1}},
        |-|/.style={
          to path={
            let \p1=(\tikztostart),
                \p2=(\tikztotarget) in
                -- (\x1,.5*\y1+.5*\y2) -- (\x2,.5*\y1+.5*\y2) \tikztonodes
                                                                       -- (\tikztotarget)
          }
        }
    }
    % you can leave the default value for the optional argument blank
    % as the value of "/qrr/default" is taken anyway
    % (but you could make different \List macros
    % with different default default values).
    \newcommand*{\List}[2][default=sort entry black]{%
      \tikzset{#1}%
      \par\noindent%
      \edef\listtoprocess{#2}%
      \pgfkeysgetvalue{name row}{\rowname}
      \def\ListToProcess{}%
      \begin{tikzpicture}[remember picture,inner sep=2pt, outer sep=0]
        \foreach \content in \listtoprocess{
          \IfSubStr{\content}{/}{% true
            \xdef\ListToProcess{\ListToProcess,\content}
          }{%                      false
            \xdef\ListToProcess{\ListToProcess,{/qrr/default}/\content}
          }
        }
        \StrGobbleLeft{\ListToProcess}{1}[\ListToProcess]% removes the first comma (\listToProcess is empty at the start)
        \foreach [count=\i] \Style/\Value in \ListToProcess {
          \ifnum\i=1\relax
            \node [raw sort entry, \Style] (\rowname-\i) {\Value};
          \else
            \node [raw sort entry, right of=\rowname-\number\numexpr\i-1\relax, \Style] (\rowname-\i) {\Value};
          \fi
        }
      \end{tikzpicture}%
    }

\begin{document}

\List[default=sort entry blackgray, name row=a]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}

\bigskip

\List[default=sort entry blackgray, name row=b]{1, 2, 3, s1/1, s1/2, s1/3, 1, 2, 3}

\tikz[overlay,remember picture] \draw[thick, shorten >=\pgflinewidth,->] (a-7.south) to[|-|] (b-9.north);
\end{document}

Output

enter image description here

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .