Choropleth映射返回未定义 [英] Choropleth map returning undefined

查看:58
本文介绍了Choropleth映射返回未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试绘制美国各州的choropleth地图,并且基本上是从此处使用Mike Bostock的示例 https ://bl.ocks.org/mbostock/4060606 我使用的是教育而不是失业,但除此之外是相同的.我只想再增加一块,并显示郡名和比率.但是,当我呼叫县名时,会返回"undefined".为了清楚起见,比率"返回的很好,县"显示为未定义.有人可以帮忙吗?谢谢!

I'm attempting a choropleth map of US Counties, and am essentially using Mike Bostock's example from here https://bl.ocks.org/mbostock/4060606 I am using education instead of unemployment, but otherwise it's the same. I'd like to add just one more piece to it and have the county name display along with the rate. However, when I call the county name, I get "undefined" returned. To be clear 'rate' returns just fine, 'county' shows up undefined. Can anyone help? Thanks!

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.counties {
  fill: none;
  /*stroke: black;*/
}

.states {
  fill: none;
  stroke: #fff;
  stroke-linejoin: round;
}

</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script>

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var Bachelor = d3.map();

var path = d3.geoPath();

var x = d3.scaleLinear()
    .domain([0, 70])
    .rangeRound([600, 860]);

var color_domain = [10, 20, 30, 40, 50, 60, 70]
var ext_color_domain = [10, 20, 30, 40, 50, 60, 70]
var color = d3.scaleThreshold()
    .domain(color_domain)
    .range([" #85c1e9", "#5dade2", "#3498db", "#2e86c1", "#2874a6", " #21618c"," #1b4f72"]);
var g = svg.append("g")
    .attr("class", "key")
    .attr("transform", "translate(0,40)");

g.selectAll("rect")
  .data(color.range().map(function(d) {
      d = color.invertExtent(d);
      if (d[0] == null) d[0] = x.domain()[0];
      if (d[1] == null) d[1] = x.domain()[1];
      return d;
    }))
  .enter().append("rect")
    .attr("height", 8)
    .attr("x", function(d) { return x(d[0]); })
    .attr("width", function(d) { return x(d[1]) - x(d[0]); })
    .attr("fill", function(d) { return color(d[0]); });

g.append("text")
    .attr("class", "caption")
    .attr("x", x.range()[0])
    .attr("y", -6)
    .attr("fill", "#000")
    .attr("text-anchor", "start")
    .attr("font-weight", "bold")
    .text("% of Adults with Bachelor's or higher");

g.call(d3.axisBottom(x)
    .tickSize(13)
    .tickFormat(function(x, i) { return i ? x : x; })
    .tickValues(color.domain()))
  .select(".domain")
    .remove();

d3.queue()
    .defer(d3.json, "https://d3js.org/us-10m.v1.json")
    .defer(d3.tsv, "Bachelor2.tsv", function(d) { Bachelor.set(d.id, d.rate, d.county); })
    .await(ready);


function ready(error, us) {
  if (error) throw error;


  svg.append("g")
      .attr("class", "counties")
    .selectAll("path")
    .data(topojson.feature(us, us.objects.counties).features)
    .enter().append("path")
      .attr("fill", function(d) { return color(d.rate = Bachelor.get(d.id)); })
      .attr("d", path)
    .append("title")
      .text(function(d) { return (d.county +" " d.rate +"%"); });

  svg.append("path")
      .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
      .attr("class", "states")
      .attr("d", path);
}

</script>

推荐答案

您的代码中有两个问题.

There are two problems in your code.

代码中的第一个问题就在这里:

The first problem in your code lies here:

Bachelor.set(d.id, d.rate, d.county);

在两个 javascript映射和D3映射(略有不同),您不能为同一键设置两个值.因此,语法必须为:

In both javascript maps and D3 maps (which are slightly different), you cannot set two values for the same key. Therefore, the syntax has to be:

map.set(键,值)

map.set(key, value)

让我们看看.

这可行,将值"bar"设置为"foo":

This works, setting the value "bar" to "foo":

var myMap = d3.map();
myMap.set("foo", "bar");
console.log(myMap.get("foo"))

<script src="https://d3js.org/d3.v4.min.js"></script>

但是,这不起作用:

var myMap = d3.map();
myMap.set("foo", "bar", "baz");
console.log(myMap.get("foo"))

<script src="https://d3js.org/d3.v4.min.js"></script>

如您所见,未设置值"baz".

As you can see, the value "baz" was not set.

假设countryBachelor2.tsv文件中的属性.这带来了第二个问题:

That was assuming that country is a property in your Bachelor2.tsv file. And that brings us to the second problem:

在您的路径中,这是数据:

In your paths, this is the data:

topojson.feature(us, us.objects.counties).features

如果您查看代码,则可以为该数据设置一个名为rate的属性(使用地图)...

If you look at your code, you set a property named rate (using your map) to that data...

.attr("fill", function(d) { return color(d.rate = Bachelor.get(d.id)); })
//you set 'rate' to the datum here --------^

...但是您永远不会设置名为country的属性.因此,没有这样的属性供您在回调中使用.

...but you never set a property named country. Therefore, there is no such property for you to use in the callbacks.

如上所述,您不能使用与设置rate相同的映射进行设置.解决方案是使用对象代替.另外,您可以使用两个地图,这似乎是最快的选择.

As explained above, you cannot set it using the same map you used to set the rate. A solution is using an object instead. Alternatively, you could use two maps, which seems to be the fastest option.

这篇关于Choropleth映射返回未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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