Public
Edited
May 15, 2024
1 star
Insert cell
Insert cell
Insert cell
viewof race = Inputs.select([...new Set(parsed.map((d) => d.contest))])
Insert cell
Insert cell
Insert cell
Plot.plot({
color: { legend: true },
marks: [
Plot.barY(vals, {
fill: "voteType",
fx: "candidate",
y: "votes",
x: groups.includes("group by ward") ? "ward" : undefined
//sort: { x: "y", reverse: true }
}),
Plot.ruleY([0])
]
})
Insert cell
missing = client.query(
`SELECT precinct, precinct[11] as ward, voteType, candidate FROM data WHERE contest = '${race}' AND votes = 0 AND precinct NOT LIKE '%Provisional' ORDER BY voteType, ward`
)
Insert cell
vals = client.query(
`SELECT precinct, SUM(votes) votes, precinct[11] as ward, voteType, candidate FROM data WHERE contest = '${race}' GROUP BY all ORDER BY voteType, ward`
)
Insert cell
client
Type SQL, then Shift-Enter. Ctrl-space for more options.

Insert cell
client = DuckDBClient.of({"data": parsed})
Insert cell
parsed = parseMontclairResults(data)
Insert cell
import {DuckDBClient} from "@observablehq/duckdb";

Insert cell
import { JSZip } from "https://cdn.jsdelivr.net/npm/jszip@3.7.1/dist/jszip.min.js"
Insert cell
parseMontclairResults(data)
Insert cell
Insert cell
data = fetch(
`https://results.enr.clarityelections.com//NJ/Essex/${code}/${current}/reports/${filename}xml.zip`
)
.then(zipreader)
.then((d) => d.get(filename + ".xml"))
.catch(
(err) =>
`https://results.enr.clarityelections.com//NJ/Essex/${code}/${current}/reports/detailxml.zip`
)
Insert cell
filename = year === 2024 ? "detail" : "detailwithoutvotetypes"
Insert cell
function parseMontclairResults(xml) {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xml, 'text/xml');

const contestElements = xmlDoc.getElementsByTagName('Contest');
const montclairResults = [];

for (let i = 0; i < contestElements.length; i++) {
const contest = contestElements[i];
const contestText = contest.getAttribute('text');

if (contestText.includes('Montclair')) {
const choiceElements = contest.getElementsByTagName('Choice');

for (let j = 0; j < choiceElements.length; j++) {
const choice = choiceElements[j];
const choiceText = choice.getAttribute('text');
const voteTypeElements = choice.getElementsByTagName('VoteType');

for (let k = 0; k < voteTypeElements.length; k++) {
const voteType = voteTypeElements[k];
const voteTypeName = voteType.getAttribute('name');
const precinctElements = voteType.getElementsByTagName('Precinct');

for (let l = 0; l < precinctElements.length; l++) {
const precinct = precinctElements[l];
const precinctName = precinct.getAttribute('name');
const votes = parseInt(precinct.getAttribute('votes'), 10);

montclairResults.push({
contest: contestText,
candidate: choiceText,
voteType: voteTypeName,
precinct: precinctName,
votes
});
}
}
}
}
}

return montclairResults;
}

Insert cell
current = {
refresh;
return fetch(
`https://results.enr.clarityelections.com/NJ/Essex/${code}/current_ver.txt`
).then((d) => d.text());
}
Insert cell
code = {
if (year === 2020) {
return 103451;
} else {
return 121184;
}
}
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
XLSX = require("xlsx")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more