1

I am a beginner at working with LaTeX and especially tikz. I would like to generate a block diagram with a variable width in between the blocks, depending on the text of the arrow in between them. When I work with a constant xshift, everything works as expected. As soon as I try to use \settowidth{\mylength}{dummytext} and \the\mylength as an argument for the xshift statement, my adaptations don't work.

\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,positioning}
\usepackage{calc}
\newlength{\mylength}
%First Block
\newcommand{\startblock}[3]{
    % Place nodes
    \settowidth{\mylength}{#1}
    \node [block, label={[label distance=.2pt]270:#2}] (#2){};
% xshift = -65pt will produce my desired result
    \node [virtual, left = of #2, xshift=-\the\mylength] ({#2}i)     {};
    \node [virtual, right=of #2] ({#2}o)    {};
    % Connect nodes
    \draw [->] ({#2}i) -- node {#1} (#2);
    \draw [->] (#2) -- node {#3}({#2}o);
    %\draw [-] ({\thecblock}.south west) -- ({\thecblock}.north east);
}
%Other Blocks
\newcommand{\appendblock}[3]{
    % Place nodes
    \node [block, right={of #1}, label={[label distance=.2cm]270:{#2}}] (#2){};
    \node [virtual, right=of #2] ({#2}o)    {};
    % Connect nodes
    \draw [->] (#2) -- node {#3}({#2}o);
    %\draw [-] ({\thecblock}.south west) -- ({\thecblock}.north east);
}
\begin{document}
\settowidth{\mylength}{VerylongInput}
\the\mylength
    \tikzstyle{block} = [draw, rectangle, minimum height=3em, minimum width=5em]
    \tikzstyle{virtual} = [coordinate]
    \begin{tikzpicture}[>=stealth,auto]%, node distance=2cm]
        \startblock{VerylongInput}{Block1}{Output}
        \appendblock{Block1}{Block2}{Raus2}
        %\testap{Block2}{Toll!}{Scheisse}
    \end{tikzpicture}
\end{document}

enter image description here

enter image description here

  • \mylength is 0pt inside the \startblock. Use \setlength{\mylength}{\widthof{#1}} instead of \settowidth{\mylength}{#1} – user11232 Sep 27 '15 at 15:59
1

enter image description here

\documentclass[border=1mm,tikz]{standalone}
\usetikzlibrary{arrows,positioning}    
\begin{document}

\newcommand{\placearrow}[3]{% {arrow start point}{label above arrow}{label name}
\node [anchor=south west] (#3) at (#1) {#2};
\draw [->] (#1)--(#3.south east);
}
\newcommand{\appendblock}[3]{% {previous label name}{block label}{bloack name}
\node [block,anchor=west] (#3) at (#1.south east){};
\node [anchor=north] at (#3.south) {#2};
}
\begin{tikzpicture}[>=stealth,block/.style={draw, minimum height=3em, minimum width=5em}] 

\placearrow{0,0}{Very long input}{n1}; \appendblock{n1}{Block 1}{B1}
\placearrow{B1.east}{Output}{n2}; \appendblock{n2}{Block 2}{B2}
\placearrow{B2.east}{Raus2}{n3}; 

\end{tikzpicture}

\end{document}

Without over-complicating things, you can implement the automatic solution as above without the need for calc. However, the main error in your original code is the calculation \settowidth{\mylength}{#1} inside the new macro; it should read \setlength{\mylength}{\widthof{#1}} instead.

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.