Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions modules/Pilkada2024/BoundaryLayers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export type BoundaryLayersProps = {
code: string
}

const MIN_OPACITY = 0.1
const MAX_OPACITY = 0.7

export default function BoundaryLayers({
election,
code: parentCode,
Expand Down Expand Up @@ -56,22 +59,41 @@ export default function BoundaryLayers({
{childAreas.map((_childArea) => {
const votes = getVotesByArea(_childArea.code)

// Calculate the winner
const winner = Object.keys(candidates).reduce((acc, id) => {
if (votes[id] > votes[acc]) {
return id
}
return acc
})
// Prepare numeric votes for sorting
const candidateIds = Object.keys(candidates)
const numericVotes = candidateIds.map((id) => ({
id,
val: votes[id],
}))

// Sort descending to get winner and runner-up
numericVotes.sort((a, b) => b.val - a.val)
const winnerId = numericVotes[0]?.id
const winnerVal = numericVotes[0].val
const runnerUpVal = numericVotes[1]?.val ?? 0

// Total numeric votes
const total = numericVotes.reduce((s, x) => s + x.val, 0)

// Compute margin = winnerShare - runnerUpShare, in [0,1]
const winnerShare = winnerVal / total
const runnerUpShare = runnerUpVal / total
const margin = Math.max(0, winnerShare - runnerUpShare)

// Emphasize large margins using power > 1 (exponent = 2)
const EXPONENT = 2
const transformed = Math.max(0, Math.min(1, margin)) ** EXPONENT

return (
<AreaBoundary
area={childArea}
key={_childArea.code}
code={_childArea.code}
pathOptions={{
color: `var(--chart-${candidates[winner].nomor_urut})`,
fillOpacity: 0.3,
color: `var(--chart-${candidates[winnerId].nomor_urut})`,
fillColor: `var(--chart-${candidates[winnerId].nomor_urut})`,
fillOpacity:
MIN_OPACITY + (MAX_OPACITY - MIN_OPACITY) * transformed,
}}
eventHandlers={{
add: (e) => {
Expand Down
30 changes: 20 additions & 10 deletions modules/Pilkada2024/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use client'

import { EraserIcon, LoaderCircleIcon } from 'lucide-react'
import Link from 'next/link'
import { useState } from 'react'
import { toast } from 'sonner'
import { Combobox } from '@/components/Combobox'
import ComboboxArea from '@/components/ComboboxArea'
import GitHubIcon from '@/components/icons/GitHubIcon'
import { Button } from '@/components/ui/button'
import { config } from '@/lib/config'
import { Area } from '@/lib/const'
Expand Down Expand Up @@ -115,16 +117,24 @@ export default function Sidebar() {
/>
)}

<Button
variant="outline"
className="mt-auto items-center"
onClick={() => {
clear()
}}
>
<EraserIcon />
Clear all results
</Button>
{seleted && (
<Button variant="outline" className="mt-2 items-center" onClick={clear}>
<EraserIcon />
Clear all results
</Button>
)}

<span className="text-xs text-foreground/60 mt-4 flex flex-wrap justify-center items-center">
Data from:
<Link
href="https://github.com/razanfawwaz/pilkada-scrap"
target="_blank"
className="inline-flex justify-center items-center ml-1 gap-1 underline"
>
<GitHubIcon className="w-4 h-4" />
razanfawwaz/pilkada-scrap
</Link>
</span>
</div>
)
}
Loading