Public
Edited
Apr 21
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof color_steps = slider({
min: 0,
max: 30,
step: 1,
value: 10,
title: "Cantidad de colores",
description: "Control para la cantidad de colores a visualizar en la paleta."
})
Insert cell
// Ejemplo, se pueden definir colores mediante HEX, nombre, HSL, RGB/RGBA
swatches(["#ff3399", "hotpink", "hsl(330, 100%, 70.5%)", "rgba(128, 0, 128, 0.2)"])
Insert cell
// Resolución ejercicio a)
Insert cell
viewof pasosPaleta1 = slider({
title: "Paleta 1",
description: "Número de colores",
min: 0, max: 5, step: 1, value: 5
})
Insert cell
paleta1 = ["#f16a6b","#fecb67","#8ad55a","#3f92d2","#7a57ad"]
.slice(0, pasosPaleta1)
Insert cell
swatches(paleta1)
Insert cell
viewof pasosPaleta2 = slider({
title: "Paleta 2",
description: "Número de colores",
min: 0, max: 20, step: 1, value: 10
})
Insert cell
paleta2 = d3.quantize(d3.interpolateInferno, pasosPaleta2)
Insert cell
swatches(paleta2)
Insert cell
viewof pasosPaleta3 = slider({
title: "Paleta 3",
description: "Número de colores",
min: 2, max: 11, step: 1, value: 11
})
Insert cell
paleta3 = [
"#f2dcd2","#e7c9b9","#dbc2af","#d0b7a5","#c5ae9c",
"#baa493","#ae9a8a","#a39081","#988779","#8d7e70","#827568"
].slice(0, pasosPaleta3)
Insert cell
swatches(paleta3)
Insert cell
viewof pasosPaleta4 = slider({
title: "Paleta 4",
description: "Número de colores",
min: 2, max: 20, step: 1, value: 10
})
Insert cell
paleta4 = d3.quantize(d3.interpolateBlues, pasosPaleta4).reverse()
Insert cell
swatches(paleta4)
Insert cell
Insert cell
viewof lum_steps = slider({
min: 0,
max: 100,
step: 1,
value: 10,
title: "Luminosidad",
description: "Control para la luminosidad del color."
})
Insert cell
// Resolución ejercicio b)
Insert cell
paleta2_lum = paleta2.map(c => {
// parseamos each color a HSL
const hsl = d3.hsl(c);
// escalamos la luminosidad: 50 → factor 1, 0 → 0, 100 → 2
const factor = lum_steps / 50;
// multiplicamos y clavamos en [0,1]
const l = Math.max(0, Math.min(hsl.l * factor, 1));
// reconvertimos a CSS
return d3.hsl(hsl.h, hsl.s, l).toString();
})

Insert cell
swatches(paleta2_lum)

Insert cell
Insert cell
// Resolución ejercicio c)
Insert cell
url = "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/iris.csv"

Insert cell
data = (await d3.csv(url)).map(d => {
const sl = +d.Sepal_Length,
pl = +d.Petal_Length,
pw = +d.Petal_Width;
return {
longitud_sepalo: sl,
longitud_petalo: pl,
especie: d.Species,
area_petalo: (pl * pw) / 2
};
})

Insert cell
viewof miTabla = {
const cols = Object.keys(data[0]);
return html`<table style="border-collapse: collapse; width: 100%;">
<thead>
<tr>${cols.map(c => html`<th style="border:1px solid #aaa; padding:4px;">${c}</th>`)}</tr>
</thead>
<tbody>
${data.map(d =>
html`<tr>
${cols.map(c => html`<td style="border:1px solid #ddd; padding:4px;">${d[c]}</td>`)}
</tr>`
)}
</tbody>
</table>`;
}

Insert cell
Insert cell
// Resolución ejercicio d)
Insert cell
width = 350
Insert cell
height = 350
Insert cell
x = d3.scaleLinear()
.domain(d3.extent(data, d => d.longitud_sepalo)) // [mín, máx] de sépalos
.range([0, width])
Insert cell
y = d3.scaleLinear()
.domain(d3.extent(data, d => d.longitud_petalo)) // [mín, máx] de pétalos
.range([height, 0])
Insert cell
Insert cell
color = d3.scaleOrdinal()
.domain([...new Set(data.map(d => d.especie))]) // todas las especies únicas
.range(d3.schemeCategory10) // paleta de 10 colores

Insert cell
chart = {
// 1. Parámetros
const width = 350,
height = 350,
margin = { top: 20, right: 20, bottom: 30, left: 40 };

// 2. Crear SVG con espacio para márgenes
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);

// 3. Grupo que respeta los márgenes
const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

// 4. Ejes
g.append("g")
.call(d3.axisLeft(y));

g.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));

// 5. Puntos del scatter
g.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", d => x(d.longitud_sepalo))
.attr("cy", d => y(d.longitud_petalo))
.attr("r", 3)
.attr("fill", d => color(d.especie));

// 6. Texto identificativo (opcional)
svg.append("text")
.attr("x", margin.left + width/2)
.attr("y", margin.top - 5)
.attr("text-anchor", "middle")
.text("Iris: Sepal vs. Petal");

// 7. Retornar el nodo SVG
return svg.node();
}

Insert cell
Insert cell
colorArea = d3.scaleSequential(d3.interpolateViridis)
.domain(d3.extent(data, d => d.area_petalo))
Insert cell
r = d3.scaleSqrt()
.domain(d3.extent(data, d => d.area_petalo))
.range([2, 12])
Insert cell
chartArea = {
const width = 350,
height = 350,
margin = { top: 20, right: 100, bottom: 30, left: 40 };

// SVG con espacio para leyenda a la derecha
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);

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

// Ejes
g.append("g").call(d3.axisLeft(y));
g.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));

// Puntos
g.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", d => x(d.longitud_sepalo))
.attr("cy", d => y(d.longitud_petalo))
.attr("r", d => r(d.area_petalo))
.attr("fill", d => colorArea(d.area_petalo))
.attr("opacity", 0.8);

// Leyenda de color y tamaño
const legendValues = d3.ticks(...d3.extent(data, d=>d.area_petalo), 5);

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

// Título de leyenda
legend.append("text")
.attr("y", -10)
.attr("font-weight", "bold")
.text("area_petalo");

// Círculos de ejemplo
legend.selectAll("circle")
.data(legendValues)
.join("circle")
.attr("cy", (d,i) => i * 25)
.attr("r", d => r(d))
.attr("fill", d => colorArea(d));

// Etiquetas numéricas
legend.selectAll("text.value")
.data(legendValues)
.join("text")
.attr("class", "value")
.attr("x", r(d3.max(legendValues)) + 5)
.attr("dy", "0.35em")
.attr("y", (d,i) => i * 25)
.text(d => d.toFixed(1));

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