[Tex/LaTex] TikZ line dots and trees

graphstikz-pgftikz-trees

Given the following code:

\documentclass[12pt]{article}

\usepackage{tikz}
\usetikzlibrary{arrows,shapes}

\begin{document}

\begin{center}
\begin{tikzpicture}
\node (node1)   at (-6,0)   [draw,fill=gray!30] {node1};
\node (node2)   at (-2,-1.5)    [draw] {node2};
\node (node3)   at (2,-1.5) [draw] {node3};
\node (node4)   at (6,-1.5) [draw] {node4};

\draw (node cs:name=node1,anchor=east) |- (8,0);
\draw (node cs:name=node4,anchor=north)[-*] |- (6,0);
\draw (node cs:name=node3,anchor=north)[-*] |- (2,0);
\draw (node cs:name=node2,anchor=north)[-*] |- (-2,0);
\end{tikzpicture}
\end{center}

\end{document}

In the resulting picture, the dots ending the lines from node2, node3 and node4 are just below the horizontal line coming from node1:

enter image description here

1) How to place the dots so that they are vertically centered over the horizontal line?

2) Is it possible to realize the same graph, with exactly the same feature, but with the trees TikZ library, or with the forest package? How?

Best Answer

The code below shows two different options for placing the dots on the line. The first one uses a custom arrow tip (named Midcircle) which is similar to the * arrow tip you used, except that the circle is centered on the end coordinate of the path. The second option is to use a node to make the dot, instead of an arrow tip.

I also changed the coordinates you used a bit. The node cs coordinate system has an implicit form, so you can say node1.east, instead of node cs:name=node1,anchor=east.

And I defined the end of the vertical lines using a perpendicular coordinate: (node2.north |- node1.east).

output of code

\documentclass[12pt]{article}

\usepackage{tikz}
\usetikzlibrary{arrows.meta}

% define a new arrow tip, filled circle centered on the end of the path
\pgfdeclarearrow{
  name=Midcircle,
  parameters= {\the\pgfarrowlength},  
  setup code={
   \pgfarrowssettipend{0.25\pgfarrowlength}
   \pgfarrowssetlineend{-0.25\pgfarrowlength}
   \pgfarrowlinewidth=\pgflinewidth
   \pgfarrowssavethe\pgfarrowlength
  },
  drawing code={
   \pgfpathcircle{\pgfpoint{0.25\pgfarrowlength}{0pt}}{0.5\pgfarrowlength}
   \pgfusepathqfill
  },
  defaults = { length = 5pt }
}
\begin{document}

\begin{center}
\begin{tikzpicture}[
  box/.style={draw}
]
\node [box,fill=gray!30] (node1) at (-6,0)    {node1};
\node [box]              (node2) at (-2,-1.5) {node2};
\node [box]              (node3) at (2,-1.5)  {node3};
\node [box]              (node4) at (6,-1.5)  {node4};

\draw               (node1.east)  -- (8,0);
\draw [-Midcircle] (node4.north) -- (node4.north |- node1.east);
\draw [-Midcircle] (node3.north) -- (node3.north |- node1.east);
\draw [-Midcircle] (node2.north) -- (node2.north |- node1.east);
\end{tikzpicture}

\begin{tikzpicture}[
  box/.style={draw},
  dot/.style={minimum size=5pt,inner sep=0pt,fill,circle,node contents={}}
]
\node [box,fill=gray!30] (node1) at (-6,0)    {node1};
\node [box]              (node2) at (-2,-1.5) {node2};
\node [box]              (node3) at (2,-1.5)  {node3};
\node [box]              (node4) at (6,-1.5)  {node4};

\draw (node1.east)  -- (8,0);
\draw (node4.north) -- (node4.north |- node1.east) node[dot];
\draw (node3.north) -- (node3.north |- node1.east) node[dot];
\draw (node2.north) -- (node2.north |- node1.east) node[dot];
\end{tikzpicture}
\end{center}

\end{document}