更新D3JS中的文本标签

时间:2012-08-18 18:29:43

标签: javascript d3.js label force-layout

在过去的几天里,我一直在努力解决这个问题:我有一个强制导向图,标记它的边缘就像this example那样。我面临的问题是,当图表更新时(即:图表上的节点是在用户点击时添加的),它会更新图表,但它会留下我之前写过的旧边缘标签:

BEFORE&新图表出现后: BEFORE AFTER

如您所见,我的边缘标签在更新后闲置。我有一个函数,每当有新数据进入时调用,在这个函数中我有以下代码来绘制标签:

path_text = svg.selectAll(".path")
.data(force.links(), function(d){ return d.name;})
.enter().append("svg:g");
path_text.append("svg:text")
.attr("class","path-text")
.text(function(d) { return d.data.label; });

svg变量在顶级闭包中声明一次,如下所示:

var svg = d3.select("body").append("svg:svg")
        .attr("viewBox", "0 0 " + width + " " + height)
        .attr("preserveAspectRatio", "xMidYMid meet");

我的图表有一个tick()函数,可以计算每个标签的位置,如下所示:

function tick()
    {
            // Line label           
            path_text.attr("transform", function(d) 
            {
                var dx = (d.target.x - d.source.x),
                dy = (d.target.y - d.source.y);
                var dr = Math.sqrt(dx * dx + dy * dy);
                var sinus = dy/dr;
                var cosinus = dx/dr;
                var l = d.data.label.length * 6;
                var offset = (1 - (l / dr )) / 2;
                var x=(d.source.x + dx*offset);
                var y=(d.source.y + dy*offset);
                return "translate(" + x + "," + y + ") matrix("+cosinus+", "+sinus+", 

"+-sinus+", "+cosinus+", 0 , 0)";
                });
.
.
.

我已经尝试将此svg声明向下移动到更新函数中,以便每次更改图形时都会对其进行实例化。这实际上是有效的 - 但它完整地复制了整个图形。第一个原始副本仍保留旧标签 - 但第二个副本的行为正是我想要的。也许有一种方法,而不是附加svg,有一种替代方式吗?我也试过调用exit()。remove()而没有任何运气。

非常感谢你的时间。这一直是我应该如何做到的。

1 个答案:

答案 0 :(得分:1)

我将svg声明放在我的图形更新函数中,将它附加到div,并在再次附加之前清除div:

jQuery('#v').empty();
var svg = d3.select("#v").append("svg:svg")
.attr("viewBox", "0 0 " + width + " " + height)
.attr("preserveAspectRatio", "xMidYMid meet");

在我看来,这不是最干净的解决方案,但除非你们都有更好的解决方案,否则将采用这种解决方案!