Public
Edited
Jul 22, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
group = bins
.map((d) => {
return [d.x0, d3.sum(d, (d) => d.difference)];
})
.filter((d) => d[1])
Insert cell
dailyGroup = dailyBins
.map((d) => {
return [d.x0, d3.sum(d, (d) => d.difference)];
})
.filter((d) => d[1])
Insert cell
bins = d3
.bin()
.value((d) => d.timestamp)
.thresholds(
thresholdTime(
timeFrame === "Weekly" ? d3.timeWeek.every(1) : d3.timeDay.every(1)
)
)(orderedData)
.filter((d) => d[1])
Insert cell
dailyBins = d3
.bin()
.value((d) => d.timestamp)
.thresholds(thresholdTime(d3.timeDay.every(1)))(orderedData)
.filter((d) => d[1])
Insert cell
hourlyGroup = hourlyBins
.map((d) => [d.x0, d3.sum(d, (d) => d.difference)])
.slice(-24)
.map(([hour, amount]) => {
return {
hour,
amount
};
})
Insert cell
hourlyBins = d3
.bin()
.value((d) => d.timestamp)
.thresholds(thresholdTime(d3.timeHour.every(1)))(orderedData)
Insert cell
orderedData = data.slice().reverse()
Insert cell
data = {
const input = await d3.csv(url, ({ amount, timestamp }) => {
return {
amount: Number.parseInt(amount, 10),
timestamp: new Date(timestamp * 1000)
};
});

const data = input.map(({ amount, timestamp }, idx, arr) => {
let difference = null;

// this looks weird, but it's because they come in reverse-chron
if (idx + 1 !== arr.length) {
const prev = arr[idx + 1].amount;
difference = amount - prev;
}

return { difference, timestamp };
});

return data;
}
Insert cell
last24HoursData = {
// Get the current date and time
const now = new Date();

// Round down to the nearest hour
const roundedNow = new Date(now);
roundedNow.setMinutes(0, 0, 0);

// Calculate the threshold for the last 24 hours from the rounded time
const threshold = new Date(roundedNow.getTime() - 24 * 60 * 60 * 1000);

// Filter the array to include only dates within the last 24 hours
const filteredData = data
.filter(({ timestamp }) => timestamp >= threshold)
.map((d) => {
d.timestamp = dateFns.toZonedTime(d.timestamp, "America/New_York");

return d;
});

return filteredData;
}
Insert cell
Insert cell
height = width < 576 ? 300 : 500
Insert cell
function thresholdTime(n) {
return (data, min, max) => {
return d3
.scaleTime()
.domain([min, max])
.ticks(n);
};
}
Insert cell
hourFormat = d3.timeFormat("%-I %p")
Insert cell
dayFormat = d3.timeFormat("%b %-d")
Insert cell
url = 'https://raw.githubusercontent.com/rdmurphy/actblue-ticker-tracker/main/amounts.csv'
Insert cell
journalize = require("journalize@2")
Insert cell
dateFns = import("https://esm.sh/date-fns-tz@3.1.3")
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