Public
Edited
Feb 24
Insert cell
Insert cell
Insert cell
data = {
// read the text file attached
const text = await FileAttachment("t-data.csv").text()

// the CSV does not have a header, so we parse each row of text
const rawdata = d3.csvParseRows(text)

// then we convert the ISO8601 UTC timestamp in column 1 into a Date object
// we ignore the data in column 2 and 3, as we don't need it for this assignment
// each timestamp represents one observation, so for convenience we add that as a seperate field
return rawdata.map(d => ({
timestamp: d3.utcParse("%Y%m%dT%H%M%S.%LZ")(d[0]),
observation: 1
})
)
}
Insert cell
Insert cell
vl.markLine()
.encode(
vl.x().fieldT("timestamp").timeUnit("yearmonth").title("Month"),
vl.y().count().title("Total Observations")
)
.data(data)
.width(900)
.height(400)
.render()

Insert cell
Insert cell
Insert cell
vl.markRect()
.encode(
vl.x().fieldO("dayOfWeek").title("Day of Week").sort(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]),
vl.y().fieldO("hour").title("Hour of Day"),
vl.color().count().title("Observation Count")
)
.transform([
{ calculate: "hours(datum.timestamp)", as: "hour" }, // Extract hour
{ calculate: "timeFormat(datum.timestamp, '%A')", as: "dayOfWeek" } // Extract day name
])
.data(data)
.width(900)
.height(400)
.render()

Insert cell
Insert cell
vl.markRect()
.encode(
vl.x().fieldT("timestamp").timeUnit("yearmonthdate").title("Date"),
vl.y().fieldO("hour").title("Hour of Day"),
vl.color().count().title("Observation Count")
)
.transform([
{ calculate: "hours(datum.timestamp)", as: "hour" }
])
.data(data)
.width(1000)
.height(500)
.render()

Insert cell
Insert cell
viewof selectedQuarter = Inputs.select(
["2019-Q1", "2019-Q2", "2019-Q3", "2019-Q4",
"2020-Q1", "2020-Q2", "2020-Q3", "2020-Q4",
"2021-Q1", "2021-Q2", "2021-Q3", "2021-Q4",
"2022-Q1", "2022-Q2", "2022-Q3", "2022-Q4"],
{ label: "Select Quarter: ", value: "2020-Q2" }
)

Insert cell
viewof startHour = Inputs.range([0, 17], {
label: "Select Start Hour:",
value: 8, // Default: 8 AM
step: 1,
format: (d) => `${d}:00`
})

Insert cell
endHour = startHour + 24

Insert cell
viewof selectedDays = Inputs.checkbox(
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
{ label: "Select Days of the Week:", value: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] }
)

Insert cell
filteredData = data.filter(d => {
let [year, quarter] = selectedQuarter.split('-');
let qStartMonth = { "Q1": 0, "Q2": 3, "Q3": 6, "Q4": 9 }[quarter];
let qEndMonth = qStartMonth + 3;
let date = new Date(d.timestamp);
let hour = date.getHours();
let dayOfWeek = date.toLocaleString('en-US', { weekday: 'long' });

return (
date.getFullYear() == year &&
date.getMonth() >= qStartMonth && date.getMonth() < qEndMonth &&
hour >= startHour && hour < endHour &&
selectedDays.includes(dayOfWeek)
);
})

Insert cell
vl.markRect()
.encode(
vl.x().fieldT("timestamp").timeUnit("yearmonthdate").title("Date"),
vl.y().fieldO("hour").title("Hour of Day"),
vl.color().count().title("Observation Count")
)
.transform([{ calculate: "hours(datum.timestamp)", as: "hour" }])
.data(filteredData)
.width(900)
.height(500)
.render()

Insert cell
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