2017-10-01 4 views
1

Ich versuche eine Choroplethe Karte von US-Counties, und verwende im Wesentlichen Mike Bostock Beispiel von hier https://bl.ocks.org/mbostock/4060606 Ich benutze Bildung statt Arbeitslosigkeit, aber ansonsten ist es das gleiche. Ich möchte nur ein weiteres Stück hinzufügen und den Landnamen zusammen mit der Rate anzeigen lassen. Wenn ich jedoch den Kreisnamen anrufe, bekomme ich "undefined" zurück. Um klar zu sein, "Rate" kommt gut zurück, "County" erscheint undefined. Kann jemand helfen? Vielen Dank!Choropleth Karte zurück undefined

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

 
.counties { 
 
    fill: none; 
 
    /*stroke: black;*/ 
 
} 
 

 
.states { 
 
    fill: none; 
 
    stroke: #fff; 
 
    stroke-linejoin: round; 
 
} 
 

 
</style> 
 
<svg width="960" height="600"></svg> 
 
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> 
 
<script src="https://d3js.org/topojson.v2.min.js"></script> 
 
<script> 
 

 
var svg = d3.select("svg"), 
 
    width = +svg.attr("width"), 
 
    height = +svg.attr("height"); 
 

 
var Bachelor = d3.map(); 
 

 
var path = d3.geoPath(); 
 

 
var x = d3.scaleLinear() 
 
    .domain([0, 70]) 
 
    .rangeRound([600, 860]); 
 

 
var color_domain = [10, 20, 30, 40, 50, 60, 70] 
 
var ext_color_domain = [10, 20, 30, 40, 50, 60, 70] 
 
var color = d3.scaleThreshold() 
 
    .domain(color_domain) 
 
    .range([" #85c1e9", "#5dade2", "#3498db", "#2e86c1", "#2874a6", " #21618c"," #1b4f72"]); 
 
var g = svg.append("g") 
 
    .attr("class", "key") 
 
    .attr("transform", "translate(0,40)"); 
 

 
g.selectAll("rect") 
 
    .data(color.range().map(function(d) { 
 
     d = color.invertExtent(d); 
 
     if (d[0] == null) d[0] = x.domain()[0]; 
 
     if (d[1] == null) d[1] = x.domain()[1]; 
 
     return d; 
 
    })) 
 
    .enter().append("rect") 
 
    .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 color(d[0]); }); 
 

 
g.append("text") 
 
    .attr("class", "caption") 
 
    .attr("x", x.range()[0]) 
 
    .attr("y", -6) 
 
    .attr("fill", "#000") 
 
    .attr("text-anchor", "start") 
 
    .attr("font-weight", "bold") 
 
    .text("% of Adults with Bachelor's or higher"); 
 

 
g.call(d3.axisBottom(x) 
 
    .tickSize(13) 
 
    .tickFormat(function(x, i) { return i ? x : x; }) 
 
    .tickValues(color.domain())) 
 
    .select(".domain") 
 
    .remove(); 
 

 
d3.queue() 
 
    .defer(d3.json, "https://d3js.org/us-10m.v1.json") 
 
    .defer(d3.tsv, "Bachelor2.tsv", function(d) { Bachelor.set(d.id, d.rate, d.county); }) 
 
    .await(ready); 
 

 

 
function ready(error, us) { 
 
    if (error) throw error; 
 

 

 
    svg.append("g") 
 
     .attr("class", "counties") 
 
    .selectAll("path") 
 
    .data(topojson.feature(us, us.objects.counties).features) 
 
    .enter().append("path") 
 
     .attr("fill", function(d) { return color(d.rate = Bachelor.get(d.id)); }) 
 
     .attr("d", path) 
 
    .append("title") 
 
     .text(function(d) { return (d.county +" " d.rate +"%"); }); 
 

 
    svg.append("path") 
 
     .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })) 
 
     .attr("class", "states") 
 
     .attr("d", path); 
 
} 
 

 
</script>

+0

Wenn Sie Ihre Kartendaten [us-10m.v1.json] (https://d3js.org/us-10m.v1.json) einchecken, werden keine Landnamen existieren. Sie sollten also lieber eine andere Kartendaten ändern. – 1Cr18Ni9

+0

@ 1Cr18Ni9 Der ursprüngliche Code verwendet eine Karte, um die "Rate" einzustellen. OP versuchte, die gleiche Karte für das "Land" zu verwenden. –

+0

@Gerardo Sie haben Recht! – 1Cr18Ni9

Antwort

0

Es gibt zwei Probleme in Ihrem Code.

Das erste Problem in Ihrem Code liegt hier:

Bachelor.set(d.id, d.rate, d.county); 

In beiden javascript maps und D3 Karten (die etwas anders sind), können Sie nicht zwei Werte für den gleichen Schlüssel eingestellt werden. Daher hat die Syntax sein:

map.set (Schlüssel, Wert)

Sagen wir es zeigen.

Dies funktioniert, Einstellen des Wertes "bar" zu "foo":

var myMap = d3.map(); 
 
myMap.set("foo", "bar"); 
 
console.log(myMap.get("foo"))
<script src="https://d3js.org/d3.v4.min.js"></script>

aber das wird nicht funktionieren:

var myMap = d3.map(); 
 
myMap.set("foo", "bar", "baz"); 
 
console.log(myMap.get("foo"))
<script src="https://d3js.org/d3.v4.min.js"></script>

Wie Sie sehen können, wurde der Wert "baz" nicht gesetzt.

Das wurde davon ausgegangen, dass country eine Eigenschaft in Ihrer Bachelor2.tsv Datei ist. Und das bringt uns zum zweiten Problem:

In den Pfad, ist dies die Daten:

topojson.feature(us, us.objects.counties).features 

Wenn Sie Ihren Code suchen, können Sie eine Eigenschaft namens rate (Ihre Karte verwenden) auf diese Daten ...

.attr("fill", function(d) { return color(d.rate = Bachelor.get(d.id)); }) 
//you set 'rate' to the datum here --------^ 

... aber Sie haben nie eine Eigenschaft mit dem Namen country festgelegt. Daher gibt es keine solche Eigenschaft, die Sie in den Rückrufen verwenden können.

Wie oben beschrieben, können Sie es nicht mit der gleichen Karte einstellen, mit der Sie die rate festgelegt haben. Eine Lösung verwendet stattdessen ein Objekt. Alternativ könnten Sie auch zwei Karten verwenden, was die schnellste Option zu sein scheint.

+0

Danke Gerardo. Ich habe mich gefragt, ob zwei Karten die einfachste Option sein könnten. Ich schätze die Hilfe! –