Quebras de linha manuais/automáticas e alinhamento de texto em nós TikZ

Quebras de linha manuais/automáticas e alinhamento de texto em nós TikZ

Como posso inserir uma quebra de linha em um nó TikZ? Simplesmente colocar \\onde eu quero o intervalo não funciona (veja MWE).

Existe uma maneira de quebrar as linhas automaticamente em alguma largura especificada?

E posso controlar o alinhamento do texto (esquerda, direita, centralizado, justificado)?

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node {First line\\second line};
\end{tikzpicture}
\end{document}

Responder1

O problema, segundo oManual do TikZ-PGFé aquele

Normalmente, quando um nó é digitado, todo o texto fornecido entre colchetes é colocado em uma linha longa (em um \hbox, para ser mais preciso), e o nó se tornará tão largo quanto necessário (§17.4.3).

Agora, o manual TikZ-PGF explica três maneiras de conseguir a quebra de linha dentro de um nó TikZ, se desejar.

  1. Use um ambiente multilinha dentro do nó.

Pode-se usar um ambiente dentro do nó que force a quebra de linha ou crie um ambiente de quebra de linha para conseguir a quebra de linha dentro do nó. O exemplo no manual usa o tabularambiente:

\documentclass{article}

\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\node [draw] (example-tabular) {
\begin{tabular}{cc}
eaxmple1 & example2 \\
example 3 & example4 \\
\end{tabular}
};
\end{tikzpicture}

\end{document}

insira a descrição da imagem aqui

  1. Usar \\e align.

Se quiser inserir quebras de linha manualmente, você pode usar \\e o argumento opcional align. (Se você não especificar uma opção para align, a quebra de linha não acontecerá e o problema observado pelo OP ocorrerá.)

\begin{tikzpicture}
\node (example-align) [draw, align=left]{example \\ example example};
\end{tikzpicture}

insira a descrição da imagem aqui

A vantagem desta opção é que o tamanho do nó é automaticamente definido para a largura da linha mais longa dentro do nó, como pode ser visto na imagem a seguir, onde a largura do nó é definida para a largura da segunda linha. No entanto, a desvantagem desta solução é que você mesmo precisa controlar manualmente a quebra de linha (mais sobre isso abaixo).

Vale ressaltar também que você pode controlar o espaçamento das linhas através de um argumento opcional do \\comando:

\begin{tikzpicture}
\node (example-align) [draw, align=left]{example \\[5em] example example};
\end{tikzpicture}

insira a descrição da imagem aqui

Observe, entretanto, que \\não pode ser aninhado dentro de um grupo. Então, por exemplo, o seguinte seránãotrabalhar.

\begin{tikzpicture}
\node (example-align) [draw, align=left]{\textbf{example \\ example example}};
\end{tikzpicture}

Em vez disso, você precisaria fazer:

\begin{tikzpicture}
\node (example-align) [draw, align=left]{\textbf{example}\\\textbf{example example}};
\end{tikzpicture}
  1. Use text widthe \\(e talvez aligntambém).

Por fim, a terceira opção apontada no manual do TikZ-PGF é usar o text widthargumento, que, acredito, cria internamente um minipageambiente. Esta solução define manualmente a largura do nó e pode então ser usada em conjunto com a quebra manual de linha:

\begin{tikzpicture}
\node (example-textwidth-1) [draw, text width=3cm]{example \\ example};
\end{tikzpicture}

insira a descrição da imagem aqui

Além disso, pode ser usado com um bloco de texto mais longo cuja largura padrão é maior que a largura especificada por meio de text width. Nesses casos, o texto será automaticamente quebrado dentro de uma caixa com a largura especificada:

\begin{tikzpicture}
\node (example-textwidth-2) [draw, text width=3cm]{This is a demonstration text for showing how line breaking works.};
\end{tikzpicture}

insira a descrição da imagem aqui

O text widthargumento também pode ser usado em conjunto com o alignargumento para produzir efeitos diferentes. As opções para alignsão left, flush left, right, flush right, center, flush center, justify, e none. Ver §17.4.3 para detalhes dos diferentes efeitos destas alignopções em conjunto com o text widthargumento.

Em resumo, porém, as flushvariantes não tentam equilibrar as fronteiras esquerda e direita através da hifenização. Na minha opinião, o resultado muitas vezes não parece bom (veja a imagem), mas pode ser usado se, por qualquer motivo, você quiser evitar a hifenização.

insira a descrição da imagem aqui

(O nó superior na imagem imediatamente acima usa align=lefte o nó inferior usa align=flush left.)

Uma quarta opção

Uma quarta, e acho que a opção preferida não discutida no manual TikZ-PGF, é usar ovarwidthpacote. Este pacote essencialmente cria um minipageambiente, mas define automaticamente o tamanho horizontal do ambiente para a maior largura dentro dele. Acima, você notará que a text widthopção muitas vezes tornava o nó maior do que o necessário. Por exemplo, na imagem reproduzida imediatamente abaixo, você pode ver que há espaço extra na margem direita:

insira a descrição da imagem aqui

Porém, se usarmos o varwidthpacote, esse espaço extra é eliminado,mesmo que ambos estejam configurados para 3cm:

\documentclass{article}

\usepackage{tikz}
\usepackage{varwidth}

\begin{document}

\begin{tikzpicture}
\node (example-textwidth-3) [draw, text width=3cm, align=left]{This is a demonstration text for showing how line breaking works.};
\end{tikzpicture}

\begin{tikzpicture}
\node (example-varwidth) [draw, align=left] {\begin{varwidth}{3cm}This is a demonstration text for showing how line breaking works.\end{varwidth}};
\end{tikzpicture}

\end{document}

insira a descrição da imagem aqui

Discussão

No geral, acho que a quarta opção é a preferida, pois torna o nó o mais compacto possível (a menos, é claro, que você façanãodeseja que o nó seja compacto).

No entanto, há pelo menos dois contras na quarta opção que posso imaginar e que você pode querer considerar antes de determinar como deseja implementar texto multilinha dentro de um nó TikZ, embora eu ache que o primeiro contra desta opção tenha uma solução alternativa.

A primeira desvantagem é a seguinte: como @percusse apontou nos comentários, o varwidthpacote efetivamente faz a mesma coisa que alignfaz com o nó, o que presumivelmente faz com varwidthque sejam discutidas efetivamente quaisquer diferenças visíveis entre as opções possíveis para align. Portanto, se você deseja ter uma margem alinhada à direita em seu nó e especificá-la via align=right, não haverá diferença visível entre isso e, digamos, align=left. Isto pode ser superado, no entanto, fazendo uso doragged2epacote. Se você deseja que seu nó tenha uma margem alinhada à direita, mas também deseja que ele seja o mais compacto possível (e não quer perder tempo manipulando manualmente a configuração text widthpor meio de um método de 'adivinhar e verificar'):

\documentclass{article}

\usepackage{tikz}
\usepackage{varwidth}
\usepackage{ragged2e}

\begin{document}

\begin{tikzpicture}
\node (example-varwidth-left) [draw, align=left]{\begin{varwidth}{3cm}This is a demonstration text for showing how line breaking works.\end{varwidth}};
\end{tikzpicture}

\begin{tikzpicture}
\node (example-varwidth-right) [draw, align=right]{\begin{varwidth}{3cm}This is a demonstration text for showing how line breaking works.\end{varwidth}};
\end{tikzpicture}

\begin{tikzpicture}
\node (example-varwidth-ragged) [draw, align=flush right] {\begin{varwidth}{3cm}\RaggedLeft This is a demonstration text for showing how line breaking works.\end{varwidth}};
\end{tikzpicture}

\end{document} 

insira a descrição da imagem aqui

Na imagem você pode ver que não há diferença entre os dois primeiros nós, mas o uso dos comandos disponibilizados por ragged2eproduz um efeito visível no terceiro nó.

A segunda desvantagem da quarta opção surge se você realmente deseja controlar a quebra de linha manualmente. O varwidthambiente ainda tenta equilibrar as linhas através da hifenização, o que pode levar, na minha opinião, a resultados feios:

\begin{tikzpicture}
\node (example-varwidth-linebreak) [draw, align=left]{\begin{varwidth}{3cm}This is a demonstration \\ text for showing how line breaking works.\end{varwidth}};
\end{tikzpicture}

insira a descrição da imagem aqui

Se você deseja controlar manualmente a quebra de linha, sugiro a segunda opção, especificando o alignargumento e inserindo \\'s como desejar.

Atualização (conforme comentário de @percusse):

No caso de querer controlar manualmente as quebras de linha, a segunda opção é preferível à quarta opção porque a segunda opção define a largura do nó como o comprimento da linha mais longa dentro do nó. Nenhuma quebra de texto e nenhuma hifenização são impostas. Como resultado, não haverá, na minha opinião, uma saída "feia" da segunda opção, precisamente porque nenhuma quebra automática de texto e hifenização é imposta.

Além disso, é por isso que incluí a quarta opção além das três indicadas no manual TikZ-PGF. Se você deseja impor a quebra automática de texto dentro do nó com uma determinada largurabem como ter o tamanho do nó o mais compacto possível, então você desejará usar o varwidthambiente. Compare os dois nós a seguir, um com aligne outro com varwidthdefinido como 3cm:

\begin{tikzpicture}
\node (example) [draw, align=left]{This is a demonstration text for showing how line breaking works.};
\end{tikzpicture}

\begin{tikzpicture}
\node (example) [draw]{\begin{varwidth}{3cm}This is a demonstration text for showing how line breaking works.\end{varwidth}};
\end{tikzpicture}

insira a descrição da imagem aqui


Termo aditivo

A rigor, este adendo está fora do âmbito da questão; no entanto, dada a natureza pretendida desta questão, conforme indicado nos comentários sobre a questão, pensei em acrescentar que você pode colocar qualquer um dos ambientes de lista ( itemize, enumerate, e description) dentro de um nó, incorporando-o dentro de um ambiente minipageou varwidth. Novamente, acho que o varwidthambiente é preferível pelas razões enumeradas (sem trocadilhos!) Acima.

\documentclass{article}

\usepackage{tikz}
\usepackage{varwidth}
\usepackage{enumitem}

\begin{document}

\begin{tikzpicture}
\node [draw] (example-list) {
\begin{varwidth}{3cm}
\begin{enumerate}[leftmargin=*]
\item{First item}
\item{Second item}
\end{enumerate}
\end{varwidth}
};
\end{tikzpicture}

\end{document}

insira a descrição da imagem aqui

Responder2

Se você deseja apenas dividir a linha em seus pontos de referência, basta dividir o próprio nó em várias linhas.

Por exemplo, na seção 3.12 do manual TikZ, o rascunho do código abaixo

\begin{tikzpicture}
  \draw (0,0) -- (3,0) 
  node [above,align=center,midway]
  {
    First line \\
    Second Line
  };
\end{tikzpicture}

quebra a linha sem a necessidade de mais pacotes/ferramentas.

NOTA: este método não funcionou para mim quando o nó está sozinho; apenas quando faz parte de uma linha. No entanto, nenhum pacote extra é necessário.

A saída do script:

Saída do script TikZ sem pacotes extras

informação relacionada