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

 

 

 

  • SmashingConf Friburgo 2024
  • Clase magistral de CSS moderno avanzado, con Manuel Matuzović

  • Índice
    1. Overview Of Tour De France Data
    2. Preparación de SVG
    3. Vue Component Overview
    4. GreenSock Animation
      1. Animating Stages/Spokes Inside The Wheel
      2. ADDING INTERACTIVITY
    5. Final Project
      1. VUEX
      2. Mixins
    6. Conclusion

    ¿Alguna vez ha tenido un requisito en el que tenía 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 habituales? 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 crear una infografía interactiva. Seguro que puedes tener una infografía sencilla con toda la información disponible por adelantado, sin ninguna interacción del usuario. Pero pensar en crear una experiencia interactiva cambia el panorama tecnológico que elegimos. Por lo tanto, primero entendamos por qué Vue.js. Y verá por qué GSAP (GreenSock Animation Platform) y SVG (Scalable Vector Graphics) 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 maneras poderosas. En este caso, será SVG. Puede actualizar y administrar fácilmente diferentes elementos SVG, dinámicamente, utilizando solo un pequeño subconjunto de funciones disponibles en Vue.js; algunas de las funciones básicas que se ajustan a los requisitos aquí son enlace de datos, representación de listas, enlace dinámico de clases para nombrar un pocos. Esto también le permite agrupar elementos SVG relevantes y componerlos.

     

    Vue.js funciona bien con bibliotecas externas sin perder su gloria, ese 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 manera, Vue.js promueve una estructura de aplicación modular.

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

    Vue.js also comes packaged with powerful lifecycle hooks that let you tap into the different stages of application to modify application behavior. Setting up and maintaining Vue.js applications doesn’t require a big commitment, meaning you can take phased-approach to scale your project as you go.

    The infographic is very light-weight in a visual sense, as the main aim of this article is to learn how to think in terms of data, visual elements, and of course, Vue.js — the framework that makes all the interactivity possible. In addition, we’ll use GreenSock, a library for animating SVG elements. Before we dive in, take a look at the demo.

    We’ll start with:

    1. The overview of the data for infographic;
    2. SVG image preparation;
    3. An overview of Vue components in context of the SVG artwork;
    4. Code samples and diagrams of key interactivity.

    The infographic that we’re going to build is about Tour De France, the annual bicycle racing event held in France.

    Tour De France  —  Interactive bicycle listing game stages (rear-wheel) and participating teams (front-wheel). (Large preview)

    Overview Of Tour De France Data

    In infographic design, data drives the design of your infographic. Therefore, while planning your infographic design, it’s always a good idea to have all data, information, and statistics available for the given subject matter.

    During Tour De France of 2017, I learned everything about this biggest cycling event that I could in 21 days of the game in July, and I familiarized myself with the subject.

    Basic entities of the race that I decided to go for in my design are,

    • Stages,
    • Teams,
    • Routes,
    • Winners,
    • Length and classifications of each routes.

    This next part of the process depends on your thinking style, so you can be creative here.

    I created two sets of data, one for stages and other for teams. These two datasets have multiple rows of data (but within limit)  —  which matched with two wheels of the bicycle with multiple spokes in each. And that defined the key element of the design, The Bicycle Art that you saw at the beginning  —  where each spoke will be interactive responsible to drive what information is revealed on screen.

     

    I mentioned within limits above, because what we’re aiming for in this instance is not a full-blown data-visualization in context of big data but rather an infographic with high-level data.

    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 te olvides de la increíble combinación de SVG y Vue.js mientras lo haces, ya que te 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 escenario:

    { "ID": 1, "NAME": "STAGE 01", "DISTANCE": "14", "ROUTE": "KMDÜSSELDORF / DÜSSELDORF", "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 la etapa y el objeto del equipo. Cuando se hace clic en una etapa, primero activaremos esa etapa, pero también usaremos UCI_CODEla tecla para activar el equipo ganador correspondiente.

    Preparación de SVG

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

    Vea el SVG 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 sencillo. Cree su obra de arte infográfica en Adobe Illustrator y guárdela como SVG. Asegúrese de nombrar cada groupuno de ellos layermientras trabaja en Illustrator, porque necesitará esos identificadores para separar las partes del código SVG que eventualmente completarán `

    You can also use SVGOMG and further optimize SVG code exported from Adobe Illustrator.

    Important Note: If you use SVGOMG to optimize SVG markup, your code certainly will look neat, but note that it will convert all rect elements into path with d attribute. This results into losing x and y values of the rectangle, in case you wish to adjust few pixels manually later-on.

     

    Second thing, make sure to uncheck Clean Id option (right-hand side options in SVGOMG interface), this will help maintain all groups and ids intact that were created in Illustrator.

    Vue Component Overview

    Even if interactivity and data-flow in your infographic project is quite simple in nature, you should always take a moment to draw up a tree diagram of components.

    This will especially help in case you’re not using any shared-data mechanism, where child components are dependent on the values sent from the parent component (i.e. via props) or vice-versa (i.e. this.$emit events). This is your chance to brainstorm these prop values, emit events and local data — and document them before starting to write the code.

    Vue component tree. (Large preview)

    Diagram above is the snapshot of Vue components that is partially derived from interactivity requirements and partially based on SVG markup. You should be able to see how SVG markup will be split up based on this tree structure. It’s pretty self-explanatory from hierarchy view-point.

    1. Chain-wheel will imitate rotation of spokes.
    2. Stage component is the rear wheel that will list all 21 stages.
    3. Stage-detail component will display related information on a curved path (left-hand side).
    4. Team component is the front wheel that will list all participating teams on spokes.
    5. Team-detail component will display related information on a curved path (right-hand side).
    6. Navigation will include back and next button to access stages.

    The diagram below represents the same Vue components seen above, but in the context of the infographic design.

    Vue Components blended into SVG. (Large preview)

    Less is more — should be the approach you should try to take while working on similar projects. Think through the animation and transition requirements you have, if you can get away with using TweenLite instead of TweenMax — do so. If you have the option to choose elementary shapes and simpler paths over complex ones — by all means try to opt-in for light-weight elements that are easy to animate — without any performance penalty.

    Next section will take you through an exciting part with GreenSock animation and Vue.js.

    GreenSock Animation

    Let’s take a closer look at:

    1. Text animation on a curved path;
    2. Spoke animation on a wheel.

    ### Animating Text On A Curved Path Anime en Español

    Remember the curve path seen around the bicycle wheel, that curved path is slightly bigger than the radius of the bicycle wheel. Therefore, when we animate text on this path, it will look as if it follows the shape of the wheel.

    See the Pen Text on a Curved Path by Krutie (@krutie) on CodePen.

    path and textPath is a sweet combination of SVG elements that allows you to set text on any path using xlink:href attribute.

    pathlanguage-javascript">curvedPath" stroke="none" fill="none" d="..."/text
 textPath xlink_href="#curvedPath" class="stageDetail" startOffset="0%" {{ stage.KEY_MOMENT }} /textPath
/text

    To animate text along the path, we’ll simply animate its startOffset attribute using GreenSock.

     

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

    As you increase the startOffset percentage, text will travel further through the circle perimeter.

    In our final project, this animation is triggered every time any spoke is clicked. Now, let’s move on to a more exciting part of the animation.

    Animating Stages/Spokes Inside The Wheel

    It’s visible from the demo that stage and team components are similar in nature with couple of small differences. So, let’s focus on just one wheel of the bicycle.

    The CodePen example below zooms in on just the three key ideas:

    1. Fetch stage data;
    2. Arrange spokes dynamically based on the data;
    3. Re-arrange spokes when stage (spoke) is clicked.

    See the Pen TDF Wheel Animation by Krutie (@krutie) on CodePen.

    You may have noticed in the static SVG CodePen above that the spokes are nothing but SVG rectangles and text grouped together. I have grouped them together since I wanted to pick both text and rectangle for the purpose of animation.

    g v-for="stage in stages" class="stage" rect x="249" y="250" stroke="#3F51B5" stroke-width="1"/ text transform="translate(410 245)" fill="#3F51B5" 
 {{ stage.NAME }}
 /text/g

    We will render them in `

    When all 21 stages are available on screen, we’ll set their initial positions by calling, let’s say, 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)}

    Three key elements of setting the stage are:

    1. Rotation
      To rotate spokes, we’ll simply map through all elements with className stage, and set dynamic rotation value that is calculated for each spoke.
    2. Transform Origin
      Notice transformOrigin value in the code above, which is as important as index value, because “0% 100%” enables each spoke to rotate from the center of the wheel.
    3. stageAngle
      This is calculated using total number of stages divided by 360-degree. This will help us lay every spokes evenly in 360-degree circle.

    ADDING INTERACTIVITY

    Next step would be to add click-event on each stage to make it interactive and reactive to data changes  —  hence, it will breathe more life into an SVG image!

    Let’s say, if stage/spoke is clicked, it executes goAnimate(), which is responsible to activate and rotate the stage being clicked using the stageId parameter.

     

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

    We’ll use DirectionalRotationPlugin…which is a key ingredient for this interactivity. And yes, it is included in TweenMax.

    There are three different ways of using this plugin. It animates rotation property in 1) clockwise, 2) counter-clockwise and 3) in the shortest distance calculated to the destination.

    As you’d have guessed by now, we’re using the third option to rotate the shortest distance between the current stage and new stage.

    Review the CodePen above and you’ll see how Stage 01 is constantly moving around the circle, leaving its original spot for new active stage at 0-degree angle.

    First, we need to find the angle of a stage being clicked, and interchange its rotation with Stage 01. So, how do we find the rotation value of the stage being clicked? Check out the diagram below.

    Distance calculation from Stage 01 to the ‘clicked’ stage. (Large preview)

    For example, if Stage 05 is clicked (as you can see above), the journey from Stage 01 to Stage 05  —  requires 4 x angle-value.

    And therefore, we can get the correct angle using, (Active stage Id - 1) * 17 degree, followed by ‘_short’ string postfix to trigger directional rotation plugin.

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

    The final goAnimate() function will look something like below:

    _.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

    Once we have the rear wheel ready, the front wheel (for team) should follow the same logic with a couple of tweaks.

    Instead of stage, we’ll fetch team data and update registration point of transformOrigin attribute to enable spokes generation from opposite registration point than the stage wheel.

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

    Final Project

    Like me, if you have written all animation and data related functions in Vue components itself. It’s time to clean them up using Vuex and Mixins.

    Using Vuex state management to power both wheels with data. (Large preview)

    VUEX

    Vuex eases up the management of shared data among components, and more importantly, it streamlines your code, keeping methods and data() clean and tidy, leaving components only to render the data, not to handle it.

     

    Lifecycle hooks are a very suitable place to perform any HTTP requests. We fetch initial data in created hook, when the Vue application has initialized, but hasn’t yet mounted into the DOM.

    Empty state variables, stages and teams are updated using mutations at this stage. We then, use watcher (only once) to keep track of these two variables, and soon as they’re updated, we call in animation script (from mixin.js).

    Every time user interacts with stage or team component, it will communicate with Vuex store, executes setActiveData, and updates current stage and current team values. That is how we set active data.

    And when the active data is set after state update, goAnimate will kick in to animate (directional rotate) spokes using updated values.

    Recommended reading: Creating Custom Inputs With Vue.js

    Mixins

    Now that the data is handled by Vuex, we’ll separate out GreenSock animations. This will prevent our Vue components being cluttered with long animation scripts. All GreenSock functions are grouped together in mixin.js file.

    Since you have access to Vuex Store within Mixins, all GSAP functions use state variables to animate SVG elements. You can see fully functional store.js and mixin.js in the CodeSandbox example over here.

    Conclusion

    Creating interactive and engaging infographics requires you to be analytical with the data, creative with visuals and efficient with the technology you use, which in this case is Vue.js. You can further use these concepts in your project. As a closing note, I’ll leave you with this circular interactive color wheel below that uses an idea similar to the one we’ve discussed in this article.

    See the Pen Material UI Circular Colour Palette made with Vue JS and GSAP by Krutie (@krutie) on CodePen.

    With no doubt, Vue.js has many great features; we’re able to create interactive infographics with just a few things, such as watchers, computed properties, mixins, directive (see color-wheel example) and a few other methods. Vue.js is the glue that holds both SVG and GreenSock animation together efficiently, giving you ample of opportunity to be creative with any number of subject matter and custom interactivity at the same time.

    (rb, ra, yk, il)Explore more on

    • Vue
    • SVG
    • JavaScript
    • Interaction Design

    Browse All Smashing Magazine Topics

    • Accessibility
    • Best practices
    • Business
    • Career
    • Checklists
    • CSS
    • Data Visualization
    • Design
    • Design Patterns
    • Design Systems
    • E-Commerce
    • Figma
    • Freebies
    • HTML
    • Illustrator
    • Inspiration
    • JavaScript
    • Mobile
    • Performance
    • Privacy
    • React
    • Responsive Design
    • Round-Ups
    • SEO
    • Typography
    • Tools
    • UI
    • Usability
    • UX
    • Vue
    • Wallpapers
    • Web Design
    • Workflow

    With a commitment to quality content for the design community.

    Founded by Vitaly Friedman and Sven Lennartz. 2006–2024.

    Smashing is proudly running on Netlify, TinaCMS and Swell.

    Fonts by Latinotype.

    • ✎ Write for us
    • Contact us
    • About us (Impressum)
    • Privacy policy
    • Membership login
    • Delivery times
    • Advertise






    Tal vez te puede interesar:

    1. Creación de su propia biblioteca de validación de React: la experiencia del desarrollador (Parte 3)
    2. Introducción a Quasar Framework: creación de aplicaciones multiplataforma
    3. Creación de un componente web retro que se puede arrastrar con iluminación
    4. Creación y acoplamiento de una aplicación Node.js con arquitectura sin estado con la ayuda de Kinsta

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

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

    Overview Of Tour De France DataPreparación de SVGVue Component OverviewGreenSock AnimationFinal ProjectConclusionSmashingConf Friburgo 2024 Clase magistral d

    programar

    es

    https://pseint.es/static/images/programar-creacion-de-una-infografia-interactiva-con-vue-957-0.jpg

    2024-05-20

     

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

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Update cookies preferences