{
const svgBackgroundColor = '#c2b502',
height = 400,
width = 400,
blockColor = '#b784a7',
svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.style("background-color", svgBackgroundColor),
container = svg.append("g")
.attr("transform", `translate(${width/2},${height/2})`),
numCols = 5,
numRows = 5,
numSquares = numCols * numRows,
squareSize = 30,
expandedSquareSize = squareSize * 2,
data = d3.range(numSquares);
let x1 = d3.scaleBand()
.domain(d3.range(numCols))
.range([-(squareSize*numCols)/2,(squareSize*numCols)/2]),
y1 = d3.scaleBand()
.domain(d3.range(numRows))
.range([(squareSize*numRows)/2, -(squareSize*numRows)/2]),
xExpanded = d3.scaleBand()
.domain(d3.range(numCols))
.range([-(width/2),(width/2)]),
yExpanded = d3.scaleBand()
.domain(d3.range(numRows))
.range([(height/2), -(height/2)]);
function update(data){
let squares = container.selectAll('path')
.data(data, d => d);
squares
.join('path')
.attr("d", d => d3.line()(getPathPoints(x1(d%numCols), y1(Math.floor(d/numRows)), squareSize)))
.attr("fill", blockColor)
.style('opacity', 1)
.transition()
.duration(2000)
.delay(1000)
.attr("d", d => d3.line()(getAlteredPathPoints(xExpanded(d%numCols) + (xExpanded.bandwidth()-expandedSquareSize)/2, yExpanded(Math.floor(d/numRows)) + (yExpanded.bandwidth() - expandedSquareSize)/2, expandedSquareSize)));
}
update(data);
function reRun(){
d3.selectAll("path").remove();
update(data);
}
d3.select("button#runAnimation").on("click", reRun);
yield svg.node();
}