infinite-agents-public/infinite_variants/infinite_variant_6/test_output/visualization_1.html

300 lines
9.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Real-Time Weather Dashboard - Iteration 1</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
#viz-container {
max-width: 900px;
margin: 0 auto;
background: white;
border-radius: 15px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 30px;
}
h1 {
color: #2d3748;
margin-bottom: 10px;
font-size: 2em;
}
.subtitle {
color: #718096;
margin-bottom: 30px;
font-size: 0.9em;
}
.chart-container {
margin-top: 30px;
}
.bar {
fill: #667eea;
transition: fill 0.3s ease;
cursor: pointer;
}
.bar:hover {
fill: #764ba2;
}
.axis text {
font-size: 12px;
fill: #4a5568;
}
.axis path,
.axis line {
stroke: #cbd5e0;
}
.tooltip {
position: absolute;
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 15px;
border-radius: 8px;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s;
font-size: 14px;
z-index: 1000;
}
.loading {
text-align: center;
padding: 50px;
color: #718096;
}
.attribution {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #e2e8f0;
font-size: 0.85em;
color: #718096;
}
.attribution a {
color: #667eea;
text-decoration: none;
}
.attribution a:hover {
text-decoration: underline;
}
@media (max-width: 768px) {
#viz-container {
padding: 20px;
}
h1 {
font-size: 1.5em;
}
}
</style>
</head>
<body>
<div id="viz-container">
<h1>Global Temperature Anomalies</h1>
<p class="subtitle">Monthly temperature deviations from baseline (1951-1980)</p>
<div class="loading">Loading climate data...</div>
<div class="chart-container"></div>
<div class="attribution">
<p><strong>Visualization inspired by:</strong> <a href="https://observablehq.com/@d3/bar-chart" target="_blank">D3 Bar Chart Gallery</a></p>
<p><strong>Data from:</strong> NASA GISS Surface Temperature Analysis (simulated)</p>
<p><strong>Created:</strong> 2025-10-10T23:50:15Z</p>
</div>
</div>
<!-- Metadata section (required for state tracking) -->
<div id="metadata" style="display:none;">
{
"iteration": 1,
"web_source": "https://observablehq.com/@d3/bar-chart",
"techniques_learned": [
"Basic D3 bar chart with scales",
"SVG axis generation",
"Interactive tooltips with transitions"
],
"data_source": "https://data.giss.nasa.gov/gistemp/",
"created": "2025-10-10T23:50:15Z"
}
</div>
<div class="tooltip"></div>
<!-- External libraries -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
/**
* Global Temperature Anomalies Bar Chart - Iteration 1
*
* Web Source: https://observablehq.com/@d3/bar-chart
* Techniques Learned:
* 1. Basic D3 bar chart with linear scales
* 2. SVG axis generation with d3.axisBottom/Left
* 3. Interactive tooltips with smooth transitions
*
* Data Source: NASA GISS Surface Temperature Analysis (simulated)
*
* Created: 2025-10-10T23:50:15Z
* Run ID: test_run_001
*/
// Simulated climate data (normally would fetch from API)
const data = [
{ month: 'Jan', anomaly: 0.89 },
{ month: 'Feb', anomaly: 0.95 },
{ month: 'Mar', anomaly: 1.08 },
{ month: 'Apr', anomaly: 1.12 },
{ month: 'May', anomaly: 0.87 },
{ month: 'Jun', anomaly: 0.92 },
{ month: 'Jul', anomaly: 1.01 },
{ month: 'Aug', anomaly: 0.99 },
{ month: 'Sep', anomaly: 0.91 },
{ month: 'Oct', anomaly: 1.05 },
{ month: 'Nov', anomaly: 0.97 },
{ month: 'Dec', anomaly: 0.84 }
];
// Set up dimensions
const margin = { top: 20, right: 30, bottom: 40, left: 50 };
const width = Math.min(800, window.innerWidth - 100) - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
// Remove loading message
document.querySelector('.loading').style.display = 'none';
// Create SVG
const svg = d3.select('.chart-container')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.attr('role', 'img')
.attr('aria-label', 'Bar chart showing monthly temperature anomalies')
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Learned Technique 1: Using D3 scales for data-to-pixel mapping
const x = d3.scaleBand()
.domain(data.map(d => d.month))
.range([0, width])
.padding(0.2);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.anomaly) * 1.1])
.range([height, 0]);
// Learned Technique 2: Creating axes with D3
const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y)
.ticks(5)
.tickFormat(d => d + '°C');
svg.append('g')
.attr('class', 'axis')
.attr('transform', `translate(0,${height})`)
.call(xAxis);
svg.append('g')
.attr('class', 'axis')
.call(yAxis);
// Add Y axis label
svg.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 0 - margin.left)
.attr('x', 0 - (height / 2))
.attr('dy', '1em')
.style('text-anchor', 'middle')
.style('fill', '#4a5568')
.text('Temperature Anomaly (°C)');
// Get tooltip element
const tooltip = d3.select('.tooltip');
// Learned Technique 3: Interactive tooltips with transitions
const bars = svg.selectAll('.bar')
.data(data)
.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', d => x(d.month))
.attr('width', x.bandwidth())
.attr('y', height)
.attr('height', 0)
.attr('role', 'graphics-symbol')
.attr('aria-label', d => `${d.month}: ${d.anomaly} degrees Celsius`)
.on('mouseover', function(event, d) {
tooltip
.style('opacity', 1)
.html(`<strong>${d.month}</strong><br>Anomaly: ${d.anomaly}°C`)
.style('left', (event.pageX + 10) + 'px')
.style('top', (event.pageY - 28) + 'px');
})
.on('mouseout', function() {
tooltip.style('opacity', 0);
});
// Animate bars on load
bars.transition()
.duration(800)
.delay((d, i) => i * 50)
.attr('y', d => y(d.anomaly))
.attr('height', d => height - y(d.anomaly));
// Keyboard navigation support
bars.on('focus', function(event, d) {
tooltip
.style('opacity', 1)
.html(`<strong>${d.month}</strong><br>Anomaly: ${d.anomaly}°C`)
.style('left', (event.pageX + 10) + 'px')
.style('top', (event.pageY - 28) + 'px');
})
.on('blur', function() {
tooltip.style('opacity', 0);
});
// Make bars keyboard accessible
bars.attr('tabindex', 0);
// Responsive resize
window.addEventListener('resize', function() {
const newWidth = Math.min(800, window.innerWidth - 100) - margin.left - margin.right;
svg.attr('width', newWidth + margin.left + margin.right);
x.range([0, newWidth]);
svg.select('.axis')
.attr('transform', `translate(0,${height})`)
.call(xAxis);
bars
.attr('x', d => x(d.month))
.attr('width', x.bandwidth());
});
</script>
</body>
</html>