2014-01-23 31 views
2

正如我的用户名所示,我正在学习d3.js,使用Scott Murray的优秀书籍。作为一项练习,我试图用一些关于美国辍学率的公开数据创建一个choropleth(与他在书中使用的非常相似)。我有两个单独的csvs,一个是来自一组学生的数据,另一个是不同组的数据。我希望数据可以通过单击从一个CSV更新到另一个的数据。除了数值名称(DRPHI vs DRPBL),csvs的名称和值本身,它们是相同的。但是,点击更新无效 - 没有任何反应。 我在这里错过了一些非常基本的东西吗?我很抱歉,如果我。非常感谢您的参与。 我的代码(基于非常倚重穆雷的代码)是在这里:d3.js - 基于新的.csv更新choropleth中的数据?

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <title>D3: Setting path fills dynamically to generate a choropleth</title> 
     <script type="text/javascript" src="../d3/d3.v3.js"></script> 
     <style type="text/css"> 
     </style> 
    </head> 
    <body> 
    <p>Click on this text to update the chart with values for another set of students.</p> 
     <script type="text/javascript"> 

      var w = 500; 
      var h = 300; 

      var projection = d3.geo.albersUsa() 
            .translate([w/2, h/2]) 
            .scale([500]); 

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

      var color = d3.scale.quantize() 
           .range(["rgb(237,248,233)","rgb(186,228,179)","rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"]); 
           //Colors taken from colorbrewer.js, included in the D3 download 

      var svg = d3.select("body") 
         .append("svg") 
         .attr("width", w) 
         .attr("height", h); 

      d3.csv("1_dropout_by_state.csv", function(data) { 

       color.domain([ 
        d3.min(data, function(d) { return d.DRPHI; }), 
        d3.max(data, function(d) { return d.DRPHI; }) 
       ]); 

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

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

         var dataState = data[i].state; 

         var dataValue = parseFloat(data[i].DRPHI); 

         for (var j = 0; j < json.features.length; j++) { 

          var jsonState = json.features[j].properties.name; 

          if (dataState == jsonState) { 

           json.features[j].properties.value = dataValue; 

           break; 

          } 
         }  
        } 

        svg.selectAll("path") 
         .data(json.features) 
         .enter() 
         .append("path") 
         .attr("d", path) 
         .style("fill", function(d) { 
          var value = d.properties.value; 

          if (value) { 
           return color(value); 
          } else { 
           return "#ccc"; 
          } 
         }); 

       }); 

      }); 

      d3.select("p") 
       .on("click", function() { 
        d3.csv("2_dropout_by_state.csv", function(data) { 

       color.domain([ 
        d3.min(data, function(d) { return d.DRPBL; }), 
        d3.max(data, function(d) { return d.DRPBL; }) 
       ]); 

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

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

         var dataState = data[i].state; 

         var dataValue = parseFloat(data[i].DRPBL); 

         for (var j = 0; j < json.features.length; j++) { 

          var jsonState = json.features[j].properties.name; 

          if (dataState == jsonState) { 

           json.features[j].properties.value = dataValue; 

           break; 

          } 
         }  
        } 

        svg.selectAll("path") 
         .data(json.features) 
         .enter() 
         .append("path") 
         .attr("d", path) 
         .style("fill", function(d) { 
          var value = d.properties.value; 

          if (value) { 
           return color(value); 
          } else { 
           return "#ccc"; 
          } 
         }); 

       }); 

      }); 
     }); 


     </script> 
    </body> 
</html> 

回答

2

你看什么,因为D3的选择的工作方式发生。 This tutorial可能有助于了解正在发生的事情。

简单地说,你是在显示其他数据,选择所有现有path元素的功能:

svg.selectAll("path") 

,并结合数据对他们说:

.data(json.features) 

此数据是与之前绑定的元素完全相同。现在D3通过将数据元素与DOM元素进行匹配来计算它的连接。由于您之前使用过相同的数据,所以一切都完美匹配。因此,.enter()选择是空的。由于这是你操作的唯一的东西,没有任何反应。

要做你想做的事,你不需要追加新的元素 - 它足以绑定新的数据和更新。这是所有你可能需要的代码:

svg.selectAll("path") 
        .style("fill", function(d) { 
         var value = d.properties.value; 

         if (value) { 
          return color(value); 
         } else { 
          return "#ccc"; 
         } 
        }); 

是需要更新的唯一事情是填充颜色,所以这是你需要在你的代码来处理嘛。路径本身(d属性)保持原样。