无法在d3.js地图上渲染城市名称标签:超出范围NAME? [英] inexplicable inability to render city name labels on a d3.js map: out of scope NAME?

查看:596
本文介绍了无法在d3.js地图上渲染城市名称标签:超出范围NAME?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照规范



和点坐标





解决方案:



正确的方式




  • 在GIS软件(ArcGIS-pay,Q-GIS-free)上打开地图,编辑并更正路径和点属性,并再次导出为TopoJSON .-



简单方法




  • 前往:



    现在你在那里正确的countie信息删除一列(您有重复的资讯)



    < img src =https://i.stack.imgur.com/4xf1M.pngalt =输入图片说明here>


    I'm following the canonical "Let’s Make a Map" tutorial- but to spice things up I'm melding it with one about Germany- so I'm working with slightly different data.

    Things are so far working out- barring this minor hiccup- but now I've come to the section "#Displaying Places" which is where you're supposed to show the names of the cities on the map.

    The problem is happening in the following line:

       .text(function(d) {
            if (d.properties.name!=="Berlin" &&
                d.properties.name!=="Bremen"){
    
                    //for some reason this is undefined
                    console.log(d.properties.name);
                    return d.properties.name;
            }
        })
    

    The value of that console.log(d.properties.name); is always undefined and I can't figure out why!

    I suppose it's because name is out of scope for d- but I don't know how to fix it. Is that right? If so- how to fix it? if not- what is the real problem?

    Here is what my code looks like- it's pretty concise:

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
    
    .subunit{fill:#fff;}
    .subunit.Nordrhein-Westfalen{ fill: #aba; }
    .subunit.Baden-Württemberg{ fill: #bab; }
    .subunit.Hessen{ fill: #bcb; }
    .subunit.Niedersachsen{ fill: #cbc; }
    .subunit.Thüringen{ fill: #cdc; }
    .subunit.Hamburg{ fill: #dcd; }
    .subunit.Schleswig-Holstein{ fill: #ded; }
    .subunit.Rheinland-Pfalz{ fill: #ede; }
    .subunit.Saarland{ fill: #efe; }
    .subunit.Sachsen-Anhalt{ fill: #fef; }
    .subunit.Brandenburg{ fill: #aaa; }
    .subunit.Mecklenburg-Vorpommern{ fill: #bbb; }
    .subunit.Bayern { fill: #ccc; }
    .subunit.Sachsen { fill: #ddd; }
    .subunit.Bremen { fill: #eee; }
    .subunit.Berlin { fill: #fff; }
    
    .subunit-boundary {
      fill: none;
      stroke: #777;
      stroke-dasharray: 2,2;
      stroke-linejoin: round;
    }
    
    
    .place,
    .place-label {
      fill: #444;
      font-size:14px;
    }
    
    text {
      font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
      font-size: 20px;
      pointer-events: none;
    }
    
    
    </style>
    <body>
    <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="//d3js.org/topojson.v1.min.js"></script>
    <script>
    
    var width = 960,
        height = 1160;
    
    var projection = d3.geo.mercator()
        .center([10.5, 51.35])
        .scale(3000)
        .translate([width / 2, height / 2]);
    
    var path = d3.geo.path()
        .projection(projection);
    
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    
    
    d3.json("de.json", function(error, de) {
    
        //colouring the different subunits
        svg.selectAll(".subunit")
           .data(topojson.feature(de, de.objects.subunits).features)
           .enter().append("path")
           .attr("class", function(d) {
            // console.log(d.properties.name);
            return "subunit " + d.properties.name;
           })
           .attr("d", path);
    
        //adding a border to the states
        svg.append("path")
            .datum(topojson.mesh(de, de.objects.subunits, function(a,b) {
                if (a!==b ||
                    a.properties.name === "Berlin"||
                    a.properties.name === "Bremen"){
                        var ret = a;
                    }
                        return ret;
                    }))
            .attr("d", path)
            .attr("class", "subunit-boundary");
    
        // add small black dots for populated places
        svg.append("path")
           .datum(topojson.feature(de, de.objects.places))
           .attr("d", path)
           .attr("class", "place");
    
    
    
        //trying to display names of cities
        svg.selectAll(".place-label")
           .data(topojson.feature(de, de.objects.places).features)
           .enter().append("text")
           .attr("class", "place-label")
           .attr("transform", function(d) {
    
                //small test
                //console.log( "translate(" + projection(d.geometry.coordinates) + ")" );
    
                return "translate(" + projection(d.geometry.coordinates) + ")";
            })
           .attr("dy", ".35em")
           .text(function(d) {
                if (d.properties.name!=="Berlin" &&
                    d.properties.name!=="Bremen"){
    
                        //for some reason this is undefined
                        console.log(d.properties.name);
                        return d.properties.name;
                }
            })
           .attr("x", function(d) {
                return d.geometry.coordinates[0] > -1 ? 6 : -6;
            })
           .style("text-anchor", function(d) {
                return d.geometry.coordinates[0] > -1 ? "start" : "end";
           });
    
    
    
    });
    
    </script>
    

    Here is the data file.

    EDIT

    expected

    actual

    解决方案

    Inside your .topojson you have two section:

    • properties: names of your counties and polygons
    • places: coordinates of the points

    You access the first collection with:

    de.objects.subunits
    

    And the second collection through:

    de.subunits.places
    

    After file is loaded sepearte into two different variables to use it:

    d3.json("de.json", function(error, de) {
        var counti = topojson.feature(de, de.objects.subunits)
        var places = topojson.feature(de, de.objects.places)
    

    then referenciate the content adding .features

       .data(counti.features)   // <-- to draw your paths and get the .name: München
    

    or

       .data(places.features)  // <-- to draw the circles for the cities: "coordinates": [11.573039376427117, 48.131688134368815]
    

    Mike's topojson has:

    {
      "type": "Feature",
      "properties": {
        "name": "Ayr"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -4.617021378468872,
          55.44930882146421
        ]
      }
    

    and you has:

     {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Point",
        "coordinates": [
          11.573039376427117,
          48.131688134368815
        ]
      }
    

    Mike's point properties looks like this:

    and point coordinates

    Your point properties:

    Solution:

    The right way

    • Open your map on GIS software (ArcGIS-pay, Q-GIS-free) edit and correct paths and points properties and export as TopoJSON again.-

    Easy way

    • Go to: geojson.io load your json and add propertie name to your point (16 points, easy cake) and save as TopoJSON again.-

    Now you're there correct countie info deleting one column (you has duplicate info)

    这篇关于无法在d3.js地图上渲染城市名称标签:超出范围NAME?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆