javascript - D3 工具提示中未定义的属性

标签 javascript d3.js

我试图在工具提示中添加两个属性,但一直失败。我可以在工具提示中显示四个属性中的两个,但不是全部。可以显示“id”和“rate”,但不能显示“state”和“county”。我认为这是由于数据加载错误造成的,但无法修复。你能帮忙吗?

我还在底部列出了部分数据。

这是我的代码:

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

.counties {
  fill: none;
}

.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 unemployment = d3.map();

var path = d3.geoPath();

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

var color = d3.scaleThreshold()
    .domain([0, 1, 2, 4, 8, 10])
    .range(d3.schemeBlues[6]);

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("x", x.range()[0] - 30)
    .attr("y", -6)
    .attr("fill", "#000")
    .attr("text-anchor", "start")
    .attr("font-weight", "bold")
    .text("House Price to Income Ratio Rate");

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, "data.tsv", function(d) { unemployment.set(d.id, +d.rate, d.state, 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 = unemployment.get(d.id)); })
    .attr("d", path)
    .append("title")
    .text(function(d) { var q = d3.format(".2f")
        return 'State:' + d.state + ' ' + d.county + ' ' +d.id + ':' +(q(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>

数据:

id  rate    state   county
47035   0.66    TN  CUMBERLAND
47089   1.26    TN  JEFFERSON
47129   1.08    TN  MORGAN
47155   1.34    TN  SEVIER
47105   1.16    TN  LOUDON
47145   1.1 TN  ROANE
47151   1.26    TN  SCOTT
47067   1.21    TN  HANCOCK
47173   1.03    TN  UNION
47063   1.22    TN  HAMBLEN
47033   1.17    TN  CROCKETT
47157   1.06    TN  SHELBY
47167   1.02    TN  TIPTON
47045   0.75    TN  DYER
47069   1.19    TN  HARDEMAN
47075   1.3 TN  HAYWOOD
47097   1.05    TN  LAUDERDALE
47047   1.38    TN  FAYETTE
47095   1.16    TN  LAKE
47017   1.11    TN  CARROLL
47005   1.19    TN  BENTON
47079   0.99    TN  HENRY
47183   1.06    TN  WEAKLEY
47131   1.1 TN  OBION
47053   1.13    TN  GIBSON
47113   1.26    TN  MADISON
47109   1.25    TN  MCNAIRY
47039   1.37    TN  DECATUR
47071   1.28    TN  HARDIN
47077   1.45    TN  HENDERSON
47023   1.21    TN  CHESTER
47181   1.34    TN  WAYNE
47055   1.16    TN  GILES
47099   1.31    TN  LAWRENCE
47101   1.32    TN  LEWIS
47141   1.45    TN  PUTNAM
47049   1.46    TN  FENTRESS
47133   1.2 TN  OVERTON

最佳答案

您的问题在于您正在访问每个地理特征的数据,而不是 tsv 中的行,此处:

 .text(function(d) { var q = d3.format(".2f")
        return 'State:' + d.state + ' ' + d.county + ' ' +d.id + ':' +(q(d.rate)); }
        );
该函数中的

d 包含来自 geojson 的特征数据,如下所示:

Object { type: "Feature", id: "18121", properties: Object, geometry: Object }  
Object { type: "Feature", id: "39103", properties: Object, geometry: Object }

您需要正确映射数据并使用 d3.map() 访问它。看起来您正在使用 this example ,您的修改看起来很直观,但是:

.defer(d3.tsv, "data.tsv", function(d) { unemployment.set(d.id, +d.rate, d.state, d.county); })

产生这样的数据结构:

Object { $47035: 0.66, $47089: 1.26, $47129: 1.08, $47155: 1.34, $47105: 1.16, $47145: 1.1, $47151: 1.26, $47067: 1.21, $47173: 1.03, $47063: 1.22, 28 more… }

我不相信 d3.map().set() 允许每个键有多个值。相反,您可以使用对象作为值:

.defer(d3.tsv, "data.tsv", function(d) { unemployment.set(d.id, d); })

要访问 tsv 文件中的列,您可以使用如下行:

unemployment.get(d.id).state
<小时/>

最后,您可能拥有每个县的完整数据集,尽管您可能只查看选定的县,在这种情况下,您可以添加检查以查看数据是否存在(否则您的 d3.map()当您查找每个县的数据时,某些县将返回未定义的结果。类似这样的事情会起作用:

.attr("fill", function(d) {  if(unemployment.get(d.id)) { return color(d.rate = unemployment.get(d.id).rate); } else { return "none"; } })
.attr("d", path)
.append("title")
.text(function(d) { var q = d3.format(".2f"); 
    if (unemployment.get(d.id)) {
            return 'State:' + unemployment.get(d.id).state + ' ' + unemployment.get(d.id).county + ' ' +d.id + ':' +(q(d.rate)); 
        }
        else {
            return "no data";
        }
    });

Here's a block一切都在行动。

注意,上面的代码块中d.rate是在显示颜色时设置的,所以之后设置文本内容时不需要使用失业图来设置该值。在您正在使用的可能示例 in this block 中也是如此。 .

关于javascript - D3 工具提示中未定义的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44622503/

相关文章:

javascript - D3 从大 csv 创建条形图

javascript - 如何向浏览器指示js文件已更改并且无需刷新即可反射(reflect)在客户端。那么它会下载新副本吗?

javascript - 嵌入应用程序时从 D3 Observable 中删除单元格

javascript - 如何使用 d3.js 在折线图上的某个点显示图标

javascript - 窗口本身加载后如何触发加载事件?

javascript - D3 Javascript 绘图函数

javascript - D3.js 无限规模使用 d3.svg.brush

javascript - react 。聊天工具包 API。 MessageList 组件错误 - 呈现来自其他房间的消息。组件生命周期和状态

javascript:构建数组项的条件

javascript - 如何在 jQuery 中使用其中心作为引用点来缩小 div?