xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;top:0;right:0;bottom:0;left:0; }
path { stroke: black; stroke-width: 1px }
</style>
</head>
<body>
<script>
var nodes = [
{ "type": "country", "name": "A", "value": 15 },
{ "type": "country", "name": "B", "value": 5 },
{ "type": "country", "name": "C", "value": 25 },
{ "type": "club", "name": "D", "value": 50 },
{ "type": "club", "name": "E", "value": 10 }
]
var links = [
{ "source": "A", "target": "D", "value": 1 },
{ "source": "A", "target": "E", "value": 15 },
{ "source": "B", "target": "D", "value": 5 },
{ "source": "B", "target": "E", "value": 50 },
{ "source": "C", "target": "D", "value": 15 },
]
let maxRValue = d3.max(nodes, (d) => d.value)
let maxLinkValue = d3.max(links, (d) => d.value)
var w = 800, h = 800, r = 350
const radians = 0.0174532925
let linkScale = d3.scaleLinear()
.domain([0, maxLinkValue])
.range([0, r])
let rScale = d3.scaleSqrt()
.domain([0, maxRValue])
.range([10, 75])
var numberOfCountries = 3
//fix the circles to the radius
nodes.forEach(function(node, i){
if (node.type == "country") {
let a = (360/numberOfCountries) * i
node.fx = w/2 + x(a, r)
node.fy = h/2 + y(a, r)
}
})
var g = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.append("g")
g.append("circle")
.attr("cx", w/2)
.attr("cy", h/2)
.attr("r", r)
.style("fill", "none")
.style("stroke", "grey")
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.name; }))
var link = g.append("g")
.attr("class", "links")
.selectAll("path")
.data(links)
.enter()
.append("path");
var node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter()
.append("g")
node.append("circle")
.attr("r", (d) => rScale(d.value))
.style("fill", function(d){
return d.type == "country" ? "PaleVioletRed" : "MediumSeaGreen"
})
.style("stroke", "white")
.style("stroke-width", 3)
node.append("text")
.text((d) => d.name)
.style("text-anchor", "middle")
.attr("dy", "0.35em")
.style("stroke", "white")
.style("stroke-width", 3)
node.append("text")
.text((d) => d.name)
.style("text-anchor", "middle")
.attr("dy", "0.35em")
simulation
.nodes(nodes)
.on("tick", ticked)
simulation.force("link")
.links(links)
.distance((d) => linkScale(d.value))
.strength(0.5)
function ticked() {
link.attr("d", function(d) {
return "M" + d.source.x + " " + d.source.y
+ " L" + d.target.x + " " + d.target.y;
})
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"
})
}
function x (angle, radius) {
// rotate 90
let a = 90 - angle
return radius * Math.sin(a * radians)
}
function y (angle, radius) {
// rotate 90
let a = 90 - angle
return radius * Math.cos(a * radians)
}
</script>
</body>
https://d3js.org/d3.v4.min.js