Public
Edited
Apr 24
Insert cell
Insert cell
cars
Insert cell
Insert cell
{
// filter the cars to all that have the attributes we want to show.
const cars_filtered = cars.filter(car => car['power (hp)'] != null && car['economy (mpg)'] != null);
// create the scatter plot, the code for the function is down below.
const plot_data = create_scatterplot(cars_filtered, 'power (hp)', 'economy (mpg)');

// get the node to plot it in Observable
return plot_data.svg.node();
}
Insert cell
Insert cell
{
// filter the cars to all that have the attributes we want to show.
const cars_filtered = cars.filter(car => car['power (hp)'] != null && car['economy (mpg)'] != null);
// create the scatter plot, the code for the function is down below.
const plot_data = create_scatterplot(cars_filtered, 'power (hp)', 'economy (mpg)');

// the callback function that is called each time the brush is created/changed
function brushed(event) {
// it just logs the event to the console for you to inspect
console.log(event);
}

// add the brush visuals to the SVG
plot_data.svg.append("g")
.attr("class", "brush")
.call(d3.brushX().on("brush", brushed));

// get the node to plot it in Observable
return plot_data.svg.node();
}
Insert cell
Insert cell
{
// filter the cars to all that have the attributes we want to show.
const cars_filtered = cars.filter(car => car['power (hp)'] != null && car['economy (mpg)'] != null);
// create the scatter plot, the code for the function is down below.
const plot_data = create_scatterplot(cars_filtered, 'power (hp)', 'economy (mpg)');

// the callback function that is called each time the brush is created/changed
function brushed(event) {
// log the ranges to the console for you to inspect
console.log([plot_data.scaleX.invert(event.selection[0]),plot_data.scaleX.invert(event.selection[1])]);
}

// add the brush visuals to the SVG
plot_data.svg.append("g")
.attr("class", "brush")
.call(d3.brushX().on("brush", brushed));

// get the node to plot it in Observable
return plot_data.svg.node();
}
Insert cell
Insert cell
Insert cell
{
// filter the cars to all that have the attributes we want to show.
const cars_filtered = cars.filter(car => car['power (hp)'] != null && car['economy (mpg)'] != null);
// create the scatter plot, the code for the function is down below.
const plot_data = create_scatterplot(cars_filtered, 'power (hp)', 'economy (mpg)');

// get the node to plot it in Observable
return plot_data.svg.node();
}
Insert cell
function create_scatterplot(data, attributeX, attributeY) {
const width = 1000;
const height = 300;
const margin = {top:20, bottom: 35, left:35, right:5};
const radius = 2;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const scaleX = d3.scaleLinear().domain(d3.extent(data, d => d[attributeX])).range([margin.left, width - margin.right]);
const scaleY = d3.scaleLinear().domain(d3.extent(data, d => d[attributeY])).range([height - margin.bottom, margin.top]);

svg.append('g')
.attr('transform', `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(scaleX))
.append('text')
.attr('x', scaleX.range()[1])
.attr('y', margin.bottom - 5)
.text(attributeX)
.style('fill', 'black')
.style('text-anchor', 'end');

svg.append('g')
.attr('transform', `translate(${margin.left}, 0)`)
.call(d3.axisLeft(scaleY))
.append('text')
.attr('x', 0)
.attr('y', margin.top - 5)
.text(attributeY)
.style('fill', 'black')
.style('text-anchor', 'middle');

svg.selectAll('circle')
.data(data)
.join('circle')
.attr('r', radius)
.attr('cx', d => scaleX(d[attributeX]))
.attr('cy', d => scaleY(d[attributeY]));

return {svg, scaleX, scaleY};
}
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