Я следил за руководством по хороплету с использованием D3 по этой ссылке. http://Synthese.sbecker.net/articles/2012/07/18/learning-d3-part-7-choropleth-maps
вместо безработицы у меня есть файл json, в котором указано количество автомобильных аварий по округам по штатам. Формат этого json-файла
{
"id":1001,
"crashTotal":2
},
И это для каждого из элементов в файле json; по одному на каждый округ. Идентификатор — это код штата + округа FIPS, а crashTotal — его тезка.
Я внимательно следил за кодом примера и наткнулся на функцию квантования.
// quantize function takes a data point and returns a number
// between 0 and 8, to indicate intensity, the prepends a 'q'
// and appends '-9'
function quantize(d) {
return "q" + Math.min(8, ~~(data[d.id] * 9 / 12)) + "-9";
}
Для меня данные — это набор переменных, равный файлу crashes.json. Я не понимаю, почему я не могу использовать значения crashTotal из своих данных для использования в соответствии с функцией квантования.
Когда я пытаюсь использовать следующий код
~~data[d.id] or +data[d.id]
Я получаю 0 или NaN. Почему это? Я новичок в использовании d3, поэтому я не уверен, как это должно работать. Спасибо.
Мой код очень близок к коду примера, но с моими JSON-файлами страны и штата США, преобразованными из шейп-файлов переписи. Кто-нибудь может помочь?
РЕДАКТИРОВАТЬ: я бы решил, что объясню проблему немного подробнее. Это не проблема между использованием функции квантования или квантования по шкале d3, а скорее в том, как получить доступ к моим данным, чтобы раскрасить каждый округ. Как уже говорилось, мой файл данных представляет собой JSON в формате, указанном выше. Ниже показано, как я устанавливаю данные и как я вызываю квантизацию.
d3.json("Crashes.json", function(crashes) {
max = +crashes[0].crashTotal;
min = +crashes[0].crashTotal;
maxFIPS = +crashes[0].id;
minFIPS = +crashes[0].id;
for(i = 0; i < crashes.length; i++) {
if(+crashes[i].crashTotal > max) {
maxFIPS = +crashes[i].id;
max = +crashes[i].crashTotal;
}
if(+crashes[i].crashTotal < min) {
minFIPS = +crashes[i].id;
min = +crashes[i].crashTotal;
}
}
data=crashes;
//for(i = 0; i < data.length; i++) {
// document.writeln(data[i].id + " " + data[i].crashTotal);
// }
counties.selectAll("path")
.attr("class", quantize);
//.text(function (d){return "" + d.value;});
//console.log("maxFIPS:" + maxFIPS + " minFIPS:" + minFIPS + "\n" + "max:" + max + " min:" + min);
});
function quantize(d) {
return "q" + Math.min(8, ~~data[d.id]) + "-9";
}
Если бы я заменил data[d.id] в приведенной выше функции квантизации, он бы фактически окрашивался в соответствии с цветовой схемой, указанной в скобках или документе CSS. Как мне заставить это использовать числа CrashTotal из моих данных?
РЕДАКТИРОВАТЬ [3-6-2014] После ответа Амелии у меня теперь есть следующая кодовая скобка.
d3.json("Crashes.json", function(crashes) {
crashDataMap = d3.map();
crashes.forEach(function(d) {crashDataMap.set(d.id, d);});
data = crashDataMap.values();
quantize = d3.scale.quantize()
.domain(d3.extent(data, function(d) {return d.crashTotal;}))
.range(d3.range(9).map(function(i) {return "q" + i + "-9"}));
//min = d3.min(crashDataMap.values(), function(d) {return d.crashTotal;});
//max = d3.max(crashDataMap.values(), function(d) {return d.crashTotal;});
//console.log(quantize(crashDataMap.get(6037).crashTotal));
counties.selectAll("path")
.attr("class", function(d) {return quantize(crashDataMap.get(d.id).crashTotal);});
});
Это должно дать мне правильный цвет для моей карты, но моя карта остается белой. Я могу подтвердить, что, тестируя квантизацию, я получаю правильное имя класса из моего файла CSS.
console.log(quantize(crashDataMap.get(1001).crashTotal)); //returns q0-9
Приветствуется дополнительная помощь. Спасибо.
EDIT2[3-6-2014] Я решил просто опубликовать весь код, который у меня есть здесь, надеясь, что кто-то сможет разобраться в безумии, почему это не работает.
//CSS or <style></style> bracket
svg {
background: white;
}
path {
fill: none;
stroke: #000;
stroke-width: 0.1px;
}
#counties path{
stroke: #000;
stroke-width: 0.25px;
}
#states path{
fill: none;
stroke: #000;
stroke-width: 0.5px;
}
.Blues .q0-9{fill:rgb(247,251,255)}
.Blues .q1-9{fill:rgb(222,235,247)}
.Blues .q2-9{fill:rgb(198,219,239)}
.Blues .q3-9{fill:rgb(158,202,225)}
.Blues .q4-9{fill:rgb(107,174,214)}
.Blues .q5-9{fill:rgb(66,146,198)}
.Blues .q6-9{fill:rgb(33,113,181)}
.Blues .q7-9{fill:rgb(8,81,156)}
.Blues .q8-9{fill:rgb(8,48,107)}
//Crashes.js file
var width = 960
var height = 500;
var data;
var crashDataMap;
var quantize;
var path = d3.geo.path();
var zoom = d3.behavior.zoom()
.on("zoom", zoomed);
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom)
.append("g");
var counties = svg.append("g")
.attr("id", "counties")
.attr("class", "Blues");
var states = svg.append("g")
.attr("id", "states");
d3.json("county.json", function(county) {
var countyFeatures = topojson.feature(county, county.objects.county);
counties.selectAll("path")
.data(countyFeatures.features)
.enter().append("path")
.attr("d", path);
});
d3.json("state.json", function(state) {
var stateFeatures = topojson.feature(state, state.objects.state);
states.selectAll("path")
.data(stateFeatures.features)
.enter().append("path")
.attr("d", path);
});
d3.json("Crashes.json", function(crashes) {
crashDataMap = d3.map();
crashes.forEach(function(d) {crashDataMap.set(d.id, d);});
data = crashDataMap.values();
quantize = d3.scale.quantize()
.domain(d3.extent(data, function(d) {return d.crashTotal;}))
.range(d3.range(9).map(function(i) {return "q" + i + "-9"}));
/*
for(i = 0; i < data.length; i++) {
console.log(quantize(crashDataMap.get(data[i].id).crashTotal));
}
*/
counties.selectAll("path")
.attr("class", function(d) {return quantize(crashDataMap.get(d.id).crashTotal);});
});
function zoomed() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
};
Взгляните, где я сгенерировал пути для округов. После оператора .enter().append("path")
, если бы я ввел код .attr("class", "q8-9)
, он окрасил бы каждый округ в соответствии со схемой, определенной как q8-9.
Если я вызову counties.selectAll("path").attr("class", "q8-9")
где-нибудь за пределами кодовой скобки, ничего не произойдет; карта остается белой. Это беспокоит меня, поскольку я явно понятия не имею, почему это может произойти. Я могу убедиться, что элементы пути есть как для округа, так и для штата.