2015-04-03 69 views
1

我有一个使用d3呈现的树形图。因为我想要快速响应并且经济(如果我真的不需要运行js),我使用div的百分比。但是过渡是使用百分比进行的某种有线连接。看完这个issue我已经尝试了几个styleTweens,但是我没有任何运气......d3使用styleTween百分比转换

如何在d3中使用百分比值的转换?

这里是下面的代码的小提琴:http://jsfiddle.net/0z7p68wb/(只需点击某处树状图中启动动画)

var target = d3.select("#target") 
render = function(data, oldData) { 
        // our custom d3 code 
        console.log("render!", data, oldData); 

        // draw rectangles 
        var margin = {margin: 0.2, padding: 2}, 
         width = 100 - margin.margin * 2, 
         height = 100 - margin.margin * 2; 

        var treemap = d3.layout.treemap() 
          .size([100, 100]) 
          //.sticky(true) 
          .value(function(d) { return d.size; }); 

        // bind data 
        var nodes = target.datum(data) 
         .selectAll(".node") 
         .data(treemap.nodes); 

        // transform existing nodes 
        if (data !== oldData) 
         nodes.transition() 
          .duration(1500) 
          .call(position); 

        // append new nodes 
        nodes.enter().append("div") 
         .attr("class", "node") 
         .style("position", "absolute") 
         .style("display", function(d,i) { return i==0 ? "none" : "block"}) 
         .style("background-color", "silver") 
         .call(position) 
         ; 


        // remove obsolete nodes 
        nodes.exit().remove(); 

        // set position of nodes 
        function position() { 
         this.style("left", function(d) { return d.x + "%"; }) 
          .style("top", function(d) { return d.y + "%"; }) 
          .style("width", function(d) { return Math.max(0, d.dx) + "%"; }) 
          .style("height", function(d) { return Math.max(0, d.dy) + "%"; }) 
        } 
       } 

tree1 = { 
      name: "tree", 
      children: [ 
       { name: "Word-wrapping comes for free in HTML", size: 16000 }, 
       { name: "animate makes things fun", size: 8000 }, 
       { name: "data data everywhere...", size: 5220 }, 
       { name: "display something beautiful", size: 3623 }, 
       { name: "flex your muscles", size: 984 }, 
       { name: "physics is religion", size: 6410 }, 
       { name: "query and you get the answer", size: 2124 } 
      ] 
     }; 

tree2 = { 
      name: "tree", 
      children: [ 
       { name: "Word-wrapping comes for free in HTML", size: 8000 }, 
       { name: "animate makes things fun", size: 10000 }, 
       { name: "data data everywhere...", size: 2220 }, 
       { name: "display something beautiful", size: 6623 }, 
       { name: "flex your muscles", size: 1984 }, 
       { name: "physics is religion", size: 3410 }, 
       { name: "query and you get the answer", size: 2124 } 
      ] 
     }; 

tree = tree1; 
render(tree, tree); 

d3.select("#target").on("click", function(){ 
    console.log("click"); 
    tree = tree == tree1 ? tree2 : tree1; 
    render(tree, {}); 
}); 

回答

2

明白了!

// transform existing nodes 
    if (data !== oldData) 
     nodes.transition() 
      .duration(1500) 
      .call(position) 
      .styleTween('left', function(d,i,a){ 
       return d3.interpolateString(this.style.left, d.x + "%") 
      }) 
      .styleTween('top', function(d,i,a){; 
       return d3.interpolateString(this.style.top, d.y + "%") 
      }) 
      .styleTween('width', function(d,i,a){; 
       return d3.interpolateString(this.style.width, Math.max(0, d.dx) + "%") 
      }) 
      .styleTween('height', function(d,i,a){; 
       return d3.interpolateString(this.style.height, Math.max(0, d.dy) + "%") 
      }) 
      ;