基于人口的彩色编码地图

时间:2013-10-30 05:49:24

标签: json d3.js mapping heatmap

美好的一天,

我在svg中的着色遇到了麻烦。我创建了一个简单的地图,我想根据他们的人口为国家着色......

这是我的代码..

       <!DOCTYPE html>
       <html lang="en">
       <head>
       <meta charset="utf-8">
       <title>World Population</title>
       <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
       <script type="text/javascript" src="http://d3js.org/queue.v1.min.js"></script>
       <script type="text/javascript" src="http://d3js.org/topojson.v1.min.js">
       </script> 
        </head>
           <style>

              path {
               stroke:white;
               stroke-width: 1px;
               }

               body {
               font-family: Arial, sans-serif;
               }

             .country {
              font: 10px sans-serif;
              font-weight: bold;
              }

             .legend {
              font-size: 12px;
             }

             div.tooltip {   
            position: absolute;           
           text-align: center;           
           width: 150px;                  
           height: 25px;                 
          padding: 2px;             
           font-size: 10px;     
             background: #FFFFE0;
          border: 1px;      
           border-radius: 8px;           
           pointer-events: none;         
            }        
            </style>
              <body>
              <script type="text/javascript">
               var width = 960,
                height = 500;

      // Setting color domains(intervals of values) for our map

  var color_domain = [50, 150, 350, 750, 1500]
  var ext_color_domain = [0, 50, 150, 350, 750, 1500]
  var legend_labels = ["< 50", "50+", "150+", "350+", "750+", "> 1500"]
  var color = d3.scale.threshold()
  .domain(color_domain)
  .range(["#adfcad", "#ffcb40", "#ffba00", "#ff7d73", "#ff4e40", "#ff1300"]);

  var div = d3.select("body").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);

  var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .style("margin", "10px auto");


  var projection = d3.geo.equirectangular()
   .center([0, 5])
   .scale(150)
   .translate([width / 2, height / 2])
   .rotate([0, 0])
   .precision(.9);

  //var projection = d3.geo.albers()
  //.rotate([-105, 0])
  //.center([-10, 65])
  //.parallels([52, 64])
  //.scale(700)
  //.translate([width / 2, height / 2]);

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

  //Reading map file and data

  queue()
  //    .defer(d3.json, "Script/topojson/examples/russia.json")
  .defer(d3.json, "Script/topojson/examples/world-110m.json")
  .defer(d3.csv, "data/accidents.csv")
  .await(ready);

  //Start of Choropleth drawing

  function ready(error, world, data) {
      var rateById = {};
      var nameById = {};

      data.forEach(function (d) {


          rateById[d.RegionCode] = +d.Deaths;
          nameById[d.RegionCode] = d.RegionName;
      });

      //Drawing Choropleth

      svg.append("g")
      .attr("class", "path")
      .selectAll("path")

      .data(topojson.feature(world, world.objects.countries).features)
      .enter().append("path")
      .attr("d", path)
      .style("fill", function (d) {
          return color(rateById[d.properties.RegionName]);
      })
      .style("opacity", 0.8)

      //Adding mouseevents
      .on("mouseover", function (d) {
          d3.select(this).transition().duration(300).style("opacity", 1);
          div.transition().duration(300)
          .style("opacity", 1)
          div.text(nameById[d.properties.countries] + " : " +  
                rateById[d.properties.countries])
          .style("left", (d3.event.pageX) + "px")
          .style("top", (d3.event.pageY - 30) + "px");
      })
      .on("mouseout", function () {
          d3.select(this)
          .transition().duration(300)
          .style("opacity", 0.8);
          div.transition().duration(300)
          .style("opacity", 0);
      })

      // Adding cities on the map

      d3.csv("data/s.csv", function (error, data) {
          var city = svg.selectAll("g.country")
          .data(data)
          .enter()
          .append("g")
          .attr("class", "country")
          .attr("transform", function (d) { return "translate(" + projection([d.lon, d.lat]) + ")"; });

          city.append("circle")
          .attr("r", 3)
          .style("fill", "lime")
          .style("opacity", 0.75);

          city.append("text")
          .attr("x", 5)
          .text(function (d) { return d.countries; });
      });

  }; // <-- End of Choropleth drawing

  //Adding legend for our Choropleth

  var legend = svg.selectAll("g.legend")
  .data(ext_color_domain)
  .enter().append("g")
  .attr("class", "legend");

  var ls_w = 20, ls_h = 20;

  legend.append("rect")
  .attr("x", 20)
  .attr("y", function (d, i) { return height - (i * ls_h) - 2 * ls_h; })
  .attr("width", ls_w)
  .attr("height", ls_h)
  .style("fill", function (d, i) { return color(d); })
  .style("opacity", 0.8);

  legend.append("text")
  .attr("x", 50)
  .attr("y", function (d, i) { return height - (i * ls_h) - ls_h - 4; })
  .text(function (d, i) { return legend_labels[i]; });

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

这是我的整个代码..

这是我的数据

      id,   RegionCode, RegionName,    Population   
      608,  PHL,        Philippines,   10500              
      124,  CAN,            Canada,        2540                    
      156,  CHN,            China,         95874                    

这是我的其他数据

          country,lat,lon
           PHILIPPINES,13,122
           CANADA,60,-95             
           CHINA,35,105

颜色必须保护国家的人口数

我遇到了foreach的麻烦。未定义的错误

3 个答案:

答案 0 :(得分:1)

问题是代码中的一个简单错误。您需要引用cId[d.Population]

,而不是引用cId[d.id]

答案 1 :(得分:0)

另一个问题为什么在我的鼠标悬停时它为人口返回NAN?

       <!DOCTYPE html>
         <html lang="en">
          <head>
          <meta charset="utf-8">
          <title>Population - Choropleth</title>

<script src="Scripts/d3.v3.min.js" ></script>
<script src="Scripts/queue.v1.min.js"></script>
<script src="Scripts/topojson.v1.min.js"></script>
<!--<script type="text/javascript" src="http://d3js.org/d3.v3.min.js" charset="utf-8">                 </script>-->


     </head>
      <style>

      path {
        stroke:white;
        stroke-width: 1px;
    }

    body {
 font-family: Arial, sans-serif;
   }

       .city {
        font: 10px sans-serif;
          font-weight: bold;
      }

     .legend {
     font-size: 12px;
      }

     div.tooltip {   
      position: absolute;           
      text-align: center;           
     width: 200px;                  
    height: 80px;                 
        padding: 2px;             
     font-size: 10px;     
      background: #FFFFE0;
     border: 1px;      
      border-radius: 8px;           
        pointer-events: none;  
      font-family:'Courier New';
      font-size:medium;      
 }        
  </style>
       <body>
    <script type="text/javascript">
  var width = 900,
        height = 400;

  // Setting color domains(intervals of values) for our map

  var color_domain = [50, 150, 350, 750, 1500];
  var ext_color_domain = [0, 50, 150, 350, 750, 1500];
  var legend_labels = ["< 50", "50+", "150+", "350+", "750+", "> 1500"];
  var color = d3.scale.log()
  .domain(color_domain)
  .range(["#adfcad", "#ffcb40", "#ffba00", "#ff7d73", "#ff4e40", "#ff1300"]);

  var div = d3.select("body").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);

  var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .style("margin", "10px auto");

  var projection = d3.geo.equirectangular()
  .center([0, 5])
    .scale(150)
    .translate([width / 2, height / 2])
    .rotate([0, 0])
    .precision(9);


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

  //Reading map file and data

  queue()

  .defer(d3.json, "Scripts/topojson/examples/world-110m.json")
  .defer(d3.csv, "data/accidents.csv")
  .await(ready);

  //Start of Choropleth drawing

  function ready(error, map, data) {
      var cId = {};
      var nameById = {};




      data.forEach(function (d) {
          cId[d.id] = +d.Population;
          nameById[d.id] = d.RegionName;

          //console.log(data);

      });

      // 
      //Drawing Choropleth
      svg.append("g")

      .attr("class", "region")
      .selectAll("path")
      //.data(topojson.object(map, map.objects.russia).geometries)

      .data(topojson.feature(map, map.objects.countries).features)
     .enter()
      .append("path")
     .attr("d", path)
      .style("fill", function (d) {
          return color(cId[d.id]);


      })
      //.style("opacity", 0.8)

      //Adding mouseevents
      .on("mouseover", function (d) {
          d3.select(this)
          .transition()
         .duration(300)
         .style("opacity", 1);
          div.transition()
          .duration(300)
          .style("opacity", 1)

          // div.text(nameById[d.id])//+""+cId[d.Population] // + " " + cid[d.Population])
          div.text("Country Name :" + nameById[d.id] + "' <br />'" + "Population :" + cId[d.Population])
      .style("left", (d3.event.pageX) + "px")
      .style("top", (d3.event.pageY - 30) + "px");
      })
      .on("mouseout", function () {
          d3.select(this)
          .transition().duration(300)
          .style("opacity", 0.8);
          div.transition().duration(300)
          .style("opacity", 0);
      })

      // Adding cities on the map

      //d3.tsv("cities.tsv", function (error, data) {
      d3.csv("data/s.csv", function (error, data) {


          var city = svg.selectAll("g.city")
          .data(data)
          .enter()
          .append("path")
          .attr("class", "city")
          .attr("transform", function (d) { return "translate(" + projection([d.lon, d.lat]) + ")"; });
          console.log(data)
          city.append("circle")
          .attr("r", 3)
          .style("fill", "lime")
          .style("opacity", 0.75);

          city.append("text")
          .attr("x", 5)
          .text(function (d) { return d.countries; });


      });

  }; // <-- End of Choropleth drawing

  //Adding legend for our Choropleth

  var legend = svg.selectAll("g.legend")
  .data(ext_color_domain)
  .enter().append("g")
  .attr("class", "legend");

  var ls_w = 20, ls_h = 20;

  legend.append("rect")
  .attr("x", 20)
  .attr("y", function (d, i) { return height - (i * ls_h) - 2 * ls_h; })
  .attr("width", ls_w)
  .attr("height", ls_h)
  .style("fill", function (d, i) { return color(d); })
  .style("opacity", 0.8);

  legend.append("text")
  .attr("x", 50)
  .attr("y", function (d, i) { return height - (i * ls_h) - ls_h - 4; })
  .text(function (d, i) { return legend_labels[i]; });

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

答案 2 :(得分:0)

尝试生成类似的HTML代码:

<table data-i2="css:[{color:'#888888'},{color:'#000000'}]">
    <tr data-i2="rate:1500">
        <td>Philippines</td>
        <td>1500</td>
    </tr>
    <tr data-i2="rate:2540">
        <td>Canada</td>
        <td>2540</td>
    </tr>
    <tr data-i2="rate:95874">
        <td>China</td>
        <td>95874</td>
    </tr>
</table>

然后调用i2ui方法:i2.emph()。

请参阅演示 - http://jsfiddle.net/AMjP9/