Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
csvURL = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQnHgas3xU6bgePkI9MTVl69yScquadmlP0iTAvKm6G9I_V0t7Rb21shTF0bo1kOA/pub?gid=1422083165&single=true&output=csv"
Insert cell
rawData = d3.csv(csvURL)
Insert cell
data = rawData.map(item => {
return {
...item,
H: parseInt(item.H),
M: parseInt(item.M),
total: parseInt(item.total),
anio: parseInt(item.anio),
};
});
Insert cell
plotLineFunc = (anio, color) => {
return Plot.lineY(
Array.from(d3.rollup(dataMeses.filter(item => item.anio === anio),
v => d3.sum(v, d => d.subtotal),
d => d.mes), ([mes, total]) => ({anio, mes, total})),
{
x: d=>+d.mes,
y: d=>+d.total,
stroke: color,
tip: true
}
);
};
Insert cell
plotDotFunc = (anio, color) => {
return Plot.dot(
Array.from(d3.rollup(dataMeses.filter(item => item.anio === anio),
v => d3.sum(v, d => d.subtotal),
d => d.mes), ([mes, total]) => ({anio, mes, total})),
{
x: d=>+d.mes,
y: d=>+d.total,
fill: color,
tip: true
}
);
};
Insert cell
textMarkFunc = (anio, color) => {
return Plot.text(
Array.from(d3.rollup(dataMeses.filter(item => item.anio === anio),
v => d3.sum(v, d => d.subtotal),
d => d.mes), ([mes, total]) => ({anio, mes, total})),
Plot.selectMaxY({
x: d=>+d.mes,
y: d=>+d.total,
text: d => d.anio,
dy: -10,
fill: color,
stroke: "white",
strokeWidth: 5,
})
);
};
Insert cell
function rollupData(data, key, valueKey) {
return Array.from(
d3.rollup(
data,
v => d3.sum(v, d => d[valueKey]),
d => d[key]
),
([keyValue, total]) => ({[key]: keyValue, total})
);
}

Insert cell
function rollupAndFlattenData(data, keys, value) {
// Rollup data
const rollupDataKeys = Array.from(
d3.rollup(
data,
v => d3.sum(v, d => d[value]),
d => d[keys[0]],
d => d[keys[1]],
),
([keyName, total]) => ({keyName, total})
);

// Flatten total
let result = [];
rollupDataKeys.forEach(obj => {
obj.total.forEach((value, key) => {
let item = {};
item[keys[0]] = obj.keyName;
item['total'] = value;
item[keys[1]] = key;
result.push(item);
});
});
return result;
}
Insert cell
topAmeCen = Array.from(d3.group(data.filter(item => item.region == "América Central" && item.anio == "2023").sort((a, b) => b.total - a.total).slice(0, 5), d => d.pais)).map(item => item[0])
Insert cell
topAmeSur = Array.from(d3.group(data.filter(item => item.region == "América del Sur" && item.anio == "2023").sort((a, b) => b.total - a.total).slice(0, 5), d => d.pais)).map(item => item[0])
Insert cell
topIslasCar = Array.from(d3.group(data.filter(item => item.region == "Islas del Caribe" && item.anio == "2023").sort((a, b) => b.total - a.total).slice(0, 5), d => d.pais)).map(item => item[0])
Insert cell
topAfrica = Array.from(d3.group(data.filter(item => item.region == "África" && item.anio == "2023").sort((a, b) => b.total - a.total).slice(0, 5), d => d.pais)).map(item => item[0])
Insert cell
topAsia = Array.from(d3.group(data.filter(item => item.region == "Asia" && item.anio == "2023").sort((a, b) => b.total - a.total).slice(0, 5), d => d.pais)).map(item => item[0])
Insert cell
filteredCountry = data.filter(item => regionSelection.includes(item.region));
Insert cell
filteredData = data.filter(item => countrySelection.includes(item.pais));
Insert cell
filteredTableData = yearSelection.sort((a, b) => b.total - a.total)
.filter(item => regionTableSelection.includes(item.region));
Insert cell
countryData = data.filter(item => country.includes(item.pais));
Insert cell
yearsCountriesInterval = Array.from({length: yearsCountries[1] - yearsCountries[0] + 1}, (_, i) => yearsCountries[0] + i).toString();
Insert cell
yearsRegionInterval = Array.from({length: yearsRegions[1] - yearsRegions[0] + 1}, (_, i) => yearsRegions[0] + i).toString();
Insert cell
yearsCountryInterval = Array.from({length: yearsCountry[1] - yearsCountry[0] + 1}, (_, i) => yearsCountry[0] + i).toString();
Insert cell
csvMesesURL = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQnHgas3xU6bgePkI9MTVl69yScquadmlP0iTAvKm6G9I_V0t7Rb21shTF0bo1kOA/pub?gid=751854368&single=true&output=csv"
Insert cell
rawDataMeses = d3.csv(csvMesesURL)
Insert cell
dataMeses = rawDataMeses.map(item => {
return {
...item,
canalizados: parseInt(item.canalizados),
presentados: parseInt(item.presentados),
subtotal: parseInt(item.subtotal),
mes: parseInt(item.mes),
};
});
Insert cell
filteredCountry2024 = dataMeses.filter(item => region2024Selection.includes(item.region));
Insert cell
filteredData2024 = dataMeses.filter(item => country2024Selection.includes(item.pais) && item.anio === "2024");
Insert cell
filteredTableData2024 = dataMeses.filter(item => regionTable2024Selection.includes(item.region) && item.anio === "2024");
Insert cell
total2024 = Array.from(d3.rollup(filteredTableData2024, v => d3.sum(v, d => d.subtotal), d => d.pais), ([pais, total]) => ({pais, total}));
Insert cell
function processAnio(data, year, rollupData) {
let dataAnio = data.filter(d => d.anio == year);
let totalAnio = rollupData(data, 'anio', 'total').filter(d => d.anio == year);

let percentageAnio = dataAnio.map((item, index) => {
let percentage = (item.total / totalAnio[0].total) * 100;
return {
pais: item.pais,
percentage: percentage
};
});

return percentageAnio;
}
Insert cell
percentageAnio = processAnio(data, selectProcessAnio, rollupData)
Insert cell
function processPercentage(data, n) {
// Sort the array in descending order based on the 'percentage' property
data.sort((a, b) => b.percentage - a.percentage);

// Take the top n values
let top = data.slice(0, n-1);

// Get the remaining values
let remaining = data.slice(n-1);

// Sum the 'percentage' values of the remaining objects
let otherPercentage = remaining.reduce((sum, item) => sum + item.percentage, 0);

// Create a new object for 'Other'
let other = {
pais: 'Otros',
percentage: otherPercentage
};

// Add the new object to the array
top.push(other);

return top;
}

Insert cell
percentageAnioProcessed = processPercentage(percentageAnio, rangeTopAnio);
Insert cell
anioSexo = Array.from(d3.rollup(data,
v => {
let H = d3.sum(v, d => d.H);
let M = d3.sum(v, d => d.M);
return {H, M, total: H + M};
},
d => d.anio
)).map(([anio, value]) => ({anio, ...value}));
Insert cell
function rollupDataKeysValues(data, keys, value1, value2) {
// Rollup data
const rollupDataKeys = Array.from(
d3.rollup(
data,
v => ({sum1: d3.sum(v, d => d[value1]), sum2: d3.sum(v, d => d[value2])}),
d => d[keys[0]],
d => d[keys[1]],
),
([keyName, total]) => ({keyName, total})
);

// Flatten total
let result = [];
rollupDataKeys.forEach(obj => {
obj.total.forEach((value, key) => {
let item = {};
item[keys[0]] = obj.keyName;
item[value1[0]] = value.sum1;
item[value2[0]] = value.sum2;
item['total'] = value.sum1 + value.sum2
item[value1[0]+'_per'] = Math.round((value.sum1 / item['total']) * 100);
item[value2[0]+'_per'] = Math.round((value.sum2 / item['total']) * 100);
item[keys[1]] = key;
result.push(item);
});
});
return result;
}

Insert cell
regionAnioSexo = rollupDataKeysValues(data, ['region', 'anio'], 'H', 'M')
Insert cell
paisAnioSexo = rollupDataKeysValues(data, ['pais', 'anio'], 'H', 'M')
Insert cell
Insert cell
import {searchCheckbox} from "@john-guerra/search-checkbox"
Insert cell
import {interval} from '@mootari/range-slider'
Insert cell
import {theme_Flat} from '@mootari/range-slider'

Insert cell
d3 = require("d3@6")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
test = data.filter(d => d.pais == countryDots && (d.anio == "2021" || d.anio == "2023"))
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more