gpt4 book ai didi

javascript - 在三 Angular 形内强制图表 d3.js

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:43:02 29 4
gpt4 key购买 nike

我正在研究 d3.js 力图,我有一个问题。 是否可以在带有某些坐标的三 Angular 形内制作力图?

这是我的代码:

var width = 500;
var height = 500;
//margin
var marginLeft = 10;
var marginTop = 10;
var marginRight = 10;
var marginBottom = 10;
var margin = { left: marginLeft , top: marginTop, right: marginRight, bottom: marginBottom};

//size of canvas
var innerWidth = width - margin.left - margin.right;
var innerHeight = height - margin.top - margin.bottom;

var radius = 10;

var svg = d3.select(".forcechart").append("svg")
.attr("width", width)
.attr("height", height)
.style("background", "#eee");

var tr = svg.append("polygon") // attach a polygon
.style("stroke", "black") // colour the line
.style("fill", "none") // remove any fill colour
.attr("points", "250,0, 12,173, 250,250"); // x,y points

var group = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var graph = {
"nodes": [ { "x": 0, "y": 0 },
{ "x": 100, "y": 100 },
{ "x": 500, "y": 500 },
{ "x": 300, "y": 0 },
{ "x": 300, "y": 0 },
{ "x": 100, "y": 100 },
{ "x": 500, "y": 500 },
{ "x": 300, "y": 0 },
{ "x": 300, "y": 0 },
{ "x": 100, "y": 100 },
{ "x": 500, "y": 500 },
{ "x": 300, "y": 0 },
{ "x": 300, "y": 0 },
{ "x": 100, "y": 100 },
{ "x": 500, "y": 500 },
{ "x": 300, "y": 0 },
{ "x": 300, "y": 0 },
{ "x": 100, "y": 100 },
{ "x": 500, "y": 500 },
{ "x": 300, "y": 0 },
{ "x": 300, "y": 0 },
],
"links": []
};


var nodes = graph.nodes,
links = graph.links;

var force = d3.layout.force()
.size([innerWidth, innerHeight])
.nodes(nodes)
.links(links);

force.linkDistance(100);
force.charge(-200);

var link = group.selectAll('.link')
.data(links)
.enter().append('line')
.attr('class', 'link');

var node = group.selectAll('.node')
.data(nodes)
.enter().append('circle')
.attr('class', 'node');

force.on('tick', function() {
node.attr('r', radius)
.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; });

link.attr('x1', function(d) { return d.source.x; })
.attr('y1', function(d) { return d.source.y; })
.attr('x2', function(d) { return d.target.x; })
.attr('y2', function(d) { return d.target.y; });

});


force.start();

完整代码在这里:http://codepen.io/Balzzac/pen/vGWXdQ .现在它是“组”内的力图,我需要使其位于三 Angular 形“tr”内,这样没有一个节点在我的三 Angular 形边界之外。

感谢您的帮助!

PS 对不起我的英语 =)

最佳答案

这个问题实际上有两个部分。首先,你需要你的力布局收敛到不同的焦点然后默认 width/2, height/2 .这个新焦点应该是三 Angular 形的质心。幸运的是 d3a helper method为多边形计算这个。其次,既然我们收敛于三 Angular 形的质心,我们如何将我们的节点绑定(bind)在该三 Angular 形内。我在下面使用的方法计算从质心到节点绘制的线与三 Angular 形边缘线之间的交点(交点计算来自此 question )。所有 3 条边都没有交点意味着圆在三 Angular 形中,任何一条边有交点意味着我们需要把圆带到那条边上。

UPDATE -- 对代码进行了一些概括并将其转换为 block here使用 N 边多边形。

让我们来看代码:

<!DOCTYPE html>
<html>

<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>

<body>
<script>
var width = 500,
height = 500,
radius = 10;

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.style("background", "#eee");

// our polygon
var trianglePoints = [
[250, 0],
[12, 173],
[250, 250]
];

var tr = svg.append("polygon") // attach a polygon
.style("stroke", "black") // colour the line
.style("fill", "none") // remove any fill colour
.attr("points", trianglePoints.join(" ")); // x,y points

var group = svg.append("g");

var nodes = d3.range(20).map(function(d){ return {} }),
links = [],
cent = d3.geom.polygon(trianglePoints).centroid();

var force = d3.layout.force()
.size([width, height])
.nodes(nodes)
.links(links);

force.linkDistance(100);
force.charge(-200);

var link = group.selectAll('.link')
.data(links)
.enter().append('line')
.attr('class', 'link');

var node = group.selectAll('.node')
.data(nodes)
.enter().append('circle')
.attr('class', 'node')
.call(force.drag); //<-- make them draggable to test

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 - (height / 2 - cent[1]));

// test intersections on all 3 edges
var i =
getLineIntersection(trianglePoints[0][0], trianglePoints[0][1],
trianglePoints[1][0], trianglePoints[1][1], cent[0], cent[1], x, y) ||
getLineIntersection(trianglePoints[1][0], trianglePoints[1][1],
trianglePoints[2][0], trianglePoints[2][1], cent[0], cent[1], x, y) ||
getLineIntersection(trianglePoints[0][0], trianglePoints[0][1],
trianglePoints[2][0], trianglePoints[2][1], cent[0], cent[1], x, y) ||
false;

// set it to intersection
if (i){
x = i.x;
y = i.y;
}

return "translate(" + x + "," + y + ")";

});

link.attr('x1', function(d) {
return d.source.x;
})
.attr('y1', function(d) {
return d.source.y;
})
.attr('x2', function(d) {
return d.target.x;
})
.attr('y2', function(d) {
return d.target.y;
});

});

// 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;
}

force.start();
</script>
</body>

</html>

关于javascript - 在三 Angular 形内强制图表 d3.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36949486/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com