Ich möchte mit D3, a la, ein World Choropleth für die Anzeige abbilden:
Ich möchte einen Datensatz anzeigen, der mit ISO-Alpha-3-Schlüsseln verschlüsselt ist. So...
danger.csv
iso,level
AFG,100
ALB,0
DZA,12
etc.
Wenn ich den Anweisungen auf topojson folge, weiß ich, dass ich ...
wget "http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_0_countries.zip"
unzip ne_50m_admin_0_countries.zip
ogr2ogr -f "GeoJSON" output_features.json ne_50m_admin_0_countries.shp -select iso_a3
topojson -o topo.json output_features.json --id-property iso_a3
um eine Weltkarte json zu erstellen, die von ISO3 identifiziert wurde.
Meine Frage ist: Zu welchem Zeitpunkt im Workflow sollte ich die Daten von danger.csv mit den Geodaten zusammenführen? Ich hatte zuvor mit qGIS als GUI gearbeitet, aber wo / sollte / passiert die Zusammenführung? In der .shp? Nach dem Ogr2ogr? Dynamisch im Browser nach dem Topojson-Shrink (wie hier http://bl.ocks.org/mbostock/4060606 http://bl.ocks.org/mbostock/3306362 )?
Ich verstehe mich ziemlich gut mit Python, aber JavaScript ist noch ziemlich neu und ich kopiere und füge Bostock-Beispiele mehr ein, als dass ich dort ein generativer Programmierer bin.
(Ich habe auch eine verwandte, aber umfangreichere Nachverfolgung von Stackoverflow, die ich möglicherweise hier migrieren sollte: /programming/18604877/how-to-do-time-data-in-d3-maps )
Antworten:
Stellen Sie sich zwei Fragen:
Werden Sie die Geografie für mehrere Datensätze wiederverwenden?
Wenn Sie dieselbe Geografie mit mehreren Datensätzen verwenden, ist es sinnvoll, die Geografie und die Daten getrennt zu halten und sie im Client zusammenzuführen. Viele meiner Beispiele haben aus diesem Grund separate CSV- (oder TSV-) Dateien. Auf diese Weise kann TopoJSON für US-Bundesstaaten und Grafschaften oder auch für Länder der Welt wiederverwendet werden, anstatt für jedes Beispiel ein eigenes TopoJSON zu erstellen.
Wenn Sie diese Geografie jedoch nur einmal verwenden , sollten Sie die Daten wahrscheinlich als Eigenschaften in die Geografie „backen“, um den Code zu vereinfachen. Dieser Ansatz ist einfacher, da Sie nur eine einzige Datei laden müssen (also keine queue.js ) und da die Daten als Eigenschaften jedes Features gespeichert werden, müssen Sie die Daten nicht im Client verknüpfen (also kein d3). Karte ).
Randnotiz: TSV und CSV speichern Eigenschaften häufig wesentlich effizienter als GeoJSON und TopoJSON, da letztere die Eigenschaftsnamen für jedes Objekt wiederholen müssen. Die Dateigröße kann ein weiterer Grund sein, Ihre Daten in einer separaten Datei zu speichern und im Client zu verknüpfen.
Sind Ihre Daten bereits an die Geografie gebunden (z. B. eine Eigenschaft Ihres Shapefiles)?
Angenommen, Sie haben auf die erste Frage mit "Nein" geantwortet und möchten die Daten in die Geografie einbrennen (und nicht im Client). Wie Sie dies tun, hängt vom Format der Daten ab.
Wenn Ihre Daten bereits eine Eigenschaft Ihres Shapefiles sind, können Sie
topojson -p
steuern, welche Eigenschaften in der generierten TopoJSON-Datei gespeichert werden. Sie können damit auch Eigenschaften umbenennen und in Zahlen umwandeln. Siehe Machen wir eine Karte für Beispiele.Befinden sich Ihre Daten in einer separaten CSV- oder TSV-Datei, geben Sie mit topojson -e (zusätzlich zu
-p
) eine externe Eigenschaftendatei an , die mit Ihren geografischen Features verknüpft werden kann. Cribbing das Beispiel aus dem Wiki, wenn Sie eine TSV-Datei wie folgt hatten:Mit
-e
können Sie diese einer numerischen Ausgabeeigenschaft mit dem Namen "Arbeitslosigkeit" zuordnen:Ein Beispiel für diesen Ansatz ist die Bevölkerung von Kentucky, bl.ocks.org/5144735 .
quelle
Gute Frage. Eines der von Ihnen angegebenen Beispiele scheint den Trick zu tun, obwohl es schwer zu befolgen ist.
Sie werden feststellen, dass das Beispiel zwei externe Datendateien hat, us.json und unemployment.tsv . Sie können sich "unemployment.tsv" als Ihre Gefahr vorstellen. us.json sind die geografischen Merkmale, mit denen Sie Parameter aus danger.csv verknüpfen möchten. Letzterer, unemployment.tsv, hat
id
undrate
Felder, in denenid
derselbe ist wie derid
in us.json.Im Client mit D3 sollten Sie Ihre Daten und Funktionen zumindest anhand dieses Beispiels zusammenführen. Im Client wird die Arbeitslosenquote in diesem Beispiel mithilfe der Funktion d3.map () mit den County-Features verknüpft . Hier wird es initialisiert:
Und hier
rate
wird folgendes abgebildetid
:Ich muss zugeben, dass ich nicht weiß, wofür es
queue()
ist, aber es ist nicht wichtig für diese Diskussion. Was wichtig ist, ist, dassdasAuf das kannid
Feld in jedem County-Feature durch die Arbeitslosigkeit ersetzt wirdrate
.rate
jetzt über die gemeinsam genutzte ID zugegriffen werdenid
( BEARBEITEN: Wie @ blord-castillo hervorhebt, ist dies tatsächlich die Erzeugung eines neuen assoziativen Arrays oder Schlüssel-Hash, bei dem das dem zugeordnetrate
istid
). Hier wird derrate
zum Zwecke der Symbologie aufgerufen (hier stehen für jedes Quantil vordefinierte CSS-Klassen zur Verfügung):Wobei die
quantize()
Funktion den Namen der CSS-Klasse zurückgibt, die verwendet werden soll, um dieses Feature (Landkreis) basierend auf seiner Arbeitslosenquote zu formatieren, die jetzt imid
Feld des Features definiert ist.quelle
Zunächst muss die erste Zeile Ihrer CSV eine durch Kommas getrennte Liste von Spaltennamen sein, um diese Methode verwenden zu können. Wenn dies nicht möglich ist, geben Sie einen Kommentar dazu ein und ich werde sehen, ob ich herausfinden kann, wie ich es
d3.csv.parseRows
anstelle von verwenden solld3.csv.parse
.d3.csv.parse
wird von der Prüferfunktion aufgerufen.defer(function, url, assessor)
.Ich gehe davon aus, dass Ihre Datei jetzt so aussieht:
Auf diese Weise können Sie einen Nachschlage-Hash von ISO3 bis zur Gefahrenstufe erstellen.
Code-Komplettlösung
Zuerst erstellen Sie ein d3.map () -Objekt, das als Ihr Schlüssel-Hash fungiert, und speichern dieses in der Variablen dangerByISO3.
Verwenden Sie die Warteschlange zum parallelen Laden.
Laden Sie Ihren Topojson als erstes Argument, das an die Funktion await übergeben wird (nach einem Fehler). Beachten Sie hier den Stil, bei dem es sich um eine verkettete Funktion handelt
queue()
, die jedoch in einer separaten Zeile aufgeführt ist (kein abschließendes Semikolonqueue()
).Hier passieren zwei Dinge. Zunächst laden Sie danger.csv als zweites Argument, das an die Funktion await übergeben werden soll. Wie Sie weiter unten sehen werden, wird dieses Argument nicht verwendet. Stattdessen wird der Ladefunktion d3.csv ein Prüferargument bereitgestellt. Dieser Prüfer verarbeitet jede Zeile der CSV. In diesem Fall rufen wir die set-Funktion auf dangerByISO3 auf, sodass wir für jede Tastenkombination
iso
denlevel
als Wert für diesen Schlüssel festlegen . Die+d.level
Notation verwendet unary+
, um den Wert von d.level in eine Zahl umzuwandeln.Sobald beide Datenquellen geladen sind, werden sie als zwei separate Argumente an die Funktion übergeben
ready()
. Das erste Argument für den Rückruf ist immer der erste aufgetretene Fehler. Wenn kein Fehler aufgetreten ist, wird null als erstes Argument übergeben. Das zweite Argument ist die erste Datenquelle (Ergebnis der ersten Aufgabe) und das dritte Argument ist die zweite Datenquelle (Ergebnis der zweiten Aufgabe).Dies ist die Rückruffunktion
ready()
. Zuerst nehmen wir daserror
Argument, das null sein sollte, wenn die beiden Ladetasks erfolgreich abgeschlossen wurden (Sie sollten tatsächlich eine Sprache hinzufügen, um Fehler abzufangen und zu behandeln). Als nächstes nehmen wir die Topojson-Daten als Objektcountries
. Diese Daten sollten im Hauptteil der Funktion mit so etwas wie verarbeitet werden.data(topojson.feature(world,world.objects.countries).features)
. Daready()
es kein drittes Argument gibt, wird das Ergebnis der zweiten Aufgabe, unser csv, einfach verworfen. Wir haben es nur verwendet, um den Schlüssel-Hash zu erstellen und brauchten ihn danach nicht mehr.quelle