Прежде всего, поскольку вы не опубликовали свой код, мой ответ будет касаться кода в JSFiddle , которым вы поделились.
Давайте разберемся с вашими двумяВыдает отдельно:
Расположение меток
Мне кажется, что вы хотите поместить метки в середину ссылок и всегда горизонтально, как обычный текст.В этом случае решение отбрасывает textPath
, что фактически упростит ваш выбор:
var link_label = svg.selectAll(".link_label")
.data(links)
.enter()
.append("text")
.text(function(d, i) {
return d.n;
});
Теперь это просто вопрос получения среднего положения этих путей, что мы можем сделать, используяgetTotalLength()
и getPointAtLength()
внутри функции tick
:
link_label.attr("x", function(d, i) {
var pathLength = d3.select("#link_" + i).node().getTotalLength();
d.point = d3.select("#link_" + i).node().getPointAtLength(pathLength / 2);
return d.point.x
})
.attr("y", function(d) {
return d.point.y
})
Здесь я сохраняю значение в свойстве, поскольку оно будет одинаковым как для x, так и для y позиции.Таким образом мы избегаем ненужных повторных расчетов.Кроме того, кто-то может поспорить, что вычисление следует размещать вне функции tick
, чтобы получить длину пути только один раз: к сожалению, это не так, потому что во время моделирования длина пути постоянно меняется.
Тени для текста
Здесь есть несколько разных подходов.Простой, вероятно, не самый красивый, использует text-shadow .Вот простая белая тень вверх, вправо, вниз и влево:
.shadow {
text-shadow: 2px 2px 0 #fff, 2px -2px 0 #fff, -2px 2px 0 #fff, -2px -2px 0 #fff
}
То, что CSS работает на Chrome и FireFox, но не на Safari.
Все вместе, вот демонстрация:
var nodes = [{
"ix": 0
},
{
"ix": 1
},
{
"ix": 2
},
{
"ix": 3
}
];
var links = [{
"source": 0,
"target": 2,
"n": 12
},
{
"source": 0,
"target": 1,
"n": 34
},
{
"source": 1,
"target": 2,
"n": 56
},
{
"source": 1,
"target": 0,
"n": 78
},
{
"source": 0,
"target": 3,
"n": 90
}
];
var w = 400,
h = 400;
var force = d3.layout.force()
.size([w, h])
.nodes(nodes)
.links(links)
.gravity(1)
.linkDistance(30)
.charge(-20000)
.linkStrength(1);
force.start();
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 " + w + " " + h)
.append("g");
var marker = svg.selectAll("marker")
.append("svg:defs")
.data(["end-arrow"])
.enter()
.append("svg:marker")
.attr("id", String)
.attr("viewBox", "0 -3 6 6")
.attr("refX", 11.3)
.attr("refY", -0.2)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-3L6,0L0,3");
var link = svg.selectAll("line.link")
.data(links)
.enter()
.append("svg:path")
.attr("id", function(d, i) {
return "link_" + i;
})
.style("stroke", "black")
.style("stroke-width", 2)
.style("fill", "none")
.attr("marker-end", "url(#end-arrow)");
var link_label = svg.selectAll(".link_label")
.data(links)
.enter()
.append("text")
.style("text-anchor", "middle")
.style("dominant-baseline", "central")
.attr("class", "shadow")
.text(function(d, i) {
return d.n;
});
var node = svg.selectAll(".node")
.data(force.nodes())
.enter()
.append("svg:g")
.attr("class", "node");
node.append("svg:circle")
.attr("r", 10)
.style("fill", "black");
node.call(force.drag);
force.on("tick", function() {
link.attr("d", function(d) {
var dx = d.target.x - d.source.x;
var dy = d.target.y - d.source.y;
var dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x +
"," +
d.source.y +
"A" +
dr +
"," +
dr +
" 0 0,1 " +
d.target.x +
"," +
d.target.y;
});
link_label.attr("x", function(d, i) {
var pathLength = d3.select("#link_" + i).node().getTotalLength();
d.point = d3.select("#link_" + i).node().getPointAtLength(pathLength / 2);
return d.point.x
})
.attr("y", function(d) {
return d.point.y
})
node.attr("transform", function(d) {
return ("translate(" + d.x + "," + d.y + ")");
});
});
.shadow {
text-shadow: 2px 2px 0 #fff, 2px -2px 0 #fff, -2px 2px 0 #fff, -2px -2px 0 #fff
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Редактировать: взгляните на Ответ Ксавье , белые круги выглядят гораздо лучше, чем тень текста.