Public
Edited
Aug 29, 2023
2 forks
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
xScale = d3.scaleLinear(
d3.extent( data, d => d.revenues_mm ),
[ margin.left, width - margin.right ]
)
Insert cell
yScale = d3.scaleLinear(
d3.extent( data, d => d.profit_mm ),
[ height - margin.bottom, margin.top ]
)
Insert cell
Insert cell
colors = d3.scaleOrdinal().range(d3.schemeCategory10)
Insert cell
xAxis = d3.axisBottom(xScale)
Insert cell
yAxis = d3.axisLeft(yScale)
Insert cell
Insert cell
chart = {
const svg = html `<svg width="900" height="500" />`
const g = d3.select(svg)
.append('g')
.style('font-family', 'sans-serif')
.style('font-size', 10)
g
.selectAll('g')
.data( data )
// each data point is a group
.join('g')
.attr('class', 'scatter-point')
.attr('transform', d => `translate(${xScale(d.revenues_mm)},${yScale(d.profit_mm)})`)
// .call() passes in the current d3 selection
// This is great if we want to append something
// but still want to work with the original selection after that
.call(g => g
// first we append a circle to our data point
.append('circle')
.attr('r', 5)
.style('stroke', d => colors( d.category ))
.style('stroke-width', 2)
.style('fill', 'transparent')
)
.call(g => g
// then we append a text label to the data point
.append('text')
.attr('x', 8)
.attr('dy', '0.35em')
// I've filter out values too low in order to avoid label overlap
// see what happens if you remove the condition and just return d.company
.text(d => d.revenues_mm < 10000 ? '' : d.company)
)
d3.select(svg)
.append('g')
.attr('class', 'y-axis')
.attr('transform', `translate(${ margin.left },0)`)
.call(yAxis)
// remove the line between the ticks and the chart
.select('.domain').remove()
d3.select(svg)
.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0,${ height - margin.bottom })`)
.call(xAxis)
// remove the line between the ticks and the chart
.select('.domain').remove()
// Here, I'm appending and positioning the y-axis label (Profit ($MM))
g.append('g')
.attr('transform', `translate(${margin.left + 6},${margin.top + 4})`)
.append('text')
.attr('transform', 'rotate(90)')
.text(data.y)

// Here, I'm appending and positioning the x-axis label (Revenue ($MM))
g.append('text')
.attr('x', width - margin.right - 6)
.attr('y', height - margin.bottom - 5)
.attr('text-anchor', 'end')
.text(data.x)
return svg
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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