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>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<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>
|
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
svg {
|
svg {
|
||||||
@ -13,7 +13,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>Live Heatmap with Smooth Scrolling</h2>
|
<h2>Live Heatmap with Continuous Scrolling</h2>
|
||||||
<div id="chart"></div>
|
<div id="chart"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -46,7 +46,7 @@
|
|||||||
// Axis
|
// Axis
|
||||||
const yAxis = svg.append("g")
|
const yAxis = svg.append("g")
|
||||||
.attr("class", "y-axis")
|
.attr("class", "y-axis")
|
||||||
.call(d3.axisLeft(y).ticks(20));
|
.call(d3.axisLeft(y).ticks(6));
|
||||||
|
|
||||||
const grid = svg.append("g");
|
const grid = svg.append("g");
|
||||||
|
|
||||||
@ -63,29 +63,23 @@
|
|||||||
.attr("height", 5) // Fixed height for heatmap blocks
|
.attr("height", 5) // Fixed height for heatmap blocks
|
||||||
.attr("fill", d => colorScale(d.value))
|
.attr("fill", d => colorScale(d.value))
|
||||||
.merge(cells) // Merge updates
|
.merge(cells) // Merge updates
|
||||||
.transition()
|
|
||||||
.duration(500)
|
|
||||||
.attr("y", d => y(new Date(d.timestamp)))
|
.attr("y", d => y(new Date(d.timestamp)))
|
||||||
.attr("visibility", d =>
|
.attr("visibility", d =>
|
||||||
y(new Date(d.timestamp)) >= 0 && y(new Date(d.timestamp)) <= height
|
y(new Date(d.timestamp)) >= 0 && y(new Date(d.timestamp)) <= height
|
||||||
? "visible"
|
? "visible"
|
||||||
: "hidden"
|
: "hidden"
|
||||||
); // Hide items out of bounds
|
);
|
||||||
|
|
||||||
// Remove old data that moves off the screen
|
// Remove old data that moves off the screen
|
||||||
cells.exit().remove();
|
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 = [];
|
let allData = [];
|
||||||
setInterval(() => {
|
const scrollingSpeed = 10; // Pixels per second
|
||||||
// Generate random data
|
const pixelsPerMillisecond = scrollingSpeed / 1000;
|
||||||
|
|
||||||
|
function generateData() {
|
||||||
const newData = Array.from({ length: 10 }, (_, i) => ({
|
const newData = Array.from({ length: 10 }, (_, i) => ({
|
||||||
id: `${Date.now()}-${i}`,
|
id: `${Date.now()}-${i}`,
|
||||||
category: i,
|
category: i,
|
||||||
@ -93,18 +87,29 @@
|
|||||||
value: Math.random() * 100,
|
value: Math.random() * 100,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Add new data to the global array and keep only recent data
|
|
||||||
allData = [...allData, ...newData].filter(d =>
|
allData = [...allData, ...newData].filter(d =>
|
||||||
new Date(d.timestamp) >= new Date(Date.now() - 60000)
|
new Date(d.timestamp) >= new Date(Date.now() - 60000)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Update time scale domain
|
// Continuous scroll
|
||||||
y.domain([new Date(Date.now() - 60000), new Date()]);
|
d3.timer(elapsed => {
|
||||||
yAxis.transition().duration(500).call(d3.axisLeft(y).ticks(20));
|
// 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);
|
updateHeatmap(allData);
|
||||||
}, 1000);
|
|
||||||
|
// Smoothly shift axis
|
||||||
|
yAxis.call(d3.axisLeft(y).ticks(6));
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user