{
var svg = d3.create("svg")
.attr('height', 500)
.attr('width', 1000)
.style("cursor", "crosshair");
var margin = {top: 20, right: 20, bottom: 30, left: 50};
var width = +svg.attr("width") - margin.left - margin.right;
var height = +svg.attr("height") - margin.top - margin.bottom;
var g = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var random = d3.randomNormal();
var points = d3.range(1000).map(function() {
return {
x: random(),
y: random()
};
});
var xScale = d3.scaleLinear()
.domain(
d3.extent(points, function(d) {
return d.x;
})
)
.rangeRound([0, width]);
var yScale = d3.scaleLinear()
.domain(
d3.extent(points, function(d) {
return d.y;
})
)
.rangeRound([height, 0]);
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
var circleG = g.append('g');
var circles = circleG.selectAll('circle')
.data(points).enter()
.append('circle')
.attr('fill', 'steelblue')
.attr('r', 5)
.attr('cx', function(d) {
return xScale(d.x);
})
.attr('cy', function(d) {
return yScale(d.y);
});
var axisG = g.append('g');
axisG.append("g")
.attr("transform", "translate(0," + height + ")")
.classed('axis-x', true)
.call(xAxis);
axisG.append("g")
.classed('axis-y', true)
.call(yAxis);
var brush = d3.brush()
.extent([[0, 0], [width, height]])
.on("end", (event) => {
if (!event.selection) return;
var [[x0, y0], [x1, y1]] = event.selection;
var selected = points.filter(d => {
var cx = xScale(d.x);
var cy = yScale(d.y);
return cx >= x0 && cx <= x1 && cy >= y0 && cy <= y1;
});
circles.attr("fill", d =>
selected.includes(d) ? "red" : "blue"
);
});
g.append("g")
.call(brush);
return svg.node();
}