feat: pretty close

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2024-11-21 21:31:01 +01:00
parent e424fa2d03
commit 97c0adaa3b
Signed by: kjuulh
GPG Key ID: D85D7535F18F35FA

View File

@ -3,9 +3,15 @@
<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 Intensity</title> <title>Space-Themed Heatmap</title>
<script src="https://d3js.org/d3.v7.min.js"></script> <script src="https://d3js.org/d3.v7.min.js"></script>
<style> <style>
body {
background-color: black;
color: white;
font-family: Arial, sans-serif;
}
svg { svg {
display: block; display: block;
margin: auto; margin: auto;
@ -13,12 +19,15 @@
.legend { .legend {
font-size: 12px; font-size: 12px;
display: flex;
justify-content: center;
flex-wrap: wrap;
} }
.legend-item { .legend-item {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 5px; margin: 5px;
} }
.legend-color { .legend-color {
@ -29,7 +38,7 @@
</style> </style>
</head> </head>
<body> <body>
<h2>Live Heatmap with Intensity</h2> <h2>Space-Themed Continuous Heatmap</h2>
<div id="chart"></div> <div id="chart"></div>
<div id="legend" class="legend"></div> <div id="legend" class="legend"></div>
@ -41,16 +50,16 @@
// Categories with labels // Categories with labels
const categories = [ const categories = [
{ id: 0, label: "User Onboarded", color: "#1f77b4" }, { id: 0, label: "User Onboarded", color: "#FFD700" },
{ id: 1, label: "Payment Accepted", color: "#ff7f0e" }, { id: 1, label: "Payment Accepted", color: "#00BFFF" },
{ id: 2, label: "Payment Failed", color: "#d62728" }, { id: 2, label: "Payment Failed", color: "#FF4500" },
{ id: 3, label: "Product Added to Cart", color: "#9467bd" }, { id: 3, label: "Product Added to Cart", color: "#9400D3" },
{ id: 4, label: "Checkout Started", color: "#2ca02c" }, { id: 4, label: "Checkout Started", color: "#32CD32" },
{ id: 5, label: "Order Placed", color: "#8c564b" }, { id: 5, label: "Order Placed", color: "#8B4513" },
{ id: 6, label: "Order Cancelled", color: "#e377c2" }, { id: 6, label: "Order Cancelled", color: "#FF69B4" },
{ id: 7, label: "Refund Processed", color: "#7f7f7f" }, { id: 7, label: "Refund Processed", color: "#A9A9A9" },
{ id: 8, label: "Subscription Renewed", color: "#bcbd22" }, { id: 8, label: "Subscription Renewed", color: "#BDB76B" },
{ id: 9, label: "Feedback Submitted", color: "#17becf" }, { id: 9, label: "Feedback Submitted", color: "#00FFFF" },
]; ];
// Store last intensity for each category // Store last intensity for each category
@ -96,7 +105,7 @@
.attr("x", d => x(d.category)) .attr("x", d => x(d.category))
.attr("width", x.bandwidth()) .attr("width", x.bandwidth())
.attr("y", d => y(new Date(d.timestamp))) .attr("y", d => y(new Date(d.timestamp)))
.attr("height", 5) // Fixed height for heatmap blocks .attr("height", 4) // Minimized spacing between blocks
.attr("fill", d => categories[d.category].color) .attr("fill", d => categories[d.category].color)
.attr("opacity", d => d.intensity) .attr("opacity", d => d.intensity)
.merge(cells) // Merge updates .merge(cells) // Merge updates
@ -114,12 +123,12 @@
// Real-time simulation // Real-time simulation
let allData = []; let allData = [];
const scrollingSpeed = 10; // Pixels per second const scrollingSpeed = 20; // Pixels per second
function generateData() { function generateData() {
// Simulate sporadic events with intensity // Simulate sporadic events with intensity
const newData = categories.map(c => { const newData = categories.map(c => {
if (Math.random() < 0.5) return null; // 50% chance no data for this category if (Math.random() < 0.7) return null; // 70% chance no data for this category
const newIntensity = Math.random(); // Random intensity const newIntensity = Math.random(); // Random intensity
const smoothIntensity = d3.interpolate(lastIntensity.get(c.id), newIntensity)(0.5); // Smooth transition const smoothIntensity = d3.interpolate(lastIntensity.get(c.id), newIntensity)(0.5); // Smooth transition
lastIntensity.set(c.id, smoothIntensity); // Update last intensity lastIntensity.set(c.id, smoothIntensity); // Update last intensity
@ -144,8 +153,8 @@
const now = Date.now(); const now = Date.now();
const delta = now - lastTimestamp; const delta = now - lastTimestamp;
// Generate data periodically (every 1 second) // Generate data periodically (every 500ms for more activity)
if (delta >= 1000) { if (delta >= 500) {
generateData(); generateData();
lastTimestamp = now; lastTimestamp = now;
} }
@ -161,4 +170,3 @@
</script> </script>
</body> </body>
</html> </html>