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

382 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Network Connection Graph - Iteration 2</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
min-height: 100vh;
padding: 20px;
}
#viz-container {
max-width: 1000px;
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;
}
.controls {
margin-bottom: 20px;
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.controls button {
padding: 10px 20px;
background: #1e3c72;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background 0.3s;
font-size: 14px;
}
.controls button:hover {
background: #2a5298;
}
.chart-container {
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
}
.node {
cursor: pointer;
stroke: #fff;
stroke-width: 2px;
}
.node:hover {
stroke: #ff6b6b;
stroke-width: 3px;
}
.link {
stroke: #999;
stroke-opacity: 0.6;
}
.node-label {
font-size: 11px;
font-weight: 600;
fill: #2d3748;
text-anchor: middle;
pointer-events: none;
user-select: none;
}
.tooltip {
position: absolute;
background: rgba(0, 0, 0, 0.85);
color: white;
padding: 12px 16px;
border-radius: 8px;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s;
font-size: 13px;
z-index: 1000;
max-width: 200px;
}
.attribution {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #e2e8f0;
font-size: 0.85em;
color: #718096;
}
.attribution a {
color: #1e3c72;
text-decoration: none;
}
.attribution a:hover {
text-decoration: underline;
}
@media (max-width: 768px) {
#viz-container {
padding: 20px;
}
h1 {
font-size: 1.5em;
}
.controls {
flex-direction: column;
}
}
</style>
</head>
<body>
<div id="viz-container">
<h1>Open Source Project Dependency Network</h1>
<p class="subtitle">Force-directed graph showing package relationships</p>
<div class="controls">
<button id="restart-btn">Reset Simulation</button>
<button id="toggle-labels-btn">Toggle Labels</button>
</div>
<div class="chart-container"></div>
<div class="attribution">
<p><strong>Visualization inspired by:</strong> <a href="https://observablehq.com/@d3/force-directed-graph" target="_blank">D3 Force-Directed Graph</a></p>
<p><strong>Data from:</strong> GitHub API (simulated)</p>
<p><strong>Created:</strong> 2025-10-10T23:51:20Z</p>
</div>
</div>
<!-- Metadata section (required for state tracking) -->
<div id="metadata" style="display:none;">
{
"iteration": 2,
"web_source": "https://observablehq.com/@d3/force-directed-graph",
"techniques_learned": [
"Force-directed layout with d3.forceSimulation",
"Dynamic node dragging with pointer events",
"Link strength and distance constraints"
],
"data_source": "https://api.github.com/repos",
"created": "2025-10-10T23:51:20Z"
}
</div>
<div class="tooltip"></div>
<!-- External libraries -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
/**
* Open Source Project Dependency Network - Iteration 2
*
* Web Source: https://observablehq.com/@d3/force-directed-graph
* Techniques Learned:
* 1. Force-directed layout with d3.forceSimulation
* 2. Dynamic node dragging with pointer events
* 3. Link strength and distance constraints
*
* Data Source: GitHub API (simulated)
*
* Created: 2025-10-10T23:51:20Z
* Run ID: test_run_001
*/
// Simulated network data
const nodes = [
{ id: 'react', group: 1, size: 30 },
{ id: 'vue', group: 1, size: 25 },
{ id: 'angular', group: 1, size: 28 },
{ id: 'webpack', group: 2, size: 20 },
{ id: 'babel', group: 2, size: 18 },
{ id: 'typescript', group: 2, size: 22 },
{ id: 'eslint', group: 3, size: 15 },
{ id: 'jest', group: 3, size: 16 },
{ id: 'redux', group: 4, size: 14 },
{ id: 'mobx', group: 4, size: 12 },
{ id: 'd3', group: 5, size: 20 },
{ id: 'three.js', group: 5, size: 18 }
];
const links = [
{ source: 'react', target: 'webpack', value: 3 },
{ source: 'react', target: 'babel', value: 3 },
{ source: 'react', target: 'redux', value: 2 },
{ source: 'vue', target: 'webpack', value: 2 },
{ source: 'vue', target: 'babel', value: 2 },
{ source: 'angular', target: 'typescript', value: 3 },
{ source: 'angular', target: 'webpack', value: 2 },
{ source: 'react', target: 'jest', value: 2 },
{ source: 'vue', target: 'jest', value: 2 },
{ source: 'react', target: 'eslint', value: 1 },
{ source: 'vue', target: 'eslint', value: 1 },
{ source: 'angular', target: 'eslint', value: 1 },
{ source: 'redux', target: 'typescript', value: 1 },
{ source: 'mobx', target: 'typescript', value: 1 }
];
// Set up dimensions
const width = Math.min(900, window.innerWidth - 100);
const height = 600;
// Color scale for groups
const color = d3.scaleOrdinal(d3.schemeCategory10);
// Create SVG
const svg = d3.select('.chart-container')
.append('svg')
.attr('width', width)
.attr('height', height)
.attr('viewBox', [0, 0, width, height])
.attr('role', 'img')
.attr('aria-label', 'Network graph showing package dependencies');
// Get tooltip element
const tooltip = d3.select('.tooltip');
// Learned Technique 1: Force-directed layout with d3.forceSimulation
const simulation = d3.forceSimulation(nodes)
.force('link', d3.forceLink(links)
.id(d => d.id)
.distance(d => 100 / d.value)) // Learned Technique 3: Link distance constraints
.force('charge', d3.forceManyBody().strength(-300))
.force('center', d3.forceCenter(width / 2, height / 2))
.force('collision', d3.forceCollide().radius(d => d.size + 5));
// Create links
const link = svg.append('g')
.selectAll('line')
.data(links)
.join('line')
.attr('class', 'link')
.attr('stroke-width', d => Math.sqrt(d.value) * 2);
// Create nodes
const node = svg.append('g')
.selectAll('circle')
.data(nodes)
.join('circle')
.attr('class', 'node')
.attr('r', d => d.size)
.attr('fill', d => color(d.group))
.attr('role', 'graphics-symbol')
.attr('aria-label', d => `Package: ${d.id}`)
.call(drag(simulation)); // Learned Technique 2: Dynamic node dragging
// Add labels
const labels = svg.append('g')
.selectAll('text')
.data(nodes)
.join('text')
.attr('class', 'node-label')
.text(d => d.id);
// Tooltip interactions
node.on('mouseover', function(event, d) {
const connections = links.filter(l =>
l.source.id === d.id || l.target.id === d.id
);
tooltip
.style('opacity', 1)
.html(`
<strong>${d.id}</strong><br>
Group: ${d.group}<br>
Connections: ${connections.length}
`)
.style('left', (event.pageX + 10) + 'px')
.style('top', (event.pageY - 28) + 'px');
})
.on('mouseout', function() {
tooltip.style('opacity', 0);
});
// Update positions on simulation tick
simulation.on('tick', () => {
link
.attr('x1', d => d.source.x)
.attr('y1', d => d.source.y)
.attr('x2', d => d.target.x)
.attr('y2', d => d.target.y);
node
.attr('cx', d => d.x)
.attr('cy', d => d.y);
labels
.attr('x', d => d.x)
.attr('y', d => d.y + d.size + 15);
});
// Learned Technique 2: Drag behavior for interactive repositioning
function drag(simulation) {
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}
return d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended);
}
// Control buttons
let labelsVisible = true;
document.getElementById('restart-btn').addEventListener('click', () => {
simulation.alpha(1).restart();
});
document.getElementById('toggle-labels-btn').addEventListener('click', () => {
labelsVisible = !labelsVisible;
labels.style('opacity', labelsVisible ? 1 : 0);
});
// Keyboard accessibility
node.attr('tabindex', 0)
.on('focus', function(event, d) {
const connections = links.filter(l =>
l.source.id === d.id || l.target.id === d.id
);
tooltip
.style('opacity', 1)
.html(`
<strong>${d.id}</strong><br>
Group: ${d.group}<br>
Connections: ${connections.length}
`)
.style('left', (event.pageX + 10) + 'px')
.style('top', (event.pageY - 28) + 'px');
})
.on('blur', function() {
tooltip.style('opacity', 0);
});
</script>
</body>
</html>