MCPcopy Create free account
hub / github.com/Alfredredbird/CyberKelp / renderGraph

Function renderGraph

script.js:509–678  ·  view source on GitHub ↗
({ nodes, links, connCount })

Source from the content-addressed store, hash-verified

507}
508
509function renderGraph({ nodes, links, connCount }) {
510 const svgEl = document.getElementById("graph-svg");
511 const tooltip = document.getElementById("graph-tooltip");
512 const svg = d3.select(svgEl);
513 svg.selectAll("*").remove();
514
515 const W = svgEl.clientWidth || 800;
516 const H = svgEl.clientHeight || 600;
517
518 // Zoom container
519 const g = svg.append("g");
520
521 const zoom = d3.zoom()
522 .scaleExtent([0.2, 4])
523 .on("zoom", e => g.attr("transform", e.transform));
524 svg.call(zoom);
525
526 // Simulation
527 if (graphSimulation) graphSimulation.stop();
528 graphSimulation = d3.forceSimulation(nodes)
529 .force("link", d3.forceLink(links).id(d => d.id).distance(90).strength(0.4))
530 .force("charge", d3.forceManyBody().strength(-220))
531 .force("center", d3.forceCenter(W / 2, H / 2))
532 .force("collision", d3.forceCollide().radius(d => graphNodeRadius(connCount[d.id]) + 10));
533
534 // ── Defs: glow filter ──
535 const defs = svg.append("defs");
536
537 const glowFilter = defs.append("filter").attr("id", "node-glow").attr("x", "-50%").attr("y", "-50%").attr("width", "200%").attr("height", "200%");
538 glowFilter.append("feGaussianBlur").attr("stdDeviation", "4").attr("result", "blur");
539 const feMerge = glowFilter.append("feMerge");
540 feMerge.append("feMergeNode").attr("in", "blur");
541 feMerge.append("feMergeNode").attr("in", "SourceGraphic");
542
543 const activeGlow = defs.append("filter").attr("id", "active-glow").attr("x", "-80%").attr("y", "-80%").attr("width", "260%").attr("height", "260%");
544 activeGlow.append("feGaussianBlur").attr("stdDeviation", "7").attr("result", "blur");
545 const feMerge2 = activeGlow.append("feMerge");
546 feMerge2.append("feMergeNode").attr("in", "blur");
547 feMerge2.append("feMergeNode").attr("in", "SourceGraphic");
548
549 // ── Links ──
550 const linkGroup = g.append("g").attr("class", "links");
551 const linkSel = linkGroup.selectAll("line")
552 .data(links)
553 .join("line")
554 .attr("stroke", "rgba(0,201,177,0.18)")
555 .attr("stroke-width", 1);
556
557 // ── Nodes ──
558 const nodeGroup = g.append("g").attr("class", "nodes");
559 const nodeSel = nodeGroup.selectAll("g")
560 .data(nodes)
561 .join("g")
562 .attr("class", "graph-node")
563 .style("cursor", "pointer")
564 .call(
565 d3.drag()
566 .on("start", (e, d) => {

Callers 1

openGraphViewFunction · 0.85

Calls 3

graphNodeRadiusFunction · 0.85
closeGraphViewFunction · 0.85
loadNoteFunction · 0.85

Tested by

no test coverage detected