gpt4 book ai didi

d3.js - 在 rect svg 中添加文本并将其附加到圆环图中的圆弧

转载 作者:行者123 更新时间:2023-12-04 04:05:24 27 4
gpt4 key购买 nike

我想为圆环图中的每条弧线添加标签。我通过获取每个弧的质心并添加来添加,但不知何故它没有添加到正确的位置。我无法弄清楚,所以我需要一些帮助。我已经在 codepen 中添加了我的代码。链接是here .我的 donut 应该是这样的。

image

示例代码是:

svg.selectAll(".dataText")
.data(data_ready)
.enter()
.each(function (d) {
var centroid = arc.centroid(d);
d3.select(this)
.append('rect')
.attr("class", "dataBG_" + d.data.value.label)
.attr('x', (centroid[0]) - 28)
.attr('y', (centroid[1]) - 5)
.attr('rx', '10px')
.attr('ry', '10px')
.attr("width", 50)
.attr("height", 20)
.style('fill', d.data.value.color)
.style("opacity", 1.0);
d3.select(this)
.append('text')
.attr("class", "dataText_" + d.data.value.label)
.style('fill', 'white')
.style("font-size", "11px")
.attr("dx", (centroid[0]) - 7)
.attr("dy", centroid[1] + 7)
.text(Math.round((d.data.value.value)) + "%");
});

提前致谢。

最佳答案

codepen 上的“坏”状态与理想状态之间的区别在于,在您不喜欢的状态中,您采用质心,然后将文本置于其中心。粗圆弧的质心是从一个线段帽的中点到另一个的圆弧的中点。如果它有一些有限的厚度并且是一个物理对象,这大致是形状的“质心”。我不认为这是你想要的。你想要的是外弧的中点。没有生成它的函数,但计算起来很容易。此外,我认为您希望为文本 anchor 位于图表左侧的弧与图表右半部分的弧以不同的方式证明文本。我将复制您的代码并对其进行修改,并附上注释解释。

// for some reason I couldn't get Math.Pi to work in d3.js, so
// I'm just going to calculate it once here in the one-shot setup
var piValue = Math.acos(-1);
// also, I'm noting the inner radius here and calculating the
// the outer radius (this is similar to what you do in codepen.)
var innerRadius = 40
var thickness = 30
var outerRadius = innerRadius + thickness

svg.selectAll(".dataText")
.data(data_ready)
.enter()
.each(function (d) {
// I'm renaming "centroid" to "anchor - just a
// point that relates to where you want to put
// the label, regardless of what it means geometrically.

// no more call to arc.centroid
// var centroid = arc.centroid(d);

// calculate the angle halfway between startAngle and
// endAngle. We can just average them because the convention
// seems to be that angles always increase, even if you
// if you pass the 2*pi/0 angle, and that endAngle
// is always greater than startAngle. I subtract piValue
// before dividing by 2 because in "real" trigonometry, the
// convention is that a ray that points in the 0 valued
// angles are measured against the positive x-axis, which
// is angle 0. In D3.pie conventions, the 0-angle points upward
// along the y-axis. Subtracting pi/2 to all angles before
// doing any trigonometry fixes that, because x and y
// are handled normally.

var bisectAngle = (d.startAngle + d.endAngle - piValue) / 2.0
var anchor = [ outerRadius * Math.cos(bisectAngle), outerRadius * Math.sin(bisectAngle) ];

d3.select(this)
.append('rect')
.attr("class", "dataBG_" + d.data.value.label)

// now if you stopped and didn't change anything more, you'd
// have something kind of close to what you want, but to get
// it closer, you want the labels to "swing out" from the
// from the circle - to the left on the left half of the
// the chart and to the right on the right half. So, I'm
// replacing your code with fixed offsets to code that is
// sensitive to which side we're on. You probably also want
// to replace the constants with something related to the
// the dynamic size of the label background, but I leave
// that as an "exercise for the reader".

// .attr('x', anchor[0] - 28)
// .attr('y', anchor[1] - 5)

.attr('x', anchor[0] < 0 ? anchor[0] - 48 : anchor[0] - 2)
.attr('y', anchor[1] - 10

.attr('rx', '10px')
.attr('ry', '10px')
.attr("width", 50)
.attr("height", 20)
.style('fill', d.data.value.color)
.style("opacity", 1.0);
d3.select(this)
.append('text')
.attr("class", "dataText_" + d.data.value.label)
.style('fill', 'white')
.style("font-size", "11px")

// changing the text centering code to match the box
// box-centering code above. Again, rather than constants,
// you're probably going to want something a that
// that adjusts to the size of the background box

// .attr("dx", anchor[0] - 7)
// .attr("dy", anchor[1] + 7)

.attr("dx", anchor[0] < 0 ? anchor[0] - 28 : anchor[0] + 14)
.attr("dy", anchor[1] + 4)
.text(Math.round((d.data.value.value)) + "%");
});

我测试过。您的代码笔示例中的此代码。如果我影响了您对每个人的示例,我深表歉意 - 我不熟悉 codepen,也不知道协作规则。这只是建议,通过一些调整可以提高效率,但我想保持平行以明确我要更改的内容和原因。希望这能给您一些好的想法。

关于d3.js - 在 rect svg 中添加文本并将其附加到圆环图中的圆弧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62592698/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com