Arrow working for rect without radius
This commit is contained in:
parent
cad37c1a0c
commit
39fd72caf8
85
script.js
85
script.js
@ -1,3 +1,57 @@
|
||||
/**
|
||||
* Finds the intersection point between
|
||||
* * a rectangle centered in point B
|
||||
* with sides parallel to the x and y axes
|
||||
* * a line passing through points A and B (the center of the rectangle)
|
||||
*
|
||||
* @param width: rectangle width
|
||||
* @param height: rectangle height
|
||||
* @param xB; rectangle center x coordinate
|
||||
* @param yB; rectangle center y coordinate
|
||||
* @param xA; point A x coordinate
|
||||
* @param yA; point A y coordinate
|
||||
* @author Federico Destefanis
|
||||
* @see <a href="https://stackoverflow.com/a/31254199/2668213">based on</a>
|
||||
*/
|
||||
|
||||
function lineIntersectionOnRect(width, height, xB, yB, xA, yA) {
|
||||
|
||||
var w = width / 2;
|
||||
var h = height / 2;
|
||||
|
||||
var dx = xA - xB;
|
||||
var dy = yA - yB;
|
||||
|
||||
//if A=B return B itself
|
||||
if (dx == 0 && dy == 0) return {
|
||||
x: xB,
|
||||
y: yB
|
||||
};
|
||||
|
||||
var tan_phi = h / w;
|
||||
var tan_theta = Math.abs(dy / dx);
|
||||
|
||||
//tell me in which quadrant the A point is
|
||||
var qx = Math.sign(dx);
|
||||
var qy = Math.sign(dy);
|
||||
|
||||
|
||||
if (tan_theta > tan_phi) {
|
||||
xI = xB + (h / tan_theta) * qx;
|
||||
yI = yB + h * qy;
|
||||
} else {
|
||||
xI = xB + w * qx;
|
||||
yI = yB + w * tan_theta * qy;
|
||||
}
|
||||
|
||||
return {
|
||||
x: xI,
|
||||
y: yI
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
const angle_between = (x1, y1, x2, y2) => {
|
||||
let angle = Math.atan2(y2-y1, x2-x1);
|
||||
if (angle < 0) angle += 2*Math.PI
|
||||
@ -28,9 +82,9 @@ const box_intersection = (angle, box_width, box_height, border_radius) => {
|
||||
const half_height = box_height / 2;
|
||||
const half_width = box_width / 2;
|
||||
|
||||
if (hits_border_radius(angle, box_width, box_height, border_radius)) {
|
||||
return arc_border_box_intersection(angle, half_width, half_height, border_radius)
|
||||
}
|
||||
// if (hits_border_radius(angle, box_width, box_height, border_radius)) {
|
||||
// return arc_border_box_intersection(angle, half_width, half_height, border_radius)
|
||||
// }
|
||||
|
||||
return straight_border_box_intersection(angle, half_width, half_height)
|
||||
}
|
||||
@ -40,6 +94,7 @@ const straight_border_box_intersection = (angle, box_width, box_height) => ({
|
||||
x: Math.sin(angle) * box_height,
|
||||
});
|
||||
|
||||
|
||||
const arc_border_box_intersection = (angle, box_width, box_height, border_radius) => {
|
||||
//TODO:
|
||||
return 1;
|
||||
@ -48,8 +103,9 @@ const arc_border_box_intersection = (angle, box_width, box_height, border_radius
|
||||
const SVG_WIDTH = 960;
|
||||
const SVG_HEIGHT = 500;
|
||||
|
||||
const BOX_WIDTH = 60;
|
||||
const BOX_HEIGHT = 20;
|
||||
const BOX_WIDTH = 120;
|
||||
const BOX_HEIGHT = 40;
|
||||
const BORDER_RADIUS = 10;
|
||||
|
||||
const MARKER_VIEWBOX = {
|
||||
minX: 0,
|
||||
@ -74,7 +130,7 @@ const graph = {
|
||||
x: 250,
|
||||
y: 250,
|
||||
w: BOX_WIDTH,
|
||||
h: BOX_HEIGHT + 10,
|
||||
h: BOX_HEIGHT,
|
||||
}
|
||||
],
|
||||
links: [
|
||||
@ -150,6 +206,7 @@ const nodes = svg
|
||||
.attr('class', 'node-box')
|
||||
.attr('width', node => node.w)
|
||||
.attr('height', node => node.h)
|
||||
.attr('rx', BORDER_RADIUS)
|
||||
.attr('x', node => node.x)
|
||||
.attr('y', node => node.y)
|
||||
.attr('id', node => node.name)
|
||||
@ -184,13 +241,14 @@ const force = d3
|
||||
.each(link => {
|
||||
const markerId = generateMarkerId(link.index);
|
||||
|
||||
//In radians
|
||||
const linkAngle = angle_between(
|
||||
link.source.x,
|
||||
-link.source.y,
|
||||
link.target.x,
|
||||
-link.target.y
|
||||
);
|
||||
|
||||
|
||||
const intersectionPoint = box_intersection(
|
||||
linkAngle,
|
||||
link.target.w,
|
||||
@ -198,11 +256,20 @@ const force = d3
|
||||
0
|
||||
);
|
||||
|
||||
const intersect = lineIntersectionOnRect(BOX_WIDTH, BOX_HEIGHT, link.source.x, link.source.y, link.target.x, link.target.y);
|
||||
|
||||
const marker = d3.select(`#${markerId}`)
|
||||
const distance = Math.sqrt( ((intersectionPoint.x)**2) + ((intersectionPoint.y) ** 2) );
|
||||
|
||||
let distance;
|
||||
|
||||
// if(hits_border_radius(linkAngle, link.target.w, link.target.h, BORDER_RADIUS)) {
|
||||
// distance = Math.sqrt( ((intersectionPoint.x)**2) + ((intersectionPoint.y) ** 2) );
|
||||
// } else {
|
||||
distance = Math.sqrt(Math.pow(intersect.x - link.source.x, 2) + Math.pow(intersect.y - link.source.y, 2));
|
||||
// }
|
||||
marker.attr('refX', _ => {
|
||||
const markerHeight = MARKER_VIEWBOX.maxY - MARKER_VIEWBOX.minY
|
||||
return distance + markerHeight
|
||||
return distance + markerHeight/2 + 2;
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user