Public
Edited
May 25
Insert cell
Insert cell
workbook = FileAttachment("DatosParaTFM@1.xlsx").xlsx()
Insert cell
workbook.sheetNames
Insert cell
data1 = workbook.sheet(0, {
headers: true,
// range: "A1:J10"
})
Insert cell
data1
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
grpCartera = {
return Array.from(
d3.group(data1, d => d.Cartera),
([Cartera, values]) => ({
Cartera,
Saldo: d3.sum(values, d => +(d.Saldo / 1e6)),
Cobrado: d3.sum(values, d => +(d.Cobrado/ 1e6)),
Por_Cobrar: d3.sum(values, d => +(d.PorCobrar/ 1e6)),
Operaciones: d3.sum(values, d => +d.Operaciones),
Provisiones: d3.sum(values, d => +(d.Provisiones/ 1e6))
})
);
}
Insert cell
import {Plot} from "@observablehq/plot"
Insert cell
Insert cell
Plot.plot({ height: 400, width: 800,
x:{label: "Carteras"},
y:{label: "Saldos (en millones)"},
marks:[
Plot.barY(grpCartera,{
x: "Cartera",
y: "Saldo",
fill: "Cartera",
title: d => `Saldo: $${(d.Saldo ).toFixed(2)}M`
})
]
})
Insert cell
Insert cell
grpCarteraAnio = {
return Array.from(
d3.group(data1, d => d.Cartera, d => d.Año),
([Cartera, anioMap]) =>
Array.from(anioMap, ([Año, values]) => ({
Cartera,
Año,
Saldo: d3.sum(values, d => +(d.Saldo / 1e6)),
Cobrado: d3.sum(values, d => +(d.Cobrado / 1e6)),
Por_Cobrar: d3.sum(values, d => +(d.PorCobrar / 1e6)),
Operaciones: d3.sum(values, d => +d.Operaciones),
Provisiones: d3.sum(values, d => +(d.Provisiones / 1e6))
}))
).flat();
}
Insert cell
Insert cell
viewof anioSeleccionado = Inputs.select(
Array.from(new Set(data1.map(d => d.Año))).sort(),
{ label: "Selecciona el año" }
)
Insert cell
Insert cell
Plot.plot({ height: 400, width: 800,
y:{label: "Carteras",
tickRotate: -90},
x:{label: "Saldos (en millones)"},
marks:[
Plot.barX(grpCarteraAnio.filter(d => d.Año === anioSeleccionado),{
y: "Cartera",
x: "Saldo",
fill: "Cartera",
title: d => `${d.Año} - $Saldo: $${(d.Saldo ).toFixed(2)}M`
})
]
})
Insert cell
Insert cell
Insert cell
viewof carteraSeleccionada = Inputs.select(
Array.from(new Set(data1.map(d => d.Cartera))),
{label: "Selecciona la cartera"}
)
Insert cell
Insert cell
Plot.plot({
width: 700,
height: 400,
x: {
label: "Mes",
tickFormat: d => `Mes ${d}`
},
y: {
label: "Año",
reverse: true, // años descendentes de arriba hacia abajo
type: "band"
},
color: {
legend: true,
label: "Cobrado (color)"
},
marks: [
// Círculos codificados por color y tamaño
Plot.dot(data1.filter(d => d.Cartera === carteraSeleccionada), {
x: "Mes",
y: "Año",
r: d => Math.sqrt(d.Cobrado), // radio proporcional
fill: d => d.Cobrado, // color por valor
stroke: "black", // redundancia visual
title: d => `Año ${d.Año}, Mes ${d.Mes}\n$${d.Cobrado.toFixed(2)}`
}),

// Etiquetas con valores redondeados
Plot.text(data1.filter(d => d.Cartera === carteraSeleccionada), {
x: "Mes",
y: "Año",
text: d => d.Cobrado.toFixed(0),
dy: 5,
fontSize: 10,
textAnchor: "middle"
})
]
})
Insert cell
Insert cell
Plot.plot({
width: 700,
height: 400,
x: {
label: "Mes",
tickFormat: d => `Mes ${d}`
},
y: {
label: "Año",
reverse: true,
type: "band"
},
color: {
legend: true,
label: "Operaciones (color)"
},
marks: [
// Círculos con codificación por color y tamaño
Plot.dot(data1.filter(d => d.Cartera === carteraSeleccionada), {
x: "Mes",
y: "Año",
r: d => Math.sqrt(d.Operaciones),
fill: d => d.Operaciones,
stroke: "black", // codificación redundante (borde)
title: d => `Año ${d.Año}, Mes ${d.Mes}\nOperaciones: ${d.Operaciones}`
}),

// Texto sobre los círculos
Plot.text(data1.filter(d => d.Cartera === carteraSeleccionada), {
x: "Mes",
y: "Año",
text: d => d.Operaciones,
dy: 5,
fontSize: 10,
textAnchor: "middle"
})
]
})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more