Saltar al contenido

¿Cómo conectar bloques Beamer mediante flechas?

Solución:

JLDiaz le explicó cómo arreglar su código, pero el resultado podría mejorarse. La solución que sugiero quizás no sea perfecta porque es algo que requiere un poco de cuidado, pero proporciona un mejor resultado en mi humilde opinión.

Se basa en el paquete. textpos para colocar los bloques, en Cambiar el ancho predeterminado de los bloques en el proyector para personalizar el ancho del bloque y en el tikzmark macro para identificar bloques.

En realidad, lo interesante de tu solución es el mecanismo en el que identificaste bloques poniéndolos dentro de un nodo TikZ para luego conectarlos usando los anclajes del nodo. Esta solución, sin embargo, utiliza textpos así: ¿cómo identificar todo el bloque? Esa es la razón por la cual tikzmark es necesario. Tenga en cuenta que el uso de textpos ayuda a no tener tales problemas de desalineación vertical.

los tikzmark está construido de tal manera que el nodo podría extenderse en su ancho y en su altura (esa es la parte que requiere un poco de cuidado): observe que la altura del bloque depende en última instancia de su contenido, por lo que mi sugerencia es 1) primero escribe el contenido 2) arregla su altura después.

El punto de la mark identificado está exactamente en el centro del título del bloque y el nodo identifica un área más grande que el bloque:

ingrese la descripción de la imagen aquí

Como puede ver en la imagen, la mitad del nodo construido a través de tikzmark está vacío: esto se hace para asegurar que la conexión de bloques paralelos la flecha se pueda realizar por medio de algo como

path[line width=0.2cm](n2.east)edge[bend left](n1.west);

Como consecuencia, la parte superior permanece vacía y debe tener en cuenta este comportamiento en caso de que dibuje conexiones comenzando / terminando en la parte superior del bloque. Este problema se ha solucionado de una manera particular con un ancla especial.

El código que muestra todas las cosas:

documentclass[aspectratio=169]{beamer}
usepackage{lmodern}
usepackage{tikz}
usepackage[overlay]{textpos}
usetheme{Frankfurt}

newcommand{tikzmark}[2][minimum width=6cm,minimum height=1.5cm]{
 tikz[remember picture,overlay]
 node[anchor=west,
       inner sep=0pt,
       outer sep=6pt,
       xshift=-0.5em,
       yshift=-3ex,
       #1](#2){};
}

newcommand{shownode}[1]{
  tikz[remember picture,overlay]draw[red](#1.south east)rectangle(#1.north west);
}

newcommand{showanchor}[1]{
  tikz[remember picture,overlay]draw[red,thick,mark=x] plot coordinates{(#1)};
}

% original code from Stefan Kottwitz
% https://tex.stackexchange.com/a/12551/13304
newenvironment<>{varblock}[2][.9textwidth]{%
  setlength{textwidth}{#1}
  begin{actionenv}#3%
    definsertblocktitle{#2}%
    par%    
    usebeamertemplate{block begin}%
    }
  {par%
    usebeamertemplate{block end}%
  end{actionenv}}

newenvironment{myblock}[1]{begin{textblock*}{500pt}(#1)}{end{textblock*}}

% special way to reach the top of the block
defnewabove(#1){
([yshift=1.5ex]#1.center)
}

begin{document}
begin{frame}
begin{myblock}{0.55textwidth, -0.2textheight}
    tikzmark{n1}
    shownode{n1}    
    %remove the previous line: just used to see where the invisible node is placed
    begin{varblock}[6cm]{title1}
    text1
    end{varblock}
    showanchor{n1}
    %remove also this: just used to see where n1 is positioned
end{myblock}

begin{myblock}{0em, -0.2textheight}
    tikzmark{n2}
    shownode{n2}
    begin{varblock}[6cm]{title2}
    text2
    end{varblock}
    showanchor{n2}
end{myblock} 

begin{myblock}{0.3textwidth, 0.2textheight}
    tikzmark[minimum width=5cm,minimum height=2.25cm]{n3} % customization of width and height
    shownode{n3}
    begin{varblock}[5cm]{title3}
    text3\
    text
    end{varblock}
    showanchor{n3}
end{myblock}

begin{tikzpicture}[remember picture,overlay,-stealth]
path[line width=0.2cm](n2.east)edge[bend left](n1.west);
path[line width=0.2cm](n1.south)edge[bend left](n3.east);
path[line width=0.2cm](n3.west)edge[bend left](n2.south);
% in case you need to connect some block from ``north''
%path[line width=0.2cm](n3.north)edge[bend left](n1.south west); % is wrong
path[line width=0.2cm]newabove(n3) edge[bend left](n1.south west);
end{tikzpicture}
end{frame}
end{document}

Eliminando todas las cosas para hacer visibles los nodos y anclas y la ruta especial que muestra cómo llegar a la parte superior del bloque, terminas con:

ingrese la descripción de la imagen aquí

que supongo que es lo que querías.

Cómo lidiar con el problema de la altura de los bloques.

Dado que esto podría ser una desventaja del procedimiento, veamos un ejemplo.

Al principio, uno debe preocuparse por el contenido de los bloques sin considerar la altura u otras cosas. Por ejemplo:

documentclass[aspectratio=169]{beamer}
usepackage{lmodern}
usepackage{tikz}
usetheme{Frankfurt}
usepackage[overlay]{textpos}

newcommand{tikzmark}[2][minimum width=6cm,minimum height=1.5cm]{
 tikz[remember picture,overlay]
 node[anchor=west,
       inner sep=0pt,
       outer sep=6pt,
       xshift=-0.5em,
       yshift=-3ex,
       #1](#2){};
}

newcommand{shownode}[1]{
  tikz[remember picture,overlay]draw[red](#1.south east)rectangle(#1.north west);
}

newcommand{showanchor}[1]{
  tikz[remember picture,overlay]draw[red,thick,mark=x] plot coordinates{(#1)};
}

% original code from Stefan Kottwitz
% https://tex.stackexchange.com/a/12551/13304
newenvironment<>{varblock}[2][.9textwidth]{%
  setlength{textwidth}{#1}
  begin{actionenv}#3%
    definsertblocktitle{#2}%
    par%    
    usebeamertemplate{block begin}%
    }
  {par%
    usebeamertemplate{block end}%
  end{actionenv}}

newenvironment{myblock}[1]{begin{textblock*}{500pt}(#1)}{end{textblock*}}

% special way to reach the top of the block
defnewabove(#1){
([yshift=1.5ex]#1.center)
}

begin{document}
begin{frame}

begin{myblock}{0cm,-2.5cm}
    tikzmark{n1}
    begin{varblock}[6cm]{title1}
    Hello! :) This is the text of my block. Here I want to say
    that the height of the blocks is not so problematic.
    end{varblock}
end{myblock}

begin{myblock}{8cm,-2.5cm}
    tikzmark{n2}
    begin{varblock}[6cm]{title2}
    This is my very long block with even an equation:
    [Delta_n=
     begin{cases}
       1 quad q_n>0\
       0 quad q_n=0
     end{cases}
    ]
    end{varblock}
end{myblock}


% I can leave all blank lines I want




begin{myblock}{8cm,2cm}
    tikzmark{n3}
    begin{varblock}[6cm]{title3}
    Short text
    end{varblock}
end{myblock}



begin{myblock}{0cm,2cm}
    tikzmark{n4}
    begin{varblock}[6cm]{title4}
    Short text
    end{varblock}
end{myblock}

begin{tikzpicture}[remember picture,overlay,-stealth,line width=0.2cm]
draw (n1.east)--(n2.west);
draw (n2.south)--newabove(n3);
draw (n3.west)--(n4.east);
draw newabove(n4)--(n1.south);
end{tikzpicture}
end{frame}
end{document}

Observe que dejé intencionalmente algunas líneas en blanco. Después de dos ejecuciones de compilación obtenemos:

ingrese la descripción de la imagen aquí

Oh … hay un problema con los bloques 1 y 2. ¿Por qué? Porque la altura es incorrecta; usando nuestro shownode y showanchor es posible entender la razón:

ingrese la descripción de la imagen aquí

Observe ahora que el valor predeterminado es 1.5cm por la altura. Por lo tanto, algo como 0.75cm para un bloque con el título y una línea en el cuerpo.

En el bloque 1 tenemos 4 líneas + el título, por lo que, a grandes rasgos, tenemos tres veces la altura estándar: 0.75cm x 3=2.25cm. Sin embargo, este es solo el bloque, por lo que para tener el nodo completo debemos multiplicar por dos nuevamente. Totalmente: 4.5cm.

Mire ahora el segundo bloque: está un poco más alto que el bloque 1. Supongo que es 1cm más alto, así que pongamos 5.5cm.

Entonces tenemos que actualizar:

begin{myblock}{0cm,-2.5cm}
    tikzmark[minimum width=6cm, minimum height=4.5cm]{n1}
    shownode{n1}
    begin{varblock}[6cm]{title1}
    Hello! :) This is the text of my block. Here I want to say
    that the height of the blocks is not so problematic.
    end{varblock}
    showanchor{n1}
end{myblock}

begin{myblock}{8cm,-2.5cm}
    tikzmark[minimum width=6cm, minimum height=5.5cm]{n2}
    shownode{n2}
    begin{varblock}[6cm]{title2}
    This is my very long block with even an equation:
    [Delta_n=
     begin{cases}
       1 quad q_n>0\
       0 quad q_n=0
     end{cases}
    ]
    end{varblock}
    showanchor{n2}
end{myblock}

Esto proporciona:

ingrese la descripción de la imagen aquí

Más o menos hemos terminado. Pero todavía estoy insatisfecho con el bloque 2: no es muy preciso. Supongo que necesitamos 0.25cm más. Entonces:

begin{myblock}{8cm,-2.5cm}
    tikzmark[minimum width=6cm, minimum height=5.75cm]{n2}
    shownode{n2}
    begin{varblock}[6cm]{title2}
    This is my very long block with even an equation:
    [Delta_n=
     begin{cases}
       1 quad q_n>0\
       0 quad q_n=0
     end{cases}
    ]
    end{varblock}
    showanchor{n2}
end{myblock}

Esto da:

ingrese la descripción de la imagen aquí

Oh .. mal. ¡Demasiado! Ok, acortémoslo un poco a 5.7cm. Seguro que esto será correcto. En conclusión:

ingrese la descripción de la imagen aquí

Arreglé tu código en algunos puntos:

  1. Lo más importante, tienes que dar también la remember picture opción a sus superposiciones. Sin él, el nombre de cada nodo no se refiere a las coordenadas adecuadas, ya que son nodos en una imagen tikz diferente.
  2. baseline La opción no es realmente necesaria en este caso.
  3. inner sep puesto a cero para los nodos del bloque
  4. % agregado al final de algunas líneas para evitar el espacio vertical (lo que todavía sucede, no sé por qué, y se puede hacer visible descomentando la primera línea de la every overlay node estilo.

El código resultante es:

documentclass[aspectratio=169]{beamer}
usepackage{tikz}
usetheme{Frankfurt}

tikzset{
  every overlay node/.style={
    %draw=black,fill=white,rounded corners,
    anchor=north west, inner sep=0pt,
  },
}
% Usage:
% tikzoverlay at (-1cm,-5cm) {content};
% or
% tikzoverlay[text width=5cm] at (-1cm,-5cm) {content};
deftikzoverlay{%
   tikz[remember picture, overlay]node[every overlay node]
}%

begin{document}

begin{frame}
tikzoverlay (n1) at (8cm,2cm) {%
  begin{minipage}{0.4textwidth}%
    begin{block}{title1}%
      {Text1}
    end{block}
  end{minipage}
};

tikzoverlay (n2) at (0cm,2cm) {%
  begin{minipage}{0.4textwidth}%
    begin{block}{title2}%
      Text2
    end{block}
  end{minipage}
};

tikzoverlay (n3) at (5cm,0cm) {%
  begin{minipage}{0.4textwidth}%
    begin{block}{Title3}%
      Text3
    end{block}
  end{minipage}
};

begin{tikzpicture}[remember picture, overlay]
  path [line width=0.3cm,->] (n1.south) edge (n3.south);
  path [line width=0.3cm,->] (n3.north) edge (n2.south);
  path [line width=0.3cm,->] (n2.east) edge (n1.west);
end{tikzpicture}
end{frame}
end{document}

Que produce (después compilando dos veces):

resultado

Lo cual es feo, en mi humilde opinión, pero supongo que es lo que estabas pidiendo.

Editar:

Cuando escribí el código anterior, no presté atención a los valores de las coordenadas donde se dibujó cada nodo. Supuse que el resultado con el nodo2 en un nivel diferente al del nodo1 fue intencional. Pero el comentario de OP me hizo darme cuenta de que, de hecho, ambos nodos usan la misma coordenada y, entonces, ¿por qué no están alineados?

La razón es que no están dibujados en el mismo tikzpicture, por lo que no comparten el espacio de coordenadas. Cada tikzpicture (o tikz comando) inicia su propio sistema de coordenadas. Entonces, la nueva pregunta es “¿por qué entonces casi ¿trabajó?”.

La razón de esto es que cada figura tiene la opción overlay, lo que significa que independientemente de lo que realmente dibuje la imagen, el espacio reservado por tex para esa imagen es cero. Es un punto adimensional. Ese punto es entonces el origen de la figura.

Entonces, si tuviéramos tres figuras sin espacio entremedias, ya que cada una es vista por tex como un punto adimensional, las tres se dibujarán “en el mismo punto” y, por lo tanto, sus sistemas de coordenadas coincidirán. Pero si las figuras están separadas por palabras, entonces cada una tendrá su propio origen.

Sucede que en tu caso las cifras están separados por espacios en blanco e incluso por ` par, porque hay líneas vacías en el código fuente y finales de línea entre las cifras.

Entonces, la solución es eliminar todo este espacio no deseado, eliminando las líneas en blanco entre las figuras y comentando los retornos de carro al final de cada figura (que de otro modo producirían un espacio):

documentclass[aspectratio=169]{beamer}
usepackage{tikz}
usetheme{Frankfurt}

tikzset{
  every overlay node/.style={
    %draw=black,fill=white,rounded corners,
    anchor=north west, inner sep=0pt,
  },
}
% Usage:
% tikzoverlay at (-1cm,-5cm) {content};
% or
% tikzoverlay[text width=5cm] at (-1cm,-5cm) {content};
deftikzoverlay{%
   tikz[remember picture, overlay]node[every overlay node]
}%

begin{document}

begin{frame}
tikzoverlay (n1) at (8cm,2cm) {%
  begin{minipage}{0.4textwidth}%
    begin{block}{title1}%
      {Text1}
    end{block}
  end{minipage}
};%
tikzoverlay (n2) at (0cm,2cm) {%
  begin{minipage}{0.4textwidth}%
    begin{block}{title2}%
      Text2
    end{block}
  end{minipage}
};%
tikzoverlay (n3) at (5cm,0cm) {%
  begin{minipage}{0.4textwidth}%
    begin{block}{Title3}%
      Text3
    end{block}
  end{minipage}
};%
%
begin{tikzpicture}[remember picture, overlay]
  path [line width=0.3cm,->] (n1.south) edge (n3.south);
  path [line width=0.3cm,->] (n3.north) edge (n2.south);
  path [line width=0.3cm,->] (n2.east)  edge (n1.west);
end{tikzpicture}
end{frame}
end{document}

Resultado:

resultado

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *