Skip to content

Commit

Permalink
🚀 Indicador 2.7 con leyendas y estructura única en datos
Browse files Browse the repository at this point in the history
  • Loading branch information
1cgonza committed Nov 14, 2024
1 parent 29d8937 commit a843238
Show file tree
Hide file tree
Showing 20 changed files with 394 additions and 30 deletions.
3 changes: 3 additions & 0 deletions aplicaciones/procesador/fuente/aplicacion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { readdir, rm } from 'fs/promises';
import { rutaEstaticosDatos, rutaEstaticosDescarga } from './utilidades/constantes';
import calcularPesos from './datosDescarga';
import JuegoCategorias from './modulos/JuegoCategorias';
import VariableDoble from './modulos/VariableDoble';

async function inicio() {
await vaciarProcesados();
Expand Down Expand Up @@ -68,6 +69,8 @@ async function procesarDatos() {
await ya25.procesar('2.5: porcentaje marco integral', 'YA_2.5', 'Sheet 1', 'ya2-5');
const ya26 = new VariableSingular('educ_inicial_icbf', true, 'conteo');
await ya26.procesar('2.6: educación inicial icbf', 'YA_2.6', 'Sheet 1', 'ya2-6');
const ya27 = new VariableDoble('#_estudiantes', true, 'conteo', 1);
await ya27.procesar('2.7: matriculados', 'YA_2.7', 'Sheet1', 'ya2-7');

/** 3 */
const ya31 = new VariableSingular('promedio_matematicas', true, 'promedio');
Expand Down
291 changes: 291 additions & 0 deletions aplicaciones/procesador/fuente/modulos/VariableDoble.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
import { limpiarDepartamento, limpiarMunicipio } from '../limpieza/lugar';
import type {
Departamento,
Errata,
Municipio,
RespuestaPorcentaje2,
VariableDoble,
VariableValorSingular,
} from '@/tipos';
import { esNumero, guardarJSON, redondearDecimal } from '../utilidades/ayudas';
import maquinaXlsx from '../utilidades/maquinaXlsx';
import { departamentos } from '../utilidades/lugaresColombia';
import { DatosIndicadorNal, TiposEstructura } from '../../../../tipos/compartidos';

export default class {
datosNacionales: DatosIndicadorNal;
datosDepartamentos: RespuestaPorcentaje2;
datosMunicipios: RespuestaPorcentaje2;
errata: { fila: number; error: string }[];
nombreVariableValor: VariableValorSingular;
estructura: TiposEstructura;
exportarMunicipios: boolean;

constructor(
nombreVariable: VariableValorSingular,
ascendente: boolean,
estructura: TiposEstructura,
unidadMedida = 100
) {
this.datosNacionales = {
ascendente,
estructura,
unidadMedida,
datos: {},
datosMunicipio: true,
maxNal: 0,
minNal: Infinity,
maxDep: 0,
minDep: Infinity,
maxMun: 0,
minMun: Infinity,
};
this.errata = [];
this.datosMunicipios = {};
this.datosDepartamentos = {};
this.nombreVariableValor = nombreVariable;
this.estructura = estructura;
this.exportarMunicipios = true;
}

async procesar(nombreReferencia: string, nombreArchivo: string, hoja: string, nombreParaArchivo: string) {
await maquinaXlsx(nombreReferencia, nombreArchivo, hoja, this.procesarMunicipios);
this.procesarDepartamentos();
this.procesarNacional();

if (!this.exportarMunicipios) this.datosNacionales.datosMunicipio = false;
guardarJSON(this.datosMunicipios, `${nombreParaArchivo}-mun`);
guardarJSON(this.datosDepartamentos, `${nombreParaArchivo}-dep`);
guardarJSON(this.datosNacionales, `${nombreParaArchivo}-nal`);

if (this.errata.length) guardarJSON(this.errata, `Errata ${nombreParaArchivo}`);
}

validarValor(valor: number, numeroFila: number) {
if (valor && isNaN(valor)) {
this.errata.push({ fila: numeroFila, error: `el valor no es un número: ${valor}` });
return false;
}

return true;
}

procesarMunicipios = (fila: VariableDoble, numeroFila: number) => {
const valor = fila['#_estudiantes'];
const categoria = fila.sector;

if (fila.hasOwnProperty('codmpio')) {
const municipio = limpiarMunicipio(+fila.codmpio);
const tieneValor = this.validarValor(valor, numeroFila);
if (!tieneValor) return;

// Si no existe el municipio
if (municipio.hasOwnProperty('error') && valor) {
// El código de datos nacionales es 1001 entonces lo podemos comparar directo.
if (fila.codmpio == 1001) {
this.datosNacionales.datos[fila.anno] = valor;
return;
}
// Si termina en 00 y no lo encontró antes significa que es el dato del departamento.
// else if (`${fila.codmpio}`.slice(-2) === '00') {
// // Poner ceros al principio y convertir a texto para que quede bien al comparar con código departamento.
// const codigoCompleto = `${fila.codmpio}`.padStart(5, '0');
// const codigoDep = codigoCompleto.slice(0, 2); // sacar los primeros dos números.
// const dep = departamentos.datos.find((obj) => obj[0] === codigoDep); // buscar el departamento.

// // agregar datos del departamento si existen.
// if (dep) {
// if (!this.datosDepartamentos[fila.anno]) {
// this.datosDepartamentos[fila.anno] = [];
// }

// this.datosDepartamentos[fila.anno].push([(dep as Departamento)[0], valor]);
// return;
// } else {
// this.errata.push({ fila: numeroFila, error: `No existe departamento con código: ${codigoDep}` });
// }
// }

// No pasó ninguna prueba, registrar en errata para revisar el caso.
this.errata.push({ fila: numeroFila, error: (municipio as Errata).mensaje });
return;
}

this.registrarAño(numeroFila, fila.anno, { datos: municipio, valor, categoria });
} else {
// if (fila.hasOwnProperty('coddepto') && fila.coddepto) {
// const departamento = limpiarDepartamento(+fila.coddepto);
// const tieneValor = this.validarValor(valor, numeroFila);
// if (!tieneValor) return;
// this.revisarMinMax(valor, 'maxDep', 'minDep');
// this.exportarMunicipios = false;
// this.registrarAño(numeroFila, fila.anno, null, { datos: departamento, valor });
// } else {
// this.errata.push({ fila: numeroFila, error: `No hay valor en coddepto` });
// }
}
};

procesarDepartamentos() {
if (this.exportarMunicipios) {
for (const año in this.datosMunicipios) {
const datosAño = this.datosMunicipios[año];
const deps: { [codDep: string]: [total: number, noOficial: number, oficial: number][] } = {};

datosAño.forEach((municipio) => {
const codDepartamento = municipio[0].slice(0, 2);
if (!deps[codDepartamento]) {
deps[codDepartamento] = [];
}

deps[codDepartamento].push([municipio[1], municipio[2], municipio[3]]);
});

for (const codDep in deps) {
const yaExiste =
this.datosDepartamentos[año] && this.datosDepartamentos[año].find(([codigo]) => codigo === codDep);

if (yaExiste) {
// Ya existen datos departamentales, no hacer nada.
} else {
// No hay datos de este departamento en la tabla original, procesarlos con los datos que tenemos de los municipios.
const departamento = limpiarDepartamento(+codDep);

if (departamento.hasOwnProperty('error')) {
this.errata.push({ fila: Infinity, error: (departamento as Errata).mensaje });
} else {
if (!this.datosDepartamentos[año]) {
this.datosDepartamentos[año] = [];
}

const suma = deps[codDep].reduce(
(valorAnterior, valorActual) => [
valorAnterior[0] + valorActual[0],
valorAnterior[1] + valorActual[1],
valorAnterior[2] + valorActual[2],
],
[0, 0, 0]
);
if (this.estructura === 'conteo') {
this.revisarMinMax(suma[0], 'maxDep', 'minDep');
this.datosDepartamentos[año].push([(departamento as Departamento)[0], suma[0], suma[1], suma[2]]);
} else {
// const porcentaje = redondearDecimal(suma / deps[codDep].length, 1, 2);
// this.revisarMinMax(porcentaje, 'maxDep', 'minDep');
// this.datosDepartamentos[año].push([(departamento as Departamento)[0], porcentaje]);
}
}
}
}
}
}
}

procesarNacional() {
for (const año in this.datosDepartamentos) {
if (this.datosNacionales.datos[año]) {
this.revisarMinMax(this.datosNacionales.datos[año] as number, 'maxNal', 'minNal');
// Ya existen datos a nivel nacional para este año
} else {
// No hay datos nacionales, sacarlos a partir de los datos departamentales.
const datosAño = this.datosDepartamentos[año];
const suma = datosAño.reduce(
(depAnterior, valorActual) => [
'',
depAnterior[1] + valorActual[1],
depAnterior[2] + valorActual[2],
depAnterior[3] + valorActual[3],
],
['', 0, 0, 0]
);

if (this.estructura === 'conteo') {
this.revisarMinMax(suma[1], 'maxNal', 'minNal');
this.datosNacionales.datos[año] = [suma[1], suma[2], suma[3]];
} else {
// const porcentaje = redondearDecimal(suma[1] / datosAño.length, 1, 2);
// this.revisarMinMax(porcentaje, 'maxNal', 'minNal');
// this.datosNacionales.datos[año] = porcentaje;
}
}
}
}

registrarAño(
numeroFila: number,
año: number | string,
municipio: { datos: Municipio | Errata; valor?: number; categoria?: string } | null,
departamento?: { datos: Departamento | Errata; valor?: number; categoria?: string }
) {
if (año) {
if (esNumero(`${año}`)) {
const indice = parseInt(`${año}`.replace(',', ''));

if (!indice) {
console.log(año, indice, parseInt(`${año}`), esNumero(`${año}`));
}

if (!this.datosMunicipios[indice]) {
this.datosMunicipios[indice] = [];
}

if (!this.exportarMunicipios) {
if (!this.datosDepartamentos[indice]) {
this.datosDepartamentos[indice] = [];
}
}

if (municipio && municipio.valor) {
const codMunicipio = (municipio.datos as Municipio)[3];
let existe = this.datosMunicipios[indice].find(([lugar]) => lugar === codMunicipio);

if (!existe) {
existe = [(municipio.datos as Municipio)[3], 0, 0, 0];

if (municipio.categoria && municipio.categoria === 'NO_OFICIAL') {
existe[3] = redondearDecimal(municipio.valor, 1, 2);
} else if (municipio.categoria && municipio.categoria === 'OFICIAL') {
existe[2] = redondearDecimal(municipio.valor, 1, 2);
}

existe[1] = existe[3] + existe[2];
this.revisarMinMax(existe[1], 'maxMun', 'minMun');

this.datosMunicipios[indice].push(existe);
} else {
if (municipio.categoria && municipio.categoria === 'NO_OFICIAL') {
existe[3] = redondearDecimal(municipio.valor, 1, 2);
} else if (municipio.categoria && municipio.categoria === 'OFICIAL') {
existe[2] = redondearDecimal(municipio.valor, 1, 2);
}

existe[1] = existe[3] + existe[2];

this.revisarMinMax(existe[1], 'maxMun', 'minMun');
}
}

if (departamento && departamento.valor) {
// this.datosDepartamentos[indice].push([
// (departamento.datos as Departamento)[0],
// redondearDecimal(departamento.valor, 1, 2),
// ]);
}
} else {
this.errata.push({ fila: numeroFila, error: `El año ${año} no es número.` });
}
} else {
this.errata.push({ fila: numeroFila, error: `No hay año en esta fila, sino ${año}` });
}
}

revisarMinMax(valor: number, llaveMax: 'maxNal' | 'maxDep' | 'maxMun', llaveMin: 'minNal' | 'minDep' | 'minMun') {
if (this.datosNacionales[llaveMax] < valor) {
this.datosNacionales[llaveMax] = valor;
}

if (this.datosNacionales[llaveMin] > valor) {
this.datosNacionales[llaveMin] = valor;
}
}
}
15 changes: 14 additions & 1 deletion aplicaciones/procesador/fuente/tipos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export type RespuestaPorcentaje = {
[año: string]: [lugar: string, porcentaje: number, variable2?: number][];
};

export type RespuestaPorcentaje2 = {
[año: string]: [lugar: string, total: number, noOficial: number, oficial: number][];
};

export type RespuestaCategorias = {
[año: string]: [lugar: string, valor: { [categoria: string]: number }][];
};
Expand Down Expand Up @@ -126,12 +130,21 @@ export type VariableValorSingular =
| 'porcentaje'
| 'P51'
| 'educ_inicial_icbf'
| 'porcentaje_nacidos_vivos_personal_calificado';
| 'porcentaje_nacidos_vivos_personal_calificado'
| '#_estudiantes';

export type VariablesSingulares = {
[llave in VariableValorSingular]: number;
};

export type VariableDoble = {
'#_estudiantes': number;
sector: string;
codmpio: number;
anno: number;
coddepto?: number;
};

export type VariablesNumDen = {
anno: string;
departamento: string;
Expand Down
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions aplicaciones/www/estaticos/datos/ya2-7-dep.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"2012":[["11",926593,818163,108430],["13",454802,423276,31526],["15",264833,262294,2539],["17",177125,177125,0],["18",117870,117723,147],["19",313467,311608,1859],["20",253256,250853,2403],["23",417893,412871,5022],["25",460374,435830,24544],["27",143595,143595,0],["41",247928,247791,137],["44",201408,200632,776],["47",325943,322831,3112],["50",196494,186920,9574],["52",354974,353857,1117],["54",271258,268455,2803],["63",105514,105514,0],["66",186592,184846,1746],["68",371382,364050,7332],["70",208855,208099,756],["73",278607,276363,2244],["76",716351,589574,126777],["81",59947,59947,0],["85",95122,95122,0],["86",85159,85159,0],["88",9997,9997,0],["91",20481,19871,610],["94",10215,10215,0],["95",21745,21745,0],["97",9237,9237,0],["99",15489,15489,0],["05",1203211,1079651,123560],["08",413486,363998,49488]],"2020":[["11",1306724,797970,508754],["13",523545,421016,102529],["15",248020,201034,46986],["17",158181,137141,21040],["18",100859,90518,10341],["19",285440,256187,29253],["20",306096,256900,49196],["23",408436,356926,51510],["25",626289,409604,216685],["27",136167,133518,2649],["41",254030,219710,34320],["44",266943,245038,21905],["47",368756,321485,47271],["50",234258,189269,44989],["52",301235,271890,29345],["54",326862,268950,57912],["63",90879,78780,12099],["66",181560,152018,29542],["68",442253,347043,95210],["70",224737,198759,25978],["73",278118,231581,46537],["76",797949,528058,269891],["81",71004,66418,4586],["85",100054,91046,9008],["86",77515,75274,2241],["88",11606,8753,2853],["91",21505,20773,732],["94",13256,13122,134],["95",21874,20276,1598],["97",10031,9925,106],["99",22272,21937,335],["05",1245126,1013554,231572],["08",561076,381435,179641]],"2021":[["11",1263840,805425,458415],["13",526471,432599,93872],["15",248350,205505,42845],["17",157444,137133,20311],["18",96489,87890,8599],["19",289130,262287,26843],["20",305487,262944,42543],["23",406104,361354,44750],["25",619040,416537,202503],["27",143813,141157,2656],["41",254037,223644,30393],["44",286666,268720,17946],["47",372835,333287,39548],["50",232792,190926,41866],["52",294817,267538,27279],["54",336605,282101,54504],["63",88677,77376,11301],["66",180998,154895,26103],["68",441962,351767,90195],["70",224351,202846,21505],["73",276969,235986,40983],["76",784786,534261,250525],["81",73309,68794,4515],["85",100050,92466,7584],["86",78218,76016,2202],["88",11184,8923,2261],["91",21838,21118,720],["94",14599,14204,395],["95",22028,20353,1675],["97",10785,10659,126],["99",24307,23997,310],["05",1224285,1001356,222929],["08",567005,390001,177004]],"2022":[["11",1237299,775856,461443],["13",532729,428685,104044],["15",245151,199003,46148],["17",152316,131653,20663],["18",93279,83873,9406],["19",289294,260326,28968],["20",306962,258047,48915],["23",402462,350729,51733],["25",627651,413055,214596],["27",151008,147959,3049],["41",254010,218048,35962],["44",292976,272325,20651],["47",393798,346741,47057],["50",237315,189633,47682],["52",288779,258021,30758],["54",340730,281076,59654],["63",87829,75917,11912],["66",179029,150432,28597],["68",444630,345473,99157],["70",222240,197358,24882],["73",274933,227467,47466],["76",774534,513503,261031],["81",70629,65317,5312],["85",99325,90440,8885],["86",74638,72156,2482],["88",11486,8847,2639],["91",21165,20343,822],["94",13007,12651,356],["95",21862,19803,2059],["97",10328,10181,147],["99",25192,24868,324],["05",1211860,986159,225701],["08",577765,378829,198936]],"2023":[["11",1214728,761651,453077],["13",531175,418359,112816],["15",240085,192786,47299],["17",146606,125594,21012],["18",91373,82054,9319],["19",285888,255605,30283],["20",304519,252468,52051],["23",395214,345382,49832],["25",622118,407517,214601],["27",152328,148738,3590],["41",251103,213127,37976],["44",294449,271327,23122],["47",380227,329152,51075],["50",236086,185026,51060],["52",277830,246652,31178],["54",339440,277353,62087],["63",85337,73285,12052],["66",172555,143961,28594],["68",439372,337362,102010],["70",216903,189851,27052],["73",267222,217964,49258],["76",750687,490414,260273],["81",69866,64009,5857],["85",98893,89355,9538],["86",75154,72435,2719],["88",11408,8449,2959],["91",20348,19498,850],["94",13855,13571,284],["95",21582,19502,2080],["97",10156,10023,133],["99",25556,25219,337],["05",1181738,960389,221349],["08",576333,372713,203620]]}
1 change: 1 addition & 0 deletions aplicaciones/www/estaticos/datos/ya2-7-mun.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions aplicaciones/www/estaticos/datos/ya2-7-nal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"ascendente":true,"estructura":"conteo","unidadMedida":1,"datos":{"2012":[8939203,8432701,506502],"2020":[10022656,7835908,2186748],"2021":[9979271,7964065,2015206],"2022":[9966211,7814774,2151437],"2023":[9800134,7620791,2179343]},"datosMunicipio":true,"maxNal":10022656,"minNal":8939203,"maxDep":1306724,"minDep":9237,"maxMun":1306724,"minMun":1}
3 changes: 2 additions & 1 deletion aplicaciones/www/src/componentes/DescripcionYa.astro
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ if (definicion) {
const maximos = definirMedidasMax(respuesta.maxNal, respuesta, umbral);

for (const año in respuesta.datos) {
ordenados.push({ año, valor: respuesta.datos[año] });
const valor = Array.isArray(respuesta.datos[año]) ? respuesta.datos[año][0] : respuesta.datos[año];
ordenados.push({ año, valor });
}

const posX = (valor: number) => {
Expand Down
2 changes: 1 addition & 1 deletion aplicaciones/www/src/componentes/Linea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class Linea {
punto.onmouseenter = (evento) => {
const x = evento.pageX;
const y = evento.pageY;
informacion.innerText = `${nombre} en ${año}: ${valor}${
informacion.innerText = `${nombre} en ${año}: ${new Intl.NumberFormat('de-DE').format(valor)}${
unidad.toLocaleLowerCase() === 'porcentaje' ? '%' : ''
}`;
informacion.classList.add('visible');
Expand Down
5 changes: 4 additions & 1 deletion aplicaciones/www/src/componentes/LineaTiempo.astro
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,10 @@ const { alto, meta, umbral } = Astro.props;
const lineaNacional = new Linea(
contenedorLineas,
'Colombia',
lista,
lista.map((obj) => {
obj.valor = obj.valor ? (Array.isArray(obj.valor) ? obj.valor[0] : obj.valor) : obj.valor;
return obj;
}),
obtenerVariableCSS('--fucsiaEsmalte'),
visualizaciones.dataset.unidad
);
Expand Down
Loading

0 comments on commit a843238

Please sign in to comment.