Public
Edited
Apr 16
Fork of Lab - Barras
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
populations
Insert cell
Insert cell
marginPop = ({top: 10, bottom: 45, left: 75, right: 10})
Insert cell
widthPop = width
Insert cell
heightPop = 400
Insert cell
Insert cell
maxPopulation = d3.max(populations, d => d.population) //valor maximo de la poblacion
Insert cell
Insert cell
populationScale = d3.scaleLinear()
.domain([0, maxPopulation])
.range([marginPop.left, widthPop - marginPop.right])
Insert cell
countries = populations.map(d => d.country)
Insert cell
Insert cell
countryScale = d3.scaleBand()
.domain(countries)
.range([marginPop.top, heightPop - marginPop.bottom])
.padding(0.2)
Insert cell
Insert cell
xAxisPop = d3.axisBottom(populationScale).tickFormat(d3.format('~s'))
Insert cell
yAxisPop = d3.axisLeft(countryScale)
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', widthPop)
.attr('height', heightPop);
// barras
svg.append('g')
.selectAll('rect') //Selecciona todos los elementos <rect> dentro del grupo. Inicialmente no hay ninguno (es un "placeholder" para el data join).
.data(populations) //Vincula el array de datos populations a los elementos <rect> (data join).
.join('rect') //Crea un <rect> por cada elemento en populations que no tenga un <rect> asociado (enter selection).
.attr('x', populationScale(0)) //Posición horizontal inicial de la barra. //populationScale(0) siempre mapea al extremo izquierdo del eje X (0 población).
.attr('y', d => countryScale(d.country)) //Posición vertical de la barra según el país.
.attr('width', d => populationScale(d.population) - populationScale(0)) //Ancho de la barra = diferencia entre la población del país y 0 (convertido a píxeles). Ejemplo: Si populationScale(1000000) = 200px, el ancho será 200px - 0px = 200px.
.attr('height', countryScale.bandwidth()) // Altura de la barra = ancho de banda predefinido por la escala (espacio entre países).
.attr('fill', 'steelblue');
// eje y
svg.append('g')
.attr('transform', `translate(${marginPop.left})`)
.call(yAxisPop)
.call(g => g.select('.domain').remove()); // eliminar la línea base del eje
// eje x
svg.append('g')
.attr('transform', `translate(0, ${heightPop - marginPop.bottom})`)
.call(xAxisPop)
.call(g => g.select('.domain').remove())
// agregar una etiqueta al eje x
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', width / 2)
.attr('y', 40)
.text("Población");
return svg.node();
}
Insert cell
Insert cell
//maxPopulation

populationScaleInverted = d3.scaleLinear()
.domain([0, maxPopulation])
.range([heightPop - marginPop.bottom, marginPop.top]);
Insert cell
countryScaleInverted = d3.scaleBand()
.domain(countries)
.range([marginPop.left, widthPop - marginPop.right])
.padding(0.2)
Insert cell
Insert cell
xAxisPopInverted = d3.axisBottom(countryScaleInverted)
Insert cell
yAxisPopInverted = d3.axisLeft(populationScaleInverted).tickFormat(d3.format('~s'))
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', widthPop)
.attr('height', heightPop);
// barras
svg.append('g')
.selectAll('rect')
.data(populations)
.join('rect')
.attr('x', d => countryScaleInverted(d.country))
.attr('y', d => populationScaleInverted(d.population))
.attr('width', countryScaleInverted.bandwidth())
.attr('height', d => heightPop - marginPop.bottom - populationScaleInverted(d.population))
.attr('fill', 'steelblue');

// eje y
svg.append('g')
.attr('transform', `translate(${marginPop.left})`)
.call(yAxisPopInverted)
.call(g => g.select('.domain').remove()); // eliminar la línea base del eje
// eje x
svg.append('g')
.attr('transform', `translate(0, ${heightPop - marginPop.bottom})`)
.call(xAxisPopInverted)
.call(g => g.select('.domain').remove())
// agregar una etiqueta al eje x
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', width / 2)
.attr('y', 40)
.text("Población");
return svg.node();
}
Insert cell
Insert cell
averagePopulation = d3.mean(populations, d => d.population);
Insert cell
{
const svg = d3.create('svg')
.attr('width', widthPop)
.attr('height', heightPop);
// barras
svg.append('g')
.selectAll('rect')
.data(populations)
.join('rect')
.attr('x', d => countryScaleInverted(d.country))
.attr('y', d => populationScaleInverted(d.population))
.attr('width', countryScaleInverted.bandwidth())
.attr('height', d => heightPop - marginPop.bottom - populationScaleInverted(d.population))
.attr('fill', 'steelblue');

// eje y
svg.append('g')
.attr('transform', `translate(${marginPop.left})`)
.call(yAxisPopInverted)
.call(g => g.select('.domain').remove()); // eliminar la línea base del eje
// eje x
svg.append('g')
.attr('transform', `translate(0, ${heightPop - marginPop.bottom})`)
.call(xAxisPopInverted)
.call(g => g.select('.domain').remove())
// agregar una etiqueta al eje x
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', width / 2)
.attr('y', 40)
.text("Población");

svg.append('line')
.attr('x1', marginPop.left) //Donde inciia (eje x)
.attr('x2', widthPop - marginPop.right) //Donde termina (eje x)
.attr('y1', populationScaleInverted(averagePopulation)) //Donde inicia (eje y)
.attr('y2', populationScaleInverted(averagePopulation)) //Donde termina (eje y)
.attr('stroke', 'red')
.attr('stroke-width', 2);
return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', widthPop)
.attr('height', heightPop);
// Lineas lollipop
svg.append('g')
.selectAll('line')
.data(populations)
.join('line')
.attr('x1', d=>countryScaleInverted(d.country) + countryScaleInverted.bandwidth()/2) //Para que este centrado en el nombre del pais
.attr('x2', d=>countryScaleInverted(d.country) + countryScaleInverted.bandwidth()/2) //Donde termina (eje x)
.attr('y1', heightPop - marginPop.bottom) //Donde inicia (eje y)
.attr('y2', d=>populationScaleInverted(d.population)) //Donde termina (eje y)
.attr('stroke', 'red')
.attr('stroke-width', 2);


// Circulos lollipop
svg.append('g')
.selectAll('circle')
.data(populations)
.join('circle')
.attr('cx', d=>countryScaleInverted(d.country) + countryScaleInverted.bandwidth()/2)
.attr('cy', d=>populationScaleInverted(d.population))
.attr('r', 5)
.attr('fill', 'red')


// eje y
svg.append('g')
.attr('transform', `translate(${marginPop.left})`)
.call(yAxisPopInverted)
.call(g => g.select('.domain').remove()); // eliminar la línea base del eje
// eje x
svg.append('g')
.attr('transform', `translate(0, ${heightPop - marginPop.bottom})`)
.call(xAxisPopInverted)
.call(g => g.select('.domain').remove())
// agregar una etiqueta al eje x
.append('text')
.attr('fill', 'black')
.attr('font-family', 'sans-serif')
.attr('x', width / 2)
.attr('y', 40)
.text("Población");
return svg.node();
}
Insert cell
Insert cell
diamonds = FileAttachment("diamonds-10k.csv").csv({typed: true})
Insert cell
diamonds
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
html`<div style='font-family: sans-serif; font-size: 10px; font-weight: bold;'>Diamond Cut</div>
${swatches({color})}`
Insert cell
diamondsChart
Insert cell
Insert cell
colorToCutToCount = d3.rollup(
diamonds,
v => d3.rollup(v, leaves => leaves.length, d => d.cut),
d => d.color
);
Insert cell
Insert cell
marginDiamond = ({top: 10, bottom: 50, left: 85, right: 10})
Insert cell
widthDiamond = width
Insert cell
heightDiamond = 600
Insert cell
Insert cell
Insert cell
diamondColors = Array.from(colorToCutToCount.keys()).sort();
Insert cell
Insert cell
groupX = d3.scaleBand()
.domain(diamondColors)
.range([marginDiamond.left, widthDiamond - marginDiamond.right])
.padding(0.1)
Insert cell
Insert cell
new Set(diamonds.map(d => d.cut))
Insert cell
diamondCuts = ['Premium', 'Ideal', 'Very Good', 'Good', 'Fair']
Insert cell
Insert cell
barX = d3.scaleBand()
.domain(diamondCuts)
.range([0, groupX.bandwidth()])
.padding(0.1)
Insert cell
Insert cell
maxCount = d3.max(colorToCutToCount.values(), cuts => d3.max(cuts.values()));
Insert cell
Insert cell
y = d3.scaleLinear()
.domain([0, maxCount]).nice()
.range([heightDiamond - marginDiamond.bottom, marginDiamond.top])
Insert cell
Insert cell
color = d3.scaleOrdinal()
.domain(diamondCuts)
.range(['#bd0026', '#f03b20', '#fd8d3c', '#fecc5c', '#ffffb2'])
Insert cell
Insert cell
xAxisDiamond = d3.axisBottom(groupX)
Insert cell
yAxisDiamond = d3.axisLeft(y)
Insert cell
Insert cell
legend = html`<div style='font-family: sans-serif; font-size: 10px; font-weight: bold;'>Diamond Cut</div>
${swatches({color})}`
Insert cell
{
// set up
const svg = d3.create('svg')
.attr('width', widthDiamond)
.attr('height', heightDiamond);
/*
Tarea A:
- agregar un <g> al svg por cada grupo de barras
- usar colorToCutToCount como los datos
- posicionar cada grupo usando la escala groupX
*/
const groups = svg.append('g')
.selectAll('g.group')
.data(colorToCutToCount)
.join('g')
.attr('transform', d => `translate(${groupX(d[0])},0)`);

/*
Tarea B:
- agregar las barras a cada grupo
- definir los atributos x, width, y, height y fill
*/
groups.selectAll('rect')
.data(d => Array.from(d[1], ([cut, count]) => ({cut, count})))
.join('rect')
.attr('x', d => barX(d.cut))
.attr('width', barX.bandwidth())
.attr('y', d => y(d.count))
.attr('height', d => y(0) - y(d.count))
.attr('fill', d => color(d.cut));

// adicionar ejes

svg.append('g')
.attr('transform', `translate(0,${heightDiamond - marginDiamond.bottom})`)
.call(xAxisDiamond)
.call(g => g.select('.domain').remove())
.append('text')
.attr('x', widthDiamond / 2)
.attr('y', 30)
.attr('dominant-baseline', 'hanging')
.attr('text-align', 'middle')
.attr('fill', 'black')
.text('Diamond Color');
svg.append('g')
.attr('transform', `translate(${marginDiamond.left})`)
.call(yAxisDiamond)
.call(g => g.select('.domain').remove())
.append('text')
.attr('x', -50)
.attr('y', heightDiamond / 2)
.attr('dominant-baseline', 'middle')
.attr('text-align', 'end')
.attr('fill', 'black')
.text('Count');
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