2013-05-01 38 views
8

LIVE DEMOD3过渡和背部

所以我有这样的概念,即所有的单轴数据应该被允许显示在所有的基本途径;至少从馅饼到酒吧。理想情况下,这将是一个动画过渡,但那是困难进来。

获取饼图工作很容易,就像获取条形图一样。以下是我迄今为止:

# fields 
width = 750 
height = width/2 
margin = 20 
radius = (height-(margin*2))/2 

# helpers 
pie  = d3.layout.pie().value (d) -> d 
arc  = d3.svg.arc() 
    .outerRadius(radius) 
    .innerRadius(radius/4) 
x  = d3.scale.linear().domain([0, 100]).range [0, width] 

$http.get('/Classification_Top_10_by_Count.json').success (data) -> 

    percents = (parseFloat item.Percent for item in data).sort d3.ascending 

    svg  = d3.select('#svgStage').append('svg')   
     .attr('width', width+(margin*2)) 
     .attr('height', height+(margin*2)) 

    svg.data([percents]) 

    g = svg.append('g') 
     .attr('transform', "translate(#{radius},#{radius})") 

    paths = g.selectAll 'path' 

    paths.data(pie).enter().append('path') 
     .attr('d', arc) 

    toBars = -> 
     g.selectAll('path').transition().duration(2000) 
      .attr 'd', (d, index) -> 
       # this is over complex because I was playing with it. 
       cord = 
        tl : [0,   index*20] 
        tr : [d.value*20, index*20] 
        br : [d.value*20, index*20-20] 
        bl : [0,   index*20-20] 
       oCord = [ 
        cord.tl 
        cord.tr 
        cord.br 
        cord.bl 
       ] 
       "M #{oCord[0][0]}, #{oCord[0][2]} 
       A 0, 0 0 0, 0 #{oCord[1][0]}, #{oCord[1][3]} 
       L #{oCord[2][0]}, #{oCord[2][4]} 
       A 0, 0 0 0, 0 #{oCord[3][0]}, #{oCord[3][5]} 
       Z" 

显然,这个工作它必须是路径元素路径元素,现在的过渡工作。问题是它看起来像废话。它一开始就看起来乱码,直到它结束,并成为体面的条形图。

我一直在看这个:http://d3-example.herokuapp.com/examples/showreel/showreel.html 这演示了一个酒吧以我想要的方式过渡到甜甜圈。查看源代码,这是通过自定义补间完成的。 (查看源代码行518)

现在我在我的头上。这里发生了什么?我怎样才能使这个转换工作?有没有其他人处理这个问题?


UPDATE

只是要清楚,下面的插图我升技转型的意图更加清晰。

enter image description here


赏金清晰度。我为这个问题添加了一笔赏金,因为我需要解释发生了什么问题。 Superboggly做到了,所以他得到了赏金。然而阿米特·阿维夫的方法是优越的,所以我接受他的答案是最正确的。我也有+1。

+0

我只能看到在之前的HTML线660 ......我应该在看另一个文件呢? – 2013-05-02 02:45:49

+0

你是对的。它的518, – Fresheyeball 2013-05-02 17:32:40

+0

除了任何技术问题,你将如何从一个楔形动画到一个酒吧?因为甜甜圈“楔子”实际上只是弯曲的酒吧,所以您只需将它们弄平即可。楔子自然不适用于这种变换。如果你添加一个中间步馅饼 - >甜甜圈 - >酒吧它能帮助你达到你想要的效果吗? – 2013-05-03 11:57:17

回答

8

这是我的看法:http://jsfiddle.net/amitaviv99/x6RWs/42/

我的方法是既近似圆弧利用三次Bezier曲线&酒吧,有确切的相同数量的控制点。代码有点复杂,需要一些工作。但结果非常顺利。

下面是摘录(SO需要..)

var bezierArc = function(radiusIn, radiusOut, startAngle, endAngle){ 
    var arcIn = makeCompArc(radiusIn, startAngle, endAngle); 
    var arcIOut = makeCompArc(radiusOut, startAngle, endAngle); 
    var lines = makeBezierDoubleLine(radiusIn, radiusOut, startAngle, endAngle); 
    var path = [arcIn, lines[0], arcOut, lines[1]].join(' '); 

    return path; 
} 
+0

它看起来不错! – 2013-05-11 21:08:13

9

D3在路径之间进行内插很不错,但是它在路径前后遇到了问题,所以我不想接管整个补间过程,我想也许我们可以想出更好的路径来创建D3的工作更容易。我的result

第一件事是看看svg弧路径元素。它基本上是这样的:

A rx,ry a f1,f2 x,y 

您可以阅读详细信息here。这会从你所在的位置(前一个最终坐标)到坐标x,y绘制一条弧线。但需要注意的是,前两个数字是隐含的椭圆的半径,并且是结束坐标之前的最后一部分,我标记为f1,f2是标记,因此不是可插值的。

所以从您的代码的转变的主要的怪事是因为你想插

之间

一个RX,RY,0 0,1

一个0.0 0 0,

如果您在一种情况下将结束路径设置为A0,0 0 0,1,您将立即看到更平滑的过渡。

为了让这些部分更好地融合在一起,我为馅饼的内半径制作了一个动画,这样片段看起来更像棒但是弯曲,然后我让D3找出曲线到棒的转换,但不切换弧标志。然后你想要酒吧有平头。如果增加隐含的椭圆半径,路径将具有更平坦的弧度!所以我只用了100,100。我的最后过渡为条路径是这样的:

"M " + oCord[0][0] + "," + oCord[0][1] + 
"A100,100 0 0,1 " + oCord[1][0] + "," + oCord[1][1] + 
"L " + oCord[2][0] + "," + oCord[2][1] + 
"A100,100 0 0,0 " + oCord[3][0] + "," + oCord[3][1] + 
"Z"; 

再到实际,正确,拉平我有第二个过渡(串行它们运行)为零的路径的弧段的端点。我怀疑有一种更好的方法可以用D3转换进行这种清理,但是持续时间为0的转换也可以。

为了很好地工作,我将路径设置为从上方平展弧形曲线。具有较大的半径和正确的标志意味着D3计算的转换回甜甜圈图表效果良好。然后我简单地将内半径制作回来。

+0

您的解决方案效果很好。但是当我更新数组的值大的差距[2,3,24],例如,d3在转换期间吐出无效路径 - jsfiddle here:http://jsfiddle.net/geoe5sy7/1/。任何线索为什么D3不能顺利过渡?非常感谢! – 2015-05-25 14:29:58

+1

查看控制台输出我认为科学记数法让SVG很困惑。当你建立你的路径字符串时,请确保格式化数字,以便它们是常规的浮动。你正在得到非常小的数字,可能会被替换为0. – Superboggly 2015-05-28 01:27:43