I have .attr
that create my link paths in d3 as below, Lines 42 in the demo:
link.each(function (d){})
.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;
});
The above draws my path links. I've changed this to calculate making the link paths smaller. However, there is a lot of repeated logic and not sure how to call a function to return my the values required. As below:
link.attr("x1", function(d) {
// Total difference in x and y from source to target
let diffX = d.target.x - d.source.x;
let diffY = d.target.y - d.source.y;
// Length of path from center of source node to center of target node
let pathLength = Math.sqrt((diffX * diffX) (diffY * diffY));
// x and y distances from center to outside edge of target node
let offsetX = (diffX * 40) / pathLength;
return d.source.x offsetX;
}).attr("y1", function(d) {
let diffX = d.target.x - d.source.x;
let diffY = d.target.y - d.source.y;
let pathLength = Math.sqrt((diffX * diffX) (diffY * diffY));
let offsetY = (diffY * 40) / pathLength;
return d.source.y offsetY;
}).attr("x2", function(d) {
let diffX = d.target.x - d.source.x;
let diffY = d.target.y - d.source.y;
let pathLength = Math.sqrt((diffX * diffX) (diffY * diffY));
let offsetX = (diffX * 40) / pathLength;
return d.target.x - offsetX;
}).attr("y2", function(d) {
let diffX = d.target.x - d.source.x;
let diffY = d.target.y - d.source.y;
let pathLength = Math.sqrt((diffX * diffX) (diffY * diffY));
let offsetY = (diffY * 40) / pathLength;
return d.target.y - offsetY;
})
It returns offsetX
for d.source.x
/d.target.x
values and offsetY
for d.source.y
/d.target.y
.
Ideally i dont want all this repeated logic and have tried doing a .call()
on the link which goes into a function but then I dont know how to return the result into the attributes themselves e.g.
.attr('x1', function (d) {
return d.source.x; //function return from .call()
})
I've also tried putting the function call within the above attribute but get an error of "is not a function" e.g
.attr('x1', function (d) {
return this.myNewPathFunction(d);
})
Lines 42 in the demo
CodePudding user response:
You could move your logic to a function like so:
const coordinate = (position, d, index, nodes) => {
// Total difference in x and y from source to target
let diffX = d.target.x - d.source.x;
let diffY = d.target.y - d.source.y;
// Length of path from center of source node to center of target node
let pathLength = Math.sqrt(diffX * diffX diffY * diffY);
// x and y distances from center to outside edge of target node
let offsetX = (diffX * 40) / pathLength;
let offsetY = (diffY * 40) / pathLength;
if (position === 'x1') return d.source.x offsetX;
if (position === 'y1') return d.source.y offsetY;
if (position === 'x2') return d.target.x - offsetX;
if (position === 'y2') return d.target.y - offsetY;
};
link
.attr('x1', (d, i, nodes) => coordinate('x1', d, i, nodes))
.attr('y1', (d, i, nodes) => coordinate('y1', d, i, nodes))
.attr('x2', (d, i, nodes) => coordinate('x2', d, i, nodes))
.attr('y2', (d, i, nodes) => coordinate('y2', d, i, nodes));