This data is from The JSE Archive and was found through NCSU.
This dataset is about baseball players in the 1991-1992 MLB season.
This scatterplot shows the salaries of baseball players with varying stats.
forked from curran's block: Scatter Plot with Size Legend
xxxxxxxxxx
<html>
<head>
<title>Solution</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
margin: 0px;
}
.axis .tick line {
stroke-width: 1px;
stroke: #dddddd;
}
.axis .tick text {
font-size: 20px;
fill: #8E8883;
}
.axis .domain {
display: none;
}
.axis__label {
text-anchor: middle;
font-size: 30px;
fill: #635F5D;
}
.legend .tick text {
font-size: 20px;
fill: #8E8883;
font-family: sans-serif;
alignment-baseline: middle;
}
.legend__label {
font-size: 30px;
fill: #635F5D;
font-family: sans-serif;
}
</style>
</head>
<body>
<svg width="1200" height="500"></svg>
<script>
const xValue = d => d.battingAverage;
const yValue = d => d.numRuns;
const sizeValue = d => d.salary;
const sizeMax = 13;
const xLabel = "Batting Average";
const yLabel = "Number of Runs";
const margin = {top: 30, right: 500, bottom: 100, left: 100};
const svg = d3.select("svg");
const width = +svg.attr("width");
const height = +svg.attr("height");
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const xScale = d3.scaleLinear().range([0, innerWidth]);
const yScale = d3.scaleLinear().range([innerHeight, 0]);
const sizeScale = d3.scaleSqrt()
.range([0, sizeMax]);
const xAxis = d3.axisBottom()
.scale(xScale)
.tickSizeInner(-innerHeight)
.tickPadding(15);
const yAxis = d3.axisLeft()
.scale(yScale)
.tickSizeInner(-innerWidth)
.ticks(5)
.tickPadding(10);
const g = svg.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);
const xAxisG = g.append("g")
.attr("class", "axis")
.attr("transform", `translate(0, ${innerHeight})`);
const yAxisG = g.append("g")
.attr("class", "axis");
xAxisG
.append("text")
.attr("class", "axis__label")
.attr("x", innerWidth / 2)
.attr("y", 85)
.text(xLabel);
yAxisG
.append("text")
.attr("class", "axis__label")
.attr("transform", "rotate(-90)")
.attr("x", -innerHeight / 2)
.attr("y", -45)
.text(yLabel);
function sizeLegend(selection, props){
const sizeScale = props.sizeScale;
const positionX = props.positionX;
const positionY = props.positionY;
const ticksCount = props.ticks;
const tickFill = props.tickFill;
const tickSpacing = props.tickSpacing;
const tickPadding = props.tickPadding;
const label = props.label;
const labelX = props.labelX;
const labelY = props.labelY;
let legendG = selection
.selectAll(".legend--size")
.data([null]);
legendG = legendG
.enter().append("g")
.attr("class", "legend legend--size")
.merge(legendG)
.attr("transform", `translate(${positionX}, ${positionY})`);
const legendLabel = legendG
.selectAll(".legend__label")
.data([null]);
legendLabel
.enter().append("text")
.attr("class", "legend__label")
.merge(legendLabel)
.attr("x", labelX)
.attr("y", labelY)
.text(label);
const ticks = legendG
.selectAll(".tick")
.data(sizeScale.ticks(ticksCount).filter(d => d));
const ticksEnter = ticks
.enter().append("g")
.attr("class", "tick");
ticksEnter
.merge(ticks)
.attr("transform", (d, i) => `translate(0, ${i * tickSpacing})`);
ticks.exit().remove();
ticksEnter
.append("circle")
.merge(ticks.select("circle"))
.attr("r", sizeScale)
.attr("fill", tickFill);
ticksEnter
.append("text")
.merge(ticks.select("text"))
.attr("x", tickPadding)
.text(d => d);
}
function render(data){
xScale
.domain(d3.extent(data, xValue))
.nice();
yScale
.domain(d3.extent(data, yValue))
.nice();
sizeScale
.domain([0, d3.max(data, sizeValue)]);
xAxisG.call(xAxis);
yAxisG.call(yAxis);
const circles = g.selectAll("circle").data(data);
circles.exit().remove();
circles
.enter().append("circle")
.attr("r", 5)
.merge(circles)
.attr("cx", d => xScale(xValue(d)))
.attr("cy", d => yScale(yValue(d)))
.attr("r", d => sizeScale(sizeValue(d)))
.attr("stroke", "white")
.attr("opacity", 0.6);
sizeLegend(svg, {
sizeScale: sizeScale,
positionX: 722,
positionY: 200,
ticks: 5,
tickFill: "black",
tickSpacing: 35,
tickPadding: 16,
label: "Salary (thousands)",
labelX: -20,
labelY: -30
});
}
function type(d){
d.salary = +d.salary;
d.battingAverage = +d.battingAverage;
d.onBase = +d.onBase;
d.numRuns=+d.NumberRuns;
return d;
}
d3.csv("baseball.csv", type, render);
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js