Published
Edited
Dec 1, 2020
Fork of New Cases
Insert cell
Insert cell
chart = {
const root = d3.create("div")
.attr("class", "root");
const svg = root.append("svg")
.attr("viewBox", [0, 0, width, height]);
// svg.append("g")
// .call(yAxis);
// svg.append("path")
// .datum(avg)
// .attr("fill", color)
// .attr("opacity", 0.15)
// .attr("d", area);
// svg.append("g")
// .attr("fill", "#F5B48F")
// .attr("opacity", 1)
// .selectAll("rect")
// .data(data)
// .join("rect")
// .attr("x", (d, i) => x(i+2))
// .attr("y", d => y(d.new_cases))
// .attr("height", d => y(0) - y(d.new_cases))
// .attr("width", x.bandwidth())
svg.append("path")
.datum(avg)
.attr("fill", "none")
.attr("stroke", color)
.attr("stroke-width", 3)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("d", line);
svg.append("g")
.call(xAxis)
.select('.domain').attr("opacity", 0)
.select('.tick:first-of-type text').remove()
.selectAll('.tick text')
.attr('font-size', 15)
.attr('font-family', 'Helvetica')
.attr('fill', 'gray');
window.addEventListener("resize", () => resized(width, root, svg));
setTimeout(() => resized(width, root, svg), 12);
return root.node();
}
Insert cell
function resized(width, root, svg) {
let measuredWidth = root.node().getBoundingClientRect().width;
if (measuredWidth == 0) {
setTimeout(() => resized(width, root, svg), 12);
return;
}
let scale = width / measuredWidth;
svg.selectAll("line").attr("stroke-width", scale + "px");
svg.selectAll("text").attr("transform", "scale(" + scale + " " + scale + ")");
}
Insert cell
html`
<style>
.cooltip {
background: white;
border: 1px solid lightgrey;
padding: 10px;
position: absolute;
font-family: Helvetica, Arial, sans-serif;
}
.date {
font-weight: 700;
font-size: 14px;
}
.desc {
font-size: 10px;
text-transform: uppercase;
color: grey;
}
.num {
font-size: 14px;
}
</style>
`
Insert cell
area = d3.area()
.curve(curve)
.x((d, i) => x(i+2)+3)
.y0(y(0))
.y1(d => y(d.new_cases))
Insert cell
curve = d3.curveLinear
Insert cell
line = d3.line()
.defined(d => !isNaN(d.new_cases))
.x((d, i) => x(i+2)+3)
.y(d => y(d.new_cases))
Insert cell
avg = data.map(rollingAvg).filter(d => d != null)
Insert cell
data = Object.assign(await d3.csv("https://raw.githubusercontent.com/prayaggordy/D3-covid-map/master/data/md_statewide.csv", d3.autoType)).map(({date, new_cases}) => ({date, new_cases: +new_cases}))
Insert cell
function rollingAvg (b, index, array) {
let count = 0;
for (let i = 0; i < 7; ++i) {
if (index - i < 0)
return {...b, new_cases: count/i}
count += array[index - i].new_cases;
};
return {...b, new_cases: count/7};
};
Insert cell
xDate = d3.scaleUtc()
.domain(d3.extent(data, d => d.date))
.range([margin.left, width - margin.right])
Insert cell
x = d3.scaleBand()
.domain(d3.range(data.length+2))
.range([margin.left, width - margin.right])
.padding(0.1)
Insert cell
y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.new_cases)+6]).nice()
.range([height - margin.bottom, margin.top])
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xDate).ticks(width / 150).tickSize(0))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisRight(y)
.ticks(height / 50, data.format)
.tickSize(0))
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".tick:not(:first-of-type) line")
.attr("stroke-dasharray", "2,2")
.attr("stroke-opacity", d => d === 1 ? null : 0.25)
.attr("x2", width - margin.left - margin.right))
.call(g => g.selectAll(".tick text")
.attr("x", 4)
.attr("dy", -4))
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 44)
.attr("text-anchor", "start")
.text(" " + "cases"))
.call(g => g.select(".tick:first-of-type text").remove())
Insert cell
color = "#E05F15"
Insert cell
height = 600
Insert cell
width = 550
Insert cell
margin = ({top: 20, right: 10, bottom: 20, left: 0})
Insert cell
d3 = require("d3@5")
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