2014-02-06 18 views
2

Я пытаюсь загрузить карту D3 с помощью topjson и объединить с ней отдельный файл CSV с данными, которые я хотел бы использовать для окраски карты. Я могу переключаться между несколькими слоями, но не каждый раз перерисовывать карту. Я прочесывал доски, чтобы понять, как это сделать, но я не могу понять, как это понять. Может ли кто-нибудь помочь?Создание многослойной карты с D3

Я хочу, чтобы данные CSV и JSON были разделены на случай, если мы хотим динамически редактировать CSV, когда мы идем. Я хотел бы либо добавить соответствующие классы в каждую страну за один раз, либо добавить и удалить классы, когда пользователь переключается между тремя кнопками. Либо работает для меня, я просто не могу понять, как это сделать.

var width = 945 

var height = 550 

var svg = d3.select('#content').append('svg').attr('width', width).attr('height', height); 

var projection = d3.geo.mercator().scale(175); 

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

var all_data = {}; 

var tierById = d3.map(); 

var quantize = d3.scale.quantize() 
    .domain([0, 1]) 
    .range(d3.range(2).map(function(i) { return "tier" + i; })); 

queue() 
    .defer(d3.json, "data/world.json") 
    .defer(d3.csv, "data/wod.csv") 
    .await(setUpChoropleth); 

function setUpChoropleth(error, json) { 

    svg.append("g") 
    .attr("class", "countries") 
    .selectAll("path") 
    .data(topojson.feature(json, json.objects.countries).features) 
    .enter().append("svg:path") 
    .attr("d", path); 

} 

function drawTierI() { 
    queue() 
     .defer(d3.json, "data/world.json") 
     .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_i); }) 
     .await(ready); 

    function ready(error, json) { 
    svg.append("g") 
     .attr("class", "countries") 
     .selectAll("path") 
     .data(topojson.feature(json, json.objects.countries).features) 
     .enter().append("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

function drawTierII() { 
    queue() 
     .defer(d3.json, "data/world.json") 
     .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_ii); }) 
     .await(ready); 

    function ready(error, json) { 
    svg.append("g") 
     .attr("class", "countries") 
     .selectAll("path") 
     .data(topojson.feature(json, json.objects.countries).features) 
     .enter().append("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

function drawTierIIPlus() { 
    queue() 
     .defer(d3.json, "data/world.json") 
     .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_ii_plus); }) 
     .await(ready); 

    function ready(error, json) { 
    svg.append("g") 
     .attr("class", "countries") 
     .selectAll("path") 
     .data(topojson.feature(json, json.objects.countries).features) 
     .enter().append("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

$('button#tier_i').click(function (e) { 
    $("svg").empty(); 
    drawTierI(); 
}); 

$('button#tier_ii').click(function (e) { 
    $("svg").empty(); 
    drawTierII(); 
}); 

$('button#tier_ii_plus').click(function (e) { 
    $("svg").empty(); 
    drawTierIIPlus(); 
}); 

Вот jfiddle моего кода: http://jsfiddle.net/2H7Pm/ Я, кажется, некоторые проблемы синтаксиса с JSON, однако.

Пример карты НЕ работает на моем GitHub однако: http://newamericafoundation.github.io/worldofdrones/

Спасибо за помощь!

ответ

1

Вам нужно просто выбрать существующие пути вместо добавления новых после начальной настройки choropleth, например.

function drawTierI() { 
    csv.forEach(function(d) { tierById.set(d.id, +d.tier_i); }); 

    function ready(error, json) { 
    svg.selectAll("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

и аналогичным образом для других функций. Вам не нужно перезагружать JSON и CSV на каждом шаге либо - приведенный выше код при условии, что ваши данные CSV сохраняются в переменной csv, которую вы бы заселить таким образом:

var csv; 
function setUpChoropleth(error, json, _csv) { 
    csv = _csv; 
    // rest of setup 
} 

Тогда вы можете просто do

$('button#tier_i').click(function (e) { 
    drawTierI(); 
}); 

, чтобы изменить отображаемую переменную без необходимости сначала очистить SVG.

+0

Спасибо! В этом есть смысл. Любые советы по устранению отставания, возникающего при переключении слоев? Похоже, мне не нужно было загружать CSV и JSON на каждый клик, но это единственный способ, который я могу вызвать несколько столбцов из CSV. –

+0

Ах да, я этого не заметил. Будет обновлен ответ. –

+0

Спасибо, это прекрасно работает, как вы описали! Определенно узнал что-то новое о D3 и JS благодаря вам. –

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