Creación de una infografía interactiva con Vue.js

Publicado: 2022-03-10
Resumen rápido ↬ ¿Alguna vez ha tenido un requisito en el que tuvo que diseñar y crear una experiencia web interactiva pero el sistema de cuadrícula se quedó corto? Además, los elementos de diseño se convirtieron en formas inusuales que simplemente no encajarían en los diseños web normales. En este artículo, vamos a crear una infografía interactiva utilizando Vue.js, SVG y GreenSock utilizando datos dinámicos y un diseño inusual.

Este artículo presenta un enfoque moderno para construir una infografía interactiva. Seguro que puede tener una infografía simple con toda la información disponible por adelantado, sin ninguna interacción del usuario. Pero pensar en construir una experiencia interactiva cambia el panorama tecnológico que elegimos. Por lo tanto, entendamos primero, ¿por qué Vue.js? Y verá por qué GSAP (plataforma de animación GreenSock) y SVG (gráficos vectoriales escalables) se convierten en opciones obvias.

Vue.js proporciona formas prácticas de crear interfaces de usuario dinámicas basadas en componentes donde puede manipular y administrar elementos DOM de manera poderosa. En este caso, será SVG. Puede actualizar y administrar fácilmente diferentes elementos SVG, de forma dinámica, utilizando solo un pequeño subconjunto de funciones disponibles en Vue.js. pocos. Esto también le permite agrupar elementos SVG relevantes y dividirlos en componentes.

Vue.js funciona bien con bibliotecas externas sin perder su gloria, eso es GSAP aquí. Hay muchos otros beneficios de usar Vue.js, uno de los cuales es que Vue.js le permite aislar plantillas, scripts y estilos relacionados para cada componente. De esta forma, Vue.js promueve una estructura de aplicación modular.

Lectura recomendada : Reemplazo de jQuery con Vue.js: no es necesario un paso de compilación

Vue.js también viene con potentes enlaces de ciclo de vida que le permiten acceder a las diferentes etapas de la aplicación para modificar el comportamiento de la aplicación. La configuración y el mantenimiento de las aplicaciones de Vue.js no requieren un gran compromiso, lo que significa que puede adoptar un enfoque por etapas para escalar su proyecto sobre la marcha.

La infografía es muy liviana en un sentido visual, ya que el objetivo principal de este artículo es aprender a pensar en términos de datos, elementos visuales y, por supuesto, Vue.js, el marco que hace posible toda la interactividad. Además, usaremos GreenSock, una biblioteca para animar elementos SVG. Antes de sumergirnos, echa un vistazo a la demostración.

¡Más después del salto! Continúe leyendo a continuación ↓

Empezaremos con:

  1. La descripción general de los datos para infografía;
  2. preparación de imágenes SVG;
  3. Una descripción general de los componentes de Vue en el contexto de la obra de arte SVG;
  4. Ejemplos de código y diagramas de interactividad clave.

La infografía que vamos a construir es sobre el Tour de Francia, el evento anual de carreras de bicicletas que se lleva a cabo en Francia.

Cree una infografía interactiva con Vue.js, SVG y GreenSock
Tour de Francia: etapas interactivas del juego de listas de bicicletas (rueda trasera) y equipos participantes (rueda delantera). (Vista previa grande)

Descripción general de los datos del Tour de Francia

En el diseño infográfico, los datos impulsan el diseño de su infografía. Por lo tanto, al planificar el diseño de su infografía, siempre es una buena idea tener todos los datos, la información y las estadísticas disponibles para el tema en cuestión.

Durante el Tour de Francia de 2017, aprendí todo lo que pude sobre este evento ciclista más grande en 21 días de juego en julio, y me familiaricé con el tema.

Las entidades básicas de la carrera que decidí seguir en mi diseño son,

  • etapas,
  • equipos,
  • rutas,
  • ganadores,
  • Longitud y clasificaciones de cada ruta.

La siguiente parte del proceso depende de su estilo de pensamiento, por lo que puede ser creativo aquí.

Creé dos conjuntos de datos, uno para etapas y otro para equipos. Estos dos conjuntos de datos tienen múltiples filas de datos (pero within limit ), que coincidieron con dos ruedas de la bicicleta con múltiples radios en cada una. Y eso definió el elemento clave del diseño, The Bicycle Art que viste al principio, donde cada radio será interactivo y responsable de impulsar qué información se revela en la pantalla.

Mencioné within limits anteriores, porque lo que buscamos en este caso no es una visualización de datos en toda regla en el contexto de big data, sino más bien una infografía con datos de alto nivel.

Por lo tanto, dedica tiempo de calidad a los datos y busca similitudes, diferencias, jerarquías o tendencias que puedan ayudarte a transmitir una historia visual. Y no se olvide de la increíble combinación de SVG y Vue.js mientras lo hace, ya que lo ayudará a lograr el equilibrio adecuado entre información (datos), interactividad (Vue.js) y elementos de diseño (SVG Artwork). ) de infografía.

Aquí está el fragmento de un objeto de datos de etapa:

 { "ID": 1, "NAME": "STAGE 01", "DISTANCE": "14", "ROUTE": "KMDUSSELDORF / DUSSELDORF", "WINNER": "THOMAS G.",
    "UCI_CODE": "SKY",
    "TYPE": "Individual Time Trial",
    "DATE": "Saturday July 1st",
    "KEY_MOMENT": " Geraint Thomas takes his first win at 32"
}

Y el fragmento de objeto de datos del equipo como se muestra a continuación:

 { "ID": 1,
    "UCI_CODE": "SKY",
    "NAME": " TEAM SKY",
    "COUNTRY": "Great Britain",
    "STAGE_VICTORIES": 1,
    "RIDERS": 8
}

Esta infografía funciona con una lógica muy simple.

UCI_CODE (Union Cycliste Internationale) es la clave de conexión entre el escenario y el objeto del equipo. Cuando se hace clic en una etapa, primero activaremos esa etapa, pero también usaremos la tecla UCI_CODE para activar el equipo ganador correspondiente.

Preparación SVG

Con un par de conjuntos de datos y un concepto aproximado de arte de bicicletas listo, aquí está el CodePen SVG estático de la infografía que se me ocurrió.

Vea el SVG de Pen Static Bicycle de Krutie(@krutie) en CodePen.

Vea el SVG de Pen Static Bicycle de Krutie(@krutie) en CodePen.

Hemos creado solo un radio para cada rueda, eso se debe a que crearemos dinámicamente el resto de los radios usando una cantidad de registros que se encuentran en el conjunto de datos y los animaremos usando la Biblioteca GreenSock.

El flujo de trabajo para crear este código SVG también es muy simple. Cree su obra de arte infográfica en Adobe Illustrator y guárdela como SVG. Asegúrese de nombrar cada group y layer mientras trabaja en Illustrator, porque necesitará esas identificaciones para separar partes del código SVG que eventualmente llenará el área <template> de los componentes de Vue. Recuerde que los nombres de las capas dados en Illustrator se convierten en identificadores de element ids en el marcado SVG.

También puede usar SVGOMG y optimizar aún más el código SVG exportado desde Adobe Illustrator.

Nota importante: si usa SVGOMG para optimizar el marcado SVG, su código ciertamente se verá bien, pero tenga en cuenta que convertirá todos los elementos <rect> en <ruta> con el atributo d . Esto da como resultado la pérdida de los valores x e y del rectángulo, en caso de que desee ajustar algunos píxeles manualmente más adelante.

En segundo lugar, asegúrese de desmarcar la opción Clean Id (opciones del lado derecho en la interfaz de SVGOMG), esto ayudará a mantener intactos todos los grupos e ID que se crearon en Illustrator.

Descripción general de los componentes de Vue

Incluso si la interactividad y el flujo de datos en su proyecto de infografía son de naturaleza bastante simple, siempre debe tomarse un momento para dibujar un diagrama de árbol de componentes.

Esto ayudará especialmente en caso de que no esté utilizando ningún mecanismo de datos compartidos, donde los componentes secundarios dependen de los valores enviados desde el componente principal (es decir, a través de accesorios) o viceversa (es decir, eventos this.$emit). Esta es su oportunidad de hacer una lluvia de ideas sobre estos valores prop, emitir eventos y datos locales, y documentarlos antes de comenzar a escribir el código.

Árbol de componentes Vue
Árbol de componentes de Vue. (Vista previa grande)

El diagrama anterior es la instantánea de los componentes de Vue que se deriva parcialmente de los requisitos de interactividad y se basa parcialmente en el marcado SVG. Debería poder ver cómo se dividirá el marcado SVG en función de esta estructura de árbol. Es bastante autoexplicativo desde el punto de vista de la jerarquía.

  1. La rueda de cadena imitará la rotación de los radios.
  2. El componente de etapa es la rueda trasera que enumerará las 21 etapas.
  3. El componente de detalle del escenario mostrará información relacionada en una ruta curva (lado izquierdo).
  4. El componente del equipo es la rueda delantera que enumerará todos los equipos participantes en los radios.
  5. El componente de detalles del equipo mostrará información relacionada en una ruta curva (lado derecho).
  6. La navegación incluirá el botón Atrás y Siguiente para acceder a las etapas.

El siguiente diagrama representa los mismos componentes de Vue que se ven arriba, pero en el contexto del diseño infográfico.

Componentes de Vue mezclados en SVG
Componentes Vue mezclados en SVG. (Vista previa grande)

Menos es más: debería ser el enfoque que debe intentar adoptar mientras trabaja en proyectos similares. Piense en los requisitos de animación y transición que tiene, si puede salirse con la suya usando TweenLite en lugar de TweenMax, hágalo. Si tiene la opción de elegir formas elementales y caminos más simples en lugar de complejos, intente optar por elementos livianos que sean fáciles de animar, sin ninguna penalización de rendimiento.

La siguiente sección lo llevará a través de una parte emocionante con la animación GreenSock y Vue.js.

Animación GreenSock

Echemos un vistazo más de cerca a:

  1. Animación de texto en un camino curvo;
  2. Animación hablada en una rueda.
### Animación de texto en una ruta curva

Recuerde la trayectoria curva que se ve alrededor de la rueda de la bicicleta, esa trayectoria curva es ligeramente más grande que el radio de la rueda de la bicicleta. Por lo tanto, cuando animamos el texto en este camino, parecerá que sigue la forma de la rueda.

Vea el texto del bolígrafo en una ruta curva de Krutie (@krutie) en CodePen.

Vea el texto del bolígrafo en una ruta curva de Krutie (@krutie) en CodePen.

path y textPath es una dulce combinación de elementos SVG que le permite establecer texto en cualquier ruta usando el atributo xlink:href .

 <pathlanguage-javascript">curvedPath " stroke="none" fill="none" d="..."/>

<text>
  <textPath xlink:href=" #curvedPath "
          class="stageDetail"
          startOffset="0%">
          {{ stage.KEY_MOMENT }}
   </textPath>
</text>

Para animar el texto a lo largo de la ruta, simplemente animaremos su atributo startOffset usando GreenSock.

 tl.fromTo( ".stageDetail", 1, { opacity: 0,
  attr: { startOffset: "0%" }
},
{opacity: 1,
  attr: { startOffset: "10%" }

}, 0.5 );

A medida que aumenta el porcentaje de startOffset , el texto viajará más a través del perímetro del círculo.

En nuestro proyecto final, esta animación se activa cada vez que se hace clic en cualquier radio. Ahora, pasemos a una parte más emocionante de la animación.

Animación de escenarios/radios dentro de la rueda

Es visible en la demostración que los componentes del stage y del team son de naturaleza similar con un par de pequeñas diferencias. Entonces, concentrémonos en una sola rueda de la bicicleta.

El siguiente ejemplo de CodePen se enfoca solo en las tres ideas clave:

  1. Obtener datos de la etapa;
  2. Organice los radios dinámicamente en función de los datos;
  3. Reorganizar los radios cuando se hace clic en el escenario (radio).

Vea la animación Pen TDF Wheel de Krutie (@krutie) en CodePen.

Vea la animación Pen TDF Wheel de Krutie (@krutie) en CodePen.

Es posible que haya notado en el CodePen SVG estático anterior que los radios no son más que rectángulos SVG y texto agrupado. Los agrupé porque quería elegir tanto el texto como el rectángulo para la animación.

 <g v-for="stage in stages" class="stage">

    <rect x="249" y="250" width="215" height="1" stroke="#3F51B5" stroke-width="1"/>

    <text transform="translate(410 245)" fill="#3F51B5" >
      {{ stage.NAME }}
    </text>

</g>

Los representaremos en el área <template> del componente Vue utilizando valores obtenidos de la fuente de datos.

Cuando las 21 etapas estén disponibles en la pantalla, estableceremos sus posiciones iniciales llamando, digamos, setSpokes() .

 // setSpokes() let stageSpokes = document.querySelectorAll(".stage") let stageAngle = 360/this.stages.length _.map(stageSpokes, (item, index) => { TweenMax.to(item, 2, { rotation: stageAngle*index, transformOrigin: "0% 100%" }, 1) }

Los tres elementos clave para preparar el escenario son:

  1. Rotación
    Para rotar radios, simplemente mapearemos todos los elementos con className stage y estableceremos el valor de rotation dinámica que se calcula para cada radio.
  2. Transformar origen
    Observe el valor de transformOrigin en el código anterior, que es tan importante como el valor de index , porque "0% 100%" permite que cada radio gire desde el centro de la rueda.
  3. ángulo de escenario
    Esto se calcula utilizando el número total de etapas dividido por 360 grados. Esto nos ayudará a colocar cada radio de manera uniforme en un círculo de 360 ​​grados.

AGREGAR INTERACTIVIDAD

El siguiente paso sería agregar un evento de clic en cada etapa para que sea interactivo y reactivo a los cambios de datos; por lo tanto, ¡le dará más vida a una imagen SVG!

Digamos que, si se hace clic en stage/spoke, ejecuta goAnimate() , que es responsable de activar y rotar el escenario en el que se hace clic usando el parámetro stageId .

 goAnimate (stageId) { // activate stage id this.activeId = stageId // rotate spokes }

Usaremos DirectionalRotationPlugin... que es un ingrediente clave para esta interactividad. Y sí, está incluido en TweenMax.

Hay tres formas diferentes de usar este complemento. Anima la propiedad de rotación en 1) en el sentido de las agujas del reloj, 2) en el sentido contrario a las agujas del reloj y 3) en la distancia más corta calculada hasta el destino.

Como ya habrás adivinado, estamos usando la tercera opción para rotar la distancia más corta entre la etapa actual y la nueva etapa.

Revise el CodePen anterior y verá cómo la Etapa 01 se mueve constantemente alrededor del círculo, dejando su lugar original para la nueva etapa activa en un ángulo de 0 grados.

Primero, necesitamos encontrar el ángulo de un escenario en el que se hace clic e intercambiar su rotación con el escenario 01 . Entonces, ¿cómo encontramos el valor de rotación de la etapa en la que se hace clic? Mira el diagrama a continuación.

Cálculo de la distancia desde la Etapa 01 hasta la etapa 'pulsada'
Cálculo de la distancia desde la etapa 01 hasta la etapa 'pulsada'. (Vista previa grande)

Por ejemplo, si se hace clic en la Etapa 05 (como puede ver arriba), el viaje de la Etapa 01 a la Etapa 05 requiere un valor de ángulo de 4 x.

Y, por lo tanto, podemos obtener el ángulo correcto usando (Active stage Id - 1) * 17 degree, seguido del sufijo de cadena '_short' para activar el complemento de rotación direccional.

 angle = 360/21 stages = 17 activeId = 5
new angle = ( (activeId-1) *angle)+'_short'
          = ((5-1)\*17)+'_short'
          = 68

La función final goAnimate() se verá como a continuación:

 _.map(spokes, (item, index) => { if(activeId == index+1) { // active stage TweenMax.to(item, 2, { rotation: 0+'_short', transformOrigin: "0 100%" }) } else if (index == 0) { // first stage TweenMax.to(item, 2,
    { rotation: (activeId*angle)-angle+'_short',
      transformOrigin: "0 100%"
    })

  } else {
    TweenMax.to(item, 2, 
    { rotation: index*angle+'_short', 
      transformOrigin: "0 100%"
    })
  }

}) // end of map

Una vez que tengamos la rueda trasera lista, la rueda delantera (para el equipo) debería seguir la misma lógica con un par de ajustes.

En lugar del escenario, buscaremos los datos del equipo y actualizaremos el punto de registro del atributo transformOrigin para habilitar la generación de radios desde el punto de registro opuesto al de la rueda del escenario.

 // set team spokes map(teamSpokes, (index, key) => { TweenMax.to(index, 2, { rotation: angle*key, transformOrigin: "100% 100%" }, 1) })

Proyecto final

Como yo, si ha escrito todas las funciones relacionadas con la animación y los datos en los componentes de Vue. Es hora de limpiarlos usando Vuex y Mixins.

Uso de la administración de estado de Vuex para impulsar ambas ruedas con datos
Uso de la administración de estado de Vuex para impulsar ambas ruedas con datos. (Vista previa grande)

VUEX

Vuex facilita la gestión de los datos compartidos entre los componentes y, lo que es más importante, agiliza su código, manteniendo los methods y data() limpios y ordenados, dejando los componentes solo para representar los datos, no para manejarlos.

Los enlaces de ciclo de vida son un lugar muy adecuado para realizar cualquier solicitud HTTP. Obtenemos los datos iniciales en el enlace created , cuando la aplicación Vue se ha inicializado, pero aún no se ha montado en el DOM.

Las variables de estado vacías, las stages y los teams se actualizan mediante mutaciones en esta etapa. Luego, usamos el observador (solo una vez) para realizar un seguimiento de estas dos variables, y tan pronto como se actualicen, llamamos al script de animación (desde mixin.js ).

Cada vez que el usuario interactúa con el componente de etapa o equipo, se comunicará con la tienda Vuex, ejecutará setActiveData y actualizará la etapa actual y los valores actuales del equipo. Así es como configuramos los datos activos.

Y cuando los datos activos se configuran después de la actualización de estado, goAnimate se activará para animar (girar direccionalmente) los radios usando los valores actualizados.

Lectura recomendada : Creación de entradas personalizadas con Vue.js

mezclas

Ahora que Vuex maneja los datos, separaremos las animaciones de GreenSock. Esto evitará que nuestros componentes de Vue se saturen con largos guiones de animación. Todas las funciones de GreenSock se agrupan en el archivo mixin.js .

Dado que tiene acceso a Vuex Store dentro de Mixins, todas las funciones GSAP usan variables de state para animar elementos SVG. Puede ver store.js y mixin.js totalmente funcionales en el ejemplo de CodeSandbox aquí.

Conclusión

La creación de infografías interactivas y atractivas requiere que sea analítico con los datos, creativo con las imágenes y eficiente con la tecnología que utiliza, que en este caso es Vue.js. Puede seguir utilizando estos conceptos en su proyecto. Como nota de cierre, lo dejaré con esta rueda de color interactiva circular a continuación que utiliza una idea similar a la que hemos discutido en este artículo.

Vea la paleta de colores circulares de la interfaz de usuario de Pen Material hecha con Vue JS y GSAP por Krutie (@krutie) en CodePen.

Vea la paleta de colores circulares de la interfaz de usuario de Pen Material hecha con Vue JS y GSAP por Krutie (@krutie) en CodePen.

Sin duda, Vue.js tiene muchas características excelentes; podemos crear infografías interactivas con solo algunas cosas, como observadores, propiedades calculadas, mixins, directivas (ver el ejemplo de la rueda de colores) y algunos otros métodos. Vue.js es el pegamento que mantiene juntas las animaciones SVG y GreenSock de manera eficiente, brindándole una amplia oportunidad de ser creativo con cualquier número de temas e interactividad personalizada al mismo tiempo.