Public
Edited
Mar 21
Insert cell
Insert cell
Insert cell
{
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]);

// make copy of the scales
var xScaleOri = xScale.copy();
var yScaleOri = yScale.copy();

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);

// implement your zoom function here
var zoom = d3.zoom()
.scaleExtent ([1,10])
.on("zoom", (event) => {
var transform = event.transfrom;

var newXScale = transform.rescaleX(xScaleOri);
var newYScale = transform.rescaleY(yScaleOri);

circles
.attr("cx", d => newXScale(d.x))
.attr("cy", d => newYScale(d.y));

axisG.select(".axis-x").call(xAxis.scale(newXScale));
axisG.select(".axis-y").call(yAxis.scale(newYScale));
});

svg.call(zoom);
return svg.node();
}
Insert cell
Insert cell
<style>
.selected {
fill: red;
stroke: brown;
}
</style>
Insert cell
{
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);

// similarly, implement the brush functionality

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();
}
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