2017-01-14 5 views
0

私はD3 Globeの実装を進めています。ユーザーがボタンをクリックしたときに地球にパスを追加しようとしていますが、これは成功しているとは言えません。一度にすべてのパスを追加しても問題はありませんが、トリガーイベント後に追加しようとすると失敗します。私のjsfiddle:http://jsfiddle.net/Guill84/b6xvj76e/1/。私はJSONに問題があるとは思わないが、期待通りにコンソールにポップアップする。D3 Globeへの新しいパスの追加

失敗したスクリプトのビットは、フィドルの一番下に表示されます。私は、参照を容易にするために以下に貼り付け:

$("#clickMe").click(function() { 
    data = { 
    "type": "FeatureCollection", 
    "features": [{ 
     "type": "Feature", 
     "properties": { 
     "name": "path1" 
     }, 
     "year": "2010", 
     "geometry": { 
     "type": "Polygon", 
     "coordinates": "[[[116.4551,40.2539],[117.5977,44.3408],[116.4551,40.2539]]]" 
     }, 
     "id": "RML" 
    }, 
    { 
     "type": "Feature", 
     "properties": { 
     "name": "path2" 
     }, 
     "year": "2010", 
     "geometry": { 
     "type": "Polygon", 
     "coordinates": "[[[116.4551,40.2539],[122.3438,41.0889],[116.4551,40.2539]]]" 
     }, 
     "id": "RML" 
    }, 
    { 
     "type": "Feature", 
     "properties": { 
     "name": "path3" 
     }, 
     "year": "2010", 
     "geometry": { 
     "type": "Polygon", 
     "coordinates": "[[[116.4551,40.2539],[105.9961,37.3096],[116.4551,40.2539]]]" 
     }, 
     "id": "RML" 
    }, 
    { 
     "type": "Feature", 
     "properties": { 
     "name": "path4" 
     }, 
     "year": "2010", 
     "geometry": { 
     "type": "Polygon", 
     "coordinates": "[[[116.4551,40.2539],[109.5996,35.6396],[116.4551,40.2539]]]" 
     }, 
     "id": "RML" 
    }]} 



    console.log(data); 
    var svg = d3.select("#body"); 


    flows = svg.selectAll("path") 
    .data(data) 
    .enter().append("svg:path") 
    .attr("d", clip) 
    .style("stroke", "black") 
    .attr("id", function(d) { 
     return d.properties.name.split(' ').join('_') 
    }); 


}); 

答えて

1

問題三次のとおり

1)あなたのJSON構造に問題がある:配列はによって使用されるとき、したがって、エラーを引き起こし、文字列形式で指定されclip機能。

2)data.featuresを作成する必要がある場合は、dataオブジェクトを直接バインドします。これは、作成する必要のある4つのパスを含む配列です。

3)選択すると、既存の国のパスが選択されます。これを避けるには、新しいパスにクラスを追加します。たとえば、それらをflowとして分類します。

4)フローパスは、レンダリング関数のスコープ内で宣言されているため、リフレッシュ機能では更新できません。

はここ3つの修正とあなたのコードです:

$("#clickMe").click(function() { 
    // 1) Arrays: Fixed arrays for coordinates so they are not serialized in a string 
    var data = { 
     "type": "FeatureCollection", 
     "features": [ 
      { 
       "type": "Feature", 
       "properties": { 
        "name": "path1" 
       }, 
       "year": "2010", 
       "geometry": { 
        "type": "Polygon", 
        "coordinates": [[[116.4551, 40.2539], [117.5977, 44.3408], [116.4551, 40.2539]]] 
       }, 
       "id": "RML" 
      }, 
      { 
       "type": "Feature", 
       "properties": { 
        "name": "path2" 
       }, 
       "year": "2010", 
       "geometry": { 
        "type": "Polygon", 
        "coordinates": [[[116.4551, 40.2539], [122.3438, 41.0889], [116.4551, 40.2539]]] 
       }, 
       "id": "RML" 
      }, 
      { 
       "type": "Feature", 
       "properties": { 
        "name": "path3" 
       }, 
       "year": "2010", 
       "geometry": { 
        "type": "Polygon", 
        "coordinates": [[[116.4551, 40.2539], [105.9961, 37.3096], [116.4551, 40.2539]]] 
       }, 
       "id": "RML" 
      }, 
      { 
       "type": "Feature", 
       "properties": { 
        "name": "path4" 
       }, 
       "year": "2010", 
       "geometry": { 
        "type": "Polygon", 
        "coordinates": [[[116.4551, 40.2539], [109.5996, 35.6396], [116.4551, 40.2539]]] 
       }, 
       "id": "RML" 
      } 
     ] 
    }; 

    console.log(data); 

    var svg = d3.select("#body"); 

    // 3) Selection: Add a class to avoid collision with existing paths 
    // 4) Using var declared outside so it can be used on the update function 
    flows = svg.selectAll("path.flow") 
     // 2) Data binding: Bind the features property instead, which is an array 
     .data(data.features); 

    // 3) Enter nodes: When appending them, class them as flow so they keep separated 
    flows.enter().append("svg:path") 
     .classed("flow", true) 
     .attr("d", clip) 
     .style("stroke", "black") 
     .style("stroke-width", "1px") 
     .attr("id", function (d) { 
      return d.properties.name.split(' ').join('_') 
     }); 
}); 

は、今では動作しますが、私はまだ地球上の追加のパスを参照することはできません。 UPDATE - -コメントに示されているように

、追加のパスが従わなかった

)は、path要素はあなたの最初の問題を解決した、しかし、svg要素のDOMに追加確かにあります地球の動きこれは、svgに追加されたパスのためでしたが、refresh()関数(ポイント4を追加)の国の図形に沿って更新されていませんでした。

これを行うには、refresh()関数内でこれらのパスを選択する必要があります(スクリプトの先頭にvar flowsを宣言すれば十分です)。このように:

function refresh(duration) { 
    (duration ? feature.transition().duration(duration) : feature).attr("d", clip); 
    // 4) Added the flows to the paths selection whose d attribute will be updated (only when present) 
    flows && (duration ? flows.transition().duration(duration) : flows).attr("d", clip); 
} 

完全なバージョンは、このフィドルで見ることができます:http://jsfiddle.net/oscar_dr/0psy5udk/2/

+0

オスカーは、あなたの入力のためにあなたを-thank。あなたの答えは90%です。パスは現在画面上に正しく表示されていますが、それらはsvgに正しく追加されていますが、ユーザーが地図を移動したりズームイン/ズームアウトしたりすると更新されません。これはあなたがそれらを参照するために別のクラスを使用したためでしょうか?ちなみに、私は 'フィーチャー'クラスを使っていて、正しく表示しています。彼らはちょうど周りに移動しないでください – Noobster

+0

ちなみに、それはおそらくあなたがそれらを見ていない...あなたが中国上にマウスを移動し、それらを追加すると、彼らは正しくsvgに追加されていることがわかります...彼らはちょうど失敗地球儀が動くように更新するには – Noobster

+1

なぜ私はそれらが更新されないのか知っていると思う:var 'svg'の初期化に従って'#body'要素に追加されます。おそらく 'g'要素を使ってすべての国のパスを追加し、' .flow'をこの要素に追加してください。私がコンピュータにアクセスすると、このメッセージがあまり意味を持たない場合に備えて、私の回答を更新します。 –

関連する問題