feat: fully continuous scroll
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
23885cd9e4
commit
f31c9a7022
47
index.html
47
index.html
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Live Heatmap with Smooth Scrolling</title>
|
||||
<title>Live Heatmap with Continuous Scrolling</title>
|
||||
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||
<style>
|
||||
svg {
|
||||
@ -13,7 +13,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Live Heatmap with Smooth Scrolling</h2>
|
||||
<h2>Live Heatmap with Continuous Scrolling</h2>
|
||||
<div id="chart"></div>
|
||||
|
||||
<script>
|
||||
@ -46,7 +46,7 @@
|
||||
// Axis
|
||||
const yAxis = svg.append("g")
|
||||
.attr("class", "y-axis")
|
||||
.call(d3.axisLeft(y).ticks(20));
|
||||
.call(d3.axisLeft(y).ticks(6));
|
||||
|
||||
const grid = svg.append("g");
|
||||
|
||||
@ -63,29 +63,23 @@
|
||||
.attr("height", 5) // Fixed height for heatmap blocks
|
||||
.attr("fill", d => colorScale(d.value))
|
||||
.merge(cells) // Merge updates
|
||||
.transition()
|
||||
.duration(500)
|
||||
.attr("y", d => y(new Date(d.timestamp)))
|
||||
.attr("visibility", d =>
|
||||
y(new Date(d.timestamp)) >= 0 && y(new Date(d.timestamp)) <= height
|
||||
? "visible"
|
||||
: "hidden"
|
||||
); // Hide items out of bounds
|
||||
);
|
||||
|
||||
// Remove old data that moves off the screen
|
||||
cells.exit().remove();
|
||||
|
||||
// Shift all cells upward to simulate scrolling
|
||||
grid.selectAll("rect")
|
||||
.transition()
|
||||
.duration(500)
|
||||
.attr("y", d => y(new Date(d.timestamp)));
|
||||
}
|
||||
|
||||
// Simulate real-time updates
|
||||
// Real-time simulation
|
||||
let allData = [];
|
||||
setInterval(() => {
|
||||
// Generate random data
|
||||
const scrollingSpeed = 10; // Pixels per second
|
||||
const pixelsPerMillisecond = scrollingSpeed / 1000;
|
||||
|
||||
function generateData() {
|
||||
const newData = Array.from({ length: 10 }, (_, i) => ({
|
||||
id: `${Date.now()}-${i}`,
|
||||
category: i,
|
||||
@ -93,18 +87,29 @@
|
||||
value: Math.random() * 100,
|
||||
}));
|
||||
|
||||
// Add new data to the global array and keep only recent data
|
||||
allData = [...allData, ...newData].filter(d =>
|
||||
new Date(d.timestamp) >= new Date(Date.now() - 60000)
|
||||
);
|
||||
}
|
||||
|
||||
// Update time scale domain
|
||||
y.domain([new Date(Date.now() - 60000), new Date()]);
|
||||
yAxis.transition().duration(500).call(d3.axisLeft(y).ticks(20));
|
||||
// Continuous scroll
|
||||
d3.timer(elapsed => {
|
||||
// Generate data periodically (every 1 second)
|
||||
if (Math.floor(elapsed) % 1000 === 0) {
|
||||
generateData();
|
||||
}
|
||||
|
||||
// Update heatmap with filtered data
|
||||
// Update the domain of the y-axis
|
||||
const now = new Date();
|
||||
const past = new Date(now.getTime() - 60000);
|
||||
y.domain([past, now]);
|
||||
|
||||
// Update positions of all heatmap cells
|
||||
updateHeatmap(allData);
|
||||
}, 1000);
|
||||
|
||||
// Smoothly shift axis
|
||||
yAxis.call(d3.axisLeft(y).ticks(6));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user