TopoJSON - действительно мощный инструмент. Он имеет свой собственный CLI ( интерфейс командной строки ) для генерации ваших собственных файлов TopoJSON.
Этот CLI позволяет вам создать уникальный файл с топологией и данными, которые вы хотите объединить.
Несмотря на то, что версия v3.0.2 , первая версия выглядит для меня ясной. Это пример того, как вы можете объединить файл csv
с json
через общий атрибут id
.
# Simplified versión from https://bl.ocks.org/luissevillano/c7690adccf39bafe583f72b044e407e8
# note is using TopoJSON CLI v1
topojson \
-e data.csv \
--id-property CUSEC,cod \
-p population=+t1_1,area=+Shape_area \
-o cv.json \
-- cv/shapes/census.json
Существует файл data.csv
со столбцом cod
и файл census.json
со свойством с именем CUSEC
.
- Используя --id-property
, вы можете указать, какие атрибуты будут использоваться при слиянии.
- С помощью свойства -p
вы можете создавать новые свойства на лету .
Это надежное решение, в котором вы используете один уникальный файл (с одним уникальным запросом ) со всеми данными. Этот лучший сценарий не всегда возможен, поэтому следующим может быть другое решение.
Возвращаясь к JavaScript
, вы можете создать новую переменную, доступную через общий атрибут, следующим образом. Имея ваши данные в формате:
// countryStatistics
{
"idTopo": "004",
"country": "Afghanistan",
"countryCode": "afg",
// ..
},
И ваш файл TopoJSON имеет структуру:
{"type":"Polygon","arcs":[[0,1,2,3,4,5]],"id":"004"},
{"type":"MultiPolygon","arcs":[[[6,7,8,9]],[[10,11,12]]],"id":"024"} // ...
Распространенным решением ситуации такого типа является создание переменной Array
, доступной для этого idTopo
:
var dataById = [];
countryStatistics.forEach(function(d) {
dataById[d.idTopo] = d;
});
Тогда эта переменная будет иметь следующую структуру:
[
004:{
"idTopo": "004",
"country": "Afghanistan",
"countryCode": "afg",
//...
},
008: {
//...
}
]
Отсюда вы можете получить доступ к свойствам через атрибут idTopo
, например:
dataById['004'] // {"idTopo":"004","country":"Afghanistan","countryCode":"afg" ...}
Вы можете выполнить итерацию данных Topo и добавить следующие свойства для каждой функции:
var countries = topojson
.feature(data, data.objects.countries)
.features.map(function(d) {
d.properties = dataById[d.id];
return d
});
Или используйте этот массив, когда вам это нужно
// ...
.on("mouseover", function(d) {
d3.select(this).classed("hovered", true);
console.log(dataById[d.id]);
});