Estou produzindo alguns fluxogramas de teoria de controle TikZ
onde especifiquei o tamanho da caixa do nó. Como estou fazendo muitos desses fluxogramas, defini estilos globais para eles, por exemplo, o box
estilo que estou usando atualmente:
box/.style={rectangle, draw, minimum width = 8ex,
minimum height = 4ex, inner sep = 1ex}
A quantidade de texto nos nós varia. O problema é que se o texto de um nó exigir mais espaço do que minimum
, o restante dos nós nessa imagem deverá manter o mesmo tamanho do nó maior. Como posso fazer isso? A solução emessa questãoé um que eu gostaria de evitar, pois na minha opinião é muito "manual", preciso de automação.
Um MWE:
\documentclass[12pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
box/.style={rectangle, draw, minimum width = 8ex,
minimum height = 4ex, inner sep = 0},
split/.style={circle, draw, minimum size = 2.5pt, fill=black,
inner sep = 0},
}
\begin{document}
\begin{tikzpicture}[
every path/.style={>={stealth}, ->, draw, node distance = 1pt, inner sep = 0pt},
]
\node[split] (split) {};
\node[box] (I) at ($(split) + (4,0)$) {Short};
\node[box] (P) at ($(I)+(0,1)$) {This node has long node text};
\node[box] (D) at ($(I)+(0,-1)$) {Short};
\draw (split.north) |-(P);
\draw (split.east) -- (I) ;
\draw (split.south) |-(D);
\end{tikzpicture}
\end{document}
Responder1
Esta respostafoi convertido para sua própria biblioteca TikZ ext.node-families
como parte do meutikz-ext
pacote de tensões.
Eu acho que isso é quase tão automático quanto parece. Ele usa o .aux
arquivo e não funciona quando a imagem é externalizada com oexternal
biblioteca.
Você especifica uma família de nós que deve ter a mesma dimensão com as seguintes chaves que estão todas no espaço de nomes /tikz/node family
:
Tipo: caixa de texto.
Antes de um nó ser construído, a dimensão da caixa de texto que contém o texto do nó (
\pgfnodeparttextbox
) é medida e comparada. O maior valor é usado.text height=<name>
: Nós com o mesmo terão a mesma altura de texto.<name>
text depth=<name>
: Nós com o mesmo terão a mesma profundidade de texto.<name>
text width=<name>
: nós com o mesmo terão a mesma largura de texto.<name>
text width align = left|center|right
:Definir a largura da caixa de texto apenas estende a caixa para a direita. O conteúdo da caixa precisa ser realinhado. A
text width align
chave (defaultcenter
) garante que isso seja feito corretamente.text=<name>
define tudotext height
etext depth
paratext width
o mesmo .<name>
Por padrão, isso só é configurado para as formas base
rectangle
ecircle
. Depois que outra forma é declarada (geralmente carregando uma dasshapes.*
bibliotecas), ela pode ser configurada da mesma maneira usando\tikzset{node family/setup shape=<shape name>}
Isso deve ser feito apenas uma vez por formato.
Como isso altera apenas as dimensões da caixa de texto, para formas diferentes na mesma família, isso pode levar a larguras ou alturas diferentes da forma, uma vez que suas dimensões são calculadas de forma diferente com base no tamanho da caixa de texto. Considere este exemplo:
\tikz[nodes=draw, node family/text width=test] \node {Foo} node[circle] {Barbarbar};
o que leva à seguinte saída:
Tipo: Altura mínima e largura mínima.
Ao contrário das medidas da caixa de texto, utiliza-se a altura e a largura da forma que são calculadas pela própria declaração da forma. Como esse cálculo é feito em algum lugar dentro da declaração da forma, novas declarações de forma são necessárias:
Circle
eRectangle
.width=<name>
: Nós com o mesmo terão a mesma largura.<name>
height=<name>
: Nós com o mesmo terão a mesma altura.<name>
Assim como acontece com
/pgf/minimum width
and/pgf/minimum height
, isso ignora quaisquer valores de/pgf/outer xsep
e/pgf/outer ysep
ou da própria largura da linha.
Definir um valor vazio desabilitará as ações desta biblioteca.<name>
Internamente, a escrita no .aux
arquivo acontece no final da imagem que utiliza \tikz@atend@picture
( execute at end picture
).
A chave prefix
especifica prefix
para todas as famílias de nós. Por padrão \pgfpictureid-
, isso faz com que as famílias de nós se apliquem apenas a TikZpictures individualmente.
No exemplo abaixo, todas as famílias são nomeadas, test
mas são todas diferentes.
Também usei a positioning
biblioteca que torna o efeito mais perceptível.
O código ainda pode ser um pouco otimizado como no exemplo abaixo sete macros adicionais são definidas pelo .aux
arquivo. Talvez seja melhor salvar todos os valores de uma família em uma macro?
Código
\documentclass[12pt,tikz]{standalone}
\usetikzlibrary{
positioning, % better positioning (right=of …)
ext.node-families, % node families
arrows.meta % arrow tips
}
\begin{document}
\begin{tikzpicture}[
node distance=.3cm and 1cm,
box/.style={
rectangle, draw, minimum width=+8ex, minimum height=+4ex, inner sep=+0pt,
node family/text width=test},
split/.style={
circle, draw, minimum size=+2.5pt, fill=black, inner sep=+0pt}]
\node[split] (split) {};
\node[box, right=of split] (I) {Short};
\node[box, above=of I] (P) {This node has long node text};
\node[box, below=of I] (D) {Short};
\draw[-Stealth] (split.north) |-(P);
\draw[-Stealth] (split.east) -- (I) ;
\draw[-Stealth] (split.south) |-(D);
\end{tikzpicture}
\tikz % only the same height (text is still centered)
\foreach \cnt[count=\Cnt] in {a,...,h}
\node[draw, Circle, node family/height=test] at (right:\Cnt) {\cnt};
\tikz % height and text height (text depth set to zero)
\foreach \cnt[count=\Cnt] in {a,...,h}
\node[draw, Circle, text depth=+0pt,
node family={height=test, text height=test}]
at (right:\Cnt) {\cnt};
\begin{tikzpicture}[% http://tex.stackexchange.com/q/134983
nodes={circle, draw=black, node family/text=test}]
\node (A) {$n$};
\node[right=0pt of A] (B) {$n+1$};
\end{tikzpicture}
\end{document}
Saída
Primeira compilação
Segunda compilação
Saída (exemplos)