Public
Edited
Apr 16
Insert cell
Insert cell
Insert cell
{
// Variables de visualización
const width = 800;
const height = 600;
const margin = {top: 50, right: 80, bottom: 60, left: 70};
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;


// Mapeo para los nombres de las columnas
const columnas = {
"Longitud de Sépalo": "longitud_sepalo",
"Ancho de Sépalo": "ancho_sepalo",
"Longitud de Pétalo": "longitud_petalo",
"Ancho de Pétalo": "ancho_petalo"
};

// Obtener las especies únicas
const especies = [...new Set(irisTransformado.map(d => d.especie))];
especies.unshift("Todas"); // Añadir la opción "Todas" al inicio

// Crear elementos de selección para ejes X, Y y especie
const formContainer = d3.create("div")
.style("margin-bottom", "20px")
.style("display", "flex")
.style("flex-wrap", "wrap")
.style("gap", "20px");

// Selector para el eje X
const xAxisSelector = formContainer.append("div").style("margin-right", "20px");
xAxisSelector.append("label")
.attr("for", "x-axis-select")
.text("Eje X: ")
.style("margin-right", "5px");

const xSelect = xAxisSelector.append("select")
.attr("id", "x-axis-select")
.style("padding", "5px");

Object.keys(columnas).forEach(nombre => {
xSelect.append("option")
.attr("value", columnas[nombre])
.text(nombre);
});

// Selector para el eje Y
const yAxisSelector = formContainer.append("div").style("margin-right", "20px");
yAxisSelector.append("label")
.attr("for", "y-axis-select")
.text("Eje Y: ")
.style("margin-right", "5px");

const ySelect = yAxisSelector.append("select")
.attr("id", "y-axis-select")
.style("padding", "5px");

Object.keys(columnas).forEach((nombre, i) => {
ySelect.append("option")
.attr("value", columnas[nombre])
.property("selected", i === 2) // Preseleccionar "Longitud de Pétalo" para el eje Y
.text(nombre);
});

// Selector para la especie
const speciesSelector = formContainer.append("div");
speciesSelector.append("label")
.attr("for", "species-select")
.text("Especie: ")
.style("margin-right", "5px");

const speciesSelect = speciesSelector.append("select")
.attr("id", "species-select")
.style("padding", "5px");

especies.forEach(especie => {
speciesSelect.append("option")
.attr("value", especie)
.text(especie);
});

// Crear el contenedor para el gráfico
const svgContainer = d3.create("div");

// Función para actualizar el gráfico
function updateChart() {
// Obtener los valores seleccionados
const xAttribute = xSelect.property("value");
const yAttribute = ySelect.property("value");
const selectedSpecies = speciesSelect.property("value");
// Filtrar los datos según la especie seleccionada
const filteredData = selectedSpecies === "Todas"
? irisTransformado
: irisTransformado.filter(d => d.especie === selectedSpecies);
// Crear escalas para los ejes X e Y
const x = d3.scaleLinear()
.domain(d3.extent(irisTransformado, d => d[xAttribute]))
.range([margin.left, width - margin.right])
.nice();
const y = d3.scaleLinear()
.domain(d3.extent(irisTransformado, d => d[yAttribute]))
.range([height - margin.bottom, margin.top])
.nice();
// Escala de colores
const color = d3.scaleOrdinal()
.domain(especies.filter(e => e !== "Todas"))
.range(d3.schemeCategory10);
// Limpiar el SVG anterior
svgContainer.html("");
// Crear nuevo SVG
const svg = svgContainer.append("svg")
.attr("width", width)
.attr("height", height);
// Añadir título
svg.append("text")
.attr("x", width / 2)
.attr("y", margin.top / 2)
.attr("text-anchor", "middle")
.style("font-size", "18px")
.style("font-weight", "bold")
.text(`${Object.keys(columnas).find(key => columnas[key] === xAttribute)} vs ${Object.keys(columnas).find(key => columnas[key] === yAttribute)}`);
// Añadir ejes
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x))
.append("text")
.attr("x", width - margin.right)
.attr("y", -10)
.attr("fill", "black")
.attr("text-anchor", "end")
.style("font-size", "14px")
.text(Object.keys(columnas).find(key => columnas[key] === xAttribute));
svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 15)
.attr("x", -margin.top)
.attr("dy", ".71em")
.attr("fill", "black")
.attr("text-anchor", "end")
.style("font-size", "14px")
.text(Object.keys(columnas).find(key => columnas[key] === yAttribute));
// Añadir puntos
svg.append("g")
.selectAll("circle")
.data(filteredData)
.join("circle")
.attr("cx", d => x(d[xAttribute]))
.attr("cy", d => y(d[yAttribute]))
.attr("r", 6)
.attr("fill", d => color(d.especie))
.attr("stroke", "white")
.attr("stroke-width", 1)
.attr("opacity", 0.7);
// Añadir leyenda si se muestran todas las especies
if (selectedSpecies === "Todas") {
const legend = svg.append("g")
.attr("transform", `translate(${width - margin.right + 20}, ${margin.top})`);
legend.append("text")
.attr("x", -10)
.attr("y", -10)
.attr("font-size", "12px")
.attr("font-weight", "bold")
.text("Especies");
especies.filter(e => e !== "Todas").forEach((especie, i) => {
const legendRow = legend.append("g")
.attr("transform", `translate(0, ${i * 20})`);
legendRow.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 5)
.attr("fill", color(especie));
legendRow.append("text")
.attr("x", 10)
.attr("y", 4)
.attr("font-size", "10px")
.text(especie);
});
}
}

// Configurar event listeners para actualizar el gráfico cuando cambian las selecciones
xSelect.on("change", updateChart);
ySelect.on("change", updateChart);
speciesSelect.on("change", updateChart);

// Dibujar el gráfico inicial
updateChart();

// Crear un div contenedor para todo
const container = d3.create("div");
container.append(() => formContainer.node());
container.append(() => svgContainer.node());

return container.node();
}
Insert cell
iris = d3.csv("https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv", d3.autoType)
Insert cell
irisTransformado = iris.map(d => ({
longitud_sepalo: d.sepal_length,
longitud_petalo: d.petal_length,
especie: d.species,
area_petalo: (d.petal_length * d.petal_width) / 2
}))
Insert cell
// Obtener rango de sepalo
extentSepalLength = d3.extent(irisTransformado , d => d.longitud_sepalo)
Insert cell
// Obtener rango de petalo
extentPetalLength = d3.extent(irisTransformado , d => d.longitud_petalo)
Insert cell
// Crear la escala x para la longitud de los sépalos
x = d3.scaleLinear()
.domain(extentSepalLength)
.range([0, 350])
Insert cell
y = d3.scaleLinear()
.domain(extentPetalLength)
.range([350, 0])
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