This scatterplot was created from this table of most costly earthquakes found on Wikipedia. The original table includes event rank, year, location, magnitude, and property damage amounts as unadjusted costs. In cases where a range was given, the midpoint value has been used in the visualization. Each incident is color-coded by continent. (Continent data was manually added.)
This work was forked from curran's block: Scatter Plot Axis Labels, part of the video course: D3.js in Motion.
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js"></script>
<title>Earthquake Scatter Plot</title>
<style>
body {
margin: 0px;
}
.tick text, .legendCells text {
font-size: 14pt;
font-family: sans-serif;
}
.tickline {
stroke: #E0E0E0;
}
.axis-label, .legend-label {
fill: black;
font-size: 18pt;
font-family: sans-serif;
}
.dotmarker {
}
</style>
</head>
<body>
<svg width="960" height="500"></svg>
<script>
const xValue = d => d.magnitude;
const xLabel = 'Magnitude (Richter)';
const yValue = d => d.cost;
const yLabel = 'Property Cost';
const margin = { left: 180, right: 30, top: 20, bottom: 120 };
const colorValue = d => d.continent;
const colorLabel = 'Continent';
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 g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const xAxisG = g.append('g')
.attr('transform', `translate(0, ${innerHeight})`);
const yAxisG = g.append('g');
const colorLegendG = g.append('g')
.attr('transform', `translate(${innerWidth - 179}, 243)`);
colorLegendG.append('text')
.attr('class', 'legend-label')
.attr('x', -30)
.attr('y', -25)
.text(colorLabel);
xAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', innerWidth / 2)
.attr('y', 70)
.text(xLabel);
yAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', -innerHeight / 2)
.attr('y', -120)
.attr('transform', `rotate(-90)`)
.style('text-anchor', 'middle')
.text(yLabel);
const xScale = d3.scaleLinear();
const yScale = d3.scaleLog();
const colorScale = d3.scaleOrdinal(d3.schemeDark2);
const colorLegend = d3.legendColor()
.scale(colorScale)
.shape('rect');
// customize appearance of axis
function customAxis(g, axis) {
g.call(axis);
g.select(".domain").remove();
g.selectAll(".tick:not(:first-of-type) line").attr("class", "tickline")
}
const xAxis = d3.axisBottom()
.scale(xScale)
.tickPadding(15)
.tickSize(-innerHeight);
const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(3)
.tickFormat(d => d3.format("$,.1f")(d) + " B")
.tickPadding(15)
.tickSize(-innerWidth);
const row = d => {
d.rank = +d.rank;
d.magnitude = +d.magnitude;
d.cost = +d.cost;
return d;
};
d3.csv('earthquakes.csv', row, data => {
xScale
.domain(d3.extent(data, xValue))
.range([0, innerWidth])
.nice();
yScale
.domain(d3.extent(data, yValue))
.range([innerHeight, 0])
.nice();
g.selectAll('circle').data(data)
.enter().append('circle')
.attr('cx', d => xScale(xValue(d)))
.attr('cy', d => yScale(yValue(d)))
.attr('r', 8)
.attr('fill', d => colorScale(colorValue(d)))
.attr('class', 'dotmarker');
xAxisG.call(g => customAxis(g, xAxis));
yAxisG.call(g => customAxis(g, yAxis));
colorLegendG.call(colorLegend)
.selectAll('.cell text')
.attr('dy', '0.1em');
});
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js