在d3中绘制人口普查轨迹和人口的地图

时间:2017-05-05 12:35:10

标签: javascript d3.js

这是我的要点,所有内容都已到位。为什么不绘制人口和大片数据呢?



var width = 960, height = 500;
var data; // declare a global variable 
var svg = d3.select('body').append('svg')
  .attr('width', width)
  .attr('height', height)
var threshold = d3.scaleThreshold()
  .domain([1, 10, 20, 200, 800, 2000, 5000, 10000])
  .range(d3.schemeOrRd[9]);

d3.queue()
  .defer(d3.json, 'https://umbcvis.github.io/classes/class-12/tracts.json')
  .defer(d3.json, 'https://umbcvis.github.io/classes/class-12/population.json')
  .await(ready);

// Note: scale and translate will be determined by the data
var projection = d3.geoConicConformal()
  .parallels([38 + 18 / 60, 39 + 27 / 60])
  .rotate([77, -37 - 40 / 60]);

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

function ready(error, json, population) {
  if (error) throw error;

  // Convert topojson to GeoJSON
  geojson = topojson.feature(json, json.objects.tracts);
  tracts = geojson.features;

  // Set the projection's scale and translate based on the GeoJSON
  projection.fitSize([960, 500], geojson);

  // Extract an array of features (one tract for each feature)
  tracts.forEach(function(tract) {
    var countyfips = tract.properties.COUNTYFP;
    var tractce = tract.properties.TRACTCE;
    pop = population.filter(function(d) {
      return (d[2] === countyfips) &&
        (d[3] === tractce);
    });
    pop = +pop[0][0];
    var aland = tract.properties.ALAND / 2589975.2356;

    //area in square miles
    tract.properties.density = pop / aland;
  });
  svg.selectAll('path.tract')
    .data(tracts)
    .enter()
    .append('path')
    .attr('class', 'tract')
    //        .attr('d', path)
    .style('fill', function(d) {
      return threshold(d.properties.density);
    })
    .style('stroke', '#000')

  // Draw all counties in MD
  fips = geojson.features.map(function(d) {
    return d.properties.COUNTYFP;
  });
  uniqueFips = d3.set(fips).values();
  counties = uniqueFips.map(function(fips) {
    return json.objects.tracts.geometries
      .filter(function(d) {
        return d.properties.COUNTYFP === fips;
      });
  });
  counties = counties.map(function(county) {
    return topojson.merge(json, county);
  })
  svg.selectAll("path.county")
    .data(counties)
    .enter()
    .append('path')
    .attr('class', 'county')
    .attr('d', path)
    .style('stroke', 'red')
    .style('stroke-width', '2px')
    .style('fill', 'none');

  // 1. NEW: Define an array with Rockville MD longitude & latitude
  var Rockville = [-77.1528, 39.0840];
  // 2. NEW: Add an HTML <div> element that will function as the tooltip
  var tooltip = d3.select('body').append('div')
    .attr('class', 'tooltip')
    .text('Hello, world!')
  // 3. NEW: Add a draggable circle to the map
  // See: https://bl.ocks.org/mbostock/22994cc97fefaeede0d861e6815a847e)
  var layer2 = svg.append("g");
  layer2.append("circle")
    .attr("class", "Rockville")
    .attr("cx", projection(Rockville)[0])
    .attr("cy", projection(Rockville)[1])
    .attr("r", 10)
    .style("fill", "yellow") // Make the dot yellow
    .call(d3.drag() // Add the drag behavior
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

  //Add legend

  addLegend();
}

function addLegend() {
  var formatNumber = d3.format("d");
  var x = d3.scalePow().exponent('.15')
    .domain([1, 80000])
    .range([0, 300]);
  var xAxis = d3.axisBottom(x)
    .tickSize(13)
    .tickValues(threshold.domain())
    .tickFormat(formatNumber)
  var g = svg.append("g")
    .attr('transform', 'translate(100, 200)')
    .call(xAxis);
  g.select(".domain")
    .remove();
  g.selectAll("rect")
    .data(threshold.range().map(function(color) {
      var d = threshold.invertExtent(color);
      if (d[0] == null) d[0] = x.domain()[0];
      if (d[1] == null) d[1] = x.domain()[1];
      return d;
    }))
    .enter().insert("rect", ".tick")
    .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 threshold(d[0]);
    });
  g.append("text")
    .attr("fill", "#000")
    .attr("font-weight", "bold")
    .attr("text-anchor", "start")
    .attr("y", -6)
    .text("Population per square mile");
}

function dragstarted(d) {
  d3.select(this).raise().classed("active", true);
}

function dragged(d) {
  d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}

function dragended(d) {
  d3.select(this).classed("active", false);
}
&#13;
path {
  fill: #555555;
  stroke: #aaaaaa;
}

body {
  position: absolute;
  margin: 0px;
  font: 16px sans-serif;
}

.info {
  color: #000;
  position: absolute;
  top: 450px;
  left: 800px;
}

.tooltip {
  position: absolute;
  visibility: visible;
  background-color: #aaa;
  padding: 5px;
}


/* This style is used when dragging the dot */

.active {
  stroke: #000;
  stroke-width: 2px;
}

path {
  fill: #555555;
  stroke: #aaaaaa;
}

svg {
  background-color: #4682b4;
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
&#13;
&#13;
&#13;

要点: https://bl.ocks.org/MTClass/0fb9c567311cfd2ea31f884a974fd246

1 个答案:

答案 0 :(得分:0)

您尚未为您的小册子定义路径:

  svg.selectAll('path.tract')
    .data(tracts)
    .enter()
    .append('path')
    .attr('class', 'tract')
    //        .attr('d', path)
    .style('fill', function(d) {
      return threshold(d.properties.density);
    })
    .style('stroke', '#000')

出于某种原因,这被注释掉了:

.attr('d', path)

所以你的小册子没有形状。

例如: <path class="tract" style="fill: rgb(215, 48, 31); stroke: rgb(0, 0, 0);"></path>

尝试取消注释该行,您应该得到:

enter image description here

var width = 960, height = 500;
var data; // declare a global variable 
var svg = d3.select('body').append('svg')
  .attr('width', width)
  .attr('height', height)
var threshold = d3.scaleThreshold()
  .domain([1, 10, 20, 200, 800, 2000, 5000, 10000])
  .range(d3.schemeOrRd[9]);

d3.queue()
  .defer(d3.json, 'https://umbcvis.github.io/classes/class-12/tracts.json')
  .defer(d3.json, 'https://umbcvis.github.io/classes/class-12/population.json')
  .await(ready);

// Note: scale and translate will be determined by the data
var projection = d3.geoConicConformal()
  .parallels([38 + 18 / 60, 39 + 27 / 60])
  .rotate([77, -37 - 40 / 60]);

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

function ready(error, json, population) {
  if (error) throw error;

  // Convert topojson to GeoJSON
  geojson = topojson.feature(json, json.objects.tracts);
  tracts = geojson.features;

  // Set the projection's scale and translate based on the GeoJSON
  projection.fitSize([960, 500], geojson);

  // Extract an array of features (one tract for each feature)
  tracts.forEach(function(tract) {
    var countyfips = tract.properties.COUNTYFP;
    var tractce = tract.properties.TRACTCE;
    pop = population.filter(function(d) {
      return (d[2] === countyfips) &&
        (d[3] === tractce);
    });
    pop = +pop[0][0];
    var aland = tract.properties.ALAND / 2589975.2356;

    //area in square miles
    tract.properties.density = pop / aland;
  });
  svg.selectAll('path.tract')
    .data(tracts)
    .enter()
    .append('path')
    .attr('class', 'tract')
    .attr('d', path)
    .style('fill', function(d) {
      return threshold(d.properties.density);
    })
    .style('stroke', '#000')

  // Draw all counties in MD
  fips = geojson.features.map(function(d) {
    return d.properties.COUNTYFP;
  });
  uniqueFips = d3.set(fips).values();
  counties = uniqueFips.map(function(fips) {
    return json.objects.tracts.geometries
      .filter(function(d) {
        return d.properties.COUNTYFP === fips;
      });
  });
  counties = counties.map(function(county) {
    return topojson.merge(json, county);
  })
  svg.selectAll("path.county")
    .data(counties)
    .enter()
    .append('path')
    .attr('class', 'county')
    .attr('d', path)
    .style('stroke', 'red')
    .style('stroke-width', '2px')
    .style('fill', 'none');

  // 1. NEW: Define an array with Rockville MD longitude & latitude
  var Rockville = [-77.1528, 39.0840];
  // 2. NEW: Add an HTML <div> element that will function as the tooltip
  var tooltip = d3.select('body').append('div')
    .attr('class', 'tooltip')
    .text('Hello, world!')
  // 3. NEW: Add a draggable circle to the map
  // See: https://bl.ocks.org/mbostock/22994cc97fefaeede0d861e6815a847e)
  var layer2 = svg.append("g");
  layer2.append("circle")
    .attr("class", "Rockville")
    .attr("cx", projection(Rockville)[0])
    .attr("cy", projection(Rockville)[1])
    .attr("r", 10)
    .style("fill", "yellow") // Make the dot yellow
    .call(d3.drag() // Add the drag behavior
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

  //Add legend

  addLegend();
}

function addLegend() {
  var formatNumber = d3.format("d");
  var x = d3.scalePow().exponent('.15')
    .domain([1, 80000])
    .range([0, 300]);
  var xAxis = d3.axisBottom(x)
    .tickSize(13)
    .tickValues(threshold.domain())
    .tickFormat(formatNumber)
  var g = svg.append("g")
    .attr('transform', 'translate(100, 200)')
    .call(xAxis);
  g.select(".domain")
    .remove();
  g.selectAll("rect")
    .data(threshold.range().map(function(color) {
      var d = threshold.invertExtent(color);
      if (d[0] == null) d[0] = x.domain()[0];
      if (d[1] == null) d[1] = x.domain()[1];
      return d;
    }))
    .enter().insert("rect", ".tick")
    .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 threshold(d[0]);
    });
  g.append("text")
    .attr("fill", "#000")
    .attr("font-weight", "bold")
    .attr("text-anchor", "start")
    .attr("y", -6)
    .text("Population per square mile");
}

function dragstarted(d) {
  d3.select(this).raise().classed("active", true);
}

function dragged(d) {
  d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}

function dragended(d) {
  d3.select(this).classed("active", false);
}
path {
  fill: #555555;
  stroke: #aaaaaa;
}

body {
  position: absolute;
  margin: 0px;
  font: 16px sans-serif;
}

.info {
  color: #000;
  position: absolute;
  top: 450px;
  left: 800px;
}

.tooltip {
  position: absolute;
  visibility: visible;
  background-color: #aaa;
  padding: 5px;
}


/* This style is used when dragging the dot */

.active {
  stroke: #000;
  stroke-width: 2px;
}

path {
  fill: #555555;
  stroke: #aaaaaa;
}

svg {
  background-color: #4682b4;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>