let width = 800;
let height = 800;
let svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
let marge = { top: 10, bottom: 10, left: 10, right: 10 };
let g = svg
.append("g")
.attr("transform", "translate(" + marge.top + "," + marge.left + ")");
let nodes = [
{ name: "1", group: 2.5 },
{ name: "2", group: 2 },
{ name: "3", group: 2 },
{ name: "4", group: 2 },
{ name: "5", group: 2 },
{ name: "6", group: 2 },
{ name: "7", group: 2 },
{ name: "8", group: 2 },
{ name: "9", group: 2 },
];
let edges = [
{ source: 0, target: 1, value: 2,relation:"连接线" },
{ source: 0, target: 0, value: 2,relation:"" },
{ source: 0, target: 2, value: 2,relation:"连接线" },
{ source: 0, target: 3, value: 2,relation:"连接线" },
{ source: 0, target: 4, value: 2,relation:"连接线" },
{ source: 0, target: 5, value: 2,relation:"连接线" },
{ source: 0, target: 6, value: 2,relation:"连接线" },
{ source: 0, target: 7, value: 2,relation:"连接线" },
{ source: 0, target: 8, value: 2,relation:"连接线" },
{ source: 8, target: 0, value: 2,relation:"连接线" },
{ source: 8, target: 8, value: 2,relation:"" },
{ source: 8, target: 6, value: 2,relation:"连接线" },
];
let forceSimulation = d3
.forceSimulation()
.force("link", d3.forceLink())
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter());
forceSimulation.nodes(nodes).on("tick", ticked);
forceSimulation
.force("link")
.links(edges)
.distance(function (d) {
return d.value * 100;
});
forceSimulation
.force("center")
.x(width / 2)
.y(height / 2);
console.log(nodes);
console.log(edges[0].source);
let defs = svg.append("defs");
let arrow_path = "M0,0 L5.19,3 L0,6 L0,0";
defs
.append("marker")
.attr("id", "arrow0")
.attr("markerUnits", "userSpaceOnUse")
.attr("markerWidth", "12")
.attr("markerHeight", "12")
.attr("viewBox", "0 0 12 12")
.attr("refX", "20")
.attr("refY", "3")
.attr("orient", "auto")
.append("path")
.attr("d", arrow_path)
.attr("fill", "#757f7f");
defs
.append("marker")
.attr("id", "arrow1")
.attr("markerUnits", "userSpaceOnUse")
.attr("markerWidth", "12")
.attr("markerHeight", "12")
.attr("viewBox", "0 0 12 12")
.attr("refX", "5")
.attr("refY", "2.5")
.attr("orient", "auto")
.append("path")
.attr("d", arrow_path)
.attr("fill", "#757f7f");
let links = g
.append("g")
.selectAll("path")
.data(edges)
.enter()
.append("path")
.attr("stroke", function (d, i) {
return "#757f7f";
})
.attr("stroke-width", 1)
.attr("marker-end",(d)=>{
let x1 = d.source.x;
let y1 = d.source.y;
let x2 = d.target.x;
let y2 = d.target.y;
if (x1 === x2 && y1 === y2) {
return "url(#arrow1)"
}
return "url(#arrow0)"})
.attr("fill", "#d2691e00");
let linksText = g
.append("g").attr("font-size",6)
.selectAll("text")
.data(edges)
.enter()
.append("text")
.text(function (d) {
return d.relation;
});
let gs = g
.selectAll(".circleText")
.data(nodes)
.enter()
.append("g")
.attr("transform", function (d, i) {
let cirX = d.x;
let cirY = d.y;
return "translate(" + cirX + "," + cirY + ")";
})
.call(
d3
.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)
);
gs.append("circle")
.attr("r", function (d, i) {
return 15;
})
.attr("fill", function (d, i) {
return "#f1bcd8";
});
gs.append("text").attr("font-size",10)
.attr("x", -25)
.attr("y", -5)
.attr("dy", 10)
.text(function (d) {
return d.name;
});
function ticked() {
links.attr("d", (d) => {
let x1 = d.source.x;
let y1 = d.source.y;
let x2 = d.target.x;
let y2 = d.target.y;
if (x1 === x2 && y1 === y2) {
return `M${x1 - 15},${y1} A${25},${25} ${0},${1},${1} ${
x1 + 15
},${y1}`;
}
const {x:moveX,y:moveY}= getTargetXY(15,d.value*100,d.source,d.target);
return `M${x1} ${y1}L${x2} ${y2}`;
});
linksText
.attr("x", function (d) {
return (d.source.x + d.target.x) / 2;
})
.attr("y", function (d) {
return (d.source.y + d.target.y) / 2;
});
gs.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
function dragstarted(event) {
if (!event.active) forceSimulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
function dragged(event) {
event.subject.fx += event.dx;
event.subject.fy += event.dy;
}
function dragended(event) {
if (!event.active) forceSimulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}