在D3力导向图中添加链接标签

5
我已经创建了一个力导向图,但是我无法在创建的链接中添加文本。
我该怎么做?
以下是我的代码 link 我使用以下行来附加链接标题,但它没有显示。
link.append("title")
  .text(function (d) {
     return d.value;
   });

我在这个问题上做错了什么?

1
你想给链接添加标签还是工具提示?从代码看,它似乎是工具提示,但从文本看似乎是标签... - VividD
这个问题可能会有所帮助:https://dev59.com/L2oy5IYBdhLWcg3wQ78F - Lars Kotthoff
1
我已经完成了答案,并附加了一些额外的信息,希望这对您解决问题有所帮助! - VividD
@VividD 谢谢。实际上我正在尝试在我的代码中实现它。 - analyticalpicasso
我附上了链接和工作示例的说明(修改了您在上面评论中的最后一个链接的示例)。 :) 希望这对您有用! - VividD
显示剩余5条评论
1个回答

11

这个链接 包含了您所需要的解决方案。

enter image description here

关键点在于 "title" 属性可以添加工具提示。对于标签,您需要提供略微复杂一些(但不要过于复杂)的代码,比如上面链接示例中的代码:

// Append text to Link edges
var linkText = svgCanvas.selectAll(".gLink")
    .data(force.links())
    .append("text")
    .attr("font-family", "Arial, Helvetica, sans-serif")
    .attr("x", function(d) {
        if (d.target.x > d.source.x) {
            return (d.source.x + (d.target.x - d.source.x)/2); }
        else {
            return (d.target.x + (d.source.x - d.target.x)/2); }
    })
    .attr("y", function(d) {
        if (d.target.y > d.source.y) {
            return (d.source.y + (d.target.y - d.source.y)/2); }
        else {
            return (d.target.y + (d.source.y - d.target.y)/2); }
    })
    .attr("fill", "Black")
    .style("font", "normal 12px Arial")
    .attr("dy", ".35em")
    .text(function(d) { return d.linkName; });

代码的思路很简单:计算链接的中点,并在该位置显示一些文本(您可以决定实际上显示什么文本)。还有一些额外的计算和条件,您可以从代码中弄清楚,但是根据您的需求和美学,您肯定需要对它们进行更改。

编辑:这里重要的提示是,“gLink”是链接的类名,先前使用此代码进行定义:

// Draw lines for Links between Nodes
var link = svgCanvas.selectAll(".gLink")
    .data(force.links())

在你的示例中,可能会有所不同,需要调整代码。



以下是如何将上面示例的解决方案合并到另一个没有链接标签的力导向布局示例中的指南:

SVG对象组织和数据绑定

在D3力导向布局中,布局必须提供节点和链接数组,并且必须调用force.start()。之后,可以根据要求和设计创建视觉元素。在我们的情况下,以下代码为每个链接初始化SVG“g”元素。这个“g”元素应该包含一个可视化表示链接的线和对应于该链接的文本。

force
    .nodes(graph.nodes)
    .links(graph.links)
    .start();

var link = svg.selectAll(".link")
    .data(graph.links)
   .enter()
    .append("g")
    .attr("class", "link")
    .append("line")
    .attr("class", "link-line")
    .style("stroke-width", function (d) {
        return Math.sqrt(d.value);
    });

var linkText = svg.selectAll(".link")
    .append("text")
    .attr("class", "link-label")
   .attr("font-family", "Arial, Helvetica, sans-serif")
    .attr("fill", "Black")
    .style("font", "normal 12px Arial")
    .attr("dy", ".35em")
    .attr("text-anchor", "middle")
    .text(function(d) {
        return d.value;
    });

"g"元素具有"class"为"link",线条具有"class"为"link-line",广告标签具有"class"为"link-label"。这是为了方便地选择"g"元素,并且可以通过类别"link-line"和"link-label"来方便地在CSS文件中设置线条和标签的样式(尽管在本例中没有使用此样式)。

由于位置的初始化将在动画过程中更新,因此此处不进行线条和文本位置的初始化。

力导向动画

为了使动画可见,“tick”函数必须包含确定线条和文本位置的代码:

    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; });

    linkText
        .attr("x", function(d) {
            return ((d.source.x + d.target.x)/2);
        })
        .attr("y", function(d) {
            return ((d.source.y + d.target.y)/2);
        });

这里是结果示例:plunker

enter image description here


太好了,解释的非常好。有些东西我以前不是很明白,现在我可以跟着做研发了。非常感谢! - analyticalpicasso
1
.attr("x", function(d) { if (d.target.x > d.source.x) { return (d.source.x + (d.target.x - d.source.x)/2); } else { return (d.target.x + (d.source.x - d.target.x)/2); } }) .attr("y", function(d) { if (d.target.y > d.source.y) { return (d.source.y + (d.target.y - d.source.y)/2); } else { return (d.target.y + (d.source.y - d.target.y)/2); } })这里返回了NaN。该怎么办? - PRANSHU MIDHA
非常好的例子,非常感谢。在 Plunker 的例子中,我如何为每个节点添加标签(而不是悬停)? - Vincent Diallo-Nort

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接