{
const margin = { top: 10, bottom: 10, right: 10, left: 10 };
const visHeight = 500 - margin.top - margin.bottom;
const visWidth = width - margin.left - margin.right;
const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);
const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const row = d3.scaleBand()
.domain(d3.range(numRows))
.range([0, visHeight])
.padding(0.05);
const col = d3.scaleBand()
.domain(d3.range(numCols))
.range([0, visWidth])
.padding(0.05);
const cells = g.append('g')
.selectAll('g')
.data(data)
.join('g')
.attr('transform', d => `translate(${col(d.col)}, ${row(d.row)})`);
cells.append('rect')
.attr('width', col.bandwidth())
.attr('height', row.bandwidth())
.attr('fill', 'white')
.attr('stroke', 'red');
cells.selectAll('text')
.data(d => d.words)
.join('text')
.attr('font-size', 15)
.attr('font-family', 'sans-serif')
.attr('dominant-baseline', 'hanging')
.attr('x', 5)
.attr('y', (d, i) => i * 15 + 2)
.text(d => d);
return svg.node();
}