Published unlisted
Edited
May 11, 2022
Insert cell
html`
<button id="startLine">Start Animation</button>
`
Insert cell
<!--<this section is original code>!-->
<style>
* {
box-sizing: border-box;
}
.row {
display: flex;
}

.column {
padding: 5px;
}
</style>

<html>
<h2 style="text-align:left; font-family:sans-serif">Voters Per Polling Place in Georgia</h2>
<font size = 3 style="text-align:left; font-family:sans-serif;"> Voter registrations in Metro Atlanta have <font color = '#BF1F2C'><strong><i>jumped </strong></font></i> sharply. The number of polling places <strong> <font color= "#BF1F2C">hasn't</font></strong> kept pace, resulting in <strong> <font color= "#BF1F2C"><i> more </font></strong></i> voters assigned to each polling place.</h5>

<br><br>
<font size = 1 style="text-align:left; font-family:sans-serif;"><strong># of Voters per Polling Location</strong></h6>
<div class = "row">
<div class = "column">
${plot1}
<font size = 1 style="text-align:right; font-family:sans-serif;"><strong></strong></h6>
</div>
<div class="column">
${legend}
</div>
<body>
<div style = "position:relative; left:-800px; top:-220px;">
<strong>Election Year</strong>
</div>
</body>
</div>
</html>`
Insert cell
//I found this underlying code from the example provided in class (https://observablehq.com/@mprasse/week-12-interaction-and-animation-d3-transitions-behavior). I substantially edited it by creating more lines, changing colors, and changing the data. I also changed it by adding this code to a variable, and placing that in an html block. I also changed the dimensions and size of the graph.

plot1 =
{
var margin = {top: 60, right: 20, bottom: 30, left: 50},
width = 700 - margin.left - margin.right,
height = 365 - margin.top - margin.bottom;
const svg = d3.select(DOM.svg(width, height));
let x = d3.scaleLinear()
.domain(d3.extent([{date: 2012, value: 2430}, {date: 2020, value: 4109}], d => d.date))
.range([margin.left, width - margin.right])
let y = d3.scaleLinear()
.domain([0, d3.max([{date: 2012, value: 2430}, {date: 2020, value: 4109}], d => d.value)]).nice()
.range([height - margin.bottom, margin.top])
let xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0).tickFormat(d3.format("d")))
let yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.call(g => g.select(".domain").remove())
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 3)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text([{date: 2012, value: 2398}, {date: 2020, value: 3118}].y))
let line = d3.line()
.defined(d => !isNaN(d.value))
.x(d => x(d.date))
.y(d => y(d.value))

svg.append("g")
.call(xAxis);

svg.append("g")
.call(yAxis);
let path = svg.append("path")
.attr("d", line([{date: 2012, value: 2398}, {date: 2020, value: 3118}]))
.attr("stroke", "#BF1F2C")
.attr("stroke-width", "3")
.attr("class", "line")
.attr("fill", "none");

let path2 = svg.append("path")
.attr("d", line([{date: 2012, value: 2478}, {date: 2016, value: 2198}, {date: 2018, value: 2590}, {date: 2020, value: 3281}])) //Paths 2-4 were created by me and a substantial change to the original.
.attr("stroke", "#D9737B")
.attr("stroke-width", "3")
.attr("class", "line")
.attr("fill", "none");

let path3 = svg.append("path")
.attr("d", line([{date: 2012, value: 3072}, {date: 2016, value: 3305}, {date: 2018, value: 3943}, {date: 2020, value: 4689}]))
.attr("stroke", "#021F59")
.attr("stroke-width", "3")
.attr("class", "line")
.attr("fill", "none");

let path4 = svg.append("path")
.attr("d", line([{date: 2012, value: 2430}, {date: 2016, value: 2929}, {date: 2018, value: 3703}, {date: 2020, value: 4109}]))
.attr("stroke", "#4D688C")
.attr("stroke-width", "3")
.attr("class", "line")
.attr("fill", "none");

var totalLength = path.node().getTotalLength()

//animate lines
d3.select("#startLine").on("click", function() {
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(10000)
.ease(d3.easeLinear)
.attr("stroke-dashoffset", 0)

//Paths 2-4 were created by me and a substantial change to the original.
path2
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(10000)
.ease(d3.easeLinear)
.attr("stroke-dashoffset", 0)

path3
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(10000)
.ease(d3.easeLinear)
.attr("stroke-dashoffset", 0)
path4
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(10000)
.ease(d3.easeLinear)
.attr("stroke-dashoffset", 0)


})
return svg.node();
}


Insert cell
//this is original code, I found code online to make a circle and then combined that with code to add text next to it.

legend =
{
var margin = {top: 60, right: 20, bottom: 30, left: 50},
width = 700 - margin.left - margin.right,
height = 365 - margin.top - margin.bottom;
const svg = d3.select(DOM.svg(500, 500));

svg.append("circle").attr("cx",20).attr("cy",50).attr("r", 6).style("fill", "#021F59")
svg.append("circle").attr("cx",20).attr("cy",80).attr("r", 6).style("fill", "#4D688C")
svg.append("circle").attr("cx",20).attr("cy",140).attr("r", 6).style("fill", "#BF1F2C")
svg.append("circle").attr("cx",20).attr("cy",110).attr("r", 6).style("fill", "#D9737B")
svg.append("text").attr("x", 45).attr("y", 50).text("Cherokee County").style("font-size", "15px").attr("alignment-baseline","middle")
svg.append("text").attr("x", 45).attr("y", 80).text("Hall County").style("font-size", "15px").attr("alignment-baseline","middle")
svg.append("text").attr("x", 45).attr("y", 140).text("Fulton County").style("font-size", "15px").attr("alignment-baseline","middle")
svg.append("text").attr("x", 45).attr("y", 110).text("DeKalb County").style("font-size", "15px").attr("alignment-baseline","middle")


return svg.node();
}
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