如何计算径向线上单个点的x和y坐标?

时间:2018-12-20 09:47:09

标签: d3.js

创建lineRadial时,如何获得线的各个点的xy坐标?

lineGenerator.angle()返回每个点的角度 lineGenerator.radius()返回每个点的半径

let width = 700;
let height = 500;

let svg = d3.select('svg')
  .attr('width', width)
  .attr('height', height);
  
let g = svg.append('g')
  .attr('transform', `translate(${width/2}, ${height/2})`);

let randomY = d3.randomNormal(0,4);
let data = d3.range(20).map( (el,i) => { return {x:i, y:randomY()}; });

let r = 200;


let startAngle = -90 * (Math.PI / 180); // convert deg to rad
let endAngle =  90 * (Math.PI / 180); // convert deg to rad
 
let x = d3.scaleLinear()
  .domain([ 0, 20 ])
  .range([ startAngle, endAngle ]);

let y = d3.scaleLinear()
  .domain([ 0,4 ])
  .range([r - 10, r]);
  
let line = d3.lineRadial()
  .angle( (d) => { return x(d.x); })
  .radius( (d) => { return y(d.y); });
  
g.append('path')
   .data([data])
   .attr('class', 'line')
   .attr('fill', 'none')
   .attr('stroke', 'blue')
   .attr('d', line);
   
g.selectAll('points')
   .data(data)
   .enter().append('circle')
   .attr('fill', 'none')
   .attr('stroke', 'black')
   .attr('cx', line.angle() )
   .attr('cy', line.radius() )
   .attr('r', 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<svg></svg>

1 个答案:

答案 0 :(得分:3)

一些三角函数...

let width = 700;
let height = 500;

let svg = d3.select('svg')
  .attr('width', width)
  .attr('height', height);
  
let g = svg.append('g')
  .attr('transform', `translate(${width/2}, ${height/2})`);

let randomY = d3.randomNormal(0,4);
let data = d3.range(20).map( (el,i) => { return {x:i, y:randomY()}; });

let r = 200;

let startAngle = -90 * (Math.PI / 180); // convert deg to rad
let endAngle =  90 * (Math.PI / 180); // convert deg to rad
 
let x = d3.scaleLinear()
  .domain([ 0, 20 ])
  .range([ startAngle, endAngle ]);

let y = d3.scaleLinear()
  .domain([ 0,4 ])
  .range([r - 10, r]);
  
let line = d3.lineRadial()
  // stash the angle and radius, while they are calculated
  // angle must be rotated...
  .angle( (d) => { d.a = x(d.x) - Math.PI/2; return x(d.x); })
  .radius( (d) => { d.r = y(d.y); return y(d.y); });
  
g.append('path')
   .data([data])
   .attr('class', 'line')
   .attr('fill', 'none')
   .attr('stroke', 'blue')
   .attr('d', line);
   
g.selectAll('points')
   .data(data)
   .enter().append('circle')
   .attr('fill', 'none')
   .attr('stroke', 'black')
   .attr('transform', function(d){
      // convert to cartesian
      let p = {
          x: (d.r * Math.cos(d.a)),
          y: (d.r * Math.sin(d.a))
      };
    return 'translate(' + p.x + ',' + p.y + ')';
   })
   .attr('r', 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<svg></svg>