我正在尝试绘制 C 数据结构的协作图。最初,我从 Doxygen 获得了 dot 文件,并尝试使用 dot2tex 进行转换,取得了不同程度的成功,但没有一个产生像样的输出(即没有对齐,没有典型的“正确”外观,制作精良的 TikZ 图)。这种图类似于依赖图,只是它包含指向链接结构的每个数据结构链接的引用(换句话说,指针/引用字段与其引用的结构之间有一条边/路径连接)。
我想知道是否tikz-qtree
可以用于此目的,因为我想优化空间使用,而 dot/graphvix/dot2tex(并手动调整输出)不是最优的
协作图示例:
原始点语法:
digraph G
{
edge [fontname="Helvetica",fontsize="10",labelfontname="Helvetica",labelfontsize="10"];
node [fontname="Helvetica",fontsize="10",shape=record];
Node1 [label="faultstate",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
Node2 -> Node1 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" entry" ,fontname="Helvetica"];
Node2 [label="vm_map_entry",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$structvm__map__entry.html"];
Node2 -> Node2 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" prev\nnext\nright\nleft" ,fontname="Helvetica"];
Node3 -> Node2 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" object" ,fontname="Helvetica"];
Node3 [label="vm_map_object",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$unionvm__map__object.html"];
Node4 -> Node3 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" sub_map" ,fontname="Helvetica"];
Node4 [label="vm_map",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$structvm__map.html"];
Node2 -> Node4 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" root\nheader" ,fontname="Helvetica"];
Node5 -> Node3 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" vm_object" ,fontname="Helvetica"];
Node5 [label="vm_object",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$structvm__object.html"];
Node5 -> Node5 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" backing_object" ,fontname="Helvetica"];
Node4 -> Node1 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" map" ,fontname="Helvetica"];
Node5 -> Node1 [dir="back",color="darkorchid3",fontsize="10",style="dashed",label=" first_object\nobject" ,fontname="Helvetica"];
}
转换后的 TeX 语法(通过 graphviz 的 dot 进行 dot 到 xdot 中间转换之后)来自 dot2tex(TikZ 模式):
\documentclass{article}
\usepackage[x11names, rgb]{xcolor}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{snakes,arrows,shapes}
\usepackage{amsmath}
\begin{document}
\pagestyle{empty}
\enlargethispage{100cm}
\begin{tikzpicture}[>=latex',line join=bevel,]
\node (Node1) at (28bp,10bp) [draw=black,fill=grey75,record] {faultstate};
\node (Node3) at (213bp,10bp) [draw=black,fill=white,record] {vm\_map\_object};
\node (Node2) at (65bp,178bp) [draw=black,fill=white,record] {vm\_map\_entry};
\node (Node5) at (140bp,88bp) [draw=black,fill=white,record] {vm\_object};
\node (Node4) at (65bp,88bp) [draw=black,fill=white,record] {vm\_map};
\draw [darkorchid3,<-,dashed] (Node3) ..controls (247.46bp,28.666bp) and (252.35bp,32.972bp) .. (256bp,38bp) .. controls (258.83bp,41.907bp) and (274.89bp,84.957bp) .. (266bp,98bp) .. controls (230bp,150.83bp) and (152.79bp,168.33bp) .. (Node2);
\definecolor{strokecol}{rgb}{0.0,0.0,0.0};
\pgfsetstrokecolor{strokecol}
\draw (284bp,88bp) node { object};
\draw [darkorchid3,<-,dashed] (Node2) ..controls (120bp,183.99bp) and (123bp,181.48bp) .. (123bp,178bp) .. controls (123bp,172.43bp) and (115.33bp,169.35bp) .. (Node2);
\draw (134bp,190bp) node { prev};
\draw (134bp,179bp) node {next};
\draw (134bp,168bp) node {right};
\draw (134bp,157bp) node {left};
\draw [darkorchid3,<-,dashed] (Node2) ..controls (32.825bp,146.58bp) and (12.591bp,123.18bp) .. (4bp,98bp) .. controls (-5.6625bp,69.676bp) and (12.453bp,35.188bp) .. (Node1);
\draw (16.5bp,88bp) node { entry};
\draw [darkorchid3,<-,dashed] (Node5) ..controls (185.12bp,92.844bp) and (188bp,90.849bp) .. (188bp,88bp) .. controls (188bp,83.324bp) and (180.25bp,80.95bp) .. (Node5);
\draw (222.5bp,88bp) node { backing\_object};
\draw [darkorchid3,<-,dashed] (Node4) ..controls (35.128bp,68.878bp) and (31.433bp,64.745bp) .. (29bp,60bp) .. controls (22.399bp,47.129bp) and (24.124bp,29.744bp) .. (Node1);
\draw (40bp,49bp) node { map};
\draw [darkorchid3,<-,dashed] (Node5) ..controls (179.37bp,70.063bp) and (185.87bp,65.478bp) .. (191bp,60bp) .. controls (201.97bp,48.297bp) and (208.13bp,30.2bp) .. (Node3);
\draw (228.5bp,49bp) node { vm\_object};
\draw [darkorchid3,<-,dashed] (Node5) ..controls (131.95bp,58.339bp) and (126.18bp,45.94bp) .. (117bp,38bp) .. controls (100.03bp,23.315bp) and (75.247bp,16.617bp) .. (Node1);
\draw (158bp,50bp) node { first\_object};
\draw (158bp,39bp) node {object};
\draw [darkorchid3,<-,dashed] (Node4) ..controls (61.38bp,57.989bp) and (62.694bp,45.955bp) .. (70bp,38bp) .. controls (83.331bp,23.486bp) and (133.52bp,16.635bp) .. (Node3);
\draw (91.5bp,49bp) node { sub\_map};
\draw [darkorchid3,<-,dashed] (Node2) ..controls (65bp,139.31bp) and (65bp,111.67bp) .. (Node4);
\draw (80bp,128bp) node { root};
\draw (80bp,117bp) node {header};
\end{tikzpicture}
\end{document}
获得的输出:
注意:这是没有的--tikzedgelabels
。使用该选项会产生损坏的图表。dot2tex 只喜欢直边,因此连接节点的弯曲曲线/边不会起作用。
所需输出:
不要丑陋的
\draw -(coordinate)
结构。我想要 TikZ 风格的边缘标签,不要固定的绘图点。我希望布局流畅,并在画布中实现图表节点的最佳分布。--tikzedgelabels
不行。仅供参考,我可以在评论中看到它。
答案1
仅基于 percusse 的优秀解决方案的答案,但对样式进行了一些修改。我尝试获取更轻量的代码。我添加了一个scope
用于标签的选项。我删除了它,pos=.5
因为它是默认值。我删除了样式myline
,并将选项放在了范围内。我利用了从同一顶点用一条路径绘制多条边的可能性。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[ %some style declarations
mynode/.style = {draw,inner sep=2mm},
scale=1.5]
% Placing the nodes: you have to place them, no way to know beforehand
\node[fill=red,
mynode] (n0) at (0,0) {faultstate};
\node[mynode] (n1) at (1,2) {vm\_map};
\node[mynode] (n2) at (1,5) {vm\_map\_entry};
\node[mynode] (n3) at (3.5,2) {vm\_object};
\node[mynode] (n4) at (5,0) {vm\_map\_object};
%Now the edges and labels
\begin{scope}[> = stealth, ->,blue,thick,
every node/.style = {black,right,align=center}]
\draw (n1) edge node {root\\header} (n2);
\draw (n0) edge [bend left] node {entry} (n2)
edge [bend left] node {map} (n1)
edge [bend right] node [pos=0.8,
below right] {first\_object \\object} (n3);
\draw (n4) edge [bend left] node [pos=0.8] {sub\_map} (n1)
edge [bend right] node {vm\_object} (n3);
\draw (n3) edge [loop right] node {backing\_object} (n3);
\draw (n2) edge [loop right,
min distance =1 cm,
out=10,
in=-10] node {prev\\next\\right\\left} (n2)
edge [looseness=1.8,
out=30,
in=20] node [below left] {object} (n4) ;
\end{scope}
\end{tikzpicture}
\end{document}
答案2
这里有很多不同的选项。然后,您可以选择一些更专门针对树和图的库,但我建议在尝试之前先熟悉 TikZ 语言。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[>=stealth,%some style declarations
myline/.style={->,blue,thick,dashed},
mynode/.style={draw,inner sep=2mm},scale=1.5]
% Placing the nodes: you have to place them, no way to know beforehand
\node[mynode,fill=red] (n0) at (0,0) {faultstate};
\node[mynode] (n1) at (1,2) {vm\_map};
\node[mynode] (n2) at (1,5) {vm\_map\_entry};
\node[mynode] (n3) at (3.5,2) {vm\_object};
\node[mynode] (n4) at (5,0) {vm\_map\_object};
%Now the edges and labels
\draw[myline] (n0) edge[bend left] node[pos=0.5,black,right] {entry} (n2) ;
\draw[myline] (n0) edge[bend left] node[pos=0.5,black,right] {map} (n1);
\draw[myline] (n0) edge[bend right] node[pos=0.8,black,below right,align=center] {first\_object \\object} (n3);
\draw[myline] (n4) edge[bend left] node[pos=0.8,black,right] {sub\_map}(n1);
\draw[myline] (n4) edge[bend right] node[pos=0.5,black,right] {vm\_object} (n3) ;
\draw[myline] (n3) edge[loop right] node[pos=0.5,black,right] {backing\_object} () ;
\draw[myline] (n1) edge node[pos=0.5,black,right,align=center] {root\\header} (n2);
\draw[myline] (n2) edge[loop right,min distance =1 cm,out=10,in=-10] node[pos=0.5,black,right,align=center] {prev\\next\\right\\left} (n2) ;
\draw[myline] (n2) edge[out=30,in=20,looseness=1.8] node[pos=0.5,black,right] {object} (n4) ;
\end{tikzpicture}
\end{document}
绘制完成后,我使用了 1.5 的缩放比例使其更开放一些,虽然这不是必需的,但在我看来看起来更好。
答案3
我的回答试图解释为什么@soze 得到那么奇怪的结果。
首先,当您在 dot 中定义颜色时,您必须使用与 xcolor 相同的语法,因此:
fillcolor="grey75" 错误 => fillcolor="gray!75"
color="darkorchid3" 又错了 => color="DarkOrchid3"
另一件事:record
形状给我每个节点的错误,而使用形状时rectangle
不会出现任何问题。
我调用graph.dot
@soze 文件进行了修改:
digraph G
{
edge [fontname="Helvetica",fontsize="10",labelfontname="Helvetica",labelfontsize="10"];
node [fontname="Helvetica",fontsize="10",shape=rectangle];
Node1 [label="faultstate",height=0.2,width=0.4,color="black", fillcolor="gray!75", style="filled" fontcolor="black"];
Node2 -> Node1 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" entry" ,fontname="Helvetica"];
Node2 [label="vm_map_entry",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$structvm__map__entry.html"];
Node2 -> Node2 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" prev\nnext\nright\nleft" ,fontname="Helvetica"];
Node3 -> Node2 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" object" ,fontname="Helvetica"];
Node3 [label="vm_map_object",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$unionvm__map__object.html"];
Node4 -> Node3 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" sub_map" ,fontname="Helvetica"];
Node4 [label="vm_map",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$structvm__map.html"];
Node2 -> Node4 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" root\nheader" ,fontname="Helvetica"];
Node5 -> Node3 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" vm_object" ,fontname="Helvetica"];
Node5 [label="vm_object",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$structvm__object.html"];
Node5 -> Node5 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" backing_object" ,fontname="Helvetica"];
Node4 -> Node1 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" map" ,fontname="Helvetica"];
Node5 -> Node1 [dir="back",color="DarkOrchid3",fontsize="10",style="dashed",label=" first_object\nobject" ,fontname="Helvetica"];
}
使用以下方法编译:
dot2tex -ftikz -tverbatim graph.dot > graph.tex
pdflatex graph.tex
我得到(没有错误):