Public
Edited
Apr 6, 2023
1 fork
4 stars
Insert cell
Insert cell
bills = ({
'house': [
{
label: 'Theoretical party line vote',
sublabel: '102 yes votes from Republicans and 48 nos from Democrats.',
votes: { yes: {R: 102, D: 0}, no: {R: 0, D: 48 }, absent: {R: 0, D: 0} },
potentialVotes: { yes: {R: 0, D: 0}, no: {R: 0, D: 0 } }
},
{
label: 'HB 372 – Constitutional right to hunt and trap',
sublabel: 'House vote 64-34. Senate vote forthcoming.',
votes: { yes: {R: 64, D: 0}, no: {R: 4, D: 30 }, absent: {R: 0, D: 2} },
potentialVotes: { yes: {R: 34, D: 0}, no: {R: 0, D: 16 } }
},
{
label: 'HB 517 – Expanded Legislative power over universities',
sublabel: 'House vote 61-37. Senate vote forthcoming.',
votes: { yes: {R: 61, D: 0}, no: {R: 7, D: 30 }, absent: {R: 0, D: 2} },
potentialVotes: { yes: {R: 34, D: 0}, no: {R: 0, D: 16 } }
},
{
label: 'HB 551 – Constitutional right to carry concealed firearms',
sublabel: 'House vote 65-33. Senate vote forthcoming.',
votes: { yes: {R: 65, D: 0}, no: {R: 3, D: 30 }, absent: {R: 0, D: 2} },
potentialVotes: { yes: {R: 34, D: 0}, no: {R: 0, D: 16 } }
},
{
label: 'HB 915 – Makes state supreme court justices appointed',
sublabel: 'House vote 59-39. Senate vote forthcoming.',
votes: { yes: {R: 59, D: 0}, no: {R: 9, D: 30 }, absent: {R: 0, D: 2} },
potentialVotes: { yes: {R: 34, D: 0}, no: {R: 0, D: 16 } }
},
{
label: 'HB 965 – Strips lawyer licensing from state supreme court jurisdiction',
sublabel: 'House vote 45-55. Received too few votes to advance to Senate.',
votes: { yes: {R: 45, D: 0}, no: {R: 23, D: 32 }, absent: {R: 0, D: 0} },
potentialVotes: { yes: {R: 0, D: 0}, no: {R: 0, D: 0 } }
},
{
label: 'SB 272 – Enshrines county sheriff powers in Constitution',
sublabel: 'Senate vote 22-28. House vote forthcoming.',
votes: { yes: {R: 22, D: 0}, no: {R: 12, D: 16 }, absent: {R: 0, D: 0} },
potentialVotes: { yes: {R: 68, D: 0}, no: {R: 0, D: 32 } }
},
{
label: 'SB 534 – Forbids consideration of political data in redistricting',
sublabel: 'House vote 31-19, including one Democrat who said she had misvoted. Senate vote forthcoming.',
votes: { yes: {R: 30, D: 1}, no: {R: 4, D: 15 }, absent: {R: 0, D: 0} },
potentialVotes: { yes: {R: 68, D: 0}, no: {R: 0, D: 32 } }
},
{
label: 'SB 563 – Establishes a mental health trust fund',
sublabel: 'Senate vote 40-10. House vote forthcoming.',
votes: { yes: {R: 29, D: 11}, no: {R: 5, D: 5 }, absent: {R: 0, D: 0} },
potentialVotes: { yes: {R: 68, D: 0}, no: {R: 0, D: 32 } }
},
]
})
Insert cell
graphic = {
const width = 600
const height = 1200
const mark = (vote, i, sign) => `<g transform="translate(${sign*Math.floor(i/4)*12 + (i >= 100 ? 8 : 0)},${i%4*12})"><circle
r="5"
cx="0" cy="0"
fill="${fill(vote)}"
fill-opacity="0.7"
stroke="${stroke(vote)}"
/>
</g>`
const houseVotes = bills.house.map((bill, i) => {
const yesVotes =
[].concat(
[...Array(bill.votes.yes.R).keys()].map(d => ({party: 'R', type: 'counted'}))
).concat(
[...Array(bill.votes.yes.D).keys()].map(d => ({party: 'D', type: 'counted'}))
).concat(
[...Array(bill.potentialVotes.yes.R).keys()].map(d => ({party: 'R', type: 'potential'}))
).concat(
[...Array(bill.potentialVotes.yes.D).keys()].map(d => ({party: 'D', type: 'potential'}))
)
const noVotes =
[].concat(
[...Array(bill.votes.no.R).keys()].map(d => ({party: 'R', type: 'counted'}))
).concat(
[...Array(bill.votes.no.D).keys()].map(d => ({party: 'D', type: 'counted'}))
).concat(
[...Array(bill.votes.absent.R).keys()].map(d => ({party: 'R', type: 'absent'}))
).concat(
[...Array(bill.votes.absent.D).keys()].map(d => ({party: 'D', type: 'absent'}))
).concat(
[...Array(bill.potentialVotes.no.R).keys()].map(d => ({party: 'R', type: 'potential'}))
).concat(
[...Array(bill.potentialVotes.no.D).keys()].map(d => ({party: 'D', type: 'potential'}))
)
return `<g transform="translate(210, ${50+i*120})">
<g class="nos" transform="translate(0,10)">
${noVotes.map((vote, i) => mark(vote, i, -1))}</g>

<text y=-40 x=-140 font-size=13 font-weight="bold">${bill.label}</text>
<text y=-25 x=-140 font-size=11 >${bill.sublabel}</text>

<line x1="10" x2="10" y1="-12" y2="55" stroke-width="2" stroke="black" />

<text x="15" y="-3" text-anchor="start">YES votes</text>
<g class="yeses" transform="translate(20,10)">
${yesVotes.map((vote, i) => mark(vote, i, 1))}
</g>

<text x="318" y="-3" text-anchor="middle">100 yes</text>
<text x="5" y="-3" text-anchor="end">NO votes</text>
<line x1="318" x2="318" y1="0" y2="55" stroke-width="1" stroke="black" stroke-dasharray="2"/>
</g>
`})


return html`<svg width=${width} height=${height} viewBox="0 0 ${width} ${height}"
font-family="Arial, sans-serif" font-size="10"
>
<g>${houseVotes}</g>
</svg>`
}
Insert cell
stroke = vote => vote.party === 'R' ? '#d73027' : '#4575b4'
Insert cell
fill = vote => {
if (vote.type === 'absent') return 'gray'
if (vote.type === 'potential') return 'white'
else return vote.party === 'R' ? '#d73027' : '#4575b4'
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more