Creación de la lógica del gráfico
Clase 14 de 21 • Curso Práctico de Vue.js
Contenido del curso
Guillermo Castaño Vèlez
Jose Morales Varon
Josue Cerron Tuesta
Fabian Esteban Duran Avellaneda
Miguel Angel Reyes Moreno
Angel David Velasco Bonifaz
Diana Martinez
Eduardo Esteban Álvarez Castañeda
Eduardo Torres
Jesús Daniel González Alemán
Josue Donaldo Ramirez Marquez
Santiago Jimenez Moncada
Argeliandris Rincón
Jesner Wilian Ramirez Cueva
Carlos Rodríguez
Gerardo Pérez Pérez
Ojo no voy a decir que la explicación esta mal, pero este ejercicio siempre me recuerda que los profesores de programación en general tiene muy mala metodología al explicar la lógica.. por lo menos desde mi forma de aprender.. un dibujito de vez en cuando para mostrar los pasos del programa no sobra, y da un mejor panorama de lo que va a pasar
Tienes mucha razón.
Con una ilustración hubiera sudo mejor!
Prefiero usar librerías que permite crear los gráficos, ya que la lógica ya esta establecida. Me pareció muy enredada la explicación para la creación de este tipo de componentes.
Ejercicios de porcentajes explicados por Julio Profe
Lo realice más fácil, respetando que si todos los valores son positivos, partan de 0, o negativos, igual partan de 0. les dejo mi codigo.
Graphic.vue
<template> <div> <svg viewBox="0 0 300 200"> <line stroke="#c4c4c4" stroke-widt="2" x1="0" :y1="minmax * max" x2="300" :y2="minmax * max" /> <polyline fill="none" stroke="#0689B0" stroke-widt="2" :points="points" /> <line stroke="#04b500" stroke-widt="2" x1="200" y1="0" x2="200" y2="200" /> </svg> <p>Ultimos 30 días</p> <div>{{ points }}</div> </div> </template> <script setup> import { toRefs, defineProps, computed } from "vue"; const props = defineProps({ amounts: { type: Array, default: () => [], }, }); const { amounts } = toRefs(props); //minimo por si todos los valores son positivos desde abajo sea 0 const min = Math.min(...amounts.value) < 0 ? Math.min(...amounts.value) : 0; //maximo por si todos los valores son negativos desde arriba sea 0 const max = Math.max(...amounts.value) > 0 ? Math.max(...amounts.value) : 0; //el factor para saber el numero de pixeles sobre el monto en altura const minmax = 200 / (max - min); //funcion que retorna la posicion en y de 0 a 200 const amountToPixels = (amount) => { return (max - amount) * minmax; }; const points = computed(() => { const total = amounts.value.length; const xInterval = 300 / total; const media = xInterval / 2; return amounts.value.reduce((points, amount, index) => { const x = xInterval * index + media; const y = amountToPixels(amount); console.log(y); return `${points} ${x},${y}`; }, ""); }); </script>
Hola, sin duda el componente del gráfico es el más interesante pero también el más complicado del curso, si sienten que es demasiado para ustedes, no hay ningún problema en saltarse hasta las clases del próximo componente si es necesario.
Recuerden que siempre pueden tomar el código del repositorio del curso si es necesario.
Creo que toda esta sección está de más, ya que lo que se está viendo, no es Vue como tal, sino que como usar JavaScript para graficar usando SVG. Creo que podría ser más interesante, que en este mismo proyecto, hubiésemos consumido una API con valores dummy y así usar alguna librería que los grafique (en el mundo laboral o vida real, el uso de librerías de terceros es imprescindible)
Comparto mi solución
const amountToPixels = (amount) => { const min = Math.min(...amounts.value); const max = Math.max(...amounts.value); const absMax = Math.abs(max) > Math.abs(min) ? Math.abs(max) : Math.abs(min); const percentage = Math.round((Math.abs(amount) / absMax) * 100); const y = amount < 0 ? 100 + percentage : 100 - percentage; return `${y}`; };
Explicación de la parte matemática:
La distancia entre los números quiere decir cuantos números hay entre -500 y 200 por ejemplo y para eso hay que sumarlos en valor absoluto y el valor absoluto simplemente es que sean todos los números en positivo.
Entonces sacamos minmax que es la cantidad total que tenemos.
Luego tenemos amountAbs que para sacar un porcentaje es la división entre una parte de una cantidad entre todo lo que hay ejemplo: una clase de 40 niños cuál es el porcentaje si solo cogemos 20 ,pues seria 20/40 que da 1/2 y esto es 0.5 y si lo multiplcas por 100 da 50% y ya tenemos el porcentaje.
Qué ocurre, que los pixeles que tenemos no son 100px sino que son 200px asi que para cuadarlo en el gráfico lo multiplicamos por 2 porque lo que se intenta con esto es que la gráfica representa un valor cualquiera dentro del rectángulo gráfico transformando la cantidad total de 0-100 que es un porcentaje.
Gracias por sus comentarios mataron el video
por que no utilizamos una libreria de graficas y listo? saben cuantos estudiantes va a salir corriendo despues de esta clase!
Pero si no hay nada de extrema complicación en las clases del gráfico en svg, más bien esta genial que explique al menos detalles básicos de los polyline y lines. Los estudiantes curiosos y que realmente tienen ansias de aprender muy probablemente se sientan satisfechos con estas clases!
en tono de broma*** El que tenga miedo de morir mejor que no viva jajajajajaja
Esta función es mucho más sencilla:
const amountToPx = (amount) => { const min = Math.min(...amounts.value); const max = Math.max(...amounts.value); return 200 - ((amount - min) / Math.abs(max - min)) * 200; };
.
Recordar que deben agregar el valor inicial al .reduce con su pixel en la posición cero:
const x0 = amountToPx(amounts.value[0]); return amounts.value.reduce(() => { // code }, `0,${x0}`);
Les comparto mi funcion para normalizar
type Range ={min: number, max:number} export function normalizeRange (from: Range, to: Range) { const fromHeight = Math.abs(from.max - from.min) // 16 const toHeight = Math.abs(to.max - to.min) // 200 return function normalizeRange (value: number) { // Movemos movemos el valor para hacerlo relativo a cero const valueFromZero = (value - from.min) // 16 // Obtenemos el porcentage relativo al tamaño del origen const valuePercentage = valueFromZero / fromHeight // 1 // Convertimos a los valores del target const targetSize = valuePercentage * toHeight // 200 // Agregamos el offset de min const result = targetSize + to.min // 200 return result } } // uso const yNormalizer = normalizeRange({ min, max }, { min: 0, max: 200 }) const y = yNormalizer(amount)