No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripción 🔥

Aprende todo un fin de semana sin pagar una suscripción 🔥

Regístrate

Comienza en:

5D
16H
46M
22S
Curso Profesional de Next.js

Curso Profesional de Next.js

Oscar Barajas Tavares

Oscar Barajas Tavares

Implementación de nuestro componente Chart en el dashboard

18/31
Recursos

Aportes 16

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Clase #18: Implementación de nuestro componente Chart en el dashboard 18/31 📊



 

Método reduce:

 

El método reduce() aplica una función a un acumulador y a cada valor de una array (de izquierda a derecha) para reducirlo a un único valor. Fuente: aquí

 
La sintaxis es: arr.reduce(callback(accumulator, currentValue), initialValue)
 
Donde arr es un arreglo no vacío; callback es la función que se ejecuta con cada valor del arreglo (excepto el primer valor si no se indica el valor inicial); accumulator como su nombre lo dice es el encargado de guardar o acumular los valores por cada llamada de la función callback; currentValue es el valor actual que se pasa desde el arreglo; initialValue es opcional, en caso de que no se indique, el método seleccionará al primer valor del arreglo como valor inicial y actuará como acumulador en la primera llamada de la función callback.
 
Ejemplo: tenemos una array con costos y las función consiste en una suma:

const number = [1800, 50, 300, 20, 100] 
//Éste es el arr

function sum_reducer(accumaltor, currentValue) {
	return accumulator + currentValue;
} //La función sum_reduce es la función callback

let sum = numbers.reduce(sum_reduce) //no se especifica el initialValue

/*El resultado de sum es 21 porque 1800 se convirtió en el initialValue y por lo tanto el accumulator y 50 el currentValue, luego la suma de 1800 + 50 = 1850 se convierte en el accumulator y el siguiente número 300 se convierte en currentValue y así hasta sumar todos los elementos del array*/

let summation = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, initialValue);
/*En caso de que indiquen un valor inicial por ejemplo initialValue = 10, el primer elemento 1800 sería el currentValue y el resultado final sería 31:*/

 

Operadores de incremento con b= ++a; y b = a++;

 
Es importante recordar cómo funcionan el operador de incrementar y las posiciones de lado izquierdo y derecho y cómo afectan a las variables. Fuente: aquí
 
Ejemplo:

let x = 3;
const y = x++; //Aquí primero asigna el valor de 'x' a 'y', luego incrementa 'x' en uno
console.log(`x:${x}, y:${y}`);
// output: "x:4, y:3"

let x = 3;
const x = ++y; //Aquí primero incrementa en uno a 'x' y luego asigna a 'y' el valor de 'x'
console.log(`x:${x}, y:${y}`);
// output: "a:4, b:4"

 

Continuando con el Proyecto: 🔨

 
Ir a VSC al archivo index.js de la ruta src/pages/dasboard, vamos a eliminar la constante people, como queremos mostrar las barras de los gráficos hacemos el import de Chart con:

import { Chart } from '@common/Chart'

 
Dentro del return, antes del primer div se agrega la etiqueta <Chart /> con la clase que indica que se le agrega 2 rem de margin bottom: “mb-8” y 0.5 rem de margin top: "mt-2" (Fuente: aquí):

<Chart className="mb-8 mt-2" chartData={data} />

 
Antes del return y dentro de la función Dashboard() la lógica queda:

//Con categoryNames se conoce cuántos elementos están dentro de las categorías
  const categoryNames = products?.map((product) => product.category);
  //Con categoryCount se conocen los nombres de las categorías
  const categoryCount = categoryNames?.map((category) => category.name);

  /* console.log(categoryNames);
  console.log(categoryCount);*/

  //Con countOcurrences se conoce el número de ocurrencias (frecuencia) que aparece cada categoría
  //Lógiga constante = (array, value) => array.reduce((a,v) => (v === value? a + 1: a), 0);
  const countOcurrences = (arr) => arr.reduce((prev, curr) => ((prev[curr] = ++prev[curr] || 1), prev), {});
  /* console.log(countOcurrences(categoryCount)) */
  //El objeto data contiene la información necesaria para el gráfico
  const data = {
    datasets: [
      {
        label: 'Categories',
        data: countOcurrences(categoryCount),
        borderWidth: 2,
        backgroundColor: ['#ffbb11', '#c0c0c0', '#50AF95', '#f3ba2f', '#2a71d0'],
      },
    ],
  };

 
Dato importante: cómo realizar la operación de reduce en countOcurrences:

//Si colocamos solo 3 productos para mostrar en el dashboard

const categoryNames = products?.map((product) => product.category);

/*La salida de categoryNames nos trae toda la información por cada producto
(3) [{…}, {…}, {…}]
        1. 0: {id: 1, name: 'Clothes', image: 'https://api.lorem.space/image/fashion?w=640&h=480&r=3714'}
        2. 1: {id: 3, name: 'Furniture', image: 'https://api.lorem.space/image/furniture?w=640&h=480&r=9014'}
        3. 2: {id: 3, name: 'Furniture', image: 'https://api.lorem.space/image/furniture?w=640&h=480&r=9014'}
        4. length: 3
        5. [[Prototype]]: Array(0)
*/

const categoryCount = categoryNames?.map((category) => category.name);

/*Con categoryCount se obtiene un arreglo con todas las categorías en este caso de 3 productos
(3) ['Clothes', 'Furniture', 'Furniture']
        1. 0: "Clothes"
        2. 1: "Furniture"
        3. 2: "Furniture"
        4. length: 3
        5. [[Prototype]]: Array(0)

*/


const countOcurrences = (arr) => arr.reduce((prev, curr) => ((prev[curr] = ++prev[curr] || 1), prev), {});

/*Con countOcurrences para estos 3 productos tenemos que el array es {Clothes, Furniture, Furniture}
     0        1         2
Función: (prev[curr] = ++prev[curr] || 1)

Para la primera iteración:
prev = {} es vacío porque se le indicó con llaves {}
curr = {Clothes}
La función: si {} == Clothes entonces {Clothes} se incrementa en 1 si no se crea {Clothes : 1}, en este caso se cumplió el lado derecho y se crea 1 Clothes

Para la segunda iteración:
prev = {Clothes : 1} así quedó en la primera iteración
curr = {Furniture}
La función: ¿En {Clothes : 1} hay un Furniture? Como no hay, entonces  se crea y agrega { Furniture : 1}, se cumplió el lado derecho

Para la tercera iteración:
prev = {Clothes : 1, Furniture : 1} así quedó en la segunda iteración
curr = {Furniture}
La función: ¿En {Clothes : 1, Furniture : 1} hay un Furniture? Como si hay, entonces  se incrementa Furniture { Furniture : 2}, se cumplió el lado izquierdo */

console.log(countOcurrences(categoryCount));
//La salida queda: {Clothes : 1, Furniture : 2}

 

Si quieren que sirva lo de legend, lo deben pasar por dentro de plugins: { legend {…}}, así dice los docs

una cosa es saber y otra totalmente distinta es enseñar, deben evaluar que tipo de estrategias son más pedagógicas para facilitar el aprendizaje tienen dev´s muy buenos pero eso no lo hace buenos profes.

Muy buena la librería chart-js!! 👌

Alguien podrìa explicarme como se está implementando Reduce en esta clase? La verdad es que no se explicó para nada… estoy muy confundido

Hace tiempo me mentalice que estos cursos eran para tener una idea general de cómo funcionan estás tecnologías, de esta forma no se me hace tan frustrante verlos, porque la verdad es que no explica nada…

Podemos usar el siguiente código para hacerlo de manera más legible reducir un arreglo que tiene elementos repetidos para obtener otro arreglo con los elementos apareciendo una sola vez en dicho array:
.

const categories = Array.from(new Set([
    "categoria-1",
    "categoria-1",
    "categoria-1",

    "categoria-2",
    "categoria-2",
    "categoria-2",

    "categoria-3",
    "categoria-3",
    "categoria-3",
]))

console.log(categories)

//output: ["categoria-1", "categoria-2", "categoria-3"]

.
En el código del proyecto sería algo así:
.

const categories =  new Set(categoryCount);
//Luego "categories" se utiliza como data

.
Espero a haber ayudado😁💚

El “offset” en la primera paginación prefiero ponerlo en 0 para que empiece a hacer fetch desde el elemento 0 del array.

Muy genial esta clase

Si alguien tiene en error en la parte de Chart.register(), cambielon a chartJS.register().

Me estoy rompiendo la cabeza por no poder entender por que tengo este error:

la parte del codigo correspondiente esta tal cual la hizo Oscar:

 const categoryNames = products?.data.map((product) => product.category);
  const categoryCount = categoryNames?.map((category) => category.name);

Lo mas raro, es que cuando comento ambas lineas, y las voy descomentando una a la vez, no me tira ese error, pero no me muestra el dashboard. En el momento que refresco la pagina, nuevamente aparece este error.
Ayuda por favor 😦

Más Simple?


.
Para hacer más comprensible la lógica para contar la frecuencia de ocurrencia de cada categoría, he simplificado el callmack del método reduce de las siguiente manera:
Recuerden que también se puede acceder al valor de una clave en un objeto de esta manera:

  • objectName[keyName]
  //Logic for the chart
  const categoryNames = products?.map((product) => product.category.name);

  const reducer = (acumulatorObject, current) => {
      if  ( acumulatorObject[current] ) {
        acumulatorObject[current] += 1 //Si la categoria actual 'current' ya existía en el objeto acumulador, entonces incrementamos uno a su valor.
      } else {
        acumulatorObject[current] = 1 //Si no existía, creamos la clave y le asignamos el valor de uno.
      }
      return acumulatorObject; //retornamos el objeto acumulador actualizado.
  };
  const categoryOccurence = categoryNames.reduce(reducer, {})

  const data = {
    datasets: [
      {
        label: 'Categories',
        data: categoryOccurence,
        borderWidth: 2,
        backgroundColor: ['#d32244', '#c0c0c0', '#50AF95', '#f3ba2f', '#2a71d0'],
      },
    ],
  };

Gracias a los compañeros cuyos comentarios anteriores y me ayudaron a entenderlo 😃

también podemos evitarnos crear un nuevo array en una nueva linea de código de esta forma

const categories = products?.map(product => product?.category).map(category => category.name);

y lo pasaríamos igual

const data = {
    datasets: [{
    label: 'Categories',
    data: countOccurrences(categories), // **
    borderWidth: 2,
    backgroundColor: ['#ffbb11','#c0c0c0', '#50AF95', 'f3ba2f', '#2a71d0']
    }]
}

o incluso evitarnos crear un nuevo arreglo y una nueva funcion, de esta forma

const categories = products?.map(product => product?.category).map(category => category.name).reduce((prev, curr) => ((prev[curr] = ++prev[curr] || 1), prev), {});

y lo pasaríamos así

const data = {
    datasets: [{
    label: 'Categories',
    data: categories,
    borderWidth: 2,
    backgroundColor: ['#ffbb11','#c0c0c0', '#50AF95', 'f3ba2f', '#2a71d0']
    }]
}

Chart.js

Creo que la API debería resetearse a la data por default, si es que hay alguna manera. No se si la gente lo hará con intención pero con tanta data basura se termina dañando la misma API para los ejemplos.