You need to enable JavaScript to run this app. d3.js实现坐标轴与文本位置同步旋转、矩形保持不旋转问题求解
优惠活动
大模型
产品
解决方案
定价
更多

d3.js实现坐标轴与文本位置同步旋转、矩形保持不旋转问题求解

实现方案

要实现坐标轴旋转后矩形位置同步偏移但矩形本身不旋转,核心思路是手动计算每个刻度点旋转后的坐标,将矩形容器平移到该坐标,矩形内部相对容器定位,不做旋转处理即可。

核心改动说明

  • 统一管理旋转参数,提前将角度转为弧度并计算对应三角函数值
  • 通过二维旋转公式,以坐标轴的变换原点(0,5)为旋转中心,计算每个刻度点旋转后的坐标
  • 矩形、文本仅相对自身父容器定位,不需要加旋转属性,即可保持原有朝向

完整实现代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>
test()
function test() {
  var width = 800
  var height = 600
  var margin = 20
  // 统一配置旋转角度
  const rotateAngle = 30
  const rotateRad = rotateAngle * Math.PI / 180
  const cos = Math.cos(rotateRad)
  const sin = Math.sin(rotateRad)
  // 旋转原点和坐标轴保持一致
  const rotateOriginX = 0
  const rotateOriginY = 5

  var svg = d3.select('body').append('svg')
      .attr('width',width).attr('height',height)
      .style('border','1px solid red')

  var g = svg.append('g')
      .attr("transform", `translate(${margin}, ${margin})`)
  var data = [
      {pos:0,name:'A'},            
      {pos:2,name:'B'},      
      {pos:12,name:'C'},
      {pos:15,name:'D'},
      {pos:20,name:'E'},
      {pos:23,name:'F'},
      {pos:26,name:'G'},
  ];

  var xranges = data.map(function(d){
      return d.pos
  }) 
  
  var scalelinear = d3.scaleLinear()
      .domain([d3.min(xranges), d3.max(xranges)])
      .range([0, width-2*margin]);
  
  var scalepoint = d3.scalePoint()
      .domain(xranges)
      .range([0, width-2*margin]);

  var scale = scalepoint
  var x_axis = d3.axisTop()
      .scale(scale)
  
  g.append("g")
    .call(x_axis)
    .attr("transform", `translate(${rotateOriginX}, ${rotateOriginY}) rotate(${rotateAngle})`)
  var iw = 48
  var ih = 80

  var g1 = g.selectAll(null)
      .data(data).enter()
      .append('g')
      .attr("transform", d => {
        // 原始刻度坐标
        const originX = scale(d.pos)
        const originY = 0
        // 计算旋转后的坐标
        const relativeX = originX - rotateOriginX
        const relativeY = originY - rotateOriginY
        const rotatedX = rotateOriginX + relativeX * cos - relativeY * sin
        const rotatedY = rotateOriginY + relativeX * sin + relativeY * cos
        return `translate(${rotatedX}, ${rotatedY})`
      })
  
  g1.append('rect')
    .attr('x', -iw/2)
    .attr('y', 0)
    .attr('width', iw)
    .attr('height', ih)
    .attr('fill','none')
    .attr('stroke','black')

  g1.append('text')
    .attr('x', 0)
    .attr('y', ih/2)
    .text(d => d.name)
    .attr('text-anchor','middle')
    .attr('fill','none')
    .attr('stroke','black')
}

内容的提问来源于stack exchange,提问作者lucky1928

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 17:36:07