Saltos de línea manuales/automáticos y alineación de texto en nodos TikZ

Saltos de línea manuales/automáticos y alineación de texto en nodos TikZ

¿Cómo puedo insertar un salto de línea en un nodo TikZ? Simplemente poner \\donde quiero el descanso no funciona (ver MWE).

¿Hay alguna manera de hacer que las líneas se rompan automáticamente en un ancho específico?

¿Y puedo controlar la alineación del texto (izquierda, derecha, centrado, justificado)?

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

Respuesta1

El problema, según elManual de TikZ-PGFes eso

Normalmente, cuando se compone un nodo, todo el texto que usted proporciona entre llaves se coloca en una línea larga (en un \hbox, para ser precisos), y el nodo se volverá tan ancho como sea necesario (§17.4.3).

Ahora, el manual de TikZ-PGF explica tres formas de lograr un salto de línea dentro de un nodo TikZ si se desea.

  1. Utilice un entorno de varias líneas dentro del nodo.

Se puede utilizar un entorno dentro del nodo que fuerce el salto de línea o cree un entorno de salto de línea para lograr el salto de línea dentro del nodo. El ejemplo del manual utiliza el tabularentorno:

\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}

ingrese la descripción de la imagen aquí

  1. Uso \\y align.

Si desea insertar saltos de línea manualmente, puede utilizar \\y el argumento opcional align. (Si no especifica una opción para align, no se producirá el salto de línea y se producirá el problema observado por el OP).

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

ingrese la descripción de la imagen aquí

La ventaja de esta opción es que el tamaño del nodo se establece automáticamente en el ancho de la línea más larga dentro del nodo, como se puede ver en la imagen adjunta, donde el ancho del nodo se establece en el ancho de la segunda línea. Sin embargo, la desventaja de esta solución es que usted mismo debe controlar manualmente el corte de línea (más sobre esto a continuación).

También vale la pena señalar que puedes controlar el espaciado de las líneas mediante un argumento opcional del \\comando:

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

ingrese la descripción de la imagen aquí

Sin embargo, tenga en cuenta que \\no se pueden anidar dentro de un grupo. Así, por ejemplo, lo siguientenotrabajar.

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

En su lugar, necesitarías hacer:

\begin{tikzpicture}
\node (example-align) [draw, align=left]{\textbf{example}\\\textbf{example example}};
\end{tikzpicture}
  1. Utilice text widthy \\(y tal vez aligntambién).

Finalmente, la tercera opción que se indica en el manual de TikZ-PGF es utilizar el text widthargumento que, creo, crea un minipageentorno internamente. Esta solución establece manualmente el ancho del nodo y luego se puede usar junto con el salto de línea manual:

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

ingrese la descripción de la imagen aquí

Además, se puede utilizar con un bloque de texto más largo cuyo ancho predeterminado sea mayor que el ancho especificado mediante text width. En tales casos, el texto se ajustará automáticamente dentro de un cuadro del ancho especificado:

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

ingrese la descripción de la imagen aquí

El text widthargumento también se puede utilizar junto con el alignargumento para producir diferentes efectos. Las opciones para alignson left, flush left, right, flush right, center, flush center, justifyy none. Consulte §17.4.3 para obtener detalles de los diferentes efectos de estas alignopciones junto con el text widthargumento.

En resumen, sin embargo, las flushvariantes no intentan equilibrar los bordes izquierdo y derecho mediante la separación de palabras. En mi opinión, el resultado a menudo no se ve bien (ver imagen), pero puede usarse si, por cualquier motivo, desea evitar la separación de palabras.

ingrese la descripción de la imagen aquí

(El nodo superior en la imagen inmediatamente superior usa align=left, y el nodo inferior usa align=flush left).

Una cuarta opción

Una cuarta, y creo que la opción preferida que no se comenta en el manual de TikZ-PGF, es utilizar elvarwidthpaquete. Este paquete esencialmente crea un minipageentorno pero establece automáticamente el tamaño horizontal del entorno en la parte más ancha dentro de él. Arriba, notará que la text widthopción a menudo hacía que el nodo fuera más grande de lo necesario. Por ejemplo, en la imagen que se reproduce inmediatamente debajo, se puede ver que hay espacio extra en el margen derecho:

ingrese la descripción de la imagen aquí

Sin embargo, si utilizamos el varwidthpaquete, este espacio extra se elimina,aunque ambos están 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}

ingrese la descripción de la imagen aquí

Discusión

En general, creo que la cuarta opción es la más preferida, ya que hace que el nodo sea lo más compacto posible (a menos, por supuesto, que nonodesea que el nodo sea compacto).

No obstante, se me ocurren al menos dos desventajas de la cuarta opción que quizás quieras considerar antes de determinar cómo deseas implementar texto de varias líneas dentro de un nodo TikZ, aunque creo que la primera desventaja de esta opción tiene una solución alternativa.

La primera desventaja es la siguiente: como @percusse señaló en los comentarios, el varwidthpaquete efectivamente hace lo mismo que lo que alignhace con el nodo, lo que presumiblemente hace varwidthque se discuta cualquier diferencia visible entre las posibles opciones para align. Entonces, si desea tener un margen alineado a la derecha en su nodo y lo especifica mediante align=right, no habrá diferencia visible entre eso y, digamos, align=left. Sin embargo, esto se puede superar haciendo uso de laragged2epaquete. Si desea que su nodo tenga un margen alineado a la derecha pero también desea que sea lo más compacto posible (y no desea tomarse el tiempo para manipular manualmente la configuración text widthmediante un método de "adivinar y 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} 

ingrese la descripción de la imagen aquí

En la imagen, puede ver que no hay diferencia entre los dos primeros nodos, pero el uso de los comandos disponibles mediante ragged2eproduce un efecto visible en el tercer nodo.

La segunda desventaja de la cuarta opción surge si realmente deseas controlar el salto de línea manualmente. El varwidthentorno todavía intenta equilibrar las líneas mediante la separación de palabras, lo que, en mi opinión, puede conducir a resultados desagradables:

\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}

ingrese la descripción de la imagen aquí

Si desea controlar manualmente el salto de línea, sugeriría la segunda opción, especificando el alignargumento e insertando \\'s como desee.

Actualización (según el comentario de @percusse):

En el caso de querer controlar manualmente los saltos de línea, la segunda opción es preferible a la cuarta porque la segunda opción establece el ancho del nodo en la longitud de la línea más larga dentro del nodo. No se aplica ningún ajuste de texto ni separación de palabras. Como resultado, en mi opinión, no habrá resultados "feos" de la segunda opción precisamente porque no se aplica ajuste de texto ni separación de palabras.

Además, es por eso que he incluido la cuarta opción además de las tres indicadas en el manual de TikZ-PGF. Si desea imponer el ajuste de texto dentro del nodo con un ancho determinadoasí como tener el tamaño del nodo lo más compacto posible, entonces querrás utilizar el varwidthentorno. Compare los siguientes dos nodos, uno con aligny otro con varwidthconfigurado en 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}

ingrese la descripción de la imagen aquí


Apéndice

Estrictamente hablando, esta adenda está fuera del alcance de la pregunta; sin embargo, dada la naturaleza prevista de esta pregunta, como se indica en los comentarios sobre la pregunta, pensé que agregaría que puede colocar cualquiera de los entornos de la lista ( itemize, enumeratey description) dentro de un nodo incrustándolo dentro de un entorno minipageo varwidth. Nuevamente, creo que el varwidthentorno es preferible por las razones enumeradas anteriormente (¡sin juego de palabras!).

\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}

ingrese la descripción de la imagen aquí

Respuesta2

Si solo busca dividir la línea en sus puntos de referencia, basta con dividir el nodo en varias líneas.

Por ejemplo, de la sección 3.12 del manual de TikZ, el borrador del código a continuación

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

rompe la línea sin necesidad de más paquetes/herramientas.

NOTA: este método no me funcionó cuando el nodo está solo; justo cuando es parte de una línea. Sin embargo, no se necesitan paquetes adicionales.

La salida del guión:

Salida del script TikZ sin paquetes adicionales

información relacionada