2025-06-25 18:59:39 +08:00

125 lines
5.8 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>D3 Flowchart</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<svg id="flowchart" width="1400" height="900"></svg>
<script>
const nodes = [
// Overall Goal
{ id: 'G1', x: 550, y: 20, width: 300, height: 50, color: '#2E8B57' }, // darkseagreen
// Main Pillars
{ id: 'P1', x: 50, y: 150, width: 300, height: 50, color: 'black' },
{ id: 'P2', x: 550, y: 150, width: 300, height: 50, color: 'black' },
{ id: 'P3', x: 1050, y: 150, width: 300, height: 50, color: 'black' },
// Column 1
{ id: 'W1', x: 250, y: 300, width: 150, height: 50, color: 'white', stroke: 'black' },
{ id: 'N1e', x: 50, y: 250, width: 150, height: 50, color: 'lightgrey' },
{ id: 'N1f', x: 50, y: 320, width: 150, height: 50, color: 'lightgrey' },
{ id: 'N1b_2d', x: 250, y: 400, width: 150, height: 70, color: 'lightgrey' },
{ id: 'W2', x: 50, y: 600, width: 150, height: 70, color: 'white', stroke: 'black' },
{ id: 'N1c', x: 50, y: 450, width: 150, height: 50, color: 'lightgrey' },
{ id: 'N1d', x: 50, y: 520, width: 150, height: 50, color: 'lightgrey' },
{ id: 'N1a', x: 250, y: 520, width: 150, height: 50, color: 'lightgrey' },
// Column 2
{ id: 'W3', x: 450, y: 300, width: 150, height: 50, color: 'white', stroke: 'black' },
{ id: 'N2a', x: 450, y: 400, width: 150, height: 70, color: 'lightgrey' },
{ id: 'W4', x: 650, y: 520, width: 150, height: 70, color: 'white', stroke: 'black' },
{ id: 'N2b', x: 450, y: 520, width: 150, height: 50, color: 'lightgrey' },
{ id: 'N2c', x: 650, y: 650, width: 150, height: 50, color: 'lightgrey' },
// Column 3
{ id: 'W5', x: 850, y: 300, width: 150, height: 70, color: 'white', stroke: 'black' },
{ id: 'W6', x: 1050, y: 300, width: 150, height: 50, color: 'white', stroke: 'black' },
{ id: 'W7', x: 1250, y: 300, width: 150, height: 50, color: 'white', stroke: 'black' },
{ id: 'N3a', x: 850, y: 450, width: 150, height: 70, color: 'lightgrey' },
{ id: 'N3b', x: 1050, y: 450, width: 150, height: 70, color: 'lightgrey' },
{ id: 'N3c', x: 1250, y: 450, width: 150, height: 70, color: 'lightgrey' }
];
const links = [
{ source: 'P1', target: 'G1', path: 'M200,150 V95 H700 V70' },
{ source: 'P2', target: 'G1', path: 'M700,150 V70' },
{ source: 'P3', target: 'G1', path: 'M1200,150 V95 H700 V70' },
{ source: 'W1', target: 'P1', path: 'M325,300 V225 H200 V200' },
{ source: 'N1e', target: 'W1', path: 'M125,275 H250' },
{ source: 'N1f', target: 'W1', path: 'M125,345 H250' },
{ source: 'N1b_2d', target: 'W1', path: 'M325,400 V350' },
{ source: 'W2', target: 'P1', path: 'M125,600 V225 H200 V200' },
{ source: 'N1c', target: 'W2', path: 'M125,475 V580 H125 V600' },
{ source: 'N1d', target: 'W2', path: 'M125,545 V600' },
{ source: 'N1a', target: 'W2', path: 'M325,545 H200 V600' },
{ source: 'W3', target: 'P2', path: 'M525,300 V225 H700 V200' },
{ source: 'N1b_2d', target: 'W3', path: 'M400,435 H450' },
{ source: 'N2a', target: 'W3', path: 'M525,400 V350' },
{ source: 'W4', target: 'P2', path: 'M725,520 V225 H700 V200' },
{ source: 'N2a', target: 'W4', path: 'M525,470 V555 H650' },
{ source: 'N2b', target: 'W4', path: 'M525,545 H650' },
{ source: 'N2c', target: 'W4', path: 'M725,650 V590' },
{ source: 'W5', target: 'P3', path: 'M925,300 V225 H1200 V200' },
{ source: 'N3a', target: 'W5', path: 'M925,450 V370' },
{ source: 'W6', target: 'P3', path: 'M1125,300 V225 H1200 V200' },
{ source: 'N3b', target: 'W6', path: 'M1125,450 V350' },
{ source: 'W7', target: 'P3', path: 'M1325,300 V225 H1200 V200' },
{ source: 'N3c', target: 'W7', path: 'M1325,450 V350' },
{ source: 'W1', target: 'W3', path: 'M400,325 H450' },
{ source: 'N2a', target: 'N1b_2d', path: 'M450,435 H400' },
{ source: 'W2', target: 'W4', path: 'M200,635 H650' }
];
const svg = d3.select("#flowchart");
// Define arrow marker
svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 8)
.attr("refY", 0)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5")
.attr("fill", "black");
// Draw links
svg.append("g")
.selectAll("path")
.data(links)
.enter().append("path")
.attr("d", d => d.path)
.attr("stroke", "black")
.attr("stroke-width", 1.5)
.attr("fill", "none")
.attr("marker-end", "url(#arrow)");
// Draw nodes
const nodeGroup = svg.append("g")
.selectAll("g")
.data(nodes)
.enter().append("g")
.attr("transform", d => `translate(${d.x}, ${d.y})`);
nodeGroup.append("rect")
.attr("width", d => d.width)
.attr("height", d => d.height)
.attr("fill", d => d.color)
.attr("stroke", d => d.stroke || "none")
.attr("stroke-width", 1.5);
</script>
</body>
</html>