En este módulo, aprenderemos a trabajar con dos tipos de escalas muy útiles en D3.js: las escalas de tiempo y las escalas logarítmicas. Estas escalas son esenciales para representar datos que varían en el tiempo o que tienen una distribución exponencial.

Escalas de Tiempo

Las escalas de tiempo en D3.js se utilizan para mapear fechas y horas a valores numéricos. Esto es especialmente útil para crear gráficos de series temporales.

Creando una Escala de Tiempo

Para crear una escala de tiempo, utilizamos d3.scaleTime(). Aquí hay un ejemplo básico:

// Definimos el rango de fechas
const startDate = new Date(2020, 0, 1); // 1 de enero de 2020
const endDate = new Date(2020, 11, 31); // 31 de diciembre de 2020

// Creamos la escala de tiempo
const timeScale = d3.scaleTime()
    .domain([startDate, endDate]) // Dominio de la escala
    .range([0, 500]); // Rango de la escala

Ejemplo Práctico: Gráfico de Líneas con Escala de Tiempo

Vamos a crear un gráfico de líneas que muestra datos a lo largo del tiempo.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gráfico de Líneas con Escala de Tiempo</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
    <svg width="600" height="400"></svg>
    <script>
        const data = [
            { date: new Date(2020, 0, 1), value: 30 },
            { date: new Date(2020, 1, 1), value: 50 },
            { date: new Date(2020, 2, 1), value: 80 },
            { date: new Date(2020, 3, 1), value: 65 },
            { date: new Date(2020, 4, 1), value: 95 },
            { date: new Date(2020, 5, 1), value: 70 }
        ];

        const svg = d3.select("svg");
        const margin = { top: 20, right: 30, bottom: 30, left: 40 };
        const width = +svg.attr("width") - margin.left - margin.right;
        const height = +svg.attr("height") - margin.top - margin.bottom;

        const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);

        const x = d3.scaleTime()
            .domain(d3.extent(data, d => d.date))
            .range([0, width]);

        const y = d3.scaleLinear()
            .domain([0, d3.max(data, d => d.value)])
            .range([height, 0]);

        const line = d3.line()
            .x(d => x(d.date))
            .y(d => y(d.value));

        g.append("g")
            .attr("transform", `translate(0,${height})`)
            .call(d3.axisBottom(x));

        g.append("g")
            .call(d3.axisLeft(y));

        g.append("path")
            .datum(data)
            .attr("fill", "none")
            .attr("stroke", "steelblue")
            .attr("stroke-width", 1.5)
            .attr("d", line);
    </script>
</body>
</html>

Explicación del Código

  1. Definición de Datos: Creamos un array de objetos con fechas y valores.
  2. Configuración del SVG: Definimos el tamaño del SVG y los márgenes.
  3. Creación de Escalas: Utilizamos d3.scaleTime() para la escala X y d3.scaleLinear() para la escala Y.
  4. Creación de Ejes: Añadimos los ejes X e Y utilizando d3.axisBottom() y d3.axisLeft().
  5. Dibujo de la Línea: Utilizamos d3.line() para crear la línea que conecta los puntos de datos.

Escalas Logarítmicas

Las escalas logarítmicas son útiles cuando los datos abarcan varios órdenes de magnitud. Se crean utilizando d3.scaleLog().

Creando una Escala Logarítmica

Aquí hay un ejemplo básico de cómo crear una escala logarítmica:

const logScale = d3.scaleLog()
    .domain([1, 1000]) // Dominio de la escala
    .range([0, 500]); // Rango de la escala

Ejemplo Práctico: Gráfico de Barras con Escala Logarítmica

Vamos a crear un gráfico de barras que utiliza una escala logarítmica.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gráfico de Barras con Escala Logarítmica</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
    <svg width="600" height="400"></svg>
    <script>
        const data = [1, 10, 100, 1000, 10000];

        const svg = d3.select("svg");
        const margin = { top: 20, right: 30, bottom: 30, left: 40 };
        const width = +svg.attr("width") - margin.left - margin.right;
        const height = +svg.attr("height") - margin.top - margin.bottom;

        const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);

        const x = d3.scaleBand()
            .domain(data.map((d, i) => i))
            .range([0, width])
            .padding(0.1);

        const y = d3.scaleLog()
            .domain([1, d3.max(data)])
            .range([height, 0]);

        g.append("g")
            .attr("transform", `translate(0,${height})`)
            .call(d3.axisBottom(x).tickFormat(i => data[i]));

        g.append("g")
            .call(d3.axisLeft(y));

        g.selectAll(".bar")
            .data(data)
            .enter().append("rect")
            .attr("class", "bar")
            .attr("x", (d, i) => x(i))
            .attr("y", d => y(d))
            .attr("width", x.bandwidth())
            .attr("height", d => height - y(d));
    </script>
</body>
</html>

Explicación del Código

  1. Definición de Datos: Creamos un array de valores que abarcan varios órdenes de magnitud.
  2. Configuración del SVG: Definimos el tamaño del SVG y los márgenes.
  3. Creación de Escalas: Utilizamos d3.scaleBand() para la escala X y d3.scaleLog() para la escala Y.
  4. Creación de Ejes: Añadimos los ejes X e Y utilizando d3.axisBottom() y d3.axisLeft().
  5. Dibujo de las Barras: Utilizamos selectAll y data para crear las barras del gráfico.

Ejercicios Prácticos

Ejercicio 1: Gráfico de Líneas con Escala de Tiempo

Crea un gráfico de líneas que muestre la temperatura diaria durante un mes. Utiliza una escala de tiempo para el eje X y una escala lineal para el eje Y.

Ejercicio 2: Gráfico de Barras con Escala Logarítmica

Crea un gráfico de barras que muestre la población de diferentes países. Utiliza una escala logarítmica para el eje Y para manejar las grandes diferencias en la población.

Soluciones

Solución al Ejercicio 1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gráfico de Líneas con Escala de Tiempo</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
    <svg width="600" height="400"></svg>
    <script>
        const data = [
            { date: new Date(2021, 0, 1), temp: 5 },
            { date: new Date(2021, 0, 2), temp: 7 },
            { date: new Date(2021, 0, 3), temp: 6 },
            { date: new Date(2021, 0, 4), temp: 8 },
            { date: new Date(2021, 0, 5), temp: 10 },
            { date: new Date(2021, 0, 6), temp: 12 },
            { date: new Date(2021, 0, 7), temp: 15 }
        ];

        const svg = d3.select("svg");
        const margin = { top: 20, right: 30, bottom: 30, left: 40 };
        const width = +svg.attr("width") - margin.left - margin.right;
        const height = +svg.attr("height") - margin.top - margin.bottom;

        const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);

        const x = d3.scaleTime()
            .domain(d3.extent(data, d => d.date))
            .range([0, width]);

        const y = d3.scaleLinear()
            .domain([0, d3.max(data, d => d.temp)])
            .range([height, 0]);

        const line = d3.line()
            .x(d => x(d.date))
            .y(d => y(d.temp));

        g.append("g")
            .attr("transform", `translate(0,${height})`)
            .call(d3.axisBottom(x));

        g.append("g")
            .call(d3.axisLeft(y));

        g.append("path")
            .datum(data)
            .attr("fill", "none")
            .attr("stroke", "steelblue")
            .attr("stroke-width", 1.5)
            .attr("d", line);
    </script>
</body>
</html>

Solución al Ejercicio 2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gráfico de Barras con Escala Logarítmica</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
    <svg width="600" height="400"></svg>
    <script>
        const data = [
            { country: "China", population: 1400000000 },
            { country: "India", population: 1300000000 },
            { country: "USA", population: 330000000 },
            { country: "Indonesia", population: 270000000 },
            { country: "Pakistan", population: 220000000 }
        ];

        const svg = d3.select("svg");
        const margin = { top: 20, right: 30, bottom: 30, left: 40 };
        const width = +svg.attr("width") - margin.left - margin.right;
        const height = +svg.attr("height") - margin.top - margin.bottom;

        const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);

        const x = d3.scaleBand()
            .domain(data.map(d => d.country))
            .range([0, width])
            .padding(0.1);

        const y = d3.scaleLog()
            .domain([1, d3.max(data, d => d.population)])
            .range([height, 0]);

        g.append("g")
            .attr("transform", `translate(0,${height})`)
            .call(d3.axisBottom(x));

        g.append("g")
            .call(d3.axisLeft(y));

        g.selectAll(".bar")
            .data(data)
            .enter().append("rect")
            .attr("class", "bar")
            .attr("x", d => x(d.country))
            .attr("y", d => y(d.population))
            .attr("width", x.bandwidth())
            .attr("height", d => height - y(d.population));
    </script>
</body>
</html>

Conclusión

En esta sección, hemos aprendido a trabajar con escalas de tiempo y logarítmicas en D3.js. Estas escalas son fundamentales para representar datos que varían en el tiempo o que tienen una distribución exponencial. Hemos visto ejemplos prácticos de cómo crear gráficos de líneas y barras utilizando estas escalas, y hemos proporcionado ejercicios para reforzar los conceptos aprendidos. En el próximo módulo, exploraremos cómo crear visualizaciones básicas utilizando D3.js.

D3.js: De Principiante a Avanzado

Módulo 1: Introducción a D3.js

Módulo 2: Trabajando con Selecciones

Módulo 3: Datos y Escalas

Módulo 4: Creando Visualizaciones Básicas

Módulo 5: Visualizaciones Avanzadas

Módulo 6: Interactividad y Animación

Módulo 7: Trabajando con Datos Reales

Módulo 8: Rendimiento y Optimización

Módulo 9: Mejores Prácticas y Técnicas Avanzadas

Módulo 10: Proyecto Final

© Copyright 2024. Todos los derechos reservados