javascript - D3.js:放错位置的标签
问题描述
我是 d3.js 的新手,我正在尝试创建一个半圆环图并将标签放在每个弧的中间。
我用 CodeSandbox 做了一个开发人员,它工作得很好。标签放置正确,但是当我将该代码带到我的 Web 应用程序的代码时。代码完全相同。这些标签放错了位置,我不知道为什么:(
两个代码之间的唯一区别在于,第一个屏幕截图的代码位于 Bootstrap 的“Col”内,而第二个屏幕截图的代码与您在 CodeSandBox 中看到的不同。
在这里,您可以在我的 Web 应用程序中看到半圆环图的屏幕截图:
如您所见,当 CodeSandbox 中的相同代码正常工作时,每个拱门的标签和正确图例的标签都放错了位置,将所有标签放在正确的位置。正如您在此屏幕截图中看到的:
为什么会这样?我怎样才能使标签正确地放置在两个开发项目中?
你可以在这个 CodeSandoox 中看到我的半甜甜圈图的所有代码
编辑我:
我在我的代码中创建了一个跟踪,以了解取决于 Web 浏览器的值。
这是我将标签居中到弧线的代码:
//We center the text inside the arc
arcs
.append("svg:text")
.attr("transform", function(d) {
var textWidth = getTextWidth(
(d.value.toFixed(2) + "%").toString(),
"Roboto"
);
console.log(
"d.value: " +
d.value +
" textWidth: " +
textWidth +
" arc.centroid(d)[0]: " +
arc.centroid(d)[0]
);
return (
"translate(" +
(arc.centroid(d)[0] - textWidth) +
"," +
arc.centroid(d)[1] +
")"
);
})
.attr("class", "label-half-donut")
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
// are we past the center?
return (d.endAngle + d.startAngle) / 2 > Math.PI ? "end" : "start";
})
.text(function(d) {
return d.value.toFixed(2) + "%";
});
您可以在 CodeSandBox 按钮中找到所有代码。
CodeSandBox 的代码我用 Chrome 运行它,我得到了这个图形
Chrome 中返回的值是:
d.value: 13.13 textWidth: 33.916015625 arc.centroid(d)[0]: -86.00117936328948
构建弧的标签是这样的:
<g class="slice">
<path fill="#17A2B8" d="M-124.99275003141527,-1.3462687637091173A125,125,0,0,1,-116.9896333088247,-44.02755612416768L-47.07429579530035,-16.85261627690394A50,50,0,0,0,-49.98187231803007,-1.3462687637091153Z"></path>
<text transform="translate(-119.91719498828948,-16.12597743156403)" class="label-half-donut" dy=".35em" text-anchor="start">13.13%</text>
</g>
当我使用 Firefox 在我的网站上运行相同的代码时,我得到了这个图形:
返回的值为:
d.value: 13.13 textWidth: 38.150001525878906 arc.centroid(d)[0]: -86.00117936328948
构建弧的标签是:
<g class="slice">
<path fill="#17A2B8" d="M-124.99275003141527,-1.3462687637091173A125,125,0,0,1,-116.9896333088247,-44.02755612416768L-47.07429579530035,-16.85261627690394A50,50,0,0,0,-49.98187231803007,-1.3462687637091153Z"></path>
<text transform="translate(-124.15118088916839,-16.12597743156403)" class="label-half-donut" dy=".35em" text-anchor="start">13.13%</text>
</g>
两者的区别在于相同值“13.13”返回的textWidth返回不同的值,并且translate函数的x不同,因为是使用该值计算的。
这怎么可能?难道我做错了什么?
编辑二:
在@Coola 提出的解决方案之后。这适用于 Firefox,但不适用于 Chrome :(
火狐
铬合金
textWidth 的值仍然不同,具体取决于我使用的是 Firefox 还是 Chrome。
火狐
d.value: 13.13 textWidth: 38.150001525878906 arc.centroid(d)[0] -86.00117936328948
d.value: 59.7 textWidth: 38.150001525878906 arc.centroid(d)[0]: -33.49019847517988
d.value: 23.88 textWidth: 38.150001525878906 arc.centroid(d)[0]: 59.22461768695275
d.value: 17.91 textWidth: 38.150001525878906 arc.centroid(d)[0]: 84.79723004914864
铬合金
d.value: 13.13 textWidth: 33.916015625 arc.centroid(d)[0]: -86.00117936328948
d.value: 59.7 textWidth: 33.916015625 arc.centroid(d)[0]: -33.49019847517988
d.value: 23.88 textWidth: 33.916015625 arc.centroid(d)[0]: 59.22461768695275
d.value: 17.91 textWidth: 33.916015625 arc.centroid(d)[0]: 84.79723004914864
解决方案
您的文本翻译未正确计算。您x
对转换的价值应该是arc.centroid(d)[0] - textWidth / 2
.
所以你的变换应该是这样的:
.attr("transform", function(d) {
var textWidth = getTextWidth(
(d.value.toFixed(2) + "%").toString(),
"Roboto"
);
console.log(
"d.value: " +
d.value +
" textWidth: " +
textWidth +
" arc.centroid(d)[0]: " +
arc.centroid(d)[0]
);
let x = arc.centroid(d)[0] - textWidth / 2;
let y = arc.centroid(d)[1];
return "translate(" + x + "," + y + ")";
})
Firefox 开发者版 v75.0b:
更新
在与 OP 讨论后,他们的工作区仍然存在问题。我们进行了更多调查,发现问题是由 font-family 的继承样式引起的,而 font-family 的计算textWidth
正在完成Roboto
。.style("font-family", "'Roboto', sans-serif")
为了解决这个问题,我们添加了标签文本的样式。这解决了问题,工作代码框在这里。
推荐阅读
- python - 添加唯一整数
- javascript - 无法在highchart js上显示数据
- css - 更改 WooCommerce 计费字段的 css
- angular - 如何使用 my-date-picker 填充默认日期
- mercurial - 在 .hgignore 中包含相对路径
- javascript - freeCodeCamp 计数卡
- php - 使用 PHP - SQLSTATE [42000] 创建数据库表:语法错误或访问冲突:1064
- java - 从特定列excel apache poi启动表
- reactjs - 连接 API 时出现 REACT、NODE、EXPRESS 错误
- batch-file - taskkill 关闭窗口和 for 循环过早结束