4

This is probably a question about aligning of nodes among themselves, but I hacked together this little diagram and tried to place them side by side, connected with an arrow by using offsets. There should be a better way.

\documentclass{minimal}

\usepackage{tikz}
\usetikzlibrary{shapes,arrows,calc,positioning,shapes.geometric,decorations.pathreplacing}

\tikzstyle{block} = [rectangle, draw, text width=1.8cm, text centered, minimum height=1cm]
\tikzstyle{line} = [draw, -latex']

\begin{document}

    \begin{tikzpicture}
    \node[block](column1) {Column 1};
    \node[block, right of=column1, node distance=2.05cm](column2) {Column 2};
    \node[block, right of=column2, node distance=2.05cm](column3) {Column 3};
    \node[block, right of=column3, node distance=2.05cm](columnn) {Column N};
    \node[block, below of=column1, node distance=1cm](value1s) {Value 1};
    \node[block, below of=column2, node distance=1cm](value2s) {Value 2};
    \node[block, below of=column3, node distance=1cm](value3s) {...};
    \node[block, below of=columnn, node distance=1cm](valuens) {Value N};

% Attempting to vertically align the nodes with a Y-shift to place the diagrams side by side
    \node[block, right of=columnn, node distance=4cm, yshift=1.5104cm](column) {Column};
    \node[block, below of=column, node distance=1cm](value1) {Value 1};
    \node[block, below of=value1, node distance=1cm](value2) {Value 2};
    \node[block, below of=value2, node distance=1cm](value3) {...};
    \node[block, below of=value3, node distance=1cm](valuen) {Value N};

  \draw [decorate,decoration={brace,amplitude=10pt,raise=2mm}] (value1.north east) -- (valuen.south east) node [black,midway,xshift=1.7cm,text width=1.8cm] (aggappl) {Lorem ipsum dolor};

  \draw [decorate,decoration={brace,amplitude=10pt,raise=2mm,mirror}] (value1s.south west) -- (valuens.south east) node [black,midway,yshift=-1cm] (aggnoappl) {Lorem ipsum dolor};

    \path [line,shorten >=2mm,shorten <=2mm] (valuens.north east) -> (value2.west);
    \end{tikzpicture}

\end{document}

The steps in the arrow can be seen in the screenshot, so it is not really horizontal: enter image description here

3
3

(When I tried your not-very-minimal example, the arrow looked pretty horizontal even on full zoom. So I made a small modification to emphasise the slope by making it point to value1.west instead.)

I think the easiest way to circumvent this issue is to use the -| syntax for coordinates. This looks like (coordinate specification -| coordinate specification) and means "Take the point that is along from the first coordinate and below the second", guaranteeing that it is horizontal to the first coordinate. The coordinate specification can be any valid way of specifying a coordinate (without the brackets), such as (0,0 -| 3,3) or (valuens.north east -| value1.west).

(There's also |- for "above the first coordinate, along from the second")

\documentclass{article}
%\url{http://tex.stackexchange.com/q/328445/86}


\usepackage{tikz}
\usetikzlibrary{shapes,arrows,calc,positioning,shapes.geometric,decorations.pathreplacing}

\tikzstyle{block} = [rectangle, draw, text width=1.8cm, text centered, minimum height=1cm]
\tikzstyle{line} = [draw, -latex']

\begin{document}

    \begin{tikzpicture}
    \node[block](column1) {Column 1};
    \node[block, right of=column1, node distance=2.05cm](column2) {Column 2};
    \node[block, right of=column2, node distance=2.05cm](column3) {Column 3};
    \node[block, right of=column3, node distance=2.05cm](columnn) {Column N};
    \node[block, below of=column1, node distance=1cm](value1s) {Value 1};
    \node[block, below of=column2, node distance=1cm](value2s) {Value 2};
    \node[block, below of=column3, node distance=1cm](value3s) {...};
    \node[block, below of=columnn, node distance=1cm](valuens) {Value N};

% Attempting to vertically align the nodes with a Y-shift to place the diagrams side by side
    \node[block, right of=columnn, node distance=4cm, yshift=1.5104cm](column) {Column};
    \node[block, below of=column, node distance=1cm](value1) {Value 1};
    \node[block, below of=value1, node distance=1cm](value2) {Value 2};
    \node[block, below of=value2, node distance=1cm](value3) {...};
    \node[block, below of=value3, node distance=1cm](valuen) {Value N};

  \draw [decorate,decoration={brace,amplitude=10pt,raise=2mm}] (value1.north east) -- (valuen.south east) node [black,midway,xshift=1.7cm,text width=1.8cm] (aggappl) {Lorem ipsum dolor};

  \draw [decorate,decoration={brace,amplitude=10pt,raise=2mm,mirror}] (value1s.south west) -- (valuens.south east) node [black,midway,yshift=-1cm] (aggnoappl) {Lorem ipsum dolor};

    \path [line,shorten >=2mm,shorten <=2mm] (valuens.north east) -> (value1.west);

\path [line,shorten >=2mm,shorten <=2mm] (valuens.north east) -> (valuens.north east -| value1.west);

    \end{tikzpicture}

\end{document}

horizontal arrow

1
  • Yep, now it's absolutely ideally horizontal!
    – ajeh
    Sep 7 '16 at 20:04
1

I can offer two explanations and one solution.

Explanation 1: The steps are largely artifacts by the viewer that computes the lines and introduces some errors. When I compile your code and successively enlarge the picture up to several 1000%, the irregularities always stay of the same minimal size, while everything else grows. I'd expect the steps also to grow if they were introduced by tikz. Moreover, I have less steps than in your picture.

Explanation 2: You don't position the second stack of blocks strictly horizontally to the right, but do some computations. Internally everything is converted to binary, so inevitably already the conversion of your hard coded real number will introduce some errors.

Solution: Position the second stack of blocks strictly horizontally from the point where the arrow should start. To this end, replace the \node commands for the blocks on the righthand side by

\node[block](value2) at (valuens.north east)[xshift=3cm] {Value 2};
\node[block, above of=value2, node distance=1cm](value1) {Value 1};
\node[block, above of=value1, node distance=1cm](column) {Column};
\node[block, below of=value2, node distance=1cm](value3) {...};
\node[block, below of=value3, node distance=1cm](valuen) {Value N};

The difference to your code is that value2 is positioned first, and the other blocks relative to this one.

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.