grid_cartogram = {
let size = 1000;
let w = width < size ? width : size;
let xmax = d3.max(grid.map(o => o.x)) + 1;
let ymax = d3.max(grid.map(o => o.y)) + 1;
let h = (ymax * w) / xmax;
let map = d3
.create('svg')
.attr('width', w)
.attr('height', h);
let pad = 0.02 * w;
let x_scale = d3
.scaleLinear()
.domain([0, xmax])
.range([pad, w - pad]);
let y_scale = d3
.scaleLinear()
.domain([0, ymax])
.range([pad, h - pad]);
let dx = (0.98 * (w - 2 * pad)) / xmax;
let dy = (0.98 * (h - 2 * pad)) / ymax;
let s = d3.min([dx, dy]);
map
.selectAll('rect')
.data(grid)
.join('rect')
.attr('x', d => x_scale(d.x))
.attr('y', d => y_scale(d.y))
.attr('width', dx)
.attr('height', dy)
.attr('rx', 0.005 * w)
.attr('stroke', 'black')
.attr('fill', '#eee');
map
.selectAll('text')
.data(grid)
.join('text')
.attr('x', d => x_scale(d.x) + 0.33 * dx)
.attr('y', d => y_scale(d.y) + 0.62 * dy)
.attr('font-size', 0.02 * w)
.style('pointer-events', 'none')
.text(d => d.abbr);
return map.node();
}