2017-02-04 50 views
0

我已經在D3中使用隊列函數創建了一個使用下面的代碼讀取兩個json文件的地圖。第一個json文件是幫助生成Map的Topojson。第二個Json文件包含鼠標懸停在生成的Map上時需要顯示的文本。D3地圖應該讀取第二個外部json數據,使用隊列並在懸停上顯示

$(function() { 
// Assign Canvas size 
var margin = { top: 50, left: 50, right: 50, bottom: 50}, 
    height = 800 - margin.top - margin.bottom, 
    width = 800 - margin.left - margin.right; 

// add svg to Canvas 
var svg = d3.select("#map") 
    .append("svg") 
     .attr("viewBox", "0 0 " + width + " " + height) 
     .attr("preserveAspectRatio", "xMinYMin"); 

var tooltip = d3.select('body').append('div') 
    .attr('class', 'hidden tooltip'); 

// Read topojson and external data 
d3.queue() 
    .defer(d3.json, "tn_topojson.json") 
    .defer(d3.json, "tn_data.json") 
    .await(ready) 

// create a new projection using geoMercator and center it using 
// translate and zoom in a certain amount 
var projection = d3.geoMercator() 
    .translate([ -7880, 1500 ]) 
    .scale(6000) 

// create a path using geo path using the new projection 
var path = d3.geoPath() 
    .projection(projection) 

function ready (error, tn, data){ 
    console.log(tn); 
    console.log(data); 
    var constituency = topojson.feature(tn, tn.objects.collection).features; 
    console.log(constituency); 

    //add the path to the constituency 
    svg.selectAll(".constituency") 
     .data(constituency) 
     .enter().append("path") 
     .attr("class", "constituency") 
     .attr("d", path) 
     .attr('class', function(d){ 
        return "constituency " + "c" + d.properties.AC_NO 
       }) 
     .on('mouseover', function(d){ 
      d3.select(this).classed("selected", true) 
      var mouse = d3.mouse(svg.node()).map(function(d) { 
       return parseInt(d); 
      }); 
      tooltip.classed('hidden', false) 
       .attr('style', 'left:' + (mouse[0] + 15) + 
        'px; top:' + (mouse[1] + 30) + 'px') 
       .html(d.properties.AC_NAME) 
     }) 
     .on('mouseout', function(d){ 
      d3.select(this).classed("selected", false) 
     }) 

} 

}); 

Console.log函數顯示第二個json文件加載正常。但是如何從第二個json文件獲取數據以將其內容顯示到相應的路徑。

的topojson包含憲法ID和憲法名稱與acno數據的第二JSON文件

+0

你可以同時提供JSON樹的樣本?在輸入D3之前合併兩個jsons的另一種方法會更好嗎? – Sam0

+0

這些是我用於數據[tn_data.json](http://interactive.thehindu.com/libraries/tn_data.json),[tn_topojson.json](http://interactive.thehindu.com/)的文件libraries/tn_topojson.json)tn_data會動態生成單獨的,所以它不能被合併到同一個文件,如果有一種方法來組合它,一旦數據加載它可能工作 –

回答

0

創建一個對象(即哈希地圖)對應。然後做你的mouseover回調查找:

function ready(error, tn, data) { 

    // convert to object for easy lookup 
    var dataMap = {}; 
    data.forEach(function(d){ 
    dataMap[d.acno] = d; 
    }) 

    ... 

    .on('mouseover', function(d) { 
     d3.select(this).classed("selected", true) 
     var mouse = d3.mouse(svg.node()).map(function(d) { 
     return parseInt(d); 
     }); 

     var fd = dataMap[d.properties.AC_NO], 
      html = fd.constituency + "<br>" + fd.district; 

     ... 

完全跑步代碼:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
    <script src="https://d3js.org/topojson.v2.js"></script> 
 
    <style> 
 
    .selected { 
 
     fill: yellow; 
 
    } 
 
    .hidden { 
 
     display: none; 
 
    } 
 
    .tooltip { 
 
     position: absolute; 
 
     color: red; 
 
    } 
 
    </style> 
 
</head> 
 

 
<body> 
 

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

 
    <script> 
 
    // Assign Canvas size 
 
    var margin = { 
 
     top: 50, 
 
     left: 50, 
 
     right: 50, 
 
     bottom: 50 
 
     }, 
 
     height = 800 - margin.top - margin.bottom, 
 
     width = 800 - margin.left - margin.right; 
 

 
    // add svg to Canvas 
 
    var svg = d3.select("#map") 
 
     .append("svg") 
 
     .attr("viewBox", "0 0 " + width + " " + height) 
 
     .attr("preserveAspectRatio", "xMinYMin"); 
 

 
    var tooltip = d3.select('body').append('div') 
 
     .attr('class', 'hidden tooltip'); 
 

 
    // Read topojson and external data 
 
    d3.queue() 
 
     .defer(d3.json, "https://jsonblob.com/api/cb3b9a06-eae5-11e6-90ab-a963f5aa6b60") 
 
     .defer(d3.json, "https://jsonblob.com/api/b87933de-eae5-11e6-90ab-b9261b06ccd0") 
 
     .await(ready) 
 

 
    // create a new projection using geoMercator and center it using 
 
    // translate and zoom in a certain amount 
 
    var projection = d3.geoMercator() 
 
     .translate([-7880, 1500]) 
 
     .scale(6000) 
 

 
    // create a path using geo path using the new projection 
 
    var path = d3.geoPath() 
 
     .projection(projection) 
 

 
    function ready(error, tn, data) { 
 
     
 
     var dataMap = {}; 
 
     data.forEach(function(d){ 
 
     dataMap[d.acno] = d; 
 
     }) 
 

 
     var constituency = topojson.feature(tn, tn.objects.collection).features; 
 

 

 
     //add the path to the constituency 
 
     svg.selectAll(".constituency") 
 
     .data(constituency) 
 
     .enter().append("path") 
 
     .attr("class", "constituency") 
 
     .attr("d", path) 
 
     .attr('class', function(d) { 
 
      return "constituency " + "c" + d.properties.AC_NO 
 
     }) 
 
     .on('mouseover', function(d) { 
 
      d3.select(this).classed("selected", true) 
 
      var mouse = d3.mouse(svg.node()).map(function(d) { 
 
      return parseInt(d); 
 
      }); 
 
      
 
      var fd = dataMap[d.properties.AC_NO], 
 
       html = fd.constituency + "<br>" + fd.district; 
 
      
 
      tooltip.classed('hidden', false) 
 
      .attr('style', 'left:' + (mouse[0] + 15) + 
 
       'px; top:' + (mouse[1] + 30) + 'px') 
 
      .html(html) 
 
     }) 
 
     .on('mouseout', function(d) { 
 
      d3.select(this).classed("selected", false) 
 
     }) 
 

 
    } 
 
    </script> 
 
</body> 
 

 
</html>

+0

真棒感謝我所需要的... –