If all you want to do is to horizontally align the (bang1)
and (bang2)
nodes, you don't need such complicated calculations. You can use the let
syntax to get the x-coordinate of (bang1)
and the y-coordinate of (sub3)
, using something like
\path let \p1=(bang1), \p2=(sub3) in
node[bangnode,yshift=-2cm,anchor=north] (bang2) at (\x1,\y2) {Bang};
A complete example:
\documentclass[12pt]{standalone}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,shapes,backgrounds,fit,calc}
\begin{document}
\begin{tikzpicture}[node distance=3cm, auto]
\tikzset{
mynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=red!50,very thick, inner sep=1em, minimum size=3em, text centered},
keynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=orange!50,very thick, inner sep=1em, minimum size=3em, text centered},
bangnode/.style={shape=star, star points=20, star point ratio=1.65,draw=black, top color=white, bottom color=yellow!50,very thick, inner sep=2em, minimum size=3em, text centered,font=\bfseries},
myarrow/.style={->, >=latex', shorten >=1pt, thick},
mylabel/.style={text width=7em, text centered}
}
\node[bangnode](bang1){Bang};
\node[keynode,below left=2cm and 2cm of bang1](key){Key Message};
\node[mynode,below right of=key](sub1){Sub Topic 1};
\node[mynode,below of=sub1](sub2){Sub Topic 2};
\node[mynode,below of=sub2](sub3){Sub Topic 3};
\path let \p1=(bang1), \p2=(sub3) in
node[bangnode,yshift=-2cm,anchor=north] (bang2) at (\x1,\y2) {Bang};
%ARROWS
\draw[<->,bend left=45] (sub1)[]to(sub2);
\draw[<->,bend left=45] (sub2)to(sub3);
\draw[<->,bend left=45] (sub1)to (key);
\draw[<->,bend left=45] (sub2)to (key);
\draw[<->,bend left=45] (sub3)to (key);
\begin{pgfonlayer}{background}
\node [fill=blue!10,fit=(bang1) (bang2) (sub1)(sub2)(sub3)(key)] {};
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
Another simpler option would be to use the perpendicular coordinate system, and use something like
\node[bangnode,yshift=-2cm,anchor=north] (bang2) at (bang1|-sub3) {Bang};
to place the node using the x-coordinate of (bang1)
and the y-coordinate of (sub3)
. A complete example:
\documentclass[12pt]{standalone}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,shapes,backgrounds,fit,calc}
\begin{document}
\begin{tikzpicture}[node distance=3cm, auto]
\tikzset{
mynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=red!50,very thick, inner sep=1em, minimum size=3em, text centered},
keynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=orange!50,very thick, inner sep=1em, minimum size=3em, text centered},
bangnode/.style={shape=star, star points=20, star point ratio=1.65,draw=black, top color=white, bottom color=yellow!50,very thick, inner sep=2em, minimum size=3em, text centered,font=\bfseries},
myarrow/.style={->, >=latex', shorten >=1pt, thick},
mylabel/.style={text width=7em, text centered}
}
\node[bangnode](bang1){Bang};
\node[keynode,below left=2cm and 2cm of bang1](key){Key Message};
\node[mynode,below right of=key](sub1){Sub Topic 1};
\node[mynode,below of=sub1](sub2){Sub Topic 2};
\node[mynode,below of=sub2](sub3){Sub Topic 3};
\node[bangnode,yshift=-2cm,anchor=north] (bang2) at (bang1|-sub3) {Bang};
%ARROWS
\draw[<->,bend left=45] (sub1)[]to(sub2);
\draw[<->,bend left=45] (sub2)to(sub3);
\draw[<->,bend left=45] (sub1)to (key);
\draw[<->,bend left=45] (sub2)to (key);
\draw[<->,bend left=45] (sub3)to (key);
\begin{pgfonlayer}{background}
\node [fill=blue!10,fit=(bang1) (bang2) (sub1)(sub2)(sub3)(key)] {};
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
And, to answer the specific question, of course you can calculate distances between nodes, using veclen
and the let
syntax; a simple example:
\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}
\begin{document}
\begin{tikzpicture}
\node (A) {A};
\node[below left=of A ] (B) {B};
\node[below =of B ] (C) {C};
\node[below right =of C ] (D) {D};
\draw (B) -- (D);
\draw (B) let \p1 = ($ (D) - (B) $)
in circle ({veclen(\x1,\y1)});
\end{tikzpicture}
\end{document}
In the original code:
\draw (key) let
\p1 = ($ (sub3) - (key) $);
in
circle ({veclen(\x1,\y1)});
there's a superfluous semicolon at the end of the second line; once this is removed:
\draw (key) let
\p1 = ($ (sub3) - (key) $)
in
circle ({veclen(\x1,\y1)});
the code should work.
I don't really get the question so I hope this is what you wanted. If you include a full document (such that we copy paste and see the problem on our systems) things are much more easier.
Here, you can change the default setting within a scope but your block
style had a node distance
which was resetting every time it is issued. I've made it 2mm such that we can see the difference easier.
\documentclass[tikz]{standalone}
\usetikzlibrary{arrows,shapes.geometric,positioning}
\begin{document}
\begin{tikzpicture}[decision/.style={diamond, draw, text width=4.5em, text badly centered, node distance=3.5cm, inner sep=0pt},
block/.style ={rectangle, draw, text width=6em, text centered, rounded corners, minimum height=4em, minimum height=2em},
cloud/.style ={draw, ellipse, minimum height=2em},
line/.style ={draw,-latex'},
node distance = 1cm,
auto]
\node [block] (1st) {1st};
\node [block, right= of 1st] (2nd1) {2nd1};
\begin{scope}[node distance=2mm and 10mm]%Here we change it for everything inside this scope
\node [block, above= of 2nd1] (2nd2) {2nd2};
\node [block, below= of 2nd1] (2nd3) {2nd3};
\node [block, right= of 2nd1] (3rd1) {3rd1};
\node [block, above= of 3rd1] (3rd2) {3rd2};
\node [block, above= of 3rd2] (3rd3) {3rd3};
\end{scope}
\node [block, below= of 3rd1] (3rd4) {3rd4};
\node [block, below= of 3rd4] (3rd5) {3rd5};
\path [line] (1st) -- (2nd1);
\path [line] (2nd1) -- (2nd2);
\path [line] (2nd1) -- (2nd3);
\path [line] (2nd2) -- (3rd3);
\path [line] (2nd1) -- (3rd1);
\path [line] (1st) -- (2nd1);
\end{tikzpicture}
\end{document}
Best Answer
You are loading the
positioning
library but then usebelow of=...
, however the library provides the syntaxbelow=<optional length> of ...
, whilebelow of
is already provided by the TikZ core.Try something like this instead: