gpt4 book ai didi

javascript - D3 4.0 有向边和标签的图

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:12:22 25 4
gpt4 key购买 nike

我正在尝试使用 d3 (v4.0) 创建一个图,该图具有节点的有向边和标签,如下所示:http://jsfiddle.net/chrisJamesC/HgHqy/但使用较新版本的 D3。

这是我目前所拥有的:https://jsfiddle.net/4nu57pgn/1/但我似乎无法弄清楚如何告诉 D3 使边缘看起来是视觉定向的(带有箭头)或显示节点 ID。

var svg = d3.select("svg");
var width = svg.attr("width");
var height = svg.attr("height");
svg = svg.call(d3.zoom().on("zoom", zoomed)).append("g");
var color = d3.scaleOrdinal(d3.schemeCategory10);

var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));

function createGraph (error, graph) {
if (error) throw error;

var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke", function(d) { return color(d.type); });


var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 10)
.attr("fill", function(d) { if (d.root == "true") return color(d.root); return color(d.type); })
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

node.on("click",function(d){
console.log("clicked", d.id);
});

node.append("title")
.text(function(d) { return d.id; });

simulation
.nodes(graph.nodes)
.on("tick", ticked);

simulation.force("link")
.links(graph.links);

function ticked() {
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; });

node
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
}

function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}

function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}

function zoomed() {
svg.attr("transform", "translate(" + d3.event.transform.x + "," + d3.event.transform.y + ")" + " scale(" + d3.event.transform.k + ")");
}

我是 D3 的新手,如果能为我指明正确的方向,我将不胜感激。

最佳答案

箭头

要在行尾添加箭头,您需要使用 SVG 定义标记。只需稍作修改即可更新 d3 v3 代码以使用 v4 执行此操作。您提供的示例设置了三个箭头定义(每种类型的关系一个),但要创建一个箭头定义,您可以使用此:

svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 20)
.attr("refY", 0)
.attr("markerWidth", 8)
.attr("markerHeight", 8)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");

markerWidthmarkerHeightrefXrefY 的值很重要,决定了标记的位置- 不幸的是,我不知道它们如何与 viewBox 或圆半径相互作用,所以这些是通过反复试验选择的。

无需将标记捕获为变量,因为它将使用 URL 说明符进行引用,如下所示:

  var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke", function(d) { return color(d.type); })
.attr("marker-end", "url(#arrow)");

标签

同样,对 v3 代码稍作修改即可。文本标签需要单独附加到 SVG,而不是作为节点的子节点,并在 ticked 函数中独立翻译。

设置标签:

var text = svg.append("g").attr("class", "labels").selectAll("g")
.data(graph.nodes)
.enter().append("g");

text.append("text")
.attr("x", 14)
.attr("y", ".31em")
.style("font-family", "sans-serif")
.style("font-size", "0.7em")
.text(function(d) { return d.id; });

然后在力模拟开始时将它们平移到正确的位置:

  function ticked() {
// ...
text
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
}

水平偏移由设置标签时的 x 值定义(在本例中为 14)。

在一起

参见 this fiddle完整示例。

关于javascript - D3 4.0 有向边和标签的图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39439608/

25 4 0