sprucegoose
sprucegoose

Reputation: 610

get d3.extent of property from a shapefile to use as domain

I have a geojson file and am generating a map with D3. I'm creating a choropleth, and using a property in the json file to color the areas of the map. For the color scale, I'm using d3.scale.quantile(). If I set the domain manually, it works fine. However, I'm trying to pull the extent of the property in my json file to use as the domain, and am getting NaN instead of values. The property is called "someno".

Here is a Plunker that shows what I tried. Code is below, too.

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

    <style>
    #boroughs {
      stroke: none;
        stroke-width: 0px;
        fill: #ddd;
        opacity:.7;
        position:absolute;
        top:0;
        left:0;
    }
    #legendcontainer{
      position: absolute;
      bottom:10px;
      right:10px;
    }
    </style>

    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="http://d3js.org/topojson.v0.min.js"></script>

    <body>
    <div id="legendcontainer"></div>
    <script>

    var width = Math.max(960, window.innerWidth),
        height = Math.max(500, window.innerHeight);

    var container = d3.select("body").append("div")
            .attr("id", "container")
            .style("width", width + "px")
            .style("height", height + "px");

    var projection = d3.geo.mercator()
            .center([-73.94, 40.70])
            .scale(80000)
            .translate([(width) / 2, (height)/2]);

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

    d3.json("nyc.json", function(error, nyb) {

    var map = container.append("svg")
            .attr("id", "boroughs")
            .style("width", width + "px")
            .style("height", height + "px");

    var chor = d3.scale.quantile()
        // I don't want to manually specify the domain. How can I get the extent of a property from my shapefile?
        .domain(d3.extent(nyb, function(d) { return d.properties.someno; }))
        // manually specifying the domain works:
        //.domain([0,100])
        .range(["#f8eb60", "#f6bd5a", "#f09253", "#ec654a"]);

    map.selectAll("path")
            .data(nyb.features)
            .enter().append("path")
            .attr("class", function(d){ return d.properties.borough; })
            .attr("d", path)
        .attr("fill", function(d) {
          return chor(d.properties.someno);
        });

        legendheader = d3.select("#legendcontainer")
            .append("p")
            .append("text")
            .text("Legend")
            .style("font-size", "16px");

            var leg = d3.select("#legendcontainer").append("svg");
            var legend = leg.selectAll('g.legendEntry')
            .data(chor.range())
            .enter()
            .append('g').attr('class', 'legendEntry');

            legend
                .append('rect')
                .attr("x", 10)
                .attr("y", function(d, i) {
                   return (i * 20) + 5;
                })
               .attr("width", 15)
               .attr("height", 15)
               .style("stroke", "none")
               .attr("fill", function(d){ return d; });

            legend
               .append('text')
               .attr("x", 35)
               .attr("y", function(d, i) {
                  return (i * 20) + 5;
               })
               .attr("dy", "0.8em")
               .text(function(d,i) {
                   var extent = chor.invertExtent(d);
                   return +extent[0] + " - " + +extent[1];
               })
               .style("font-size", "14px");

    });

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

Upvotes: 0

Views: 186

Answers (1)

Kasper Pedersen
Kasper Pedersen

Reputation: 516

Looks like you're passing the wrong thing to d3.extent.

Should be the features-array not the whole nyb object:

d3.extent(nyb.features, function(d) { return d.properties.someno; })

Upvotes: 1

Related Questions