Наиболее очевидным решением здесь было бы установить маркер на marker-end
или marker-start
в соответствии со значением свойства flag
.
Однако, подумав еще раз, мы можем сделать что-то ещеинтересно здесь: мы можем установить все маркеры как marker-end
и, в соответствии с flag
, мы swap x1
и x2
свойства, что делает:
x1
меньше x2
, если флаг R
; x1
больше x2
, если флаг L
;
Это можно сделать с помощью:
data.forEach(function(d) {
if ((d.flag === "L" && d.x1 < d.x2) || (d.flag === "R" && d.x1 > d.x2)) {
d.x1 = d.x2 + (d.x2 = d.x1, 0);
}
});
Вот демоверсия:
const csv = `x1,y1,x2,y2,flag
1,2,3,2,L
3,3,5,4,R
5,3,6,3,L
7,5,8,5,R
8,6,9,6,L
9,7,2,8,L`;
const data = d3.csvParse(csv, function(d) {
d.x1 = +d.x1 * 20;
d.y1 = +d.y1 * 15;
d.x2 = +d.x2 * 20;
d.y2 = +d.y2 * 15;
return d;
});
data.forEach(function(d) {
if ((d.flag === "L" && d.x1 < d.x2) || (d.flag === "R" && d.x1 > d.x2)) d.x1 = d.x2 + (d.x2 = d.x1, 0);
});
const svg = d3.select("svg");
const marker = svg.append("defs")
.append("marker")
.attr("id", "marker")
.attr("viewBox", "0 0 10 10")
.attr("refX", "5")
.attr("refY", "5")
.attr("markerWidth", "6")
.attr("markerHeight", "6")
.attr("orient", "auto")
.append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z");
const enterSelection = svg.selectAll(null)
.data(data)
.enter()
.append("line")
.attr("x1", d => d.x1)
.attr("y1", d => d.y1)
.attr("x2", d => d.x2)
.attr("y2", d => d.y2)
.attr("marker-end", "url(#marker)")
.style("stroke-width", "1px")
.style("stroke", "black");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
Поскольку ваши значения слишком малы, я умножу их здесь, чтобы мы могли лучше видеть линии.Кроме того, поскольку вы не указали ни одного маркера, я использую его в MDN .