{
const svgBackgroundColor = "#081c15",
mazeEnterColor = "#f8961e",
mazeExitColor = "#faedcd",
mazePathColor = "#333d29",
mazeWallColor = "#95d5b2",
mazeWallWidth = 4,
radius = 4,
svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("background-color", svgBackgroundColor),
container = svg.append("g")
.attr("transform",`translate(${margin.left},${margin.top})`),
numRows = mazeWidth,
numCols = mazeHeight,
y = d3.scaleBand()
.range([0,width])
.domain(d3.range(numRows)),
x = d3.scaleBand()
.range([0, height])
.domain(d3.range(numCols)),
clusterColors = d3.scaleSequential()
.domain([0,numCols * numRows])
.interpolator(d3.interpolateRainbow),
update = (edges,nodes) => {
let lines = container.selectAll(".mazePathLines")
.data(edges, d => d.id)
lines
.join(
enter => enter.append("path")
.classed('mazePathLines', true)
.attr("d", d => {
let x1 = x(d.source.id % numCols) + x.bandwidth();
let y1 = y(Math.floor(d.source.id/numCols)) + y.bandwidth();
let x2 = x(d.target.id % numCols) + x.bandwidth();
let y2 = y(Math.floor(d.target.id/numCols)) + y.bandwidth();
return d3.line()([[x1,y1],[x2,y2]]);
})
.attr("stroke", d => clusterColors(d.cluster))
.attr("stroke-width", mazeWallWidth)
.attr("fill", mazePathColor)
.style('opacity', d => d.status == 'union' ? 1 : .05)
.attr("stroke-linecap", "round"),
update => update.call(e => e.transition()
.duration(0)
.attr("stroke", d => clusterColors(d.cluster))
.style("opacity", d => d.status == "union" ? 1 : .05)
)
)
let circles = container.selectAll("circle")
.data(nodes, d => d.id)
.join(
enter => enter.append("circle")
.attr('cx', d => x(d.id%numCols) + x.bandwidth())
.attr('cy', d => y(Math.floor(d.id/numCols)) + y.bandwidth())
.attr('r', radius)
.attr("stroke", d => clusterColors(d.cluster))
.attr("fill", d => clusterColors(d.cluster))
.style("opacity", d => d.status == "visible" ? .6 : .2),
update => update.call(e => e.transition()
.duration(0)
.attr("fill", d => clusterColors(d.cluster))
.attr("stroke", d => clusterColors(d.cluster))
.style("opacity", d => d.status == "visible" ? .6 : .2)
)
)
}//end update function
let mazeSolution = kruskalMaze();
let maze = mazeSolution[0];
let animated = mazeSolution[1];
update(graph.edges,graph.nodes);
let count = 0
let interval = d3.interval(function(elapsed) {
if (count >= animated.length) {
interval.stop(); // <== !!!
return;
}
let updatedClusters = animated[count];
let currentEdge = maze[count];
if(currentEdge){
//display this edge/nodes
graph.edges.forEach(gE => {
if(gE.id == currentEdge.id){
//un-hide the edge
gE.status = currentEdge.final;
}
gE.cluster = updatedClusters[gE.source.id];
});
graph.nodes.forEach(gn => {
if(gn.status != 'visible'){
if(gn.id == currentEdge.source.id || gn.id == currentEdge.target.id){
gn.status = "visible";
}
}
gn.cluster = updatedClusters[gn.id];
})
}//end if currentEdge
update(graph.edges,graph.nodes);
count++
}, 1);
yield svg.node();
}