Aqui está a imagem que meu código existente produz: Espero que o FFFFF do losango possa estar diretamente acima de C e diretamente à direita de E. Como devo fazer isso? Abaixo está meu caso mínimo de trabalho:
\documentclass[tikz,border=2pt]{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes,snakes}
\usepackage{siunitx} %SI单位
%\usepackage{xparse}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node[rectangle,draw, very thick, minimum size=10mm] (A) {
A};
\node[rectangle,draw, very thick, minimum size=10mm] (B) [below=of A]{B};
\node[rectangle,draw=red, very thick, minimum size=10mm] (C) [right=of B]{C};
\node[rectangle,draw, very thick, minimum size=10mm] (D) [right=of C]{D};
\node[rectangle,draw, very thick, minimum size=10mm] (E) [above=of D] {E};
\node[diamond,draw, very thick, minimum size=10mm] (F) [above=of C] {FFFFFfF};
%Lines
\draw[->] (A) -> (B);
\draw[->] (B) -> (C);
\draw[->] (C) -> (D);
\draw[->] (D) -> (E);
\draw[->] (E) -> (F);
\draw[->] (F) -> (C);
\end{tikzpicture}
\end{document}
E o que finalmente espero conseguir é isto, ou seja, preciso adicionar uma moldura pontilhada bem grande. Como isso deve ser realizado?
Responder1
Você deseja a opção on grid=true
, que usará os centros dos nós (em vez de suas bordas) para posicionamento. Mas então você precisará aumentar node distance
.
Para a caixa tracejada, sugiro usar a fit
biblioteca.
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes,snakes}
\usepackage{siunitx} %SI单位
%\usepackage{xparse}
\usetikzlibrary{positioning, fit}
\begin{document}
\begin{tikzpicture}[on grid=true, node distance=3cm]
\node[rectangle,draw, very thick, minimum size=10mm] (A) {
A};
\node[rectangle,draw, very thick, minimum size=10mm] (B) [below=of A]{B};
\node[rectangle,draw=red, very thick, minimum size=10mm] (C) [right=of B]{C};
\node[rectangle,draw, very thick, minimum size=10mm] (D) [right=of C]{D};
\node[rectangle,draw, very thick, minimum size=10mm] (E) [above=of D] {E};
\node[diamond,draw, very thick, minimum size=10mm] (F) [above=of C] {FFFFFfF};
%Lines
\draw[->] (A) -> (B);
\draw[->] (B) -> (C);
\draw[->] (C) -> (D);
\draw[->] (D) -> (E);
\draw[->] (E) -> (F);
\draw[->] (F) -> (C);
\node[draw, dashed, fit = {(B)(D)}, text height=2cm]{for $i=1,2,\dots,N$};
\end{tikzpicture}
\end{document}
Responder2
- Você pode primeiro definir o estilo dos nós e arestas nas
tikzpicture
opções e depois escrever um código curto da imagem. - O retângulo tracejado é desenhado como um nó, que se ajusta aos nós B ... D:
\documentclass[border=3.141592]{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, % new
fit, % new
positioning,
shapes}
\begin{document}
\begin{tikzpicture}[% nodes, edges styles
node distance = 10mm and 10mm,
D/.style = {diamond, aspect=1.3,
inner xsep=0mm, draw, thick},
F/.style = {draw, dashed, inner ysep=3ex, yshift=-1ex,
fit=#1},
N/.style = {draw=#1, thick, minimum size=10mm},
N/.default = black,
every edge/.append style = {draw, -Straight Barb}
]
\node (A) [N] {A};
\node (B) [N, below=of A] {B};
\node (C) [N=red,
right=of B] {C};
\node (D) [N, right=of C] {D};
\node (E) [N, above=of D] {E};
\path (E) -- node (F) [D] {FFFFFfF} (A); % <---
% dashed rectangle
\node[F=(B) (D),
label={[anchor=south]below:{for $i=1,2,\dotsc,N$}}] {};
% arrows
\draw (A) edge (B)
(B) edge (C)
(C) edge (D)
(D) edge (E)
(E) edge (F)
(F) edge (C);
\end{tikzpicture}
\end{document}
Responder3
Você pode colocar o nó F ema interseçãode uma linha vertical que passa C
e uma linha horizontal que passa por A
ou E
:
\node[diamond] (F) at (C|-E) {FFFFFfF};
Com a calc
biblioteca você pode colocá-la a meio caminho entre (os centros) A
e E
:
\node[diamnond] (F) at ($(A)!.5!(E)$) {FFFFFfF};
ou a meio caminho entre as fronteiras A
e E
com um nó ao longo de um caminho:
\path (A) -- node[diamond] (F) {FFFFFfF} (E);
Porém, no último você também pode usar A.center
e E.center
no primeiro você pode usar, ($(A.east)!.5!(E.west)$)
mas como seus nós A
têm E
a mesma largura, não há diferença entre colocar um nó no meio do caminho entre seus centros e no meio entre suas bordas.
É claro que, em todos estes casos, onode distance
não será mais observado, mas para o F
nó já era tarde demais para isso.
Você pode usar oon grid
opçãoda positioning
biblioteca para que ela meça a distância do nó entre os centros dos nós, o que exige que você defina cuidadosamente uma distância de nó apropriada. (→A resposta de Sandy G)
Você pode colocar os nós em um matrix of nodes
que os colocará em uma grade, mas garantirá que uma distância mínima do nó seja observada entre eles, representada por row sep
e column sep
. Usando a palavra-chavebetween origins
in row sep
e/ou column sep
um algoritmo de posicionamento semelhante à on grid
opção pode ser usado para a matriz.
\matrix[
matrix of nodes,
row sep=1cm,
column sep=1cm,
cells={nodes={draw, very thick, minimum size=10mm}}]{
|(A)| A & |[diamond] (F)| FFFFFfF & |(E)| E \\
|(B)| B & |[draw=red] (C)| C & |(D)| D \\};
Código
\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{fit, graphs, matrix, positioning, shapes.geometric}
\begin{document}
\begin{tikzpicture}
\begin{scope}[nodes={draw, very thick, minimum size=10mm}]
\node (A) {A};
\node (B) [below=of A] {B};
\node[draw=red] (C) [right=of B] {C};
\node (D) [right=of C] {D};
\node (E) [above=of D] {E};
\node[diamond] (F) at (C|-E) {FFFFFfF};
% with calc
% \node[diamnond] (F) at ($(A)!.5!(E)$) {FFFFFfF};
% or without
% \path (A) -- node[diamond] (F) {FFFFFfF} (E);
\end{scope}
\graph[path, ->, use existing nodes] {A, B, C, D, E, F -> C};
\node[
fit={(B)(D)([yshift=+-1em]C.south)}, dashed, inner sep=+.5em, thick, draw,
label={[above, inner sep=+.2em]south:for $i = 1, 2, \dots, N$}]{};
\end{tikzpicture}
\begin{tikzpicture}
\matrix[
matrix of nodes,
row sep=1cm,
column sep=1cm,
cells={nodes={draw, very thick, minimum size=10mm}}]{
|(A)| A & |[diamond] (F)| FFFFFfF & |(E)| E \\
|(B)| B & |[draw=red] (C)| C & |(D)| D \\};
\graph[path, ->, use existing nodes] {A, B, C, D, E, F -> C};
\node[
fit={(B)(D)([yshift=+-1em]C.south)}, dashed, inner sep=+.5em, thick, draw,
label={[above, inner sep=+.2em]south:for $i = 1, 2, \dots, N$}]{};
\end{tikzpicture}
\end{document}