这里有一个数据库图的示例:
\documentclass{tufte-handout}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}
\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.5pt%
\advance\pgfutil@tempdima by.25\pgflinewidth%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\pgfpathmoveto{\pgfqpoint{0pt}{-6\pgfutil@tempdima}}%
\pgfpathlineto{\pgfqpoint{-6\pgfutil@tempdima}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{6\pgfutil@tempdima}}%
\pgfusepathqstroke%
}
\tikzset{
entity/.code={
\tikzset{
label=above:#1,
name=#1,
inner sep=0pt,
every entity/.try,
fill=white,
general shadow={
shadow xshift=0.0625in,
shadow yshift=-0.0625in,
opacity=0.5,
fill=black!50
}
}%
\def\entityname{#1}%
},
entity anchor/.style={matrix anchor=#1.center},
every entity/.style={
draw,
},
every property/.style={
inner xsep=0.25cm, inner ysep=0.125cm, anchor=west, text width=1.45in
},
zig zag to/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
},
zig zag to/.default=0.5,
one to many/.style={
-crow's foot, zig zag to
},
many to one/.style={
crow's foot-, zig zag to
},
many to many/.style={
crow's foot-crow's foot, zig zag to
}
}
\def\property#1{\node[name=\entityname-#1, every property/.try]{#1};}
\def\properties{\begingroup\catcode`\_=11\relax\processproperties}
\def\processproperties#1{\endgroup%
\def\propertycode{}%
\foreach \p in {#1}{%
\expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\propertycode%
\expandafter\expandafter\expandafter{\expandafter\propertycode\expandafter\property\expandafter{\p}\\}%
}%
\propertycode%
}
\begin{document}
\begin{tikzpicture}[every node/.style={font=\ttfamily}, node distance=1in]
\matrix [entity=Msp\string_Support\string_Period] {
\properties{
spe_refno,
spe_peo_refno,
spe_spcs_refno,
spe_start,
spe_expected_end,
(etc)
}
};
\matrix [entity=People,
right=3cm of Msp\string_Support\string_Period-spe_refno,
entity anchor=People-peo_refno] {
\properties{
peo_refno,
peo_surname,
peo_dob,
peo_hrv_ethnic,
(etc)
}
};
\matrix [entity=Sp\string_Contracted\string_Services,
below left =4.5cm and -1cm of Msp\string_Support\string_Period-spe_refno,
entity anchor=Sp\string_Contracted\string_Services-spcs_spcn_contract_id] {
\properties{
spcs_spcn_contract_id,
exp_org_name,
exp_hrv_exp_type,
(etc)
}
};
\matrix [entity=Msp\string_Referral,
below right =4cm and -1cm of People-peo_refno,
entity anchor=Msp\string_Referral-ref_peo_refno] {
\properties{
ref_peo_refno,
ref_exp_refno,
ref_spcs_refno,
ref_type,
ref_received_by,
ref_reject_date,
(etc)
}
};
\matrix [entity=Hou\string_Ref\string_Values,
right=4cm of People-peo_refno,
entity anchor=Hou\string_Ref\string_Values-hrv_code] {
\properties{
hrv_code,
hrv_hrd_domain,
hrv_name,
(etc)
}
};
\matrix [entity=Msp\string_External\string_Parties,
below right=4cm and 7.5cm of Msp\string_Referral-ref_exp_refno,
entity anchor=Msp\string_Referral-ref_exp_refno] {
\properties{
exp_refno,
exp_org_name,
exp_hrv_exp_type,
(etc)
}
};
\draw [many to one] (Msp\string_Support\string_Period-spe_refno) to (People-peo_refno);
\draw [many to one] (Msp\string_Support\string_Period-spe_spcs_refno) to (Sp\string_Contracted\string_Services-spcs_spcn_contract_id);
\draw [many to one] (People-peo_refno) to (Msp\string_Referral-ref_peo_refno);
\draw [many to one] (Msp\string_Referral-ref_spcs_refno) to (Sp\string_Contracted\string_Services-spcs_spcn_contract_id);
\draw [many to one] (Msp\string_Referral-ref_exp_refno) to (Msp_External_Parties-exp_refno);
\end{tikzpicture}
\end{document}
这给了我这个输出:
我希望锯齿形曲线表现得优雅,并避免与其他形状或其他锯齿形曲线重叠。
也就是说,左侧的锯齿形应该锚定在 Sp_Contracted_Services 表的左侧和 Msp_Support_Period 表的左侧。此外,中间的锯齿形应该锚定在 People 的右侧和 Msp_Referral 的右侧。
我怎样才能实现这个目标?
答案1
我认为将zigzag
和many to one
样式概括为自动避免交叉节点并不容易,甚至不可能。但是,手动调整边缘却很容易。
\documentclass{tufte-handout}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\usetikzlibrary{shadows}
\usetikzlibrary{calc}
\makeatletter
\pgfarrowsdeclare{crow's foot}{crow's foot}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}%
\pgfarrowsrightextend{+.5\pgflinewidth}%
}
{
\pgfutil@tempdima=0.5pt%
\advance\pgfutil@tempdima by.25\pgflinewidth%
\pgfsetdash{}{+0pt}%
\pgfsetmiterjoin%
\pgfpathmoveto{\pgfqpoint{0pt}{-6\pgfutil@tempdima}}%
\pgfpathlineto{\pgfqpoint{-6\pgfutil@tempdima}{0pt}}%
\pgfpathlineto{\pgfqpoint{0pt}{6\pgfutil@tempdima}}%
\pgfusepathqstroke%
}
\tikzset{
entity/.code={
\tikzset{
label=above:#1,
name=#1,
inner sep=0pt,
every entity/.try,
fill=white,
general shadow={
shadow xshift=0.0625in,
shadow yshift=-0.0625in,
opacity=0.5,
fill=black!50
}
}%
\def\entityname{#1}%
},
entity anchor/.style={matrix anchor=#1.center},
every entity/.style={
draw,
},
every property/.style={
inner xsep=0.25cm, inner ysep=0.125cm, anchor=west, text width=1.45in
},
zig zag to/.style={
to path={(\tikztostart) -| ($(\tikztostart)!#1!(\tikztotarget)$) |- (\tikztotarget)}
},
zig zag to/.default=0.5,
one to many/.style={
-crow's foot, zig zag to
},
many to one/.style={
crow's foot-, zig zag to
},
many to many/.style={
crow's foot-crow's foot, zig zag to
}
}
\def\property#1{\node[name=\entityname-#1, every property/.try]{#1};}
\def\properties{\begingroup\catcode`\_=11\relax\processproperties}
\def\processproperties#1{\endgroup%
\def\propertycode{}%
\foreach \p in {#1}{%
\expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\propertycode%
\expandafter\expandafter\expandafter{\expandafter\propertycode\expandafter\property\expandafter{\p}\\}%
}%
\propertycode%
}
\begin{document}
\begin{tikzpicture}[every node/.style={font=\ttfamily}, node distance=1in]
\matrix [entity=Msp\string_Support\string_Period] {
\properties{
spe_refno,
spe_peo_refno,
spe_spcs_refno,
spe_start,
spe_expected_end,
(etc)
}
};
\matrix [entity=People,
right=3cm of Msp\string_Support\string_Period-spe_refno,
entity anchor=People-peo_refno] {
\properties{
peo_refno,
peo_surname,
peo_dob,
peo_hrv_ethnic,
(etc)
}
};
\matrix [entity=Sp\string_Contracted\string_Services,
below left =4.5cm and -1cm of Msp\string_Support\string_Period-spe_refno,
entity anchor=Sp\string_Contracted\string_Services-spcs_spcn_contract_id] {
\properties{
spcs_spcn_contract_id,
exp_org_name,
exp_hrv_exp_type,
(etc)
}
};
\matrix [entity=Msp\string_Referral,
below right =4cm and -1cm of People-peo_refno,
entity anchor=Msp\string_Referral-ref_peo_refno] {
\properties{
ref_peo_refno,
ref_exp_refno,
ref_spcs_refno,
ref_type,
ref_received_by,
ref_reject_date,
(etc)
}
};
\matrix [entity=Hou\string_Ref\string_Values,
right=4cm of People-peo_refno,
entity anchor=Hou\string_Ref\string_Values-hrv_code] {
\properties{
hrv_code,
hrv_hrd_domain,
hrv_name,
(etc)
}
};
\matrix [entity=Msp\string_External\string_Parties,
below right=4cm and 7.5cm of Msp\string_Referral-ref_exp_refno,
entity anchor=Msp\string_Referral-ref_exp_refno] {
\properties{
exp_refno,
exp_org_name,
exp_hrv_exp_type,
(etc)
}
};
\draw [many to one] (Msp\string_Support\string_Period-spe_refno) to (People-peo_refno);
\draw [crow's foot-] (Msp\string_Support\string_Period-spe_spcs_refno.west)
-- ++(-1.5cm,0) |-
(Sp\string_Contracted\string_Services-spcs_spcn_contract_id.west);
\draw [crow's foot-] (People-peo_refno.east) -- ++(0.5cm,0)
-- ++(0,-3.2cm) --++(-4cm,0)
|- (Msp\string_Referral-ref_peo_refno);
\draw [many to one] (Msp\string_Referral-ref_spcs_refno) to (Sp\string_Contracted\string_Services-spcs_spcn_contract_id);
\draw [many to one] (Msp\string_Referral-ref_exp_refno) to (Msp_External_Parties-exp_refno);
\end{tikzpicture}
\end{document}