Маркер анимации D3 по нескольким путям с группой гнезд d3 - PullRequest
0 голосов
/ 14 мая 2018

enter image description here Я работаю над проектом, чтобы иметь несколько путей, представляющих маршруты на карте.Я следую этому примеру с гнездом d3 , группирую свои данные по ключу, чтобы создать несколько маршрутов.

Я хотел бы анимировать элемент круга для перехода по каждому отдельному маршруту.Я вижу, что моя проблема очень похожа на этот пример и это решение , но я не понимаю, как применить решение к моему примеру.

Я не могу понять, как получить индекс / ключ моих групп в функцию createPathTween.Таким образом, у меня есть только один элемент круга в первой из моих групп, а не элемент круга, переходящий вдоль каждого маршрута / пути.Может кто-нибудь помочь мне разобраться, как разместить элемент переходного круга на каждом пути маршрута?

Это мой код d3

<html>
<head>
    <title>Hello</title>
    <script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>

    <style>

        }
        .placeVisited{
          fill:#999;
        }

        .journey{
          fill: none;
        }

    </style>
</head>
<body>

<script>

  var width = 1200;
  var height = 550;

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

  var g = svg.append( "g" );

  var projection = d3.geoMercator()
    .center([55, 12])
    .scale(220)
    .translate([width/2,height/2])

  var geoPath = d3.geoPath()
    .projection(projection);

  var voyageLine = d3.line()
    .x(function(d) { return projection([d.lon,d.lat])[0] ; })
    .y(function(d) { return projection([d.lon,d.lat])[1]; })
    .curve(d3.curveBasis);

  var parseDate = d3.timeParse("%d %B %Y");
  var parseYear = d3.timeParse("%Y");


  var color = d3.scaleOrdinal(d3.schemeCategory10);

d3.queue()
  .defer(d3.csv, "multipleVoyages2.csv")
    .await(ready);

function ready (error, data){

  data.forEach(function(d) {
    d.year = parseYear(d.year);
    d.lon= +d.lon;
    d.lat = +d.lat;
  });

var dataNest = d3.nest()
    .key(function(d){return d.VoyageID;})
    .entries(data);

var journey = g.selectAll(".journey")
    .data(dataNest)
    .enter()
    .append("path")
    .attr("class", "journey")
    .style("stroke", function(d) {
      return d.color = color(d.key); })
    .attr("d", function(d){
      return voyageLine(d.values);
    })
    .attr("stroke-dasharray", function() {
        var totalLength = this.getTotalLength();
        return totalLength + " " + totalLength;
            })
    .attr("stroke-dashoffset", function() {
        var totalLength = this.getTotalLength();
        return totalLength;
            })
    .transition()
    .ease(d3.easeLinear)
    .duration(5000)
    .attr("stroke-dashoffset", 0);


var marker = g.append("circle")
      .attr("r", 7)
      .style("fill", "pink")
      .attr("transform", "translate(-100,-100)")
        .transition()
        .ease(d3.easeLinear)
        .duration(5000)
        .attrTween("transform", createPathTween);


var placeGroups = g.selectAll(".placeVisited")
    .data(dataNest)
    .enter()
    .append( "g" )
    .attr("class","placeVisited");

var placeVisited = placeGroups.selectAll("placeVisited")
    .data(function(d){
    return d.values;
  })
    .enter()
    .append("circle")
    .attr("fill", function(d){
      return d.color = color(d.VoyageID);
    })
    .attr("cx", function(d, i) {
      return projection([d.lon, d.lat])[0];

    })
    .attr("cy", function(d, i) {
            return projection([d.lon, d.lat])[1];

    })
    .attr("r", 5)

//transitioning marker

//from this example -- http://fiddle.jshell.net/RnNsE/2/
function createPathTween(d, i, a) {
  // var path = this.parentNode.getElementsByTagName("journey")[0];
   var path = this.parentNode.getElementsByClassName("journey")[i]; //don't understand how to get the index for each group
    var l = path.getTotalLength();
    console.log("path");
    console.log(path);

    return function(t) {
        var p = path.getPointAtLength(t * l);
        return "translate(" + p.x + "," + p.y + ")";
      };

}
}
    </script>
</body>
</html>

и мой csv:

VoyageID,VoyageType,voyageName,ObjectID,arrivalDateTxt,year,ObjectNumber,placeName,lon,lat,url,,,
1,Pleasure cruise,Postcards home,170207,14 January 1906,1906,ANMS1113[006],Port Pirie,138.16,-33.183,http://collections.anmm.gov.au/en/objects/details/170207/,,,
1,Pleasure cruise,Postcards home,170205,1 May 1907,1907,ANMS1113[004],Mount Lofty Ranges,138.6,-34.933,http://collections.anmm.gov.au/en/objects/details/170205/,,,
1,Pleasure cruise,Postcards home,170216,26 October 1907,1907,ANMS1113[015],Brisbane,153,-27.5,http://collections.anmm.gov.au/en/objects/details/170216/,,,
1,Pleasure cruise,Postcards home,170200,4 November 1907,1907,ANMS1113[001],Adelaide,138.6,-34.933,http://collections.anmm.gov.au/en/objects/details/170200/,,,
1,Pleasure cruise,Postcards home,170213,26 November 1907,1907,ANMS1113[012],Fremantle,115.766,-32.5,http://collections.anmm.gov.au/en/objects/details/170213/,,,
1,Pleasure cruise,Postcards home,170209,3 December 1907,1907,ANMS1113[008],Adelaide,138.6,-34.933,http://collections.anmm.gov.au/en/objects/details/170209/,,,
1,Pleasure cruise,Postcards home,170212,10 December 1907,1907,ANMS1113[011],Melbourne,144.966,-37.75,http://collections.anmm.gov.au/en/objects/details/170212/,,,
1,Pleasure cruise,Postcards home,170217,20 December 1907,1907,ANMS1113[016],Sydney,151.166,-33.916,http://collections.anmm.gov.au/en/objects/details/170217/,,,
1,Pleasure cruise,Postcards home,170203,26 December 1907,1907,ANMS1113[002],Brisbane,153,-27.5,http://collections.anmm.gov.au/en/objects/details/170203/,,,
1,Pleasure cruise,Postcards home,170215,26 December 1907,1907,ANMS1113[014],Brisbane,153,-27.5,http://collections.anmm.gov.au/en/objects/details/170215/,,,
1,Pleasure cruise,Postcards home,170211,8 January 1908,1908,ANMS1113[010],Port Pirie,138.16,-33.183,http://collections.anmm.gov.au/en/objects/details/170211/,,,
1,Pleasure cruise,Postcards home,170208,14 January 1908,1908,ANMS1113[007],Port Pirie,138.16,-33.183,http://collections.anmm.gov.au/en/objects/details/170208/,,,
2,Kayak adventure,Oskar,1,1 March 1961,1961,,London,-0.127758,51.507351,,,,
2,Kayak adventure,Oskar,2,2 April 1961,1961,,Paris,2.352222,48.856614,,,,
2,Kayak adventure,Oskar,3,3 June 1961,1961,,Lyon,4.835659,45.764043,,,,
2,Kayak adventure,Oskar,4,28 June 1961,1961,,Calais,1.858686,50.95129,,,,
2,Kayak adventure,Oskar,5,10 July 1961,1961,,Frankfurt,8.682127,8.682127,,,,
2,Kayak adventure,Oskar,6,19 December 1961,1961,,Berlin,13.404954,52.520007,,,,
2,Kayak adventure,Oskar,7,25 January 1962,1962,,Amsterdam,4.895168,52.370216,,,,
2,Kayak adventure,Oskar,8,30 June 1962,1962,,rome,12.496366,41.902783,,,,
2,Kayak adventure,Oskar,9,24 November 1962,1962,,Milan,9.189982,45.464204,,,,
2,Kayak adventure,Oskar,10,19 January 1963,1963,,Turin,7.686856,45.070312,,,,
2,Kayak adventure,Oskar,11,27 January 1963,1963,,Florence,11.255814,43.76956,,,,
2,Kayak adventure,Oskar,12,30 April 1963,1963,,Vienna,16.373819,48.208174,,,,
3,Whaling ,Barque Terror,123,12 March 1845,1845,,Island 1,155.370833,-24.916667,,,,
3,Whaling ,Barque Terror,777,15 March 1845,1845,,Island 2,162.81738,-20.6739,,,,
3,Whaling ,Barque Terror,546,22 March 1845,1845,,Place in ocean 3,160.26464,-11.66325,,,,
3,Whaling ,Barque Terror,888,23 July 1845,1845,,Place in ocean 4,161.94638,-10.18388,,,,
3,Whaling ,Barque Terror,543,19 December 1845,1845,,Place in ocean 5,160.90712,-8.94461,,,,
3,Whaling ,Barque Terror,2134,22 January 1846,1846,,Place in ocean 6,158.74232,-9.01835,,,,
3,Whaling ,Barque Terror,6666,30 January 1846,1846,,Back home,157.26555,-8.19361,,,,

1 Ответ

0 голосов
/ 14 мая 2018

Вы можете получить paths для анимации после того, как закончите, используя функцию delay как для вашего path, так и для marker, например, так:

.duration(5000)
.delay(function(d, i) { // 'i' will give you the index
    return i * 5000; // Multiply by 5000 so that it starts after the previous one has finished.
});

и чтобы получить маркер circle для каждого path, вам необходимо создать такое же число circles, например:

var marker = g.selectAll('circle')
            .data(dataNest).enter()
            .append("circle")...

Также используйте d3.curveCatmullRom для лучшего path.

Вот такой поршень

...