我已经使用 d3.js 成功绘制了网格。网格由 10 行和 5 列组成。我应该如何使用 mouseOnclick 标记行和列的交集?该交点应该看起来像 I 指示该点相交。
var svg = d3.select("body").append("svg").attr("width", 500).attr("height", 500);
var inputs = [
{ "x1": 100, "x2": 500, "y1": 50, "y2": 50},
{ "x1": 100, "x2": 500, "y1": 90, "y2": 90},
{ "x1": 100, "x2": 500, "y1": 130, "y2": 130},
{ "x1": 100, "x2": 500, "y1": 170, "y2": 170},
{ "x1": 100, "x2": 500, "y1": 210, "y2": 210},
{ "x1": 100, "x2": 500, "y1": 250, "y2": 250},
{ "x1": 100, "x2": 500, "y1": 290, "y2": 290},
{ "x1": 100, "x2": 500, "y1": 330, "y2": 330},
{ "x1": 100, "x2": 500, "y1": 370, "y2": 370},
{ "x1": 100, "x2": 500, "y1": 400, "y2": 400},
//columns
{ "x1": 100, "x2": 100, "y1": 50, "y2": 400},
{ "x1": 200, "x2": 200, "y1": 50, "y2": 400},
{ "x1": 300, "x2": 300, "y1": 50, "y2": 400},
{ "x1": 400, "x2": 400, "y1": 50, "y2": 400},
{ "x1": 500, "x2": 500, "y1": 50, "y2": 400},
]
svg.selectAll("line").data(inputs).enter().append("line")
.attr("x1", function(d) {
return d.x1;
})
.attr("x2", function(d) {
return d.x2;
})
.attr("y1", function(d) {
return d.y1;
})
.attr("y2", function(d) {
return d.y2;
})
.attr("stroke", "red")
这是我的 fiddle :https://jsfiddle.net/7mmgedax/
最佳答案
您需要将数组拆分为行和列,然后找到每个点的交集。点交点的一个非常基本的算法如下所示:
function calculateIntersectionPoint(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
// if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
var denominator, a, b, numerator1, numerator2, result = {
x: null,
y: null,
onLine1: false,
onLine2: false
};
denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY));
if (denominator == 0) {
return result;
}
a = line1StartY - line2StartY;
b = line1StartX - line2StartX;
numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b);
numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b);
a = numerator1 / denominator;
b = numerator2 / denominator;
// if we cast these lines infinitely in both directions, they intersect here:
result.x = line1StartX + (a * (line1EndX - line1StartX));
result.y = line1StartY + (a * (line1EndY - line1StartY));
/*
// it is worth noting that this should be the same as:
x = line2StartX + (b * (line2EndX - line2StartX));
y = line2StartX + (b * (line2EndY - line2StartY));
*/
// if line1 is a segment and line2 is infinite, they intersect if:
if (a > 0 && a < 1) {
result.onLine1 = true;
}
// if line2 is a segment and line1 is infinite, they intersect if:
if (b > 0 && b < 1) {
result.onLine2 = true;
}
// if line1 and line2 are segments, they intersect if both of the above are true
return result;
};
可以在 https://jsfiddle.net/8gguunnq/1/ 找到工作演示。
在交点处画了一个圆。如果要省略边界条件,请将循环限制更改为 https://jsfiddle.net/8gguunnq/2/
关于javascript - 如何在 svg 和 d3.js 中指向线的交点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45955788/