function choroplethMap({
data = data,
geography = geography,
tickSize = 6,
width = 960,
height = 600,
marginTop = 60,
marginRight = 10,
marginBottom = 10,
marginLeft = 10,
scaleType = 'scaleSequential',
colorVariable = 'value',
colorInterpolator = d3.interpolateYlGnBu,
geographyIdVariable = 'id',
dataIdVariable = 'id',
colorDomain = d3.extent(data, d => d[colorVariable]),
titleFontSize = 20,
titleFontFamily = 'sans-serif',
titleFontWeight = 'bold',
titleMaxCharsPerLine = 65,
legend: legendOptions = {},
} = {}) {
const dataById = d3.map(data, d => d[dataIdVariable]);
const extent = [
[marginLeft, marginTop],
[width - marginRight - marginLeft, height - marginBottom - marginTop]
];
const projection = d3.geoMercator()
.fitExtent(extent, geography);
const path = d3.geoPath()
.projection(projection);
const colorScale = d3[scaleType]()
.interpolator(colorInterpolator)
.domain(colorDomain);
const topo = topojson.topology({ geography: geography });
const border = topojson.merge(topo, topo.objects.geography.geometries);
const svg = d3.create('svg')
.attr('viewBox', [0, 0, 975, 610]);
svg.append('g')
.attr('fill', 'none')
.selectAll('path')
.data(geography.features)
.join('path')
.attr('d', path)
.attr('fill', (d) => {
const id = d.properties[geographyIdVariable];
if (dataById.has(id)) {
const datum = dataById.get(id);
return colorScale(datum[colorVariable]);
}
});
svg.append('path')
.datum(border)
.attr('fill', 'none')
.attr('stroke', '#434343')
.attr('stroke-width', 1)
.attr('d', path);
const options = Object.assign({
color: colorScale,
},legendOptions);
const legendSVG = legend(options);
const legendWidth = +d3.select(legendSVG).attr('width');
const legendHeight = +d3.select(legendSVG).attr('height');
const legendNode = svg.append('g')
.attr('transform', `translate(${width / 2 - legendWidth / 2}, 0)`);
Array.from(legendSVG.children).forEach((child) => {
legendNode.node().appendChild(child);
});
legendNode.select('g').selectAll('text')
.filter(function() { return d3.select(this).attr('font-weight') === 'bold'; })
.attr('font-size', 14);
return svg.node();
}