我正在尝试在 Tikz 中构建一棵树(主题是论证理论,其中论点互相攻击和辩护),但是在树的几个级别之后,节点被放置在彼此的顶部,或者以到其父节点的弧相互交叉的方式放置。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows}
\tikzset{
every node/.style={minimum size=4mm, inner sep=0.5mm, font=\sffamily},
level 1/.style={every child/.style={edge from parent/.style={draw,red}}},
level 2/.style={every child/.style={edge from parent/.style={draw,green}}},
level 3/.style={every child/.style={edge from parent/.style={draw,red}}},
level 4/.style={every child/.style={edge from parent/.style={draw,green}}},
level 5/.style={every child/.style={edge from parent/.style={draw,red}}},
level 6/.style={every child/.style={edge from parent/.style={draw,green}}},
def/.style={circle,thick,solid,draw=green!50,fill=green!20},
att/.style={circle,thick,solid,draw=red!50,fill=red!20}
}
\begin{document}
\begin{tikzpicture}[<-,>=stealth', semithick]
\node[def, label=east:defense] {}
child[level distance=11mm] { node[att, label=east:attack] {}
child {node[def, label=east:defense] {}
child { node[att, label=east:attack] {} }
child { node[att, label=east:attack] {} }
}
child {node[def, label=east:defense] {}
child {node[att, label=east:attack] {}}
child {node[att, label=east:attack] {}}
}
child {node[def, label=east:defense] {}
child {node[att, label=east:attack] {} }
child {node[att, label=east:attack] {} }
child {node[att, label=east:attack] {} }
}
};
\end{tikzpicture}
\end{document}
结果如下:
可以看到,在最底层,中间两个节点的弧不可避免地会交叉。此外,最底层第一个节点之后的两个节点是相互叠放的。
是否有一个“随意调整节点之间的距离,以便它们之间的弧线不交叉,节点不会出现在彼此之上”的命令可供我使用?非常感谢您的帮助,我希望这不是一个重复的问题,因为我找不到类似的问题!
答案1
这是展示forest
包;标签和着色是根据级别的条件测试自动完成的:
\documentclass{article}
\usepackage{forest}
\begin{document}
\begin{forest}
for tree={
edge={<-,>=latex},
l sep=1cm,
circle,
minimum size=12pt,
anchor=west,
where={iseven(level)}
{edge={green},
draw=green!50,
fill=green!20,
edge label={node[anchor=west,right,font=\sffamily,xshift=7pt,yshift=1pt]{\color{black}defense}}
}
{edge={red},
draw=red!50,
fill=red!20,
edge label={node[anchor=west,font=\sffamily,xshift=7pt,yshift=1pt]{\color{black}attack}}
},
if={level>1}
{s sep=1.3cm}
{}
}
[,tikz={\node[pos=0,font=\sffamily,anchor=west,xshift=12pt,yshift=1pt]{defense};}
[,s sep=1.85cm
[ [] [] ]
[ [] [] ]
[ [] [] [] ]
]
]
\end{forest}
\end{document}
由于标记和着色是根据节点级别的条件测试自动完成的,因此相同的序言for tree
规范适用于
[,tikz={\node[pos=0,font=\sffamily,anchor=west,xshift=12pt,yshift=1pt]{defense};}
[,s sep=1.85cm
[ [ [] [] ] [] ]
[ [ [] [] ] [] ]
[ [ [] [] ] [] [ [] [] ] ]
]
]
将生产
答案2
您可以为每个级别设置不同的兄弟距离
\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{arrows}
\tikzset{
every node/.style={minimum size=4mm, inner sep=0.5mm, font=\sffamily},
level 1/.style={every child/.style={edge from parent/.style={draw,red}}},
level 2/.style={every child/.style={edge from parent/.style={draw,green}},
sibling distance=12em},
level 3/.style={every child/.style={edge from parent/.style={draw,red}},
sibling distance=5em},
def/.style={circle,thick,draw=green!50,fill=green!20,label={right:defense}},
att/.style={circle,thick,draw=red!50,fill=red!20,label={#1:attack}},
att/.default=right
}
\begin{document}
\begin{tikzpicture}[<-,>=stealth']
\node[def] {}
child[level distance=11mm] { node[att={[yshift=1mm]right}] {}
child {node[def] {}
child { node[att] {} }
child { node[att] {} }
}
child {node[def] {}
child {node[att] {}}
child {node[att] {}}
}
child {node[def] {}
child {node[att] {} }
child {node[att] {} }
child {node[att] {} }
}
};
\end{tikzpicture}
\end{document}
或者使用graphdrawing
库(需要 pgf/tikz 版本 3.0.0 和 LuaLaTeX):
\documentclass[margin=5mm,tikz]{standalone}
\usetikzlibrary{graphs,graphdrawing}
\usegdlibrary{trees}
\usetikzlibrary{arrows}
\tikzset{
every node/.style={minimum size=4mm, inner sep=0.5mm},
def/.style={circle,thick,solid,draw=green!50,fill=green!20,label={right:defense}},
att/.style={circle,thick,solid,draw=red!50,fill=red!20,label={#1:attack}},
att/.default=right
}
\begin{document}
\begin{tikzpicture}[>=stealth',font=\sffamily]
\graph[tree layout,empty nodes]{
{[trie]a[def]<-[red]a[att={[yshift=1mm]right}]<-[green]{[nodes=def]a,b,c},},
{[nodes=att,edges=red,trie,sibling distance=\widthof{attack\qquad}]
a a a<-{a,b},
a a b<-{a,b},
a a c<-{a,b,c},
}
};
\end{tikzpicture}
\end{document}
答案3
添加sibling distance
会使事情稍微扩散一些。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}
\tikzset{
every node/.style={minimum size=4mm, inner sep=0.5mm, font=\sffamily},
level 1/.style={every child/.style={edge from parent/.style={draw,red}}},
level 2/.style={every child/.style={edge from parent/.style={draw,green}}},
level 3/.style={every child/.style={edge from parent/.style={draw,red}}},
level 4/.style={every child/.style={edge from parent/.style={draw,green}}},
level 5/.style={every child/.style={edge from parent/.style={draw,red}}},
level 6/.style={every child/.style={edge from parent/.style={draw,green}}},
def/.style={circle,thick,solid,draw=green!50,fill=green!20},
att/.style={circle,thick,solid,draw=red!50,fill=red!20}
}
\begin{document}
\begin{tikzpicture}[<-,>=stealth', semithick,sibling distance=10em]
\node[def, label=east:defense] {}
child[level distance=11mm] { node[att, label=east:attack] {}
child {node[def, label=east:defense] {}
child { node[att, label=east:attack] {} }
child { node[att, label=east:attack] {} }
}
child {node[def, label=east:defense] {}
child {node[att, label=east:attack] {}}
child {node[att, label=east:attack] {}}
}
child {node[def, label=east:defense] {}
child {node[att, label=east:attack] {} }
child {node[att, label=east:attack] {} }
child {node[att, label=east:attack] {} }
}
};
\end{tikzpicture}
\end{document}