3

DataMapsを使用して世界地図を作成しました。

私の目的は、いくつかの API データに基づいて、マップ上でアークを非同期的に表示および非表示にすることです。


私はすでに何を試しましたか

API5 秒ごと に呼び出して、応答データをマップにプッシュします。(これは将来的に非同期呼び出しに置き換えられます)

以下の私の例では、は私の応答arcData arrayを表しています。API

経由でアークにアクセスできますDOM manipulation。私の場合、d3.selectAll('path.datamaps-arc').transition().duration(3500).style("opacity", 0);すべてのアークをゆっくりとフェードアウトさせ、後でそれらを削除するために使用しています。

var arcData = //Test Data
[
  {
    origin: 
    {
          latitude: 52.520008,
          longitude: 13.404954
    },
    destination: {
          latitude: 37.618889,
          longitude: -122.375
    }
 },
 {   origin: 
    {
          latitude: 52.520008,
          longitude: 13.404954
    },
    destination: {
          latitude: 25.793333,
          longitude:-80.290556
    }
 },
 {
    origin: 
    {
          latitude: 52.520008,
          longitude: 13.404954
    },
    destination: {
          latitude: 35.877778,
          longitude: -78.7875
    }
 }
];


$(document).ready(function() {
  var map = new Datamap({ //create data map
    element: document.getElementById('container'),
    fills: {
      defaultFill: "#343a40",
    }
  });
  
  //call API every 4 seconds [Workaround for this fiddle]  
  setInterval(function() {
    //add arcs to map
    map.arc(arcData, {strokeWidth: 2, animationSpeed: 1000, strokeColor: '#b1dd00'}); // add arc Data

    //Remove all arcs [should be replaced by a function that asynchronously hides single arcs after x seconds]
    d3.selectAll('path.datamaps-arc').transition().duration(3500).style("opacity", 0);
    d3.selectAll('path.datamaps-arc').transition().delay(3500).remove();
  }, 4000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script>
<script src="https://datamaps.github.io/scripts/datamaps.world.min.js"></script>
<div id="container" style="position: relative; width: 500px; height: 300px;"></div>


このソリューションは基本的に機能しますが、次の点に注意してください。

私の問題

すべての円弧が同時に非表示になります。今後APIを非同期で呼び出すと、アークが現在描画されているときに競合が発生し、その間に削除プロセスがトリガーされます。

私が欲しいもの

いくつかの識別子ですべてのアークにアクセスし、完全に描画された後に個別に削除できるソリューション。

4

2 に答える 2

1

さて、私はあなたの問題を解決しようとしました。私がしたことは、データマップの各アークに一意の ID を割り当てたことです。独立したアークに簡単にアクセスでき、それに応じて遷移を変更できます。

デモ目的で、ランダムに遅延させましたが、正常に動作します。最初のアークを 1000 ミリ秒遅らせ、2 番目のアークを 2000 ミリ秒、3 番目のアークを 3000 ミリ秒遅らせました。独自のアルゴリズムを実装して、アークの遷移を必要に応じて遅らせることができます。参照できるコードにコメントを追加しました。

setInterval は 4000 ミリ秒ごとに実行されるため、いずれかのアークの遅延が 4000 ミリ秒を超える場合、すべてのアークが同時に生成されるのを最初の 1 回だけ見ることができます。その後のアークの生成は非常にランダムになりますので、覚えておいてください。

var arcData = //Test Data
                [{
                        origin: {
                            latitude: 52.520008,
                            longitude: 13.404954
                        },
                        destination: {
                            latitude: 37.618889,
                            longitude: -122.375
                        }
                    },
                    {
                        origin: {
                            latitude: 52.520008,
                            longitude: 13.404954
                        },
                        destination: {
                            latitude: 25.793333,
                            longitude: -80.290556
                        }
                    },
                    {
                        origin: {
                            latitude: 52.520008,
                            longitude: 13.404954
                        },
                        destination: {
                            latitude: 35.877778,
                            longitude: -78.7875
                        }
                    }
                ];


            $(document).ready(function() {
                var map = new Datamap({ //create data map
                    element: document.getElementById('container'),
                    fills: {
                        defaultFill: "#343a40",
                    }
                });
                //hide arc function which will take x amount of delay and arc-id which you want to delay.
                function hideArc(delay, arcId) {
                    d3.select('#' + arcId).transition().duration(delay).style("opacity", 0);
                    d3.select('#' + arcId).transition().delay(delay).remove();
                }

                //call API every 4 seconds [Workaround for this fiddle]  
                setInterval(function() {
                    //add arcs to map
                    map.arc(arcData, {
                        strokeWidth: 2,
                        animationSpeed: 1000,
                        strokeColor: '#b1dd00'
                    }); // add arc Data
                    let arcIds = [];// it will hold all the unique arc-ids
                    d3.selectAll('path.datamaps-arc')[0].forEach((ele, index) => {
                        ele.setAttribute('id', 'datamap-arc-' + index);
                        arcIds.push('datamap-arc-' + index);// pushing new generated ids to arcIds array
                    });
                    //mapping of delay and arc-id, this part is replaceable, you can change it the way you want to change the delay of respective arc.   
                    let arcIdAndDelaymapping = arcIds.map((aercId, index) => {
                        return {
                            aercId,
                            delay:1000*(index+1)
                        }
                    })


                    //Remove all arcs [should be replaced by a function that asynchronously hides single arcs after x seconds]
                    //calling hideArc function with their respective delays.  
                    arcIdAndDelaymapping.forEach((arcMapping) => {
                        hideArc(arcMapping.delay, arcMapping.aercId);
                    })
                }, 4000);
            });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"></script>
<script src="https://datamaps.github.io/scripts/datamaps.world.min.js"></script>
<div id="container" style="position: relative; width: 500px; height: 300px;"></div>

うまくいけば、それはあなたの問題を解決します。ハッピーコーディング!! そして、データマップを探索させてくれてありがとう。

于 2019-04-01T11:17:01.280 に答える