Javascript D3.js围绕中点旋转轴标签

Javascript D3.js围绕中点旋转轴标签,javascript,d3.js,Javascript,D3.js,我现在正在使用D3.js,尽管我发现了非常相似的案例,但我并不能真正地将它们放在一起继续工作 我有一个类似于雷达图的东西,我想在我创建的每一个ax(轴的数量不是固定的,可以是4个,但也可以是40个)中添加文本,我已经有了,但是只要文本达到180度,实际上是0度,就可以围绕中心点旋转文本并将其旋转 结果应该如下所示: 我现在得到的是: 我只知道如何在弧内达到这一点,这也很好地显示了出来,但我并没有真正为我的案例找到答案 这是我的代码段,我在其中附加了以下文本条件: //Write criter

我现在正在使用D3.js,尽管我发现了非常相似的案例,但我并不能真正地将它们放在一起继续工作

我有一个类似于雷达图的东西,我想在我创建的每一个ax(轴的数量不是固定的,可以是4个,但也可以是40个)中添加文本,我已经有了,但是只要文本达到180度,实际上是0度,就可以围绕中心点旋转文本并将其旋转

结果应该如下所示:

我现在得到的是:

我只知道如何在
内达到这一点,这也很好地显示了出来,但我并没有真正为我的案例找到答案

这是我的代码段,我在其中附加了以下文本条件:

//Write criterias
      axis.append("text")
        .attr("class","labels")
        .attr("font-size","12px")
        .attr("font-family","Montserrat")
        .attr("text-anchor","middle") 
        .attr("fill","white")
        .attr("x",function (d, i) {
          return radius * Math.cos(angleSlice * i - Math.PI/2)*options.circles.labelFactor;
        })
        .attr("y",function (d, i) {
          return radius * Math.sin(angleSlice * i - Math.PI/2)*options.circles.labelFactor;
        })
        .text(function (d) {
          return d;
        });
编辑:

这是我的小提琴:


感谢您的建议

您可以使用类似的方法旋转所有标签。您可能需要根据您想要的方式调整定位和旋转角度

var angle = 180;

svg.selectAll(".labels")
   .attr("transform", "translate(300,0) rotate("+angle+")");

有些人发现旋转SVG元素很困难,因为
transform
属性的
rotate
函数会围绕原点(0,0)而不是围绕其中心旋转元素:

如果未提供可选参数和,则旋转将围绕当前用户坐标系的原点()

因此,一个简单的选择是删除文本的
x
y
属性,并使用
transform
对它们进行定位。这样,我们可以很容易地计算旋转:

.attr("transform", function(d, i) {
    var rotate = angleSlice * i > Math.PI / 2 ?
        (angleSlice * i * 180 / Math.PI) - 270 :
        (angleSlice * i * 180 / Math.PI) - 90;
    return "translate(" + radius * Math.cos(angleSlice * i - Math.PI / 2) * options.circles.labelFactor +
        "," + radius * Math.sin(angleSlice * i - Math.PI / 2) * options.circles.labelFactor +
        ") rotate(" + rotate + ")"
})
这是您的代码:

数据=[{
名称:“数据1”,
价值:22,
}, {
名称:“数据2”,
价值:50,
}, {
名称:'DATA3',
值:0,
}, {
名称:'DATA4',
数值:24,
}, {
名称:'DATA5',
价值:22,
}, {
名称:'DATA6',
数值:30,
}, {
名称:'DATA7',
价值:20,
}, {
名称:'DATA8',
价值:41,
}, {
名称:'DATA9',
价值:31,
}, {
名称:'DATA10',
数值:30,
}, {
名称:'DATA11',
数值:30,
}, {
名称:'DATA12',
数值:30,
}, {
名称:'DATA13',
数值:30,
}, {
名称:'DATA14',
数值:30,
}, ];
变量选项={
宽度:600,
身高:600,
利润:{
前100名,
右:100,,
底数:100,
左:100
},
圆圈:{
级别:6,
最大值:100,
labelFactor:1.15,
不透明度:0.2,
},
};
var allAxis=(data.map(函数(i,j)){
返回i.name
})),
总计=所有轴长度,
半径=数学最小值(options.width/2,options.height/2),
angleSlice=Math.PI*2/总计,
格式=d3.格式(“”);
var rScale=d3.scale.linear()
.domain([0,options.circles.maxValue])
.范围([50,半径]);
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,options.width+options.margins.left+options.margins.right)
.attr(“高度”,options.height+options.margins.top+options.margins.bottom);
var g=svg.append(“g”)
.attr(“transform”、“translate”(+(options.width/2+options.margins.left)+)、“+(options.height/2+options.margins.top)+”);
var axisGrid=g.append(“g”)
.attr(“类”、“axisWraper”);
变量轴=轴网格。选择全部(“.axis”)
.数据(allAxis)
.输入()
.附加(“g”)
.attr(“类”、“轴”)
//将它们添加到行中
轴。附加(“行”)
.attr(“x1”,0)
.attr(“y1”,0)
.attr(“x2”,函数(d,i){
var tempX2=半径*Math.cos(角度切片*i-Math.PI/2);
返回tempX2;
})
.attr(“y2”,函数(d,i){
var tempY=半径*Math.sin(angleSlice*i-Math.PI/2);
返回坦比;
})
.attr(“类”、“行”)
.attr(“笔划”、“黑色”)
.attr(“填充”、“无”);
//画背景圈
axisGrid.selectAll(“.levels”)
.数据([6,5,4,3,2,1])
.输入()
.附加(“圆圈”)
.attr(“类”、“网格圈”)
.attr(“r”,函数(d,i){
返回parseInt(半径/options.circles.levels*d,10);
})
.attr(“笔划”、“黑色”)
.attr(“填充不透明度”,选项。圆圈。不透明度);
//写入数据
axis.append(“文本”)
.attr(“类别”、“标签”)
.attr(“字体大小”,“12px”)
.attr(“字体系列”、“蒙特塞拉特”)
.attr(“文本锚定”、“中间”)
.attr(“填充”、“黑色”)
.attr(“转换”,函数(d,i){
var rotate=angleSlice*i>Math.PI?(angleSlice*i*180/Math.PI)-270:(angleSlice*i*180/Math.PI)-90;
返回“translate(“+radius*Math.cos(angleSlice*i-Math.PI/2)*options.circles.labelFactor+”,“+radius*Math.sin(angleSlice*i-Math.PI/2)*options.circles.labelFactor+”)rotate(“+rotate+”)
})
.文本(功能(d){
返回d;
});

就像Gerardo Furtado在他生活中提到的那样,如果你放弃
x
y
属性,而通过
变换
属性进行所有定位和旋转,你会变得更容易。然而,您可以让浏览器执行所有的三角运算,从而使他的方法更进一步。您所需要做的就是指定适当变换定义的列表

.attr("transform", function(d, i) {
  var angleI = angleSlice  * i * 180 / Math.PI - 90;   // the angle to rotate the label
  var distance = radius * options.circles.labelFactor; // the distance from the center
  var flip = angleI > 90 ? 180 : 0;                    // 180 if label needs to be flipped

  return "rotate(" + angleI + ") translate(" + distance + ")" + "rotate(" + flip + ")");
  //       ^1.^                    ^2.^                           ^3.^
})
如果省略和属性,它们将默认为
0
,这意味着文本都将从原点开始。从那里,只需应用三种变换即可轻松地将其移动和旋转到最终位置:

  • 根据文本在周长上的位置将其旋转到一定角度
  • 将旋转后的文本向外翻译到最终位置
  • 使用另一个
    旋转
    翻转圆圈左侧的文本
  • 请查看以下代码片段,以获得一个可用的演示:

    数据=[{
    名称:“数据1”,
    价值:22,
    },
    {
    名称:“数据2”,
    价值:50,
    },
    {
    名称:'DATA3',
    值:0,
    },
    {
    名称:'DATA4',
    数值:24,
    },
    {
    名称:'DATA5',
    价值:22,
    },
    {
    名称:'DATA6',
    数值:30,
    },
    {
    名称:'DATA7',
    价值:20,
    },
    {
    名称:'DATA8',
    价值:41,
    },
    {
    姓名:DA