2016-10-27 5 views
1

ここで見られるような選択回転を統合する必要があるd3 sunburstチャートを作成しています:http://bl.ocks.org/musically-ut/4678148選択歪み(部分的に選択されたパスのみにズーム)。私はjsFiddle:https://jsfiddle.net/h943x6yu/を作成しました。これは2つを組み合わせる試みを強調しています。このチャートは歪んで回転しますが、回転は予測できません。グラフ上の位置(最初のリンクのように)に関係なく、選択したパスを上の12時の位置に回転します。任意の提案をいただければ幸いです。d3サンバーストチャート選択回転が動作しない

d3.json("flare.json", function(error, root) { 
if (error) throw error; 

var g = svg.selectAll("g") 
    .data(partition.nodes(root)) 
    .enter().append("g"); 

path = g.append("path") 
    .attr("d", arc) 
    .style("fill", function(d) { return color((d.children ? d : d.parent).name); }) 
    .on("click", magnify) 
    // .on('mouseover', tip.show) 
    // .on('mouseout', tip.hide) 
    .each(stash); 

var text = g.append("text") 
    .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; }) 
    .attr("x", function(d) { return y(d.y); }) 
    .attr("dx", "6") // margin 
    .attr("dy", ".35em") // vertical-align 
    .text(function(d) { 
     return d.name; 
    }) 
.attr('font-size', function(d) { 
    if (d.value < 100000) { 
     return '10px' 
    } else { 
     return '20px'; 
    } 
}) 
.on("click", magnify); 

var innerG = d3.selectAll("g.inner"); 



// Distort the specified node to 80% of its parent. 
function magnify(node) { 
    text.transition().attr("opacity", 0); 
    spin(node); 

    if (parent = node.parent) { 
     var parent, 
      x = parent.x, 
      k = 0.8; 
     console.log(x) 
     parent.children.forEach(function(sibling) { 
      x += reposition(sibling, x, sibling === node 
       ? parent.dx * k/node.value 
       : parent.dx * (1 - k)/(parent.value - node.value)); 
     }); 
    } else { 
     reposition(node, 0, node.dx/node.value); 
    } 

    path.transition() 
    .duration(750) 
    .attrTween("d", arcTween) 
    .each("end", function(e, i) { 
     // check if the animated element's data e lies within the visible angle span given in node 
     if (e.x >= node.x && e.x < (node.x + node.dx)) { 
     // get a selection of the associated text element 
      var arcText = d3.select(this.parentNode).select("text"); 
     // fade in the text element and recalculate positions 
      arcText.transition().duration(750) 
      .attr("opacity", 1) 
      .attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" }) 
      .attr("x", function(d) { 
       return y(d.y); 
      }); 
     } 
    }); 

} 

function spin(d) { 
    var newAngle = - (d.x + d.dx/2); 

    innerG 
     .transition() 
     .duration(1500) 
     .attr("transform", "rotate(" + ((180/Math.PI * newAngle) - 90) + ")"); 

    path 
     .classed("selected", function (x) { return d.name == x.name; }); 
} 

// Recursively reposition the node at position x with scale k. 
function reposition(node, x, k) { 
    // console.log(node) 
    node.x = x; 
    if (node.children && (n = node.children.length)) { 
     var i = -1, n; 
     while (++i < n) x += reposition(node.children[i], x, k); 
    } 
    return node.dx = node.value * k; 
} 

// Stash the old values for transition. 
function stash(d) { 
    d.x0 = d.x; 
    d.dx0 = d.dx; 
} 

// Interpolate the arcs in data space. 
function arcTween(a) { 
    var i = d3.interpolate({x: a.x0, dx: a.dx0}, a); 
    return function(t) { 
     var b = i(t); 
     a.x0 = b.x; 
     a.dx0 = b.dx; 
     return arc(b); 
    }; 
}; 
}); 

答えて

0

よく分かりやすいように、私はそれを理解しました。これが最善の解決策であるかどうかは分かりませんが、うまくいきます。

私は同様に、xとy変数を設定:

var x = d3.scale.linear() 
    .range([0, 2 * Math.PI]); 

var y = d3.scale.linear() 
    .range([0, radius]); 

などのように、私は私の円弧を設定:

var arc = d3.svg.arc() 
    .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); }) 
    .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); }) 
    .innerRadius(function(d) { return Math.max(0, y(d.y)) }) 
    .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)) }) 
    .cornerRadius(function(d) { return 5;}); 

上記は私の元jsFiddle例でした。私の元のスピン関数は、(のonClick)と呼ばれていた

それはそうのように走った:

function spin(d) { 
     var newAngle = - (d.x + d.dx/2); 
     console.log('newAngle', newAngle) 

     innerG 
      .transition() 
      .duration(1500) 
      .attr("transform", "rotate(" + ((180/Math.PI * newAngle) - 90) + ")"); 


    path 
     .classed("selected", function (x) { return d.name == x.name; }); 
} 

これは私の予測不可能なスピンを与えていました。ちょっと手を加えた後、スピントランスフォームをx変数を使って実行すると、以前にインスタンス化されたスピンを2回クリックすると、毎回90度に修正されることに気付きました。この時点で、私は変換に-90を落としたとの約束を作成/ 2回それを実行するために機能:

function spin(d) { 

    var spin1 = new Promise (function(resolve, reject) { 
     var newAngle = - x(d.x + d.dx/2); 
     console.log('newAngle', newAngle) 

     innerG 
      .transition() 
      .duration(1500) 
      .attr("transform", "rotate(" + ((180/Math.PI * newAngle)) + ")"); 
      resolve("Success!"); 
    }); 

    spin1.then(function() { 
     var newerAngle = - x(d.x + d.dx/2); 
     console.log('newerAngle', newerAngle) 

     innerG 
      .transition() 
      .duration(1500) 
      .attr("transform", "rotate(" + ((180/Math.PI * newerAngle)) + ")"); 
    }) 

    path 
     .classed("selected", function (x) { return d.name == x.name; }); 
} 

これはおそらくビットhackieですが、非常によく動作します。最終結果をここに表示:https://jsfiddle.net/d28nw97x/1/

関連する問題