<!-- templates/render_member.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Member Network</title> <script src="https://d3js.org/d3.v7.min.js"></script> <style> .node { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: 0.6; } </style> </head> <body> <h1>Member Network</h1> <select id="memberSelect"> <!-- Options will be populated dynamically --> </select> <div id="graph"></div> <script> // Fetch member names from Neo4j fetch('/list_members/get_member_names') .then(response => response.json()) .then(members => { const select = document.getElementById('memberSelect'); members.forEach(member => { const option = document.createElement('option'); option.value = member; option.text = member; select.appendChild(option); }); }); // Handle member selection document.getElementById('memberSelect').addEventListener('change', function() { console.log("Member selected:", this.value); // Log the selected member name const selectedMember = this.value; fetch(`/list_members/render_member?member_name=${encodeURIComponent(selectedMember)}`, { method: 'GET', }) .then(response => response.json()) .then(data => { console.log("Graph data received:", data); // Log the graph data renderGraph(data); }) .catch(error => { console.error("Error fetching graph data:", error); // Log any errors }); }); // Render D3 network graph function renderGraph(data) { const width = 800; const height = 600; const svg = d3.select("#graph") .selectAll("svg") // Remove existing SVG elements first .remove() .append("svg") .attr("width", width) .attr("height", height); const simulation = d3.forceSimulation(data.nodes) .force("link", d3.forceLink(data.links).id(d => d.id)) .force("charge", d3.forceManyBody().strength(-500)) .force("center", d3.forceCenter(width / 2, height / 2)); const link = svg.append("g") .attr("class", "links") .selectAll("line") .data(data.links) .enter().append("line") .attr("stroke-width", 2); const node = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(data.nodes) .enter().append("circle") .attr("r", 5) .attr("fill", d => d.label === 'Person' ? 'steelblue' : 'orange') .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); node.append("title") .text(d => `${d.name} (${d.label})`); 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); }); 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; } } </script> </body> </html>