diff --git a/public/modules/dynamic/editors/states-editor.js b/public/modules/dynamic/editors/states-editor.js index e8351218..a514008a 100644 --- a/public/modules/dynamic/editors/states-editor.js +++ b/public/modules/dynamic/editors/states-editor.js @@ -1290,9 +1290,9 @@ function openStateMergeDialog() { const statesSelector = validStates .map( s => /* html */ ` -
+
- +
` @@ -1301,16 +1301,57 @@ function openStateMergeDialog() { alertMessage.innerHTML = /* html */ `
-
Select multiple states to merge and the ruling state to merge into
+
Merge states
+

+ Check the checkbox next to each state you want to merge. + Use the radio button to pick the ruling state that will absorb all others (its name, color, and capital will be kept). + Hover over a row to highlight the state on the map. +

${statesSelector}
`; + byId("mergeStatesForm") + .querySelectorAll("div[data-id]") + .forEach(el => { + el.addEventListener("mouseenter", highlightStateOnMergeHover); + el.addEventListener("mouseleave", stateHighlightOff); + }); + + function highlightStateOnMergeHover(event) { + if (!layerIsOn("toggleStates")) return; + const state = +event.currentTarget.dataset.id; + if (!state) return; + const d = regions.select("#state" + state).attr("d"); + if (!d) return; + + stateHighlightOff(); + + const path = debug + .append("path") + .attr("class", "highlight") + .attr("d", d) + .attr("fill", "none") + .attr("stroke", "red") + .attr("stroke-width", 1) + .attr("opacity", 1) + .attr("filter", "url(#blur1)"); + + const totalLength = path.node().getTotalLength(); + const duration = (totalLength + 5000) / 2; + const interpolate = d3.interpolateString(`0, ${totalLength}`, `${totalLength}, ${totalLength}`); + path + .transition() + .duration(duration) + .attrTween("stroke-dasharray", () => interpolate); + } + $("#alert").dialog({ width: fitContent(), title: `Merge states`, + close: stateHighlightOff, buttons: { Merge: function () { const formData = new FormData(byId("mergeStatesForm"));