2014-07-24 61 views
1

D3和SVG的新问题,并且我正在越来越困惑为什么我的数学计算x,y坐标(围绕圆/钟面的SVG元素位置的计算)使用)旋转+电弧距离的角度...基本上:基于D3 + svg转换的旋转角度计算x/y坐标的混淆

  1. 我创建圆/钟面(包括翻译):

    var face = d3.select(".chart").append("g") 
        .attr("class", "clock-face") 
        .attr('transform','translate(' + width/2 + ',' + (circleRadius + margin) + ')'); 
    
  2. 我追加一个 “G” 元件(包含数据+一些视觉材料)到钟面&施加旋转到各个数据点容器(基于线性标尺定位一圈元素):

    var circleScale = d3.scale.linear() 
        .range([0, data.length]) 
        .domain([0, 60]); 
    
    // data container 
    var bar = face.selectAll('g') 
        .data(data) 
        .enter().append('g') 
        .attr('transform', function(d, i) { 
         return 'rotate(' + circleScale(i) + ')'; 
        }) 
        .each(function(d, i) { 
         // set theta 
         d.theta = circleScale(i); 
    }); 
    
  3. 我想能够计算我的个人数据点容器的x/y坐标基于它的THETA(旋转角)值:

    function calcPosition(centerX, centerY, radius, theta) { 
        var coords = {}; 
        var x = centerX + radius * Math.cos(theta); 
        var y = centerX + radius * Math.sin(theta); 
        coords.x = x; 
        coords.y = y; 
    
        return coords; 
    }; 
    
    var origin = calcPosition(0, 0, circleRadius, d.theta); 
    
    face.append('circle') 
        .attr('cx', origin.x) 
        .attr('cy', origin.y) 
        .attr('r', 5) 
        .attr('fill', 'yellow') 
    

然而,这将产生完全错误的x/y坐标。我相信我的trig在计算基于旋转角度的x/y坐标时是正确的,但是关于SVG转换的一些事情正在烦人......任何建议?

非常感谢!

+0

'theta'在_degrees_或_radians_中? –

+0

@PaulS。好问题...原来我有这样的圆比例:var circleScale = d3.scale.linear()。range([0,data.length])。domain([0,2 * Math.PI]); – vesperae

+0

但这样做会产生奇怪的结果(不正确地映射到360度)......但是由于某种原因,将圆圈标尺更改为以下工作方式......我发现这可能是我的错误点。但我很困惑D3尺度:var circleScale = d3.scale.linear()。range([0,data.length])。domain([0,60]); – vesperae

回答

1

在您的圆圈缩放中,看起来您在范围和域之间错误地进行了交换。 范围应该是[0,360][0,2*Math.PI]。请注意,您目前的状态为[0,60],而不是360,这可能是一个错误。 也许该域名应该变为[0,data.length] - 正如您目前的范围 - 但我不确定数据的性质以及是否有意义。我希望域名是[0,12],一天中的几小时。

至于你calcPosition三角函数的东西,theta必须弧度为它工作,这将表明您circleScale应该在[0,2*Math.PI]范围。但是,对于SVG转换,您需要使用度数。所以无论如何,您需要在其中一个实例中进行一些转换。此外,您在calcPosition中有一个错误,其中y应该基于centerY而不是centerX

最后,我建议先计算所有的d.theta,在一个简单的for循环中,而不是在渲染时在each函数中这样做。这主要是为了分离问题并避免错误(例如,如果在渲染条之前尝试访问d.theta,会发生什么情况?)。

+0

啊哈!这非常有意义......谢谢你! – vesperae