2017-01-19 8 views
0

Arc Tweenデモの修正版であるビジュアルを作成しようとしています。その中で、各アークの色と一般的な半径を定義するためのデータの配列が必要です。区間では、開始角度と終了角度の両方がゆっくりとアニメートされます。しかし、私はそれぞれの弧を定義する方法は、物事をアニメーション化することを引き起こしていると思います。 SCRIPTアークの開始角度と終了角度をランダム化してアニメーション化する

// Modified from Arc Tween 
// https://bl.ocks.org/mbostock/5100636 

var tau = 2 * Math.PI; // http://tauday.com/tau-manifesto 
var overlap = 50 

var jsonArcs = [ 
    { "base_radius": 370, "color" : "red"}, 
    { "base_radius": 330, "color" : "orange"}, 
    { "base_radius": 290, "color" : "yellow"}, 
    { "base_radius": 250, "color" : "green"}, 
    { "base_radius": 210, "color" : "blue" }, 
    { "base_radius": 170, "color" : "purple"}, 
    { "base_radius": 130, "color" : "black"}, 
    { "base_radius": 90, "color" : "red"} 
]; 


var arc = d3.arc() 
    .startAngle(function(d) { return Math.random() * tau; }) 
    .endAngle(function(d) { return Math.random() * tau; }) 
    .innerRadius(function(d) { return d.base_radius - overlap * Math.random(); }) 
    .outerRadius(function(d) { return d.base_radius + overlap * Math.random(); }); 

var center_def = d3.arc() 
    .innerRadius(0) 
    .outerRadius(60) 
    .startAngle(0); 


var svg = d3.select("svg"), 
    width = +svg.attr("width"), 
    height = +svg.attr("height"), 
    g = svg.append("g").attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 

    var path = g.selectAll("path") 
     .data(jsonArcs) 
    .enter().append("path") 
     .attr("fill", function(d, i) { return d.color; }) 
     .attr("d", arc); 


var center = g.append("path") 
    .datum({endAngle: tau}) 
    .style("fill", "black") 
    .attr("d", center_def); 


d3.interval(function() { 

    path.transition() 
    .duration(750) 
    .attrTween("d", arcTween(Math.random() * tau, arc)); 
}, 2500); 

function arcTween(newAngle, obj) { 

    return function(d) { 

    var interpolate = d3.interpolate(d.endAngle, newAngle); 

    return function(t) { 

     d.endAngle = interpolate(t); 

     return obj(d); 
    }; 
    }; 
} 

代わりの各円弧が滑らかに新しい角度に開始角度からアニメーション

<!DOCTYPE html> 

<html> 
<head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width"> 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
    <title>Arcs</title> 
</head> 
<body> 
    <svg width="960" height="500"></svg> 
</body> 
</html> 

HTMLは、全体の視覚は、新しい状態に複数回ジャンプします。

どのようにして、各アークが開始角度と終了角度を古いものから新しいものにスムーズに移行するようにこの機能を設定しますか?

+0

関連:http://stackoverflow.com/questions/22792685/i-can-tween-a-d3-arcs-endangle-but-not-its-startangle-what-am-i-doing-wrong提供されたデータを使用して複数のアークを呼び出す方法がわからない –

答えて

2

いくつかの問題は、あなたのARC機能がランダム半径私はあなたが欲しいと思うものではありませんすべての呼び出しを返すために起こっている

  1. ここにあります。円弧を内側/外側の半径の1つから次の半径へと遷移させることができますが、簡単にするために、各パスが最初はランダムな半径を取得するだけです。

  2. 開始/終了角度の古いペアからあなたは現在の角度をどこかに保存する必要があります。 local variableに保存します。各パスに結び付けられます。

  3. 各パスの内外の半径が異なるため、各セグメントごとに異なる円弧関数を設定する必要があります。私はちょうど "の前にパス上の各呼び出しにランダムな初期角度を設定

    1. var tau = 2 * Math.PI; // http://tauday.com/tau-manifesto 
          var overlap = 50; 
          var currentSegment = d3.local(); 
          var segmentRadius = d3.local(); 
      
          var jsonArcs = [ 
           { "base_radius": 370, "color" : "red"}, 
           { "base_radius": 330, "color" : "orange"}, 
           { "base_radius": 290, "color" : "yellow"}, 
           { "base_radius": 250, "color" : "green"}, 
           { "base_radius": 210, "color" : "blue" }, 
           { "base_radius": 170, "color" : "purple"}, 
           { "base_radius": 130, "color" : "black"}, 
           { "base_radius": 90, "color" : "red"} 
          ]; 
      
          var arc = d3.arc() 
           .innerRadius(function() { return segmentRadius.get(this).innerRadius }) 
           .outerRadius(function() { return segmentRadius.get(this).outerRadius }); 
      
          var center_def = d3.arc() 
           .innerRadius(0) 
           .outerRadius(60) 
           .startAngle(0); 
      
          var svg = d3.select("svg"), 
           width = +svg.attr("width"), 
           height = +svg.attr("height"), 
           g = svg.append("g").attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 
      
          var path = g.selectAll("path") 
           .data(jsonArcs) 
           .enter().append("path") 
           .attr("fill", function(d, i) { return d.color; }) 
           .each(function(d) { 
            var angles = randomAngles(); 
            d.startAngle = angles.startAngle; 
            d.endAngle = angles.endAngle; 
            segmentRadius.set(this, { 
            innerRadius: d.base_radius - overlap * Math.random(), 
            outerRadius: d.base_radius + overlap * Math.random() 
            }); 
           }) 
           .attr("d", arc) 
           .each(function(d) {currentSegment.set(this, d)}); 
      
          var center = g.append("path") 
           .datum({endAngle: tau}) 
           .style("fill", "black") 
           .attr("d", center_def); 
      
          d3.interval(function() { 
           path.transition() 
            .duration(750) 
            .attrTween("d", arcTween); 
          }, 2500); 
      
          function arcTween() { 
           var thisPath = this; 
           var interpolate = d3.interpolate(currentSegment.get(this), randomAngles()); 
           currentSegment.set(this, interpolate(0)); 
      
           return function(t) { 
           return arc.call(thisPath, interpolate(t)); 
           }; 
          } 
          function randomAngles() { 
           var angles = [Math.random() * tau, Math.random() * tau].sort(); 
           return {startAngle: angles[0], endAngle: angles[1]}; 
          } 
      

      お知らせ変更されたコードについてのいくつかのこと:ここにコードを作業

    d "属性が設定されています

  4. segmentRadius d3.local変数に同じチェーンの最後にセグメント半径を格納しました。また、それぞれの補間が遷移
  5. 遷移関数では、パスの 'this'を保持するためにarcを呼び出す必要があったため、segmentRadiusを取得するときにarc.innerRadiusで 'this'が正しくなるようにする必要がありました。
  6. d3.interpolateは、数字だけでなくオブジェクトをうまく処理できます。

さらに詳しいことを知りたい場合は、hereに取り組んでいる同様の例があります。

+0

ありがとう!これは多くの意味があります。私は呼び出しごとに半径のランダム化に苦労していましたが、以前の状態を保存することは考えていませんでした。私はまた、 "それぞれの" –

関連する問題