正确访问d3地图标签的分配json坐标 [英] correctly accessing assigned json coordinates for d3 map labels

查看:105
本文介绍了正确访问d3地图标签的分配json坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出具有以下结构的外部json文件"us-states.json":

{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "GEO_ID": "0400000US23", "STATE": "23", "NAME": "Maine", "LSAD": "", "CENSUSAREA": 30842.923000 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -67.619761, 44.519754 ], [ -67.615410, 44.521973 ], [ -67.587738, 44.516196 ] ... ] ] ] } } ...

我能够渲染地图并使用data.csv中的值对其进行着色,但是无法附加地图标签并使它们显示(脚本的底部).

<script type="text/javascript">

var width = 800;
var height = 460;

var projection = d3.geo.albersUsa()
                   .translate([width/2, height/2])    
                   .scale([1000]);          

var path = d3.geo.path()               
             .projection(projection);  

var color = d3.scale.linear()
.range(["rgb(255,90,95)","rgb(84,36,55)","rgb(0,80,160)"]);

var svg = d3.select("body")
            .append("svg")
            .attr("class","map")
            .attr("width", width)
            .attr("height", height)
            .attr("align","center");

d3.csv("data.csv", function(data) {
color.domain([1,2,3]);

d3.json("us-states.json", function(json) {

for (var i = 0; i < data.length; i++) {

    var dataState = data[i].state;
    var dataValue = data[i].value;
    var dataLink = data[i].link;

    for (var j = 0; j < json.features.length; j++)  {
        var jsonState = json.features[j].properties.NAME;
        var jsonStateCoords = json.features[j].geometry.coordinates

        if (dataState == jsonState) {

        json.features[j].properties.value = dataValue; 
        json.features[j].properties.link = dataLink;
        json.features[j].properties.coordinates = jsonStateCoords;

        break;
        }
    }
};

svg.selectAll("path")
    .data(json.features)
    .enter()
    .append("path")
    .attr("d", path)
    .style("stroke", "#fff")
    .style("stroke-width", "1")
    .style("fill", function(d) {

    var value = d.properties.value;

    if (value) {
    return color(value);
    } else {
    return "rgb(213,222,217)";
    }

    })  

// part of the script that isn't working
svg.selectAll("text")
   .data(json.features)
   .enter()
   .append("svg:text")
   .attr("d", path)
   .text(function(d){return d.properties.state; })
   .attr("x", function(d){ return d.properties.coordinates[0]  })
   .attr("y", function(d){ return d.properties.coordinates[1]  })
   .attr("text-anchor","middle")
   .attr('font-size', '13px')
   .attr('color', 'white');


});
</script>

我可以console.log(jsonStateCoords)看到它们.为什么我无法访问返回d.properties.coords.xd.properties.coords.y的字段值?取而代之的是d.properties.coords is undefined.谢谢

解决方案

在状态上添加标签时,您要寻找的是找到状态边界路径的质心. d3提供了一种计算质心的方法.

svg.selectAll("text")
   .data(json.features)
   .enter()
   .append("svg:text")
   .attr("text-anchor","middle")
   .attr('font-size', '13px')
   .attr('fill', 'blue')
    .text(function(d) {
      return d.properties.NAME;
    })
    .attr("x", function(d) {
      return path.centroid(d)[0];
    })
    .attr("y", function(d) {
      return path.centroid(d)[1];
    })

相关问题:

如何为每个州添加标签在d3.js(albersUsa)中?

d3.js在其中添加标签路径的中心

块:

http://bl.ocks.org/pgiraud/9f400d54ce2ea7b4f820

http://bl.ocks.org/LuisSevillano/b51c795f7d68aedfb24485fbdb570c3c>

此处的测试代码:

 var width = 800;
var height = 460;

var projection = d3.geo.albersUsa()
                   .translate([width/2, height/2])    
                   .scale([1000]);          

var path = d3.geo.path()               
             .projection(projection);  

var color = d3.scale.linear()
.range(["rgb(255,90,95)","rgb(84,36,55)","rgb(0,80,160)"]);

var svg = d3.select("body")
            .append("svg")
            .attr("class","map")
            .attr("width", width)
            .attr("height", height)
            .attr("align","center");

d3.csv("https://cors-anywhere.herokuapp.com/https://gist.githubusercontent.com/radaatyr/313875565a6af5832473625157bd8d40/raw/bc0edee1910034bcc72aac82de659883e6a91f45/postus.json", function(data) {
  color.domain([1,2,3]);
  
  

  d3.json("https://gist.githubusercontent.com/radaatyr/0e5fcda67ff33afb92b505c5af16d779/raw/bce351a66607ae2c9215a7919981b840c9bb4ddf/us-states.json", function(json) {

    for (var i = 0; i < data.length; i++) {

    var dataState = data[i].state;
    var dataValue = data[i].value;
    var dataLink = data[i].link;

    for (var j = 0; j < json.features.length; j++)  {
        var jsonState = json.features[j].properties.NAME;
        var jsonStateCoords = json.features[j].geometry.coordinates

        if (dataState == jsonState) {

        json.features[j].properties.value = dataValue; 
        json.features[j].properties.link = dataLink;
        json.features[j].properties.coords = jsonStateCoords;

        break;
        }
    }
    };

    svg.selectAll("path")
        .data(json.features)
        .enter()
        .append("path")
        .attr("d", path)
        .style("stroke", "#fff")
        .style("stroke-width", "1")
        .style("fill", function(d) {

        var value = d.properties.value;

        if (value) {
        return color(value);
        } else {
        return "rgb(213,222,217)";
        }

        })  

    // part of the script that isn't working
    svg.selectAll("text")
       .data(json.features)
       .enter()
       .append("svg:text")
       .attr("text-anchor","middle")
       .attr('font-size', '13px')
       .attr('fill', 'blue')
        .text(function(d) {
          return d.properties.NAME;
        })
        .attr("x", function(d) {
          return path.centroid(d)[0];
        })
        .attr("y", function(d) {
          return path.centroid(d)[1];
        })
  });
  

}); 

 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script> 

give an external json file "us-states.json" with this structure:

{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "GEO_ID": "0400000US23", "STATE": "23", "NAME": "Maine", "LSAD": "", "CENSUSAREA": 30842.923000 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -67.619761, 44.519754 ], [ -67.615410, 44.521973 ], [ -67.587738, 44.516196 ] ... ] ] ] } } ...

I'm able to render a map and color it with values from data.csv but can't append map labels and get them to appear (very end of the script at the bottom).

<script type="text/javascript">

var width = 800;
var height = 460;

var projection = d3.geo.albersUsa()
                   .translate([width/2, height/2])    
                   .scale([1000]);          

var path = d3.geo.path()               
             .projection(projection);  

var color = d3.scale.linear()
.range(["rgb(255,90,95)","rgb(84,36,55)","rgb(0,80,160)"]);

var svg = d3.select("body")
            .append("svg")
            .attr("class","map")
            .attr("width", width)
            .attr("height", height)
            .attr("align","center");

d3.csv("data.csv", function(data) {
color.domain([1,2,3]);

d3.json("us-states.json", function(json) {

for (var i = 0; i < data.length; i++) {

    var dataState = data[i].state;
    var dataValue = data[i].value;
    var dataLink = data[i].link;

    for (var j = 0; j < json.features.length; j++)  {
        var jsonState = json.features[j].properties.NAME;
        var jsonStateCoords = json.features[j].geometry.coordinates

        if (dataState == jsonState) {

        json.features[j].properties.value = dataValue; 
        json.features[j].properties.link = dataLink;
        json.features[j].properties.coordinates = jsonStateCoords;

        break;
        }
    }
};

svg.selectAll("path")
    .data(json.features)
    .enter()
    .append("path")
    .attr("d", path)
    .style("stroke", "#fff")
    .style("stroke-width", "1")
    .style("fill", function(d) {

    var value = d.properties.value;

    if (value) {
    return color(value);
    } else {
    return "rgb(213,222,217)";
    }

    })  

// part of the script that isn't working
svg.selectAll("text")
   .data(json.features)
   .enter()
   .append("svg:text")
   .attr("d", path)
   .text(function(d){return d.properties.state; })
   .attr("x", function(d){ return d.properties.coordinates[0]  })
   .attr("y", function(d){ return d.properties.coordinates[1]  })
   .attr("text-anchor","middle")
   .attr('font-size', '13px')
   .attr('color', 'white');


});
</script>

I can console.log(jsonStateCoords) and see them. why am I not able to access the field values returning d.properties.coords.x or d.properties.coords.y? getting d.properties.coords is undefined instead. thanks

What you're looking for when adding label over the states, is to find the centroid of the state boundary path. d3 has a a method to calculate the centroid.

svg.selectAll("text")
   .data(json.features)
   .enter()
   .append("svg:text")
   .attr("text-anchor","middle")
   .attr('font-size', '13px')
   .attr('fill', 'blue')
    .text(function(d) {
      return d.properties.NAME;
    })
    .attr("x", function(d) {
      return path.centroid(d)[0];
    })
    .attr("y", function(d) {
      return path.centroid(d)[1];
    })

Related questions:

How to add Label to each state in d3.js (albersUsa)?

d3.js add a label in the center of a path

Blocks:

http://bl.ocks.org/pgiraud/9f400d54ce2ea7b4f820

http://bl.ocks.org/LuisSevillano/b51c795f7d68aedfb24485fbdb570c3c

Testing code here:

var width = 800;
var height = 460;

var projection = d3.geo.albersUsa()
                   .translate([width/2, height/2])    
                   .scale([1000]);          

var path = d3.geo.path()               
             .projection(projection);  

var color = d3.scale.linear()
.range(["rgb(255,90,95)","rgb(84,36,55)","rgb(0,80,160)"]);

var svg = d3.select("body")
            .append("svg")
            .attr("class","map")
            .attr("width", width)
            .attr("height", height)
            .attr("align","center");

d3.csv("https://cors-anywhere.herokuapp.com/https://gist.githubusercontent.com/radaatyr/313875565a6af5832473625157bd8d40/raw/bc0edee1910034bcc72aac82de659883e6a91f45/postus.json", function(data) {
  color.domain([1,2,3]);
  
  

  d3.json("https://gist.githubusercontent.com/radaatyr/0e5fcda67ff33afb92b505c5af16d779/raw/bce351a66607ae2c9215a7919981b840c9bb4ddf/us-states.json", function(json) {

    for (var i = 0; i < data.length; i++) {

    var dataState = data[i].state;
    var dataValue = data[i].value;
    var dataLink = data[i].link;

    for (var j = 0; j < json.features.length; j++)  {
        var jsonState = json.features[j].properties.NAME;
        var jsonStateCoords = json.features[j].geometry.coordinates

        if (dataState == jsonState) {

        json.features[j].properties.value = dataValue; 
        json.features[j].properties.link = dataLink;
        json.features[j].properties.coords = jsonStateCoords;

        break;
        }
    }
    };

    svg.selectAll("path")
        .data(json.features)
        .enter()
        .append("path")
        .attr("d", path)
        .style("stroke", "#fff")
        .style("stroke-width", "1")
        .style("fill", function(d) {

        var value = d.properties.value;

        if (value) {
        return color(value);
        } else {
        return "rgb(213,222,217)";
        }

        })  

    // part of the script that isn't working
    svg.selectAll("text")
       .data(json.features)
       .enter()
       .append("svg:text")
       .attr("text-anchor","middle")
       .attr('font-size', '13px')
       .attr('fill', 'blue')
        .text(function(d) {
          return d.properties.NAME;
        })
        .attr("x", function(d) {
          return path.centroid(d)[0];
        })
        .attr("y", function(d) {
          return path.centroid(d)[1];
        })
  });
  

});

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>

这篇关于正确访问d3地图标签的分配json坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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