Published
Edited
Dec 13, 2019
Insert cell
md`# Scatterplot`

Insert cell
Insert cell
height = 300
Insert cell
dataset = generate2DRandomDataSet(numberOfPoints, 2, minValue, maxValue);
Insert cell
// Create SVG
// Code pulled from https://observablehq.com/@sistrall/interacting-with-svg-drawings
svg = {
// Create an SVG element: width is a variable
// made available from the Observable standard lib.
const node = DOM.svg(width, height)
// Wrap the SVG element in a d3 object:
// it's pretty common when using d3.
const svg = d3.select(node)
// Create clipPath to contain the circles
d3.select(node)
.append("clipPath")
.attr("id", "chart-area")
.append("rect")
.attr("x", padding)
.attr("y", padding)
.attr("width", width - padding * 3)
.attr("height", height - padding * 2)
// Finally, the block returns the SVG element, which is made
// available via the d3 `node` function.
return svg.node();
}
Insert cell
padding = 50
Insert cell
minValue = 0
Insert cell
maxValue = 10
Insert cell
numberOfPoints = 10
Insert cell
minValX = d3.min(dataset, function(d){
return d[0];
})
Insert cell

maxValX = d3.max(dataset, function(d){
return d[0];
})
Insert cell
minValY = d3.min(dataset, function(d){
return d[1];
})
Insert cell
maxValY = d3.max(dataset, function(d){
return d[1];
})
Insert cell
scaleDataX = d3.scaleLinear()
.domain([minValue, maxValue + 1]) // range of input values
.range([padding, width - padding]); // what to scale it to
Insert cell
scaleDataY = d3.scaleLinear()
.domain([minValue, maxValue + 1]) // range of input values
.range([(height - padding), padding]); // what to scale it to

Insert cell
// Radius scale
rScale = d3.scaleLinear()
.domain([0, maxValue])
.range([5, 20]);
Insert cell
xAxis = d3.axisBottom()
.scale(scaleDataX)
.ticks(5);
Insert cell
yAxis = d3.axisLeft()
.scale(scaleDataY)
.ticks(5);
Insert cell
{
let groupData = ['one']
let updateGroupCircles = d3.select(svg)
.data(groupData)
updateGroupCircles.enter()
.append("g")
.attr("id", "circles")
.attr("clip-path", "url(#chart-area)")
updateGroupCircles.exit()
.remove()
// Plot the circles
let updateCircles = d3.select(svg)
.select("g")
.selectAll("circle")
.data(dataset);
updateCircles.enter()
.append("circle")
.attr("cx", function(d, i){
return scaleDataX(d[0]);
})
.attr("cy", function(d, i){
return scaleDataY(d[1]);
})
.attr("r", function(d, i){
return rScale(d[1]);
})
.attr("color", "blue");
updateCircles.exit()
.remove()
// Add text to the data points
d3.select(svg)
.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d, i){
return "(" + d[0] + ", " + d[1] + ")";
})
.attr("x", function(d, i){
return scaleDataX(d[0]);
})
.attr("y", function(d, i){
return scaleDataY(d[1]);
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "red");
}
Insert cell
// Add axes
{
d3.select(svg)
.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, " + (height - padding) +")")
.call(xAxis)
d3.select(svg)
.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ", 0)")
.call(yAxis)
}
Insert cell
// Add click listener
d3.select(svg)
.on("click", function(data, index){
d3.select(svg)
.selectAll("circle")
.data(dataset)
.transition()
.duration(1000)
.on("start", function() {
d3.select(this)
.attr("fill", "magenta")
})
.transition()
.duration(1000)
.attr("fill", "black")
.attr("r", 15)
})
Insert cell
Insert cell
// Import D3 library
d3 = require("https://d3js.org/d3.v5.min.js")
Insert cell
/* Function generates 2D array of size dataSetSizeX length and dataSetSizeY height with values
between minValue and maxValue INCLUSIVELY, row is X column is Y*/
function generate2DRandomDataSet(dataSetSizeX, dataSetSizeY, minValue, maxValue){
var dataset = new Array(dataSetSizeX); //Initialize empty array
for(var i = 0; i < dataSetSizeX; i++)
dataset[i] = new Array(dataSetSizeY);

for (var i = 0; i < dataSetSizeX; i++) {
for(var j = 0; j < dataSetSizeY; j++){
var newNumber = Math.random() * (maxValue - minValue + 1) + minValue;
newNumber = Math.floor(newNumber) // Round to nearest integer value
dataset[i][j] = newNumber; //Add new number to array
}
}
return dataset
}
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