Construyendo un Calendario de Mapa de Calor de Contribuciones de GitHub en React

JavaScriptJavaScriptIntermediate
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Este proyecto te guiará a través de la creación de un calendario de mapa de calor en React, similar al gráfico de contribuciones de GitHub. Este tipo de calendario puede ser una forma convincente de visualizar datos de actividad a lo largo del tiempo, con la intensidad del color que indica el nivel de actividad en un día determinado. Al final de este proyecto, tendrás una clara comprensión de cómo integrar y usar un calendario de mapa de calor en una aplicación React.

👀 Vista previa

Instalar las dependencias necesarias

La base de nuestro calendario de mapa de calor es una nueva aplicación React.

Funcionalidad:

  • Instalar las dependencias del proyecto.
  • Instalar la biblioteca react-calendar-heatmap para el mapa de calor.
  • Instalar date-fns para manipular fechas con facilidad.

Para instalar las dependencias del proyecto, use el siguiente comando:

cd github-heatmap-calendar
npm install

Para agregar la funcionalidad del calendario de mapa de calor, necesitamos instalar una biblioteca específica de React, junto con una biblioteca de utilidades de fechas. (La biblioteca ya está incluida en el proyecto y no es necesario instalarla.)

npm install react-calendar-heatmap date-fns

Crear el esqueleto del componente de mapa de calor

Comenzaremos creando la estructura básica de nuestro componente de mapa de calor sin ninguna funcionalidad.

Funcionalidad:

  • Crear un nuevo archivo para el componente de mapa de calor.
  • Definir el componente funcional con contenido de marcador de posición.

Código:

// src/GitHubCalendar.js
import React from "react";

const GitHubCalendar = () => {
  return (
    <div>
      {/* Marcador de posición para el mapa de calor */}
      <div>El mapa de calor irá aquí</div>
    </div>
  );
};

export default GitHubCalendar;
✨ Revisar Solución y Practicar

Agregar estado para el filtrado

Antes de poblar nuestro mapa de calor, agreguemos un poco de estado para manejar el filtrado de datos basado en la interacción del usuario.

Funcionalidad:

  • Importar el hook useState.
  • Inicializar la variable de estado colorFilter.

Código:

// src/GitHubCalendar.js
import React, { useState } from "react";

const GitHubCalendar = () => {
  const [colorFilter, setColorFilter] = useState(null);

  return (
    <div>
      {/* Marcador de posición para el mapa de calor */}
      <div>El mapa de calor irá aquí</div>
    </div>
  );
};

export default GitHubCalendar;
✨ Revisar Solución y Practicar

Generar datos ficticios

Generar datos ficticios para simular la actividad. Lo reemplazaremos con datos reales en una aplicación del mundo real.

Funcionalidad:

  • Utilizar date-fns para crear un rango de fechas.
  • Poblar una matriz con datos ficticios para cada día.

Código:

// src/GitHubCalendar.js
import { subYears, isBefore, format } from "date-fns";

// Agregar dentro del componente GitHubCalendar
const startDate = subYears(new Date(), 1);
const endDate = new Date();
const values = [];
let currentDate = startDate;

while (isBefore(currentDate, endDate)) {
  values.push({
    date: format(currentDate, "yyyy-MM-dd"),
    count: Math.floor(Math.random() * 5)
  });
  currentDate = new Date(currentDate.setDate(currentDate.getDate() + 1));
}
✨ Revisar Solución y Practicar

Renderizar el mapa de calor del calendario

Ahora incluiremos el componente CalendarHeatmap y le pasaremos nuestros datos ficticios.

Funcionalidad:

  • Renderizar el mapa de calor con datos.
  • Definir una escala de colores basada en la cuenta.

Código:

// src/GitHubCalendar.js
import CalendarHeatmap from "react-calendar-heatmap";
import "react-calendar-heatmap/dist/styles.css";

// Agregar dentro del retorno del componente GitHubCalendar
<CalendarHeatmap
  startDate={startDate}
  endDate={endDate}
  values={values}
  classForValue={(value) => {
    if (!value || value.count === 0) {
      return "color-empty";
    }
    return `color-scale-${value.count}`;
  }}
  showWeekdayLabels={true}
/>;
✨ Revisar Solución y Practicar

Implementar la lógica de filtrado

Crear botones para cada nivel de actividad que filtrarán el mapa de calor cuando se hagan clic en ellos.

Funcionalidad:

  • Agregar botones que establecen el estado colorFilter.
  • Filtrar los datos del mapa de calor según el filtro seleccionado.

Código:

// src/GitHubCalendar.js
// Agregar debajo del componente CalendarHeatmap en el retorno del componente
<div className="filter-bar">
  {Array.from({ length: 5 }, (_, i) => (
    <button
      key={i}
      className={`filter-btn color-scale-${i}`}
      onClick={() => setColorFilter(colorFilter === i ? null : i)}
    >
      Filtrar {i}
    </button>
  ))}
</div>
✨ Revisar Solución y Practicar

Dar estilo al componente

Definir el CSS para el mapa de calor y los botones de filtrado para comunicar visualmente los datos.

Funcionalidad:

  • Agregar reglas CSS para los colores del mapa de calor y el estilo de los botones.

Código:

/* src/App.css */
/* Agrega tus reglas CSS aquí */
.color-empty {
  fill: #ebedf0; /* Sin contribuciones - color blanco */
}
.color-scale-0 {
  fill: #ebedf0; /* Verde más claro - Cambia esto a tu verde más claro */
}
.color-scale-1 {
  fill: #9be9a8; /* Verde claro */
}
.color-scale-2 {
  fill: #40c463; /* Verde medio */
}
.color-scale-3 {
  fill: #30a14e; /* Verde oscuro */
}
.color-scale-4 {
  fill: #216e39; /* Verde más oscuro */
}

.filter-bar {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.filter-btn {
  background: none;
  border: 2px solid transparent;
  margin: 0 5px;
  padding: 5px 10px;
  cursor: pointer;
  transition:
    background-color 0.3s,
    border-color 0.3s;
}

/* Aplica los mismos colores a los botones de filtrado */
.filter-btn.color-scale-0 {
  border-color: #ebedf0;
}
.filter-btn.color-scale-1 {
  border-color: #9be9a8;
}
.filter-btn.color-scale-2 {
  border-color: #40c463;
}
.filter-btn.color-scale-3 {
  border-color: #30a14e;
}
.filter-btn.color-scale-4 {
  border-color: #216e39;
}

.filter-btn:hover,
.filter-btn:focus {
  background-color: #ddd;
}

.reset {
  border-color: #000; /* Color del borde del botón de restablecimiento */
}

/* Destaca el filtro activo */
.filter-btn.active {
  border-color: #666; /* Color del borde del botón activo */
  font-weight: bold;
}

Réfierase a los ejemplos de CSS anteriores para obtener orientación sobre la configuración de las escalas de colores y los estilos de los botones.

✨ Revisar Solución y Practicar

Ensamblar la aplicación

Integrar el componente del mapa de calor en tu archivo principal de la aplicación.

Funcionalidad:

  • Importar el componente GitHubCalendar en App.js.
  • Renderizar el componente GitHubCalendar en la aplicación.

Código:

// src/App.js
import React from "react";
import "./App.css";
import GitHubCalendar from "./GitHubCalendar";

function App() {
  return (
    <div className="App">
      <GitHubCalendar />
    </div>
  );
}

export default App;
✨ Revisar Solución y Practicar

Lanzar la aplicación

Con todos los componentes en su lugar, es hora de ver en acción tu calendario de mapa de calor.

Funcionalidad:

  • Ejecutar la aplicación y ver el calendario de mapa de calor.

Comandos:

npm start

Esto compilará la aplicación de React y la abrirá en tu navegador web predeterminado en el puerto 8080.

Resumen

¡Felicidades! Acabas de crear una aplicación de React que incluye un calendario de mapa de calor similar al gráfico de contribuciones de GitHub. Comenzando con la inicialización del proyecto, instalaste las bibliotecas necesarias, creaste un componente de mapa de calor, implementaste la funcionalidad de filtrado y le diste estilo al componente. Este proyecto proporcionó un enfoque paso a paso para construir un componente de interfaz de usuario complejo en React, que se puede adaptar para mostrar varios tipos de datos de series de tiempo o actividad de usuario.