Built with blockbuilder.org
xxxxxxxxxx
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
//TODO
//https://jsfiddle.net/04bxv2zw/17/
d3.select('#gen')
.on("click", function(d){
var i = d3.select("#ns")
nS = i.property("value");
if (nS < 3){
nS = 3
i.property("value", nS)
}
generateLayout(nS);
});
var width = 500,
height = 500,
radius = 20;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
// center of svg
var px = width / 2,
py = height / 2,
nodes = d3.range(20).map(function(d){ return {} });
nodes.forEach(function(d){
d.x = width/2 + Math.random()
d.y = 20
})
generateLayout(10);
function generateLayout(ns){
svg.selectAll("*").remove();
if (!ns) ns = parseInt(Math.random() * 5) + 4;
var ang = d3.range(ns).map(function(d){ return Math.random() * (2 * Math.PI) }).sort();
var polyPoints = ang.map(function(a){
var r = radius,
x = r * Math.cos(a) + px;
y = r * Math.sin(a) + py;
return [x, y];
});
console.log(polyPoints)
var w = 300;
var h = 300;
var tb = .5
var ta =.5
var polyPoints = [[50,50],[w,50],[w,h],[50,h]];
var maxY = d3.max(polyPoints,function(d){return d[1]})
console.log(polyPoints)
var cent = d3.polygonCentroid(polyPoints);
svg.append("polygon")
.style("stroke", "black")
.style("fill", "none")
.attr("points", polyPoints.join(" "));
var force = d3.forceSimulation()
// .force("charge", d3.forceManyBody().strength(2))
.velocityDecay(0.3)
.force("y", d3.forceY(height).strength(.015))
.force("collide", d3.forceCollide().radius(radius).strength(1.5).iterations(10))
//.alphaDecay(0.0005)
.nodes(nodes)
var node = svg.selectAll('.node')
.data(nodes)
.enter()
.append('circle')
.attr('class', 'node')
// .call(force.drag);
var N = polyPoints.length;
force.on('tick', function(e) {
node.attr('r', radius)
.attr('transform', function(d) {
// change focus to the center of the triangle
// var x = (d.x - (width / 2 - cent[0]))
// y = (d.y + (maxY)),
var x = d.x
var y = d.y
inter = false;
for (var i = 0; i < N; i++){
var f = i;
s = (i + 1) < N ? (i + 1) : 0;
inter = getLineIntersection(polyPoints[f][0], polyPoints[f][1],
polyPoints[s][0], polyPoints[s][1], cent[0], cent[1], x, y)
if (inter){
x = inter.x;
y = inter.y;
break;
}
}
return "translate(" + x + "," + y + ")";
});
});
// force.start();
}
// from https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
function getLineIntersection(p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) {
var s1_x, s1_y, s2_x, s2_y;
s1_x = p1_x - p0_x;
s1_y = p1_y - p0_y;
s2_x = p3_x - p2_x;
s2_y = p3_y - p2_y;
var s, t;
s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y);
t = (s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);
if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
var intX = p0_x + (t * s1_x);
var intY = p0_y + (t * s1_y);
return {
x: intX,
y: intY
};
}
return false;
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js