d3.js中的Javascript对象问题

时间:2017-10-03 21:29:45

标签: javascript d3.js

我正在尝试使用在django Web框架上运行的HTML页面使用d3渲染地图。这是直接来自d3的示例档案的地图示例:http://bl.ocks.org/NPashaP/a74faf20b492ad377312

我注意到了各州'低,高,平均和颜色都是使用这个函数随机生成的(我注释掉了):

// var sampleData ={};  /* Sample random data. */   
// ["HI", "AK", "FL", "SC", "GA", "AL", "NC", "TN", "RI", "CT", "MA",
// "ME", "NH", "VT", "NY", "NJ", "PA", "DE", "MD", "WV", "KY", "OH", 
// "MI", "WY", "MT", "ID", "WA", "DC", "TX", "CA", "AZ", "NV", "UT", 
// "CO", "NM", "OR", "ND", "SD", "NE", "IA", "MS", "IN", "IL", "MN", 
// "WI", "MO", "AR", "OK", "KS", "LS", "VA"]
//  .forEach(function(d){ 
//      var low=Math.round(100*Math.random()), 
//          mid=Math.round(100*Math.random()), 
//          high=Math.round(100*Math.random());
//      sampleData[d]={low:d3.min([low,mid,high]), 
// high:d3.max([low,mid,high]), 
//              avg:Math.round((low+mid+high)/3), 
// color:d3.interpolate("#ffffcc", "#800026")(low/100)}; 
//  });

sampleData控制台登录broswer时,它会打印一个对象字典,在展开时,如下所示:

{"HI":{low:20, high:10, avg:15, color:'#ffffcc'}, "AK"....

当我用自己的数据替换变量sampleData时:

var sampleData= {
    "HI":{low:69, color:"#e6e6ff"},
    "AK":{low:84, color:"#e6e6ff"},
    "FL":{low:1099, color:"#0000ff"},
    "SC":{low:223, color:"#b3b3ff"},
    "GA":{low:614, color:"#8080ff"},
    "AL":{low:228, color:"#b3b3ff"},
    "NC":{low:686, color:"#8080ff"},
    "TN":{low:416, color:"#b3b3ff"},
    "RI":{low:119, color:"#ccccff"},
    "CT":{low:319, color:"#b3b3ff"},
    "MA":{low:1195, color:"#0000ff"},
    "ME":{low:128, color:"#ccccff"},
    "NH":{low:225, color:"#b3b3ff"},
    "VT":{low:163, color:"#ccccff"},
    "NY":{low:1779, color:"#0000b3"},
    "NJ":{low:550, color:"#8080ff"},
    "AZ":{low:537, color:"#8080ff"},
    "AR":{low:222, color:"#b3b3ff"},
    "CA":{low:3453, color:"#000066"},
    "DE":{low:84, color:"#e6e6ff"},
    "ID":{low:155, color:"#ccccff"},
    "IL":{low:1082, color:"#0000ff"},
    "IN":{low:452, color:"#b3b3ff"},
    "IA":{low:219, color:"#b3b3ff"},
    "KS":{low:197, color:"#ccccff"},
    "KY":{low:274, color:"#b3b3ff"},
    "LA":{low:274, color:"#b3b3ff"},
    "MD":{low:662, color:"#8080ff"},
    "MI":{low:894, color:"#8080ff"},
    "MN":{low:670, color:"#8080ff"},
    "MS":{low:82, color:"#e6e6ff"},
    "MO":{low:509, color:"#8080ff"},
    "MT":{low:72, color:"#e6e6ff"},
    "NE":{low:165, color:"#ccccff"},
    "NV":{low:206, color:"#b3b3ff"},
    "NM":{low:213, color:"#b3b3ff"},
    "ND":{low:46, color:"#e6e6ff"},
    "OH":{low:941, color:"#8080ff"},
    "OK":{low:215, color:"#b3b3ff"},
    "OR":{low:1152, color:"#0000ff"},
    "PA":{low:1171, color:"#0000ff"},
    "SD":{low:43, color:"#e6e6ff"},
    "TX":{low:1490, color:"#0000ff"},
    "UT":{low:270, color:"#b3b3ff"},
    "VA":{low:723, color:"#8080ff"},
    "WA":{low:1667, color:"#0000b3"},
    "WV":{low:83, color:"#e6e6ff"},
    "WI":{low:541, color:"#8080ff"},
    "WY":{low:44, color:"#e6e6ff"},
    };`

我只能用十六进制颜色填充地图的某些部分。 Screenshot of results. Some states filled in, but not all.

我的浏览器控制台会返回使用原始sampleData时未发生的错误:

uStates.js:72 Uncaught TypeError: Cannot read property 'color' of undefined
at SVGPathElement.<anonymous> (uStates.js:72)
at SVGPathElement.u (d3.v3.min.js:1)
at d3.v3.min.js:3
at Y (d3.v3.min.js:1)
at Array.Co.each (d3.v3.min.js:3)
at Array.Co.style (d3.v3.min.js:3)
at Object.uStates.draw (uStates.js:72)
at (index):136

除此之外,使用原始sampleData时显示的小工具提示在使用我的自定义sampleData变量时不会显示。我想知道为什么会这样。以下是Javascript代码:

function tooltipHtml(n, d){ /* function to create html content string in 
tooltip div. */
    return "<h4>"+n+"</h4><table>"+
        "<tr><td>number:</td><td>"+(d.low)+"</td></tr>"+
        "</table>";
}

任何人都可以告诉我:

  1. 为什么我在控制台中收到特定错误?
  2. 为什么只有某些状态被填入状态缩写字符串旁边的对象中提供的十六进制?
  3. 为什么工具提示不适用于我的sampleData

1 个答案:

答案 0 :(得分:0)

您的两个美国州数据集之间存在不匹配:文件uStatePaths中的uStates.js包含50个州,而sampleData只包含48个州,其中缺少的是科罗拉多州和路易斯安那州。当执行开始时,第一个状态设置为fill值,但是一旦达到第一个状态,执行将停止,在sampleData中没有找到匹配状态,这会抛出您看到的错误。同样的问题会导致您的工具提示无法按预期工作。

如果不匹配是偶然的,您可以通过填写sampleData中缺少的状态来轻松解决此问题。如果这是故意的,您可以通过在访问其属性之前uStates.js检查data[d.id]是否存在的代码中为您的代码引入安全措施来避免错误。

查看代码的working fork。代码使用上面提到的检查并将所有不匹配的状态用红色着色:

.style("fill",function(d){ return data[d.id] ? data[d.id].color : "red" ; })