Here's a working example. I've reformatted it a fair bit and added some styles to help keep straight what's doing what.
\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta,%
positioning,%
shapes,calc%%
}
\tikzset{%%
ura hub/.style={circle,
anchor=center,
draw=red!80!black,
inner color=white,
outer color=red!50,
inner sep=2pt},
ura hour hand/.style={line width=0.8mm,
red,
shorten <=-2mm,
{Round Cap[]-Kite[length=12pt,width=6pt,inset=5pt]},
},
ura minute hand/.style={red,
thick,
opacity=0.6,
transparency group,
{-Kite[]}},
ura matt/.style={circle,
draw=gray,
thick,
fill=#1!5,
minimum width=20mm,
inner sep=0pt,
anchor=center,
},
ura body/.style={circle,
minimum width=21mm,
fill=gray!50}
}
\begin{document}
\begin{tikzpicture}[
J/.style = {thick, bend left, shorten >=1mm, shorten <=1mm, -{Straight Barb[]}},
pics/ura/.style n args={3}{
code={\node[ura body] (ura) at (0,0) {};
\foreach \i in
{north,south,east,west,north west,north east,south west,south east}
{\coordinate (-\i) at (ura.\i);}
%%
\node[ura matt=#1] at (ura.center) {};
\node[font=\tiny,below=1mm of ura.center] {tik-tak};
%% minutes and hours on clock
\foreach \a/\label in
{0/3, 30/2, 60/1,
90/12, 120/11, 150/10,
180/9, 210/8, 240/7,
270/6, 300/5, 330/4}
{
\draw[very thick] ($(ura.center)+(\a:8.2mm)$) --
($(ura.center)+(\a:9.9mm)$);
\node[inner sep=0pt,anchor=center,font=\tiny] (N/\a) at ($(ura.center)+(\a:7mm)$) {\tiny\label};
%\draw ($(ura.center)+(\a:7mm)$) circle (1pt);
%\draw (N/\a) -- (ura.center);
}
%% minute tick marks
\foreach \s in {1,2,...,60}
{
\draw ($(ura.center)+(6*\s:9mm)$) -- ($(ura.center)+(6*\s:9.8mm)$);
}
\draw[ura hour hand] (ura.center) -- ($(ura.center)+(#2,6mm)$);
\draw[ura minute hand] ($(ura.center)+(#3-180:3mm)$) -- (ura.center) -- ($(ura.center)+(#3:8mm)$);
\node[ura hub] at (ura.center) {};
}
},
X/.style={above=0mm of #1-north,font=\footnotesize\sffamily\bfseries}
]
%-------
\pic (A) at (0, 0) {ura={teal}{0}{150}};
\node[X=A] {ura A};
\pic (B) at (4, 0) {ura={yellow}{0}{120}};
\node[X=B] {ura B};
\node[below=2mm of A-south] (myC) {};
\pic[anchor=north] (C) at (myC) {ura={yellow}{0}{120}};
\node[X=C] {ura C};
%-------
\draw[J] (A-east) to node[above,sloped] {11:50} (B-west);
\draw[J] (B-west) to node[below,sloped] {11:55} (A-east);
%----------------
\end{tikzpicture}
\end{document}
The problem seems to be how the anchoring mechanism of the pic
gets smuggled into the options for the nodes you're using. So, in each of those nodes, I've specified that the anchor be anchor=center
.
I've left the lines
%\draw ($(ura.center)+(\a:7mm)$) circle (1pt);
%\draw (N/\a) -- (ura.center);
in there for you to play with. Remove the anchor=center
from the options for the nodes, this will show that \draw
gets things right, but node
s don't.
Stylistically I think it makes better sense to use \draw
instead of \node
when all you're doing in drawing. So for example, for the hub for the two hands, instead of writing
\node[ura hub] at (ura.center) {};
it makes better sense to write
\draw[ura hub] (ura.center) circle (2.5pt);
in which case I've redefined the key 'ura hub' to be:
ura hub/.style={red,
line width=1pt,
inner color=white,
outer color=red!50,
},
A clean version
Here's a clean version of what I'm suggesting above about how to use \draw
and \node
. Also, I've removed the dependency on the TikZ library calc
, and I've renamed some of the keys to make clear which ones are being used for nodes and to make clear what the function of others (formerly X
and J
) are about. And though how you set the hours on the clock follows the example from the TikZ manual, I've rewritten in a manner that I believe is a bit easier to understand.
\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta,%
positioning,%
shapes,
}
\tikzset{%%
ura body for node/.style={circle,
minimum width=21mm,
fill=gray!50},
ura matt/.style={draw=gray,
thick,
fill=#1!5,
},
ura hour hand/.style={line width=0.8mm,
red,
shorten <=-2mm,
{Round Cap[]-Kite[length=12pt,width=6pt,inset=5pt]},
},
ura minute hand/.style={red,
thick,
opacity=0.6,
transparency group,
{-Kite[]}},
ura hours for node/.style={inner sep=0pt,anchor=center,font=\tiny,node contents=#1},
ura hub/.style={red,
line width=1pt,
inner color=white,
outer color=red!50,
},
}
\begin{document}
\begin{tikzpicture}[
arrow path between clocks/.style = {thick, bend left, shorten >=1mm, shorten <=1mm, -{Straight Barb[]}},
pics/ura/.style n args={3}{
code={\node[ura body for node] (ura) at (0,0) {};
\foreach \i in
{north,south,east,west,north west,north east,south west,south east}
{\coordinate (-\i) at (ura.\i);}
%%
\draw[ura matt=#1] (ura.center) circle (10mm);
\node[font=\tiny,below=1mm of ura.center] {tik-tak};
%% minutes and hours on clock
%% major tick marks
\foreach \myhour in {1,...,12}
{
\pgfmathsetmacro\myangle{int(90-\myhour*30)}
%% tick mark for hour
\draw[very thick] (ura.center) ++(\myangle:8.2mm) -- ++(\myangle:1.7mm);
%% place numbers for the hours
\path (ura.center) ++ (\myangle:7mm) node[ura hours for node=\myhour];
}
%% minor tick marks
\foreach \mysecond in {1,2,...,60}
{
\pgfmathsetmacro\myangle{int(6*\mysecond)}
%% tick marks for seconds
\draw (ura.center) ++ (\myangle:9mm) -- ++ (\myangle:0.8mm);
}
\draw[ura hour hand] (ura.center) -- ++(#2,6mm);
\draw[ura minute hand] (ura.center) ++ (#3-180:3mm) -- ++ (#3:11mm);
\draw[ura hub] (ura.center) circle (2.5pt);
}
},
position clock title at/.style={above=0mm of #1-north,font=\footnotesize\sffamily\bfseries}
]
%% the clocks:
%% clock A
\pic (A) at (0, 0) {ura={teal}{0}{150}};
\node[position clock title at=A] {ura A};
%% clock B
\pic (B) at (4, 0) {ura={yellow}{0}{120}};
\node[position clock title at=B] {ura B};
%% clock C
\node[below=4mm of A-south] (myC) {};
\pic[anchor=north] (C) at (myC) {ura={yellow}{0}{120}};
\node[position clock title at=C] {ura C};
%% Mapping between clocks
\draw[arrow path between clocks] (A-east) to node[above,sloped] {11:50} (B-west);
\draw[arrow path between clocks] (B-west) to node[below,sloped] {11:55} (A-east);
\end{tikzpicture}
\end{document}
A final example
In this last example, you can pass your clock the time in a more human readable form (instead of having to think in terms of angles and degrees). I've also adjusted the hour hand to progress continuously around the clock according to hour and minute (as with a real analogue clock).
\documentclass[12pt,tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta,%
positioning,%
shapes,
}
\tikzset{%%
ura body for node/.style={circle,
minimum width=21mm,
fill=gray!50},
ura matt/.style={draw=gray,
thick,
fill=#1!5,
},
ura hour hand/.style={line width=0.8mm,
red,
shorten <=-2mm,
{Round Cap[]-Kite[length=12pt,width=6pt,inset=5pt]},
},
ura minute hand/.style={red,
thick,
opacity=0.6,
transparency group,
{-Kite[]}},
ura hours for node/.style={inner sep=0pt,anchor=center,font=\tiny,node contents=#1},
ura hub/.style={red,
line width=1pt,
inner color=white,
outer color=red!50,
},
}
\makeatletter
\def\ae@parse@hour@minutes#1:#2;{%%
\pgfmathsetmacro\my@hour{int(90-#1*30)-30/60*#2}%%
\pgfmathsetmacro\my@minu{int(90-#2*6)}}
\newcommand\aeUraCode[2]{%%
\ae@parse@hour@minutes#2;
\node[ura body for node] (ura) at (0,0) {};
\foreach \i in
{north,south,east,west,north west,north east,south west,south east}
{\coordinate (-\i) at (ura.\i);}
%%
\draw[ura matt=#1] (ura.center) circle (10mm);
\node[font=\tiny,below=1mm of ura.center] {tik-tak};
%% minutes and hours on clock
%% major tick marks
\foreach \myhour in {1,...,12}
{
\pgfmathsetmacro\myangle{int(90-\myhour*30)}
%% tick mark for hour
\draw[very thick] (ura.center) ++(\myangle:8.2mm) -- ++(\myangle:1.7mm);
%% place numbers for the hours
\path (ura.center) ++ (\myangle:7mm) node[ura hours for node=\myhour];
}
%% minor tick marks
\foreach \mysecond in {1,2,...,60}
{
\pgfmathsetmacro\myangle{int(6*\mysecond)}
%% tick marks for seconds
\draw (ura.center) ++ (\myangle:9mm) -- ++ (\myangle:0.8mm);
}
\draw[ura hour hand] (ura.center) -- ++(\my@hour:6mm);
\draw[ura minute hand] (ura.center) ++ (\my@minu-180:3mm) -- ++ (\my@minu:11mm);
\draw[ura hub] (ura.center) circle (2.5pt);
}
\makeatother
\begin{document}
\begin{tikzpicture}[
arrow path between clocks/.style = {thick, bend left, shorten >=1mm, shorten <=1mm, -{Straight Barb[]}},
pics/ura/.style n args={2}{code={\aeUraCode{#1}{#2}}},
position clock title at/.style={above=0mm of #1-north,font=\footnotesize\sffamily\bfseries}
]
%% the clocks:
%% clock A
\pic (A) at (0, 0) {ura={teal}{11:50}};
\node[position clock title at=A] {ura A};
%% clock B
\pic (B) at (4, 0) {ura={yellow}{11:55}};
\node[position clock title at=B] {ura B};
%% clock C
\node[below=4mm of A-south] (myC) {};
\pic[anchor=north] (C) at (myC) {ura={yellow}{12:45}};
\node[position clock title at=C] {ura C};
%% clock D
\node[below=4mm of B-south] (myD) {};
\pic[anchor=north] (D) at (myD) {ura={blue}{3:24}};
\node[position clock title at=D] {ura D};
%% Mapping between clocks
\draw[arrow path between clocks] (A-east) to node[above,sloped] {11:50} (B-west);
\draw[arrow path between clocks] (B-west) to node[below,sloped] {11:55} (A-east);
\end{tikzpicture}
\end{document}