-1

I would like to recreate a type of node to represent commit, tag or tree objects in Git, like the one below

git tag representation

That is, I would like to have table-like internal structure of a node, representing internal structure of an object. I don't need different widths of those internal lines.

It would be good to be able to refer to individual parts of node, so that lines or arrows can be drawn from specific internal parts, somewhat like in the image below:

git objects graph with commit, tree and blob objects


Closest I have found to the solution is Multipart nodes with multipart subparts — style issue question. The solution proposed there in question, namely using tabular with \arrayrulewidth set to the TikZ line width -- with this solution however one cannot individually address subnodes.

2

You can use pics and matrices to make the nodes in these shapes accessible from outside.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{matrix}
\tikzset{mmat/.style={matrix of nodes,inner sep=-0.4pt,
    nodes={anchor=center,draw,text height=1.1em,text depth=0.35ex,inner sep=2pt},
    row sep=-\pgflinewidth,column sep=-\pgflinewidth,
    ampersand replacement=\&},
  pics/commit/.style n args={3}{code={
  \matrix (-mat)[mmat,fill=green!20,
    column 1/.style={nodes={text width=5em-4pt,font=\sffamily,align=center}},
    column 2/.style={nodes={text width=5em-4pt,font=\ttfamily,align=center}}]{%
    #1
    };
    \node[font=\tiny,opacity=0,text width=10em-10pt,anchor=north](tmp)
        at (-mat.south){#2};
    \draw[fill=green!20,very thick,rounded corners=2pt] 
      (-mat.north west)|- ([yshift=2em]-mat.north east) 
      [sharp corners]-- (-mat.north east)    -- cycle
      [rounded corners=2pt]
      (-mat.south west) |- (tmp.south-|-mat.south east) 
      [sharp corners]-- (-mat.south east)    -- cycle;
    \draw[very thick]  (-mat.north west) -- (-mat.south west)   
    (-mat.north east) -- (-mat.south east)
    ([xshift=-3em]-mat.north east) -- ++ (0,2em);
    \path (-mat.north west) 
      node[anchor=south west,font=\sffamily\bfseries,inner sep=6pt]{commit}
      (-mat.north east) 
      node[anchor=south east,font=\sffamily,inner sep=6pt,text=gray]{size}; 
    \node[font=\tiny,text width=10em-10pt,anchor=north,text=gray](-message)
        at (-mat.south){#2};
    \node[anchor=south,font=\small\ttfamily]
     (-label) at ([yshift=2em]-mat.north){#3};
    }},
  pics/tree/.style n args={2}{code={
  \matrix (-mat)[mmat,fill=blue!20,
    column 1/.style={nodes={text width=3em-4pt,font=\sffamily,align=center}},
    column 2/.style={nodes={text width=3em-4pt,font=\ttfamily,align=center}},
    column 3/.style={nodes={text width=4em-4pt,font=\ttfamily,align=center}},
    ]{%
    #1
    };
    \draw[fill=blue!20,very thick,rounded corners=2pt] 
      (-mat.north west)|- ([yshift=2em]-mat.north east) 
      [sharp corners]-- (-mat.north east)    -- cycle
      ;
    \draw[very thick,rounded corners=2pt]  (-mat.north west) |- (-mat.south)    
        -|(-mat.north east) 
    ([xshift=-3em]-mat.north east) -- ++ (0,2em);
    \path (-mat.north west) 
      node[anchor=south west,font=\sffamily\bfseries,inner sep=6pt]{tree}
      (-mat.north east) 
      node[anchor=south east,font=\sffamily,inner sep=6pt,text=gray]{size}; 
    \node[anchor=south,font=\small\ttfamily]
     (-label) at ([yshift=2em]-mat.north){#2};
    }},
  pics/blob/.style n args={2}{code={
    \node[font=\tiny,opacity=0,text width=10em-10pt,anchor=north](tmp)
        at (0,0){#1};
    \draw[fill=red!20,very thick,rounded corners=2pt] 
      ([yshift=2em]tmp.north west) rectangle (tmp.south east);
    \node[font=\tiny,text width=10em-10pt,anchor=north](-message)
        at (0,0){#1};
    \draw[very thick]  (tmp.north west) -- 
    (tmp.north east) 
    ([xshift=-3em]tmp.north east) -- ++ (0,2em);
    \path (tmp.north west) 
      node[anchor=south west,font=\sffamily\bfseries,inner sep=6pt]{blob}
      (tmp.north east) 
      node[anchor=south east,font=\sffamily,inner sep=6pt,text=gray]{size}; 
    \node[anchor=south,font=\small\ttfamily]
     (-label) at ([yshift=2em]tmp.north){#2};
    }},
    }
\begin{document}
\begin{tikzpicture}
 \path (0,0) pic (commit1) {commit={%
    tree \& |[alias=-p12]|0de24\\
    parent \& nil\\
 }{%
 my commit message goes here and is really really cool}{%
 98ca9..}}
 (5,0) pic (tree1) {tree={%
 tree \& e8455 \& |[alias=-p13]| README\\
 tree \& e8455 \& README\\
 }{%
 98ca9..}}
 (10,0) pic (blob1) {blob={%
 require\\
 require}{%
 98ca9..}};
 \draw[very thick,-stealth] (commit1-p12.east) to[bend left] (tree1-label);
 \draw[very thick,-stealth] (tree1-p13.east) to[bend left] (blob1-label);
\end{tikzpicture}
\end{document}

enter image description here

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.