Public
Edited
Oct 8, 2023
Insert cell
Insert cell
Insert cell
file = FileAttachment("tweet.js").blob()
Insert cell
d3 = require("d3@6")
Insert cell
Insert cell
tweets = {
let tweets = [];

const text = await Files.text(file);
try {
// Twitter archive format starts with: `window.YTD.tweet.part0 = [ {`
tweets = JSON.parse(text.slice(25)).map(t => t.tweet);
} catch {
tweets = JSON.parse(text);
}

return tweets.map(t => {
t.retweet_count = +t.retweet_count;
t.favorite_count = +t.favorite_count;
t.created_at = new Date(t.created_at);
t.hour = t.created_at.getHours();
return t;
});
}
Insert cell
grouped = d3
.rollups(
tweets,
v => d3.mean(v, d => d.retweet_count),
d => d.created_at.getDay(),
d => d.created_at.getHours() + 5
)
.map(([day, v]) => v.map(([hour, value]) => ({ day, hour, value })))
.flat()
Insert cell
Insert cell
legend({ color: color })
Insert cell
Insert cell
svg = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

const g = svg
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);

g.append("g")
.call(d3.axisBottom(x).tickFormat(dateFmt))
.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call(axis =>
axis
.append("text")
.text(xAttr)
.style("fill", "black")
.attr("transform", `translate( ${x.range()[1]}, +30)`)
.style("text-anchor", "end")
)
.call(axis => axis.selectAll("line").remove())
.call(axis => axis.selectAll("path").remove());

g.append("g")
.call(d3.axisLeft(y))
.call(axis =>
axis
.append("text")
.text(yAttr)
.style("fill", "black")
.style("text-anchor", "middle")
.attr("y", -15)
)
.call(axis => axis.selectAll("line").remove())
.call(axis => axis.selectAll("path").remove());

g.selectAll(".cell")
.data(grouped)
.join("rect")
.attr("class", "cell")
.attr("x", d => x(d.day))
.attr("y", d => y(d.hour))
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.attr("fill", d => color(d.value));

return svg.node();
}
Insert cell
color = d3
.scaleSequential(d3.interpolateGreens)
.domain(d3.extent(grouped, d => d.value))
Insert cell
x = d3
.scaleBand()
.domain(d3.range(7))
.range([0, y.bandwidth() * 30])
Insert cell
y = d3
.scaleBand()
.domain(d3.range(24))
.range([0, iheight])
Insert cell
iwidth = width - margin.left - margin.right
Insert cell
iheight = height - margin.top - margin.bottom
Insert cell
yAttr = "Hours"
Insert cell
xAttr = "Day of the Week"
Insert cell
dateFmt = d => "SMTWHFS"[d]
Insert cell
height = 600
Insert cell
margin = ({ left: 50, top: 30, right: 20, bottom: 50 })
Insert cell
import { legend } from "@d3/color-legend"
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
tweet = FileAttachment("tweet.json").json()
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