Published
Edited
Oct 3, 2020
Fork of 3.3 Brushing
Insert cell
Insert cell
// Generamos 500 puntos 2d con media 0 y sigma proporcional al ancho y alto de la gráfica
data = d3.range(0,500).map(d => ({
x: d3.randomNormal(0, width/8)(),
y: d3.randomNormal(0, height/8)()
}))
Insert cell
Insert cell
chart = {

// 1. Escalas
const xScale = d3.scaleLinear([ -width/2, width/2 ], [ -width/2, width/2 ])
const yScale = d3.scaleLinear([ -height/2, height/2 ], [ -height/2, height/2 ])
// 2. Canvas
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
.property("value", []);
// 3. Vamos a crear los componentes gráficos dentro de un contenedor <g> centrado
const contenedor = svg.append('g')
.attr('class', 'container')
.attr('transform', `translate(${ width/2 },${ height/2 })`)
// 4. Creamos los puntos
const points = contenedor.selectAll('circle.point')
.data(data)
.enter()
.append('circle')
.attr('class', 'point')
.attr('cx', d => xScale(d.x))
.attr('cy', d => yScale(d.y))
.attr('r', 8)
.style('fill', color)
.style('opacity', 0.8)
// 5. Ejes
const xAxis = d3.axisBottom(xScale)
contenedor.append('g').call(xAxis)
const yAxis = d3.axisLeft(yScale)
contenedor.append('g').call(yAxis)
// 6. Removemos el texto de los ejes
contenedor.selectAll('.tick text').remove()
return svg.node()
}
Insert cell
Insert cell
brush = d3.brush()
.extent([ [ -width/2, -width/2 ], [ width/2, width/2] ])
.on('start', brushStart)
.on('brush', brushing)
Insert cell
Insert cell
brushStart = function() {
// Selecciono todos los circulos de la grafica
const points = d3.select(chart).selectAll('circle.point')
// Les seteo el color con la paleta color
points.style('fill', color)
}
Insert cell
Insert cell
brushing = function() {
// Obtenemos el bounding-box de la selección.
// Tiene las coordeandas superior-izquierda e inferior-derecha de la selección
// en este formato [[coordenada superior-izquierda ], [coordenada inferior-derecha ]]
const selection = d3.event.selection
// Seleccionamos todos los puntos de nuetra gráfica
const points = d3.select(chart).selectAll('circle.point')
// Si la selección es nula, debemos ver los puntos con los colores originales
if( selection === null ) {
points.style('fill', color)
}
// Si no es nula...
else
{
// Coordenadas de la selección: x_min, x_max, y_min, y_max
const x_min = selection[0][0] // x más a la izquierda
const x_max = selection[1][0] // x más a la derecha
const y_min = selection[0][1] // y más arriba
const y_max = selection[1][1] // y más abajo
// Le cambiamos el color a los puntos en base a si se encuentran
// dentro o fuera del área de selección.
points.style('fill', function(d) {
// Si la coordeanada x del punto es mayor a la coordeanda x_min de la selección
// y menor a la coordenada x_max de la selección, entonces está en el rango x de la selección
const inRangeX = d.x >= x_min && d.x < x_max
// Si la coordeanada y del punto es mayor a la coordeanda y_min de la selección
// y menor a la coordenada y_max de la selección, entonces está en el rango y de la selección
const inRangeY = d.y >= y_min && d.y < y_max
// Si está en el rango x y en el rango y, entonces está seleccionada
if(inRangeX && inRangeY) {
// La pintamos del color original
return color(d)
} else {
// Sino, está fuera de la selección, la pintamos de gris
return 'gray'
}
})
}
}
Insert cell
Insert cell
d3.select( chart )
.select('g.container')
.call(brush)
Insert cell
Insert cell
Insert cell
height = 500
Insert cell
color = (d) => d3.interpolateRainbow( Math.hypot(d.x, d.y) / Math.hypot(width/4, width/4) )
Insert cell
d3 = require('d3@5')
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