vis={
const svg = d3.select(DOM.svg()).attr("viewBox", [0, 0, width, height]);
svg.selectAll('.row')
.data(data)
.enter()
.append('g').attr('transform', (_, i) => `translate(0, ${i * cellSize})`)
.selectAll('.cell').data((_, i) => data[i]).enter()
.append('rect')
.attr("width", cellSize)
.attr('height', cellSize)
.attr('x', (_, i) => i * cellSize)
.attr('stroke', 'white')
.attr('stroke-width', '2px')
.attr('fill', d => d3.interpolateViridis(d/9))
.on('click', function(e, d) {
if (e.target.nodeName != 'rect') return;
let y = Math.round(e.target.getAttribute('x') / cellSize);
let x = Math.round(e.target.parentNode.getAttribute('transform').slice(13, -1) / cellSize);
target = [x,y];
path = dijkstra([0,0], target, data);
svg.select('path')
.attr('d', d3.line()(
path.map(p => [(p[1] + 0.5) * cellSize, (p[0] + 0.5) * cellSize]))
)
});
// .attr('class', 'label')
// .text(d => d)
svg.selectAll('.label').style('font-family', 'ui-monospace').style('font-size', '15px');
let target = [data.length - 1, data[0].length - 1];
let path = dijkstra([0,0],target, data);
svg.append("path")
.attr('d', d3.line()(path.map(p => [(p[1] + 0.5) * cellSize, (p[0] + 0.5) * cellSize])))
.attr('fill', 'none')
.style('stroke-linejoin', 'round')
.style('stroke-linecap', 'round')
.attr('stroke', 'red')
.attr('stroke-width', '5px')
return svg.node();
}