D3 跳过 TopoJson 中的前两个功能

D3 skipping first two features in a TopoJson

我正在使用 D3 创建交互式可视化工具。我今天刚开始使用我的地图,我注意到 topojson 的前两个功能没有加载。

topojson 的前两个条目如下所示,geojson.io 可以很好地读取这些国家/地区。 (他们出现在地图上)

 "objects":{"ne_10m_admin_0_countries":{"type":"GeometryCollection","geometries":[{"arcs":[[[0,1]],[[2,3,4,5]],[[6,7]],[[8,9]],[[10]],[[11]],[[12]],[[13]],[[14]],[[15]],[[16]],[[17]],[[18]],[[19]],[[20]],[[21]],[[22]],[[23]],[[24]],[[25]],[[26]],[[27]],[[28]],[[29]],[[30]],[[31]],[[32]],[[33]],[[34]],[[35]],[[36]],[[37]],[[38]],[[39]],[[40]],[[41]],[[42]],[[43]],[[44]],[[45]],[[46]],[[47]],[[48]],[[49]],[[50]],[[51]],[[52]],[[53]],[[54]],[[55]],[[56]],[[57]],[[58]],[[59]],[[60]],[[61]],[[62]],[[63]],[[64]],[[65]],[[66]],[[67]],[[68]],[[69]],[[70]],[[71]],[[72]],[[73]],[[74]],[[75]],[[76]],[[77]],[[78]],[[79]],[[80]],[[81]],[[82]],[[83]],[[84]],[[85]],[[86]],[[87]],[[88]],[[89]],[[90]],[[91]],[[92]],[[93]],[[94]],[[95]],[[96]],[[97]],[[98]],[[99]],[[100]],[[101]],[[102]],[[103]],[[104]],[[105]],[[106]],[[107]],[[108]],[[109]],[[110]],[[111]],[[112]],[[113]],[[114]],[[115]],[[116]],[[117]],[[118]],[[119]],[[120]],[[121]],[[122]],[[123]],[[124]],[[125]],[[126]],[[127]],[[128]],[[129]],[[130]],[[131]]],"type":"MultiPolygon","properties":{"featurecla":"Admin-0 country","scalerank":5,"LABELRANK":2,"SOVEREIGNT":"Indonesia","SOV_A3":"IDN","ADM0_DIF":0,"LEVEL":2,"TYPE":"Sovereign country","ADMIN":"Indonesia","ADM0_A3":"IDN","GEOU_DIF":0,"GEOUNIT":"Indonesia","GU_A3":"IDN","SU_DIF":0,"SUBUNIT":"Indonesia","SU_A3":"IDN","BRK_DIFF":0,"NAME":"Indonesia","NAME_LONG":"Indonesia","BRK_A3":"IDN","BRK_NAME":"Indonesia","BRK_GROUP":"","ABBREV":"Indo.","POSTAL":"INDO","FORMAL_EN":"Republic of Indonesia","FORMAL_FR":"","NAME_CIAWF":"Indonesia","NOTE_ADM0":"","NOTE_BRK":"","NAME_SORT":"Indonesia","NAME_ALT":"","MAPCOLOR7":6,"MAPCOLOR8":6,"MAPCOLOR9":6,"MAPCOLOR13":11,"POP_EST":260580739,"POP_RANK":17,"GDP_MD_EST":3028000,"POP_YEAR":2017,"LASTCENSUS":2010,"GDP_YEAR":2016,"ECONOMY":"4. Emerging region: MIKT","INCOME_GRP":"4. Lower middle income","WIKIPEDIA":-99,"FIPS_10_":"ID","ISO_A2":"ID","ISO_A3":"IDN","ISO_A3_EH":"IDN","ISO_N3":"360","UN_A3":"360","WB_A2":"ID","WB_A3":"IDN","WOE_ID":23424846,"WOE_ID_EH":23424846,"WOE_NOTE":"Exact WOE match as country","ADM0_A3_IS":"IDN","ADM0_A3_US":"IDN","ADM0_A3_UN":-99,"ADM0_A3_WB":-99,"CONTINENT":"Asia","REGION_UN":"Asia","SUBREGION":"South-Eastern Asia","REGION_WB":"East Asia & Pacific","NAME_LEN":9,"LONG_LEN":9,"ABBREV_LEN":5,"TINY":-99,"HOMEPART":1,"MIN_ZOOM":0,"MIN_LABEL":1.7,"MAX_LABEL":6.7,"NE_ID":1159320845,"WIKIDATAID":"Q252","NAME_AR":"إندونيسيا","NAME_BN":"ইন্দোনেশিয়া","NAME_DE":"Indonesien","NAME_EN":"Indonesia","NAME_ES":"Indonesia","NAME_FR":"Indonésie","NAME_EL":"Ινδονησία","NAME_HI":"इंडोनेशिया","NAME_HU":"Indonézia","NAME_ID":"Indonesia","NAME_IT":"Indonesia","NAME_JA":"インドネシア","NAME_KO":"인도네시아","NAME_NL":"Indonesië","NAME_PL":"Indonezja","NAME_PT":"Indonésia","NAME_RU":"Индонезия","NAME_SV":"Indonesien","NAME_TR":"Endonezya","NAME_VI":"Indonesia","NAME_ZH":"印度尼西亚"}},{"arcs":[[[132,-1]],[[133,134]],[[135,-8,136,137,138,139]],[[140]],[[141]],[[142]],[[143]],[[144]],[[145]]],"type":"MultiPolygon","properties":{"featurecla":"Admin-0 country","scalerank":5,"LABELRANK":3,"SOVEREIGNT":"Malaysia","SOV_A3":"MYS","ADM0_DIF":0,"LEVEL":2,"TYPE":"Sovereign country","ADMIN":"Malaysia","ADM0_A3":"MYS","GEOU_DIF":0,"GEOUNIT":"Malaysia","GU_A3":"MYS","SU_DIF":0,"SUBUNIT":"Malaysia","SU_A3":"MYS","BRK_DIFF":0,"NAME":"Malaysia","NAME_LONG":"Malaysia","BRK_A3":"MYS","BRK_NAME":"Malaysia","BRK_GROUP":"","ABBREV":"Malay.","POSTAL":"MY","FORMAL_EN":"Malaysia","FORMAL_FR":"","NAME_CIAWF":"Malaysia","NOTE_ADM0":"","NOTE_BRK":"","NAME_SORT":"Malaysia","NAME_ALT":"","MAPCOLOR7":2,"MAPCOLOR8":4,"MAPCOLOR9":3,"MAPCOLOR13":6,"POP_EST":31381992,"POP_RANK":15,"GDP_MD_EST":863000,"POP_YEAR":2017,"LASTCENSUS":2010,"GDP_YEAR":2016,"ECONOMY":"6. Developing region","INCOME_GRP":"3. Upper middle income","WIKIPEDIA":-99,"FIPS_10_":"MY","ISO_A2":"MY","ISO_A3":"MYS","ISO_A3_EH":"MYS","ISO_N3":"458","UN_A3":"458","WB_A2":"MY","WB_A3":"MYS","WOE_ID":23424901,"WOE_ID_EH":23424901,"WOE_NOTE":"Exact WOE match as country","ADM0_A3_IS":"MYS","ADM0_A3_US":"MYS","ADM0_A3_UN":-99,"ADM0_A3_WB":-99,"CONTINENT":"Asia","REGION_UN":"Asia","SUBREGION":"South-Eastern Asia","REGION_WB":"East Asia & Pacific","NAME_LEN":8,"LONG_LEN":8,"ABBREV_LEN":6,"TINY":-99,"HOMEPART":1,"MIN_ZOOM":0,"MIN_LABEL":3,"MAX_LABEL":8,"NE_ID":1159321083,"WIKIDATAID":"Q833","NAME_AR":"ماليزيا","NAME_BN":"মালয়েশিয়া","NAME_DE":"Malaysia","NAME_EN":"Malaysia","NAME_ES":"Malasia","NAME_FR":"Malaisie","NAME_EL":"Μαλαισία","NAME_HI":"मलेशिया","NAME_HU":"Malajzia","NAME_ID":"Malaysia","NAME_IT":"Malesia","NAME_JA":"マレーシア","NAME_KO":"말레이시아","NAME_NL":"Maleisië","NAME_PL":"Malezja","NAME_PT":"Malásia","NAME_RU":"Малайзия","NAME_SV":"Malaysia","NAME_TR":"Malezya","NAME_VI":"Malaysia","NAME_ZH":"马来西亚"}},{"arcs":[[[146,147,148,149]],[[150,151,152,153]],[[154]],[[155]],[[156]],[[157]],[[158]],[[159]],[[160]],[[161]],[[162]],[[163]],[[164]],[[165]],[[166]],[[167]],[[168]],[[169]],[[170]],[[171]],[[172]],[[173]],[[174]],[[175]],[[176]],[[177]],[[178]],[[179]],[[180]],[[181]],[[182]],[[183]],[[184]],[[185]],[[186]],[[187]],[[188]],[[189]],[[190]],[[191]],[[192]],[[193]],[[194]],[[195]],[[196]],[[197]],[[198]],[[199]],[[200]],[[201]],[[202]],[[203]],[[204]],[[205]],[[206]],[[207]],[[208]],[[209]],[[210]],[[211]],[[212]],[[213]],[[214]],[[215]],[[216]],[[217]],[[218]],[[219]],[[220]],[[221]],[[222]],[[223]],[[224]],[[225]],[[226]],[[227]],[[228]],[[229]],[[230]],[[231]],[[232]],[[233]],[[234]],[[235]],[[236]],[[237]]],

这是我的 JS:

<script>window.onload = setMap();

function setMap(){

d3.csv("/data/fdata.csv").then(function(data) {
        //console.log(data);
d3.json("/data/a.topojson").then(function(data2) {
        //console.log(data2);

    var width = 960,
        height = 460;

    //create new svg container for the map
    var map = d3.select("body")
        .append("svg")
        .attr("class", "map")
        .attr("width", width)
        .attr("height", height);

    var projection = d3.geoNaturalEarth1()
        .center([0, 0])
        .rotate([-2, 0, 0])
        //.parallels([43, 62])
        .scale(175)
        .translate([width / 2, height / 2]);
    var path = d3.geoPath()
        .projection(projection);

    d3.selectAll(".boundary")
    .style("stroke-width", 1 / 1);
    var b = topojson.feature(data2, data2.objects.ne_10m_admin_0_countries);

    var graticule = d3.geoGraticule();

    var attrArray = ["x1","x2","x3" ];

    function joinData(b, data){
        for (var i=0; i<data.length; i++){
            var csvRegion = data[i]; //the current region
            var csvKey = data[i].Country; //the CSV primary key

            for (var a=0; a<b.features.length; a++){     
                var geojsonProps = b.features[a].properties; //gj props
                var geojsonKey = geojsonProps.ADMIN; //the geojson primary key

                if (geojsonKey == csvKey){

                    attrArray.forEach(function(attr){
                        var val = parseFloat(csvRegion[attr]); 
                        geojsonProps[attr] = val; 
                    });
                };

            };
        };
        return b;
  };
    joinData(b,data);

    var tooltip = d3.select("body").append("div") 
        .attr("class", "tooltip")       
        .style("opacity", 0);

    var currentF = "B2";

    var color = d3.scaleQuantile()
        .domain(d3.range(0, 1000))
        .range(d3.schemeReds[7]);  

    map.append("path")
        .datum(graticule)
        .attr("class", "graticule")
        .attr("d", path);

    map.append("path")
        .datum(graticule.outline)
        .attr("class", "graticule outline")
        .attr("d", path);

   map.selectAll("path")
        .data(b.features)
        .enter()
        .append("path")
        .attr("d", path)
        //.style("stroke", "black")
        .on("mouseover", function(d) {    
            tooltip.transition()    
            .duration(200)    
            .style("opacity", .9)
            .style("stroke-opacity", 1.0);    
            tooltip.html(d.properties.ADMIN)  
            .style("left", (d3.event.pageX) + "px")   
            .style("top", (d3.event.pageY - 28) + "px");  
          })          
          .on("mouseout", function(d) {   
            tooltip.transition()    
            .duration(500)    
            .style("opacity", 0)
            .style("stroke-opacity", 0); 
          })
        .style("fill", function(d) { return color(d.properties[currentF]); });




}); //csv
}); //json

};

我认为问题出在 map.selectAll("path") 块上。当我 运行 它没有 D3 迭代功能时,它似乎很好。 (印度尼西亚和马来西亚还在。)

问题在这里:

map.append("path")
    .datum(graticule)
    .attr("class", "graticule")
    .attr("d", path);

map.append("path")
    .datum(graticule.outline)
    .attr("class", "graticule outline")
    .attr("d", path);

map.selectAll("path")
    .data(b.features)
    .enter()
    .append("path")
    .attr("d", path)

两个附加语句创建路径,然后 select 这些现有路径,当你这样做时:map.selectAll("path")。为确认,在追加特征之前,您可以 console.log(map.selectAll("path").size()) 查看有多少元素被 selected,应该是两个。

输入 selection 可用于为数据数组中在 DOM 中没有相应元素的每个项目创建 DOM 中的元素。

由于你的selection中有两条路径,data数组中的前两项对应这两个元素,因此不需要输入:它们已经存在(通过将数据与 .data() 绑定,您将数据数组中的前两个数据绑定到已经存在的路径 )。 D3 没有 "know" 这些路径不应该与那些数据数组项相关联。

为了确保输入所有项目,您可以确保在绑定数据之前有一个空 select离子:

map.selectAll(null).data()...
map.selectAll().data()...
map.selectAll(".className").data()... // where no element has that class yet