diff --git a/README.md b/README.md index e9b59c4c..91653fe6 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,77 @@ # Data Dashboard -* **Track:** _Common Core_ -* **Curso:** _Creando tu primer sitio web interactivo_ * **Unidad:** _Producto final_ *** +## Squad AukaCoders +* Victoria Lung +* Isabelle Chávez +* Edith Jurado +* Nathaly Otero Celis +* Ada Yajahuanca +* Annie Gutierrez +* Vanessa Colqui +* Maria Cristina Ortiz +* Pamela Rojas +*** + +## Descripción General +Es una representación gráfica de los indicadores clave (KPI) que intervienen en la consecución de los objetivos de negocio(Laboratoria), y que está orientada a la toma de decisiones para optimizar la estrategia de la empresa. Un dashboard debe transformar los datos en información y que estos estén en conocimiento para el negocio(Laboratoria). + +## Objetivo + +Construir una herramienta web donde las **TMs** de Laboratoria puedan ver los datos de manera fácil y rápida con respecto al desempeño de las estudiantes, para poder analizarlos, posteriormente emitir conclusiones, y así poder apoyar a las alumnas en su aprendizaje. Estos son los datos(indicadores Kpi) que revisan normalmente, los cuales debemos mostrarlos con una representación gráfica adecuada (ordenado y limpio) para que se pueda visualizar, contextualizar y comparar datos: + +* El total de estudiantes presentes por sede y generación. +* El porcentaje de deserción de estudiantes. +* La cantidad de estudiantes que superan la meta de puntos en promedio de todos los sprints cursados. La meta de puntos es 70% del total de puntos en HSE y en tech. +* El porcentaje que representa el dato anterior en relación al total de estudiantes. +* El Net Promoter Score (NPS) promedio de los sprints cursados. +* La cantidad y el porcentaje que representa el total de estudiantes que superan la meta de puntos técnicos en promedio y por sprint. +* La cantidad y el porcentaje que representa el total de estudiantes que superan la meta de puntos de HSE en promedio y por sprint. +* El porcentaje de estudiantes satisfechas con la experiencia de Laboratoria. +* La puntuación promedio de las profesores. +* La puntuación promedio de las jedi masters. + +## Desarrollo + +ETAPAS DEL DESARROLLO DEL PRODUCTO: + +* **ETAPA UNO: DISEÑO DE LA EXPERIENCIA (UX UI)** + +A partir de la necesidad de las TMs de Laboratoria de analizar datos de una manera más sencilla y práctica, nació como alternativa a esta problemática, la idea de desarrollar un **Dashboard** que simplifique dicha tarea mediante la presentacion de gráficos y datos(indicadores KPI) concisos y precisos. Para ello se hizo el siguiente esquema: + + - Elaboración de Sketch (prototipo sencillo) sobre de la herramienta web(**dashboard**). + + + ![sketch](assets/images/sketch.png) + + + - Testeo del prototipo para modificar o agregar cambios según la necesidad de las TMs: + + + ![sketch](assets/images/email.png) + + + **Feedback de TMs Lulú Vilchez:** + + * Enfocarnos en la obtención de datos de la sede Lima y las tres generaciones que la componen. + + + **ETAPA DOS: DESARROLLO (Frond end y Back End)** + + Etapa de elaboración del producto en código. Se realizó lo siguientes: -## Flujo de trabajo + - Se creó un Archivo HTML donde figura: **header** (logo de laboratoria), **nav** ( barra de navegación: sedes y generaciones (contenida en una etiqueta **selection. my-select** a quien se le aplicará el EVENTO UNO: CHANGE), students y teachers), **section. dispplay-none** (Se encuentra toda la información concerniente a los indicadores solicitados a mostrar. Dicha sección se encuentra con la propiedad ** display: none** para que cuando apliquemos en el evento **change** a la etiqueta selection ** SEDE Y GENERACIONES**, aparezca la section. También se encuentra los filtros para TECH SKILLS y LIFE SKILLS a quien se les aplicara el EVENTO DOS:CHANGE ). -1. Debes realizar un [**fork**](https://gist.github.com/ivandevp/1de47ae69a5e139a6622d78c882e1f74) - de este repositorio. + - Se creó un archivo **main.css** donde se encuentran todos los estilos aplicados a todas la partes del body del documento HTML. No hubo la necesidad de crear estilos para los eventos ya que no se creo ningun elemento en el DOM. -2. Luego deberás **clonar** tu fork en tu máquina. Recuerda que el comando a usar - es `git clone` y su estructura normalmente se ve así: + - Se creó dos archivo **javascript** : **"app.js"** donde se encuentran todos los eventos aplicados ( _change_ ) a la etiqueta **select. my-select** que se encuentra en la etiqueta **nav**, a las etiquetas **select.select-sprint-life** y **select.select-sprint-tech** que se encuentran en la etiqueta **section. display-none**; y el archivo **graphic.js** donde se encuentran las funciones generales(globales) de las gráficas ingresadas utilizando la herramienta **"Google Charts"**, las cuales son llamadas en los eventos aplicados en **app.js**. - ```bash - git clone https://github.com//freelancer.git - ``` + **ETAPA TRES: CRECIMIENTO** -3. Cuando hayas terminado tu producto, envía un Pull Request a este repositorio - (puedes solicitar apoyo de tus profes para este paso). + En esta etapa se probará el producto desarrollado y terminado para recibir un nuevo feed back, y seguir mejorándolo según las necesidades del cliente. -> Nota: No olvides que es una buena práctica describir tu proyecto en este -> archivo `README.md` y también desplegar tu web a Github Pages :smiley:. + ![sketch](assets/images/dashboard.jpg) + + *** diff --git a/assets/images/dashboard.jpg b/assets/images/dashboard.jpg new file mode 100644 index 00000000..a2e0802d Binary files /dev/null and b/assets/images/dashboard.jpg differ diff --git a/assets/images/email.png b/assets/images/email.png new file mode 100644 index 00000000..de3f6fd0 Binary files /dev/null and b/assets/images/email.png differ diff --git a/assets/images/sketch.png b/assets/images/sketch.png new file mode 100644 index 00000000..f5131937 Binary files /dev/null and b/assets/images/sketch.png differ diff --git a/css/main.css b/css/main.css index 6355c827..744ebaf3 100644 --- a/css/main.css +++ b/css/main.css @@ -1,3 +1,109 @@ -/* - * Estilos de tu proyecto - */ +/*SETEAR NUESTROS ARCHIVOS: SEA IGUAL PARA TODOS LOS NAVEGADORES*/ +* { + box-sizing: border-box; + font-family: 'Montserrat', sans-serif; + margin: 0; + padding: 0; +} +/* CLASES REUTILIZABLES*/ +/* nuevo*/ +.select-sprint {/* Etiqueta select(filtros para tech skills y life skills)*/ + font-size: 14px; + margin-left: 5px; + margin-bottom: 10px; + border-bottom: 3px solid rgb(255, 165, 0); +} +.tech-skills, .life-skills {/* div de los contenedores TECH SKILLS Y LIFE SKILLS*/ + display: inline-block; + vertical-align: middle; + margin:5px; + margin-left: 20px; + width: 45%; + position: relative; + bottom: 50px; +} +.filter-skills {/* div del contenedor de los filtros de TECH SKILLS Y LIFE SKILLS*/ + display: inline-block; + position:relative; + bottom:70px; + left:110px; +} +.value-skills {/* div que contienen los valores de TECH Y LIFE SKILLS*/ + position: relative; + bottom: 130px; +} +/* ESTILOS AL BODY*/ +body { + width: 100%; + background: #A4A4A4 ; +} +/* ESTILOS AL HEADER*/ +header{ + width: 20%; + margin: 15px auto; +} +/* Estilos a la barra de menu**/ +#navbar{ + margin-top: 15px; + padding: 20px; + background-color: white; +} +/* Estilos al filtro de la barra de menu*/ +select{ + outline: none; + border: none; + font-size: 20px; + margin-left: 10px; +} +/* ESTILOS A SECTION DE CLASE "DISPLAY NONE"*/ +section.display-none { + display: none; +} +section.container { + width: 85%; + height: 100; + margin: 100px 0 0 108px; + padding: 100px 45px;/* nuevo*/ + background-color: rgb(220, 220, 220); +} +section.container div.container { + margin:10px 60px; + text-align: center; + /*float: left;*/ +} +section.container div.container div.indicators-container { + width: 31.3%; + display: inline-block; + margin: 10px; + background-color: #fff; +} +section.container div div div.text, section.container div.skills div.text { + margin: 20px; + font-weight: 700; + font-size: 20px; +} +section.container div div div.value, section.container div.skills div.value { + margin: 10px; + display: inline-block; + width: 43%; + padding: 10px; + background-color: rgb(220, 220, 220); + font-size: 15px; + border-radius: 10px; +} +section.container div.skills { + margin:30px 67px; + background-color: #fff; + padding: 10px; + padding-bottom: 0; + width: 88,5%; +} +section.container div.skills div.text { + width: 15%; + margin-bottom: 5px; + margin-left: 20px; +} +section.container div.skills div.value { + width: 25%; + margin: 10px 21px; +} diff --git a/index.html b/index.html index 8930fa03..b9518ad0 100644 --- a/index.html +++ b/index.html @@ -1,14 +1,116 @@ - - - - - Data Dashboard - - - - - - - - - + + + + + + + Data Dashboard Laboratoria + + + + +
+ +
+ + + + + + + + + + diff --git a/js/app.js b/js/app.js index 895ae2dd..76e95a50 100644 --- a/js/app.js +++ b/js/app.js @@ -1,6 +1,745 @@ -/* - * Funcionalidad de tu producto - */ - -// Puedes hacer uso de la base de datos a través de la variable `data` -console.log(data); +window.addEventListener('load', function(event) { + var selectGeneration = document.getElementById('mySelect'); + var section = document.getElementById('section-display-none'); + /* Accediendo a los divs vacios dodne agregaremos los valores de los indicadores*/ + var enrolled = document.getElementById('enrolled'); + var dropout = document.getElementById('dropout'); + var achievement = document.getElementById('achievement'); + var achievementPercent = document.getElementById('achievement-percent'); + var cumulativeNps = document.getElementById('cumulative-nps'); + var techSkills = document.getElementById('tech-skills'); + var techSkillsPercent = document.getElementById('tech-skills-percent'); + var lifeSkills = document.getElementById('life-skills'); + var lifeSkillsPercent = document.getElementById('life-skills-percent'); + var studentSatisfaction = document.getElementById('student-satisfaction'); + var teacherRating = document.getElementById('teacher-rating'); + var jediMasterRating = document.getElementById('jedi-master-rating'); + /* Accediendo a los filtros por sprint*/ + var selectSprintTech = document.getElementById('select-sprint-tech'); + var selectSprintLife = document.getElementById('select-sprint-life'); + /* EVENTO CHANGE PARA EL FILTRO POR GENERACIONES*/ + selectGeneration.addEventListener('change', showGeneration); + // Funcion para llenar la cantidad de alumnos desertores + function showGeneration(event) { + function countOff(obj) { + var counter = 0; + for (var i = 0; i < arrStudent.length; i++) { + if (arrStudent[i]['active'] === false) { + counter++; + } + } + return Math.round(100 * counter / arrStudent.length) + '%'; + } + function countProm(obj) { + var promedioMinimo = 2100; + var counter = 0; + var arrPromStudent = []; + var arrProm = []; + for (var i = 0; i < arrStudent.length; i++) { + if (arrStudent[i]['active'] === true) { + for (var x = 0; x < arrStudent[0]['sprints'].length; x++) { + var arr = Object.values(arrStudent[i]['sprints'][x]['score']); + var sum = (arr[0] + arr[1]); + arrProm.push(sum); + } + } + } + for (var z = 0; z < arrProm.length; z += 4) { + var studentSprint = (arrProm[z] + (arrProm[z + 1]) + (arrProm[z + 2]) + (arrProm[z + 3])) / 4; + arrPromStudent.push(studentSprint); + } + for (var y = 0; y < arrPromStudent.length; y++) { + if (arrPromStudent[y] > promedioMinimo) { + counter++; + } + } + return counter; + } + // Funcion para obtener el porcentaje de satisfacción por generación + function studentsSatisfaction(obj) { + var arrSatisfaction = []; + var prome = 0; + for (var i = 0; i < rating.length; i++) { + var sum = rating[i]['student']['cumple'] + rating[i]['student']['supera']; + arrSatisfaction.push(sum); + } + for (var m = 0; m < arrSatisfaction.length; m++) { + prome += arrSatisfaction[m]; + } + return prome / rating.length + '%'; + } + // Función para promediar puntaje de profesores + function teacherProm(obj) { + var arr = []; + var prome = 0; + for (var i = 0; i < rating.length; i++) { + arr.push(rating[i]['teacher']); + } + for (var x = 0; x < arr.length; x++) { + prome += arr[x]; + } + return Math.round(prome / rating.length); + } + // Función para promediar puntaje de Jedis Masters + function jdProm(obj) { + var arr = []; + var prome = 0; + for (var i = 0; i < rating.length; i++) { + arr.push(rating[i]['jedi']); + } + for (var x = 0; x < arr.length; x++) { + prome += arr[x]; + } + return Math.round(prome / rating.length); + } + // Función para promediar nps + function nps(obj) { + var arr = []; + var prome = 0; + for (var i = 0; i < rating.length; i++) { + arr.push(rating[i]['nps']['promoters'] - rating[i]['nps']['detractors']); + } + for (var x = 0; x < arr.length; x++) { + prome += arr[x]; + } + return Math.round(prome / rating.length); + } + switch (true) { + case event.target.value === 'lima2016II': + // Llenar la cantidad de alumnos por generación y sede + section.classList.remove('display-none'); + /* Llamando a la funcion de la GRAFICO ENROLLMENT (ver graphics.js, line:3)"aqp2016II"*/ + // FALTA CAMBIAR LOS PARAMETROS + enrollmentGraphic(10, 124); + /* Llamando a la funcion de la GRAFICO ACHIEVEMENT (ver graphics.js, line:4)"aqp2016II"*/ + achievementGraphic(15, 50); + /* Llamando a la funcion de la GRAFICO NET PROMOTER SCORE(ver graphics.js, line:37)"aqp2016II"*/ + netPromoterScoreGraphic(20, 50, 17); + /* Llamando a la funcion de la GRAFICO TECH SKILLS (ver graphics.js, line:56)"aqp2016II"*/ + techSkillsGraphic(18, 30); + /* Llamando a la funcion de la GRAFICO TECH SKILLS por sprints(ver graphics.js, line:73)"aqp2016II"*/ + techSkillsSprintsGraphic(15, 5, 6, 10); + /* Llamando a la funcion de la GRAFICO LIFE SKILLS (ver graphics.js, line:110)"aqp2016II"*/ + lifesSkillsGraphic(14, 18); + /* Llamando a la funcion de la GRAFICO TECH SKILLS por sprints(ver graphics.js, line:127)"aqp2016II"*/ + lifeSkillsSprintsGraphic(5, 6, 7, 8); + /* Llamando a la funcion de la GRAFICO STUDENTS SATISFACTION (ver graphics.js, line:163)"aqp2016II"*/ + studentSatisfactionGraphic(3, 5, 7, 10); + /* Llamando a la funcion de la GRAFICO TEACHER RATING(ver graphics.js, line:182, line:201)"aqp2016II"*/ + teacherRatingGraphic(35, 54, 23, 22); + /* Llamando a la funcion de la GRAFICO JEDI MASTER RATING (ver graphics.js)"aqp2016II"*/ + jediMasterRatingGraphic(34, 12, 23, 34); + // variables a usar par alas funciones generales + var student = data.LIM['2016-2']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar de resultados según las funciones + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = (countProm(student) * 100) / arrStudent.length + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint4': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint4': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'lima2017I': + section.classList.remove('display-none'); + var student = data.LIM['2017-1']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = Math.round((countProm(student) * 100) / arrStudent.length) + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + // + case event.target.value === 'lima2017II': + section.classList.remove('display-none'); + var student = data.LIM['2017-2']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = (countProm(student) * 100) / arrStudent.length + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'aqp2016II': + section.classList.remove('display-none'); + var student = data.AQP['2016-2']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = Math.round((countProm(student) * 100) / arrStudent.length) + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'aqp2017I': + section.classList.remove('display-none'); + var student = data.AQP['2017-1']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = (countProm(student) * 100) / arrStudent.length + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'scl2016II': + section.classList.remove('display-none'); + var student = data.SCL['2016-2']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = (countProm(student) * 100) / arrStudent.length + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint4': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint4': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'scl2017I': + section.classList.remove('display-none'); + var student = data.SCL['2017-1']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = (countProm(student) * 100) / arrStudent.length + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'scl2017II': + section.classList.remove('display-none'); + var student = data.SCL['2017-2']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = Math.round((countProm(student) * 100) / arrStudent.length) + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint4': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint4': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'cdm2017I': + section.classList.remove('display-none'); + var student = data.CDMX['2017-1']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievement.textContent = countProm(student); + achievementPercent.textContent = Math.round((countProm(student) * 100) / arrStudent.length) + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(10, 39); + achievementGraphic(15, 56); + netPromoterScoreGraphic(20, 45, 17); + techSkillsGraphic(18, 30); + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(3, 34); + teacherRatingGraphic(35, 34); + jediMasterRatingGraphic(34, 23); + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint3': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + case event.target.value === 'cdm2017II': + section.classList.remove('display-none'); + // Llenar la cantidad de alumnos totales + var student = data.CDMX['2017-2']; + var arrStudent = student['students']; + var rating = student['ratings']; + enrolled.textContent = arrStudent.length; + // Llenar la cantidad de alumnos desertores + dropout.textContent = countOff(student); + achievementPercent.textContent = (countProm(student) * 100) / arrStudent.length + '%'; + studentSatisfaction.textContent = studentsSatisfaction(rating); + teacherRating.textContent = teacherProm(rating); + jediMasterRating.textContent = jdProm(rating); + cumulativeNps.textContent = nps(rating); + //Obteniendo el HSE Skills + var studentns = 0; + var accumulatorHseS = 0; + + function hseSkills() { + var quantityStu = data['CDMX']['2017-2'].students.length; + + for (var i = 0; i < data['CDMX']['2017-2'].students.length;i++) { + var countSprints = data['CDMX']['2017-2'].students[i].sprints.length; + for (var j = 0; j < countSprints;j++) { + if ('0' == data['CDMX']['2017-2'].students[i].sprints[j].number) { + if (data['CDMX']['2017-2'].students[i].sprints[j].score.hse > 840) { + accumulatorHseS++; + } + } + } + } + var studentns = quantityStu - accumulatorHseS; + return studentns; + } + + + lifeSkills.textContent= hseSkills(); + + //Obteniendo el tech Skills + var studentns2 = 0; + var accumulatortech = 0; + function techSkills() { + var quantityStu = data['CDMX']['2017-2'].students.length; + + for (var i = 0; i < data['CDMX']['2017-2'].students.length;i++) { + var countSprints = data['CDMX']['2017-2'].students[i].sprints.length; + for (var j = 0; j < countSprints;j++) { + if ('0' == data['CDMX']['2017-2'].students[i].sprints[j].number) { + if (data['CDMX']['2017-2'].students[i].sprints[j].score.tech > 1260) { + accumulatortech++; + } + } + } + } + var studentns2 = quantityStu - accumulatortech; + return studentns; + + } + + + document.getElementById('tech-skills').textContent= techSkills(); + + + + // Faltan editar los parámetros para los gráficos y que se actualice con las datos obtenidos de las funciones + enrollmentGraphic(25, 21); // + achievementGraphic(7, 39);// + netPromoterScoreGraphic(20, 45, 17);// + techSkillsGraphic(18, 30);// + techSkillsSprintsGraphic(15, 34); + lifesSkillsGraphic(14, 23); + lifeSkillsSprintsGraphic(6, 6); + studentSatisfactionGraphic(87, 97);// + teacherRatingGraphic(4.4, 4.1);// + jediMasterRatingGraphic(4.7, 4.2);// + /* Evento para tech y life por sprint*/ + selectSprintTech.addEventListener('change', showSprintTech); + function showSprintTech(event) { + switch (true) { + case event.target.value === 'sprint1': + + + + + + techSkillsSprintGraphic(7, 9); + break; + case event.target.value === 'sprint2': + techSkillsSprintGraphic(7, 8); + break; + default: + } + } + selectSprintLife.addEventListener('change', showSprintLife); + function showSprintLife(event) { + switch (true) { + case event.target.value === 'sprint1': + lifeSkillsSprintGraphic(7, 8); + break; + case event.target.value === 'sprint2': + lifeSkillsSprintGraphic(7, 8); + break; + default: + } + } + break; + default: + section.classList.add('display-none'); + } + } +}); diff --git a/js/graphics.js b/js/graphics.js new file mode 100644 index 00000000..ff3687db --- /dev/null +++ b/js/graphics.js @@ -0,0 +1,219 @@ +/* Aseguramos que cargue la libreria antes de aplicar las funciones*/ +google.charts.load('current', {packages: ['corechart']}); +/* GRAFICO PARA LA CONTENEDOR DIV "ENROLLMENT" */ +google.charts.setOnLoadCallback(enrollmentGraphic); +function enrollmentGraphic(dropout, students) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + [' Deserting Students', dropout], + ['Active Students', students] + ] + ); + var opciones = {'width': 350, + 'height': 180, + }; + var graphic = new google.visualization.PieChart(document.getElementById('graphic-enrollment')); + graphic.draw(data, opciones); +} +/* GRAFICO PARA LA CONTENEDOR DIV "ACHIEVEMENT" */ +google.charts.setOnLoadCallback(achievementGraphic); +function achievementGraphic(goalAccomplished, goalNotMet) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Students that meet the target ', goalAccomplished], + ['Students that not meet the target', goalNotMet] + ] + ); + var opciones = {'width': 350, + 'height': 180, + }; + var graphic = new google.visualization.PieChart(document.getElementById('graphic-achievement')); + graphic.draw(data, opciones); +} +/* GRAFICO PARA LA CONTENEDOR DIV "NET PROMOTER SCORE" */ +google.charts.setOnLoadCallback(netPromoterScoreGraphic); +function netPromoterScoreGraphic(promoters, passive, detractors) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Promoters', promoters], + ['Passive', passive], + ['Detractors', detractors] + ] + ); + var opciones = {'width': 350, + 'height': 180, + }; + var graphic = new google.visualization.PieChart(document.getElementById('graphic-net-promoter-score')); + graphic.draw(data, opciones); +} +/* GRAFICOS PARA DE LOS CONTENEDORES VACIOS DIV "TECH SKILLS" */ +/* Grafico general: total de estudiantes que superan la meta de puntos tÉcnicos en promedio*/ +google.charts.setOnLoadCallback(techSkillsGraphic); +function techSkillsGraphic(techGoalAccomplished, techGoalNotMet) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Students that meet the technological goal', techGoalAccomplished], + ['Students that not meet technological goal', techGoalNotMet] + ] + ); + var opciones = {'width': 400, + 'height': 320, + }; + var graphic = new google.visualization.PieChart(document.getElementById('graphic-tech-skills')); + graphic.draw(data, opciones); +} +/* Grafico especifico(por sprint): total de estudiantes que superan la meta de puntos tÉcnicos en promedio por sprints*/ +google.charts.setOnLoadCallback(techSkillsSprintsGraphic); +function techSkillsSprintsGraphic(techSprintOne, techSprintTwo, techSprintThree, techSprintFour) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Sprint 1', techSprintOne], + ['Sprint 2', techSprintTwo], + ['Sprint 3', techSprintThree], + ['Sprint 4', techSprintFour] + ] + ); + var opciones = {'width': 530, + 'height': 360, + }; + var graphic = new google.visualization.ColumnChart(document.getElementById('graphic-tech-skills-sprints')); + graphic.draw(data, opciones); +} +/* Grafico : total de estudiantes que superan la meta de puntos tÉcnicos en promedio por SPRINT*/ +google.charts.setOnLoadCallback(techSkillsSprintGraphic); +function techSkillsSprintGraphic(techGoalAccomplishedSprint, techGoalNotMetSprint) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Students that meet the technological goal for sprint', techGoalAccomplishedSprint], + ['Students that not meet technological goal for sprint', techGoalNotMetSprint] + ] + ); + var opciones = {'width': 300, + 'height': 180, + }; + var graphic = new google.visualization.PieChart(document.getElementById('graphic-tech-skills-sprint')); + graphic.draw(data, opciones); +} +/* GRAFICO PARA LA CONTENEDOR DIV "LIFE SKILLS" */ +/* Grafico general: total de estudiantes que superan la meta de puntos life en promedio*/ +google.charts.setOnLoadCallback(lifesSkillsGraphic); +function lifesSkillsGraphic(lifeGoalAccomplished, lifeGoalNotMet) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Students that meet the attitudinal goal', lifeGoalAccomplished], + ['Students that not meet attitudinal goal', lifeGoalNotMet] + ] + ); + var opciones = {'width': 400, + 'height': 320, + }; + var graphic = new google.visualization.PieChart(document.getElementById('graphic-lifes-skills')); + graphic.draw(data, opciones); +} +/* Grafico especifico(por sprint): total de estudiantes que superan la meta de puntos tÉcnicos en promedio por sprint*/ +google.charts.setOnLoadCallback(lifeSkillsSprintsGraphic); +function lifeSkillsSprintsGraphic(lifeSprintOne, lifeSprintTwo, lifeSprintThree, lifeSprintFour) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Sprint 1', lifeSprintOne], + ['Sprint 2', lifeSprintTwo], + ['Sprint 3', lifeSprintThree], + ['Sprint 4', lifeSprintFour] + ] + ); + var opciones = {'width': 530, + 'height': 360, + }; + var graphic = new google.visualization.ColumnChart(document.getElementById('graphic-lifes-Skills-sprints')); + graphic.draw(data, opciones); +} +/* Grafico : total de estudiantes que superan la meta de puntos tÉcnicos en promedio por SPRINT*/ +google.charts.setOnLoadCallback(lifeSkillsSprintGraphic); +function lifeSkillsSprintGraphic(lifeGoalAccomplishedSprint, lifeGoalNotMetSprint) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Students that meet the attitudinal goal for sprint', lifeGoalAccomplishedSprint], + ['Students that not meet attitudinal goal for sprint', lifeGoalNotMetSprint] + ] + ); + var opciones = {'width': 300, + 'height': 200, + }; + var graphic = new google.visualization.PieChart(document.getElementById('graphic-life-skills-sprint')); + graphic.draw(data, opciones); +} +/* GRAFICO PARA LA CONTENEDOR DIV "STUDENT SATISFACTION" */ +google.charts.setOnLoadCallback(studentSatisfactionGraphic); +function studentSatisfactionGraphic(studentSatisfactionOne, studentSatisfactionTwo, studentSatisfactionThree, studentSatisfactionFour) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Sprint 1', studentSatisfactionOne], + ['Sprint 2', studentSatisfactionTwo], + ['Sprint 3', studentSatisfactionThree], + ['Sprint 4', studentSatisfactionFour] + ] + ); + var opciones = {'width': 350, + 'height': 180, + }; + var graphic = new google.visualization.ComboChart(document.getElementById('graphic-student-satisfaction')); + graphic.draw(data, opciones); +} +/* GRAFICO PARA LA CONTENEDOR DIV "TEACHER RATING" */ +google.charts.setOnLoadCallback(teacherRatingGraphic); +function teacherRatingGraphic(teacherRatingOne, teacherRatingTwo, teacherRatingThree, teacherRatingFour) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Sprint 1', teacherRatingOne], + ['Sprint 2', teacherRatingTwo], + ['Sprint 3', teacherRatingThree], + ['Sprint 4', teacherRatingFour] + ] + ); + var opciones = {'width': 350, + 'height': 180, + }; + var graphic = new google.visualization.ComboChart(document.getElementById('graphic-teacher-rating')); + graphic.draw(data, opciones); +} +/* GRAFICO PARA LA CONTENEDOR DIV "JEDI MASTER RATING" */ +google.charts.setOnLoadCallback(jediMasterRatingGraphic); +function jediMasterRatingGraphic(jediMasterRatingOne, jediMasterRatingTwo, jediMasterRatingThree, jediMasterRatingFour) { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'students'); + data.addColumn('number', 'quantity'); + data.addRows([ + ['Sprint 1', jediMasterRatingOne], + ['Sprint 2', jediMasterRatingTwo], + ['Sprint 3', jediMasterRatingThree], + ['Sprint 4', jediMasterRatingFour] + ] + ); + var opciones = {'width': 350, + 'height': 180, + }; + var graphic = new google.visualization.ComboChart(document.getElementById('graphic-jedi-master-rating')); + graphic.draw(data, opciones); +}