我想重新创建一种节点来表示 Git 中的提交、标记或树对象,如下所示
也就是说,我希望节点具有类似表格的内部结构,表示对象的内部结构。我不需要这些内部线条的宽度不同。
如果能够引用节点的各个部分就好了,这样就可以从特定的内部部分绘制线条或箭头,有点像下图这样:
我发现最接近的解决方案是多部分节点与多部分子部分——样式问题问题。那里提出的解决方案是使用tabular
设置\arrayrulewidth
为 TikZ 线宽 - 但是使用此解决方案无法单独处理子节点。
答案1
您可以使用pic
s 和矩阵使得这些形状中的节点可从外部访问。
\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}