Public
Edited
May 13
Fork of d3.scale( )
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
datosMigrantes = FileAttachment("migrantes_d3.csv").csv()


Insert cell
datosMigrantes.slice(0, 5)

Insert cell
// Agrupar por región y sumar muertos
mortalidadPorRegion = {
let resultado = d3.rollups(
datosMigrantes,
v => d3.sum(v, d => +d["Total Number of Dead and Missing"]),
d => d["Region of Incident"]
);
return resultado.map(([region, total]) => ({ region, total }));
}

Insert cell
grafico = {
const svg = d3.create("svg")
.attr("width", 800)
.attr("height", 400);

const margin = {top: 30, right: 30, bottom: 100, left: 60};
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;

const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

const x = d3.scaleBand()
.domain(mortalidadPorRegion.map(d => d.region))
.range([0, width])
.padding(0.2);

const y = d3.scaleLinear()
.domain([0, d3.max(mortalidadPorRegion, d => d.total)])
.nice()
.range([height, 0]);

g.append("g")
.call(d3.axisLeft(y));

g.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(x))
.selectAll("text")
.attr("transform", "rotate(-40)")
.style("text-anchor", "end");

g.selectAll("rect")
.data(mortalidadPorRegion)
.join("rect")
.attr("x", d => x(d.region))
.attr("y", d => y(d.total))
.attr("width", x.bandwidth())
.attr("height", d => height - y(d.total))
.attr("fill", "steelblue");

return svg.node();
}

Insert cell
Insert cell
graficoDispersión = {
const width = 800;
const height = 500;
const margin = { top: 40, right: 30, bottom: 70, left: 70 };

const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);

const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

const x = d3.scaleLinear()
.domain(d3.extent(datosMigrantes, d => +d["Incident Year"]))
.range([0, width - margin.left - margin.right]);

const y = d3.scaleLinear()
.domain([0, d3.max(datosMigrantes, d => +d["Total Number of Dead and Missing"])])
.nice()
.range([height - margin.top - margin.bottom, 0]);

const color = d3.scaleOrdinal(d3.schemeCategory10);

const radius = d3.scaleSqrt()
.domain([0, d3.max(datosMigrantes, d => +d["Number of Children"])])
.range([2, 20]);

g.append("g")
.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.format("d")));

g.append("g")
.call(d3.axisLeft(y));

g.selectAll("circle")
.data(datosMigrantes.filter(d => d["Incident Year"] && d["Total Number of Dead and Missing"]))
.join("circle")
.attr("cx", d => x(+d["Incident Year"]))
.attr("cy", d => y(+d["Total Number of Dead and Missing"]))
.attr("r", d => radius(+d["Number of Children"]))
.attr("fill", d => color(d["Region of Incident"]))
.attr("opacity", 0.6);

return svg.node();
}

Insert cell
graficoDispersiónConTexto = {
const width = 800;
const height = 500;
const margin = { top: 40, right: 30, bottom: 70, left: 70 };

const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);

const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

const x = d3.scaleLinear()
.domain(d3.extent(datosMigrantes, d => +d["Incident Year"]))
.range([0, width - margin.left - margin.right]);

const y = d3.scaleLinear()
.domain([0, d3.max(datosMigrantes, d => +d["Total Number of Dead and Missing"])])
.nice()
.range([height - margin.top - margin.bottom, 0]);

const color = d3.scaleOrdinal(d3.schemeCategory10);

const radius = d3.scaleSqrt()
.domain([0, d3.max(datosMigrantes, d => +d["Number of Children"])])
.range([2, 20]);

const puntos = datosMigrantes.filter(d =>
d["Incident Year"] &&
d["Total Number of Dead and Missing"] > 100 &&
d["Number of Children"] > 0
).slice(0, 50); // mostrar solo 50 para que no se sobrecargue

g.append("g")
.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.format("d")));

g.append("g")
.call(d3.axisLeft(y));

g.selectAll("circle")
.data(puntos)
.join("circle")
.attr("cx", d => x(+d["Incident Year"]))
.attr("cy", d => y(+d["Total Number of Dead and Missing"]))
.attr("r", d => radius(+d["Number of Children"]))
.attr("fill", d => color(d["Region of Incident"]))
.attr("opacity", 0.6);

g.selectAll("text")
.data(puntos)
.join("text")
.attr("x", d => x(+d["Incident Year"]))
.attr("y", d => y(+d["Total Number of Dead and Missing"]) - 5)
.text(d => d["Region of Incident"])
.attr("font-size", "10px")
.attr("text-anchor", "middle")
.attr("fill", "#333");

return svg.node();
}

Insert cell
graficoDispersiónConTextoClaro = {
const width = 800;
const height = 500;
const margin = { top: 40, right: 30, bottom: 70, left: 70 };

const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);

const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

const x = d3.scaleLinear()
.domain(d3.extent(datosMigrantes, d => +d["Incident Year"]))
.range([0, width - margin.left - margin.right]);

const y = d3.scaleLinear()
.domain([0, d3.max(datosMigrantes, d => +d["Total Number of Dead and Missing"])])
.nice()
.range([height - margin.top - margin.bottom, 0]);

const color = d3.scaleOrdinal(d3.schemeCategory10);

const radius = d3.scaleSqrt()
.domain([0, d3.max(datosMigrantes, d => +d["Number of Children"])])
.range([2, 20]);

// Filtrar eventos más relevantes
const puntos = datosMigrantes
.filter(d =>
d["Incident Year"] &&
+d["Total Number of Dead and Missing"] > 200 &&
+d["Number of Children"] > 5
)
.slice(0, 20); // Mostrar solo 20 eventos

// Ejes
g.append("g")
.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.format("d")));

g.append("g")
.call(d3.axisLeft(y));

// Círculos
g.selectAll

Insert cell
graficoDispersiónConTextoClaro = {
const width = 800;
const height = 500;
const margin = { top: 40, right: 30, bottom: 70, left: 70 };

const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);

const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

const x = d3.scaleLinear()
.domain(d3.extent(datosMigrantes, d => +d["Incident Year"]))
.range([0, width - margin.left - margin.right]);

const y = d3.scaleLinear()
.domain([0, d3.max(datosMigrantes, d => +d["Total Number of Dead and Missing"])])
.nice()
.range([height - margin.top - margin.bottom, 0]);

const color = d3.scaleOrdinal(d3.schemeCategory10);

const radius = d3.scaleSqrt()
.domain([0, d3.max(datosMigrantes, d => +d["Number of Children"])])
.range([2, 20]);

// Filtrar eventos más relevantes
const puntos = datosMigrantes
.filter(d =>
d["Incident Year"] &&
+d["Total Number of Dead and Missing"] > 200 &&
+d["Number of Children"] > 5
)
.slice(0, 20); // Mostrar solo 20 eventos

// Ejes
g.append("g")
.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.format("d")));

g.append("g")
.call(d3.axisLeft(y));

// Círculos
g.selectAll("circle")
.data(puntos)
.join("circle")
.attr("cx", d => x(+d["Incident Year"]))
.attr("cy", d => y(+d["Total Number of Dead and Missing"]))
.attr("r", d => radius(+d["Number of Children"]))
.attr("fill", d => color(d["Region of Incident"]))
.attr("opacity", 0.7);

// Etiquetas con separación
g.selectAll("text")
.data(puntos)
.join("text")
.attr("x", d => x(+d["Incident Year"]) + 8)
.attr("y", d => y(+d["Total Number of Dead and Missing"]) - 8)
.text(d => d["Region of Incident"])
.attr("font-size", "10px")
.attr("text-anchor", "start")
.attr("fill", "#333");

return svg.node();
}

Insert cell
Insert cell
Insert cell
Insert cell
data_raw = d3.csv(
"https://gist.githubusercontent.com/sandravizz/952b2c4b2b88a310bc5aaf371716593a/raw/c3725ac3c2bd0a70640a7f753e54ba1f88f74636/Berlin%2520airbnb%2520Nov%25202021",
d3.autoType
)
Insert cell
Insert cell
extent = d3.extent(data_raw, d => d.price)
Insert cell
Insert cell
data = data_raw.filter(d => d.price > 0 & d.price < 5000)
Insert cell
Insert cell
x = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d.price))
.range([0, 1300])
Insert cell
d3.extent(data, (d) => d.price)
Insert cell
x(500)
Insert cell
Insert cell
barcode1 = {
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, 100])
.style("overflow", "visible");

svg
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (d) => x(d.price))
.attr("y", 20)
.attr("width", 1)
.attr("height", 40);

return svg.node();
}
Insert cell
Insert cell
c = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d.price))
.range(["#06d6a0", "#f20666"])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
y = d3.scaleBand().rangeRound([0, 400]).padding(0.2).domain(room)
Insert cell
Insert cell
Insert cell
barcode3 = {
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height])
.style("overflow", "visible");

let o2 = d3
.scaleLinear()
.domain(d3.extent(data, (d) => d.price))
.range([0.4, 1]);

let c2 = d3
.scaleOrdinal()
.domain(room)
.range(["#f20666", "#06d6a0", "#662e9b", "#9EF211"]);

svg
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (d) => x(d.price))
.attr("y", (d) => y(d.room_type))
.attr("width", 1)
.attr("height", y.bandwidth())
.attr("fill", (d) => c2(d.room_type))
.attr("opacity", (d) => o2(d.price));

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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