javascript - d3 和弦 : center text on circle

标签 javascript d3.js chord-diagram

我使用Andrew的d3和弦图示例并希望将弯曲切片内的所有文本标签居中。我尝试了很多东西,但始终无法将文本居中。你知道需要什么巫师技巧吗?

enter image description here

var width = 720,
height = 720,
outerRadius = Math.min(width, height) / 2 - 10,
innerRadius = outerRadius - 24;

var formatPercent = d3.format(".1%");

var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);

var layout = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.ascending);

var path = d3.svg.chord()
.radius(innerRadius);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("id", "circle")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

svg.append("circle")
.attr("r", outerRadius);

d3.csv("ex_csv.csv", function(cities) {
d3.json("ex_json.json", function(matrix) {

// Compute the chord layout.
layout.matrix(matrix);

// Add a group per neighborhood.
var group = svg.selectAll(".group")
.data(layout.groups)
.enter().append("g")
.attr("class", "group")
.on("mouseover", mouseover);


// Add the group arc.
var groupPath = group.append("path")
.attr("id", function(d, i) { return "group" + i; })
.attr("d", arc)
.style("fill", function(d, i) { return cities[i].color; });

// Add a text label.
var groupText = group.append("text")
.attr("x", 6)
.attr("dy", 15);

groupText.append("textPath")
.attr("xlink:href", function(d, i) { return "#group" + i; })
.text(function(d, i) { return cities[i].name; });

// Remove the labels that don't fit. :(
groupText.filter(function(d, i) { return groupPath[0][i].getTotalLength() / 2 - 16 < this.getComputedTextLength(); })
.remove();

// Add the chords.
var chord = svg.selectAll(".chord")
.data(layout.chords)
.enter().append("path")
.attr("class", "chord")
.style("fill", function(d) { return cities[d.source.index].color; })
.attr("d", path);


}
});
});

</script>

最佳答案

顺便说一句,我建议升级到 v4,v2 的文档几乎不存在,而且很难提供帮助。

您可以同时设置 text-anchorstartOffset 属性来实现您要查找的内容。

首先,您需要将 text-anchor 设置为 middle,因为指定中间点比找到中间点并回头寻找更容易文本应该从哪里开始。

其次,您需要设置一个startOffset。请注意,如果您使用 50%,文本将不会出现在您想要的位置,因为文本路径的总长度是您要附加到的闭环(弦 anchor )的所有边。如果您没有不同的外半径和内半径,则将其设置为 25% 即可。但是,由于外半径比内半径大 24 像素,因此您可以尝试这样计算偏移文本中心所需的像素数:

groupText.append("textPath")
.attr("xlink:href", function(d, i) { return "#group" + i; })
.text(function(d, i) { return cities[i].name; })
.attr("startOffset",function(d,i) { return (groupPath[0][i].getTotalLength() - 48) / 4 })
.style("text-anchor","middle");

我减去 48,因为 anchor 的边各有 24 个像素(半径差)。我除以四是因为路径本身加倍。如果这是一条通用线,我会除以二。

这种方法有点简单,因为每个弦 anchor 的外周与内周不同,所以我有点偏离,但它应该是可行的。

对于即将显示的标签,这会很尴尬:内半径较短,因此确定字符串是否短到可以显示的公式可能是错误的 - 这可能会导致某些字符爬行在 anchor 的一侧(您的示例还有 16 个像素作为计算文本是否太长的半径差异,而不是 24 个像素)。

这是最终结果:

enter image description here

Here是一个示范。

关于javascript - d3 和弦 : center text on circle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44447188/

相关文章:

d3.js - 如何使用 d3 在散点图中绘制两个轴的正值和负值?

d3.js - 将模板添加到 D3

javascript - javascript 中回调的代码流程

d3.js - 在 d3.js 和弦图中旋转文本路径而没有通常的 svg :text

javascript - Jquery mobile - 如何防止可折叠的 div 在点击后展开?

javascript - Accordion 菜单 - 仅打开一项

javascript - AngularJS 传递变量的正确方法

javascript - Slick slider slickAdd 添加多个

javascript - 来自 mysql 表的简单 d3.js 关系图

javascript - 尝试 d3.js 和弦图 - 显示 TypeError : imports is undefined