3

I wanted to draw a simple tree using tikz, and embed that tree in an equation:

\documentclass{article}
\usepackage[a4paper,margin=25mm,showframe]{geometry}
\usepackage{graphicx} % <--- For including graphics
\usepackage{listings} % <--- For typesetting verbatim code
\usepackage{tikz}     % <--- For drawing the diagram
\usepackage{array,amsmath}     % <--- For drawing the diagram

\usetikzlibrary{calc,positioning,shapes.geometric}

\begin{document}

\def\mytree{\tikz[inner sep=1pt] {
                  \node (T1) at (0,0) {$T_1$};
                  \node (T2) at (1,0) {$T_2$};
                  \node (INLJ) at (0.5,0.5) {\textsf{IndexJoin}};

                  \node (T3) at (1.5,0.5) {$T_3$};
                  \node (SMJ) at (1,1) {\small{\sf HashJoin}};

                  \node (T4) at (2,1) {$T_4$};
                  \node (HJ) at (1.5,1.5) {\sf HashJoin};

                  \draw (T1)--(INLJ)--(T2);
                  \draw (INLJ)--(SMJ)--(T3);
                  \draw (SMJ)--(HJ)--(T4);
}}

\[ \left( \mytree, 10.111  \right)\]

\end{document}

This results in the follow picture: enter image description here

You can see there's a lot of whitespace beneath both elements of the tuple. How can I fix this?

Another issue: is there a way to get the "[comma] 10.111" part nicer, say by vertically aligning it with the middle of the tikz picture?

==============

EDIT

Thanks to Phelype's help I'm now able to reduce the whitespace. However a related question shows up. I want to \def two variants of the tree beforehand and use them afterwards -- but latex gives compilation errors. If I \def one variant, immediately use it, then \def and use another variant there's no issues. Why is that?

OK code (errors out if I use the two trees altogether):

\def \tree1 {\tikz[inner sep=1pt, baseline=(T3.north)] {
                  \node (T1) at (0,0) {$T_1$};
                  \node (T2) at (1,0) {$T_2$};
                  \node (INLJ) at (0.5,0.5) {\small{\sffamily IndexJoin}};

                  \node (T3) at (1.5,0.5) {$T_3$};
                  \node (SMJ) at (1,1) {\small{\sffamily HashJoin}};

                  \node (T4) at (2,1) {$T_4$};
                  \node (HJ) at (1.5,1.5) {\small{\sffamily HashJoin}};

                  \draw (T1)--(INLJ)--(T2);
                  \draw (INLJ)--(SMJ)--(T3);
                  \draw (SMJ)--(HJ)--(T4);}}

\[ \left[ \tree1 , \{T1, T2, T3, T4\}; 10.111  \right]\]

\def \tree2 {\tikz[inner sep=1pt, baseline=(T3.south)] {
                  \node (T1) at (0,0) {$T_1$};
                  \node (T2) at (1,0) {$T_2$};
                  \node (INLJ) at (0.5,0.5) {\small{\sffamily IndexJoin}};

                  \node (T3) at (1.5,0.5) {$T_3$};
                  \node (SMJ) at (1,1) {\small{\sffamily HashJoin}};

                  \draw (T1)--(INLJ)--(T2);
                  \draw (INLJ)--(SMJ)--(T3);}}

\[ \left[ \tree2 , \{T1, T2, T3, T4\}; 10.111  \right]\]
3
  • 1
    Not sure, but I think if you pass the option baseline=(T3.north) to the \tikz command it will, more or less, solve both problems. Off-topic: you shouldn't use \sf, but \sffamily. Oct 18, 2018 at 20:24
  • Thanks! Mind taking a look at the followup issue?
    – Covi
    Oct 18, 2018 at 20:52
  • 1
    You can't use numbers in command names. With the first \def you define the command \tree (not \tree1) and it is required to be followed by the number 1. Later, you override that definition, and define the command \tree (again, not \tree2) and its definition requires it to be followed by 2. Then, when you use \tree1 TeX says that Use of \tree doesn't match its definition.. Oct 18, 2018 at 20:57

1 Answer 1

4

I would use baseline=(current bounding box.center) to center the tikz picture. (Not that this matters at all, I would also use a tikzpicture environment rather than a \tikz command.)

Unless I have missed something the two trees are almost identical except that the second tree has two extra edges. Rather than defining two almost identical commands why not create a \mytree and \mytree* variant, which is easy to do using \NewDocumentCommand from xparse. Doing it this way, here is the output:

enter image description here

and here is the code:

\documentclass{article}
\usepackage[a4paper,margin=25mm,showframe]{geometry}
\usepackage{graphicx} % <--- For including graphics
\usepackage{listings} % <--- For typesetting verbatim code
\usepackage{tikz}     % <--- For drawing the diagram
\usepackage{array,amsmath}     % <--- For drawing the diagram

\usetikzlibrary{calc,positioning,shapes.geometric}

\usepackage{xparse}

\NewDocumentCommand\mytree{s}{
  \begin{tikzpicture}[inner sep=1pt, baseline=(current bounding box.center)]
      \node (T1) at (0,0) {$T_1$};
      \node (T2) at (1,0) {$T_2$};
      \node (INLJ) at (0.5,0.5) {\textsf{IndexJoin}};

      \node (T3) at (1.5,0.5) {$T_3$};
      \node (SMJ) at (1,1) {\small{\sf HashJoin}};

      \node (T4) at (2,1) {$T_4$};
      \node (HJ) at (1.5,1.5) {\sf HashJoin};

      \draw (T1)--(INLJ)--(T2);
      \draw (INLJ)--(SMJ)--(T3);
      \IfBooleanT{#1}{\draw (SMJ)--(HJ)--(T4);}
  \end{tikzpicture}
}

\begin{document}

\[ \left[ \mytree*, \{T1, T2, T3, T4\}; 10.111  \right]\]

\[ \left[ \mytree, \{T1, T2, T3, T4\}; 10.111  \right]\]

\end{document}

The {s} in \NewDocumentCommand\mytree{s}{...} says that the \mytree macro has an optional *-argument; that is, it can be used as \mytree or \mytree*. Inside the definition of \mytree the line

\IfBooleanT{#1}{...}

says that if #1 (exists and) is a * then do {...}. There are also variants \IfBooleanTF and \IfBooleanF. See the xparse documentation for more details.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .