javascript - 如何在 svg 和 d3.js 中指向线的交点?

标签 javascript d3.js svg

我已经使用 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/

相关文章:

java - 在这种情况下使用异步请求是一个好习惯吗?

javascript - c3JS加载函数

ruby-on-rails - 使用 Rails Asset Pipeline 渲染 SVG HAML 模板

android - 海量矢量素材导入Android Studio

javascript - 在 Raphael 中复制 d3.js 动态树

javascript - 页面中文本的条件替换

javascript - 是什么导致不安全脚本 "unsafe"?

javascript - 如何更改 Chrome 扩展中的事件标签网址

javascript - 更新期间不会删除 d3 图表中的旧节点

javascript - 消除矩形中间的边界半径