2016-06-08 94 views
0

嗨我想曲線的線,如在小提琴http://jsfiddle.net/nj37gkgq/給出。線是以座標形式具有源和目的地的鏈接的數組。該行在d3.geo地圖中連接兩個標記。我怎樣才能做到這一點?曲線d3線使用tweendash動畫

<!DOCTYPE html> 
<html lang='en'> 

<style type="text/css"> 



<body> 


<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> 
<script src="//d3js.org/topojson.v1.min.js"></script> 

<div id="map"></div> 

<script type="text/javascript"> 

    var width = 650, 
    height = 600; 

var projection = d3.geo.albersUsa() 
    .scale(2500) 
    .translate([1000, 360]); 


var path = d3.geo.path() 
    .projection(projection); 

var svg = d3.select("#map").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var coordinates = [ 
    [ -122.762, 40.801 ], 
    [ -117.0978, 34.1178] 
]; 


d3.json(url, function(ca) { 

     svg.append("path") 
      .datum(topojson.mesh(ca, ca.objects.subunits, function(a, b) { return a === b;})) 
      .attr("d", path); 

     //for stroke of lines 
     var gradient = svg.append("svg:defs") 
      .append("svg:linearGradient") 
      .attr("id", "gradient") 
      .attr("x1", "0%") 
      .attr("y1", "0%") 
      .attr("x2", "100%") 
      .attr("y2", "100%") 
      .attr("spreadMethod", "pad"); 

     gradient.append("svg:stop") 
      .attr("offset", "0%") 
      .attr("stop-color","darkblue") 
      .attr("stop-opacity", 1); 

     gradient.append("svg:stop") 
      .attr("offset", "100%") 
      .attr("stop-color","#85c1e9") 
      .attr("stop-opacity", 1); 

     var lF = d3.svg.line() 
         .interpolate("basis") 
         .x(function(d){ return d[0] }) 
         .y(function(d){ return d[1] }); 

     //update 
     var line = svg.append("path") 
      .datum(coordinates) 
      .attr("d", function(c){ 

       var d = { 
        source: projection(c[0]), 
        target: projection(c[1]) 
       }, 

        points = []; 

        points.push(d.source); 
        points.push([(d.target[0] + d.source[0]) * .4, d.target[1]]); 
        points.push([(d.target[0] + d.source[0]) * .8, d.source[1]]); 
        points.push(d.target); 
        console.log(points); 

        return lF(points); 
      }) 
      .attr("stroke-width", "2.5") 
      .attr("stroke-linejoin", "round") 
      .attr("stroke-linecap", "round") 
      .style("stroke", "url(#gradient)"); 

     anim(); 

     function anim() { 
      line.transition() 
       .duration(2000) 
       .attrTween("stroke-dasharray", function() { 
        var len = this.getTotalLength(); 
        return function(t) { 
         return (d3.interpolateString("0," + len, len + ",0"))(t) 
        }; 
       }) 
       .each('end', anim); 
     } 

}); 


</script> 

+0

不,我們正站在之前的位置......我認爲如果你能夠提出一個工作小提琴,那麼可能會更好,其他人也可以幫助你 – Cyril

+0

你將如何在兩點之間劃線?沒有一個d3'interpolate'擬合函數會「曲線化」......你只想要一個弧? – Mark

回答

1

EDITS瓦特/更好的Squiggle

對於更所有目的波浪曲線式,我認爲兩個相對的圓弧的中點看起來不錯(c爲[[x1,y1], [x2,y2]]陣列拉特):

function twoArc(c){ 
    var source = projection(c[0]), 
     target = projection(c[1]), 
     mid = [(source[0] + target[0])/2, (source[1] + target[1])/2], 
     dx1 = mid[0] - source[0], 
     dx2 = target[0] - mid[0], 
     dy1 = mid[1] - source[1], 
     dy2 = target[1] - mid[1], 
     dr1 = Math.sqrt(dx1 * dx1 + dy1 * dy1), 
     dr2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); 

     var rv = "M"; 
     rv += source[0] + "," + source[1]; 
     rv += "A" + dr1 + "," + dr1 + " 0 0,1 "; 
     rv += mid[0] + "," + mid[1]; 
     rv += "A" + dr2 + "," + dr2 + " 0 0,0 "; 
     rv += target[0] + "," + target[1]; 

     return rv; 
    } 

這裏是一個正在運行的例子有各種 「隨機」 座標:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 
    path { 
 
    fill: none; 
 
    stroke: #000; 
 
    stroke-linejoin: round; 
 
    stroke-linecap: round; 
 
    } 
 
</style> 
 

 
<body> 
 
    <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> 
 
    <script src="//d3js.org/topojson.v1.min.js"></script> 
 
    <script> 
 
    var width = 600, 
 
     height = 350; 
 

 
    var coordinates = [ 
 
     [-118, 34], 
 
     [-74, 40], 
 
     [-86.75, 33.57], 
 
     [-92.38, 35.22], 
 
     [-84.87, 34.53], 
 
     [-83.80, 41.60], 
 
     [-96.07, 33.07], 
 
     [-112.02, 41.18], 
 
     [-111.0, 41.33] 
 
    ]; 
 

 
    var projection = d3.geo.albersUsa() 
 
     .scale(700) 
 
     .translate([width/2, height/2]); 
 

 
    var path = d3.geo.path() 
 
     .projection(projection); 
 

 
    var svg = d3.select("body").append("svg") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) { 
 
     if (error) return console.error(error); 
 

 
     svg.append("path") 
 
     .datum(topojson.mesh(us)) 
 
     .attr("d", path); 
 

 
     var line = svg.append("path") 
 
     .datum(twoRand()) 
 
     .attr("d", twoArc) 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", 3) 
 
     .style("fill", "none"); 
 

 
     anim(); 
 
     
 
     function twoArc(c){ 
 
     var source = projection(c[0]), 
 
      target = projection(c[1]), 
 
      mid = [(source[0] + target[0])/2, (source[1] + target[1])/2], 
 
      dx1 = mid[0] - source[0], 
 
      dx2 = target[0] - mid[0], 
 
      dy1 = mid[1] - source[1], 
 
      dy2 = target[1] - mid[1], 
 
      dr1 = Math.sqrt(dx1 * dx1 + dy1 * dy1), 
 
      dr2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); 
 
      
 
      var rv = "M"; 
 
      rv += source[0] + "," + source[1]; 
 
      rv += "A" + dr1 + "," + dr1 + " 0 0,1 "; 
 
      rv += mid[0] + "," + mid[1]; 
 
      rv += "A" + dr2 + "," + dr2 + " 0 0,0 "; 
 
      rv += target[0] + "," + target[1]; 
 
      
 
      return rv; 
 
     } 
 
     
 
     function twoRand(){ 
 
     var i1 = Math.floor(Math.random() * coordinates.length), 
 
      i2 = Math.floor(Math.random() * coordinates.length); 
 
     return [coordinates[i1], coordinates[i2]]; 
 
     } 
 

 
     function anim() { 
 
     
 
     line.datum(twoRand()) 
 
      .attr("d", twoArc); 
 
     
 
     line.transition() 
 
      .duration(2000) 
 
      .attrTween("stroke-dasharray", function() { 
 
      var len = this.getTotalLength(); 
 
      return function(t) { 
 
       return (d3.interpolateString("0," + len, len + ",0"))(t) 
 
      }; 
 
      }) 
 
      .each('end', anim); 
 
     } 
 
    }); 
 
    </script>

EDITS與第一Squiggle的嘗試

下面是一個 「波浪」 行的例子。

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 
    path { 
 
    fill: none; 
 
    stroke: #000; 
 
    stroke-linejoin: round; 
 
    stroke-linecap: round; 
 
    } 
 
</style> 
 

 
<body> 
 
    <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> 
 
    <script src="//d3js.org/topojson.v1.min.js"></script> 
 
    <script> 
 
    var width = 600, 
 
     height = 350; 
 

 
    var coordinates = [ 
 
     [-118, 34], //start point 
 
     [-74, 40] //end point 
 
    ]; 
 

 
    var projection = d3.geo.albersUsa() 
 
     .scale(700) 
 
     .translate([width/2, height/2]); 
 

 
    var path = d3.geo.path() 
 
     .projection(projection); 
 

 
    var lF = d3.svg.line() 
 
     .interpolate("basis") 
 
     .x(function(d){ return d[0] }) 
 
     .y(function(d){ return d[1] }); 
 

 
    var svg = d3.select("body").append("svg") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) { 
 
     if (error) return console.error(error); 
 

 
     svg.append("path") 
 
     .datum(topojson.mesh(us)) 
 
     .attr("d", path); 
 

 
     var line = svg.append("path") 
 
     .datum(coordinates) 
 
     .attr("d", function(c) { 
 
      var d = { 
 
      source: projection(c[0]), 
 
      target: projection(c[1]) 
 
      }, 
 
      points = []; 
 

 
      points.push(d.source); 
 
      points.push([(d.target[0] - d.source[0]) * 0.4, d.target[1]]); 
 
      points.push([(d.target[0] - d.source[0]) * 0.8, d.source[1]]); 
 
      points.push(d.target); 
 
      
 
      return lF(points); 
 
     }) 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", 3) 
 
     .style("fill", "none"); 
 

 
     anim(); 
 

 
     function anim() { 
 
     line.transition() 
 
      .duration(2000) 
 
      .attrTween("stroke-dasharray", function() { 
 
      var len = this.getTotalLength(); 
 
      return function(t) { 
 
       return (d3.interpolateString("0," + len, len + ",0"))(t) 
 
      }; 
 
      }) 
 
      .each('end', anim); 
 
     } 
 
    }); 
 
    </script>


隨着單圓弧

編碼此之前我看到:我通過插入抖動點到一個數組,並使用d3線擬合插值生成它你的評論,但你似乎被困在不是破折號,但如何計算路徑。我看到知道你想要的曲線路徑,但這裏有一個圖(從洛杉磯到紐約州)的一個簡單的圓弧的例子:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 
    path { 
 
    fill: none; 
 
    stroke: #000; 
 
    stroke-linejoin: round; 
 
    stroke-linecap: round; 
 
    } 
 
</style> 
 

 
<body> 
 
    <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> 
 
    <script src="//d3js.org/topojson.v1.min.js"></script> 
 
    <script> 
 
    var width = 600, 
 
     height = 350; 
 

 
    var coordinates = [ 
 
     [-118, 34], //start point 
 
     [-74, 40] //end point 
 
    ]; 
 

 
    var projection = d3.geo.albersUsa() 
 
     .scale(700) 
 
     .translate([width/2, height/2]); 
 

 
    var path = d3.geo.path() 
 
     .projection(projection); 
 

 
    var svg = d3.select("body").append("svg") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    d3.json("https://rawgit.com/jgoodall/us-maps/master/topojson/state.json", function(error, us) { 
 
     if (error) return console.error(error); 
 

 
     svg.append("path") 
 
     .datum(topojson.mesh(us)) 
 
     .attr("d", path); 
 

 
     var line = svg.append("path") 
 
     .datum(coordinates) 
 
     .attr("d", function(c) { 
 
      var d = { 
 
      source: projection(c[0]), 
 
      target: projection(c[1]) 
 
      }; 
 
      var dx = d.target[0] - d.source[0], 
 
      dy = d.target[1] - d.source[1], 
 
      dr = Math.sqrt(dx * dx + dy * dy); 
 
      return "M" + d.source[0] + "," + d.source[1] + "A" + dr + "," + dr + 
 
      " 0 0,1 " + d.target[0] + "," + d.target[1]; 
 
     }) 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", 3) 
 
     .style("fill", "none"); 
 

 
     anim(); 
 

 
     function anim() { 
 
     line.transition() 
 
      .duration(2000) 
 
      .attrTween("stroke-dasharray", function() { 
 
      var len = this.getTotalLength(); 
 
      return function(t) { 
 
       return (d3.interpolateString("0," + len, len + ",0"))(t) 
 
      }; 
 
      }) 
 
      .each('end', anim); 
 
     } 
 
    }); 
 
    </script>

給我幾分鐘,都看到有關「蜿蜒」的路線。