diff --git a/README.md b/README.md index e9b59c4c..22091d72 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,37 @@ *** -## Flujo de trabajo - -1. Debes realizar un [**fork**](https://gist.github.com/ivandevp/1de47ae69a5e139a6622d78c882e1f74) - de este repositorio. - -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í: +## Resumen: + * Un dashboard es una representación gráfica de las principales métricas o KPIs que para el seguimiento de los objetivos en una organizacion o empresa. - ```bash - git clone https://github.com//freelancer.git - ``` +## Objetivo: + * Como producto final nuestro objetio es realizar un Data Dashboard para analizar la mayor cantidad de datos posibles respecto al desempeño de las estudiantes de Laboratoria para lo cual se solicitó que construyamos una herramienta web donde puedan ver estos datos fácil y rápidamente. +![sketch 1](assets/sketch-1.png) +Partimos del siguientes esquema para desarrollar nuestro programa. -3. Cuando hayas terminado tu producto, envía un Pull Request a este repositorio - (puedes solicitar apoyo de tus profes para este paso). - -> 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:. +## Flujo de trabajo +1. El primer paso a seguir era hacer uso de este repositorio: [**fork**](https://gist.github.com/ivandevp/1de47ae69a5e139a6622d78c882e1f74) +2. Luego teniamos que seguir los siguientes lineamientos: + - 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. El NPS se calcula en base a la encuesta que las estudiantes responden al respecto de la recomendación que darían de Laboratoria, bajo la siguiente fórmula: + + [Promoters] = [Respuestas 9 o 10] / [Total respuestas] * 100 + [Passive] = [Respuestas 7 u 8] / [Total respuestas] * 100 + [Detractors] = [Respuestas entre 1 y 6] / [Total respuestas] * 100 + + [NPS] = [Promoters] - [Detractors] + - 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 l@s profesores. + - La puntuación promedio de l@s jedi masters. + + 3. Nos pidieron: + * Trabajar en parejas. + * Tener una planificación. + * La definición del diseño. + * Implementación del data dashboard usando html, css y js. + * Desplegar el producto en Github Pages. diff --git a/assets/images/logo.png b/assets/images/logo.png new file mode 100644 index 00000000..4c6a60a1 Binary files /dev/null and b/assets/images/logo.png differ diff --git a/assets/images/sketch-1.png b/assets/images/sketch-1.png new file mode 100644 index 00000000..ddacb2cb Binary files /dev/null and b/assets/images/sketch-1.png differ diff --git a/css/main.css b/css/main.css index 6355c827..63f9c4a9 100644 --- a/css/main.css +++ b/css/main.css @@ -1,3 +1,72 @@ -/* - * Estilos de tu proyecto - */ +/*quitando estilos predeterminados*/ +*{ + margin: 0; + padding: 0; + box-sizing: border-box; +} + +li{ + list-style: none; + padding-left: 10px; +} + +div{ + padding: 15px; +} + +/*agregando estilos a header*/ +header{ + width: 100%; + height: 90px; + background: white; + z-index: 1000; + position: fixed; + top: 0; + left: 0; +} +header img{ + height: 60px; + position: relative; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); +} +header .fa{ + font-size: 35px; + margin: 25px; + position: absolute; + right: 0; +} + +/*agregando estilos a nav*/ +nav{ + background: #e4e2df; + font-family: 'Montserrat', sans-serif; + font-weight: 600; + margin-top: 90px; +} + +nav div{ + width: 100%; +} + +nav select{ + background: transparent; + border: none; + font-family: 'Montserrat', sans-serif; + font-size: 30px; + font-weight: 600; + height: 45px; + margin: 10px; + padding: 5px; + width: 260px; +} +.see-info{ + background: #d8d6d3; +} + +.see-info li{ + display: inline-block; + font-size: 25px; + margin: 10px; +} diff --git a/index.html b/index.html index 8930fa03..a34c1f08 100644 --- a/index.html +++ b/index.html @@ -3,12 +3,49 @@ Data Dashboard + + + - +
+ logo laboratoria + +
+ +
+
+
+
+
+
+
+
+ + diff --git a/js/app.js b/js/app.js index 895ae2dd..eb086893 100644 --- a/js/app.js +++ b/js/app.js @@ -1,6 +1,314 @@ -/* - * Funcionalidad de tu producto - */ +// guarda en un array las sedes +var sede = Object.keys(data); // ["AQP", "CDMX", "LIM", "SCL"] +console.log(sede); +// guarda en un array los objetos de cada sede es decir las generaciones +var generation = Object.values(data); // [{…}, {…}, {…}, {…}] tiene el valor de AQP, CDMX, LIM, SCL +console.log(generation); +// guarda las generaciones en un array +var generationAarequipa = Object.keys(generation[0]); // ["2016-2", "2017-1"] +console.log(generationAarequipa); +// guarda en un array los objetos de las generaciones que guardan students y ratings +var genArequipaObject = Object.values(generation[0]); // [{…}, {…}] tiene el valor 2016-2, 2017-1 +console.log(genArequipaObject); -// Puedes hacer uso de la base de datos a través de la variable `data` -console.log(data); + +var container = document.getElementById('container'); +var container2 = document.getElementById('container2'); + +window.addEventListener('load', function() { + var selectSede = document.getElementById('sede'); + var selectGeneration = document.getElementById('generation'); + var chooseSede = ''; // va a indicar cual es la sede para tomarlas en cuenta con el siguiente filtro + + selectSede.addEventListener('change', function() { + switch (true) { + case event.target.value === 'lima': + container.textContent = ''; + console.log(data[sede[2]]); + chooseSede = 2; // chooseSede cambia a 2 porque es la posicion en el array sede que tiene lima + break; + case event.target.value === 'arequipa': + container.textContent = ''; + console.log(data[sede[0]]); + chooseSede = 0; // choose cambia a 0 por su posicion en el array sede + break; + case event.target.value === 'chile': + container.textContent = ''; + console.log(data[sede[3]]); + chooseSede = 3; // choose cambia a 3 por su posicion en el array sede + break; + case event.target.value === 'mexico': + container.textContent = ''; + console.log(data[sede[1]]); // choose cambia a 1 por su posicion en el array sede + chooseSede = 1; + break; + }; + }); + + selectGeneration.addEventListener('change', function() { + switch (true) { + case event.target.value === '2016-2': + var generation2016II = data[sede[chooseSede]]['2016-2']; // esta seleccionando el objeto que esta dentro de 2016II el cual incluye students y ratings como keys + container.textContent = ''; // limpia + showGeneration(generation2016II); + showMetas(generation2016II); + showRatings(generation2016II); + break; + case event.target.value === '2017-1': + var generation2017I = data[sede[chooseSede]]['2017-1']; + container.textContent = ''; + showGeneration(generation2017I); + showMetas(generation2017I); + showRatings(generation2017I); + break; + case event.target.value === '2017-2': + var generation2017II = data[sede[chooseSede]]['2017-2']; + container.textContent = ''; + showGeneration(generation2017II); + showMetas(generation2017II); + showRatings(generation2017II); + break; + } + }); +}); + +function showGeneration(obj) { // nos va a mostrar la cantidad de estudiantes activas + var divStudents = document.createElement('div'); // crea un div + var pStudents = document.createElement('p'); // crea un p + pStudents.textContent = 'ESTUDIANTES INSCRITAS: ' + obj['students'].length + ' inscritas'; // agrega contenido al p + divStudents.appendChild(pStudents); // agrega el p dentro del div + container.appendChild(divStudents); // agrega el div dentro del container + var acumulStudentsActive = 0; // acumulara la cantidad de estudiantes activas + for (var i = 0; i < obj['students'].length; i++) { // recorre el array con las estudiantes + if (obj['students'][i]['active'] === true) { // verifica si es true + acumulStudentsActive++; // aumenta la variable en 1 cada que es true + } + }; + var pStudentsAactive = document.createElement('p'); + pStudentsAactive.textContent = 'ESTUDIANTES ACTIVAS:' + acumulStudentsActive + ' activas'; // contenido del p que muestra las estudiantes activas + divStudents.appendChild(pStudentsAactive); // agrega el p al div + console.log(acumulStudentsActive); + var pStudentsDeserter = document.createElement('p'); + pStudentsDeserter.textContent = 'ESTUDIANTES DESERTORAS:' + (obj['students'].length - acumulStudentsActive) + ' desertoras'; // mueustra las desertoras + divStudents.appendChild(pStudentsDeserter); + + google.charts.load('current', {'packages': ['corechart']}); + google.charts.setOnLoadCallback(drawChart); + + function drawChart() { + var data = new google.visualization.DataTable(); + data.addColumn('string', 'Estudiantes'); + data.addColumn('number', 'cantidad'); + data.addRows([ + ['Activas', acumulStudentsActive], + ['Desertoras', obj['students'].length - acumulStudentsActive], + ]); + + var options = { + title: 'CANTIDAD DE ESTUDIANTES', + 'width': 700, + 'height': 500 + }; + + var chart = new google.visualization.PieChart(document.getElementById('charts-pie')); + + chart.draw(data, options); + } +}; + +function showMetas(obj) { + var tech = (1800 * 70) / 100;// calcula el 70% (1800) 1260 + var hse = (1200 * 70) / 100;// clacula el 70% (1200) 840 + var divMetas = document.createElement('div'); + container2.appendChild(divMetas); + var acumSprint1Tech = 0; // variables para guardar las alumnas que superan el 70% + var acumSprint1Hse = 0; + var acumSprint2Tech = 0; + var acumSprint2Hse = 0; + var acumSprint3Tech = 0; + var acumSprint3Hse = 0; + var acumSprint4Tech = 0; + var acumSprint4Hse = 0; + var studentsCant = obj['students'].length; + for (var j = 0; j < obj['students'].length; j++) {// recorre el array con las estudiantes + var sprintByStudents = obj['students'][j]['sprints']; // contiene un array con los sprint de cada estidiante + for (var k = 0; k < sprintByStudents.length; k++) {// recorre el array con los sprint + console.log(obj['students'][j]['sprints'][k]); + var scoreStudents = obj['students'][j]['sprints'][k]['score']; // ingresa al score para poder tomar los puntos + switch (true) { + case k === 0: // verifica que sea verdad (cuando k es cero se trata del primer sprint) + if (scoreStudents['tech'] > tech) { // compara el score tech de la alumna con el 70% deseado + acumSprint1Tech = acumSprint1Tech + 1; // acumula en la variable para contarlas + }; + if (scoreStudents['hse'] > hse) { // compara el score hse de la alumna con el 70% deseado + acumSprint1Hse = acumSprint1Hse + 1; // las cuenta + }; + break; + case k === 1: + if (scoreStudents['tech'] > tech) { + acumSprint2Tech = acumSprint2Tech + 1; + }; + if (scoreStudents['hse'] > hse) { + acumSprint2Hse = acumSprint2Hse + 1; + }; + break; + case k === 2: + if (scoreStudents['tech'] > tech) { + acumSprint3Tech = acumSprint3Tech + 1; + }; + if (scoreStudents['hse'] > hse) { + acumSprint3Hse = acumSprint3Hse + 1; + }; + break; + case k === 3: + if (scoreStudents['tech'] > tech) { + acumSprint4Tech = acumSprint4Tech + 1; + }; + if (scoreStudents['hse'] > hse) { + acumSprint4Hse = acumSprint4Hse + 1; + }; + break; + }; + }; + }; + var sprintsCant = obj['ratings'].length; + var sumTech = (acumSprint1Tech + acumSprint2Tech + acumSprint3Tech + acumSprint4Tech) / sprintsCant; // promedia la cantidad de estudiantes que superan el 70% en tech + var sumHse = (acumSprint1Hse + acumSprint2Hse + acumSprint3Hse + acumSprint4Hse) / sprintsCant; // promedia la cantidad de estudiantes que superan el 70% en hse + var promGeneral = parseInt((sumTech + sumHse) / 2); // promedia tech y hase + var pPromGeneral = document.createElement('p'); // crea el p que almacenara el promedio general + pPromGeneral.textContent = 'PROMEDIO DE ESTUDIANTES QUE SUPERARON LA META: ' + promGeneral + ' Estudiantes (' + parseInt((promGeneral * 100) / studentsCant) + ' %)'; + divMetas.appendChild(pPromGeneral); + // console.log(sumTech); + // console.log(sumHse); + if (acumSprint1Tech !== 0 || acumSprint1Hse !== 0) { // comprueba que tenga ese sprint + var ulSprint1Prom = document.createElement('ul'); + var liTech1 = document.createElement('li'); + var liHse1 = document.createElement('li'); + ulSprint1Prom.textContent = 'SPRINT 1:'; + liTech1.textContent = 'Superan el 70% en Técnico: ' + acumSprint1Tech + ' Estudiantes (' + parseInt((acumSprint1Tech * 100) / studentsCant) + ' %)'; + liHse1.textContent = 'Superan el 70% en Hse: ' + acumSprint1Hse + ' Estudiantes (' + parseInt((acumSprint1Hse * 100) / studentsCant) + ' %)'; + divMetas.appendChild(ulSprint1Prom); + ulSprint1Prom.appendChild(liTech1); + ulSprint1Prom.appendChild(liHse1); + }; + if (acumSprint2Tech !== 0 || acumSprint2Hse !== 0) { + var ulSprint2Prom = document.createElement('ul'); + var liTech2 = document.createElement('li'); + var liHse2 = document.createElement('li'); + ulSprint2Prom.textContent = 'SPRINT 2:'; + liTech2.textContent = 'Superan el 70% en Técnico: ' + acumSprint2Tech + ' Estudiantes (' + parseInt((acumSprint2Tech * 100) / studentsCant) + ' %)'; + liHse2.textContent = 'Superan el 70% en Hse: ' + acumSprint2Hse + ' Estudiantes (' + parseInt((acumSprint2Hse * 100) / studentsCant) + ' %)'; + divMetas.appendChild(ulSprint2Prom); + ulSprint2Prom.appendChild(liTech2); + ulSprint2Prom.appendChild(liHse2); + }; + if (acumSprint3Tech !== 0 || acumSprint3Hse !== 0) { + var ulSprint3Prom = document.createElement('ul'); + var liTech3 = document.createElement('li'); + var liHse3 = document.createElement('li'); + ulSprint3Prom.textContent = 'SPRINT 3:'; + liTech3.textContent = 'Superan el 70% en Técnico: ' + acumSprint3Tech + ' Estudiantes (' + parseInt((acumSprint3Tech * 100) / studentsCant) + ' %)'; + liHse3.textContent = 'Superan el 70% en Hse: ' + acumSprint3Hse + ' Estudiantes (' + parseInt((acumSprint3Hse * 100) / studentsCant) + ' %)'; + divMetas.appendChild(ulSprint3Prom); + divMetas.appendChild(liTech3); + divMetas.appendChild(liHse3); + }; + if (acumSprint4Tech !== 0 || acumSprint4Hse !== 0) { + var ulSprint4Prom = document.createElement('ul'); + var liTech4 = document.createElement('li'); + var liHse4 = document.createElement('li'); + ulSprint4Prom.textContent = 'SPRINT 4:'; + liTech4.textContent = 'Superan el 70% en Técnico: ' + acumSprint4Tech + ' Estudiantes (' + parseInt((acumSprint4Tech * 100) / studentsCant) + ' %)'; + liHse4.textContent = 'Superan el 70% en Hse: ' + acumSprint4Hse + ' Estudiantes (' + parseInt((acumSprint4Hse * 100) / studentsCant) + ' %)'; + divMetas.appendChild(ulSprint4Prom); + divMetas.appendChild(liTech4); + divMetas.appendChild(liHse4); + }; + + google.charts.load('current', {'packages': ['bar']}); + google.charts.setOnLoadCallback(drawChart); + + function drawChart() { + var data = google.visualization.arrayToDataTable([ + ['SPRINT', 'Tech', 'Hse'], + ['1', acumSprint1Tech, acumSprint1Hse], + ['2', acumSprint2Tech, acumSprint2Hse], + ['3', acumSprint3Tech, acumSprint3Hse], + ['4', acumSprint4Tech, acumSprint4Hse] + ]); + + var options = { + width: 1200, + chart: { + title: 'ESTUDIANTES QUE SUPERAN EL 70%', + subtitle: 'Cantidad de estudiantes con mas de 70% en Tech y Hse', + }, + bars: 'horizontal' // Required for Material Bar Charts. + }; + + var chart = new google.charts.Bar(document.getElementById('charts-bar')); + + chart.draw(data, google.charts.Bar.convertOptions(options)); + }; +}; + +function showRatings(obj) { + var divRatings = document.createElement('div'); // creamos un div que contenga kos datos + container3.appendChild(divRatings); + var sumNps = 0; + for (var j = 0; j < obj['ratings'].length; j++) { // recorre el array ratings + // console.log(obj['ratings'][j]['student']); // me da un objeto que contiene los keys de cumple o no + var ulStudentsPoints = document.createElement('ul'); + var liStudentsSup = document.createElement('li'); + ulStudentsPoints.textContent = 'SPRINT ' + (j + 1) + ':'; + liStudentsSup.textContent = 'Estudiantes satisfechas con la experiencia de Laboratoria : ' + (obj['ratings'][j]['student']['supera'] + obj['ratings'][j]['student']['cumple']) + '%'; + ulStudentsPoints.appendChild(liStudentsSup); + divRatings.appendChild(ulStudentsPoints); + // Creamos un li para almacenar el promedio de la puntuacion de los profesores + var liTeacherPoints = document.createElement('li'); + liTeacherPoints.textContent = 'Puntuación promedio de l@s profesores : ' + obj['ratings'][j]['teacher']; + ulStudentsPoints.appendChild(liTeacherPoints); + var liJediPoints = document.createElement('li'); + liJediPoints.textContent = 'Puntuación promedio de l@s jedis : ' + obj['ratings'][j]['jedi']; + ulStudentsPoints.appendChild(liJediPoints); + var nps = obj['ratings'][j]['nps']; + var npsPromedioBySprint = nps['promoters'] - nps['detractors']; + sumNps = sumNps + npsPromedioBySprint; + }; + var promFinalNps = parseInt(sumNps / obj['ratings'].length); + var pNpsFinal = document.createElement('p'); + pNpsFinal.textContent = 'NPS promedio: ' + promFinalNps + '%'; + container3.insertBefore(pNpsFinal, divRatings); + + + var jediPoints1 = obj['ratings'][0]['jedi']; + var teacherPoints1 = obj['ratings'][0]['teacher']; + var jediPoints2 = obj['ratings'][1]['jedi']; + var teacherPoints2 = obj['ratings'][1]['teacher']; + var jediPoints3 = obj['ratings'][2]['jedi']; + var teacherPoints3 = obj['ratings'][2]['teacher']; + var jediPoints4 = obj['ratings'][3]['jedi']; + var teacherPoints4 = obj['ratings'][3]['teacher']; + google.charts.load('current', {'packages': ['bar']}); + google.charts.setOnLoadCallback(drawChart); + function drawChart() { + var data = google.visualization.arrayToDataTable([ + ['Sprint', 'Puntuación Yedis', 'Puntuación Profesores'], + [1, jediPoints1, teacherPoints1], + [2, jediPoints2, teacherPoints2], + [3, jediPoints3, teacherPoints3], + [4, jediPoints4, teacherPoints4] + ]); + + var options = { + chart: { + title: 'Puntuación Yedis y Profesores', + subtitle: 'Puntuación 1 - 5', + } + }; + + var chart = new google.charts.Bar(document.getElementById('charts-column')); + + chart.draw(data, google.charts.Bar.convertOptions(options)); + } +}; \ No newline at end of file diff --git a/sketch-1.png b/sketch-1.png new file mode 100644 index 00000000..ddacb2cb Binary files /dev/null and b/sketch-1.png differ