Я пытаюсь сделать ориентированную по силе макет, в которой ссылки являются стрелками, указывающими на узлы (как в приведенных примерах here и here), а также в которых узлы, у которых есть дети, являются разборными (как показано в примерах Майка Бостока: here или here).D3js раскладная силовая компоновка с направленными дорожками?
До сих пор разрушение узлов прекрасно работает, но у меня возникают проблемы с пониманием того, как головки стрелок включены в пути. Вот часть моего кода, на основании приведенных выше примеров:
force.nodes(nodes)
.links(links)
.gravity(0.05)
.charge(-1500)
.linkDistance(100)
.friction(0.5)
.linkStrength(function(l, i) {return 1 })
.size([w, h])
.start();
// Append markers
vis.append("svg:defs").selectAll("marker")
.data(["end"])
.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") // <-- I not sure what this does
//.attr("d", "M0,-5L10,0L0,5");
var path = vis.selectAll("path")
.data(force.links());
// Enter new paths
path.enter().insert("svg:path")
.attr("class", "link")
.attr("marker-end", "url(#end)")
.style("stroke", "#ccc");
// Exit any old paths.
path.exit().remove();
// Update the nodes…
var node = vis.selectAll("g.node")
.data(nodes, function(d) { return d.id; })
node.select("circle")
.style("fill", color);
// Enter any new nodes.
var nodeEnter = node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.on("click", click)
.call(force.drag);
//Add an immage to the node
nodeEnter.append("svg:image")
.attr("xlink:href", function(d) { return d.image;})
.attr("x", function(d) { return (0 - Math.sqrt(d.size))/10 || 4.5;})
.attr("y", function(d) { return (0 - Math.sqrt(d.size))/10 || 4.5;})
.attr("height", 16)
.attr("width", 16);
// Exit any old nodes.
node.exit().remove();
// Re-select for update.
node = vis.selectAll("g.node");
path = vis.selectAll("path")
force.on("tick", function() {
// Draw curved links
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
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;
});
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
То, что я понимаю, что часть кода ниже отвечает за рисование стрел на, указав блок, где стрелки должны быть направлены на (например .data(["end"])
)
vis.append("svg:defs").selectAll("marker")
.data(["end"])
.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", "M0,-5L10,0L0,5");
Это затем сопоставляются, когда путь вводится (т.е. .attr("marker-end", "url(#end)");
).
Но, возможно, мне что-то не хватает, потому что на моем графике показаны пути, но не стрелки.
Спасибо за помощь!
Хороший вопрос! Боже, я боролся с этими стрелками. Я с нетерпением жду, чтобы увидеть, что здесь происходит. – d3noob
«Путь», который вы добавляете в определении маркера SVG, отвечает за рисование фактической стрелки. Вы запустили свой код с этим комментарием (первый блок кода)? –
Спасибо @LarsKotthoff, я понял это сразу после того, как я разместил вопрос. Раньше это не срабатывало, когда оно было расколото, и поскольку я не понимал, что это такое, я прокомментировал это. Написание 'path.link' почти фиксировало его. Я поставил свой ответ ниже. Тем не менее, есть еще кое-что, что мешает ему полностью работать ... – djjupa