将文本附加到在D3js中围绕原点旋转的SVG“rect”

时间:2015-07-18 20:31:38

标签: javascript d3.js

我有一个大圆圈SVG元素和四个rect元素,它们围绕它的边缘正确旋转。我正在使用

.attr('transform', function(d, i) {return 'rotate(' + 40 + ((i+1)*30) + ', 110, 155)'; })

围绕原点旋转这些矩形,其中110和155是圆的中心坐标。

我想将文字添加到矩形的一侧,我不希望它们被旋转。通常我会做类似

的事情
svg.selectAll('text')
  .data(data)
  .enter()
  .append('text')

然后我将使用为文本的矩形指定的相同x和y坐标。但是,因为我正在为矩形使用变换旋转,所以我无法指定相同的xy属性。我希望文本看起来像这样:

enter image description here

矩形围绕原点旋转,但文本不是。我尝试使用each添加文本并将其显示在矩形旁边,但无济于事。

我做了codepen来演示。如何在不旋转的情况下将文本显示在矩形旁边?

2 个答案:

答案 0 :(得分:1)

您可以计算text s'基于您应用于rect的转换的坐标。这可以通过获取rect的{​​{3}}并将该矩阵应用到您希望文本定位的位置来轻松实现。如果您在同一元素上进行更复杂的转换或各种转换的组合,这也将起作用。

在您的codepen中,这可以编码为:

box.each(function(d) {
    // Create an invisible, virtual point for the calculation
    var p = svg.node().createSVGPoint();

    // Set the point's coordinates to this rect's coordinates
    p.x = this.x.animVal.value + boxWidth / 2;  // +offset for centering on box
    p.y = this.y.animVal.value - 15;            // -offset for positioning over box

    // Transform point based on this rect's transformation matrix
    p = p.matrixTransform(this.getCTM());       

    // Append text to svg at calculated position
    svg.append('text').text('hi').attr('x', p.x).attr('y', p.y).attr('fill', 'black');
});

请注意,这会将text附加到svg而不是rect,这是Lars Kotthoff已经注意到的不允许的<?php class Booking_Controller extends CI_Controller { public function __construct(){ parent::__construct(); $this->load->model('Books_model'); } public function view() { $data["result"]=$this->Books_model->get_restaurants(); //$this->load->helper(array('form','url')); not needed $this->load->view('restaurants/booking',$data["result"]); } } 。如果需要,您可能希望插入一些文本和框的分组,而不会危及此计算的基本思想。

检查更新的transformation matrix以获取基本工作示例。

答案 1 :(得分:0)

这样的东西?

var text = svg.selectAll('text')
  .data(data)
  .enter()
  .append("text")
  .text(function(d){
    return d;
  })
  .attr('fill', 'black')
  .attr('transform', function(d, i) {
    var a = (340 + (i*30)) * Math.PI/180;
    var x = 210 * Math.cos(a) + originX;
    var y = 210 * Math.sin(a) + originY;
    return 'translate('+x+','+y+')'; 
  });

示例here