{
const svg = d3.create("svg").attr("width", width).attr("height", height);
svg
.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "#555b6e");
const g = svg.append("g");
const path = d3.geoPath().projection(projection);
g.selectAll(".countries")
.data(northAmerica.features)
.enter()
.append("path")
.attr("d", path)
.attr("stroke", (d) =>
supportedSources.includes(d.properties.name) ? "white" : "#bee3db"
)
.attr("fill", (d) =>
selectedSources.includes(d.properties.name)
? d3.interpolatePlasma(sourceScale(d.properties.name))
: "#89b0ae"
)
.attr("stroke-width", 1);
g.selectAll(".states")
.data(statesWithMigrationData.features)
.enter()
.append("path")
.attr("d", path)
.attr("stroke", "#bee3db")
.attr("stroke-width", 1)
.attr("fill", "#89b0ae");
for (let state of statesWithMigrationData.features) {
const stateArcs = state.trails
.filter((d) => selectedSources.includes(d.properties.source))
.filter((d) => d.properties.migration);
g.selectAll(".arcs")
.data(stateArcs)
.enter()
.append("path")
.attr("d", (d) => path(d))
.attr("fill", "none")
.attr("stroke-width", 2)
.attr("stroke", (d) =>
d3.interpolatePlasma(sourceScale(d.properties.source))
)
.style("stroke-dasharray", "2 20")
.style("stroke-dashoffset", (d) => Math.random() * 100)
.style(
"animation",
(d) =>
"dash " +
durationScale(parseInt(d.properties.migration[selectedPeriod])) +
"s linear infinite"
);
}
return svg.node();
}