feat: add basic grid updates
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
commit
fa3cc87b9b
111
index.html
Normal file
111
index.html
Normal file
@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Live Timeline Heatmap</title>
|
||||
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||
<style>
|
||||
.heatmap rect {
|
||||
//stroke: #aaa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Live Timeline Heatmap</h2>
|
||||
<div id="chart"></div>
|
||||
|
||||
<script>
|
||||
// Configuration
|
||||
const width = 500;
|
||||
const height = 500;
|
||||
const numCols = 10; // Number of columns
|
||||
const numRows = 20; // Number of rows
|
||||
const cellWidth = width / numCols; // Cell width
|
||||
const cellHeight = height / numRows; // Cell height
|
||||
const fadeOutRate = 0.8; // Intensity decay
|
||||
const maxIntensity = 10; // Maximum intensity value
|
||||
|
||||
// Create SVG
|
||||
const svg = d3.select("#chart")
|
||||
.append("svg")
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.append("g")
|
||||
.attr("class", "heatmap");
|
||||
|
||||
// Initialize grid
|
||||
let grid = Array.from({ length: numRows }, () =>
|
||||
Array.from({ length: numCols }, () => 0)
|
||||
);
|
||||
|
||||
// Color scale
|
||||
const colorScale = d3.scaleSequential(d3.interpolateTurbo).domain([0, maxIntensity]);
|
||||
|
||||
// Create grid rectangles
|
||||
svg.selectAll("rect")
|
||||
.data(grid.flat())
|
||||
.enter()
|
||||
.append("rect")
|
||||
.attr("x", (_, i) => (i % numCols) * cellWidth)
|
||||
.attr("y", (_, i) => Math.floor(i / numCols) * cellHeight)
|
||||
.attr("width", cellWidth)
|
||||
.attr("height", cellHeight)
|
||||
.attr("fill", colorScale(0));
|
||||
|
||||
// Function to update the heatmap
|
||||
function updateHeatmap() {
|
||||
// Decay old values
|
||||
for (let row of grid) {
|
||||
for (let col = 0; col < row.length; col++) {
|
||||
row[col] *= fadeOutRate;
|
||||
}
|
||||
}
|
||||
|
||||
// Update heatmap colors
|
||||
svg.selectAll("rect")
|
||||
.data(grid.flat())
|
||||
.transition()
|
||||
.duration(200)
|
||||
.attr("fill", d => colorScale(d));
|
||||
}
|
||||
|
||||
// Scroll rows upward and add a new empty row at the bottom
|
||||
function scrollHeatmap() {
|
||||
grid.shift(); // Remove the top row
|
||||
grid.push(Array.from({ length: numCols }, () => 0)); // Add an empty row at the bottom
|
||||
|
||||
// Update grid positions
|
||||
svg.selectAll("rect")
|
||||
.data(grid.flat())
|
||||
.transition()
|
||||
.duration(200)
|
||||
.attr("y", (_, i) => Math.floor(i / numCols) * cellHeight);
|
||||
}
|
||||
|
||||
// Function to add events to the bottom row
|
||||
function addEvent(col, intensity) {
|
||||
if (col >= 0 && col < numCols) {
|
||||
grid[grid.length - 1][col] = Math.min(
|
||||
grid[grid.length - 1][col] + intensity,
|
||||
maxIntensity
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Simulate incoming events
|
||||
setInterval(() => {
|
||||
const randomCol = Math.floor(Math.random() * numCols);
|
||||
const randomIntensity = Math.random() * 8 + 2; // Random intensity (2-10)
|
||||
addEvent(randomCol, randomIntensity);
|
||||
}, 300); // Events every 300ms
|
||||
|
||||
// Animation loop
|
||||
d3.interval(() => {
|
||||
scrollHeatmap();
|
||||
updateHeatmap();
|
||||
}, 500); // Updates every 500ms
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user