D3.js: ejemplo funcional

Realicemos un gráfico de barras animado en este capítulo. Para este ejemplo, tomamos el archivo data.csv utilizado en el capítulo anterior de los registros de población como conjunto de datos y generamos un gráfico de barras animado.

Para hacer esto, necesitamos realizar los siguientes pasos:

Step 1 - Apply styles - Aplicar estilos CSS utilizando la codificación que se proporciona a continuación.

<style>
   .bar {
      fill: green;
   }
   
   .highlight {
      fill: red;
   }
   
   .title {
      fill: blue;
      font-weight: bold;
   }
</style>

Step 2 - Define variables - Definamos los atributos SVG usando el siguiente script.

<script>
   var svg = d3.select("svg"), margin = 200,
   width = svg.attr("width") - margin,
   height = svg.attr("height") - margin;
</script>

Step 3 - Append text - Ahora, agregue texto y aplique la transformación usando la codificación a continuación.

svg.append("text")
   .attr("transform", "translate(100,0)")
   .attr("x", 50)
   .attr("y", 50)
   .attr("font-size", "20px")
   .attr("class", "title")
   .text("Population bar chart")

Step 4 - Create scale range- En este paso, podemos crear un rango de escala y agregar los elementos del grupo. Se define a continuación.

var x = d3.scaleBand().range([0, width]).padding(0.4),
   y = d3.scaleLinear()
      .range([height, 0]);
   var g = svg.append("g")
      .attr("transform", "translate(" + 100 + "," + 100 + ")");

Step 5 - Read data - Ya hemos creado el data.csvarchivo en nuestros ejemplos anteriores. El mismo archivo que hemos utilizado aquí.

year,population
2006,40
2008,45
2010,48
2012,51
2014,53
2016,57
2017,62

Ahora, lea el archivo anterior usando el código a continuación.

d3.csv("data.csv", function(error, data) {
   if (error) {
      throw error;
   }

Step 6 - Set domain - Ahora, configure el dominio usando la siguiente codificación.

x.domain(data.map(function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);

Step 7 - Add X-axis- Ahora, puede agregar el eje X a la transformación. Se muestra a continuación.

g.append("g")
   .attr("transform", "translate(0," + height + ")")
   .call(d3.axisBottom(x)).append("text")
   .attr("y", height - 250).attr("x", width - 100)
   .attr("text-anchor", "end").attr("font-size", "18px")
   .attr("stroke", "blue").text("year");

Step 8 - Add Y-axis - Agregue el eje Y a la transformación usando el código que se proporciona a continuación.

g.append("g")
   .append("text").attr("transform", "rotate(-90)")
   .attr("y", 6).attr("dy", "-5.1em")
   .attr("text-anchor", "end").attr("font-size", "18px")
   .attr("stroke", "blue").text("population");

Step 9 - Append group elements - Ahora, agregue los elementos del grupo y aplique la transformación al eje Y como se define a continuación.

g.append("g")
   .attr("transform", "translate(0, 0)")
   .call(d3.axisLeft(y))

Step 10 - Select the bar class - Ahora, seleccione todos los elementos en la clase de barra como se define a continuación.

g.selectAll(".bar")
   .data(data).enter()
   .append("rect")
   .attr("class", "bar")
   .on("mouseover", onMouseOver) 
   .on("mouseout", onMouseOut)
   .attr("x", function(d) { return x(d.year); })
   .attr("y", function(d) { return y(d.population); })
   .attr("width", x.bandwidth())
   .transition()
   .ease(d3.easeLinear)
   .duration(200)
   .delay(function (d, i) {
      return i * 25;
   })
   .attr("height", function(d) { return height - y(d.population); });
});

Aquí, agregamos el evento de escucha para el mouseout y el mouseover para realizar la animación. Aplica la animación, cuando el mouse se desplaza sobre una barra en particular y sale de ella. Estas funciones se explican en el siguiente paso.

los .ease(d3.easeLinear)La función se utiliza para realizar movimiento aparente en la animación. Procesa el movimiento de entrada y salida lenta con una duración de 200. El retraso se puede calcular usando -

.delay(function (d, i) {
   return i * 25;
})

Step 11 - Mouseover event handler function - Creemos un controlador de eventos de mouseover para manejar un evento de mouse como se muestra a continuación.

function onMouseOver(d, i) {
   d3.select(this)
      .attr('class', 'highlight');
   d3.select(this)
      .transition()
      .duration(200)
      .attr('width', x.bandwidth() + 5)
      .attr("y", function(d) { return y(d.population) - 10; })
      .attr("height", function(d) { return height - y(d.population) + 10; });
   g.append("text")
      .attr('class', 'val') 
   
   .attr('x', function() {
      return x(d.year);
   })
   
   .attr('y', function() {
      return y(d.value) - 10;
   })
}

Aquí, en el evento de mouseover, queremos aumentar el ancho y la altura de la barra, y el color de la barra de la barra seleccionada a rojo. Para el color, hemos agregado una clase 'resaltar', que cambia el color de la barra seleccionada a rojo.

Una función de transición a la barra durante 200 milisegundos. Cuando aumentamos el ancho de la barra en 5px y el alto en 10px, la transición del ancho y alto anterior de la barra al nuevo ancho y alto será por la duración de 200 milisegundos.

A continuación, calculamos un nuevo valor 'y' para la barra, de modo que la barra no se distorsione debido al nuevo valor de altura.

Step 12 - Mouseout event handler function- Creemos un controlador de eventos de mouseout para manejar un evento de mouse. Se define a continuación.

function onMouseOut(d, i) {
   d3.select(this).attr('class', 'bar');
   
   d3.select(this)
      .transition()     
      .duration(400).attr('width', x.bandwidth())
      .attr("y", function(d) { return y(d.population); })
      .attr("height", function(d) { return height - y(d.population); });
   
   d3.selectAll('.val')
      .remove()
}

Aquí, en el evento mouseout, queremos eliminar las características de selección que habíamos aplicado en el evento mouseover. Por lo tanto, revertimos la clase de barra a la clase 'barra' original y restauramos el ancho y alto originales de la barra seleccionada y restauramos el valor y al valor original.

los d3.selectAll(‘.val’).remove() La función se usa para eliminar el valor de texto que agregamos durante la selección de la barra.

Step 13 - Working Example- El programa completo se da en el siguiente bloque de código. Crea una pagina webanimated_bar.html y agregue los siguientes cambios.

<!DOCTYPE html>
<html>
   <head>
      <style>
         .bar {
            fill: green;
         }
        
         .highlight {
            fill: red;
         }
         
         .title {
            fill: blue;
            font-weight: bold;
         }
      </style>
      <script src = "https://d3js.org/d3.v4.min.js"></script>
      <title> Animated bar chart </title>
   </head>

   <body>
      <svg width = "500" height = "500"></svg>
      <script>
         var svg = d3.select("svg"),
         margin = 200, width = svg.attr("width") - margin,
         height = svg.attr("height") - margin;
         
         svg.append("text")
            .attr("transform", "translate(100,0)")
            .attr("x", 50).attr("y", 50)
            .attr("font-size", "20px")
            .attr("class", "title")
            .text("Population bar chart")
            
         var x = d3.scaleBand().range([0, width]).padding(0.4),
         y = d3.scaleLinear().range([height, 0]);
            
         var g = svg.append("g")
            .attr("transform", "translate(" + 100 + "," + 100 + ")");

         d3.csv("data.csv", function(error, data) {
            if (error) {
               throw error;
            }
               
            x.domain(data.map(function(d) { return d.year; }));
            y.domain([0, d3.max(data, function(d) { return d.population; })]);
                     
            g.append("g")
               .attr("transform", "translate(0," + height + ")")
               .call(d3.axisBottom(x))
               .append("text")
               .attr("y", height - 250)
               .attr("x", width - 100)
               .attr("text-anchor", "end")
               .attr("font-size", "18px")
               .attr("stroke", "blue").text("year");
               
            g.append("g")
               .append("text")
               .attr("transform", "rotate(-90)")
               .attr("y", 6)
               .attr("dy", "-5.1em")
               .attr("text-anchor", "end")
               .attr("font-size", "18px")
               .attr("stroke", "blue")
               .text("population");
                         
            g.append("g")
               .attr("transform", "translate(0, 0)")
               .call(d3.axisLeft(y))

            g.selectAll(".bar")
               .data(data)
               .enter()
               .append("rect")
               .attr("class", "bar")
               .on("mouseover", onMouseOver) 
               .on("mouseout", onMouseOut)   
               .attr("x", function(d) { return x(d.year); })
               .attr("y", function(d) { return y(d.population); })
               .attr("width", x.bandwidth()).transition()
               .ease(d3.easeLinear).duration(200)
               .delay(function (d, i) {
                  return i * 25;
               })
                  
            .attr("height", function(d) { return height - y(d.population); });
         });
          
          
         function onMouseOver(d, i) {
            d3.select(this)
            .attr('class', 'highlight');
               
            d3.select(this)
               .transition()     
               .duration(200)
               .attr('width', x.bandwidth() + 5)
               .attr("y", function(d) { return y(d.population) - 10; })
               .attr("height", function(d) { return height - y(d.population) + 10; });
              
            g.append("text")
               .attr('class', 'val')
               .attr('x', function() {
                  return x(d.year);
               })
               
            .attr('y', function() {
               return y(d.value) - 10;
            })
         }
          
         function onMouseOut(d, i) {
             
            d3.select(this)
               .attr('class', 'bar');
            
            d3.select(this)
               .transition()     
               .duration(200)
               .attr('width', x.bandwidth())
               .attr("y", function(d) { return y(d.population); })
               .attr("height", function(d) { return height - y(d.population); });
            
            d3.selectAll('.val')
               .remove()
         }
      </script>
   </body>
</html>

Ahora, solicita el navegador y veremos la siguiente respuesta.

Si seleccionamos cualquier barra, se resaltará en color rojo. D3 es una biblioteca de visualización de uso general que se ocupa de la transformación de datos en información, documentos, elementos, etc. y, en última instancia, ayuda a crear visualización de datos.