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

¿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:
- The overview of the data for infographic;
- SVG image preparation;
- An overview of Vue components in context of the SVG artwork;
- 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.
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_CODE
la 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 group
uno de ellos layer
mientras trabaja en Illustrator, porque necesitará esos identificadores para separar las partes del código SVG que eventualmente completarán `` area of Vue components. Remember that layer names given in Illustrator become element ids
in SVG markup.
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.
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.
- Chain-wheel will imitate rotation of spokes.
- Stage component is the rear wheel that will list all 21 stages.
- Stage-detail component will display related information on a curved path (left-hand side).
- Team component is the front wheel that will list all participating teams on spokes.
- Team-detail component will display related information on a curved path (right-hand side).
- 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.
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:
- Text animation on a curved path;
- Spoke animation on a wheel.
### Animating Text On A Curved Path
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:
- Fetch stage data;
- Arrange spokes dynamically based on the data;
- 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 `` area of the Vue component using values fetched from the data-source.
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:
- Rotation
To rotate spokes, we’ll simply map through all elements with classNamestage
, and set dynamicrotation
value that is calculated for each spoke. - Transform Origin
NoticetransformOrigin
value in the code above, which is as important asindex
value, because “0% 100%” enables each spoke to rotate from the center of the wheel. - 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.
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 = 5
new 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.
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
Deja un comentario