2014-11-23 2 views
0

Я работал над отдельными файлами, чтобы составить карту Шотландии. Тогда, Чтение файла csv, который указывает сторону, которая является большинством сообщений msps, принадлежит. На основе партии регион будет окрашен. После прочтения файла csv я попытался выбрать области, чтобы изменить их цвета, но это не сработает. Вот код:Применить изменения к выбранным элементам внутри элемента svg?

<script> 
var dataset =[] 

var width = 960, 
height = 1160; 

var projection = d3.geo.albers() 
.center([0, 55.4]) 
.rotate([4.4, 0]) 
.parallels([50, 60]) 
.scale(10000) 
.translate([width/2, height/2]); 

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

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

var gssCode = [{gss:"S12000005", reg:"central"}, 
{gss:"S12000014", reg:"central"}, 
{gss:"S12000030", reg:"central"}, 
{gss:"S12000006", reg:"dg"}, 
{gss:"S12000008", reg:"strathclyde"}, 
{gss:"S12000011", reg:"strathclyde"}, 
{gss:"S12000018", reg:"strathclyde"}, 
{gss:"S12000021", reg:"strathclyde"}, 
{gss:"S12000028", reg:"strathclyde"}, 
{gss:"S12000029", reg:"strathclyde"}, 
{gss:"S12000035", reg:"strathclyde"}, 
{gss:"S12000038", reg:"strathclyde"}, 
{gss:"S12000039", reg:"strathclyde"}, 
{gss:"S12000044", reg:"strathclyde"}, 
{gss:"S12000045", reg:"strathclyde"}, 
{gss:"S12000046", reg:"strathclyde"}, 
{gss:"S12000010", reg:"lothian"}, 
{gss:"S12000019", reg:"lothian"}, 
{gss:"S12000026", reg:"lothian"}, 
{gss:"S12000036", reg:"lothian"}, 
{gss:"S12000040", reg:"lothian"}, 
{gss:"S12000013", reg:"highland"}, 
{gss:"S12000017", reg:"highland"}, 
{gss:"S12000023", reg:"highland"}, 
{gss:"S12000027", reg:"highland"}, 
{gss:"S12000015", reg:"fife"}, 
{gss:"S12000020", reg:"grampian"}, 
{gss:"S12000033", reg:"grampian"}, 
{gss:"S12000034", reg:"grampian"}, 
{gss:"S12000024", reg:"tayside"}, 
{gss:"S12000041", reg:"tayside"}, 
{gss:"S12000042", reg:"tayside"} 
]; 

var color = { 
"Scottish Conservative and Unionist Party" : "#5ABFF4", 
"Scottish Labour" : "#846DD4", 
"Scottish Liberal Democrats" : "#FA6485", 
"Scottish National Party" : "#F6DC60", 
"Scottish Green Party" : "#31C48E", 
"Independent" : "#986561", 
"No Party Affiliation" : "#475070" 
}; 

d3.csv("map_data.csv",function(error,dataset){ 
var region = {}; 
dataset.forEach(function(d){ 
    region[d.region]=d.party; 
}); 

gssCode.forEach(function(d){ 
    d3.json(d.gss + "_topo.json", function(error, councilArea) { 
     var mesh = topojson.mesh(councilArea, councilArea.objects[d.gss + "_geo"], function(a, b) {return a==b;}); 
     svg.append("path") 
      .datum(mesh) 
      .attr("class", d.reg) 
      .attr("id", d.gss) 
      .attr("d", path) 
      .style("fill",color[region[d.reg]]); 


    }); 


}); 


}); 
</script> 
+0

Существует так много, что вы можете сделать, чтобы улучшить этот код, трудно понять, с чего начать. Самое фундаментальное замечание состоит в том, что вы не используете данные в массивах, и в этом есть сила D3. Если вы можете настроить массив идентификаторов регионов и имен, а также одну из сторон и цветов, что значительно облегчит жизнь вы. –

+0

PS Это не значит, что это критика - мы все должны что-то начать. Если вы научитесь создавать массивы, а не множество переменных, настройте свои данные соответствующим образом, а затем повторно разместите свой код. –

+0

@angusl Я переписал код .., но появились дополнительные проблемы. Ошибка при назначении mesh var .. и itr var всегда печатается как 32 внутри цикла. когда я пытался отобразить только одну область, часть выделения все еще не меняет цвет отображаемой области. – lrmals

ответ

0

Моя ошибка, определяющая массивы вместо объектов. Попробуйте следующее:

var w=960, h=1160; 

var gssCode = { 
    "S12000005":"central", 
    "S12000014":"central", 
    "S12000030":"central", 
    "S12000006":"dg", 
    "S12000008":"strathclyde", 
    "S12000011":"strathclyde", 
    "S12000018":"strathclyde", 
    "S12000021":"strathclyde", 
    "S12000028":"strathclyde", 
    "S12000029":"strathclyde", 
    "S12000035":"strathclyde", 
    "S12000038":"strathclyde", 
    "S12000039":"strathclyde", 
    "S12000044":"strathclyde", 
    "S12000045":"strathclyde", 
    "S12000046":"strathclyde", 
    "S12000010":"lothian", 
    "S12000019":"lothian", 
    "S12000026":"lothian", 
    "S12000036":"lothian", 
    "S12000040":"lothian", 
    "S12000013":"highland", 
    "S12000017":"highland", 
    "S12000023":"highland", 
    "S12000027":"highland", 
    "S12000015":"fife", 
    "S12000020":"grampian", 
    "S12000033":"grampian", 
    "S12000034":"grampian", 
    "S12000024":"tayside", 
    "S12000041":"tayside", 
    "S12000042":"tayside" 
}; 

// use your CSV here. You will need to either use queue or wrap the d3.json inside d3.csv 
var pLoad = [ 
    {reg:"tayside",party:"Scottish Labour"}, 
    ... 
]; 

var party={}; 
pLoad.forEach(function(d){ 
    party[d.reg]=d.party; 
}); 

var color = { 
    "Scottish Conservative and Unionist Party" : "#5ABFF4", 
    "Scottish Labour" : "#846DD4", 
    "Scottish Liberal Democrats" : "#FA6485", 
    "Scottish National Party" : "#F6DC60", 
    "Scottish Green Party" : "#31C48E", 
    "Independent" : "#986561", 
    "No Party Affiliation" : "#475070" 
}; 

var projection = d3.geo.albers() 
    .center([0, 55.4]) 
    .rotate([4.4, 0]) 
    .parallels([50, 60]) 
    .scale(10000) 
    .translate([w/2, h/2]); 

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

var svg = d3.select("body") 
    .append("svg") 
    .attr("width",w) 
    .attr("height",h); 

d3.json("scotland-topojson-file.json",function(err,load){ 
    svg.selectAll("path") 
     .data(topojson.feature(load,load.objects.layer1).features) 
     .enter().append("path") 
     .attr("d",path) 
     .style("fill",function(d){return color[party[gssCode[d.properties.gss]]];}) 
     .append("title") 
     .text(function(d){return gssCode[d.properties.gss]+"\n"+d.properties.gss;}); 
}); 
+0

Просто интересно, получилось ли у вас это? –

+0

Мне очень жаль .. Я был занят представлением мастера. В конце семестра вы знаете -_- ".. Я использовал это для загрузки csv d3.csv (" map_data.csv ", function (error, d) { \t pLoad = d.map (функция (d) {return [{"reg": d ["region"], "party": d ["party"]}];}); }) , но когда я зарегистрировал pLoad на консоли, он был пуст :( – lrmals

+0

Я изменил загрузку csv-файла на фиксированный массив объекта, а работа с раскраской ... Я просто не мог понять, как загрузить csv в формате массива объектов. Я очень благодарен за ваше время и усилия. – lrmals

0

Я пишу это как ответ. Он не является полным и почти наверняка не будет безошибочным, но он должен дать вам структуру для работы.

Один вопрос: у вас действительно есть много отдельных файлов с одним контуром GSS в каждом из них? Это необычно, и это намного проще, если они находятся в одном файле.

Я хотел бы начать с закреплением ваш массив gssCode:

var gssCode = [ 
    {gss:"S12000005",reg:"central"}, 
    {gss:"S12000006",reg:"dg"}, 
    ... 
]; 

Мы можем получить доступ к коду GSS с помощью

gssCode[x].gss 

и ту же идею для региона.

Затем я настроил ваш цветный поиск как объект.

var color = { 
    "Scottish Conservative and Unionist Party": "#5ABFF4", 
    "Scottish Labour": "#846DD4", 
    ... 
}; 

Установка этого в качестве объекта аккуратный трюк, как вы можете передать объект имя партии и получить цвет обратно, например,

Этот следующий раздел не изменился.

var width = 960, height = 1160; 

var projection = d3.geo.albers() 
    .center([0, 55.4]) 
    .rotate([4.4, 0]) 
    .parallels([50, 60]) 
    .scale(10000) 
    .translate([width/2, height/2]); 

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

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

Это в значительной степени ваш код, но я упростил петлю, созданную с помощью Foreach, и я загружен CSV, а затем сделал JSON в этом. Вы можете использовать queue.js (тесно связанный с D3), чтобы упростить это.

d3.csv("map_data.csv",function(error,dataset){ 

    // Assuming your CSV has fields reg and party... 
    var region = {}; 
    dataset.forEach(function(d){ 
     region[d.reg]=d.party; 
    }); 
    // ... which creates an object to lookup against, region["dg"]="The majority party in DG" 

    gssCode.forEach(function(d){ 
     d3.json(d.gss + "_topo.json", function(error, councilArea) { 
      var mesh = topojson.mesh(councilArea, councilArea.objects[d.gss + "_geo"], function(a, b) {return a==b;}); 
      svg.append("path") 
       .datum(mesh) 

       // This next line is simpler because you don't need to call get_region - it's already in your gessCode array 
       .attr("class", d.reg) 
       .attr("id", d.gss) 
       .attr("d", path) 

       // This line is new, pulling in the party from your region object (the CSV) and then the colour from your color object 
       .style("fill",color[region[d.reg]]); 

     // Closing the d3.json 
     }; 

    // Closing the forEach 
    }); 

// Closing the d3.csv 
}); 

Надеюсь, это поможет. Используйте консоль Chrome, чтобы обнаружить ошибки, и удачи!

+0

Спасибо. Я попробую это и вернусь, чтобы положить все, с чем я закончил. О json-файле я нашел один файл, который включает все области совета scotland, но я не мог понять, как отыскать объекты, которые представляют области из него. Здесь https://www.dropbox.com/s/0bczpuu9t2uds3g/all_councils_topo.json?dl = 0 – lrmals

+0

Я обновил код на основе вашего ответа, и теперь он работает как моя первая длинная версия кода, но изменение цвета не применяется к карте :(.. Карта выглядит так: https : //www.dropbox.com/s/cgmmqwzwaiumy0l/Screenshot%202014-11-25%2014.49.40.png? dl = 0 – lrmals

+0

Если вы проверите элементы пути, что он дает вам как цвет заливки? –

Смежные вопросы