我喜欢用思维导图库在 tikz 中制作思维导图。问题是节点定位是手动的(而且我非常懒惰),因此一般问题是:
‘是否可以构建具有自动节点定位功能的思维导图?‘
我做了研究,发现 tikz 带有自动图形构建算法。特别是,似乎 spring 算法最适合构建思维导图,但是,我遇到了两个问题:
- 设置同层节点边缘间最小距离的设置
sibling pre sep
似乎不适用于弹簧算法。结果是一些节点重叠:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{mindmap,trees, graphs, graphdrawing}
\usegdlibrary{force}
\usepackage{chemformula}
\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}[
spring layout,
node distance= 6cm,
sibling pre sep = 1cm, %% some sibling nodes overlap anyway
font = \small,
every node/.style = {circle, draw, align =center, text width = 1.5cm},
]
\node{Portland cement paste}
child { node {Solids in the cement paste}
child{node {C-S-H}}
child{node{\ch{Ca(OH)2}}}
child{node {$ \mathrm{C_6A\bar{S}_3H_{32}} $ and $ \mathrm{C_6A\bar{S}H_{18}} $}}
child{node{Unhydrated p. cement grains}}
}
child { node {Voids in the cement paste}
child{ node {Interlayer space in C-S-H}}
child{ node {Capillary voids}}
child{ node{Air voids}}
}
child { node {Water in the cement paste}
child{ node {Capillary water}}
child{ node {Physically absorbed water}}
child{ node {Interlayer water}}
child{ node {Chemically combined water}}
};
\end{tikzpicture}
\end{figure}
\end{document}
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{mindmap,trees, graphs, graphdrawing}
\usegdlibrary{force}
\usepackage{chemformula}
\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}[
mindmap,
spring layout,
node distance= 6cm,
sibling pre sep = 1cm, %% some sibling nodes overlap anyway
font = \small,
every node/.style = {concept, execute at begin node=\hskip0pt},
concept color=gray!20,
]
\node{Portland cement paste}
child { node {Solids in the cement paste}
child{node {C-S-H}}
child{node{\ch{Ca(OH)2}}}
child{node {$ \mathrm{C_6A\bar{S}_3H_{32}} $ and $ \mathrm{C_6A\bar{S}H_{18}} $}}
child{node{Unhydrated p. cement grains}}
}
child { node {Voids in the cement paste}
child{ node {Interlayer space in C-S-H}}
child{ node {Capillary voids}}
child{ node{Air voids}}
}
child { node {Water in the cement paste}
child{ node {Capillary water}}
child{ node {Physically absorbed water}}
child{ node {Interlayer water}}
child{ node {Chemically combined water}}
};
\end{tikzpicture}
\end{figure}
\end{document}
最后,如果您知道这两个问题(节点重叠和思维导图样式不起作用)的解决方案,或者您知道绘制思维导图的更好方法(使用自动节点定位),请告诉我。谢谢!
答案1
算法graphdrawing
提供了实现此目的的各种可能性。这里spring electrical layout
使用。适用于其他算法的对齐命令graphdrawing
在这里不起作用,因此要将其中一个子节点(我选择Solids in the cement paste
)与中心节点(Portland cement paste
)垂直对齐,必须使用将这些节点固定在画布上nail at
。通常,electric charge
(此处=10)操纵节点与其子节点之间的距离Portland cement paste
。可以使用来操纵图形叶子之间的分离,从而避免 OP 的重叠问题electric force order
。可以以通常的方式在选项中设置节点和边缘样式,tikzpicture
从而提供很大的灵活性。
\documentclass[tikz,border=3pt,12pt]{standalone}
\usetikzlibrary{graphs, graphdrawing, shapes.geometric}
\usegdlibrary{force}
\usepackage{chemformula}
\usepackage{helvet}
\usepackage[T1]{fontenc}
\renewcommand*\familydefault{\sfdefault}
\begin{document}
\begin{tikzpicture}
\graph[
random seed=10,
spring electrical layout,
node distance=3cm,
cooling factor=0.9,
electric charge=10, % separation of the parent nodes
electric force order=1.5, % separation of the child nodes
coarsen=4,
iterations=100,
edges={>=Stealth,line width=2.5pt, color=gray},
nodes={draw, circle, very thick,font=\sffamily\large,text=black,
minimum size=3cm, inner sep=1pt, align=center, text depth=0.25ex}
]
{
"Solids in\\the cement\\paste"[nail at={(0,0)}] <- {"C-S-H",
"\ch{Ca(OH)2}",
"$ \mathsf{C_6A\bar{S}_3H_{32}} $\\and\\$ \mathsf{C_6A\bar{S}H_{18}} $",
"Unhydrated\\p. cement\\grains"
};
"Voids in\\the cement\\paste" <- {"Interlayer\\space\\in C-S-H",
"Capillary\\voids",
"Air voids"
};
"Water in\\the cement\\paste" <- {"Capillary\\water",
"Physically\\absorbed\\water",
"Interlayer\\water",
"Chemically\\combined\\water"
};
"Portland\\cement\\paste"[nail at={(0,-6)}] <- {"Solids in\\the cement\\paste",
"Water in\\the cement\\paste",
"Voids in\\the cement\\paste"
};
};
\end{tikzpicture}
\end{document}
答案2
这里我只想为 Ross 的回答提供更多细节。下面的代码有更多注释,我确保节点内的换行是自动的。此外,我注意到即使没有引脚,最终结果也相当不错。
我认为到目前为止唯一的问题是思维导图样式似乎不适用于自动图形算法。
\documentclass[tikz,border=3pt,12pt]{standalone}
\usetikzlibrary{graphs, graphdrawing, shapes.geometric}
\usegdlibrary{force}
\usepackage{chemformula}
\usepackage{helvet}
\usepackage[T1]{fontenc}
\renewcommand*\familydefault{\sfdefault}
\begin{document}
\begin{tikzpicture}
\graph[
random seed = 10, % random start configuration
spring electrical layout, % documentation page sec 32, pag474 pdf of PGF TIKZ manual
node distance = 7cm, % length at which there is no attraction/repulsion
convergence tolerance = 0.001, % default 0.01. minimum movement of node in a step (while(movement > tol ... end)
cooling factor=0.95, % default 0.95.
electric charge = 3, % default 1. strength of repulsion/attracion
electric force order = 3, % default 1. reduce (greater than 1)/increase (0 to 1) long distance forces
coarsen=true, % default true. read documentation
iterations=1000, % default 500. maximum number of iterations (while i < iterations ... end)
edges={>=Stealth,line width=2.5pt, color=gray},
nodes={draw, circle, very thick, font=\sffamily\large,text=black,
minimum size=2cm, align=center, text width= 3cm, inner sep = 1pt}
% text width = 3cm for automatic line break inside the nodes
% minimum size = 2cm for minimum size of nodes
]
{
"Solids in the cement paste" <- {"C-S-H",
"\ch{Ca(OH)2}",
"$ \mathsf{C_6A\bar{S}_3H_{32}} $ and $ \mathsf{C_6A\bar{S}H_{18}} $",
"Unhydrated p. cement grains"
};
"Voids in the cement paste" <- {"Interlayer space in C-S-H",
"Capillary voids",
"Air voids"
};
"Water in the cement paste" <- {"Capillary water",
"Physically absorbed water",
"Interlayer water",
"Chemically combined water"
};
"A" <- {"B",
"C",
"S",
"E"
};
"Portland cement paste" <- {"Solids in the cement paste",
"Water in the cement paste",
"Voids in the cement paste",
"A"
};
};
\end{tikzpicture}
\end{document}