D3.js 围绕中点旋转轴标签 [英] D3.js rotate axis labels around the middle point

查看:28
本文介绍了D3.js 围绕中点旋转轴标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在使用 D3.js,尽管我发现了非常相似的案例,但我真的无法将它们放在一起继续前进.

I am working with D3.js now and even though I found very similar cases I am not really able to put them together and move on.

我有一些类似于雷达图的东西,我想附加到我创建的每个轴(轴的数量不固定可能是 4,但也可以是 40)文本,我已经有了,但是围绕中心旋转文本一旦它们达到 180 度,实际上是 0 度,就指向并转动它们.

I have something similar as a radar chart and I would like to append to each ax I create (number of axes is not fixed could be 4, but also 40) text, which I already have, but rotate the text around center point and turn them as soon as they reach 180 degrees, actually 0 degrees.

结果应该是这样的:

我现在拥有的是:

我只知道如何在 arc 内达到它,这也很好地显示了 在这里,但我并没有真正弄清楚我的情况.

I only know how to reach this within arc, which is also nicely shown here, but I did not really figure it out for my case.

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

This is my code snippet, where I append those text criteria:

//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;
        });

这是我的小提琴:https://jsfiddle.net/fsb47ndf/

感谢您的建议

推荐答案

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

Some people find it difficult to rotate an SVG element, because the rotate function of the transform attribute rotates the element around the origin (0,0), not around its center:

如果可选参数未提供,则旋转关于当前用户坐标系的原点(来源)

If optional parameters and are not supplied, the rotate is about the origin of the current user coordinate system (source)

因此,一个简单的选择是删除文本的 xy 属性,并使用 transform 定位它们.这样,我们就可以轻松计算旋转:

Thus, an easy option is dropping the x and the y attributes of the texts, and positioning them using transform. That way, we can easily calculate the rotation:

.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 + ")"
})

这是您的代码:

data = [{
   name: 'DATA1',
   value: 22,
 }, {
   name: 'DATA2',
   value: 50,
 }, {
   name: 'DATA3',
   value: 0,
 }, {
   name: 'DATA4',
   value: 24,
 }, {
   name: 'DATA5',
   value: 22,
 }, {
   name: 'DATA6',
   value: 30,
 }, {
   name: 'DATA7',
   value: 20,
 }, {
   name: 'DATA8',
   value: 41,
 }, {
   name: 'DATA9',
   value: 31,
 }, {
   name: 'DATA10',
   value: 30,
 }, {
   name: 'DATA11',
   value: 30,
 }, {
   name: 'DATA12',
   value: 30,
 }, {
   name: 'DATA13',
   value: 30,
 }, {
   name: 'DATA14',
   value: 30,
 }, ];



 var options = {

   width: 600,
   height: 600,

   margins: {
     top: 100,
     right: 100,
     bottom: 100,
     left: 100
   },

   circles: {
     levels: 6,
     maxValue: 100,
     labelFactor: 1.15,
     opacity: 0.2,
   },

 };


 var allAxis = (data.map(function(i, j) {
     return i.name
   })),
   total = allAxis.length,
   radius = Math.min(options.width / 2, options.height / 2),
   angleSlice = Math.PI * 2 / total,
   Format = d3.format('');

 var rScale = d3.scale.linear()
   .domain([0, options.circles.maxValue])
   .range([50, radius]);

 var svg = d3.select("body").append("svg")
   .attr("width", options.width + options.margins.left + options.margins.right)
   .attr("height", 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("class", "axisWraper");

 var axis = axisGrid.selectAll(".axis")
   .data(allAxis)
   .enter()
   .append("g")
   .attr("class", "axis")

 //append them lines
 axis.append("line")
   .attr("x1", 0)
   .attr("y1", 0)
   .attr("x2", function(d, i) {
     var tempX2 = radius * Math.cos(angleSlice * i - Math.PI / 2);
     return tempX2;
   })
   .attr("y2", function(d, i) {
     var tempY = radius * Math.sin(angleSlice * i - Math.PI / 2);
     return tempY;
   })
   .attr("class", "line")
   .attr("stroke", "black")
   .attr("fill", "none");

 //Draw background circles
 axisGrid.selectAll(".levels")
   .data([6, 5, 4, 3, 2, 1])
   .enter()
   .append("circle")
   .attr("class", "gridCircle")
   .attr("r", function(d, i) {
     return parseInt(radius / options.circles.levels * d, 10);
   })
   .attr("stroke", "black")
   .attr("fill-opacity", options.circles.opacity);

 //Write data
 axis.append("text")
   .attr("class", "labels")
   .attr("font-size", "12px")
   .attr("font-family", "Montserrat")
   .attr("text-anchor", "middle")
   .attr("fill", "black")
   .attr("transform", function(d, i) {
     var rotate = angleSlice * i > Math.PI ? (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 + ")"
   })
   .text(function(d) {
     return d;
   });

<script src="https://d3js.org/d3.v3.min.js"></script>

这篇关于D3.js 围绕中点旋转轴标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆