Skip to content

Commit

Permalink
Merge pull request #57 from jacksonjude/compare-counties
Browse files Browse the repository at this point in the history
Presidential county compare
  • Loading branch information
jacksonjude authored Sep 14, 2024
2 parents 983e1f3 + 4f2ee4c commit c59c134
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 92 deletions.
2 changes: 1 addition & 1 deletion CNAME
Original file line number Diff line number Diff line change
@@ -1 +1 @@
map.jacksonjude.com
beta.map.jacksonjude.com
6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ <h5 style="margin: 0; text-align: left;">
</a>
<div class='dropdown-separator'></div>
<a id="compareSortModeButton" onclick="toggleCompareSortMode(this); applyCompareToCustomMap()" style="text-align: center;">
Sort by voteshare
Sort by: voteshare
</a>
</div>
<div id="comparePresetsDropdownContainer" style="border-radius: 4rem; margin-left: 4rem; overflow: hidden;">
Expand Down Expand Up @@ -295,10 +295,10 @@ <h3 id="secondCompareDateDisplay" style="display: inline-block; padding-left: 20
</div>
</div>
<div style="display: flex; flex-direction: column; width: 466rem; margin-right: 50rem">
<div id="totalsPieChartContainer" style="position: relative; display: inline-block; vertical-align: top; padding-top: 35rem; padding-bottom: 25rem; user-select: none; -webkit-user-select: none; width: 100%">
<div id="totalsPieChartContainer" style="position: relative; display: inline-block; vertical-align: top; margin-top: 35rem; margin-bottom: 25rem; user-select: none; -webkit-user-select: none; width: 100%">
<canvas id="totalsPieChart"></canvas>
<div id="totalsPieChartOverlay" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; pointer-events: none;">
<span id="totalsPieChartOverlayText" style="font-size: 45rem; font-family: 'Bree5erif-Mono'; font-weight: bold; color: white; text-shadow: 0 0 2rem #ffffff, 0 0 5rem #000000;"></span>
<span id="totalsPieChartOverlayText" style="font-size: 45rem; font-family: 'Bree5erif-Mono'; font-weight: bold; color: white; text-shadow: 0 0 2rem #ffffff, 0 0 5rem #000000; display: flex; flex-direction: column; justify-content: center; align-items: center;"></span>
</div>
</div>
<div id="partyDropdownsBoxContainer" class="boxcontainer textbox" style="display: inline-block; margin-top: 10rem; width: 100%">
Expand Down
2 changes: 1 addition & 1 deletion src/display/control-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ document.addEventListener('keypress', async function(e) {
break

case 2:
marginValues = {safe: 5, likely: 3, lean: 1, tilt: Number.MIN_VALUE}
marginValues = cloneObject(alternateMarginValues)
break
}

Expand Down
93 changes: 70 additions & 23 deletions src/display/dropdowns/compare-dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@ var selectedCompareSlider

var showingCompareCheckboxes = false

function initializeCompareVariables()
var shouldCombineMinorThirdParties = true
var getCompareMajorParties

var compareResultCustomMapSource
var shouldSetCompareMapSource

function resetCompareVariables()
{
showingCompareMap = false
currentCompareSliderDate = null
compareMapSourceIDArray = [null, null]
compareMapDataArray = [null, null]
selectedCompareSlider = null

getCompareMajorParties = null
compareResultCustomMapSource = null
shouldSetCompareMapSource = true
}

function createComparePresetDropdownItems()
Expand Down Expand Up @@ -82,7 +92,10 @@ async function loadComparePreset(comparePresetNum)
var defaultCompareSourceIDs = currentMapType.getDefaultCompareSourceIDs()

await toggleCompareMapSourceCheckbox(defaultCompareSourceIDs[comparePresetNum][0], true)
await toggleCompareMapSourceCheckbox(defaultCompareSourceIDs[comparePresetNum][1], true)
if (defaultCompareSourceIDs[comparePresetNum][0] != defaultCompareSourceIDs[comparePresetNum][1])
{
await toggleCompareMapSourceCheckbox(defaultCompareSourceIDs[comparePresetNum][1], true)
}

var latestSliderTickEnabled = currentMapType.getMapSettingValue("latestTick")

Expand All @@ -106,12 +119,12 @@ function toggleCompareSortMode(div)
{
case CompareSortMode.voteshare:
compareSortMode = CompareSortMode.shiftMargin
div.innerHTML = "Sort by shift"
div.innerHTML = "Sort by: shift"
break

case CompareSortMode.shiftMargin:
compareSortMode = CompareSortMode.voteshare
div.innerHTML = "Sort by voteshare"
div.innerHTML = "Sort by: voteshare"
break
}
}
Expand All @@ -122,6 +135,11 @@ async function addCompareMapSource(mapSourceID, clickDivIDToIgnore)
{
ignoreMapUpdateClickArray.push(clickDivIDToIgnore)
}

if (currentViewingState == ViewingState.zooming && showingCompareMap && currentMapSource.isCustom() && !mapSources[mapSourceID].zoomingDataFunction)
{
await zoomOutMap()
}

var checkboxID = mapSourceID.replace(/\s/g, '') + "-compare"
var checkboxChecked = $("#" + checkboxID).prop('checked')
Expand Down Expand Up @@ -170,14 +188,15 @@ async function addCompareMapSource(mapSourceID, clickDivIDToIgnore)
$("#" + mapSourceToUncheck.replace(/\s/g, '') + "-compare").prop('checked', false)
}

await updateCompareMapSources(compareSourcesUpdated, false)

showingCompareMap = true

await updateCompareMapSources(compareSourcesUpdated, false)

toggleMapSettingDisable("seatArrangement", true)
updateCompareMapSlidersVisibility()
}

async function updateCompareMapSources(compareSourcesToUpdate, overrideSwapSources, swapSliderValues)
async function updateCompareMapSources(compareSourcesToUpdate, overrideSwapSources, swapSliderValues, overrideDateValues = [null, null])
{
$('.comparesourcecheckbox').prop('disabled', true)
if (compareSourcesToUpdate[0])
Expand All @@ -196,7 +215,6 @@ async function updateCompareMapSources(compareSourcesToUpdate, overrideSwapSourc
compareSourcesToUpdate = [true, true]
}

var overrideDateValues = [null, null]
if (swapSliderValues)
{
overrideDateValues[0] = $("#secondCompareDataMapDateSlider").val()
Expand All @@ -209,15 +227,15 @@ async function updateCompareMapSources(compareSourcesToUpdate, overrideSwapSourc
{
setDataMapDateSliderRange(true, "firstCompareDataMapDateSlider", "firstCompareDataMapSliderStepList", mapSources[compareMapSourceIDArray[0]].getMapDates())
$("#firstCompareDataMapDateSlider").val(overrideDateValues[0] || mapSources[compareMapSourceIDArray[0]].getMapDates().length+(latestSliderTickEnabled ? 1 : 0))
setCompareSourceDate(0, overrideDateValues[0] || mapSources[compareMapSourceIDArray[0]].getMapDates().length+(latestSliderTickEnabled ? 1 : 0), !compareSourcesToUpdate[1])
await setCompareSourceDate(0, overrideDateValues[0] || mapSources[compareMapSourceIDArray[0]].getMapDates().length+(latestSliderTickEnabled ? 1 : 0), !compareSourcesToUpdate[1])
$("#compareItemImage-0").css('display', "block")
$("#compareItemImage-0").prop('src', mapSources[compareMapSourceIDArray[0]].getIconURL())
}
if (compareSourcesToUpdate[1])
{
setDataMapDateSliderRange(true, "secondCompareDataMapDateSlider", "secondCompareDataMapSliderStepList", mapSources[compareMapSourceIDArray[1]].getMapDates())
$("#secondCompareDataMapDateSlider").val(overrideDateValues[1] || mapSources[compareMapSourceIDArray[1]].getMapDates().length+(latestSliderTickEnabled ? 1 : 0))
setCompareSourceDate(1, overrideDateValues[1] || mapSources[compareMapSourceIDArray[1]].getMapDates().length+(latestSliderTickEnabled ? 1 : 0))
await setCompareSourceDate(1, overrideDateValues[1] || mapSources[compareMapSourceIDArray[1]].getMapDates().length+(latestSliderTickEnabled ? 1 : 0))
$("#compareItemImage-1").css('display', "block")
$("#compareItemImage-1").prop('src', mapSources[compareMapSourceIDArray[1]].getIconURL())
}
Expand All @@ -226,12 +244,6 @@ async function updateCompareMapSources(compareSourcesToUpdate, overrideSwapSourc
async function loadCompareMapSource(sourceID)
{
await downloadDataForMapSource(sourceID, getIconDivsToUpdateArrayForSourceID(sourceID))

// let mapSource = mapSources[sourceID]
// let voteshareCutoff = mapSource.voteshareCutoffMargin
// mapSource.voteshareCutoffMargin = null
// await mapSource.loadMap()
// mapSource.voteshareCutoffMargin = voteshareCutoff
}

function shouldSwapCompareMapSources(firstMapSourceID, secondMapSourceID)
Expand Down Expand Up @@ -306,7 +318,9 @@ async function executeCompareMapQueue()

async function setCompareSourceDate(compareArrayIndex, dateIndex, shouldApply = true)
{
var mapDates = mapSources[compareMapSourceIDArray[compareArrayIndex]].getMapDates()
let mapSource = mapSources[compareMapSourceIDArray[compareArrayIndex]]

var mapDates = mapSource.getMapDates()

var dateToDisplay
var overrideDateString
Expand All @@ -322,13 +336,18 @@ async function setCompareSourceDate(compareArrayIndex, dateIndex, shouldApply =
}
updateSliderDateDisplay(dateToDisplay, overrideDateString, compareArrayIndex == 0 ? "firstCompareDateDisplay" : "secondCompareDateDisplay")

$("#compareItem-" + compareArrayIndex).html(mapSources[compareMapSourceIDArray[compareArrayIndex]].getName() + " (" + getDateString(dateToDisplay) + ")")

compareMapDataArray[compareArrayIndex] = mapSources[compareMapSourceIDArray[compareArrayIndex]].getMapData()[dateToDisplay.getTime()]
$("#compareItem-" + compareArrayIndex).html(mapSource.getName() + " (" + getDateString(dateToDisplay) + ")")

compareMapDataArray[compareArrayIndex] = mapSource.getMapData()[dateToDisplay.getTime()]
if (currentMapZoomRegion != null && currentMapType.getID() == USAPresidentMapType.getID())
{
compareMapDataArray[compareArrayIndex] = await mapSource.getZoomingData(compareMapDataArray[compareArrayIndex], currentMapZoomRegion, dateToDisplay.getTime())
}

if (compareArrayIndex == 0)
{
currentCustomMapSource.setCandidateNames(mapSources[compareMapSourceIDArray[compareArrayIndex]].getCandidateNames(dateToDisplay.getTime()), dateToDisplay.getTime())
let candidateNames = mapSource.getCandidateNames(dateToDisplay.getTime())
currentCustomMapSource.setCandidateNames(candidateNames, dateToDisplay.getTime())
currentCompareSliderDate = dateToDisplay
}

Expand Down Expand Up @@ -401,6 +420,31 @@ async function applyCompareToCustomMap()

if (compareRegionData0.partyVotesharePercentages && compareRegionData1.partyVotesharePercentages)
{
const compareMajorParties = getCompareMajorParties?.()
if (shouldCombineMinorThirdParties && compareMajorParties?.length == 2)
{
[[compareRegionData0, compareMajorParties[0]], [compareRegionData1, compareMajorParties[1]]].forEach(compareData => {
let compareRegionData = compareData[0]
let majorPartyIDs = compareData[1]

let minorPartyData = compareRegionData.partyVotesharePercentages
.filter(voteshareData => !majorPartyIDs.includes(voteshareData.partyID))

compareRegionData.partyVotesharePercentages = compareRegionData.partyVotesharePercentages
.filter(voteshareData => majorPartyIDs.includes(voteshareData.partyID))

let totalMinorPartyVoteshare = minorPartyData.reduce((otherVoteshare, voteshareData) => {
return otherVoteshare + voteshareData.voteshare
}, 0)

compareRegionData.partyVotesharePercentages.push({
candidate: "Other",
partyID: IndependentGenericParty.getID(),
voteshare: totalMinorPartyVoteshare
})
})
}

compareRegionData0.partyVotesharePercentages.sort((candidateData0, candidateData1) => candidateData0.voteshare-candidateData1.voteshare)
compareRegionData1.partyVotesharePercentages.sort((candidateData0, candidateData1) => candidateData0.voteshare-candidateData1.voteshare)

Expand Down Expand Up @@ -470,7 +514,10 @@ async function applyCompareToCustomMap()
}
}

currentCustomMapSource.updateMapData(resultMapArray, (new Date(getTodayString("/", false, "mdy"))).getTime(), true, null, EditingMode.voteshare)
(compareResultCustomMapSource ?? currentCustomMapSource).updateMapData(resultMapArray, (new Date(getTodayString("/", false, "mdy"))).getTime(), true, null, EditingMode.voteshare)

await setMapSource(currentCustomMapSource)
if (shouldSetCompareMapSource)
{
await setMapSource(currentCustomMapSource)
}
}
52 changes: 41 additions & 11 deletions src/display/map-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var pannedDuringClick = false
var selectedParty

const standardMarginValues = {safe: 15, likely: 5, lean: 1, tilt: Number.MIN_VALUE}
const alternateMarginValues = {safe: 5, likely: 3, lean: 1, tilt: Number.MIN_VALUE}
var defaultMarginValues = JSON.parse(getCookie(marginsCookieName)) || standardMarginValues
var marginValues = cloneObject(defaultMarginValues)
var marginNames = {safe: "Safe", likely: "Likely", lean: "Lean", tilt: "Tilt"}
Expand Down Expand Up @@ -221,7 +222,7 @@ async function reloadForNewMapType(initialLoad)
currentViewingState = currentMapType.getMapSettingValue("presViewingType") ? ViewingState.splitVote : ViewingState.viewing
currentMapZoomRegion = null

initializeCompareVariables()
resetCompareVariables()

createMapTypeDropdownItems()
createComparePresetDropdownItems()
Expand All @@ -233,7 +234,8 @@ async function reloadForNewMapType(initialLoad)
{
$("#sourceToggleButton").addClass('active')
}


currentMapType.resetOverrideSVGPath()
await loadMapSVGFile()

$("#totalsPieChart").remove()
Expand Down Expand Up @@ -615,6 +617,10 @@ async function loadDataMap(shouldSetToMax, forceDownload, previousDateOverride,
{
marginValues = currentMapSource.getCustomDefaultMargins()
}
// else if (currentMapSource.isCustom() && showingCompareMap)
// {
// marginValues = cloneObject(alternateMarginValues)
// }
else
{
marginValues = cloneObject(defaultMarginValues)
Expand Down Expand Up @@ -806,6 +812,11 @@ async function displayDataMap(dateIndex, reloadPartyDropdowns, fadeForNewSVG)
var populateSVGBoxesFunction = svgPathData[3]

var currentMapDataForDate = currentMapSource.getMapData()[dateToDisplay.getTime()]

if (currentViewingState == ViewingState.zooming && !currentMapSource.zoomingDataFunction)
{
await zoomOutMap(false)
}

switch (currentViewingState)
{
Expand All @@ -814,7 +825,7 @@ async function displayDataMap(dateIndex, reloadPartyDropdowns, fadeForNewSVG)
break

case ViewingState.zooming:
currentMapDataForDate = await currentMapSource.getZoomingData(currentMapDataForDate, currentMapZoomRegion)
currentMapDataForDate = await currentMapSource.getZoomingData(currentMapDataForDate, currentMapZoomRegion, dateToDisplay.getTime())
break

case ViewingState.splitVote:
Expand Down Expand Up @@ -1059,18 +1070,22 @@ function clearMap(fullClear, shouldResetCurrentMapSource)

if (showingCompareMap)
{
showingCompareMap = false

resetCompareVariables()
$(".comparesourcecheckbox").prop('checked', false)

compareMapSourceIDArray = [null, null]
updateCompareMapSlidersVisibility()

$(".compareitemtext").html("&lt;Empty&gt;")
$(".compareitemimage").css('display', "none")
$(".compareitemimage").attr('src', "")

toggleMapSettingDisable("seatArrangement", false)

if (currentViewingState == ViewingState.zooming)
{
zoomOutMap(false)
}
}

marginValues = cloneObject(defaultMarginValues)
Expand Down Expand Up @@ -1318,17 +1333,29 @@ async function toggleEditing(stateToSet)
updatePartyDropdownVisibility()
}

function zoomOutMap()
async function zoomOutMap(displayMap = true)
{
currentViewingState = ViewingState.viewing
currentMapZoomRegion = null

if (currentMapSource.isCustom())

const countyResultMapSourceID = "Presidential-Counties"
if (showingCompareMap && currentMapType.getID() == USAPresidentMapType.getID() && compareMapSourceIDArray[0] == countyResultMapSourceID && compareMapSourceIDArray[1] == countyResultMapSourceID)
{
const pastResultMapSourceID = "Past-Presidential-Elections"
compareMapSourceIDArray = [pastResultMapSourceID, pastResultMapSourceID]
compareResultCustomMapSource = null
getCompareMajorParties = null
shouldSetCompareMapSource = currentMapSource.isCustom();

await updateCompareMapSources([true, true], true, false, [$("#firstCompareDataMapDateSlider").val(), $("#secondCompareDataMapDateSlider").val()])
shouldSetCompareMapSource = true
}
else if (currentMapSource.isCustom())
{
currentCustomMapSource.updateMapData(displayRegionDataArray, getCurrentDateOrToday(), false, currentMapSource.getCandidateNames(getCurrentDateOrToday()))
}

displayDataMap(null, null, true)
displayMap && displayDataMap(null, null, true)
}

function getRegionData(regionID)
Expand Down Expand Up @@ -1474,9 +1501,12 @@ function getMarginIndexForValue(margin)
{
return "current"
}

const roundedMargin = getRoundedMarginValue(margin)

for (var marginName in marginValues)
{
if (Math.abs(margin) >= marginValues[marginName])
if (Math.abs(roundedMargin) >= marginValues[marginName])
{
return marginName
}
Expand Down
9 changes: 6 additions & 3 deletions src/display/region-box.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,14 @@ async function updateRegionBox(regionID = currentRegionID)

regionBoxHTML += "<div style='font-size: 17px; padding-top: 2px; padding-bottom: 5px; padding-right: 8px; display: block; line-height: 100%; border-radius: 50px;'>"

let hasVoteCountsForAll = true
let hasVoteCountsForAll = !(showingCompareMap && currentMapSource.isCustom())

sortedPercentages.forEach((voteData, i) => {
const roundedVoteshare = Math.round(voteData.voteshare*100)/100
if (roundedVoteshare <= 0 && !currentMapSource.isCustom()) { return }

regionBoxHTML += "<span id='voteshare-" + (voteData.partyID + "-" + voteData.candidate) + "' style='display: inline-block; padding: 4px; color: #fff; border-radius: " + (i == 0 ? "3px 3px" : "0px 0px") + " " + (i == sortedPercentages.length-1 ? "3px 3px" : "0px 0px") + "; " + "background: " + getGradientCSS(politicalParties[voteData.partyID].getMarginColors().safe, politicalParties[voteData.partyID].getMarginColors().lean, (showingCompareMap && currentMapSource.isCustom() ? 50 : 0) + voteData.voteshare) + "; " + " width: 100%'><span style='float: left;'>" + voteData.candidate + "</span><span style='float: right;'>"
regionBoxHTML += shiftKeyDown && voteData.votes ? addCommaFormatting(voteData.votes) : (showingCompareMap && currentMapSource.isCustom() && voteData.voteshare > 0.0 ? "+" : "") + decimalPadding(Math.round(voteData.voteshare*100)/100, 2) + currentMapSource.getVoteshareSuffix()
regionBoxHTML += shiftKeyDown && !(showingCompareMap && currentMapSource.isCustom()) && voteData.votes ? addCommaFormatting(voteData.votes) : (showingCompareMap && currentMapSource.isCustom() && voteData.voteshare > 0.0 ? "+" : "") + decimalPadding(roundedVoteshare, 2) + currentMapSource.getVoteshareSuffix()
regionBoxHTML += "</span></span><br>"

hasVoteCountsForAll = hasVoteCountsForAll && voteData.votes != null
Expand Down Expand Up @@ -237,7 +240,7 @@ async function updateRegionBox(regionID = currentRegionID)
}

tooltipsToShow.altForAlternateData[0] = regionData.altData || showingAltData
tooltipsToShow.shiftClickToEditEVs[0] = isDiscreteRegion && currentMapType.getID() == USAPresidentMapType.getID() && currentMapSource.isCustom() && currentEditingState == EditingState.viewing
tooltipsToShow.shiftClickToEditEVs[0] = isDiscreteRegion && currentMapType.getID() == USAPresidentMapType.getID() && currentMapSource.isCustom() && currentEditingState == EditingState.viewing && currentViewingState == ViewingState.viewing
tooltipsToShow.clickToZoom[0] = canZoomCurrently && currentViewingState == ViewingState.viewing
tooltipsToShow.clickToOpenLink[0] = currentMapSource.hasHomepageURL() && !tooltipsToShow.clickToZoom[0] && currentEditingState == EditingState.viewing
tooltipsToShow.clickToEditVoteshare[0] = isDiscreteRegion && currentEditingState == EditingState.editing && currentMapSource.getEditingMode() == EditingMode.voteshare
Expand Down
Loading

0 comments on commit c59c134

Please sign in to comment.