import * as d3 from "d3"; const width = 1000, height = 700; const svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height); const levels = { structural: 100, proximate: 300, outcome: 500 }; const nodes = [ { id: "poverty", name: "Poverty (India rural areas)", level: "structural", country: "India" }, { id: "education", name: "Low Female Education", level: "structural", country: "India" }, { id: "gender", name: "Gender Inequality", level: "structural", country: "India" }, { id: "access", name: "Limited Health Access (Bihar, UP)", level: "proximate", country: "India" }, { id: "delay", name: "Delay in Care-Seeking", level: "proximate", country: "India" }, { id: "hemorrhage", name: "Hemorrhage", level: "proximate" }, { id: "infection", name: "Sepsis/Infection", level: "proximate" }, { id: "mortality", name: "Maternal Death", level: "outcome" } ]; const links = [ { source: "poverty", target: "access" }, { source: "education", target: "delay" }, { source: "gender", target: "delay" }, { source: "access", target: "hemorrhage" }, { source: "delay", target: "infection" }, { source: "hemorrhage", target: "mortality" }, { source: "infection", target: "mortality" } ]; nodes.forEach((d, i) => { d.x = 100 + (i % 4) * 200; d.y = levels[d.level]; }); svg.selectAll("rect") .data(nodes) .enter() .append("rect") .attr("x", d => d.x) .attr("y", d => d.y) .attr("width", 160) .attr("height", 50) .attr("rx", 10) .attr("fill", d => d.level === "structural" ? "#F28CB1" : d.level === "proximate" ? "#89CFF0" : "#A9A9A9") .attr("stroke", "#333") .attr("stroke-width", 1); svg.selectAll("text") .data(nodes) .enter() .append("text") .attr("x", d => d.x + 10) .attr("y", d => d.y + 30) .text(d => d.name) .attr("font-size", "12px"); svg.selectAll("line") .data(links) .enter() .append("line") .attr("x1", d => nodes.find(n => n.id === d.source).x + 80) .attr("y1", d => nodes.find(n => n.id === d.source).y + 50) .attr("x2", d => nodes.find(n => n.id === d.target).x + 80) .attr("y2", d => nodes.find(n => n.id === d.target).y) .attr("stroke", "#666") .attr("stroke-width", 2) .attr("marker-end", "url(#arrow)"); svg.append("defs").append("marker") .attr("id", "arrow") .attr("viewBox", "0 -5 10 10") .attr("refX", 5) .attr("refY", 0) .attr("markerWidth", 6) .attr("markerHeight", 6) .attr("orient", "auto") .append("path") .attr("d", "M0,-5L10,0L0,5") .attr("fill", "#666"); // Legend const legendData = [ { label: "Structural Determinants", color: "#F28CB1" }, { label: "Proximate Determinants", color: "#89CFF0" }, { label: "Outcome", color: "#A9A9A9" } ]; svg.selectAll(".legend") .data(legendData) .enter() .append("rect") .attr("x", 800) .attr("y", (d, i) => 50 + i * 30) .attr("width", 20) .attr("height", 20) .attr("fill", d => d.color); svg.selectAll(".legend-text") .data(legendData) .enter() .append("text") .attr("x", 830) .attr("y", (d, i) => 65 + i * 30) .text(d => d.label) .attr("font-size", "12px");