5
\$\begingroup\$

I am still learning tikz and often have to use complicated solutions where I am sure are more simple ones. From my latest tikz files I picked one to ask for tips what I can do better, to learn about features of tikz.

The general layout should stay the same. Slight changes are fine. Suggestions should be about syntax.

I convert this file using

pdflatex 1.tex

and the result is a pdf/png like this

result

General prologue for all my tikz PNGs

\documentclass[11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{tikz}
\usepackage{pgf}
\usepackage[active,pdftex,tightpage]{preview}
  \usetikzlibrary{backgrounds}
  \usetikzlibrary{decorations.pathreplacing}
  \usetikzlibrary{positioning}
  \usetikzlibrary{shapes}
  \usetikzlibrary{shapes.multipart}
  \usetikzlibrary{trees}
  \usetikzlibrary{arrows}
\definecolor{gpcHintergrund}{RGB}{205,229,244}
\PreviewEnvironment[]{tikzpicture}
\PreviewEnvironment[]{pgfpicture}

\begin{document}

tikz intro

\begin{tikzpicture}[
      background rectangle/.style={fill=gpcHintergrund}, show background rectangle,
      every node/.style={align=center, font=\small, minimum height=1.5em, minimum width=1.0cm,node distance=0cm},
        line/.style={ draw, line width=3pt },
        cell/.style = {rectangle, fill=white, draw, text width=1.0cm,outer sep=0pt},
        capx/.style = {rectangle, draw, text width=1.3cm, color=black!60,outer sep=0pt},
      scale=0.95,
      every node/.append style={transform shape},   % (1) scale here first approx. lines stay.
    %  every node/.append style={draw},
    ]

Center nodes/boxes

   \node at (0,0) [cell] (n1) {10};
   \node[right=of n1,cell] (n2) {20};
   \node[right=of n2,cell] (n3) {30};
   \node[right=of n3,cell] (n4) {40};
   \node[right=of n4,cell] (n5) {50};
   \node[right=of n5,cell] (n6) {60};
   \node[right=of n6,cell] (n7) {70};
   \node[right=of n7,cell] (n8) {80};
   \node[right=of n8,cell,fill=black!20,text=black!60] (ne) {end};

Could this series of right=ofs be replaced by a totally different approach?

The text above and below with arrows

\node[above=of n2.west,yshift=1.0cm] (lb2) {lower\_bound(20)};
  \path [->,draw,shorten <=-1pt] (lb2) -- (n2.north west);

\node[above=of n7.west,yshift=1cm] (ub7) {upper\_bound(60)};
  \path [->,draw,shorten <=-1pt] (ub7) -- (n7.north west);

\node[above=of n4,yshift=0.5cm] (er4) {equal\_range(40)};
  \path [->,draw,shorten <=-3pt] (er4) -- (n4.north west);
  \path [->,draw,shorten <=-3pt] (er4) -- (n5.north west);


\node[below=of n3.west,yshift=-1.0cm] (lb25) {lower\_bound(25)};
  \path [->,draw,shorten <=-1pt] (lb25) -- (n3.south west);

\node[below=of n7.west,yshift=-1.0cm] (ub65) {upper\_bound(65)};
  \path [->,draw,shorten <=-1pt] (ub65) -- (n7.south west);

\node[below=of n4.east,yshift=-0.7cm] (er45) {equal\_range(45)};
  \path [->,draw,shorten <=-3pt] ([xshift=0.4ex]er45.north) -- ([xshift=0.4ex]n5.south west);
  \path [->,draw,shorten <=-3pt] (er45.north) -- (n5.south west);

equal_range(40) could have two straight/parallel arrows, not diagonal. Their tips must point exactly where they are now, but the backs could move apart until parallel. I know about |- and -| but did not manage to straighten the lines.

The curly braces "gefunden" and "nicht gefunden"

\draw[decoration={brace},decorate,color=black!50]
  ([yshift=1.3cm]ne.north west) -- node[right=6pt] {gefunden} ([yshift=0.2cm]ne.north west);

\draw[decoration={brace,mirror},decorate,color=black!50]
  ([yshift=-1.3cm]ne.south west) -- node[right=6pt] {nicht gefunden} ([yshift=-0.2cm]ne.south west);

\end{tikzpicture}

\end{document}

The placing of the braces using yshifts looks very bad to me. What could be a better way?

\$\endgroup\$
  • \$\begingroup\$ @Jamal I left the %s in there on purpose. I should be easy to copy the full src out. Don't you think that was a good idea? If not, ok... \$\endgroup\$ – towi Oct 31 '16 at 21:55
  • \$\begingroup\$ I was just unaware of that and assumed they were entirely irrelevant. You can still add them back if you wish. \$\endgroup\$ – Jamal Oct 31 '16 at 22:03
  • \$\begingroup\$ @Jamal No, now that I see it I like the beauty of it better then the practicality. Its only a handful of lines... \$\endgroup\$ – towi Oct 31 '16 at 22:24
6
\$\begingroup\$

So here are some points. Do ask if you need clarification:

  • tikz loads pgf, so having \usepackage{pgf} is redundant.
  • Personally I'd say only load the libraries you need. You may also use a single \usetikzlibrary, but that is I think just a matter of preference.
  • The arrows.meta library has replaced arrows (the latter still works, but is considered deprecated, see the manual)
  • Instead of the right=of, you can use the chains library, and place the nodes on a chain, using a loop to reduce the code if desired. There are other methods of achieving the same thing I think, but chains works fine here.
  • An alternative of the yshifts and xshifts is to use relative coordinates, e.g. ++(1cm,0) is the point 1cm to the right of the previous active coordinate.
  • For the vertical arrows: The coordinate (a-|b) has the y-coordinate of a and the x-coordinate of b. See how it's used in the code.
  • Instead of having above=of x,yshift=y, use above=y of x, e.g. above=1cm of n2.west.
  • I also added an additional style for the arrows, where the length for shorten < is made an argument. In myarrow/.style={->,shorten <=#1}, #1 indicates the argument, and the style is used as myarrow={<some length>}.
  • I modified \path[draw] to \draw.
  • For e.g. lower_bound(20) you could alternatively make the arrow and node in the same path, i.e.

    \draw [myarrow=-1pt] (n2.north west) -- ++(0,0.7cm) node[above] {lower\_bound(20)};
    

    This is merely a matter of preference though. One might find it clearer to separate the nodes from the arrows, as in your original code.

  • The standalone class is very handy for making PDFs consisting of only a tikzpicture.

enter image description here

\documentclass[11pt,border=1pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{tikz}
\usetikzlibrary{
  backgrounds,
  decorations.pathreplacing,
  chains}
\definecolor{gpcHintergrund}{RGB}{205,229,244}

\begin{document}
\begin{tikzpicture}[
      background rectangle/.style={fill=gpcHintergrund}, show background rectangle,
      every node/.style={align=center, font=\small, minimum height=1.5em, minimum width=1.0cm,node distance=0cm},
        line/.style={ draw, line width=3pt },
        cell/.style = {rectangle, fill=white, draw, text width=1.0cm,outer sep=0pt,on chain}, % added on chain
        capx/.style = {rectangle, draw, text width=1.3cm, color=black!60,outer sep=0pt},
        myarrow/.style={->,shorten <=#1},
      scale=0.95,
      every node/.append style={transform shape},   % (1) scale here first approx. lines stay.
    ]

\begin{scope}[start chain]
\foreach [count=\i] \x in {10,20,...,80}
  \node [cell] (n\i) {\x};

\node[cell,fill=black!20,text=black!60] (ne) {end};
\end{scope}

\node[above=1cm of n2.west] (lb2) {lower\_bound(20)};
  \draw [myarrow=-1pt] (lb2) -- (n2.north west);

\node[above=1cm of n7.west] (ub7) {upper\_bound(60)};
  \draw [myarrow=-1pt] (ub7) -- (n7.north west);

\node[above=0.5cm of n4] (er4) {equal\_range(40)};
  \draw [myarrow=-3pt] (er4.south-|n4.north west) -- (n4.north west);
  \draw [myarrow=-3pt] (er4.south-|n5.north west) -- (n5.north west);


\node[below=1cm of n3.west] (lb25) {lower\_bound(25)};
  \draw [myarrow=-1pt] (lb25) -- (n3.south west);

\node[below=1cm of n7.west] (ub65) {upper\_bound(65)};
  \draw [myarrow=-1pt] (ub65) -- (n7.south west);

\node[below=0.7cm of n4.east] (er45) {equal\_range(45)};
  \draw [myarrow=-3pt] (er45.north) ++(0.45ex,0) coordinate (tmp) -- (tmp|-n5.south west);
  \draw [myarrow=-3pt] (er45.north) -- (n5.south west);

\draw[decoration={brace},decorate,color=black!50]
  (ne.north west) ++(0,1.3cm) -- node[right=6pt] {gefunden} ++(0,-1.1cm);

\draw[decoration={brace,mirror},decorate,color=black!50]
  (ne.south west) ++(0,-1.3cm) -- node[right=6pt] {nicht gefunden} ++(0,1.1cm);

\end{tikzpicture}
\end{document}
\$\endgroup\$
  • \$\begingroup\$ Cool thanks! "dont load pgf" ok. "libs you need", my code is only an excerpt with other tikzs. "arrows.meta" ok. "chains" super! "++" useful for future. "vertical arrows" whow! "above=y of x" I have to read carefully. "\draw" good. "node and arrow same path" very good. "standalone class" I will read up there too. Many thanks, I will work those in and memorize your suggestions. Very, very good. \$\endgroup\$ – towi Nov 2 '16 at 14:57

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.