我尝试为实体关系图绘制关联类型。如何绘制带有分割部分=2 或 3 的倒角矩形?我找到了这个参考:使用 TikZ 水平放大的六边形但它不能完全解决我的问题。我尝试了一些“倒角矩形”和“矩形分割”的变体,但没有成功。
我怎样才能绘制这样的图形:
答案1
好的,这有点太长了,但本质上它是rectangle split
形状 + 一些基本几何的复制/粘贴的混合。
我重新定义了东锚点和西锚点,现在可以通过名称访问中间锚点left/right upper/lower bump
。可以进一步定义封装样式以简化节点设置的输入。还inner sep
需要进行一些调整。角度通过目测设置为 75 度,但也可以更改。
然而它并不完美。锚点边框仍然指向原始rectangle split
形状,不应使用,即
\draw (o) -- (b);
给出了错误的结果,但如果该点位于节点上方或下方,则会给出正确的输出,因为该形状的顶部和底部与相同rectangle split
。
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\makeatletter
\pgfdeclareshape{chamfered rectangle}{
\nodeparts{text,two,three,four}
\inheritsavedanchors[from=rectangle split]
\inheritanchorborder[from=rectangle split]
\inheritanchor[from=rectangle split]{center}
\inheritanchor[from=rectangle split]{north}
\inheritanchor[from=rectangle split]{north west}
\inheritanchor[from=rectangle split]{north east}
\inheritanchor[from=rectangle split]{base}
\inheritanchor[from=rectangle split]{south}
\inheritanchor[from=rectangle split]{south west}
\inheritanchor[from=rectangle split]{south east}
\inheritanchor[from=rectangle split]{text}
\inheritanchor[from=rectangle split]{two}
\inheritanchor[from=rectangle split]{three}
\inheritanchor[from=rectangle split]{four}
\inheritanchor[from=rectangle split]{text split west}
\inheritanchor[from=rectangle split]{two split west}
\inheritanchor[from=rectangle split]{three split west}
\inheritanchor[from=rectangle split]{four split west}
\inheritanchor[from=rectangle split]{text split east}
\inheritanchor[from=rectangle split]{two split east}
\inheritanchor[from=rectangle split]{three split east}
\inheritanchor[from=rectangle split]{four split east}
\savedanchor{\leftbump}{
\northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
\southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgfmathsetmacro{\vertih}{0.5*(\pgf@ya-\pgf@yb)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
\southwest
\advance\pgf@x by -\horizw pt
\advance\pgf@y by \vertih pt
}
\savedanchor{\rightbump}{
\northeast \pgf@xa = \pgf@x \pgf@ya=\pgf@y
\southwest \pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgfmathsetmacro{\vertih}{0.5*(\pgf@ya-\pgf@yb)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
\northeast
\advance\pgf@x by \horizw pt
\advance\pgf@y by -\vertih pt
}
\savedanchor{\lubump}{
\northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
\southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgf@lib@sh@rs@anchor@one@split@west
\pgfmathsetmacro{\vertih}{(\pgf@ya-\pgf@y)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
\pgfpoint{\pgf@xb}{\pgf@ya}
\advance\pgf@x by -\horizw pt
\advance\pgf@y by -\vertih pt
}
\savedanchor{\llbump}{
\northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
\southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgf@lib@sh@rs@anchor@three@split@west
\pgfmathsetmacro{\vertih}{(\pgf@y-\pgf@yb)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
\southwest
\advance\pgf@x by -\horizw pt
\advance\pgf@y by \vertih pt
}
\savedanchor{\rubump}{
\northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
\southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgf@lib@sh@rs@anchor@one@split@west
\pgfmathsetmacro{\vertih}{(\pgf@ya-\pgf@y)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
\northeast
\advance\pgf@x by \horizw pt
\advance\pgf@y by -\vertih pt
}
\savedanchor{\rlbump}{
\northeast\pgf@xa = \pgf@x \pgf@ya=\pgf@y
\southwest\pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgf@lib@sh@rs@anchor@three@split@west
\pgfmathsetmacro{\vertih}{(\pgf@y-\pgf@yb)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
\pgfpoint{\pgf@xa}{\pgf@yb}
\advance\pgf@x by \horizw pt
\advance\pgf@y by \vertih pt
}
\anchor{east}{\rightbump}
\anchor{west}{\leftbump}
\anchor{left upper bump}{\lubump}
\anchor{left lower bump}{\llbump}
\anchor{right upper bump}{\rubump}
\anchor{right lower bump}{\rlbump}
\backgroundpath{
\rectanglesplitparameters
\northeast
\pgf@xa = \pgf@x \pgf@ya=\pgf@y
\centerpoint
\pgf@xc = \pgf@x \pgf@yc=\pgf@y
\southwest
\pgf@xb = \pgf@x \pgf@yb=\pgf@y
\pgfmathsetmacro{\vertih}{0.5*(\pgf@ya-\pgf@yb)}
\pgfmathsetmacro{\horizw}{\vertih/tan(70)}
\pgfpathmoveto{\northeast}
\pgflineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
\pgflineto{\leftbump}
\pgflineto{\southwest}
\pgflineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
\pgflineto{\rightbump}
\pgfclosepath
\pgfmoveto{\lubump}\pgflineto{\rubump}
\pgfmoveto{\llbump}\pgflineto{\rlbump}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node (o) at (0,0) {0};
\node[chamfered rectangle,rectangle split part align={center,left,left,center},draw,inner sep=2pt] (a) at (0,3) {
\verb|COMPTE|
\nodepart{two} \verb|NUM_COMPTE |
\nodepart{three} \verb|SOLDE|
\nodepart{four} \verb|id:NUM_COMPTE|
};
\node[chamfered rectangle,rectangle split part align={center,left,left,center},draw] (b) at (3,0) {
\verb|AA|
\nodepart{two} \verb|NUM_AA |
\nodepart{three} \verb|RAND|
\nodepart{four} \verb|id:NUM_AA|
};
\draw (a.right lower bump) -- (b.left upper bump);
\draw[-latex] (o) -- (b.left lower bump);
\end{tikzpicture}
\end{document}
根据 Tom 的提示,以下是自定义形状中定义的锚点,只需按照复制/粘贴模式即可添加/删除更多锚点。然而,<nodepartnumber> split east/west
锚点仍将按照原始版本进行定义,但我认为在这种特殊情况下不需要它们。
答案2
这里有一个倒角矩形,它定义了几个你可以使用的坐标:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes,calc,arrows}
\newcommand{\chamrec}[8]{% width, height, name, 1st, 2nd, 3rd, x, y
\pgfmathsetmacro{\ind}{#2/4}
\begin{scope}[xshift=#7,yshift=#8]
\draw (\ind,0) coordinate (#3_bl) -- (#1-\ind,0) coordinate (#3_br) -- (#1,#2/2) coordinate (#3_r) -- (#1-\ind,#2) coordinate (#3_tr) -- (\ind,#2) coordinate (#3_tl) -- (0,#2/2) coordinate (#3_l) -- cycle;
\coordinate (#3_tlm) at ($0.5*(#3_tl)+0.5*(#3_l)$);
\coordinate (#3_t) at ($0.5*(#3_tl)+0.5*(#3_tr)$);
\coordinate (#3_trm) at ($0.5*(#3_tr)+0.5*(#3_r)$);
\coordinate (#3_brm) at ($0.5*(#3_br)+0.5*(#3_r)$);
\coordinate (#3_b) at ($0.5*(#3_br)+0.5*(#3_bl)$);
\coordinate (#3_blm) at ($0.5*(#3_bl)+0.5*(#3_l)$);
\coordinate (#3_sls) at ($0.5*(#3_bl)+0.5*(#3_tl)$);
\pgfmathsetmacro{\txt}{(#1-2*\ind-0.1)*1cm}
\draw (#3_tlm) -- (#3_trm);
\draw (#3_blm) -- (#3_brm);
\node[below] at (#3_t) {#4};
\node[right,text width=\txt] at (#3_sls) {#5};
\node[above right] at (#3_bl) {#6};
\end{scope}
}
\begin{document}
\begin{tikzpicture}
\chamrec{6}{2}{first}{Red}{Blue Blue Blue Blue Blue Blue Blue Blue}{Yellow}{0}{0}
\chamrec{6}{2}{second}{Ice}{Water}{Steam}{0}{3cm}
\chamrec{6}{2}{third}{Crash}{\&}{Burn}{8cm}{1.5cm}
\draw[-latex,red,very thick] (first_t) -- node[right] {asdf} (second_b);
\draw[-latex,thick] (first_trm) -- node[below,sloped] {wasd} (third_blm);
\draw[latex-latex,ultra thick,blue] (third_tlm) -- node[below,sloped] {\#ACDC} (second_brm);
\end{tikzpicture}
\begin{tikzpicture}
\chamrec{6}{6}{show}{First}{Second}{Third}{0}{0}
\foreach \x in {l,tlm,tl,t,tr,trm,r,brm,br,b,bl,blm,sls}
{ \node[circle,draw,fill=white] at (show_\x) {\tiny\x};
}
\end{tikzpicture}
\end{document}