{
const margin = {top: 40, right: 40, bottom: 40, left: 90};
const width = 600 + margin.left + margin.right;
const height = 600 + margin.top + margin.bottom;
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
.attr('font-family', 'sans-serif');
svg.append('text')
.attr('x', width / 2)
.attr('y', 5)
.attr('font-size', 14)
.attr('text-anchor', 'middle')
.attr('dominant-baseline', 'hanging')
.text('NBA players height vs. weight');
const x = d3.scaleLinear()
.domain(d3.extent(nbaPlayers, d => d.weight)).nice()
.range([margin.left, width - margin.right]);
const y = d3.scaleLinear()
.domain(d3.extent(nbaPlayers, d => d.height)).nice()
.range([height - margin.bottom, margin.top]);
const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);
svg.append('g')
.attr('transform', `translate(0,${height - margin.bottom})`)
.call(xAxis)
.call(
g => g.selectAll('.tick line').clone()
.attr('y1', 0)
.attr('y2', -(height - margin.top - margin.bottom))
.attr('stroke', '#d3d3d3')
.attr('stroke-width', 1)
)
.call(g => g.select('.domain').remove())
.append('text')
.attr('x', width / 2)
.attr('y', 30)
.attr('fill', 'black')
.attr('text-anchor', 'center')
.text('weight (kg)');
svg.append('g')
.attr('transform', `translate(${margin.left})`)
.call(yAxis)
.call(
g => g.selectAll('.tick line').clone()
.attr('x1', 0)
.attr('x2', width - margin.right - margin.left)
.attr('stroke', '#d3d3d3')
.attr('stroke-width', 1)
)
.call(g => g.select('.domain').remove())
.append('text')
.attr('x', -35)
.attr('y', height / 2)
.attr('fill', 'black')
.attr('dominant-baseline', 'center')
.attr('text-anchor', 'end')
.text('height (cm)');
svg.selectAll('circle')
.data(nbaPlayers)
.join('circle')
.attr('cx', d => x(d.weight))
.attr('cy', d => y(d.height))
.attr('r', 3)
.attr('fill', 'steelblue')
.attr('fill-opacity', 0.65);
return svg.node();
}