# Why is a tikz node's minimum width not beholden to the x scale?

I'm trying to create kind of a timeline picture where I have a set "width" of 230 and everything renders according to that width. For example, if I say a node has a width of 115 then it should be half the width of the timeline.

However, it's not working as expected. Here's my MWE:

\documentclass[11pt,a4paper]{letter}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}[x=0.5mm]%
\coordinate(start) at (0,0);
\coordinate(end) at (230, 0);

\node(start label)[below=1mm of start]{Start};
\node(end label)[below=1mm of end]{End};

\draw[thick,->] (start) -- (end);

\node(test)[draw,thick,above=1mm of start,minimum width=230,anchor=south west]{};
\end{tikzpicture}

\end{document}


Notice how I've specified x=0.5mm in the tikzpicture so that I can control the overall width of the picture even though it will always be 230 units wide. Speaking of which, because the test node has a minimum width=230, I would expect it to take up the full width of the timeline. However, it renders like this:

Why is this?

A change of default units of shapes declaration is not so simple and can lead to unexpected side effects. What you like to achieve can be partly solved with defining (common) style for your nodes, for example as:

    box/.style = {draw, thick, minimum width=#1*\unit}]%


where you declare unit in an environment with \tikzpicture with \def\unit{0.5mm} (see MWE below). unit you than use in definition of used units in image. An example of consideration aforementioned in the your MWE is:

\documentclass[11pt,a4paper]{article}

\usepackage{tikz}
\usetikzlibrary{calc,
positioning}

\begin{document}
\begin{figure}[htb]
\def\unit{0.5mm}  % here you set units used in image
\begin{tikzpicture}[x=\unit,
box/.style = {draw, thick, minimum width=#1*\unit}
]
\coordinate[label=below:Start]  (start) at (0,0);
\coordinate[label=below:End]    (end)   at (230,0);
%
\draw[thick,->] (start) -- (end);
\node (test) [box=230,
above right=2mm and 0mm of start] {};
\end{tikzpicture}
\end{figure}

\end{document}


In the case, that you like to assign units to other node shape measures, you need to add them to "box" style definition. For example:

box/.style args = {#1/#2}draw, thick, minimum width=#1*\unit, minimum height=#2*\unit}


and than use it for example as:

\node (test) [box=230/12,
above right=2mm and 0mm of start] {};


The reason is that 230 gets interpreted as 230pt. The x and y dimensions get stored in \pgf@xx and \pgf@yy, respectively. You could use them as follows.

\documentclass[11pt,a4paper]{letter}

\usepackage{tikz}
\usetikzlibrary{positioning}
\newlength{\xunit}
\newlength{\yunit}
\makeatletter
\tikzset{get units/.code={\xunit=\pgf@xx%
\yunit=\pgf@yy}}
\makeatother
\begin{document}

\begin{tikzpicture}[x=0.5mm,get units]%
\coordinate(start) at (0,0);
\coordinate(end) at (230, 0);

\node(start label)[below=1mm of start]{Start};
\node(end label)[below=1mm of end]{End};

\draw[thick,->] (start) -- (end);

\node(test)[draw,thick,above=1mm of start,minimum width=230\xunit,anchor=south west]{};
\end{tikzpicture}

\end{document}


However, this may be considered a "hack". If you want something that adjust to start and end, you could use calc (or fit).

\documentclass[11pt,a4paper]{letter}

\usepackage{tikz}
\usetikzlibrary{positioning,calc}

\begin{document}

\begin{tikzpicture}[x=0.5mm]%
\coordinate(start) at (0,0);
\coordinate(end) at (230, 0);

\node(start label)[below=1mm of start]{Start};
\node(end label)[below=1mm of end]{End};

\draw[thick,->] (start) -- (end);

\path let \p1=($(end)-(start)$) in node (test)
[draw,thick,above=1mm of start,minimum width=\x1,anchor=south west]{};
\end{tikzpicture}
\end{document}


Or to illustrate in a comparison between 230, which get interpreted as 230pt and 230 times your x unit.

\documentclass[11pt,a4paper]{letter}

\usepackage{tikz}
\usetikzlibrary{positioning,decorations.pathreplacing}

\begin{document}

\begin{tikzpicture}[x=0.5mm]%
\coordinate(start) at (0,0);
\coordinate(end) at (230, 0);

\node(start label)[below=1mm of start]{Start};
\node(end label)[below=1mm of end]{End};

\draw[thick,->] (start) -- (end);

\node(test)[draw,thick,above=8mm of start,minimum width=230*0.5mm,anchor=south west]{};
\draw[thick,decorate,decoration={brace,mirror}] (test.south west) -- (test.south east)
node[midway,below]{230*0.5mm (x unit is 0.5mm)};
\node(calc)[draw,thick,above=5mm of test.north west,minimum
width=230,anchor=south west]{};
\draw[thick,decorate,decoration={brace}] (calc.north west) --
(calc.north east)   node[midway,above]{230 gets interpreted as 230pt};
\end{tikzpicture}
\end{document}


• Thanks, but the problem now is that you're specifying 230*0.5mm in the node, so technically it's still not beholden to the scale because you're having to re-specify it. I will have a lot of nodes and want to be able to change x=0.5mm without having to update every node. In other words, I want to say minimum width=230 and have the 230 interpreted as "units", just as it is when I set the coordinate location. – me-- Jun 11 at 4:31
• I suppose I could define a length and use that everywhere instead, but it's still kinda clunky. I don't understand why coordinate uses units and node decides to use points :/ – me-- Jun 11 at 4:48
• @me-- Sorry, was offline. I think the clearest explanation is in this nice answer. Then you may be interested in this question and the related discussion. The way TikZ parses coordinates is that it takes the components and multiplies them by the unit vectors. On the other hands, dimensions are usually in pts, but some care has to be taken with circles, as really nicely explained in the above link. – user121799 Jun 11 at 6:34
• @me-- There is also this answer that allows you to find the unit lengths in all directions. (There is no need to store it in a macro and to keep track of it.) – user121799 Jun 11 at 7:41