254 lines
8.2 KiB
HTML
254 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Test Members View</title>
|
|
<script src="https://d3js.org/d3.v7.min.js"></script>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 20px;
|
|
background: #f5f5f5;
|
|
}
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
.test-section {
|
|
margin-bottom: 30px;
|
|
padding: 20px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
}
|
|
.test-section h3 {
|
|
margin-top: 0;
|
|
color: #333;
|
|
}
|
|
button {
|
|
background: #2196F3;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
margin: 5px;
|
|
}
|
|
button:hover {
|
|
background: #1976D2;
|
|
}
|
|
#graph-container {
|
|
width: 800px;
|
|
height: 600px;
|
|
border: 1px solid #ddd;
|
|
background: #f9f9f9;
|
|
margin: 20px 0;
|
|
}
|
|
.status {
|
|
padding: 10px;
|
|
margin: 10px 0;
|
|
border-radius: 4px;
|
|
}
|
|
.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
|
|
.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
|
|
.info { background: #d1ecf1; color: #0c5460; border: 1px solid #bee5eb; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>🧪 Test Members View</h1>
|
|
|
|
<div class="test-section">
|
|
<h3>D3.js Integration Test</h3>
|
|
<p>Testing D3.js library integration and basic force-directed graph functionality.</p>
|
|
<button onclick="testD3Integration()">Test D3.js Integration</button>
|
|
<button onclick="testForceGraph()">Test Force Graph</button>
|
|
<button onclick="clearGraph()">Clear Graph</button>
|
|
<div id="status"></div>
|
|
</div>
|
|
|
|
<div class="test-section">
|
|
<h3>Graph Visualization</h3>
|
|
<div id="graph-container"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let svg = null;
|
|
let simulation = null;
|
|
|
|
function showStatus(message, type = 'info') {
|
|
const statusDiv = document.getElementById('status');
|
|
statusDiv.innerHTML = `<div class="status ${type}">${message}</div>`;
|
|
}
|
|
|
|
function testD3Integration() {
|
|
try {
|
|
if (typeof d3 === 'undefined') {
|
|
throw new Error('D3.js is not loaded');
|
|
}
|
|
|
|
const version = d3.version;
|
|
showStatus(`✅ D3.js v${version} loaded successfully!`, 'success');
|
|
|
|
// Test basic D3 functionality
|
|
const testData = [1, 2, 3, 4, 5];
|
|
const testSelection = d3.select('#graph-container');
|
|
testSelection.append('div')
|
|
.attr('class', 'test-div')
|
|
.text('D3 selection test');
|
|
|
|
showStatus('✅ D3.js basic functionality working!', 'success');
|
|
|
|
} catch (error) {
|
|
showStatus(`❌ D3.js test failed: ${error.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
function testForceGraph() {
|
|
try {
|
|
if (!svg) {
|
|
setupSVG();
|
|
}
|
|
|
|
// Create sample data
|
|
const nodes = [
|
|
{ id: 'node1', name: 'Node 1', status: 'ACTIVE' },
|
|
{ id: 'node2', name: 'Node 2', status: 'ACTIVE' },
|
|
{ id: 'node3', name: 'Node 3', status: 'INACTIVE' },
|
|
{ id: 'node4', name: 'Node 4', status: 'ACTIVE' }
|
|
];
|
|
|
|
const links = [
|
|
{ source: 'node1', target: 'node2', latency: 5 },
|
|
{ source: 'node1', target: 'node3', latency: 15 },
|
|
{ source: 'node2', target: 'node4', latency: 8 },
|
|
{ source: 'node3', target: 'node4', latency: 25 }
|
|
];
|
|
|
|
renderGraph(nodes, links);
|
|
showStatus('✅ Force-directed graph created successfully!', 'success');
|
|
|
|
} catch (error) {
|
|
showStatus(`❌ Force graph test failed: ${error.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
function setupSVG() {
|
|
const container = document.getElementById('graph-container');
|
|
container.innerHTML = '';
|
|
|
|
svg = d3.select(container)
|
|
.append('svg')
|
|
.attr('width', 800)
|
|
.attr('height', 600)
|
|
.style('border', '1px solid #ddd')
|
|
.style('background', '#f9f9f9');
|
|
}
|
|
|
|
function renderGraph(nodes, links) {
|
|
if (!svg) return;
|
|
|
|
const svgGroup = svg.append('g');
|
|
|
|
// Create links
|
|
const link = svgGroup.append('g')
|
|
.selectAll('line')
|
|
.data(links)
|
|
.enter().append('line')
|
|
.attr('stroke', '#999')
|
|
.attr('stroke-opacity', 0.6)
|
|
.attr('stroke-width', 2);
|
|
|
|
// Create nodes
|
|
const node = svgGroup.append('g')
|
|
.selectAll('g')
|
|
.data(nodes)
|
|
.enter().append('g')
|
|
.attr('class', 'node')
|
|
.call(d3.drag()
|
|
.on('start', dragstarted)
|
|
.on('drag', dragged)
|
|
.on('end', dragended));
|
|
|
|
// Add circles to nodes
|
|
node.append('circle')
|
|
.attr('r', 8)
|
|
.attr('fill', d => getNodeColor(d.status));
|
|
|
|
// Add labels
|
|
node.append('text')
|
|
.text(d => d.name)
|
|
.attr('x', 12)
|
|
.attr('y', 4)
|
|
.attr('font-size', '12px');
|
|
|
|
// Set up force simulation
|
|
simulation = d3.forceSimulation(nodes)
|
|
.force('link', d3.forceLink(links).id(d => d.id).distance(100))
|
|
.force('charge', d3.forceManyBody().strength(-300))
|
|
.force('center', d3.forceCenter(400, 300));
|
|
|
|
// 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('transform', d => `translate(${d.x},${d.y})`);
|
|
});
|
|
}
|
|
|
|
function getNodeColor(status) {
|
|
switch (status) {
|
|
case 'ACTIVE': return '#4CAF50';
|
|
case 'INACTIVE': return '#FF9800';
|
|
default: return '#9E9E9E';
|
|
}
|
|
}
|
|
|
|
function dragstarted(event, d) {
|
|
if (!event.active) simulation.alphaTarget(0.3).restart();
|
|
d.fx = d.x;
|
|
d.fy = d.y;
|
|
}
|
|
|
|
function dragged(event, d) {
|
|
d.fx = event.x;
|
|
d.fy = event.y;
|
|
}
|
|
|
|
function dragended(event, d) {
|
|
if (!event.active) simulation.alphaTarget(0);
|
|
d.fx = null;
|
|
d.fy = null;
|
|
}
|
|
|
|
function clearGraph() {
|
|
if (svg) {
|
|
svg.selectAll('*').remove();
|
|
svg = null;
|
|
}
|
|
if (simulation) {
|
|
simulation.stop();
|
|
simulation = null;
|
|
}
|
|
showStatus('Graph cleared', 'info');
|
|
}
|
|
|
|
// Auto-test on load
|
|
window.addEventListener('load', () => {
|
|
setTimeout(() => {
|
|
testD3Integration();
|
|
}, 500);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |