@@ -1290,27 +1290,67 @@ function openStateMergeDialog() {
12901290 const statesSelector = validStates
12911291 . map (
12921292 s => /* html */ `
1293- <div data-tip="${ s . fullName } ">
1293+ <div data-id=" ${ s . i } " data- tip="${ s . fullName } " style="cursor:default ">
12941294 <input type="radio" name="rulingState" value="${ s . i } " />
1295- <input id="selectState${ s . i } " class="checkbox" type="checkbox" name="statesToMerge" value="${ s . i } "} />
1296- <label for="selectState${ s . i } " class="checkbox-label">${ emblem ( s . i ) } ${ s . fullName } </label>
1295+ <input id="selectState${ s . i } " class="checkbox" type="checkbox" name="statesToMerge" value="${ s . i } " />
1296+ <label for="selectState${ s . i } " class="checkbox-label"><fill-box fill=" ${ s . color } " disabled></fill-box> ${ emblem ( s . i ) } ${ s . fullName } </label>
12971297 </div>
12981298 `
12991299 )
13001300 . join ( "" ) ;
13011301
13021302 alertMessage . innerHTML = /* html */ `
13031303 <form id='mergeStatesForm' style="overflow: hidden; display: flex; flex-direction: column; gap: 1em;">
1304- <header style='font-weight:bold;'>Select multiple states to merge and the ruling state to merge into</header>
1304+ <p style="margin:0">
1305+ Check the <b>checkbox</b> next to each state you want to merge.
1306+ Use the <b>radio button</b> to pick the <em>ruling state</em> that will absorb all others (its name, color, and capital will be kept).
1307+ Hover over a row to highlight the state on the map.
1308+ </p>
13051309 <main style='display: grid; grid-template-columns: 1fr 1fr; gap: .3em;'>
13061310 ${ statesSelector }
13071311 </main>
13081312 </form>
13091313 ` ;
13101314
1315+ byId ( "mergeStatesForm" )
1316+ . querySelectorAll ( "div[data-id]" )
1317+ . forEach ( el => {
1318+ el . addEventListener ( "mouseenter" , highlightStateOnMergeHover ) ;
1319+ el . addEventListener ( "mouseleave" , stateHighlightOff ) ;
1320+ } ) ;
1321+
1322+ function highlightStateOnMergeHover ( event ) {
1323+ if ( ! layerIsOn ( "toggleStates" ) ) return ;
1324+ const state = + event . currentTarget . dataset . id ;
1325+ if ( ! state ) return ;
1326+ const d = regions . select ( "#state" + state ) . attr ( "d" ) ;
1327+ if ( ! d ) return ;
1328+
1329+ stateHighlightOff ( ) ;
1330+
1331+ const path = debug
1332+ . append ( "path" )
1333+ . attr ( "class" , "highlight" )
1334+ . attr ( "d" , d )
1335+ . attr ( "fill" , "none" )
1336+ . attr ( "stroke" , "red" )
1337+ . attr ( "stroke-width" , 1 )
1338+ . attr ( "opacity" , 1 )
1339+ . attr ( "filter" , "url(#blur1)" ) ;
1340+
1341+ const totalLength = path . node ( ) . getTotalLength ( ) ;
1342+ const duration = ( totalLength + 5000 ) / 2 ;
1343+ const interpolate = d3 . interpolateString ( `0, ${ totalLength } ` , `${ totalLength } , ${ totalLength } ` ) ;
1344+ path
1345+ . transition ( )
1346+ . duration ( duration )
1347+ . attrTween ( "stroke-dasharray" , ( ) => interpolate ) ;
1348+ }
1349+
13111350 $ ( "#alert" ) . dialog ( {
1312- width : fitContent ( ) ,
1351+ width : 600 ,
13131352 title : `Merge states` ,
1353+ close : stateHighlightOff ,
13141354 buttons : {
13151355 Merge : function ( ) {
13161356 const formData = new FormData ( byId ( "mergeStatesForm" ) ) ;
0 commit comments