2024-election-results/index.html

161 lines
5.7 KiB
HTML
Raw Permalink Normal View History

2024-11-06 12:24:11 -05:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
href="https://cdn.jsdelivr.net/npm/daisyui@4.12.14/dist/full.min.css"
rel="stylesheet"
type="text/css"
/>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="navbar bg-neutral text-neutral-content">
<button class="btn btn-ghost text-xl">2024 Election Results</button>
</div>
<div class="overflow-x-auto">
<table class="table table-xs">
<thead>
<tr>
<th>Name</th>
<th>Party</th>
<th>Votes</th>
</tr>
</thead>
<tbody id="table-body"></tbody>
</table>
</div>
<div class="navbar bg-neutral text-neutral-content">
<button class="btn btn-ghost text-xl">Breakdown Per State</button>
</div>
<div id="state-container" class="grid grid-cols-3 gap-4"></div>
<script>
(async () => {
const metaResp = await fetch(
"https://graphics.thomsonreuters.com/data/2024/us-elections/production/events/20241105/metadata.json"
);
const metadata = await metaResp.json();
const states = new Map(metadata.geo.map((c) => [c.uid, c.name]));
const parties = new Map(metadata.parties.map((c) => [c.code, c.name]));
const candidates = new Map(
metadata.candidates.map((c) => [
c.uid,
[c.fullName, parties.get(c.candidateRaces[0].majorParty)],
])
);
const presResp = await fetch(
"https://graphics.thomsonreuters.com/data/2024/us-elections/production/events/20241105/summary-votes/president.json"
);
const president = await presResp.json();
let data = president[0].state_electionTypes
.map((t) =>
t.state.officeRaces[0].candidateVotes.map((o) => {
return {
name: candidates
? candidates.get(o.candidate)
: [o.candidate, "?"],
votes: o.totalVote,
};
})
)
.reduce((acc, current) => {
current.forEach((candidate) => {
const existingCandidate = acc.find(
(c) => c.name === candidate.name
);
if (existingCandidate) {
existingCandidate.votes += candidate.votes;
} else {
acc.push(candidate);
}
});
return acc;
}, []);
let stateVotes = president[0].state_electionTypes.map((t) => {
return {
state: states ? states.get(t.state.uid) : t.uid,
current: t.state.officeRaces[0].officeVotes[0].totalVote,
expected: t.state.officeRaces[0].officeVotes[0].totalExpectedVote,
candidates: t.state.officeRaces[0].candidateVotes.map((o) => {
return {
name: candidates
? candidates.get(o.candidate)
: [o.candidate, "?"],
votes: o.totalVote,
};
}),
};
});
if (data.length > 0) {
let tableBody = document.getElementById("table-body");
tableBody.innerHTML = "";
data
.sort((a, b) => b.votes - a.votes)
.forEach((row, index) => {
let rowElement = tableBody.insertRow();
let nameCell = rowElement.insertCell();
let partyCell = rowElement.insertCell();
let votesCell = rowElement.insertCell();
nameCell.textContent = row.name[0];
partyCell.textContent = row.name[1];
votesCell.textContent = row.votes;
});
}
if (stateVotes.length > 0) {
let stateContainer = document.getElementById("state-container");
stateContainer.innerHTML = "";
stateVotes.forEach((row) => {
const table = document.createElement("table");
table.setAttribute("class", `table table-xs`);
const caption = document.createElement("caption");
caption.innerHTML = `<h2 class="text-xl">${row.state}</h2>`;
table.appendChild(caption);
const thead = document.createElement("thead");
const headerRow = document.createElement("tr");
const headers = ["Name", "Party", "Votes"];
headers.forEach((header) => {
const th = document.createElement("th");
th.textContent = header;
headerRow.appendChild(th);
});
thead.appendChild(headerRow);
table.appendChild(thead);
const tbody = document.createElement("tbody");
row.candidates
.sort((a, b) => b.votes - a.votes)
.forEach((candidate) => {
const rowElement = document.createElement("tr");
const nameCell = document.createElement("td");
nameCell.textContent = candidate.name[0];
rowElement.appendChild(nameCell);
const partyCell = document.createElement("td");
partyCell.textContent = candidate.name[1];
rowElement.appendChild(partyCell);
const votesCell = document.createElement("td");
votesCell.textContent = candidate.votes;
rowElement.appendChild(votesCell);
tbody.appendChild(rowElement);
});
table.appendChild(tbody);
stateContainer.appendChild(table);
});
}
})().catch((e) => {
console.error(e);
});
</script>
</body>
</html>