我的目标是绘制一个复杂的系统架构。
以下是一些方法如何用Latex绘制分层架构?
这种方法https://tex.stackexchange.com/a/102669/44348看起来很有趣,因此可以在该示例中进行以下修改:
- 添加阴影选项
\usetikzlibrary{shadows}
- 添加从节点剪切阴影的方法,请参见此处删除一个节点的阴影
- 制作
nodes in empty cells=false
- 添加
|[no shadows]|
到要合并的单元格只是为了创建该单元格的形状、锚点和名称,并防止错误等
我遇到了一些问题:
添加图片,如数据库使用 TikZ 显示数据库实例关系, 例如
在单元格
(stack-5-6) (stack-6-6)
中用名称来表示将来要制作的箭头。例如,创建具有边框和阴影的任意节点块
- 单元格附近没有边框和阴影
(stack-3-4)
, - 我们无法设置矩阵主体的颜色,因为它将覆盖有背景的块。
这里描述了一种添加图片的方法节点和节点矩阵但我不能很好地接受它。
这里描述了一种创建块作为背景层的方法http://www.texample.net/tikz/examples/kalman-filter/
fit
但我无法获得正确的边框和阴影。使用选项来background
获得良好的解决方案存在问题。- 单元格附近没有边框和阴影
MWE 是
\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds,shadows,positioning,fit,matrix,shapes.geometric} % add shadows #1
% a way to cut shadows in a cell #2
%https://tex.stackexchange.com/questions/129318/remove-drop-shadow-from-one-node
\makeatletter
\tikzset{no shadows/.code=\let\tikz@preactions\pgfutil@empty}
\makeatother
\tikzstyle{background}=[rectangle,
fill=red!10,
inner sep=0.2cm]
%rounded corners=5mm] % it would be great to use rounded corners...
\tikzstyle{backgroundN}=[rectangle, % to cut the background's node
fill=white,
inner sep=0.3cm]
%rounded corners=5mm] % it would be great to use rounded corners...
\tikzstyle{backgroundNN}=[rectangle, % to create the background's node
fill=red!10,
inner sep=0.2cm]
%rounded corners=5mm] % it would be great to use rounded corners...
\definecolor{mybluei}{RGB}{124,156,205}
\definecolor{myblueii}{RGB}{73,121,193}
\definecolor{mygreen}{RGB}{202,217,126}
\definecolor{mypink}{RGB}{233,198,235}
\newcommand\widernode[5][widebox]{
\node[
#1,
fit={(#2) (#3)},
label=center:{\sffamily\bfseries\color{black}#4}] (#5) {};
}
\begin{document}
\begin{tikzpicture}[node distance=2pt,outer sep=0pt, % just do nothing after modification
boxstyle/.style={
draw=white,
fill=#1,
rounded corners, drop shadow, %to get a shadow in below a node
font={\sffamily\bfseries\color{white}},
align=center,
minimum height=30pt
},
box/.style={
boxstyle=#1,
text width=2.5cm},
box/.default=mybluei,
title/.style={font={\sffamily\bfseries\color{black}}},
widebox/.style={draw=white,inner sep=0pt, rounded corners,fill=#1,drop shadow},
widebox/.default=mybluei,
mylabel/.style={font={\sffamily\bfseries\color{black}}},
]
\matrix (stack) [draw=black,% boxstyle=mybluei!40,%will overpaint blocks with background
column sep=10pt, row sep=10pt, inner sep=4mm,%
matrix of nodes,
nodes={box, outer sep=0pt, anchor=center, inner sep=3pt},%
nodes in empty cells=false,% #3
row 1/.style={nodes={fill=none,draw=none,minimum height=3mm}},
]
{
|[no shadows]|& & & &|[no shadows]|&|[no shadows]| \\ % #5
RCP main & Authoring & Browsing & Publishing & Search&|[no shadows]|\\
Rich Text &|[no shadows]| &|[no shadows]| &{XML\\ Export/Import} & MSP Export&|[no shadows]|\\
Common & |[no shadows]|&|[no shadows]| & |[no shadows]|&|[no shadows]| &\node[rotate=10] {Hello};\\
|[box=mypink]| Jtidy & |[no shadows]|&|[no shadows]| &|[box=mygreen]| GEF &|box=mygreen]| ICU4J & \\
|[no shadows]|& && &|[no shadows]|&\\};
\widernode[]{stack-1-1}{stack-1-5}{EPF Composer}{EPF} %#5
\widernode{stack-3-2}{stack-3-3}{Library Management}{LMg}
\widernode{stack-4-2}{stack-4-3}{UMA}{UMA}
\widernode{stack-4-4}{stack-4-5}{Export/Import}{ExImp}
\widernode[widebox=mygreen]{stack-5-2}{stack-5-3}{EMF}{EMF}
\widernode[widebox=mygreen]{stack-6-1}{stack-6-5}{RCP Runtime}{RCPrun}
\widernode{stack-2-6}{stack-3-6}{\begin{tikzpicture}
\node[align=center] (a) {Normal text\\works};
\end{tikzpicture}}{NTWorks}
\node [fit={(stack.south west)(stack.south east)},boxstyle=myblueii,draw=black,inner sep=0pt,below=3pt of stack.south,anchor=north,label={[mylabel]center:Java Runtime}] (JavaR) {};
% smth to create an arbitrary block with a border and shadow
\begin{pgfonlayer}{background}
\node [background,
fit=(stack-2-1) (stack-4-1)(stack-4-5),draw, drop shadow,
] {};
\node [backgroundN,
fit=(stack-3-5) ] {};
\node [backgroundNN,draw, drop shadow,
fit=(stack-3-5) ] {};
\end{pgfonlayer}
\end{tikzpicture}
\end{document}
输出原样:
输出结果:
答案1
这是你想要的吗?
问题 1:添加图片,如数据库使用 TikZ 显示数据库实例关系,例如在(stack-5-6) (stack-6-6)
名称为“将来制作箭头”的单元格中。
由于您声明了选项,因此单元格(stack-5-6) (stack-6-6)
不存在nodes in empty cells=false
,并且空单元格中没有创建节点。但您可以使用其他一些节点作为参考来放置数据库符号。作为示例,我使用了(NTWorks|-RCPrun.south)
:
\node[database, minimum width=2cm, minimum height=2cm, anchor=south] (DB3) at (NTWorks|-RCPrun.south) {DB3};
问题2:创建具有边框和阴影的任意节点块,
你几乎已经做到了:
\begin{pgfonlayer}{background}
\node [background,
fit=(stack-2-1) (stack-4-1)(stack-4-5),draw, drop shadow,
] {};
\node [backgroundN,
fit=(stack-3-5) ] {};
\node [backgroundNN,draw, drop shadow,
fit=(stack-3-5) ] {};
\end{pgfonlayer}
问题是\node [backgroundN, fit=(stack-3-5) ] {};
。此行引入了错误的白色边框。将其注释掉。
其他几点:
- 我已改为
tikzstyle
。tikzset
请阅读应该使用 \tikzset 还是 \tikzstyle 来定义 TikZ 样式? - 在节点中,
NTWorks
您使用了tikzpicture
a 内的 atikzpicture
,这是不推荐的。我采用了语法来\widernode
绘制它。 &[3mm]
第一行中第 5 列和第 6 列之间的距离已放大。这增加3mm
了column sep
。我已放大以更好地绘制fitting
节点。- 粉色拟合框的右边框已按坐标向右移动
aux
。这样MSP Export
边框就不会覆盖背景边框。 - 数据库符号取自 Thorsten Donig 对使用 TikZ 显示数据库实例关系
完整代码如下:
\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds,shadows,positioning,fit,matrix,shapes.geometric, shapes.arrows} % add shadows #1
% a way to cut shadows in a cell #2
%https://tex.stackexchange.com/questions/129318/remove-drop-shadow-from-one-node
\makeatletter
\tikzset{no shadows/.code=\let\tikz@preactions\pgfutil@empty}
\makeatother
\tikzset{background/.style={rectangle, fill=red!10, inner sep=0.2cm},
backgroundN/.style={rectangle, fill=white, inner sep=0.3cm},
backgroundNN/.style={rectangle, fill=red!10, inner sep=0.2cm}}
\definecolor{mybluei}{RGB}{124,156,205}
\definecolor{myblueii}{RGB}{73,121,193}
\definecolor{mygreen}{RGB}{202,217,126}
\definecolor{mypink}{RGB}{233,198,235}
\newcommand\widernode[5][widebox]{
\node[
#1,
fit={(#2) (#3)},
label=center:{\sffamily\bfseries\color{black}#4}] (#5) {};
}
\begin{document}
\begin{tikzpicture}[node distance=2pt,outer sep=0pt, % just do nothing after modification
boxstyle/.style={
draw=white,
fill=#1,
rounded corners, drop shadow, %to get a shadow in below a node
font={\sffamily\bfseries\color{white}},
align=center,
minimum height=30pt
},
box/.style={
boxstyle=#1,
text width=2.5cm},
box/.default=mybluei,
title/.style={font={\sffamily\bfseries\color{black}}},
widebox/.style={draw=white,inner sep=0pt, rounded corners,fill=#1,drop shadow},
widebox/.default=mybluei,
mylabel/.style={font={\sffamily\bfseries\color{black}}},
database/.style={
cylinder,
cylinder uses custom fill,
cylinder body fill=yellow!50,
cylinder end fill=yellow!50,
shape border rotate=90,
aspect=0.25,
draw
}
]
\matrix (stack) [draw=black,% boxstyle=mybluei!40,%will overpaint blocks with background
column sep=10pt, row sep=10pt, inner sep=4mm,%
matrix of nodes,
nodes={box, outer sep=0pt, anchor=center, inner sep=3pt},%
nodes in empty cells=false,% #3
row 1/.style={nodes={fill=none,draw=none,minimum height=3mm}},
]
{
|[no shadows]| & & & & |[no shadows]| &[3mm] |[no shadows]| \\ % #5
RCP main & Authoring & Browsing & Publishing & Search&|[no shadows]| \\
Rich Text &|[no shadows]| &|[no shadows]| &{XML\\ Export/Import} & MSP Export&|[no shadows]| \\
Common & |[no shadows]| &|[no shadows]| & |[no shadows]| &|[no shadows]| &\node[rotate=10] {Hello};\\
|[box=mypink]| Jtidy & |[no shadows]| & |[no shadows]| &|[box=mygreen]| GEF & |[box=mygreen]| ICU4J & \\
|[no shadows]| & & & & |[no shadows]| &\\};
\widernode[]{stack-1-1}{stack-1-5}{EPF Composer}{EPF} %#5
\widernode{stack-3-2}{stack-3-3}{Library Management}{LMg}
\widernode{stack-4-2}{stack-4-3}{UMA}{UMA}
\widernode{stack-4-4}{stack-4-5}{Export/Import}{ExImp}
\widernode[widebox=mygreen]{stack-5-2}{stack-5-3}{EMF}{EMF}
\widernode[widebox=mygreen]{stack-6-1}{stack-6-5}{RCP Runtime}{RCPrun}
\node[widebox,
fit={(stack-2-6) (stack-3-6)},
label={[text width=2.5cm, align=center]center:{\sffamily\bfseries\color{black}Normal text works}}] (NTWorks) {};
% \widernode[widebox, text width=1.5cm, align=center]{stack-2-6}{stack-3-6}{Normal text works}{NTWorks}
%
\node [fit={(stack.south west)(stack.south east)},boxstyle=myblueii,draw=black,inner sep=0pt,below=3pt of stack.south,anchor=north,label={[mylabel]center:Java Runtime}] (JavaR) {};
%
%
% % smth to create an arbitrary block with a border and shadow
\begin{pgfonlayer}{background}
\coordinate (aux) at ([xshift=2mm]stack-4-5.east);
\node [background,
fit=(stack-2-1) (stack-4-1) (aux), draw, drop shadow,
] {};
% \node [backgroundN,
% fit=(stack-3-5) ] {};
\node [backgroundNN,draw, drop shadow,
fit=(stack-3-5) ] {};
\end{pgfonlayer}
\node[database, minimum width=2cm, minimum height=2cm, anchor=south] (DB3) at (NTWorks|-RCPrun.south) {DB3};
\node[single arrow, draw, shape border rotate=90, anchor=south, fill=mybluei] at ([yshift=1mm]DB3.north) {\phantom{bpf}};
\node[fit=(NTWorks) (DB3), draw, thick] {};
\end{tikzpicture}
\end{document}
更新:打洞
我从你的评论中了解到,你的意图是holes
在你的方案中表示某些块不属于某个集合。从我的角度来看,绘制任意孔并尊重阴影是困难的。我可以设法为矩形孔绘制内部阴影,我希望类似的东西可以应用于任意孔,但我认为这应该是另一个问题。
我所做的就是应用Paul Gaborit 的shadowed
风格适应默认阴影样式(pgfmanual.pdf 中第 66.3.1 节“阴影”的第一行)。
shadowed/.style={postaction={draw=black!50, opacity=.5, line width=.5ex}}
并使用此样式为某个矩形节点绘制内部阴影:
\begin{pgfonlayer}{background}
\coordinate (aux) at ([xshift=2mm]stack-4-5.east);
\node [background, fit=(stack-2-1) (stack-4-1) (aux),
draw, drop shadow] {};
%draw a white `background` around node
\node [fill=white, fit=(stack-3-5)] (hole) {};
%draw an internal shadow
\begin{scope}
\clip (hole.south west) rectangle (hole.north east);
\path[shadowed] (hole.south west) |- (hole.north east);
\end{scope}
\end{pgfonlayer}
结果如下:
** 第二次更新:非矩形背景
您不需要使用矩形背景,因为drop shadow
也可以应用于任何封闭路径。困难的部分是如何定义复杂的背景。下面的代码显示了一个示例。我仍然使用矩形(虽然没有绘制也没有填充)背景作为参考来合成复杂的封闭形状。刚刚更改的代码如下:
\begin{pgfonlayer}{background}
\node [
fit=(stack-2-1) (stack-4-5),
] (BigGroup) {};
\draw[green, fill=green!30, very thick, drop shadow] (BigGroup.north west) -| ([shift={(-2mm,-3mm)}]stack-3-5.south west) -| (BigGroup.south east) -| ([shift={(-2mm,3mm)}]ExImp.north west)-|([xshift=-2mm]UMA.west|-BigGroup.south)-|cycle;
\end{pgfonlayer}
结果是: