SVG markers do not orient properly on d3.svg. Diagonal curve used as a link for D3 force composition

I'm a little new to SVG and d3.js.

When drawing a graph with a D3 force layout, I use a simple diagonal line generator and use the marker end to draw arrow heads.

When using an arc instead of a diagonal generator, the arrowheads look just fine. But using a diagonal generator, as in the code below, does not produce the correct markers:

var vis = this.vis = d3.select(el).append("svg:svg") .attr("width", w) .attr("height", h); var force = d3.layout.force() .gravity(0.03) .distance(120) .charge(-800) .size([w, h]); var linkDiag = d3.svg.diagonal() .projection(function(d) { return [dx, dy]; }); vis.append("svg:defs") .selectAll("marker") .data(["normal", "special", "resolved"]) .enter() .append("svg:marker") .attr("id", String) .attr("viewBox", "0 -5 10 10") .attr("refX", 15) .attr("refY", -1.5) .attr("markerWidth", 6) .attr("markerHeight", 6) .attr("orient", "auto") .append("svg:path") .attr("d", "M 0,-5 L 10,0 L0,5"); 

... and then also:

  force.on("tick", function() { 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; }) .attr("d", linkDiag) .attr("marker-end", function(d) { return "url(#special)"; }); }); 

Markers are not oriented at all with vertices.

Any help would be appreciated!

+6
source share
2 answers

It is displayed only if the arrows do not point in the right direction, because you are moving the arrow to a new position through refX and refY .

For example, check this code , which draws diagonals in different directions. The arrows are displayed correctly, with the exception of one at 180 degrees, but probably due to a rounding error.

Now try changing the refX in line 10 to a value of, say, 5. Now arrows close to the horizontal do not display correctly. To see this more sharply, try changing the value to 8.

What happens is that you hide part of the diagonal, so the line seems to end at an earlier point that is slightly curved from the actual end point. The same thing happens if the arrow is too large to overlap part of the curve. Note that for diagonals in d3 that are symmetrical bezier curves, arrows should always be displayed perfectly horizontally or vertically. You can see exactly what is happening, reducing the opacity of the arrow.

+2
source

Can you ask a question a little more? However, even if you use the code, I think the problem may be

 .attr("orient", "auto") 

Try specifying pos

0
source

Source: https://habr.com/ru/post/916444/


All Articles